mirror of
https://github.com/jeffvli/feishin.git
synced 2024-11-20 06:27:09 +01:00
Add initial support for static server
This commit is contained in:
parent
1d2e9484d8
commit
9c355ce5bd
@ -43,6 +43,11 @@ const configuration: webpack.Configuration = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
new webpack.EnvironmentPlugin({
|
new webpack.EnvironmentPlugin({
|
||||||
NODE_ENV: 'production',
|
NODE_ENV: 'production',
|
||||||
|
FS_SERVER_NAME: process.env.SERVER_URL ?? null,
|
||||||
|
FS_SERVER_URL: process.env.SERVER_URL ?? null,
|
||||||
|
FS_SERVER_TYPE: process.env.SERVER_URL ?? null,
|
||||||
|
FS_SERVER_USERNAME: process.env.SERVER_URL ?? null,
|
||||||
|
FS_SERVER_PASSWORD: process.env.SERVER_URL ?? null,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"deletePlaylist": "delete $t(entity.playlist_one)",
|
"deletePlaylist": "delete $t(entity.playlist_one)",
|
||||||
"deselectAll": "deselect all",
|
"deselectAll": "deselect all",
|
||||||
"editPlaylist": "edit $t(entity.playlist_one)",
|
"editPlaylist": "edit $t(entity.playlist_one)",
|
||||||
|
"signIn": "sign in",
|
||||||
"goToPage": "go to page",
|
"goToPage": "go to page",
|
||||||
"moveToBottom": "move to bottom",
|
"moveToBottom": "move to bottom",
|
||||||
"moveToTop": "move to top",
|
"moveToTop": "move to top",
|
||||||
@ -14,6 +15,7 @@
|
|||||||
"removeFromFavorites": "remove from $t(entity.favorite_other)",
|
"removeFromFavorites": "remove from $t(entity.favorite_other)",
|
||||||
"removeFromPlaylist": "remove from $t(entity.playlist_one)",
|
"removeFromPlaylist": "remove from $t(entity.playlist_one)",
|
||||||
"removeFromQueue": "remove from queue",
|
"removeFromQueue": "remove from queue",
|
||||||
|
"removeServer": "remove server",
|
||||||
"setRating": "set rating",
|
"setRating": "set rating",
|
||||||
"toggleSmartPlaylistEditor": "toggle $t(entity.smartPlaylist) editor",
|
"toggleSmartPlaylistEditor": "toggle $t(entity.smartPlaylist) editor",
|
||||||
"viewPlaylists": "view $t(entity.playlist_other)"
|
"viewPlaylists": "view $t(entity.playlist_other)"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
|
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
|
||||||
import { ModuleRegistry } from '@ag-grid-community/core';
|
import { ModuleRegistry } from '@ag-grid-community/core';
|
||||||
import { InfiniteRowModelModule } from '@ag-grid-community/infinite-row-model';
|
import { InfiniteRowModelModule } from '@ag-grid-community/infinite-row-model';
|
||||||
@ -22,8 +22,19 @@ import { useHandlePlayQueueAdd } from '/@/renderer/features/player/hooks/use-han
|
|||||||
import { PlayQueueHandlerContext } from '/@/renderer/features/player';
|
import { PlayQueueHandlerContext } from '/@/renderer/features/player';
|
||||||
import { AddToPlaylistContextModal } from '/@/renderer/features/playlists';
|
import { AddToPlaylistContextModal } from '/@/renderer/features/playlists';
|
||||||
import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-settings';
|
import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-settings';
|
||||||
import { PlayerState, usePlayerStore, useQueueControls } from '/@/renderer/store';
|
import {
|
||||||
import { FontType, PlaybackType, PlayerStatus } from '/@/renderer/types';
|
PlayerState,
|
||||||
|
useAuthStoreActions,
|
||||||
|
usePlayerStore,
|
||||||
|
useQueueControls,
|
||||||
|
} from '/@/renderer/store';
|
||||||
|
import {
|
||||||
|
FontType,
|
||||||
|
PlaybackType,
|
||||||
|
PlayerStatus,
|
||||||
|
ServerListItem,
|
||||||
|
ServerType,
|
||||||
|
} from '/@/renderer/types';
|
||||||
import '@ag-grid-community/styles/ag-grid.css';
|
import '@ag-grid-community/styles/ag-grid.css';
|
||||||
import { useDiscordRpc } from '/@/renderer/features/discord-rpc/use-discord-rpc';
|
import { useDiscordRpc } from '/@/renderer/features/discord-rpc/use-discord-rpc';
|
||||||
import i18n from '/@/i18n/i18n';
|
import i18n from '/@/i18n/i18n';
|
||||||
@ -48,6 +59,57 @@ export const App = () => {
|
|||||||
const { clearQueue, restoreQueue } = useQueueControls();
|
const { clearQueue, restoreQueue } = useQueueControls();
|
||||||
const remoteSettings = useRemoteSettings();
|
const remoteSettings = useRemoteSettings();
|
||||||
const textStyleRef = useRef<HTMLStyleElement>();
|
const textStyleRef = useRef<HTMLStyleElement>();
|
||||||
|
const { addServer } = useAuthStoreActions();
|
||||||
|
|
||||||
|
const setStaticServer = useCallback(() => {
|
||||||
|
console.log('process.env.FS_SERVER_URL :>> ', process.env.FS_SERVER_URL);
|
||||||
|
console.log('process.env.FS_SERVER_NAME', process.env.FS_SERVER_NAME);
|
||||||
|
console.log('process.env.FS_SERVER_TYPE :>> ', process.env.FS_SERVER_TYPE);
|
||||||
|
const url = process.env.FS_SERVER_URL;
|
||||||
|
let serverType: ServerType | null = null;
|
||||||
|
const name =
|
||||||
|
process.env.FS_SERVER_NAME || serverType === ServerType.NAVIDROME
|
||||||
|
? 'Navidrome'
|
||||||
|
: 'Jellyfin';
|
||||||
|
|
||||||
|
switch (process.env.FS_SERVER_TYPE?.toLocaleLowerCase()) {
|
||||||
|
case 'jellyfin':
|
||||||
|
serverType = ServerType.JELLYFIN;
|
||||||
|
break;
|
||||||
|
case 'navidrome':
|
||||||
|
serverType = ServerType.NAVIDROME;
|
||||||
|
break;
|
||||||
|
case 'subsonic':
|
||||||
|
serverType = ServerType.SUBSONIC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
serverType = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url || !serverType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverItem: ServerListItem = {
|
||||||
|
credential: undefined,
|
||||||
|
id: 'static-server',
|
||||||
|
name,
|
||||||
|
ndCredential: undefined,
|
||||||
|
static: true,
|
||||||
|
type: serverType,
|
||||||
|
url: url.replace(/\/$/, ''),
|
||||||
|
userId: undefined,
|
||||||
|
username: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
addServer(serverItem);
|
||||||
|
}, [addServer]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setStaticServer();
|
||||||
|
}, [setStaticServer]);
|
||||||
|
|
||||||
useDiscordRpc();
|
useDiscordRpc();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,19 +1,70 @@
|
|||||||
import { Text } from '/@/renderer/components';
|
import { openModal, closeAllModals } from '@mantine/modals';
|
||||||
|
import isElectron from 'is-electron';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Button, DropdownMenu } from '/@/renderer/components';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { RiKeyFill, RiMenuFill } from 'react-icons/ri';
|
||||||
|
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
|
||||||
|
import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form';
|
||||||
|
|
||||||
|
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||||
|
|
||||||
export const ServerCredentialRequired = () => {
|
export const ServerCredentialRequired = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const currentServer = useCurrentServer();
|
const currentServer = useCurrentServer();
|
||||||
|
|
||||||
|
const handleCredentialsModal = async () => {
|
||||||
|
if (!currentServer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = currentServer;
|
||||||
|
let password: string | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (localSettings && server.savePassword) {
|
||||||
|
password = await localSettings.passwordGet(server.id);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal({
|
||||||
|
children: server && (
|
||||||
|
<EditServerForm
|
||||||
|
isUpdate
|
||||||
|
password={password}
|
||||||
|
server={server}
|
||||||
|
onCancel={closeAllModals}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
size: 'sm',
|
||||||
|
title: server.name,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Text>
|
<Button
|
||||||
The selected server '{currentServer?.name}' requires an additional login
|
leftIcon={<RiKeyFill />}
|
||||||
to access.
|
variant="filled"
|
||||||
</Text>
|
onClick={handleCredentialsModal}
|
||||||
<Text>
|
>
|
||||||
Add your credentials in the 'manage servers' menu or switch to a different
|
{t('action.signIn', { postProcess: 'titleCase' })}
|
||||||
server.
|
</Button>
|
||||||
</Text>
|
<DropdownMenu>
|
||||||
|
<DropdownMenu.Target>
|
||||||
|
<Button
|
||||||
|
leftIcon={<RiMenuFill />}
|
||||||
|
variant="filled"
|
||||||
|
>
|
||||||
|
{t('common.menu', { postProcess: 'titleCase' })}
|
||||||
|
</Button>
|
||||||
|
</DropdownMenu.Target>
|
||||||
|
<DropdownMenu.Dropdown>
|
||||||
|
<AppMenu />
|
||||||
|
</DropdownMenu.Dropdown>
|
||||||
|
</DropdownMenu>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiMenuFill } from 'react-icons/ri';
|
import { RiMenuFill } from 'react-icons/ri';
|
||||||
import { Button, DropdownMenu, Text } from '/@/renderer/components';
|
import { Button, DropdownMenu, Text } from '/@/renderer/components';
|
||||||
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
|
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
|
||||||
|
|
||||||
export const ServerRequired = () => {
|
export const ServerRequired = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Text>No server selected.</Text>
|
<Text>No server selected.</Text>
|
||||||
@ -12,7 +15,7 @@ export const ServerRequired = () => {
|
|||||||
leftIcon={<RiMenuFill />}
|
leftIcon={<RiMenuFill />}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
>
|
>
|
||||||
Open menu
|
{t('common.menu', { postProcess: 'titleCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenu.Target>
|
</DropdownMenu.Target>
|
||||||
<DropdownMenu.Dropdown>
|
<DropdownMenu.Dropdown>
|
||||||
|
@ -4,7 +4,7 @@ import isElectron from 'is-electron';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiCheckFill } from 'react-icons/ri';
|
import { RiCheckFill } from 'react-icons/ri';
|
||||||
import { Link, Navigate } from 'react-router-dom';
|
import { Link, Navigate } from 'react-router-dom';
|
||||||
import { Button, PageHeader, Text } from '/@/renderer/components';
|
import { Button, PageHeader } from '/@/renderer/components';
|
||||||
import { ActionRequiredContainer } from '/@/renderer/features/action-required/components/action-required-container';
|
import { ActionRequiredContainer } from '/@/renderer/features/action-required/components/action-required-container';
|
||||||
import { MpvRequired } from '/@/renderer/features/action-required/components/mpv-required';
|
import { MpvRequired } from '/@/renderer/features/action-required/components/mpv-required';
|
||||||
import { ServerCredentialRequired } from '/@/renderer/features/action-required/components/server-credential-required';
|
import { ServerCredentialRequired } from '/@/renderer/features/action-required/components/server-credential-required';
|
||||||
@ -12,15 +12,36 @@ import { ServerRequired } from '/@/renderer/features/action-required/components/
|
|||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { ServerListItem, ServerType } from '/@/renderer/types';
|
||||||
|
|
||||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||||
|
|
||||||
|
export const getIsCredentialRequired = (currentServer: ServerListItem | null) => {
|
||||||
|
if (currentServer === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentServer.type === ServerType.NAVIDROME) {
|
||||||
|
return !currentServer.ndCredential || !currentServer.credential || !currentServer.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentServer.type === ServerType.JELLYFIN) {
|
||||||
|
return !currentServer.credential || !currentServer.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentServer.type === ServerType.SUBSONIC) {
|
||||||
|
return !currentServer.credential || !currentServer.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
const ActionRequiredRoute = () => {
|
const ActionRequiredRoute = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const currentServer = useCurrentServer();
|
const currentServer = useCurrentServer();
|
||||||
const [isMpvRequired, setIsMpvRequired] = useState(false);
|
const [isMpvRequired, setIsMpvRequired] = useState(false);
|
||||||
const isServerRequired = !currentServer;
|
const isServerRequired = !currentServer;
|
||||||
const isCredentialRequired = false;
|
const isCredentialRequired = getIsCredentialRequired(currentServer);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getMpvPath = async () => {
|
const getMpvPath = async () => {
|
||||||
@ -85,7 +106,6 @@ const ActionRequiredRoute = () => {
|
|||||||
color="var(--success-color)"
|
color="var(--success-color)"
|
||||||
size={30}
|
size={30}
|
||||||
/>
|
/>
|
||||||
<Text size="xl">No issues found</Text>
|
|
||||||
</Group>
|
</Group>
|
||||||
<Button
|
<Button
|
||||||
component={Link}
|
component={Link}
|
||||||
@ -93,7 +113,7 @@ const ActionRequiredRoute = () => {
|
|||||||
to={AppRoute.HOME}
|
to={AppRoute.HOME}
|
||||||
variant="filled"
|
variant="filled"
|
||||||
>
|
>
|
||||||
Go back
|
{t('page.appMenu.goBack', { postProcess: 'sentenceCase' })}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -46,7 +46,7 @@ export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditSer
|
|||||||
savePassword: server.savePassword || false,
|
savePassword: server.savePassword || false,
|
||||||
type: server?.type,
|
type: server?.type,
|
||||||
url: server?.url,
|
url: server?.url,
|
||||||
username: server?.username,
|
username: server?.username || '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -125,6 +125,7 @@ export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditSer
|
|||||||
<Stack ref={focusTrapRef}>
|
<Stack ref={focusTrapRef}>
|
||||||
<TextInput
|
<TextInput
|
||||||
required
|
required
|
||||||
|
disabled={server?.static}
|
||||||
label={t('form.addServer.input', {
|
label={t('form.addServer.input', {
|
||||||
context: 'name',
|
context: 'name',
|
||||||
postProcess: 'titleCase',
|
postProcess: 'titleCase',
|
||||||
@ -134,6 +135,7 @@ export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditSer
|
|||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
required
|
required
|
||||||
|
disabled={server?.static}
|
||||||
label={t('form.addServer.input', {
|
label={t('form.addServer.input', {
|
||||||
context: 'url',
|
context: 'url',
|
||||||
postProcess: 'titleCase',
|
postProcess: 'titleCase',
|
||||||
@ -143,6 +145,7 @@ export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditSer
|
|||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
required
|
required
|
||||||
|
data-autofocus={!server?.username}
|
||||||
label={t('form.addServer.input', {
|
label={t('form.addServer.input', {
|
||||||
context: 'username',
|
context: 'username',
|
||||||
postProcess: 'titleCase',
|
postProcess: 'titleCase',
|
||||||
@ -151,8 +154,8 @@ export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditSer
|
|||||||
{...form.getInputProps('username')}
|
{...form.getInputProps('username')}
|
||||||
/>
|
/>
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
data-autofocus
|
|
||||||
required
|
required
|
||||||
|
data-autofocus={server?.username}
|
||||||
label={t('form.addServer.input', {
|
label={t('form.addServer.input', {
|
||||||
context: 'password',
|
context: 'password',
|
||||||
postProcess: 'titleCase',
|
postProcess: 'titleCase',
|
||||||
|
@ -3,6 +3,7 @@ import { Stack, Group, Divider } from '@mantine/core';
|
|||||||
import { Button, Text, TimeoutButton } from '/@/renderer/components';
|
import { Button, Text, TimeoutButton } from '/@/renderer/components';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
import isElectron from 'is-electron';
|
import isElectron from 'is-electron';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiDeleteBin2Line, RiEdit2Fill } from 'react-icons/ri';
|
import { RiDeleteBin2Line, RiEdit2Fill } from 'react-icons/ri';
|
||||||
import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form';
|
import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form';
|
||||||
import { ServerSection } from '/@/renderer/features/servers/components/server-section';
|
import { ServerSection } from '/@/renderer/features/servers/components/server-section';
|
||||||
@ -16,6 +17,7 @@ interface ServerListItemProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ServerListItem = ({ server }: ServerListItemProps) => {
|
export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [edit, editHandlers] = useDisclosure(false);
|
const [edit, editHandlers] = useDisclosure(false);
|
||||||
const [savedPassword, setSavedPassword] = useState('');
|
const [savedPassword, setSavedPassword] = useState('');
|
||||||
const { deleteServer } = useAuthStoreActions();
|
const { deleteServer } = useAuthStoreActions();
|
||||||
@ -68,8 +70,18 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
<Stack>
|
<Stack>
|
||||||
<Group noWrap>
|
<Group noWrap>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text>URL</Text>
|
<Text>
|
||||||
<Text>Username</Text>
|
{t('form.addServer.input', {
|
||||||
|
context: 'url',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
{t('form.addServer.input', {
|
||||||
|
context: 'username',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text>{server.url}</Text>
|
<Text>{server.url}</Text>
|
||||||
@ -83,7 +95,9 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={() => handleEdit()}
|
onClick={() => handleEdit()}
|
||||||
>
|
>
|
||||||
Edit
|
{t('common.edit', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
@ -95,7 +109,9 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
timeoutProps={{ callback: handleDeleteServer, duration: 1000 }}
|
timeoutProps={{ callback: handleDeleteServer, duration: 1000 }}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
>
|
>
|
||||||
Remove server
|
{t('action.removeServer', {
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
})}
|
||||||
</TimeoutButton>
|
</TimeoutButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
@ -69,14 +69,14 @@ export const AppMenu = () => {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
title: `Update session for "${server.name}"`,
|
title: server.name,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleManageServersModal = () => {
|
const handleManageServersModal = () => {
|
||||||
openModal({
|
openModal({
|
||||||
children: <ServerList />,
|
children: <ServerList />,
|
||||||
title: 'Manage Servers',
|
title: t('page.appMenu.manageServers', { postProcess: 'sentenceCase' }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import isElectron from 'is-electron';
|
|||||||
import { Navigate, Outlet } from 'react-router-dom';
|
import { Navigate, Outlet } from 'react-router-dom';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { getIsCredentialRequired } from '/@/renderer/features/action-required/routes/action-required-route';
|
||||||
|
|
||||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||||
|
|
||||||
@ -17,9 +18,11 @@ export const AppOutlet = () => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isCredentialRequired = getIsCredentialRequired(currentServer);
|
||||||
|
|
||||||
const isServerRequired = !currentServer;
|
const isServerRequired = !currentServer;
|
||||||
|
|
||||||
const actions = [isServerRequired, isMpvRequired()];
|
const actions = [isServerRequired, isCredentialRequired, isMpvRequired()];
|
||||||
const isActionRequired = actions.some((c) => c);
|
const isActionRequired = actions.some((c) => c);
|
||||||
|
|
||||||
return isActionRequired;
|
return isActionRequired;
|
||||||
|
@ -31,7 +31,15 @@ export const useAuthStore = create<AuthSlice>()(
|
|||||||
actions: {
|
actions: {
|
||||||
addServer: (args) => {
|
addServer: (args) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
|
if (state.serverList[args.id]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.serverList[args.id] = args;
|
state.serverList[args.id] = args;
|
||||||
|
|
||||||
|
if (!state.currentServer) {
|
||||||
|
state.currentServer = args;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteServer: (id) => {
|
deleteServer: (id) => {
|
||||||
|
@ -61,15 +61,16 @@ export enum ServerType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ServerListItem = {
|
export type ServerListItem = {
|
||||||
credential: string;
|
credential?: string;
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
ndCredential?: string;
|
ndCredential?: string;
|
||||||
savePassword?: boolean;
|
savePassword?: boolean;
|
||||||
|
static?: boolean;
|
||||||
type: ServerType;
|
type: ServerType;
|
||||||
url: string;
|
url: string;
|
||||||
userId: string | null;
|
userId?: string | null;
|
||||||
username: string;
|
username?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum PlayerStatus {
|
export enum PlayerStatus {
|
||||||
|
Loading…
Reference in New Issue
Block a user