diff --git a/app/assets/javascripts/discourse/app/components/pwa-install-banner.gjs b/app/assets/javascripts/discourse/app/components/pwa-install-banner.gjs new file mode 100644 index 00000000000..450d3db0828 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/pwa-install-banner.gjs @@ -0,0 +1,81 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { hash } from "@ember/helper"; +import { action } from "@ember/object"; +import { service } from "@ember/service"; +import { modifier as modifierFn } from "ember-modifier"; +import DButton from "discourse/components/d-button"; +import DiscourseLinkedText from "discourse/components/discourse-linked-text"; + +const USER_DISMISSED_PROMPT_KEY = "dismissed-pwa-install-banner"; + +export default class PwaInstallBanner extends Component { + @service capabilities; + @service currentUser; + @service keyValueStore; + @service siteSettings; + + @tracked + bannerDismissed = + this.keyValueStore.get(USER_DISMISSED_PROMPT_KEY) === "true"; + + @tracked deferredInstallPromptEvent = null; + + registerInstallPromptListener = modifierFn(() => { + const handler = (event) => { + // Prevent Chrome 76+ from automatically showing the prompt + event.preventDefault(); + // Stash the event so it can be triggered later + this.deferredInstallPromptEvent = event; + }; + + window.addEventListener("beforeinstallprompt", handler); + + return () => { + window.removeEventListener("beforeinstallprompt", handler); + }; + }); + + get showPWAInstallBanner() { + return ( + this.capabilities.isAndroid && + this.currentUser?.trust_level > 0 && + this.deferredInstallPromptEvent && // Pass the browser engagement checks + !window.matchMedia("(display-mode: standalone)").matches && // Not be in the installed PWA already + !this.capabilities.isAppWebview && // not launched via official app + !this.bannerDismissed // Have not a previously dismissed install banner + ); + } + + @action + turnOn() { + this.dismiss(); + this.deferredInstallPromptEvent.prompt(); + } + + @action + dismiss() { + this.keyValueStore.set({ key: USER_DISMISSED_PROMPT_KEY, value: true }); + this.bannerDismissed = true; + } + + + {{#if this.showPWAInstallBanner}} +
+ {{/if}} + +} diff --git a/app/assets/javascripts/discourse/app/components/pwa-install-banner.hbs b/app/assets/javascripts/discourse/app/components/pwa-install-banner.hbs deleted file mode 100644 index ba5ed5dfb9f..00000000000 --- a/app/assets/javascripts/discourse/app/components/pwa-install-banner.hbs +++ /dev/null @@ -1,19 +0,0 @@ -{{#if this.showPWAInstallBanner}} -