Repository

js/Mobilizing/core/util/UserInteractionDone.js

import Component from './../Component';
import Device from './Device';
import Renderer from "../../renderer/audio/Renderer";

export default class UserInteractionDone extends Component {
    /**
     * Makes a fullscreen clickable div to generate a user interaction needed for audio and sensors usage
     */
    constructor({
        context
    } = {}) {
        super(...arguments);

        this.context = context;

        //fullscreen click surface
        this.clickScreen = document.createElement("div");
        this.clickScreen.className = "userInteraction";
        this.clickScreen.style.height = "100%";
        this.clickScreen.style.width = "100%";
        this.clickScreen.style.backgroundColor = "rgba(0,0,0,0.8)";
        this.clickScreen.style.position = "fixed";
        this.clickScreen.style.top = "0px";
        this.clickScreen.style.left = "0px";
        this.clickScreen.style.zIndex = 100;
        this.clickScreen.style.textAlign = "center";
        this.clickScreen.style.fontFamily = "sans-serif";
        this.clickScreen.style.fontWeight = "bold";
        this.clickScreen.style.fontSize = "40px";
        this.clickScreen.style.display = "flex";
        this.clickScreen.style.justifyContent = "center";
        this.clickScreen.style.alignItems = "center";
        this.clickScreen.innerText = "Click to activate sensors";
        this.clickScreen.style.color = "white";

        //a flag if needed...
        this.interacted = false;

        //the promise to fulfill from outside this object
        this.promise = new Promise((resolve, reject) => {
            this.promiseResolve = resolve;
            this.promiseReject = reject;
        });

        //listen the click event to generate a user interaction
        this.clickScreen.addEventListener("click", () => {

            //activate the sensors
            this.orientationGranted = false;
            this.motionGranted = false;

            //manage iOS 13+ fucking security system : must activate sensors on "click"
            if (Device.getOS() === "iOS") {
                if (typeof window.DeviceOrientationEvent.requestPermission === 'function') {
                    window.DeviceOrientationEvent.requestPermission().then((permissionState) => {
                        if (permissionState === "granted") {
                            //
                            this.orientationGranted = true;
                            this.resolve();
                        }
                    });
                }
                else {// handle regular non iOS 13+ devices
                    //resolve the promise to stop waiting
                    this.promiseResolve();
                }
            }
            else {// handle non iOS (??)
                //resolve the promise to stop waiting
                this.promiseResolve();
            }

            if (Device.getOS() === "iOS") {
                if (typeof window.DeviceMotionEvent.requestPermission === 'function') {
                    window.DeviceMotionEvent.requestPermission().then((permissionState) => {
                        if (permissionState === "granted") {
                            //
                            this.motionGranted = true;
                            this.resolve();
                        }
                    });
                }
                else {// handle regular non iOS 13+ devices
                    //resolve the promise to stop waiting
                    this.promiseResolve();
                }
            }
            else {// handle non iOS (??)
                //resolve the promise to stop waiting
                this.promiseResolve();
            }

            //creates an audio rendrer to allow "autoplay"
            //this will generate a warning about an instance of audioRendrer already existing
            //if you try to instanciate a new one in the user's script
            this.audioRenderer = new Renderer();

            //hide the temporary screen
            this.clickScreen.style.display = "none";
            this.interacted = true;
        });
    }

    resolve() {
        if (this.orientationGranted && this.motionGranted) {
            //resolve the promise to stop waiting
            this.promiseResolve();
        }
    }

    setup() {
        //the div will be added only on setup!
        document.body.appendChild(this.clickScreen);
        this.events.trigger("userinteractiondiv", this.clickScreen);
    }
}