mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-06 20:10:12 +02:00
fix duplicate server add when SERVER_LOCK is configured (#1623)
This commit is contained in:
@@ -227,6 +227,7 @@
|
||||
"remotePortError": "an error occurred when trying to set the remote server port",
|
||||
"remotePortWarning": "restart the server to apply the new port",
|
||||
"saveQueueFailed": "failed to save queue",
|
||||
"serverLockSingleServer": "only one server is allowed when server is locked",
|
||||
"serverNotSelectedError": "no server selected",
|
||||
"serverRequired": "server required",
|
||||
"sessionExpiredError": "your session has expired",
|
||||
|
||||
@@ -17,7 +17,12 @@ import { IgnoreCorsSslSwitches } from '/@/renderer/features/servers/components/i
|
||||
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
|
||||
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useAuthStoreActions, useCurrentServer } from '/@/renderer/store';
|
||||
import {
|
||||
getServerById,
|
||||
useAuthStoreActions,
|
||||
useCurrentServer,
|
||||
useServerList,
|
||||
} from '/@/renderer/store';
|
||||
import { Button } from '/@/shared/components/button/button';
|
||||
import { Center } from '/@/shared/components/center/center';
|
||||
import { Code } from '/@/shared/components/code/code';
|
||||
@@ -46,11 +51,14 @@ const SERVER_NAMES: Record<ServerType, string> = {
|
||||
[ServerType.SUBSONIC]: 'OpenSubsonic',
|
||||
};
|
||||
|
||||
const normalizeUrl = (url: string) => url.replace(/\/$/, '');
|
||||
|
||||
const LoginRoute = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { addServer, setCurrentServer } = useAuthStoreActions();
|
||||
const { addServer, setCurrentServer, updateServer } = useAuthStoreActions();
|
||||
const currentServer = useCurrentServer();
|
||||
const serverList = useServerList();
|
||||
|
||||
// Check if server lock is configured
|
||||
const serverLock = isServerLock();
|
||||
@@ -141,24 +149,43 @@ const LoginRoute = () => {
|
||||
});
|
||||
}
|
||||
|
||||
const normalizedUrl = normalizeUrl(serverUrl);
|
||||
const existingServer =
|
||||
serverLock &&
|
||||
Object.values(serverList).find((s) => normalizeUrl(s.url) === normalizedUrl);
|
||||
|
||||
const serverItem: ServerListItemWithCredential = {
|
||||
credential: data.credential,
|
||||
id: nanoid(),
|
||||
isAdmin: data.isAdmin,
|
||||
name: serverName,
|
||||
type: serverType as ServerType,
|
||||
url: serverUrl.replace(/\/$/, ''),
|
||||
url: normalizedUrl,
|
||||
userId: data.userId,
|
||||
username: data.username,
|
||||
};
|
||||
|
||||
if (data.ndCredential !== undefined) {
|
||||
serverItem.ndCredential = data.ndCredential;
|
||||
if (existingServer) {
|
||||
const updates: Partial<ServerListItemWithCredential> = {
|
||||
credential: data.credential,
|
||||
isAdmin: data.isAdmin,
|
||||
userId: data.userId,
|
||||
username: data.username,
|
||||
};
|
||||
if (data.ndCredential !== undefined) {
|
||||
updates.ndCredential = data.ndCredential;
|
||||
}
|
||||
updateServer(existingServer.id, updates);
|
||||
const updated = getServerById(existingServer.id);
|
||||
if (updated) setCurrentServer(updated);
|
||||
} else {
|
||||
if (data.ndCredential !== undefined) {
|
||||
serverItem.ndCredential = data.ndCredential;
|
||||
}
|
||||
addServer(serverItem);
|
||||
setCurrentServer(serverItem);
|
||||
}
|
||||
|
||||
addServer(serverItem);
|
||||
setCurrentServer(serverItem);
|
||||
|
||||
toast.success({
|
||||
message: t('form.addServer.success', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ import JellyfinIcon from '/@/renderer/features/servers/assets/jellyfin.png';
|
||||
import NavidromeIcon from '/@/renderer/features/servers/assets/navidrome.png';
|
||||
import SubsonicIcon from '/@/renderer/features/servers/assets/opensubsonic.png';
|
||||
import { IgnoreCorsSslSwitches } from '/@/renderer/features/servers/components/ignore-cors-ssl-switches';
|
||||
import { useAuthStoreActions } from '/@/renderer/store';
|
||||
import { useAuthStoreActions, useServerList } from '/@/renderer/store';
|
||||
import { Checkbox } from '/@/shared/components/checkbox/checkbox';
|
||||
import { Divider } from '/@/shared/components/divider/divider';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
@@ -98,6 +98,7 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
|
||||
const focusTrapRef = useFocusTrap(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { addServer, setCurrentServer } = useAuthStoreActions();
|
||||
const serverList = useServerList();
|
||||
const { servers: discovered } = useAutodiscovery();
|
||||
|
||||
const serverLock = isServerLock();
|
||||
@@ -128,6 +129,13 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
|
||||
};
|
||||
|
||||
const handleSubmit = form.onSubmit(async (values) => {
|
||||
if (serverLock && Object.keys(serverList).length >= 1) {
|
||||
toast.error({
|
||||
message: t('error.serverLockSingleServer', { postProcess: 'sentenceCase' }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const authFunction = api.controller.authenticate;
|
||||
|
||||
if (!authFunction) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { openContextModal } from '@mantine/modals';
|
||||
import isElectron from 'is-electron';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties';
|
||||
import JellyfinLogo from '/@/renderer/features/servers/assets/jellyfin.png';
|
||||
import NavidromeLogo from '/@/renderer/features/servers/assets/navidrome.png';
|
||||
import OpenSubsonicLogo from '/@/renderer/features/servers/assets/opensubsonic.png';
|
||||
@@ -23,6 +24,7 @@ export const ServerList = () => {
|
||||
const { t } = useTranslation();
|
||||
const currentServer = useCurrentServer();
|
||||
const serverListQuery = useServerList();
|
||||
const serverLock = isServerLock();
|
||||
|
||||
const handleAddServerModal = () => {
|
||||
openContextModal({
|
||||
@@ -70,15 +72,17 @@ export const ServerList = () => {
|
||||
</Accordion.Item>
|
||||
);
|
||||
})}
|
||||
<Group grow pt="md">
|
||||
<Button
|
||||
autoFocus
|
||||
leftSection={<Icon icon="add" />}
|
||||
onClick={handleAddServerModal}
|
||||
>
|
||||
{t('form.addServer.title', { postProcess: 'titleCase' })}
|
||||
</Button>
|
||||
</Group>
|
||||
{!serverLock && (
|
||||
<Group grow pt="md">
|
||||
<Button
|
||||
autoFocus
|
||||
leftSection={<Icon icon="add" />}
|
||||
onClick={handleAddServerModal}
|
||||
>
|
||||
{t('form.addServer.title', { postProcess: 'titleCase' })}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
</Accordion>
|
||||
{isElectron() && (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user