Open Spomky opened 2 months ago
While stimulus components would work, I think Twig Components would be even better (which would wrap the stimulus calls in twig).
It's easier (for me at least) to work with the new bundle structure when adding stimulus/twig components. I see you've added #80 to milestone 1.1, would you like me to take a crack at refactoring the bundle config to use AbstractBundle?
I made some progress on this, by creating a pwa-extra-bundle. I use Bootstrap rather than Tailwind, so I created twig components (which wrap stimulus controllers) where the content is configurable .
composer require survos/pwa-extra-bundle
Then cut, paste and customize
<twig:PwaInstall>
<twig:block name="install">
<button type="button" class="btn btn-primary">
<span class="bi bi-download"></span>
Install as PWA
</button>
</twig:block>
<twig:block name="launch">
<button type="button" class="btn btn-success">
<span class="bi bi-download"></span>
It's installed! Launch it!
</button>
</twig:block>
</twig:PwaInstall>
<twig:ConnectionDetector>
<twig:block name="online">
<button class="btn btn-warning">Online</button>
</twig:block>
<twig:block name="offline">
<button class="btn btn-danger">offline</button>
</twig:block>
</twig:ConnectionDetector>
Launch still does not work, as I'm not sure what it's supposed to be.
See it in action: https://noise.survos.com/, functional but unattractive, as I'm in the middle of switch to bootstrap.
Hi,
I started working on stimulus component. I am not familar with twig components and need to learn more about those. The first component I created is very simple, but allows customizing any HTML tag.
The refactoring of the bundle configuration is done in 1.1.x and I would like to release it by the end of the month.
Two stimulus components are available:
@pwa/connection-status
Shows if the browser is online or not
@pwa/backgroundsync-form
When you submit a form offline and the response usually redirects to another page, the browser will go to the action url and not the redirect one as no response is received. With this component, the developers can easily redirect to the correct page even if offline. Custom behavior will be possible soon by intercepting events.
background sync sounds very exciting, but I'm not sure how to use it. Here's the form rendering to add a task in phpwa-demo. Should the stimulus controller go on the form itself, or can it go on a div that wraps the form?
And if the user is offline, what happens? I've been reading https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Offline_and_background_operation, and an example would be very helpful.
{{ form_start(form, {attr: {class: ' class="max-w-sm mx-auto"'}}) }}
<div class="mb-5">
<label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
{{ form_label(form.name) }}
</label>
{{ form_widget(form.name, {attr: {class: 'block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 text-base focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'}}) }}
</div>
<button type="submit" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Add</button>
{{ form_end(form) }}
To work with BackgroundSync, you first need to declare what routes/methods you want to capture. In the demo, I enabled POST requests to https://localhost:8000/ and https://localhost:8000/items/*.
And you are done! ... almost done. When the form is supposed to redirect to the same page, no problem. This is the case when you add a new item. When the form is supposed to redirect the user to another page, the application is unable to redirect as no response is received. It shows the fallback page (if any), but the URL is wrong. This is the case for e.g. removing items.
The purpose of this stimulus component is to help redirecting correctly. It is used by the other forms on the page where we expect a redirection to /
.
In short:
ok you are posting data but fetch failed (when the promise rejects, it's a network error) so I redirect you. the request is in good hands and will be submitted again.
the request is in good hands and will be submitted again.
So the idea is that it would return to a page that said "Thanks for submitting! You're offline now, but your request is queued for delivery when you reconnect."
That's pretty cool!
That's the idea.
What I am trying to do now is to notify the frontend that the queue is not empty.
The BackgroundSync Plugin accepts an onSync
property, but it does not work as expected:
"onSync": async ({queue}) => {
await queue.replayRequests();
remainingRequests = await queue.getAll();
const bc = new BroadcastChannel('background-sync');
bc.postMessage({name: '{$sync->queueName}', remaining: remainingRequests.length});
bc.close();
}
The final goal is to ease features like this one: https://github.com/GoogleChrome/workbox/issues/2044#issue-436802366 Having a BackgroundSync-aware component would be great.
Sync Broadcast Stimulus Component in action. The UX is ugly and need to refresh the page. But requests are correctly queued and if asked the number of requests in the queue is send through the Broadcast system.
This is great.
Question: is it possible to bypass the form submit and go directly to the queue? In particular, I'm thinking about when you want to take photos quickly and don't want to wait for the upload.
It should be possible to bypass it using JS. With BackgroundSync, the strategy is NetworkOnly + the queue plugin i.e. will try to fetch the server and then fallback to the queue. By default the timeout is 3 seconds. It is possible to lower this value. I added an option for the NetworkFirst strategy and the page navigation, but missed it for the background sync feature. I will add it.
Description
The demo contains helpful Stimulus Components and additional JS scripts that could be added here to ease the integration.
Example