Skip to content

Commit

Permalink
Feat: Make the app a PWA (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
RikudouSage committed Apr 6, 2024
1 parent 3f58996 commit 5861e25
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 34 deletions.
10 changes: 7 additions & 3 deletions angular.json
Expand Up @@ -31,7 +31,8 @@
"input": "src/assets/favicon",
"glob": "*",
"output": "."
}
},
"src/manifest.webmanifest"
],
"styles": [
"src/styles.scss"
Expand All @@ -57,7 +58,9 @@
"maximumError": "50kb"
}
],
"outputHashing": "all"
"outputHashing": "all",
"serviceWorker": "ngsw-config.json",
"sourceMap": true
},
"development": {
"optimization": false,
Expand Down Expand Up @@ -106,7 +109,8 @@
"input": "src/assets/favicon",
"output": ".",
"glob": "*"
}
},
"src/manifest.webmanifest"
],
"styles": [
"src/styles.scss"
Expand Down
32 changes: 32 additions & 0 deletions ngsw-config.json
@@ -0,0 +1,32 @@
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js",
"/*.png",
"/*.svg"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/media/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
]
}
}
]
}
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -20,6 +20,7 @@
"@angular/platform-browser-dynamic": "^17.1.0",
"@angular/platform-server": "^17.1.0",
"@angular/router": "^17.1.0",
"@angular/service-worker": "^17.1.0",
"@angular/ssr": "^17.1.2",
"@aws-sdk/client-s3": "^3.529.1",
"@fortawesome/angular-fontawesome": "0.14",
Expand Down Expand Up @@ -60,4 +61,4 @@
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.3.2"
}
}
}
27 changes: 20 additions & 7 deletions src/app/app.component.ts
@@ -1,12 +1,11 @@
import {Component, Inject, OnInit, PLATFORM_ID, ViewContainerRef} from '@angular/core';
import {Component, OnInit, signal, ViewContainerRef} from '@angular/core';
import {RouterOutlet} from '@angular/router';
import {TopMenuComponent} from "./components/top-menu/top-menu.component";
import {AiHorde} from "./services/ai-horde.service";
import {AuthManagerService} from "./services/auth-manager.service";
import {toPromise} from "./helper/resolvable";
import {DataStorageManagerService} from "./services/data-storage-manager.service";
import {isPlatformBrowser} from "@angular/common";
import {globalAppView} from "./global-app-view";
import {SwUpdate} from "@angular/service-worker";

@Component({
selector: 'app-root',
Expand All @@ -16,20 +15,34 @@ import {globalAppView} from "./global-app-view";
styleUrl: './app.component.scss'
})
export class AppComponent implements OnInit {
private readonly isBrowser: boolean;
private updateChecked = signal(false);
private updateAvailable = signal(false);

constructor(
private readonly aiHorde: AiHorde,
private readonly authManager: AuthManagerService,
private readonly storageManager: DataStorageManagerService,
private readonly updates: SwUpdate,
view: ViewContainerRef,
@Inject(PLATFORM_ID) platformId: string,
) {
this.isBrowser = isPlatformBrowser(platformId);
globalAppView.set(view);
}

public async ngOnInit(): Promise<void> {
if (this.updates.isEnabled) {
this.updates.versionUpdates.subscribe(event => {
if (this.updateChecked()) {
return;
}
if (event.type === 'VERSION_READY') {
this.updateAvailable.set(true);
window.location.reload();
}
});

await this.updates.checkForUpdate();
this.updateChecked.set(true);
}

if (this.authManager.apiKey() !== this.authManager.anonymousApiKey) {
const user = await toPromise(this.aiHorde.currentUser());
if (!user.success) {
Expand Down
5 changes: 5 additions & 0 deletions src/app/app.config.ts
Expand Up @@ -14,6 +14,7 @@ import {S3DataStorage} from "./services/image-storage/s3.data-storage";
import {Credentials} from "./types/credentials/credentials";
import {GoogleDriveDataStorage} from "./services/image-storage/google-drive.data-storage";
import {DropboxDataStorage} from "./services/image-storage/dropbox.data-storage";
import {provideServiceWorker} from '@angular/service-worker';

export const DATA_STORAGE = new InjectionToken<DataStorage<Credentials>>('ImageStorage');

Expand Down Expand Up @@ -49,5 +50,9 @@ export const appConfig: ApplicationConfig = {
{useClass: S3DataStorage, provide: DATA_STORAGE, multi: true},
{useClass: GoogleDriveDataStorage, provide: DATA_STORAGE, multi: true},
{useClass: DropboxDataStorage, provide: DATA_STORAGE, multi: true},
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000'
}),
],
};
18 changes: 0 additions & 18 deletions src/assets/favicon/site.webmanifest

This file was deleted.

Binary file added src/assets/icons/icon-128x128.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-144x144.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-152x152.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-192x192.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-384x384.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-512x512.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-72x72.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/icons/icon-96x96.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 8 additions & 5 deletions src/index.html
Expand Up @@ -5,24 +5,27 @@
<title>HordeNG</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&amp;display=swap" rel="stylesheet">

<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<link rel="manifest" href="manifest.webmanifest">

<meta name="msapplication-TileColor" content="#2d89ef">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#409eff">

<script src="/assets/runtime-variables.js"></script>
<script src="https://apis.google.com/js/api.js"></script>
<script src="https://accounts.google.com/gsi/client"></script>
</head>
<body>
<app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
</html>
59 changes: 59 additions & 0 deletions src/manifest.webmanifest
@@ -0,0 +1,59 @@
{
"name": "HordeNG",
"short_name": "HordeNG",
"theme_color": "#409eff",
"background_color": "#1c1b22",
"display": "standalone",
"scope": "./",
"start_url": "./",
"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"
}
]
}
8 changes: 8 additions & 0 deletions yarn.lock
Expand Up @@ -222,6 +222,13 @@
dependencies:
tslib "^2.3.0"

"@angular/service-worker@^17.1.0":
version "17.3.3"
resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-17.3.3.tgz#cd8c83793771e93e0a98192428d956d92e9cb487"
integrity sha512-ZS7MPNPdvIoNKuPfK2pukKiyn+OXVMUALBjSH6k2ayiKxhMiNBCybA4KkQf6DZ9NIlKiGoBc46wf7FZybWAYbQ==
dependencies:
tslib "^2.3.0"

"@angular/ssr@^17.1.2":
version "17.3.3"
resolved "https://registry.yarnpkg.com/@angular/ssr/-/ssr-17.3.3.tgz#2d559b75d1adaec66f40cd378b83de77fd9aba5e"
Expand Down Expand Up @@ -7698,6 +7705,7 @@ wildcard@^2.0.0:
integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
name wrap-ansi-cjs
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand Down

0 comments on commit 5861e25

Please sign in to comment.