diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 3eb362f0..7580e53a 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -237,6 +237,8 @@ "input_legacyAuthentication": "enable legacy authentication", "input_name": "server name", "input_password": "password", + "input_preferInstantMix": "prefer instant mix", + "input_preferInstantMixDescription": "only use instant mix to get similar songs. useful if you have plugins that modify this behavior", "input_savePassword": "save password", "input_url": "url", "input_username": "username", diff --git a/src/renderer/api/jellyfin/jellyfin-controller.ts b/src/renderer/api/jellyfin/jellyfin-controller.ts index 9ab138f9..4926c2b5 100644 --- a/src/renderer/api/jellyfin/jellyfin-controller.ts +++ b/src/renderer/api/jellyfin/jellyfin-controller.ts @@ -627,30 +627,34 @@ export const JellyfinController: ControllerEndpoint = { getSimilarSongs: async (args) => { const { apiClientProps, query } = args; - // Prefer getSimilarSongs, where possible. Fallback to InstantMix - // where no similar songs were found. - const res = await jfApiClient(apiClientProps).getSimilarSongs({ - params: { - itemId: query.songId, - }, - query: { - Fields: 'Genres, DateCreated, MediaSources, ParentId', - Limit: query.count, - UserId: apiClientProps.server?.userId || undefined, - }, - }); + if (apiClientProps.server?.preferInstantMix !== true) { + // Prefer getSimilarSongs, where possible, and not overridden. + // InstantMix can be overridden by plugins, so this may be preferred by the user. + // Otherwise, similarSongs may have a better output than InstantMix, if sufficient + // data exists from the server. + const res = await jfApiClient(apiClientProps).getSimilarSongs({ + params: { + itemId: query.songId, + }, + query: { + Fields: 'Genres, DateCreated, MediaSources, ParentId', + Limit: query.count, + UserId: apiClientProps.server?.userId || undefined, + }, + }); - if (res.status === 200 && res.body.Items.length) { - const results = res.body.Items.reduce((acc, song) => { - if (song.Id !== query.songId) { - acc.push(jfNormalize.song(song, apiClientProps.server, '')); + if (res.status === 200 && res.body.Items.length) { + const results = res.body.Items.reduce((acc, song) => { + if (song.Id !== query.songId) { + acc.push(jfNormalize.song(song, apiClientProps.server, '')); + } + + return acc; + }, []); + + if (results.length > 0) { + return results; } - - return acc; - }, []); - - if (results.length > 0) { - return results; } } diff --git a/src/renderer/features/servers/components/add-server-form.tsx b/src/renderer/features/servers/components/add-server-form.tsx index 4116aa32..aa8dc623 100644 --- a/src/renderer/features/servers/components/add-server-form.tsx +++ b/src/renderer/features/servers/components/add-server-form.tsx @@ -21,7 +21,7 @@ import { Stack } from '/@/shared/components/stack/stack'; import { TextInput } from '/@/shared/components/text-input/text-input'; import { Text } from '/@/shared/components/text/text'; import { toast } from '/@/shared/components/toast/toast'; -import { AuthenticationResponse } from '/@/shared/types/domain-types'; +import { AuthenticationResponse, ServerListItem } from '/@/shared/types/domain-types'; import { DiscoveredServerItem, ServerType, toServerType } from '/@/shared/types/types'; const autodiscover = isElectron() ? window.api.autodiscover : null; @@ -99,7 +99,8 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { legacyAuth: false, name: (localSettings ? localSettings.env.SERVER_NAME : window.SERVER_NAME) ?? '', password: '', - savePassword: false, + preferInstantMix: undefined, + savePassword: undefined, type: (localSettings ? localSettings.env.SERVER_TYPE @@ -151,17 +152,28 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { }); } - const serverItem = { + const serverItem: ServerListItem = { credential: data.credential, id: nanoid(), name: values.name, - ndCredential: data.ndCredential, type: values.type as ServerType, url: values.url.replace(/\/$/, ''), userId: data.userId, username: data.username, }; + if (values.preferInstantMix !== undefined) { + serverItem.preferInstantMix = values.preferInstantMix; + } + + if (values.savePassword !== undefined) { + serverItem.savePassword = values.savePassword; + } + + if (data.ndCredential !== undefined) { + serverItem.ndCredential = data.ndCredential; + } + addServer(serverItem); setCurrentServer(serverItem); closeAllModals(); @@ -271,6 +283,21 @@ export const AddServerForm = ({ onCancel }: AddServerFormProps) => { {...form.getInputProps('legacyAuth', { type: 'checkbox' })} /> )} + {form.values.type === ServerType.JELLYFIN && ( + + )} {onCancel && (