Lint all files

This commit is contained in:
jeffvli 2023-07-01 19:10:05 -07:00
parent 22af76b4d6
commit 30e52ebb54
334 changed files with 76519 additions and 75932 deletions

View file

@ -14,154 +14,154 @@ import { api } from '/@/renderer/api';
const localSettings = isElectron() ? window.electron.localSettings : null;
const SERVER_TYPES = [
{ label: 'Jellyfin', value: ServerType.JELLYFIN },
{ label: 'Navidrome', value: ServerType.NAVIDROME },
// { label: 'Subsonic', value: ServerType.SUBSONIC },
{ label: 'Jellyfin', value: ServerType.JELLYFIN },
{ label: 'Navidrome', value: ServerType.NAVIDROME },
// { label: 'Subsonic', value: ServerType.SUBSONIC },
];
interface AddServerFormProps {
onCancel: () => void;
onCancel: () => void;
}
export const AddServerForm = ({ onCancel }: AddServerFormProps) => {
const focusTrapRef = useFocusTrap(true);
const [isLoading, setIsLoading] = useState(false);
const { addServer, setCurrentServer } = useAuthStoreActions();
const serverList = useAuthStore((state) => state.serverList);
const focusTrapRef = useFocusTrap(true);
const [isLoading, setIsLoading] = useState(false);
const { addServer, setCurrentServer } = useAuthStoreActions();
const serverList = useAuthStore((state) => state.serverList);
const form = useForm({
initialValues: {
legacyAuth: false,
name: '',
password: '',
savePassword: false,
type: ServerType.JELLYFIN,
url: 'http://',
username: '',
},
});
const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username;
const handleSubmit = form.onSubmit(async (values) => {
const authFunction = api.controller.authenticate;
if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' });
}
try {
setIsLoading(true);
const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth,
password: values.password,
username: values.username,
const form = useForm({
initialValues: {
legacyAuth: false,
name: '',
password: '',
savePassword: false,
type: ServerType.JELLYFIN,
url: 'http://',
username: '',
},
values.type,
);
});
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username;
const serverItem = {
credential: data.credential,
id: nanoid(),
name: values.name,
ndCredential: data.ndCredential,
type: values.type,
url: values.url.replace(/\/$/, ''),
userId: data.userId,
username: data.username,
};
const handleSubmit = form.onSubmit(async (values) => {
const authFunction = api.controller.authenticate;
addServer(serverItem);
setCurrentServer(serverItem);
closeAllModals();
if (Object.keys(serverList).length === 0) {
toast.success({ message: 'Server has been added, reloading...' });
setTimeout(() => window.location.reload(), 2000);
} else {
toast.success({ message: 'Server has been added' });
}
if (localSettings && values.savePassword) {
const saved = await localSettings.passwordSet(values.password, serverItem.id);
if (!saved) {
toast.error({ message: 'Could not save password' });
if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' });
}
}
} catch (err: any) {
setIsLoading(false);
return toast.error({ message: err?.message });
}
return setIsLoading(false);
});
try {
setIsLoading(true);
const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth,
password: values.password,
username: values.username,
},
values.type,
);
return (
<form onSubmit={handleSubmit}>
<Stack
ref={focusTrapRef}
m={5}
>
<SegmentedControl
data={SERVER_TYPES}
{...form.getInputProps('type')}
/>
<Group grow>
<TextInput
data-autofocus
label="Name"
{...form.getInputProps('name')}
/>
<TextInput
label="Url"
{...form.getInputProps('url')}
/>
</Group>
<TextInput
label="Username"
{...form.getInputProps('username')}
/>
<PasswordInput
label="Password"
{...form.getInputProps('password')}
/>
{localSettings && form.values.type === ServerType.NAVIDROME && (
<Checkbox
label="Save password"
{...form.getInputProps('savePassword', {
type: 'checkbox',
})}
/>
)}
{form.values.type === ServerType.SUBSONIC && (
<Checkbox
label="Enable legacy authentication"
{...form.getInputProps('legacyAuth', { type: 'checkbox' })}
/>
)}
<Group position="right">
<Button
variant="subtle"
onClick={onCancel}
>
Cancel
</Button>
<Button
disabled={isSubmitDisabled}
loading={isLoading}
type="submit"
variant="filled"
>
Add
</Button>
</Group>
</Stack>
</form>
);
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const serverItem = {
credential: data.credential,
id: nanoid(),
name: values.name,
ndCredential: data.ndCredential,
type: values.type,
url: values.url.replace(/\/$/, ''),
userId: data.userId,
username: data.username,
};
addServer(serverItem);
setCurrentServer(serverItem);
closeAllModals();
if (Object.keys(serverList).length === 0) {
toast.success({ message: 'Server has been added, reloading...' });
setTimeout(() => window.location.reload(), 2000);
} else {
toast.success({ message: 'Server has been added' });
}
if (localSettings && values.savePassword) {
const saved = await localSettings.passwordSet(values.password, serverItem.id);
if (!saved) {
toast.error({ message: 'Could not save password' });
}
}
} catch (err: any) {
setIsLoading(false);
return toast.error({ message: err?.message });
}
return setIsLoading(false);
});
return (
<form onSubmit={handleSubmit}>
<Stack
ref={focusTrapRef}
m={5}
>
<SegmentedControl
data={SERVER_TYPES}
{...form.getInputProps('type')}
/>
<Group grow>
<TextInput
data-autofocus
label="Name"
{...form.getInputProps('name')}
/>
<TextInput
label="Url"
{...form.getInputProps('url')}
/>
</Group>
<TextInput
label="Username"
{...form.getInputProps('username')}
/>
<PasswordInput
label="Password"
{...form.getInputProps('password')}
/>
{localSettings && form.values.type === ServerType.NAVIDROME && (
<Checkbox
label="Save password"
{...form.getInputProps('savePassword', {
type: 'checkbox',
})}
/>
)}
{form.values.type === ServerType.SUBSONIC && (
<Checkbox
label="Enable legacy authentication"
{...form.getInputProps('legacyAuth', { type: 'checkbox' })}
/>
)}
<Group position="right">
<Button
variant="subtle"
onClick={onCancel}
>
Cancel
</Button>
<Button
disabled={isSubmitDisabled}
loading={isLoading}
type="submit"
variant="filled"
>
Add
</Button>
</Group>
</Stack>
</form>
);
};

View file

@ -14,157 +14,157 @@ import { api } from '/@/renderer/api';
const localSettings = isElectron() ? window.electron.localSettings : null;
interface EditServerFormProps {
isUpdate?: boolean;
onCancel: () => void;
password?: string;
server: ServerListItem;
isUpdate?: boolean;
onCancel: () => void;
password?: string;
server: ServerListItem;
}
const ModifiedFieldIndicator = () => {
return (
<Tooltip label="Field has been modified">
<span>
<RiInformationLine color="red" />
</span>
</Tooltip>
);
return (
<Tooltip label="Field has been modified">
<span>
<RiInformationLine color="red" />
</span>
</Tooltip>
);
};
export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditServerFormProps) => {
const { updateServer } = useAuthStoreActions();
const focusTrapRef = useFocusTrap();
const [isLoading, setIsLoading] = useState(false);
const { updateServer } = useAuthStoreActions();
const focusTrapRef = useFocusTrap();
const [isLoading, setIsLoading] = useState(false);
const form = useForm({
initialValues: {
legacyAuth: false,
name: server?.name,
password: password || '',
savePassword: server.savePassword || false,
type: server?.type,
url: server?.url,
username: server?.username,
},
});
const isSubsonic = form.values.type === ServerType.SUBSONIC;
const isNavidrome = form.values.type === ServerType.NAVIDROME;
const handleSubmit = form.onSubmit(async (values) => {
const authFunction = api.controller.authenticate;
if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' });
}
try {
setIsLoading(true);
const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth,
password: values.password,
username: values.username,
const form = useForm({
initialValues: {
legacyAuth: false,
name: server?.name,
password: password || '',
savePassword: server.savePassword || false,
type: server?.type,
url: server?.url,
username: server?.username,
},
values.type,
);
});
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const isSubsonic = form.values.type === ServerType.SUBSONIC;
const isNavidrome = form.values.type === ServerType.NAVIDROME;
const serverItem = {
credential: data.credential,
name: values.name,
ndCredential: data.ndCredential,
savePassword: values.savePassword,
type: values.type,
url: values.url,
userId: data.userId,
username: data.username,
};
const handleSubmit = form.onSubmit(async (values) => {
const authFunction = api.controller.authenticate;
updateServer(server.id, serverItem);
toast.success({ message: 'Server has been updated' });
if (localSettings) {
if (values.savePassword) {
const saved = await localSettings.passwordSet(values.password, server.id);
if (!saved) {
toast.error({ message: 'Could not save password' });
}
} else {
localSettings.passwordRemove(server.id);
if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' });
}
}
} catch (err: any) {
setIsLoading(false);
return toast.error({ message: err?.message });
}
if (isUpdate) closeAllModals();
return setIsLoading(false);
});
try {
setIsLoading(true);
const data: AuthenticationResponse | undefined = await authFunction(
values.url,
{
legacy: values.legacyAuth,
password: values.password,
username: values.username,
},
values.type,
);
return (
<form onSubmit={handleSubmit}>
<Stack ref={focusTrapRef}>
<TextInput
required
label="Name"
rightSection={form.isDirty('name') && <ModifiedFieldIndicator />}
{...form.getInputProps('name')}
/>
<TextInput
required
label="Url"
rightSection={form.isDirty('url') && <ModifiedFieldIndicator />}
{...form.getInputProps('url')}
/>
<TextInput
required
label="Username"
rightSection={form.isDirty('username') && <ModifiedFieldIndicator />}
{...form.getInputProps('username')}
/>
<PasswordInput
data-autofocus
required
label="Password"
{...form.getInputProps('password')}
/>
{localSettings && isNavidrome && (
<Checkbox
label="Save password"
{...form.getInputProps('savePassword', {
type: 'checkbox',
})}
/>
)}
{isSubsonic && (
<Checkbox
label="Enable legacy authentication"
{...form.getInputProps('legacyAuth', {
type: 'checkbox',
})}
/>
)}
<Group position="right">
<Button
variant="subtle"
onClick={onCancel}
>
Cancel
</Button>
<Button
loading={isLoading}
type="submit"
variant="filled"
>
Save
</Button>
</Group>
</Stack>
</form>
);
if (!data) {
return toast.error({ message: 'Authentication failed' });
}
const serverItem = {
credential: data.credential,
name: values.name,
ndCredential: data.ndCredential,
savePassword: values.savePassword,
type: values.type,
url: values.url,
userId: data.userId,
username: data.username,
};
updateServer(server.id, serverItem);
toast.success({ message: 'Server has been updated' });
if (localSettings) {
if (values.savePassword) {
const saved = await localSettings.passwordSet(values.password, server.id);
if (!saved) {
toast.error({ message: 'Could not save password' });
}
} else {
localSettings.passwordRemove(server.id);
}
}
} catch (err: any) {
setIsLoading(false);
return toast.error({ message: err?.message });
}
if (isUpdate) closeAllModals();
return setIsLoading(false);
});
return (
<form onSubmit={handleSubmit}>
<Stack ref={focusTrapRef}>
<TextInput
required
label="Name"
rightSection={form.isDirty('name') && <ModifiedFieldIndicator />}
{...form.getInputProps('name')}
/>
<TextInput
required
label="Url"
rightSection={form.isDirty('url') && <ModifiedFieldIndicator />}
{...form.getInputProps('url')}
/>
<TextInput
required
label="Username"
rightSection={form.isDirty('username') && <ModifiedFieldIndicator />}
{...form.getInputProps('username')}
/>
<PasswordInput
data-autofocus
required
label="Password"
{...form.getInputProps('password')}
/>
{localSettings && isNavidrome && (
<Checkbox
label="Save password"
{...form.getInputProps('savePassword', {
type: 'checkbox',
})}
/>
)}
{isSubsonic && (
<Checkbox
label="Enable legacy authentication"
{...form.getInputProps('legacyAuth', {
type: 'checkbox',
})}
/>
)}
<Group position="right">
<Button
variant="subtle"
onClick={onCancel}
>
Cancel
</Button>
<Button
loading={isLoading}
type="submit"
variant="filled"
>
Save
</Button>
</Group>
</Stack>
</form>
);
};

View file

@ -12,91 +12,91 @@ import { ServerListItem as ServerItem } from '/@/renderer/types';
const localSettings = isElectron() ? window.electron.localSettings : null;
interface ServerListItemProps {
server: ServerItem;
server: ServerItem;
}
export const ServerListItem = ({ server }: ServerListItemProps) => {
const [edit, editHandlers] = useDisclosure(false);
const [savedPassword, setSavedPassword] = useState('');
const { deleteServer } = useAuthStoreActions();
const [edit, editHandlers] = useDisclosure(false);
const [savedPassword, setSavedPassword] = useState('');
const { deleteServer } = useAuthStoreActions();
const handleDeleteServer = () => {
deleteServer(server.id);
localSettings?.passwordRemove(server.name);
};
const handleDeleteServer = () => {
deleteServer(server.id);
localSettings?.passwordRemove(server.name);
};
const handleEdit = useCallback(() => {
if (!edit && localSettings && server.savePassword) {
localSettings
.passwordGet(server.id)
.then((password: string | null) => {
if (password) {
setSavedPassword(password);
} else {
const handleEdit = useCallback(() => {
if (!edit && localSettings && server.savePassword) {
localSettings
.passwordGet(server.id)
.then((password: string | null) => {
if (password) {
setSavedPassword(password);
} else {
setSavedPassword('');
}
editHandlers.open();
return null;
})
.catch((error: any) => {
console.error(error);
setSavedPassword('');
editHandlers.open();
});
} else {
setSavedPassword('');
}
editHandlers.open();
return null;
})
.catch((error: any) => {
console.error(error);
setSavedPassword('');
editHandlers.open();
});
} else {
setSavedPassword('');
editHandlers.open();
}
}, [edit, editHandlers, server.id, server.savePassword]);
return (
<Stack>
<ServerSection
title={
<Group position="apart">
<Text>Server details</Text>
</Group>
editHandlers.open();
}
>
{edit ? (
<EditServerForm
password={savedPassword}
server={server}
onCancel={() => editHandlers.toggle()}
/>
) : (
<Stack>
<Group noWrap>
<Stack>
<Text>URL</Text>
<Text>Username</Text>
</Stack>
<Stack>
<Text>{server.url}</Text>
<Text>{server.username}</Text>
</Stack>
</Group>
<Group grow>
<Button
leftIcon={<RiEdit2Fill />}
tooltip={{ label: 'Edit server details' }}
}, [edit, editHandlers, server.id, server.savePassword]);
return (
<Stack>
<ServerSection
title={
<Group position="apart">
<Text>Server details</Text>
</Group>
}
>
{edit ? (
<EditServerForm
password={savedPassword}
server={server}
onCancel={() => editHandlers.toggle()}
/>
) : (
<Stack>
<Group noWrap>
<Stack>
<Text>URL</Text>
<Text>Username</Text>
</Stack>
<Stack>
<Text>{server.url}</Text>
<Text>{server.username}</Text>
</Stack>
</Group>
<Group grow>
<Button
leftIcon={<RiEdit2Fill />}
tooltip={{ label: 'Edit server details' }}
variant="subtle"
onClick={() => handleEdit()}
>
Edit
</Button>
</Group>
</Stack>
)}
</ServerSection>
<Divider my="sm" />
<TimeoutButton
leftIcon={<RiDeleteBin2Line />}
timeoutProps={{ callback: handleDeleteServer, duration: 1000 }}
variant="subtle"
onClick={() => handleEdit()}
>
Edit
</Button>
</Group>
</Stack>
)}
</ServerSection>
<Divider my="sm" />
<TimeoutButton
leftIcon={<RiDeleteBin2Line />}
timeoutProps={{ callback: handleDeleteServer, duration: 1000 }}
variant="subtle"
>
Remove server
</TimeoutButton>
</Stack>
);
>
Remove server
</TimeoutButton>
</Stack>
);
};

View file

@ -13,106 +13,106 @@ import { titleCase } from '/@/renderer/utils';
const localSettings = isElectron() ? window.electron.localSettings : null;
export const ServerList = () => {
const serverListQuery = useServerList();
const serverListQuery = useServerList();
const handleAddServerModal = () => {
openContextModal({
innerProps: {
modalBody: (vars: ContextModalVars) => (
<AddServerForm onCancel={() => vars.context.closeModal(vars.id)} />
),
},
modal: 'base',
title: 'Add server',
const handleAddServerModal = () => {
openContextModal({
innerProps: {
modalBody: (vars: ContextModalVars) => (
<AddServerForm onCancel={() => vars.context.closeModal(vars.id)} />
),
},
modal: 'base',
title: 'Add server',
});
};
const [ignoreCORS, setIgnoreCORS] = useLocalStorage({
defaultValue: 'false',
key: 'ignore_cors',
});
};
const [ignoreCORS, setIgnoreCORS] = useLocalStorage({
defaultValue: 'false',
key: 'ignore_cors',
});
const [ignoreSSL, setIgnoreSSL] = useLocalStorage({
defaultValue: 'false',
key: 'ignore_ssl',
});
const [ignoreSSL, setIgnoreSSL] = useLocalStorage({
defaultValue: 'false',
key: 'ignore_ssl',
});
const handleUpdateIgnoreCORS = (e: ChangeEvent<HTMLInputElement>) => {
setIgnoreCORS(String(e.currentTarget.checked));
const handleUpdateIgnoreCORS = (e: ChangeEvent<HTMLInputElement>) => {
setIgnoreCORS(String(e.currentTarget.checked));
if (isElectron()) {
localSettings?.set('ignore_cors', e.currentTarget.checked);
}
};
if (isElectron()) {
localSettings?.set('ignore_cors', e.currentTarget.checked);
}
};
const handleUpdateIgnoreSSL = (e: ChangeEvent<HTMLInputElement>) => {
setIgnoreSSL(String(e.currentTarget.checked));
const handleUpdateIgnoreSSL = (e: ChangeEvent<HTMLInputElement>) => {
setIgnoreSSL(String(e.currentTarget.checked));
if (isElectron()) {
localSettings?.set('ignore_ssl', e.currentTarget.checked);
}
};
if (isElectron()) {
localSettings?.set('ignore_ssl', e.currentTarget.checked);
}
};
return (
<>
<Group
mb={10}
position="right"
sx={{
position: 'absolute',
right: 55,
transform: 'translateY(-3.5rem)',
zIndex: 2000,
}}
>
<Button
autoFocus
compact
leftIcon={<RiAddFill size={15} />}
size="sm"
variant="filled"
onClick={handleAddServerModal}
>
Add server
</Button>
</Group>
<Stack>
<Accordion variant="separated">
{Object.keys(serverListQuery)?.map((serverId) => {
const server = serverListQuery[serverId];
return (
<Accordion.Item
key={server.id}
value={server.name}
>
<Accordion.Control icon={<RiServerFill size={15} />}>
<Group position="apart">
{titleCase(server?.type)} - {server?.name}
</Group>
</Accordion.Control>
<Accordion.Panel>
<ServerListItem server={server} />
</Accordion.Panel>
</Accordion.Item>
);
})}
</Accordion>
<Divider />
<Group>
<Switch
checked={ignoreCORS === 'true'}
label="Ignore CORS (requires restart)"
onChange={handleUpdateIgnoreCORS}
/>
</Group>
<Group>
<Switch
checked={ignoreSSL === 'true'}
label="Ignore SSL (requires restart)"
onChange={handleUpdateIgnoreSSL}
/>
</Group>
</Stack>
</>
);
return (
<>
<Group
mb={10}
position="right"
sx={{
position: 'absolute',
right: 55,
transform: 'translateY(-3.5rem)',
zIndex: 2000,
}}
>
<Button
autoFocus
compact
leftIcon={<RiAddFill size={15} />}
size="sm"
variant="filled"
onClick={handleAddServerModal}
>
Add server
</Button>
</Group>
<Stack>
<Accordion variant="separated">
{Object.keys(serverListQuery)?.map((serverId) => {
const server = serverListQuery[serverId];
return (
<Accordion.Item
key={server.id}
value={server.name}
>
<Accordion.Control icon={<RiServerFill size={15} />}>
<Group position="apart">
{titleCase(server?.type)} - {server?.name}
</Group>
</Accordion.Control>
<Accordion.Panel>
<ServerListItem server={server} />
</Accordion.Panel>
</Accordion.Item>
);
})}
</Accordion>
<Divider />
<Group>
<Switch
checked={ignoreCORS === 'true'}
label="Ignore CORS (requires restart)"
onChange={handleUpdateIgnoreCORS}
/>
</Group>
<Group>
<Switch
checked={ignoreSSL === 'true'}
label="Ignore SSL (requires restart)"
onChange={handleUpdateIgnoreSSL}
/>
</Group>
</Stack>
</>
);
};

View file

@ -3,22 +3,22 @@ import styled from 'styled-components';
import { Text } from '/@/renderer/components';
interface ServerSectionProps {
children: React.ReactNode;
title: string | React.ReactNode;
children: React.ReactNode;
title: string | React.ReactNode;
}
const Container = styled.div``;
const Section = styled.div`
padding: 1rem;
border: 1px dashed var(--generic-border-color);
padding: 1rem;
border: 1px dashed var(--generic-border-color);
`;
export const ServerSection = ({ title, children }: ServerSectionProps) => {
return (
<Container>
{React.isValidElement(title) ? title : <Text>{title}</Text>}
<Section>{children}</Section>
</Container>
);
return (
<Container>
{React.isValidElement(title) ? title : <Text>{title}</Text>}
<Section>{children}</Section>
</Container>
);
};