Use OpenSlides as Progressive Web App (PWA).

This commit is contained in:
Emanuel Schütze 2019-01-16 14:04:15 +01:00
parent 460b3dcac9
commit f83f3fed46
18 changed files with 156 additions and 11 deletions

View File

@ -22,8 +22,14 @@
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss", "node_modules/material-design-icons/iconfont/material-icons.css"],
"assets": [
"src/assets",
"src/manifest.json"
],
"styles": [
"src/styles.scss",
"node_modules/material-design-icons/iconfont/material-icons.css"
],
"scripts": [
"node_modules/tinymce/tinymce.min.js",
"node_modules/tinymce/themes/modern/theme.js",
@ -58,7 +64,8 @@
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
"buildOptimizer": true,
"serviceWorker": true
}
}
},
@ -86,11 +93,16 @@
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": ["src/styles.scss"],
"styles": [
"src/styles.scss"
],
"scripts": [
"node_modules/tinymce/tinymce.min.js"
],
"assets": ["src/favicon.ico", "src/assets"]
"assets": [
"src/assets",
"src/manifest.json"
]
}
},
"lint": {
@ -98,7 +110,9 @@
"options": {
"tsConfig": "src/tsconfig.spec.json",
"format": "stylish",
"exclude": ["**/node_modules/**"]
"exclude": [
"**/node_modules/**"
]
}
}
}
@ -123,7 +137,9 @@
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": ["**/node_modules/**"]
"exclude": [
"**/node_modules/**"
]
}
}
}

26
client/ngsw-config.json Normal file
View File

@ -0,0 +1,26 @@
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.png",
"/index.html",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
]
}
}
]
}

View File

@ -32,7 +32,9 @@
"@angular/material": "^7.1.0",
"@angular/platform-browser": "^7.1.1",
"@angular/platform-browser-dynamic": "^7.1.1",
"@angular/pwa": "^0.12.1",
"@angular/router": "^7.1.1",
"@angular/service-worker": "^7.1.1",
"@ngx-pwa/local-storage": "^7.2.0",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",

View File

@ -16,6 +16,10 @@ import { PruningTranslationLoader } from './core/pruning-loader';
import { LoginModule } from './site/login/login.module';
import { AppLoadService } from './core/services/app-load.service';
// PWA
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
/**
* For the translation module. Loads a Custom 'translation loader' and provides it as loader.
* @param http Just the HttpClient to load stuff
@ -55,7 +59,8 @@ export function AppLoaderFactory(appLoadService: AppLoadService): () => Promise<
AppRoutingModule,
CoreModule,
LoginModule,
PapaParseModule
PapaParseModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
],
providers: [{ provide: APP_INITIALIZER, useFactory: AppLoaderFactory, deps: [AppLoadService], multi: true }],
bootstrap: [AppComponent]

View File

@ -0,0 +1,17 @@
import { TestBed } from '@angular/core/testing';
import { PwaService } from './pwa.service';
import { E2EImportsModule } from 'e2e-imports.module';
describe('PwaService', () => {
beforeEach(() =>
TestBed.configureTestingModule({
imports: [E2EImportsModule]
})
);
it('should be created', () => {
const service: PwaService = TestBed.get(PwaService);
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
/**
* Service for Progressive Web App options
*/
@Injectable({
providedIn: 'root'
})
export class PwaService {
public promptEvent;
public constructor(swUpdate: SwUpdate) {
// check if an update is available
swUpdate.available.subscribe(event => {
// TODO: ask user if app should update now
window.location.reload();
});
// install button
window.addEventListener('beforeinstallprompt', event => {
this.promptEvent = event;
});
}
}

View File

@ -48,7 +48,7 @@ export class ViewportService {
*/
public checkForChange(): void {
this.breakpointObserver
.observe([Breakpoints.Small, Breakpoints.HandsetPortrait])
.observe([Breakpoints.Handset, '(min-width: 600px) and (max-width: 899.99px)'])
.subscribe((state: BreakpointState) => {
if (state.matches) {
this.isMobile = true;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

View File

@ -3,15 +3,18 @@
<head>
<meta charset="utf-8">
<title>OpenSlides 3</title>
<title>OpenSlides</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="assets/img/favicon.png">
<link rel="manifest" href="manifest.json" />
<meta name="theme-color" content="#317796">
</head>
<body>
<os-root></os-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
</html>

51
client/src/manifest.json Normal file
View File

@ -0,0 +1,51 @@
{
"name": "OpenSlides",
"short_name": "OpenSlides",
"theme_color": "#317796",
"background_color": "#317796",
"display": "standalone",
"scope": "/",
"start_url": "/",
"icons": [
{
"src": "/assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/assets/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/assets/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/assets/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/assets/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "/assets/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/assets/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}