mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
add PWA support
This commit is contained in:
parent
e68fe0e115
commit
3a1c3ad260
10 changed files with 1510 additions and 1354 deletions
|
@ -43,6 +43,7 @@ module.exports = {
|
||||||
"no-shadow": "off",
|
"no-shadow": "off",
|
||||||
"@typescript-eslint/no-shadow": ["error"],
|
"@typescript-eslint/no-shadow": ["error"],
|
||||||
"no-restricted-syntax": "off",
|
"no-restricted-syntax": "off",
|
||||||
|
"import/no-unresolved": ["error", { ignore: ["^virtual:"] }],
|
||||||
"react/jsx-props-no-spreading": "off",
|
"react/jsx-props-no-spreading": "off",
|
||||||
"consistent-return": "off",
|
"consistent-return": "off",
|
||||||
"no-continue": "off",
|
"no-continue": "off",
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,6 +10,7 @@ node_modules
|
||||||
|
|
||||||
# production
|
# production
|
||||||
/dist
|
/dist
|
||||||
|
dev-dist
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||||
"eslint.format.enable": true
|
"eslint.format.enable": true,
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,15 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Because watching movies legally is boring"
|
content="The place for your favourite movies & shows"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<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="32x32" href="/favicon-32x32.png" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.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="#120f1d" />
|
||||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#E880C5" />
|
<meta name="msapplication-TileColor" content="#120f1d" />
|
||||||
<meta name="msapplication-TileColor" content="#E880C5" />
|
<meta name="theme-color" content="#120f1d" />
|
||||||
<meta name="theme-color" content="#E880C5" />
|
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
"vite": "^4.0.1",
|
"vite": "^4.0.1",
|
||||||
"vite-plugin-checker": "^0.5.6",
|
"vite-plugin-checker": "^0.5.6",
|
||||||
"vite-plugin-package-version": "^1.0.2",
|
"vite-plugin-package-version": "^1.0.2",
|
||||||
|
"vite-plugin-pwa": "^0.14.4",
|
||||||
"vitest": "^0.28.5"
|
"vitest": "^0.28.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"name": "movie-web",
|
|
||||||
"short_name": "movie-web",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-512x512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"theme_color": "#E880C5",
|
|
||||||
"background_color": "#16171D",
|
|
||||||
"display": "standalone",
|
|
||||||
"start_url": "/"
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Redirect, Route, Switch } from "react-router-dom";
|
import { Redirect, Route, Switch } from "react-router-dom";
|
||||||
|
import { useRegisterSW } from "virtual:pwa-register/react";
|
||||||
import { BookmarkContextProvider } from "@/state/bookmark";
|
import { BookmarkContextProvider } from "@/state/bookmark";
|
||||||
import { WatchedContextProvider } from "@/state/watched";
|
import { WatchedContextProvider } from "@/state/watched";
|
||||||
|
|
||||||
|
@ -12,10 +13,66 @@ import { VideoTesterView } from "@/views/developer/VideoTesterView";
|
||||||
import { ProviderTesterView } from "@/views/developer/ProviderTesterView";
|
import { ProviderTesterView } from "@/views/developer/ProviderTesterView";
|
||||||
import { EmbedTesterView } from "@/views/developer/EmbedTesterView";
|
import { EmbedTesterView } from "@/views/developer/EmbedTesterView";
|
||||||
|
|
||||||
|
function ReloadPrompt() {
|
||||||
|
const {
|
||||||
|
offlineReady: [offlineReady, setOfflineReady],
|
||||||
|
needRefresh: [needRefresh, setNeedRefresh],
|
||||||
|
updateServiceWorker,
|
||||||
|
} = useRegisterSW({
|
||||||
|
onRegistered(r) {
|
||||||
|
// eslint-disable-next-line prefer-template
|
||||||
|
console.log("SW Registered: " + r);
|
||||||
|
},
|
||||||
|
onRegisterError(error) {
|
||||||
|
console.log("SW registration error", error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
setOfflineReady(false);
|
||||||
|
setNeedRefresh(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ReloadPrompt-container">
|
||||||
|
{(offlineReady || needRefresh) && (
|
||||||
|
<div className="ReloadPrompt-toast">
|
||||||
|
<div className="ReloadPrompt-message">
|
||||||
|
{offlineReady ? (
|
||||||
|
<span>App ready to work offline</span>
|
||||||
|
) : (
|
||||||
|
<span>
|
||||||
|
New content available, click on reload button to update.
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{needRefresh && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ReloadPrompt-toast-button"
|
||||||
|
onClick={() => updateServiceWorker(true)}
|
||||||
|
>
|
||||||
|
Reload
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ReloadPrompt-toast-button"
|
||||||
|
onClick={() => close()}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<WatchedContextProvider>
|
<WatchedContextProvider>
|
||||||
<BookmarkContextProvider>
|
<BookmarkContextProvider>
|
||||||
|
<ReloadPrompt />
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* functional routes */}
|
{/* functional routes */}
|
||||||
<Route exact path="/v2-migration" component={V2MigrationView} />
|
<Route exact path="/v2-migration" component={V2MigrationView} />
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./*"]
|
"@/*": ["./*"]
|
||||||
},
|
},
|
||||||
"types": ["vite/client"]
|
"types": ["vite/client", "vite-plugin-pwa/client"]
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,46 @@
|
||||||
import { defineConfig } from "vitest/config";
|
import { defineConfig } from "vitest/config";
|
||||||
import react from "@vitejs/plugin-react-swc";
|
import react from "@vitejs/plugin-react-swc";
|
||||||
import loadVersion from "vite-plugin-package-version";
|
import loadVersion from "vite-plugin-package-version";
|
||||||
|
import { VitePWA } from "vite-plugin-pwa";
|
||||||
import checker from "vite-plugin-checker";
|
import checker from "vite-plugin-checker";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
react(),
|
react(),
|
||||||
|
VitePWA({
|
||||||
|
registerType: "autoUpdate",
|
||||||
|
injectRegister: "inline",
|
||||||
|
devOptions: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
includeAssets: [
|
||||||
|
"favicon.ico",
|
||||||
|
"apple-touch-icon.png",
|
||||||
|
"safari-pinned-tab.svg",
|
||||||
|
],
|
||||||
|
manifest: {
|
||||||
|
name: "movie-web",
|
||||||
|
short_name: "movie-web",
|
||||||
|
description: "The place for your favourite movies & shows",
|
||||||
|
theme_color: "#120f1d",
|
||||||
|
background_color: "#120f1d",
|
||||||
|
display: "standalone",
|
||||||
|
start_url: "/",
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: "android-chrome-192x192.png",
|
||||||
|
sizes: "192x192",
|
||||||
|
type: "image/png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: "android-chrome-512x512.png",
|
||||||
|
sizes: "512x512",
|
||||||
|
type: "image/png",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
loadVersion(),
|
loadVersion(),
|
||||||
checker({
|
checker({
|
||||||
typescript: true, // check typescript build errors in dev server
|
typescript: true, // check typescript build errors in dev server
|
||||||
|
|
Loading…
Reference in a new issue