mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-08 21:10:12 +02:00
add settings configuration for integrations
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import {
|
||||
SettingOption,
|
||||
SettingsSection,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import {
|
||||
useGeneralSettings,
|
||||
useIntegrationsSettings,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store';
|
||||
import { MultiSelect } from '/@/shared/components/multi-select/multi-select';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Switch } from '/@/shared/components/switch/switch';
|
||||
import { TextInput } from '/@/shared/components/text-input/text-input';
|
||||
|
||||
const MUSICBRAINZ_RELEASE_TYPES = [
|
||||
'album',
|
||||
'single',
|
||||
'ep',
|
||||
'broadcast',
|
||||
'compilation',
|
||||
'live',
|
||||
'remix',
|
||||
'appears-on',
|
||||
'audiobook',
|
||||
'audio drama',
|
||||
'demo',
|
||||
'dj-mix',
|
||||
'field recording',
|
||||
'interview',
|
||||
'mixtape/street',
|
||||
'other',
|
||||
'soundtrack',
|
||||
'spokenword',
|
||||
];
|
||||
|
||||
export const IntegrationsTab = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const { musicBrainz } = useGeneralSettings();
|
||||
const settings = useIntegrationsSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
|
||||
const updateIntegrations = (updates: Partial<typeof settings>) => {
|
||||
setSettings({
|
||||
integrations: {
|
||||
...settings,
|
||||
...updates,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const options: SettingOption[] = [
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label={t('setting.musicBrainzQueries', { postProcess: 'sentenceCase' })}
|
||||
defaultChecked={settings.musicBrainz}
|
||||
onChange={(e) => updateIntegrations({ musicBrainz: e.currentTarget.checked })}
|
||||
/>
|
||||
),
|
||||
description: t('setting.musicBrainzQueries', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('setting.musicBrainzQueries', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<MultiSelect
|
||||
aria-label={t('setting.musicbrainzExcludeReleaseTypes', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
clearable
|
||||
data={MUSICBRAINZ_RELEASE_TYPES}
|
||||
defaultValue={settings.musicBrainzExcludeReleaseTypes}
|
||||
onChange={(value) =>
|
||||
updateIntegrations({ musicBrainzExcludeReleaseTypes: value })
|
||||
}
|
||||
width={300}
|
||||
/>
|
||||
),
|
||||
description: t('setting.musicbrainzExcludeReleaseTypes', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !musicBrainz || !settings.musicBrainz,
|
||||
title: t('setting.musicbrainzExcludeReleaseTypes', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<TextInput
|
||||
defaultValue={settings.musicBrainzPrioritizeCountries.join(', ')}
|
||||
key={settings.musicBrainzPrioritizeCountries.join(',')}
|
||||
onBlur={(e) => {
|
||||
const value = e.currentTarget.value
|
||||
.split(/[,;\s]+/)
|
||||
.map((s) => s.trim().toUpperCase())
|
||||
.filter(Boolean);
|
||||
updateIntegrations({ musicBrainzPrioritizeCountries: value });
|
||||
}}
|
||||
placeholder="e.g. US, GB, DE"
|
||||
width={300}
|
||||
/>
|
||||
),
|
||||
description: t('setting.musicbrainzPrioritizeCountries', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
isHidden: !musicBrainz || !settings.musicBrainz,
|
||||
title: t('setting.musicbrainzPrioritizeCountries', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label={t('setting.youtube', { postProcess: 'sentenceCase' })}
|
||||
defaultChecked={settings.youtube}
|
||||
onChange={(e) => updateIntegrations({ youtube: e.currentTarget.checked })}
|
||||
/>
|
||||
),
|
||||
description: t('setting.youtube', {
|
||||
context: 'description',
|
||||
postProcess: 'sentenceCase',
|
||||
}),
|
||||
title: t('setting.youtube', { postProcess: 'sentenceCase' }),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<SettingsSection
|
||||
options={options}
|
||||
title={t('page.setting.integrationsTab', { postProcess: 'sentenceCase' })}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
});
|
||||
@@ -24,6 +24,14 @@ const HotkeysTab = lazy(() =>
|
||||
})),
|
||||
);
|
||||
|
||||
const IntegrationsTab = lazy(() =>
|
||||
import('/@/renderer/features/settings/components/integrations/integrations-tab').then(
|
||||
(module) => ({
|
||||
default: module.IntegrationsTab,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
const WindowTab = lazy(() =>
|
||||
import('/@/renderer/features/settings/components/window/window-tab').then((module) => ({
|
||||
default: module.WindowTab,
|
||||
@@ -61,6 +69,9 @@ export const SettingsContent = () => {
|
||||
<Tabs.Tab value="hotkeys">
|
||||
{t('page.setting.hotkeysTab', { postProcess: 'sentenceCase' })}
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="integrations">
|
||||
{t('page.setting.integrationsTab', { postProcess: 'sentenceCase' })}
|
||||
</Tabs.Tab>
|
||||
{isElectron() && (
|
||||
<Tabs.Tab value="window">
|
||||
{t('page.setting.windowTab', { postProcess: 'sentenceCase' })}
|
||||
@@ -85,6 +96,11 @@ export const SettingsContent = () => {
|
||||
<HotkeysTab />
|
||||
</Suspense>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="integrations">
|
||||
<Suspense fallback={null}>
|
||||
<IntegrationsTab />
|
||||
</Suspense>
|
||||
</Tabs.Panel>
|
||||
{isElectron() && (
|
||||
<Tabs.Panel value="window">
|
||||
<Suspense fallback={null}>
|
||||
|
||||
Reference in New Issue
Block a user