How to query WidgetKit if my widgets are being used? - ios

I would like to check if the user added my widgets to the Home Screen, is there an API for this? I could not find one. WidgetCenter.getCurrentConfigurations returns all available widgets served by the app, not the used ones.
The reasons I look for such an API are:
I would like to report usages of the widgets.
I would like to decide if I should trigger timeline reloads via WidgetCenter when state changes happen in the app.

Method WidgetCenter.shared.getCurrentConfigurations does return the number of user configured widgets:
WidgetCenter.shared.getCurrentConfigurations { widgets
if let widgets = widgets, widgets.count > 0 {
// User did configure at least one widgets
}
}
This is also according the documentation:
Retrieves information about user-configured widgets.

Unfortunately, I don't think such an API exists (yet).
For 1. I would write something that identifies the widget in a shared user defaults container. Hooks for that would be getSnapshot(for:,in:,completion:) or getTimeline(for:,in:,completion:) with context.isPreview == false. Now the difficult part is that you don't get any id for the widget so you cannot distinguish two widgets with the same configuration (afaik).
For 2. I think this is (and will be) opaque, so you just tell the WidgetCenter to reload specific or all configurations and when no widget is currently placed on the home screen nothing happens.

Related

Widget getTimeline method called multiple times for customized intents

In my iOS 14 widget with a single custom intent, when the user selects one intent, then changes to another, my getTimeline method is called multiple times for each intent on each refresh - including previously-selected ones.
I would expect getTimeline to only be called with the currently-selected intent. Is there a way to check whether the intent is the currently-selected intent? I make a network request in the getTimeline method and I do not want to make multiple requests when the widget only shows one intent.
As an example, I downloaded the Emoji Ranger sample code and added a print statement to the getTimeline method. I then:
Run the app and open it once.
Add a widget to the home screen.
Run the widget extension target on the simulator.
Select the character Egghead.
Select the character Cake.
This is what prints on the next widget refresh (usually ~15 mins):
- Timeline: nil
- Timeline: Optional("Egghead")
- Timeline: Optional("Cake")
Any help is much appreciated, thanks!

How to reload a ResourceTable programmatically in Laravel Nova?

I have a custom resource-tool (ledger entry tool) that modifies values of a resource as well as insert additional rows into related resources.
"Account" is the main resources.
"AccountTransaction" and "AccountLog" both get written to when a ledger entry is created. And through events, the account.balance value is updated.
After a successful post of a ledger entry (using Nova.request) in the resource-tool, I would like the new balance value updated in the account detail panel, as well as the new entries in AccountTransaction and AccountLog to be visible.
The simple way would be to simply reload the page, but I am looking for a more elegant solution.
Is it possible to ask these components to refresh themselves from within my resource-tool vue.js component?
Recently had the same issue, until I referred to this block of code
Nova has vuex stores modules, where they have defined storeFilters.
Assigning filters an empty object and then requesting them again "reloads" the resources. Haven't done much more research on this matter, but if you are looking for what I think you are looking for, this should be it.
async reloadResources() {
this.resourceName = this.$router.currentRoute.params.resourceName || this.$router.currentRoute.name;
if (this.resourceName) {
let filters_backup = _.cloneDeep(this.$store.getters[`${this.resourceName}/filters`]);
let filters_to_change = _.cloneDeep(filters_backup);
filters_to_change.push({});
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_to_change);
await this.$store.commit(`${this.resourceName}/storeFilters`, filters_backup);
}
},

Can you dynamically load modules in Angular?

I have an angular app with two distinct sections to it. Each section belongs to a type of user. There are some commonalities but for the most part rather different. For example:
/receptionist
- View Diary
- Answer Phone
- Make Tea
/ceo
- View Diary
- Announce Earnings
- Strategize
Both the ceo and the receptionist need the functionality for viewing the diary. I was thinking wanting to change the modules loaded (and the routing) depending on who logged in.
if (user.type === 'receptionist') {
app = angular.module('receptionistApp', ['diary', 'phone', 'tea']);
else {
app = angular.module('ceoApp', ['diary', 'earning', 'strategy']);
}
I am wanting to do this because there is some overlap, but not a lot. And each app is actually quite big.
I am not wanting to achieve anything security wise here. Each app will have different types of users and roles. Those will be secured through WebApi. I just wanting to avoid loading all of the modules when 45% of them will be of no interest to the other app.
Yes.
Also, (and you probably won't need this) you can load modules even more dynamically, and initialize AngularJS yourself instead of having it load instantly. You can remove the ng-app directive, and do a manual initialization.
angular.element(document).ready(function() {
angular.module('myApp', []);
angular.bootstrap(document, ['myApp']);
});

Dynamically Loading LI's in JQueryMobile 1.0

I've just updated my project from jquerymobile 1.0a1 to version 1.0.
I've encountered a problem with dynamic content. Based on an ajax search I populate an unordered list with list items. Previous the following code refreshed the list so that all the styling appeared correctly:
$('#myContent').find("ul").listview();
$('#myContent').find("ul").listview('refresh');
However as of 1.0 this no longer seems to work.
The list appears but the styling is all wrong and the data-theme on all the elements gets ignored.
Has anyone come across a similar issue with updating and come across the solution.
Updating lists If you add items to a listview, you'll need to call the refresh() method on it to update the styles and create
any nested lists that are added. For example:
$('#mylist').listview('refresh');
Note that the refresh() method only affects new nodes appended to a
list. This is done for performance reasons. Any list items already
enhanced will be ignored by the refresh process. This means that if
you change the contents or attributes on an already enhanced list
item, these won't be reflected. If you want a list item to be updated,
replace it with fresh markup before calling refresh.
http://jquerymobile.com/demos/1.0/docs/lists/docs-lists.html
if #myContent is the listview you can do this:
$('#myContent').listview('refresh');
if #myContent is the page you can do something like this:
$('#myContent').trigger('create');
Create vs. refresh: An important distinction Note that there is an important difference between the create event and refresh method
that some widgets have. The create event is suited for enhancing raw
markup that contains one or more widgets. The refresh method should be
used on existing (already enhanced) widgets that have been manipulated
programmatically and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new
unordered list with data-role=listview attribute after page creation,
triggering create on a parent element of that list would transform it
into a listview styled widget. If more list items were then
programmatically added, calling the listview’s refresh method would
update just those new list items to the enhanced state and leave the
existing list items untouched.
http://jquerymobile.com/demos/1.0/docs/pages/page-scripting.html
What you want can be achieved by replacing your 2 lines of code with the following:
$('#myContent ul').listview('create');
Hope this helps...
I've had this issue. The reason you are getting things all messed up is you are initalizing and refreshing the element multiple times. I noticed I had 2 different functions running that would call .listview('refresh') on the same element. After I took one out the themes and data went back to looking normal. Also are you getting any JS errors?
EDIT:
To be more specific you are calling .listview() somewhere in your code 2 times which is initializing it twice. I would wait to before you page is loaded to run the refresh so you only call it once.
Another thing you could do is check if the element is initialized already or not so you don't do it twice. Just check the element or in some cases the parent to see if the class ui-listview is present.
var element = $('#myContent').find('ul');
if ($(element).hasClass('ui-listview')) {
//Element is already initialized
$(element).listview('refresh');
} else {
//Element has not been initiliazed
$(element).listview().listview('refresh');
}
Just an FYI you can chain those events to look like $('#myContent').find('ul').listview().listview('refresh');
It cand be achived through.
$('#myContent').listview('refresh');
The below snippet shows you to load data from xml and dynamically create a list view.
function loadData()
{
$.ajax({
url:"BirthdayInvitations.xml",
dataType: "xml",
success: function(xml)
{
$(xml).find("event").each(function()
{
$("#mymenu").append('<li>' + this.textContent + ' </li>');
});
$("#mymenu").listview('refresh');
}
});
}
See if this is related to ur question http://www.amitpatil.me/demos/jquery-mobile-twitter-app/ and this one also http://www.amitpatil.me/demos/ipad-online-dictionary-app/
In first example i am using listview('refresh'); method and in second example i am using
$(document).page("destroy").page();

jQuery Tabs - Load contents only when clicked

I am relatively new to jQuery and web development.
I am using jQuery UI Tabs to create tabs.
But I want the contents to be loaded only when I select a particular tab.
OK, I assume when the user clicks a tab, you intend to fetch content dynamically, via AJAX. This really involves two things, setting an onclick even for your tab and fetching the data via ajax.
Setting an onclick event
Give your tab an class, for example my_tab. Let's say that when the user clicks the tab you want the handle_tab_click() function to fire. Here's an example of binding the onclick event to your my_tab tab:
$(".my_tab").bind("click", handle_tab_click);
Your handle_tab_click() function will be given an event argument which will be able to provide you with information on the element that fired the event (in this case, the element with class name my_tab).
function (event) {
if ($(event.target).hasClass("my_tab")) { /* handle tab click */ }
if ($(event.target).hasClass("my_tab_2")) { /* a different tab click */ }
if ($(event.target).hasClass("my_tab_3")) { /* ... */ }
}
See the JQuery event documentation for more details here.
Fetching the data via ajax
Fetching data will require you to invoke a remote script while supplying information about which tab was clicked (in order to fetch the appropriate information). In the following snippet, we're invoking the remote script myscript.php, supplying the HTTP GET argument tab_clicked=my_tab and calling the function tab_fetch_cb when the script returns. The final parameter is the type of data being returned (it's up to you to choose).
$.get("myscript.php", {tab_clicked, "my_tab"}, tab_fetch_cb, "text/json/xml")
It's up to you to design myscript.php to handle the tab_clicked parameter, fetch the appropriate data and return it (i.e. write it back out to the client).
Here's an example for tab_fetch_cb:
function tab_fetch_cb(data, status) {
// populate your newly opened tab with information
// returned from myscript.php here
}
You can read more about the JQuery get function here, and JQuery ajax functions here
I'm sorry I can't be more specific in my examples, but a lot of the processing is really dependant on your task. As it looks as it has already been pointed out, you may look to some JQuery plugins for a canned solution to your problem. That being said, it never hurts to learn how to do this stuff manually w/ JQuery.
Good luck.
UI/Tabs support loading tab content on demand via Ajax, check this example.
Loading content via Ajax adds the complexity of dealing with bookmarking / browser back buttons. Depending on your situation, you should consider loading new content with a full page request. Handling the bookmarking/browser back involves using adding anchor info in the URL.
Also, check out LavaLamp for tab selection. It's pretty nifty looking.
By default a tab widget will swap between tabbed sections onClick, but the events can be changed to onHover through an option. Tab content can be loaded via Ajax by setting an href on a tab.
source: http://docs.jquery.com/UI/Tabs
If you're using Rails, you can try this gem bettertabs
It supports ajax tabs.

Resources