DEV: migrates pwa-install-banner to gjs (#27859)

This commit is contained in:
Joffrey JAFFEUX 2024-07-11 11:53:39 +02:00 committed by GitHub
parent 478b096286
commit da1a049144
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 81 additions and 78 deletions

View File

@ -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;
}
<template>
{{#if this.showPWAInstallBanner}}
<div class="pwa-install-banner alert alert-info">
<span>
<DiscourseLinkedText
@action={{this.turnOn}}
@text="pwa.install_banner"
@textParams={{hash title=this.siteSettings.title}}
/>
</span>
<DButton
@icon="times"
@action={{this.dismiss}}
@title="banner.close"
class="btn-transparent close"
/>
</div>
{{/if}}
</template>
}

View File

@ -1,19 +0,0 @@
{{#if this.showPWAInstallBanner}}
<div class="row">
<div class="pwa-install-banner alert alert-info">
<span>
<DiscourseLinkedText
@action={{action "turnOn"}}
@text="pwa.install_banner"
@textParams={{hash title=this.siteSettings.title}}
/>
</span>
<DButton
@icon="times"
@action={{action "dismiss"}}
@title="banner.close"
class="btn-transparent close"
/>
</div>
</div>
{{/if}}

View File

@ -1,59 +0,0 @@
import Component from "@ember/component";
import discourseComputed, { bind, on } from "discourse-common/utils/decorators";
const USER_DISMISSED_PROMPT_KEY = "dismissed-pwa-install-banner";
export default Component.extend({
deferredInstallPromptEvent: null,
@bind
_onInstallPrompt(event) {
// Prevent Chrome 76+ from automatically showing the prompt
event.preventDefault();
// Stash the event so it can be triggered later
this.set("deferredInstallPromptEvent", event);
},
@on("didInsertElement")
_registerListener() {
window.addEventListener("beforeinstallprompt", this._onInstallPrompt);
},
@on("willDestroyElement")
_unregisterListener() {
window.removeEventListener("beforeinstallprompt", this._onInstallPrompt);
},
@discourseComputed
bannerDismissed: {
set(value) {
this.keyValueStore.set({ key: USER_DISMISSED_PROMPT_KEY, value });
return this.keyValueStore.get(USER_DISMISSED_PROMPT_KEY);
},
get() {
return this.keyValueStore.get(USER_DISMISSED_PROMPT_KEY);
},
},
@discourseComputed("deferredInstallPromptEvent", "bannerDismissed")
showPWAInstallBanner(deferredInstallPromptEvent, bannerDismissed) {
return (
this.capabilities.isAndroid &&
this.get("currentUser.trust_level") > 0 &&
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
!bannerDismissed // Have not a previously dismissed install banner
);
},
actions: {
turnOn() {
this.set("bannerDismissed", true);
this.deferredInstallPromptEvent.prompt();
},
dismiss() {
this.set("bannerDismissed", true);
},
},
});