Skip to content

Commit

Permalink
Add update notification popup
Browse files Browse the repository at this point in the history
  • Loading branch information
claabs committed Mar 5, 2024
1 parent 5d5bc15 commit c55cce4
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 9 deletions.
42 changes: 36 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"scripts": {
"lint": "tsc --noEmit && eslint .",
"build": "rimraf dist && tsc && rollup -c rollup.config.js && npm run analyze -- --exclude dist",
"start:build": "web-dev-server --root-dir dist --app-index index.html --open",
"start:build": "web-dev-server --root-dir dist --app-index index.html",
"analyze": "cem analyze --litelement",
"start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
"update-points": "vite-node update-rankings.ts"
Expand All @@ -29,6 +29,7 @@
"@vaadin/horizontal-layout": "^24.0.2",
"@vaadin/icon": "^24.0.3",
"@vaadin/icons": "^24.0.3",
"@vaadin/notification": "24.0",
"@vaadin/number-field": "^24.0.2",
"@vaadin/progress-bar": "24.0",
"@vaadin/select": "~24.0",
Expand All @@ -39,7 +40,8 @@
"@vaadin/vertical-layout": "^24.0.2",
"color-scales": "^3.0.2",
"immer": "^10.0.1",
"lit": "^2.0.2"
"lit": "^2.0.2",
"workbox-window": "^6.6.0"
},
"devDependencies": {
"@babel/preset-env": "^7.16.4",
Expand Down
32 changes: 31 additions & 1 deletion src/cs-buchholz-simulator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit';
import { customElement, state, query, property } from 'lit/decorators.js';
import type { TabSheetSelectedChangedEvent } from '@vaadin/tabsheet';
import { Workbox } from 'workbox-window';
import { MatchupProbability, eventPresets } from './settings.js';
import masterRating from './hltv-team-points.js';
import { generateEasyProbabilities, SimulationSettings } from './simulator.js';
Expand All @@ -9,6 +10,7 @@ import './matchup-table.js';
import './team-ratings.js';
import './team-ratings-chart.js';
import './simulation-result-viewer.js';
import './refresh-notification.js';
import '@vaadin/tabs/theme/lumo/vaadin-tabs';
import '@vaadin/tabsheet/theme/lumo/vaadin-tabsheet';
import '@vaadin/split-layout/theme/lumo/vaadin-split-layout';
Expand All @@ -20,6 +22,7 @@ import type { SimulationResultViewer } from './simulation-result-viewer.js';
import type { TeamRatingsChart } from './team-ratings-chart.js';
import type { TeamRatingDetails } from './team-ratings.js';
import type { TeamListSettings } from './team-list.js';
import type { RefreshNotification } from './refresh-notification.js';

const filterTeamRating = (seedOrder: string[]): Record<string, number> => {
const teamRating: Record<string, number> = {};
Expand Down Expand Up @@ -76,6 +79,13 @@ export class CsBuchholzSimulato extends LitElement {
@query('team-ratings-chart')
private teamRatingsChart: TeamRatingsChart;

@query('refresh-notification')
private refreshNotification: RefreshNotification;

private workbox?: Workbox;

private registration?: ServiceWorkerRegistration;

private matchupTableCustomized = false;

private simSettings: SimulationSettings = { qualWins: 3, elimLosses: 3 };
Expand Down Expand Up @@ -166,6 +176,21 @@ export class CsBuchholzSimulato extends LitElement {
super.connectedCallback();
window.addEventListener('resize', () => this.updateMobileView());
this.updateMobileView();

if ('serviceWorker' in navigator) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.addEventListener('load', this.waitForServiceWorkerUpdate.bind(this));
}
}

private openRefreshNotification() {
this.refreshNotification.open(this.workbox, this.registration);
}

private async waitForServiceWorkerUpdate(): Promise<void> {
this.workbox = new Workbox('./sw.js');
this.workbox.addEventListener('waiting', this.openRefreshNotification.bind(this));
this.registration = await this.workbox.register();
}

override render() {
Expand Down Expand Up @@ -280,6 +305,11 @@ export class CsBuchholzSimulato extends LitElement {
</detail-content>
</vaadin-split-layout>`;

return html` <main>${this.isMobileView ? mobileLayoutTemplate : desktopLayoutTemplate}</main> `;
return html`
<main>
<refresh-notification></refresh-notification>
${this.isMobileView ? mobileLayoutTemplate : desktopLayoutTemplate}
</main>
`;
}
}
83 changes: 83 additions & 0 deletions src/refresh-notification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { LitElement, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import '@vaadin/horizontal-layout/theme/lumo/vaadin-horizontal-layout.js';
import '@vaadin/button/theme/lumo/vaadin-button.js';
import '@vaadin/notification/theme/lumo/vaadin-notification.js';
import '@vaadin/icon';
import '@vaadin/icons';
import { notificationRenderer, NotificationLitRenderer } from '@vaadin/notification/lit.js';
import type { NotificationOpenedChangedEvent } from '@vaadin/notification';
import { Workbox, messageSW } from 'workbox-window';

@customElement('refresh-notification')
export class RefreshNotification extends LitElement {
private workbox: Workbox | undefined;

private registration: ServiceWorkerRegistration | undefined;

@property({ type: Boolean })
private notificationOpened = false;

public open(workbox?: Workbox, registration?: ServiceWorkerRegistration) {
console.log('opening notification', workbox, registration);
this.notificationOpened = true;
this.workbox = workbox;
this.registration = registration;
}

public close() {
this.notificationOpened = false;
this.workbox = undefined;
this.registration = undefined;
}

private async refreshPage() {
console.log('Refreshing page');
// reload the page as soon as the previously waiting service worker has taken control.
if (this.workbox) {
this.workbox.addEventListener('controlling', () => {
window.location.reload();
});

if (this.registration?.waiting) {
await messageSW(this.registration.waiting, { type: 'SKIP_WAITING' });
}
}
}

private renderNotification: NotificationLitRenderer = () =>
html`
<vaadin-horizontal-layout theme="spacing" style="align-items: center;">
<div>New version available! OK to reload?</div>
<vaadin-button
theme="primary"
style="margin-left: var(--lumo-space-xl);"
@click=${this.refreshPage}
>
Reload
</vaadin-button>
<vaadin-button theme="secondary-inline icon" @click=${this.close} aria-label="Close">
<vaadin-icon icon="vaadin:close" style="color: white"></vaadin-icon>
</vaadin-button>
</vaadin-horizontal-layout>
`;

override render() {
return html`<vaadin-notification
theme="contrast"
duration="0"
position="bottom-center"
.opened="${this.notificationOpened}"
@opened-changed="${(e: NotificationOpenedChangedEvent) => {
this.notificationOpened = e.detail.value;
}}"
${notificationRenderer(this.renderNotification, [])}
></vaadin-notification>`;
}
}

declare global {
interface HTMLElementTagNameMap {
'refresh-notification': RefreshNotification;
}
}

0 comments on commit c55cce4

Please sign in to comment.