FEATURE: Incorporate PWA install prompt into Discourse UI (#8013)

* FEATURE: Incorporate PWA install prompt into Discourse UI

This is mainly done so Discourse forums stop nagging people to install
on the very first visits to a website.

We will prevent the native install "mini-info" bar from ever appearing,
capture the event that pops with it, and delay it until the user meets
our criteria, which currently is trust_level 1.

If the event happens and the user meets our criteria we show a Discourse
alert banner proposing the install to the user. Dismissal of the banner
is recorded so the user ins't bothered anymore on the same device.


Co-Authored-By: Gerhard Schlager <mail@gerhard-schlager.at>
Co-Authored-By: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This commit is contained in:
Rafael dos Santos Silva 2019-08-19 14:09:21 -03:00 committed by GitHub
parent 6f70138f4a
commit 0a5b332b8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 0 deletions

View File

@ -0,0 +1,62 @@
import {
default as computed,
on
} from "ember-addons/ember-computed-decorators";
const USER_DISMISSED_PROMPT_KEY = "dismissed-pwa-install-banner";
export default Ember.Component.extend({
deferredInstallPromptEvent: null,
_handleInstallPromptEvent(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() {
this._promptEventHandler = Ember.run.bind(
this,
this._handleInstallPromptEvent
);
window.addEventListener("beforeinstallprompt", this._promptEventHandler);
},
@on("willDestroyElement")
_unregisterListener() {
window.removeEventListener("beforeinstallprompt", this._promptEventHandler);
},
@computed
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);
}
},
@computed("deferredInstallPromptEvent", "bannerDismissed")
showPWAInstallBanner() {
return (
this.get("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.bannerDismissed // Have not a previously dismissed install banner
);
},
actions: {
turnOn() {
this.set("bannerDismissed", true);
this.deferredInstallPromptEvent.prompt();
},
dismiss() {
this.set("bannerDismissed", true);
}
}
});

View File

@ -16,6 +16,7 @@
{{custom-html name="top"}}
{{/if}}
{{notification-consent-banner}}
{{pwa-install-banner}}
{{global-notice}}
{{create-topics-notice}}
{{plugin-outlet name="top-notices" args=(hash currentPath=router._router.currentPath)}}

View File

@ -0,0 +1,12 @@
{{#if showPWAInstallBanner}}
<div class="row">
<div class="pwa-install-banner alert alert-info">
<div class="close" {{action "dismiss"}}>
{{d-icon 'times'}}
</div>
<span>
{{discourse-linked-text action=(action "turnOn") translatedText=(i18n "pwa.install_banner" title=siteSettings.title)}}
</span>
</div>
</div>
{{/if}}

View File

@ -352,6 +352,9 @@ en:
close: "Dismiss this banner."
edit: "Edit this banner >>"
pwa:
install_banner: "Do you want to <a href>install %{title} on this device?</a>"
choose_topic:
none_found: "No topics found."
title: