Spomky-Labs / pwa-bundle

PHP library for generating a full featured PWA manifest
https://pwa.spomky-labs.com
MIT License
27 stars 1 forks source link

Stimulus Components #85

Open Spomky opened 2 months ago

Spomky commented 2 months ago

Description

The demo contains helpful Stimulus Components and additional JS scripts that could be added here to ease the integration.

Example

tacman commented 2 months ago

While stimulus components would work, I think Twig Components would be even better (which would wrap the stimulus calls in twig).

tacman commented 2 months ago

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?

tacman commented 2 months ago

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.

Spomky commented 2 months ago

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.

Spomky commented 2 months ago

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.

tacman commented 2 months ago

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) }}
Spomky commented 2 months ago

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.

tacman commented 2 months ago

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!

Spomky commented 2 months ago

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.

Spomky commented 2 months ago

@pwa/sync-broadcast

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. 2024-03-07_21h53_12

tacman commented 2 months ago

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.

Spomky commented 2 months ago

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.