cables-gl / cables_docs

cables documentation docs.cables.gl
https://cables.gl/docs/docs
33 stars 14 forks source link

Seems like Embed Patch Initialization Failure on new tab on mobile. #743

Closed sebastianpetrovski closed 1 month ago

sebastianpetrovski commented 1 month ago

Describe the bug

I have embedded a patch on a webpage that fails to initialise if the page is visited directly on android.

If I open a new tab on android chrome and visit the problem webpage directly or if I share the link to my phone and open it directly the patch doesn't initialize; and cables.gl doesn't throw an initialization error in the console or any error visible on the webpage.

Most times, but not all times, if I refresh the problem page, the patch initializes and works fine. If I visit the problem page from another page on the same domain/website the patch initializes and works fine. Likewise if I open a new tab, visit any other website/domain and then visit the problem page.

This problem doesn't exist on desktop.

I've been trying to troubleshoot it and I'm at a loss because based on the console logs it seems like things are going as planned and then they just stop. The only error message that presents is when I click a page element that's configured to trigger inside the patch.

I hope this is descriptive enough - I'll be super curious to see what you might think. The page is on a staging site so I don't want to share the URL publicly, but if it will help to see the page I can send directly to @pandrr or @steam0r

Here's the script in the head to load the patch.js

<script type="text/javascript" src="/cables_BBXYZ_Answers5/js/patch.js" async
        onload="console.log('Patch script loaded successfully')"
        onerror="console.error('Error loading patch script:', this.src)"></script>

I placed the initialize script at HTML bottom, just before the footer; it looks for a div, attaches a canvas to it and intializes the patch in that canvas. I know it's kind of an ugly way to do it, but I'm working within the constraints of a wordpress theme I'm stuck with for the time being πŸ™ƒ

<script>
    window.laytheme.on("newpageshown", function () {
        console.log("New page shown event triggered");

        var slug = jQuery("body").attr("data-slug");
        var id = jQuery("body").attr("data-id");
        var type = jQuery("body").attr("data-type");

        // Check if the user is on the required page
        if (id === "756") {
            console.log("User is on page with ID 756");

            // Create a canvas element
            var canvas = document.createElement("canvas");
            canvas.id = "glcanvas"; // Set canvas id
            canvas.style.width = "100svw"; // Set canvas width to 100% viewport width
            canvas.style.height = "100svh"; // Set canvas height to 100% viewport height
            canvas.style.zIndex = "0"; // Set z-index to ensure it's behind other elements
            canvas.style.position = "fixed"; // Set position to fixed

            // Function to check if an element is currently visible
            function isVisible(element) {
                return element.offsetWidth > 0 || element.offsetHeight > 0;
            }

            // Find the active or visible grid-inner element
            var gridInners = document.querySelectorAll(".grid-inner");
            var activeGridInner = null;
            gridInners.forEach(function(gridInner) {
                if (isVisible(gridInner)) {
                    activeGridInner = gridInner;
                }
            });

            // Check if the active grid-inner element is found
            if (activeGridInner) {
                console.log("Found active grid-inner:", activeGridInner);

                // Append the canvas to the active grid-inner element as the first child
                activeGridInner.insertBefore(canvas, activeGridInner.firstChild);
                console.log("Canvas inserted as the first child of the active grid-inner element");

                // Initialize the Cables patch
                function showError(errId, errMsg) {
                    // handle critical errors here if needed
                }

                function patchInitialized(patch) {
                    // You can now access the patch object (patch), register variable watchers and so on
                }

                function patchFinishedLoading(patch) {
                    // The patch is ready now, all assets have been loaded
                }

                document.addEventListener("CABLES.jsLoaded", function (event) {
                    CABLES.patch = new CABLES.Patch({
                        patch: CABLES.exportedPatch,
                        "prefixAssetPath": "/cables_BBXYZ_Answers5/",
                        "assetPath": "assets/",
                        "jsPath": "js/",
                        "glCanvasId": "glcanvas",
                        "glCanvasResizeToWindow": true,
                        "onError": showError,
                        "onPatchLoaded": patchInitialized,
                        "onFinishedLoading": patchFinishedLoading,
                        "canvas": {"alpha": true, "premultipliedAlpha": true } // make canvas transparent
                    });
                });

                // Disable rubberband effect on mobile devices
                canvas.addEventListener('touchmove', (e)=>{ e.preventDefault(); }, false);
            } else {
                console.log("No active grid-inner found.");
            }
        } else {
            console.log("User is not on page with ID 557");
        }
    });
</script>

Here's the click script responsible for the last 2 logs: "yay!" and Uncaught TypeError.

<script>
jQuery(document).on("click", ".forminator-radio-label, .forminator-button-submit", function(event) {
    console.log("yay!");
    CABLES.patch.config.nextButton();
});
</script>

Platform Chrome on Android - Pixel 6a

Dev Tools using chrome://inspect/#devices

Patch script loaded successfully answ3rs/:3334 New page shown event triggered answ3rs/:3342 User is on page with ID 756 answ3rs/:3368 Found active grid-inner: <div class=​"grid-inner">​…​

​ answ3rs/:3372 Canvas inserted as the first child of the active grid-inner element answ3rs/:3423 yay! answ3rs/:3424 Uncaught TypeError: Cannot read properties of undefined (reading 'config') at HTMLSpanElement. (answ3rs/:3424:15) at HTMLDocument.dispatch (jquery.min.js?ver=3.7.0:2:39997) at v.handle (jquery.min.js?ver=3.7.0:2:37968) (anonymous) @ answ3rs/:3424 dispatch @ jquery.min.js?ver=3.7.0:2 v.handle @ jquery.min.js?ver=3.7.0:2

steam0r commented 1 month ago

have you tried removing the "async" option from the script tag that loads the patch?

sebastianpetrovski commented 1 month ago

Hey @steam0r thanks for your reply - I tried removing the async tag and tried loading the page a few times - seems to be same result.

What's confounding me is even with async tag it looks like the patch script is loading first:

image

Something I didn't notice yesterday is that when the patch loads successfully the "Patch script loaded successfully" console message is below the "Canvas inserted as the first child of the active grid-inner element" console message. It seems counter-intuitive, but is that relevant?

image

steam0r commented 1 month ago

the second screenshot shows "made with cables", so the patch was loaded i guess, are you sure you are not doing things "when audiocontext is started" or something? because that (as seen on the screenshot) might need a user-interaction and is sometimes cached by browsers, or set differently on desktop/mobile

hard to tell without looking at the page, feel free to send me a link on discord (steam) so i might take a look later

sebastianpetrovski commented 1 month ago

Hey, thanks for your quick reply! Yes - the second screenshot it was loaded correctly - that's what I was trying to point out - it's weird that the patch script appears to be loading later when it loads correctly - but when the patch script is loaded first it seems to be failing to initialize. Thank you - I'll find message you on discord in case you get some time later

sebastianpetrovski commented 1 month ago

Thanks again for help with this!