Skip to content

Commit

Permalink
feat(app): App installation is now configurable (#929)
Browse files Browse the repository at this point in the history
* typo

* feat(app): App installation is now configurable

* wip

* wip

* refactor(pwa): fix for app refresh on ios

* refactor(webmanifext): add id and adjust start_url and scope

* wip
  • Loading branch information
pelord committed Apr 24, 2023
1 parent c9cc454 commit 13b76fe
Show file tree
Hide file tree
Showing 13 changed files with 1,564 additions and 1,070 deletions.
39 changes: 39 additions & 0 deletions docs/config_json.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,45 @@ Résumé

Important : Les propriétés en caractère gras suivies d'un * sont obligatoires.

***************
App
***************

.. line-block::

Permet d'activer des options pour l'application.

Exemples

.. code:: json
"app": {
"forceCoordsNA": false,
"install": {
enabled: true,
promote: false,
manifestPath: '../config/github.webmanifest'
},
"pwa": {
enable: true
}
}
Propriétés

.. line-block::

forceCoordsNA: true/false = force les coordonnées en Amérique du Nord
install: Object permettant de dire comment l'application sera installée.
install.enabled: true/false = Application installable ou non.
install.manifestPath: Identifie un chemin d'accès pour le manifest (info sur l'app).
Par défaut: 'manifest.webmanifest'
install.promote: true/false = Permet (Windows/Android) de faire afficher un message
incitant les utilisateurs a installer l'application
pwa: Object permettant de dire comment l'application sera mis en mémoire cache.
pwa.enabled: true/false = Identifie si l'application sera mis en mémoire cache.


***************
Analytics
***************
Expand Down
4 changes: 2 additions & 2 deletions docs/interactiveTour_config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Lorsqu'une certaine configuration est détectée par l'application, le bouton re
configuré un tour pour un outil X, le bouton de présentation apparaitra dans l'entête de l'outil.

Une configuration pour ne pas avoir de tour interactif en mode mobile est aussi disponible dans le fichier config.json:
"interactiveTourInMobile": true
"tourInMobile": true
par défaut les tours interactifs seront présents en mode mobile.


Expand Down Expand Up @@ -265,7 +265,7 @@ Je ne vois pas le bouton de mon tour apparaitre.
- Vérifier que le fichier interactiveTour.json est bien présent dans le dossier config de votre application.
- Vérifier que le nom de l'outil est bien exact
- Vérifier que la syntaxe du tour est bien présentée de cette façon: global: {...} ou nomGénériqueDeOutil:{...}
- Si vous êtes en mode mobile vérifier la configuration dans le fichier config.json: "introInteractiveTourInMobile": true
- Si vous êtes en mode mobile vérifier la configuration dans le fichier config.json: "tourInMobile": true
L'élément de mon tour n'est pas mis en surbrillance.
Solution:
Expand Down
2,363 changes: 1,367 additions & 996 deletions package-lock.json

Large diffs are not rendered by default.

35 changes: 33 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class AppComponent {
private themeClass = 'blue-theme';
public hasHeader = true;
public hasFooter = true;

private promptEvent: any;
constructor(
protected languageService: LanguageService,
private configService: ConfigService,
Expand All @@ -29,7 +29,7 @@ export class AppComponent {
private titleService: Title,
private metaService: Meta,
private messageService: MessageService,
private pwaService: PwaService // let there to be handled (based on configs: app.pwa.enabled)
private pwaService: PwaService
) {
this.authConfig = this.configService.getConfig('auth');

Expand All @@ -46,6 +46,10 @@ export class AppComponent {

this.hasFooter = this.configService.getConfig('hasFooter') === undefined ? false :
this.configService.getConfig('hasFooter');

this.setManifest();
this.installPrompt();
this.pwaService.checkForUpdates();
}

private readTitleConfig() {
Expand All @@ -57,6 +61,33 @@ export class AppComponent {
});
}

private setManifest() {
const appConfig = this.configService.getConfig('app');
if (appConfig?.install?.enabled) {
const manifestPath = appConfig.install.manifestPath || 'manifest.webmanifest';
document.querySelector('#igoManifestByConfig').setAttribute('href', manifestPath);
}
}

private installPrompt() {
const appConfig = this.configService.getConfig('app');
if (appConfig?.install?.enabled && appConfig?.install?.promote) {
if (userAgent.getOSName() !== 'iOS') {
window.addEventListener('beforeinstallprompt', (event: any) => {
event.preventDefault();
this.promptEvent = event;
window.addEventListener('click', () => {
setTimeout(() => {
this.promptEvent.prompt();
this.promptEvent = undefined;
}, 750);
}, { once: true });
}, { once: true });
}
}
}


private readThemeConfig() {
const theme = this.configService.getConfig('theme') || this.themeClass;
if (theme) {
Expand Down
50 changes: 12 additions & 38 deletions src/app/services/pwa.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { Platform } from '@angular/cdk/platform';
import { ConfigService, LanguageService } from '@igo2/core';
import { LanguageService } from '@igo2/core';
import { SwUpdate } from '@angular/service-worker';
import { interval } from 'rxjs';
import { ConfirmDialogService } from '@igo2/common';
Expand All @@ -10,21 +9,22 @@ import { skip, tap } from 'rxjs/operators';
providedIn: 'root'
})
export class PwaService {
promptEvent: any;
private confirmOpened: boolean = false;
constructor(
private platform: Platform,
public updates: SwUpdate,
public languageService: LanguageService,
private configService: ConfigService,
private updates: SwUpdate,
private languageService: LanguageService,
private confirmDialogService: ConfirmDialogService
) {
if (updates.isEnabled) {
this.checkForUpdates();
this.initPwaPrompt();
this.handleVersionUpdates();
}
}

checkForUpdates() {
if (this.updates.isEnabled) {
interval(60 * 1000 * 2).pipe(skip(1)).subscribe(async () => {
try {
const updateFound = await updates.checkForUpdate();
const updateFound = await this.updates.checkForUpdate();
console.log(updateFound ? 'A new version is available.' : 'Already on the latest version.');
} catch (err) {
console.error('Failed to check for updates:', err);
Expand Down Expand Up @@ -55,7 +55,7 @@ export class PwaService {
});
}

private checkForUpdates(): void {
private handleVersionUpdates(): void {
this.updates.versionUpdates.subscribe(evt => {
switch (evt.type) {
case 'VERSION_DETECTED':
Expand All @@ -64,38 +64,12 @@ export class PwaService {
case 'VERSION_READY':
console.log(`Current app version: ${evt.currentVersion.hash}`);
console.log(`New app version ready for use: ${evt.latestVersion.hash}`);
this.modalUpdatePWA();
this.modalUpdatePWA();
break;
case 'VERSION_INSTALLATION_FAILED':
console.error(`Failed to install app version '${evt.version.hash}': ${evt.error}`);
break;
}
});
}

private async initPwaPrompt() {
if (
this.configService.getConfig('app') &&
this.configService.getConfig('app.pwa') &&
this.configService.getConfig('app.pwa.enabled') &&
this.configService.getConfig('app.pwa.promote')) {
if (!this.platform.IOS) {
window.addEventListener('beforeinstallprompt', (event: any) => {
event.preventDefault();
this.promptEvent = event;
this.listenToUserAction();
}, { once: true });
}
}
}

private listenToUserAction() {
window.addEventListener('click', () => { this.showPrompt(); }, { once: true });
}

private async showPrompt() {
this.promptEvent.prompt();
const outcome = await this.promptEvent.userChoice;
this.promptEvent = undefined;
}
}
62 changes: 62 additions & 0 deletions src/config/github.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"id": "igo2DemoGitHub",
"name": "Demo Github - IGO2",
"short_name": "Demo Github - IGO",
"description": "Demo Github - IGO2 installable",
"theme_color": "#1976d2",
"background_color": "#fafafa",
"display": "standalone",
"scope": "../",
"start_url": "../",
"orientation": "any",
"icons": [
{
"src": "../assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "../assets/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
}
]
}
17 changes: 8 additions & 9 deletions src/environments/environment.github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,17 @@ import {
CommonVectorStyleOptions
} from '@igo2/geo';

import { AppOptions, InteractiveTourConfigOptions } from './environnement.interface';
interface Environment {
production: boolean;
igo: {
app: {
forceCoordsNA: boolean;
pwa?: {
enabled?: boolean;
promote?: boolean;
}
};
app: AppOptions,
catalog?: CatalogServiceOptions;
importExport?: ImportExportServiceOptions;
language?: LanguageOptions;
searchSources?: { [key: string]: SearchSourceOptions };
projections?: Projection[];
interactiveTour?: { tourInMobile: boolean; pathToConfigFile: string };
interactiveTour?: InteractiveTourConfigOptions;
depot?: { url: string; trainingGuides?: string[]; };
queryOverlayStyle?: {
base?: CommonVectorStyleOptions,
Expand All @@ -42,9 +37,13 @@ export const environment: Environment = {
igo: {
app: {
forceCoordsNA: false,
install: {
enabled: true,
promote: true,
manifestPath: './config/github.webmanifest'
},
pwa: {
enabled: false,
promote: false
}
},
catalog: {
Expand Down
17 changes: 8 additions & 9 deletions src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,19 @@ import {
CommonVectorStyleOptions
} from '@igo2/geo';

import { AppOptions, InteractiveTourConfigOptions } from './environnement.interface';

export interface Environment {
production: boolean;
igo: {
app: {
forceCoordsNA: boolean;
pwa?: {
enabled?: boolean;
promote?: boolean;
}
};
app: AppOptions;
importExport?: ImportExportServiceOptions;
language?: LanguageOptions;
searchSources?: { [key: string]: SearchSourceOptions };
optionsApi?: OptionsApiOptions;
projections?: Projection[];
spatialFilter?: SpatialFilterOptions;
interactiveTour?: { tourInMobile: boolean; pathToConfigFile: string };
interactiveTour?: InteractiveTourConfigOptions;
depot?: { url: string; trainingGuides?: string[]; };
queryOverlayStyle?: {
base?: CommonVectorStyleOptions,
Expand All @@ -44,9 +40,12 @@ export const environment: Environment = {
igo: {
app: {
forceCoordsNA: true,
pwa: {
install: {
enabled: false,
promote: false
},
pwa: {
enabled: false,
}
},
importExport: {
Expand Down
5 changes: 4 additions & 1 deletion src/environments/environment.pwa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ if (!prodEnv.igo.app.pwa) {
prodEnv.igo.app.pwa = {};
}
prodEnv.igo.app.pwa.enabled = true;
prodEnv.igo.app.pwa.promote = true;
prodEnv.igo.app.install.enabled = true;
prodEnv.igo.app.install.promote = true;
prodEnv.igo.app.install.manifestPath = undefined;

export const environment = prodEnv;
Loading

0 comments on commit 13b76fe

Please sign in to comment.