mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-01 12:18:35 -05:00
feat: PWA Support (#1488)
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import App, { AppInitialProps, AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import { parseCookies, setCookie } from 'nookies';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { ToastProvider } from 'react-toast-notifications';
|
||||
@@ -9,8 +8,11 @@ import { SWRConfig } from 'swr';
|
||||
import { PublicSettingsResponse } from '../../server/interfaces/api/settingsInterfaces';
|
||||
import Layout from '../components/Layout';
|
||||
import LoadingBar from '../components/LoadingBar';
|
||||
import PWAHeader from '../components/PWAHeader';
|
||||
import ServiceWorkerSetup from '../components/ServiceWorkerSetup';
|
||||
import StatusChecker from '../components/StatusChacker';
|
||||
import Toast from '../components/Toast';
|
||||
import ToastContainer from '../components/ToastContainer';
|
||||
import { InteractionProvider } from '../context/InteractionContext';
|
||||
import { AvailableLocales, LanguageContext } from '../context/LanguageContext';
|
||||
import { SettingsProvider } from '../context/SettingsContext';
|
||||
@@ -88,10 +90,6 @@ const CoreApp: Omit<NextAppComponentType, 'origGetInitialProps'> = ({
|
||||
|
||||
useEffect(() => {
|
||||
loadLocaleData(currentLocale).then(setMessages);
|
||||
setCookie(null, 'locale', currentLocale, {
|
||||
path: '/',
|
||||
maxAge: 60 * 60 * 24 * 365 * 10,
|
||||
});
|
||||
}, [currentLocale]);
|
||||
|
||||
if (router.pathname.match(/(login|setup|resetpassword)/)) {
|
||||
@@ -119,15 +117,19 @@ const CoreApp: Omit<NextAppComponentType, 'origGetInitialProps'> = ({
|
||||
<LoadingBar />
|
||||
<SettingsProvider currentSettings={currentSettings}>
|
||||
<InteractionProvider>
|
||||
<ToastProvider components={{ Toast }}>
|
||||
<ToastProvider components={{ Toast, ToastContainer }}>
|
||||
<Head>
|
||||
<title>Overseerr</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="initial-scale=1, viewport-fit=cover, width=device-width"
|
||||
></meta>
|
||||
<PWAHeader
|
||||
applicationTitle={currentSettings.applicationTitle}
|
||||
/>
|
||||
</Head>
|
||||
<StatusChecker />
|
||||
<ServiceWorkerSetup />
|
||||
<UserContext initialUser={user}>{component}</UserContext>
|
||||
</ToastProvider>
|
||||
</InteractionProvider>
|
||||
@@ -140,7 +142,7 @@ const CoreApp: Omit<NextAppComponentType, 'origGetInitialProps'> = ({
|
||||
|
||||
CoreApp.getInitialProps = async (initialProps) => {
|
||||
const { ctx, router } = initialProps;
|
||||
let user = undefined;
|
||||
let user: User | undefined = undefined;
|
||||
let currentSettings: PublicSettingsResponse = {
|
||||
initialized: false,
|
||||
applicationTitle: '',
|
||||
@@ -152,10 +154,10 @@ CoreApp.getInitialProps = async (initialProps) => {
|
||||
originalLanguage: '',
|
||||
partialRequestsEnabled: true,
|
||||
cacheImages: false,
|
||||
vapidPublic: '',
|
||||
enablePushRegistration: false,
|
||||
};
|
||||
|
||||
let locale = 'en';
|
||||
|
||||
if (ctx.res) {
|
||||
// Check if app is initialized and redirect if necessary
|
||||
const response = await axios.get<PublicSettingsResponse>(
|
||||
@@ -200,12 +202,6 @@ CoreApp.getInitialProps = async (initialProps) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cookies = parseCookies(ctx);
|
||||
|
||||
if (cookies.locale) {
|
||||
locale = cookies.locale;
|
||||
}
|
||||
}
|
||||
|
||||
// Run the default getInitialProps for the main nextjs initialProps
|
||||
@@ -213,6 +209,8 @@ CoreApp.getInitialProps = async (initialProps) => {
|
||||
initialProps
|
||||
);
|
||||
|
||||
const locale = user?.settings?.locale ?? 'en';
|
||||
|
||||
const messages = await loadLocaleData(locale as AvailableLocales);
|
||||
|
||||
return { ...appInitialProps, user, messages, locale, currentSettings };
|
||||
|
||||
@@ -22,163 +22,6 @@ class MyDocument extends Document {
|
||||
<Html>
|
||||
<Head>
|
||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
|
||||
<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="apple-touch-startup-image"
|
||||
href="/apple-splash-2048-2732.jpg"
|
||||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2732-2048.jpg"
|
||||
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1668-2388.jpg"
|
||||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2388-1668.jpg"
|
||||
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1536-2048.jpg"
|
||||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2048-1536.jpg"
|
||||
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1668-2224.jpg"
|
||||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2224-1668.jpg"
|
||||
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1620-2160.jpg"
|
||||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2160-1620.jpg"
|
||||
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1284-2778.jpg"
|
||||
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2778-1284.jpg"
|
||||
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1170-2532.jpg"
|
||||
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2532-1170.jpg"
|
||||
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1125-2436.jpg"
|
||||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2436-1125.jpg"
|
||||
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1242-2688.jpg"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2688-1242.jpg"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-828-1792.jpg"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1792-828.jpg"
|
||||
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1242-2208.jpg"
|
||||
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-2208-1242.jpg"
|
||||
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-750-1334.jpg"
|
||||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1334-750.jpg"
|
||||
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-640-1136.jpg"
|
||||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-startup-image"
|
||||
href="/apple-splash-1136-640.jpg"
|
||||
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta
|
||||
name="apple-mobile-web-app-status-bar-style"
|
||||
content="black-translucent"
|
||||
/>
|
||||
<link
|
||||
rel="manifest"
|
||||
href="/site.webmanifest"
|
||||
crossOrigin="use-credentials"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
|
||||
17
src/pages/profile/settings/notifications/webpush.tsx
Normal file
17
src/pages/profile/settings/notifications/webpush.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import UserSettings from '../../../../components/UserProfile/UserSettings';
|
||||
import UserNotificationSettings from '../../../../components/UserProfile/UserSettings/UserNotificationSettings';
|
||||
import UserWebPushSettings from '../../../../components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush';
|
||||
|
||||
const WebPushProfileNotificationsPage: NextPage = () => {
|
||||
return (
|
||||
<UserSettings>
|
||||
<UserNotificationSettings>
|
||||
<UserWebPushSettings />
|
||||
</UserNotificationSettings>
|
||||
</UserSettings>
|
||||
);
|
||||
};
|
||||
|
||||
export default WebPushProfileNotificationsPage;
|
||||
17
src/pages/settings/notifications/webpush.tsx
Normal file
17
src/pages/settings/notifications/webpush.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import NotificationsWebPush from '../../../components/Settings/Notifications/NotificationsWebPush';
|
||||
import SettingsLayout from '../../../components/Settings/SettingsLayout';
|
||||
import SettingsNotifications from '../../../components/Settings/SettingsNotifications';
|
||||
|
||||
const NotificationsWebPushPage: NextPage = () => {
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsNotifications>
|
||||
<NotificationsWebPush />
|
||||
</SettingsNotifications>
|
||||
</SettingsLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationsWebPushPage;
|
||||
20
src/pages/users/[userId]/settings/notifications/webpush.tsx
Normal file
20
src/pages/users/[userId]/settings/notifications/webpush.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import UserSettings from '../../../../../components/UserProfile/UserSettings';
|
||||
import UserNotificationSettings from '../../../../../components/UserProfile/UserSettings/UserNotificationSettings';
|
||||
import UserWebPushSettings from '../../../../../components/UserProfile/UserSettings/UserNotificationSettings/UserNotificationsWebPush';
|
||||
import useRouteGuard from '../../../../../hooks/useRouteGuard';
|
||||
import { Permission } from '../../../../../hooks/useUser';
|
||||
|
||||
const WebPushNotificationsPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
return (
|
||||
<UserSettings>
|
||||
<UserNotificationSettings>
|
||||
<UserWebPushSettings />
|
||||
</UserNotificationSettings>
|
||||
</UserSettings>
|
||||
);
|
||||
};
|
||||
|
||||
export default WebPushNotificationsPage;
|
||||
Reference in New Issue
Block a user