Prompt refresh when build UUID changes (#24)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
Garrett Mills 2020-10-21 10:25:41 -05:00
parent a686ffd498
commit a72fc72c83
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
8 changed files with 9774 additions and 3 deletions

View File

@ -18,6 +18,7 @@
"@angular/forms": "~10.1.5", "@angular/forms": "~10.1.5",
"@angular/platform-browser": "~10.1.5", "@angular/platform-browser": "~10.1.5",
"@angular/platform-browser-dynamic": "~10.1.5", "@angular/platform-browser-dynamic": "~10.1.5",
"@angular/pwa": "^0.1001.7",
"@angular/router": "~10.1.5", "@angular/router": "~10.1.5",
"@circlon/angular-tree-component": "^10.0.0", "@circlon/angular-tree-component": "^10.0.0",
"@fortawesome/fontawesome-free": "^5.15.1", "@fortawesome/fontawesome-free": "^5.15.1",

View File

@ -1,6 +1,13 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild, HostListener, Host} from '@angular/core'; import {AfterViewInit, Component, ElementRef, OnInit, ViewChild, HostListener, Host} from '@angular/core';
import {AlertController, ModalController, Platform, PopoverController, LoadingController} from '@ionic/angular'; import {
AlertController,
ModalController,
Platform,
PopoverController,
LoadingController,
ToastController
} from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx';
import { ApiService } from './service/api.service'; import { ApiService } from './service/api.service';
@ -70,7 +77,8 @@ export class AppComponent implements OnInit {
public darkMode = false; public darkMode = false;
protected loader?: any; protected loader?: any;
protected hasSearchOpen = false; protected hasSearchOpen = false;
protected versionInterval?: any;
protected showedNewVersionAlert = false;
protected initialized$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); protected initialized$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
constructor( constructor(
@ -85,6 +93,7 @@ export class AppComponent implements OnInit {
protected session: SessionService, protected session: SessionService,
protected loading: LoadingController, protected loading: LoadingController,
protected navService: NavigationService, protected navService: NavigationService,
protected toasts: ToastController,
) { ) {
this.initializeApp(); this.initializeApp();
} }
@ -96,9 +105,37 @@ export class AppComponent implements OnInit {
this.loader.dismiss(); this.loader.dismiss();
this.menuTree.treeModel.expandAll(); this.menuTree.treeModel.expandAll();
}, 10); }, 10);
if ( !this.versionInterval ) {
this.versionInterval = setInterval(() => {
this.checkNewVersion();
}, 1000 * 60 * 5); // Check for new version every 5 mins
}
}); });
} }
async checkNewVersion() {
if ( !this.showedNewVersionAlert && await this.session.newVersionAvailable() ) {
const toast = await this.toasts.create({
cssClass: 'compat-toast-container',
header: 'Update Available',
message: `A new version of ${this.appName} is available. Please refresh to update.`,
buttons: [
{
side: 'end',
text: 'Refresh',
handler: () => {
window.location.reload();
},
},
],
});
this.showedNewVersionAlert = true;
await toast.present();
}
}
ngOnInit() { ngOnInit() {
if ( !this.initialized$.getValue() ) { if ( !this.initialized$.getValue() ) {
this.navService.sidebarRefresh$.subscribe(([_, quiet]) => { this.navService.sidebarRefresh$.subscribe(([_, quiet]) => {
@ -376,7 +413,6 @@ export class AppComponent implements OnInit {
} }
async initializeApp() { async initializeApp() {
console.log('session', this);
this.loader = await this.loading.create({ this.loader = await this.loading.create({
message: 'Starting up...', message: 'Starting up...',
cssClass: 'noded-loading-mask', cssClass: 'noded-loading-mask',

View File

@ -10,6 +10,7 @@ import ApiResponse from '../structures/ApiResponse';
export class ApiService { export class ApiService {
protected baseEndpoint: string = environment.backendBase; protected baseEndpoint: string = environment.backendBase;
protected statUrl: string = environment.statUrl; protected statUrl: string = environment.statUrl;
protected versionUrl: string = environment.versionUrl;
constructor( constructor(
protected http: HttpClient, protected http: HttpClient,
@ -31,6 +32,17 @@ export class ApiService {
return this._request(this.statUrl); return this._request(this.statUrl);
} }
public version(): Promise<string> {
return new Promise((res, rej) => {
this._request(this.versionUrl).subscribe({
next: result => {
res(result.data.text.trim());
},
error: rej,
});
});
}
protected _request(endpoint, params = {}, method: 'get'|'post' = 'get'): Observable<ApiResponse> { protected _request(endpoint, params = {}, method: 'get'|'post' = 'get'): Observable<ApiResponse> {
return new Observable<ApiResponse>(sub => { return new Observable<ApiResponse>(sub => {
let data: any = {} let data: any = {}

View File

@ -11,6 +11,7 @@ export class SessionService {
protected data: any = {}; protected data: any = {};
protected saveTriggered = false; protected saveTriggered = false;
protected saving = false; protected saving = false;
protected loadedVersion = '';
protected privTriggerSave = debounce(() => { protected privTriggerSave = debounce(() => {
if ( this.saving ) { if ( this.saving ) {
this.triggerSave(); this.triggerSave();
@ -26,11 +27,21 @@ export class SessionService {
this.privTriggerSave(); this.privTriggerSave();
} }
public get version() {
return this.loadedVersion;
}
constructor( constructor(
protected readonly api: ApiService, protected readonly api: ApiService,
) { } ) { }
async newVersionAvailable() {
return (await this.api.version()) !== this.loadedVersion;
}
async stat() { async stat() {
this.loadedVersion = await this.api.version();
return new Promise((res, rej) => { return new Promise((res, rej) => {
this.api.stat().subscribe(response => { this.api.stat().subscribe(response => {
res(response.data); res(response.data);

View File

@ -2,4 +2,5 @@ export const environment = {
production: true, production: true,
backendBase: '/api/v1', backendBase: '/api/v1',
statUrl: '/stat', statUrl: '/stat',
versionUrl: '/i/version.html',
}; };

View File

@ -6,6 +6,7 @@ export const environment = {
production: false, production: false,
backendBase: '/link_api/api/v1', backendBase: '/link_api/api/v1',
statUrl: '/link_api/stat', statUrl: '/link_api/stat',
versionUrl: '/link_api/assets/version.html',
}; };
/* /*

View File

@ -77,3 +77,12 @@ div.picker-wrapper {
hr { hr {
background: darkgray; background: darkgray;
} }
.compat-toast-container {
color: white !important;
}
.compat-toast-container::part(header) {
font-size: 1.2em;
font-weight: bold;
}

9700
yarn.lock Normal file

File diff suppressed because it is too large Load Diff