aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/package.json11
-rw-r--r--FrontEnd/src/index.tsx1
-rw-r--r--FrontEnd/src/service-worker.tsx (renamed from FrontEnd/src/service-worker.txt)0
-rw-r--r--FrontEnd/src/sw.ts66
-rw-r--r--FrontEnd/src/views/timeline-common/ConnectionStatusBadge.tsx2
-rw-r--r--FrontEnd/tsconfig.json5
-rw-r--r--FrontEnd/vite.config.js13
7 files changed, 90 insertions, 8 deletions
diff --git a/FrontEnd/package.json b/FrontEnd/package.json
index 38dd85ff..2ae7cae1 100644
--- a/FrontEnd/package.json
+++ b/FrontEnd/package.json
@@ -30,7 +30,13 @@
"regenerator-runtime": "^0.13.7",
"remarkable": "^2.0.1",
"rxjs": "^7.1.0",
- "xregexp": "^5.0.2"
+ "xregexp": "^5.0.2",
+ "workbox-cacheable-response": "^6.1.5",
+ "workbox-expiration": "^6.1.2",
+ "workbox-precaching": "^6.1.0",
+ "workbox-routing": "^6.1.5",
+ "workbox-strategies": "^6.1.0",
+ "workbox-window": "^6.1.1"
},
"scripts": {
"start": "vite",
@@ -60,6 +66,7 @@
"eslint-plugin-react-hooks": "^4.2.0",
"prettier": "^2.3.1",
"typescript": "^4.3.2",
- "vite": "^2.3.7"
+ "vite": "^2.3.7",
+ "vite-plugin-pwa": "^0.8.1"
}
}
diff --git a/FrontEnd/src/index.tsx b/FrontEnd/src/index.tsx
index 83c25792..28034601 100644
--- a/FrontEnd/src/index.tsx
+++ b/FrontEnd/src/index.tsx
@@ -13,6 +13,7 @@ import "./index.css";
import "./i18n";
import "./palette";
+import "./service-worker";
import App from "./App";
diff --git a/FrontEnd/src/service-worker.txt b/FrontEnd/src/service-worker.tsx
index ea8dfc32..ea8dfc32 100644
--- a/FrontEnd/src/service-worker.txt
+++ b/FrontEnd/src/service-worker.tsx
diff --git a/FrontEnd/src/sw.ts b/FrontEnd/src/sw.ts
new file mode 100644
index 00000000..0130e345
--- /dev/null
+++ b/FrontEnd/src/sw.ts
@@ -0,0 +1,66 @@
+/// <reference no-default-lib="true"/>
+/// <reference lib="esnext" />
+/// <reference lib="webworker" />
+
+import { precacheAndRoute, matchPrecache } from "workbox-precaching";
+import { registerRoute, setDefaultHandler } from "workbox-routing";
+import {
+ NetworkFirst,
+ NetworkOnly,
+ StaleWhileRevalidate,
+} from "workbox-strategies";
+import { CacheableResponsePlugin } from "workbox-cacheable-response";
+import { ExpirationPlugin } from "workbox-expiration";
+
+declare let self: ServiceWorkerGlobalScope;
+
+self.addEventListener("message", (event) => {
+ if (event.data && (event.data as { type: string }).type === "SKIP_WAITING") {
+ void self.skipWaiting();
+ }
+});
+
+precacheAndRoute(self.__WB_MANIFEST);
+
+const networkOnly = new NetworkOnly();
+
+registerRoute(new RegExp("/swagger/?.*"), new NetworkOnly());
+
+registerRoute(new RegExp("/api/token/?.*"), new NetworkOnly());
+registerRoute(new RegExp("/api/search/?.*"), new NetworkOnly());
+
+registerRoute(
+ new RegExp("/api/users/.+/avatar"),
+ new StaleWhileRevalidate({
+ cacheName: "avatars",
+ plugins: [
+ new CacheableResponsePlugin({
+ statuses: [200],
+ }),
+ new ExpirationPlugin({
+ maxAgeSeconds: 60 * 60 * 24 * 30 * 3, // 3 months
+ }),
+ ],
+ })
+);
+
+registerRoute(
+ new RegExp("/api/?.*"),
+ new NetworkFirst({
+ plugins: [
+ new CacheableResponsePlugin({
+ statuses: [200],
+ }),
+ ],
+ })
+);
+
+setDefaultHandler((options) => {
+ const { request } = options;
+
+ if (request instanceof Request && request.destination === "document")
+ return matchPrecache("/index.html").then((r) =>
+ r == null ? Response.error() : r
+ );
+ else return networkOnly.handle(options);
+});
diff --git a/FrontEnd/src/views/timeline-common/ConnectionStatusBadge.tsx b/FrontEnd/src/views/timeline-common/ConnectionStatusBadge.tsx
index 1b9d6d2a..df43d8d2 100644
--- a/FrontEnd/src/views/timeline-common/ConnectionStatusBadge.tsx
+++ b/FrontEnd/src/views/timeline-common/ConnectionStatusBadge.tsx
@@ -1,6 +1,6 @@
import React from "react";
import classnames from "classnames";
-import { HubConnectionState } from "srcmicrosoft/signalr";
+import { HubConnectionState } from "@microsoft/signalr";
import { useTranslation } from "react-i18next";
export interface ConnectionStatusBadgeProps {
diff --git a/FrontEnd/tsconfig.json b/FrontEnd/tsconfig.json
index 3afe2c3e..6b691e0e 100644
--- a/FrontEnd/tsconfig.json
+++ b/FrontEnd/tsconfig.json
@@ -2,9 +2,7 @@
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
- "allowJs": false,
- "skipLibCheck": false,
- "esModuleInterop": false,
+ "skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
@@ -15,7 +13,6 @@
"jsx": "react",
"noEmit": true,
"types": ["vite/client"],
- "sourceMap": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
diff --git a/FrontEnd/vite.config.js b/FrontEnd/vite.config.js
index 2e85c36a..ee6f6931 100644
--- a/FrontEnd/vite.config.js
+++ b/FrontEnd/vite.config.js
@@ -3,10 +3,21 @@
*/
import reactRefresh from "@vitejs/plugin-react-refresh";
+import { VitePWA } from "vite-plugin-pwa";
import { defineConfig } from "vite";
export default defineConfig({
- plugins: [reactRefresh()],
+ plugins: [
+ reactRefresh(),
+ VitePWA({
+ strategies: "injectManifest",
+ srcDir: "src",
+ filename: "sw.ts",
+ base: "/",
+ manifest: false,
+ includeAssets: "**",
+ }),
+ ],
resolve: {
alias: [{ find: "@", replacement: "/src" }],
},