feishin/src/renderer/features/titlebar/components/app-menu.tsx

200 lines
7.2 KiB
TypeScript
Raw Normal View History

import { closeAllModals, openModal } from '@mantine/modals';
2023-02-08 14:42:13 -08:00
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next';
2023-01-03 02:13:40 -08:00
import { useNavigate } from 'react-router';
import { Link } from 'react-router-dom';
import packageJson from '../../../../../package.json';
2022-12-19 15:59:14 -08:00
import { ServerList } from '/@/renderer/features/servers';
import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form';
2023-01-03 02:13:40 -08:00
import { AppRoute } from '/@/renderer/router/routes';
import {
useAppStoreActions,
useAuthStoreActions,
2023-07-01 19:10:05 -07:00
useCurrentServer,
useServerList,
useSidebarStore,
} from '/@/renderer/store';
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
import { Icon } from '/@/shared/components/icon/icon';
2025-05-20 19:23:36 -07:00
import { ServerListItem, ServerType } from '/@/shared/types/domain-types';
2022-12-19 15:59:14 -08:00
const browser = isElectron() ? window.api.browser : null;
const localSettings = isElectron() ? window.api.localSettings : null;
2023-02-08 14:42:13 -08:00
2022-12-19 15:59:14 -08:00
export const AppMenu = () => {
const { t } = useTranslation();
2023-07-01 19:10:05 -07:00
const navigate = useNavigate();
const currentServer = useCurrentServer();
const serverList = useServerList();
const { setCurrentServer } = useAuthStoreActions();
const { collapsed } = useSidebarStore();
const { setSideBar } = useAppStoreActions();
2022-12-19 15:59:14 -08:00
2023-07-01 19:10:05 -07:00
const handleSetCurrentServer = (server: ServerListItem) => {
navigate(AppRoute.HOME);
setCurrentServer(server);
};
2022-12-19 15:59:14 -08:00
2023-07-01 19:10:05 -07:00
const handleCredentialsModal = async (server: ServerListItem) => {
let password: null | string = null;
2023-07-01 19:10:05 -07:00
try {
if (localSettings && server.savePassword) {
password = await localSettings.passwordGet(server.id);
}
} catch (error) {
console.error(error);
}
openModal({
children: server && (
<EditServerForm
isUpdate
onCancel={closeAllModals}
2023-07-01 19:10:05 -07:00
password={password}
server={server}
/>
),
size: 'sm',
title: `Update session for "${server.name}"`,
});
};
2022-12-19 15:59:14 -08:00
2023-07-01 19:10:05 -07:00
const handleManageServersModal = () => {
openModal({
children: <ServerList />,
title: t('page.manageServers.title', { postProcess: 'titleCase' }),
2023-07-01 19:10:05 -07:00
});
};
2022-12-19 15:59:14 -08:00
2023-07-01 19:10:05 -07:00
const handleBrowserDevTools = () => {
browser?.devtools();
};
2023-02-08 14:42:13 -08:00
2023-07-01 19:10:05 -07:00
const handleCollapseSidebar = () => {
setSideBar({ collapsed: true });
};
2023-07-01 19:10:05 -07:00
const handleExpandSidebar = () => {
setSideBar({ collapsed: false });
};
2023-09-22 18:04:15 -07:00
const handleQuit = () => {
2023-09-27 02:37:03 -07:00
browser?.quit();
2023-09-22 18:04:15 -07:00
};
2023-02-08 14:42:13 -08:00
2023-07-01 19:10:05 -07:00
return (
<>
<DropdownMenu.Item
leftSection={<Icon icon="arrowLeftS" />}
2023-07-01 19:10:05 -07:00
onClick={() => navigate(-1)}
>
{t('page.appMenu.goBack', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
<DropdownMenu.Item
leftSection={<Icon icon="arrowRightS" />}
2023-07-01 19:10:05 -07:00
onClick={() => navigate(1)}
>
{t('page.appMenu.goForward', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
{collapsed ? (
<DropdownMenu.Item
leftSection={<Icon icon="panelRightOpen" />}
2023-07-01 19:10:05 -07:00
onClick={handleExpandSidebar}
>
{t('page.appMenu.expandSidebar', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
) : (
<DropdownMenu.Item
leftSection={<Icon icon="panelRightClose" />}
2023-07-01 19:10:05 -07:00
onClick={handleCollapseSidebar}
>
{t('page.appMenu.collapseSidebar', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
)}
<DropdownMenu.Divider />
<DropdownMenu.Item
component={Link}
leftSection={<Icon icon="settings" />}
2023-07-01 19:10:05 -07:00
to={AppRoute.SETTINGS}
>
{t('page.appMenu.settings', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
<DropdownMenu.Item
leftSection={<Icon icon="edit" />}
2023-07-01 19:10:05 -07:00
onClick={handleManageServersModal}
>
{t('page.appMenu.manageServers', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
2023-07-01 19:10:05 -07:00
<DropdownMenu.Divider />
<DropdownMenu.Label>
{t('page.appMenu.selectServer', { postProcess: 'sentenceCase' })}
</DropdownMenu.Label>
2023-07-01 19:10:05 -07:00
{Object.keys(serverList).map((serverId) => {
const server = serverList[serverId];
const isNavidromeExpired =
server.type === ServerType.NAVIDROME && !server.ndCredential;
const isJellyfinExpired = server.type === ServerType.JELLYFIN && !server.credential;
2023-07-01 19:10:05 -07:00
const isSessionExpired = isNavidromeExpired || isJellyfinExpired;
2023-07-01 19:10:05 -07:00
return (
<DropdownMenu.Item
key={`server-${server.id}`}
leftSection={
2023-07-01 19:10:05 -07:00
isSessionExpired ? (
<Icon
fill="error"
icon="lock"
/>
2023-07-01 19:10:05 -07:00
) : (
<Icon
color={server.id === currentServer?.id ? 'primary' : undefined}
icon="server"
/>
2023-07-01 19:10:05 -07:00
)
}
onClick={() => {
if (!isSessionExpired) return handleSetCurrentServer(server);
return handleCredentialsModal(server);
}}
>
{server.name}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
);
})}
<DropdownMenu.Divider />
<DropdownMenu.Item
component="a"
href="https://github.com/jeffvli/feishin/releases"
leftSection={<Icon icon="brandGitHub" />}
rightSection={<Icon icon="externalLink" />}
2023-07-01 19:10:05 -07:00
target="_blank"
>
{t('page.appMenu.version', {
postProcess: 'sentenceCase',
version: packageJson.version,
})}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
2023-09-22 18:04:15 -07:00
{isElectron() && (
2023-07-01 19:10:05 -07:00
<>
<DropdownMenu.Divider />
<DropdownMenu.Item
leftSection={<Icon icon="appWindow" />}
2023-07-01 19:10:05 -07:00
onClick={handleBrowserDevTools}
>
{t('page.appMenu.openBrowserDevtools', { postProcess: 'sentenceCase' })}
2023-07-01 19:10:05 -07:00
</DropdownMenu.Item>
2023-09-22 18:04:15 -07:00
<DropdownMenu.Item
leftSection={<Icon icon="x" />}
2023-09-22 18:04:15 -07:00
onClick={handleQuit}
>
{t('page.appMenu.quit', { postProcess: 'sentenceCase' })}
2023-09-22 18:04:15 -07:00
</DropdownMenu.Item>
2023-07-01 19:10:05 -07:00
</>
)}
2023-02-08 14:42:13 -08:00
</>
2023-07-01 19:10:05 -07:00
);
2022-12-19 15:59:14 -08:00
};