diff --git a/client/angular.json b/client/angular.json
index dee0fe99b..3251ca8bf 100644
--- a/client/angular.json
+++ b/client/angular.json
@@ -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/**"
+ ]
}
}
}
diff --git a/client/ngsw-config.json b/client/ngsw-config.json
new file mode 100644
index 000000000..818b90e44
--- /dev/null
+++ b/client/ngsw-config.json
@@ -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/**"
+ ]
+ }
+ }
+ ]
+}
diff --git a/client/package.json b/client/package.json
index 2bbc8168e..54cae7dc5 100644
--- a/client/package.json
+++ b/client/package.json
@@ -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",
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index 8b7e40f66..e7f953e2e 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -1,3 +1,3 @@
-
\ No newline at end of file
+
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index b7c5bc91f..631b827e3 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -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]
diff --git a/client/src/app/core/services/pwa.service.spec.ts b/client/src/app/core/services/pwa.service.spec.ts
new file mode 100644
index 000000000..6faa381f6
--- /dev/null
+++ b/client/src/app/core/services/pwa.service.spec.ts
@@ -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();
+ });
+});
diff --git a/client/src/app/core/services/pwa.service.ts b/client/src/app/core/services/pwa.service.ts
new file mode 100644
index 000000000..0b5ffe0fc
--- /dev/null
+++ b/client/src/app/core/services/pwa.service.ts
@@ -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;
+ });
+ }
+}
diff --git a/client/src/app/core/services/viewport.service.ts b/client/src/app/core/services/viewport.service.ts
index b26bda5bb..a00f7f719 100644
--- a/client/src/app/core/services/viewport.service.ts
+++ b/client/src/app/core/services/viewport.service.ts
@@ -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;
diff --git a/client/src/assets/icons/icon-128x128.png b/client/src/assets/icons/icon-128x128.png
new file mode 100644
index 000000000..9f9241f0b
Binary files /dev/null and b/client/src/assets/icons/icon-128x128.png differ
diff --git a/client/src/assets/icons/icon-144x144.png b/client/src/assets/icons/icon-144x144.png
new file mode 100644
index 000000000..4a5f8c163
Binary files /dev/null and b/client/src/assets/icons/icon-144x144.png differ
diff --git a/client/src/assets/icons/icon-152x152.png b/client/src/assets/icons/icon-152x152.png
new file mode 100644
index 000000000..34a1a8d64
Binary files /dev/null and b/client/src/assets/icons/icon-152x152.png differ
diff --git a/client/src/assets/icons/icon-192x192.png b/client/src/assets/icons/icon-192x192.png
new file mode 100644
index 000000000..9172e5dd2
Binary files /dev/null and b/client/src/assets/icons/icon-192x192.png differ
diff --git a/client/src/assets/icons/icon-384x384.png b/client/src/assets/icons/icon-384x384.png
new file mode 100644
index 000000000..e54e8d3ea
Binary files /dev/null and b/client/src/assets/icons/icon-384x384.png differ
diff --git a/client/src/assets/icons/icon-512x512.png b/client/src/assets/icons/icon-512x512.png
new file mode 100644
index 000000000..51ee297df
Binary files /dev/null and b/client/src/assets/icons/icon-512x512.png differ
diff --git a/client/src/assets/icons/icon-72x72.png b/client/src/assets/icons/icon-72x72.png
new file mode 100644
index 000000000..2814a3f30
Binary files /dev/null and b/client/src/assets/icons/icon-72x72.png differ
diff --git a/client/src/assets/icons/icon-96x96.png b/client/src/assets/icons/icon-96x96.png
new file mode 100644
index 000000000..d271025c4
Binary files /dev/null and b/client/src/assets/icons/icon-96x96.png differ
diff --git a/client/src/index.html b/client/src/index.html
index 2677afdef..ee05d1189 100644
--- a/client/src/index.html
+++ b/client/src/index.html
@@ -3,15 +3,18 @@
- OpenSlides 3
+ OpenSlides
+
+
+