refactor(Settings): use MultiselectMenu instead Multiselect

This commit is contained in:
Botzy 2025-02-28 17:49:20 +02:00
parent 794f4e48ac
commit 7ea974f1da
3 changed files with 101 additions and 63 deletions

View file

@ -8,7 +8,7 @@ const { default: Icon } = require('@stremio/stremio-icons/react');
const { useRouteFocused } = require('stremio-router');
const { useServices } = require('stremio/services');
const { useProfile, usePlatform, useStreamingServer, withCoreSuspender, useToast } = require('stremio/common');
const { Button, ColorInput, MainNavBars, Multiselect, Toggle } = require('stremio/components');
const { Button, ColorInput, MainNavBars, MultiselectMenu, Toggle } = require('stremio/components');
const useProfileSettingsInputs = require('./useProfileSettingsInputs');
const useStreamingServerSettingsInputs = require('./useStreamingServerSettingsInputs');
const useDataExport = require('./useDataExport');
@ -316,7 +316,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_UI_LANGUAGE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
tabIndex={-1}
{...interfaceLanguageSelect}
@ -333,7 +333,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SUBTITLES_LANGUAGE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...subtitlesLanguageSelect}
/>
@ -356,7 +356,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SUBTITLES_SIZE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...subtitlesSizeSelect}
/>
@ -398,7 +398,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_DEFAULT_AUDIO_TRACK') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...audioLanguageSelect}
/>
@ -423,7 +423,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SEEK_KEY') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...seekTimeDurationSelect}
/>
@ -432,7 +432,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SEEK_KEY_SHIFT') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...seekShortTimeDurationSelect}
/>
@ -467,7 +467,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_NEXT_VIDEO_POPUP_DURATION') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
disabled={!profile.settings.bingeWatching}
{...nextVideoPopupDurationSelect}
@ -483,7 +483,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_PLAY_IN_EXTERNAL_PLAYER') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...playInExternalPlayerSelect}
/>
@ -527,7 +527,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_HTTPS_ENDPOINT') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...remoteEndpointSelect}
/>
@ -541,7 +541,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SERVER_CACHE_SIZE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...cacheSizeSelect}
/>
@ -555,7 +555,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_SERVER_TORRENT_PROFILE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...torrentProfileSelect}
/>
@ -569,7 +569,7 @@ const Settings = () => {
<div className={styles['option-name-container']}>
<div className={styles['label']}>{ t('SETTINGS_TRANSCODE_PROFILE') }</div>
</div>
<Multiselect
<MultiselectMenu
className={classnames(styles['option-input-container'], styles['multiselect-container'])}
{...transcodingProfileSelect}
/>

View file

@ -15,17 +15,18 @@ const useProfileSettingsInputs = (profile) => {
value: codes[0],
label: name,
})),
selected: [
interfaceLanguages.find(({ codes }) => codes[1] === profile.settings.interfaceLanguage)?.codes?.[0] || profile.settings.interfaceLanguage
],
onSelect: (event) => {
selectedOption: {
label: interfaceLanguages.find(({ codes }) => codes[0] === profile.settings.interfaceLanguage)?.name,
value: interfaceLanguages.find(({ codes }) => codes[1] === profile.settings.interfaceLanguage)?.codes?.[0] || profile.settings.interfaceLanguage
},
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
interfaceLanguage: event.value
interfaceLanguage: value
}
}
});
@ -36,15 +37,18 @@ const useProfileSettingsInputs = (profile) => {
value: code,
label: languageNames[code]
})),
selected: [profile.settings.subtitlesLanguage],
onSelect: (event) => {
selectedOption: {
label: languageNames[profile.settings.subtitlesLanguage],
value: profile.settings.subtitlesLanguage
},
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
subtitlesLanguage: event.value
subtitlesLanguage: value
}
}
});
@ -55,18 +59,21 @@ const useProfileSettingsInputs = (profile) => {
value: `${size}`,
label: `${size}%`
})),
selected: [`${profile.settings.subtitlesSize}`],
renderLabelText: () => {
selectedOption: {
label: `${profile.settings.subtitlesSize}%`,
value: `${profile.settings.subtitlesSize}`
},
title: () => {
return `${profile.settings.subtitlesSize}%`;
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
subtitlesSize: parseInt(event.value, 10)
subtitlesSize: parseInt(value, 10)
}
}
});
@ -74,14 +81,14 @@ const useProfileSettingsInputs = (profile) => {
}), [profile.settings]);
const subtitlesTextColorInput = React.useMemo(() => ({
value: profile.settings.subtitlesTextColor,
onChange: (event) => {
onChange: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
subtitlesTextColor: event.value
subtitlesTextColor: value
}
}
});
@ -89,14 +96,14 @@ const useProfileSettingsInputs = (profile) => {
}), [profile.settings]);
const subtitlesBackgroundColorInput = React.useMemo(() => ({
value: profile.settings.subtitlesBackgroundColor,
onChange: (event) => {
onChange: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
subtitlesBackgroundColor: event.value
subtitlesBackgroundColor: value
}
}
});
@ -104,14 +111,14 @@ const useProfileSettingsInputs = (profile) => {
}), [profile.settings]);
const subtitlesOutlineColorInput = React.useMemo(() => ({
value: profile.settings.subtitlesOutlineColor,
onChange: (event) => {
onChange: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
subtitlesOutlineColor: event.value
subtitlesOutlineColor: value
}
}
});
@ -122,15 +129,18 @@ const useProfileSettingsInputs = (profile) => {
value: code,
label: languageNames[code]
})),
selected: [profile.settings.audioLanguage],
onSelect: (event) => {
selectedOption: {
label: languageNames[profile.settings.audioLanguage],
value: profile.settings.audioLanguage
},
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
audioLanguage: event.value
audioLanguage: value
}
}
});
@ -172,18 +182,21 @@ const useProfileSettingsInputs = (profile) => {
value: `${size}`,
label: `${size / 1000} ${t('SECONDS')}`
})),
selected: [`${profile.settings.seekTimeDuration}`],
renderLabelText: () => {
selectedOption: {
label: `${profile.settings.seekTimeDuration / 1000} ${t('SECONDS')}`,
value: `${profile.settings.seekTimeDuration}`
},
title: () => {
return `${profile.settings.seekTimeDuration / 1000} ${t('SECONDS')}`;
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
seekTimeDuration: parseInt(event.value, 10)
seekTimeDuration: parseInt(value, 10)
}
}
});
@ -194,18 +207,21 @@ const useProfileSettingsInputs = (profile) => {
value: `${size}`,
label: `${size / 1000} ${t('SECONDS')}`
})),
selected: [`${profile.settings.seekShortTimeDuration}`],
renderLabelText: () => {
selectedOption: {
label: `${profile.settings.seekShortTimeDuration / 1000} ${t('SECONDS')}`,
value: `${profile.settings.seekShortTimeDuration}`,
},
title: () => {
return `${profile.settings.seekShortTimeDuration / 1000} ${t('SECONDS')}`;
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
seekShortTimeDuration: parseInt(event.value, 10)
seekShortTimeDuration: parseInt(value, 10)
}
}
});
@ -218,19 +234,22 @@ const useProfileSettingsInputs = (profile) => {
value,
label: t(label),
})),
selected: [profile.settings.playerType],
renderLabelText: () => {
selectedOption: {
label: CONSTANTS.EXTERNAL_PLAYERS.find(({ value }) => value === profile.settings.playerType)?.label,
value: profile.settings.playerType
},
title: () => {
const selectedOption = CONSTANTS.EXTERNAL_PLAYERS.find(({ value }) => value === profile.settings.playerType);
return selectedOption ? t(selectedOption.label, { defaultValue: selectedOption.label }) : profile.settings.playerType;
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
playerType: event.value
playerType: value
}
}
});
@ -241,21 +260,26 @@ const useProfileSettingsInputs = (profile) => {
value: `${duration}`,
label: duration === 0 ? 'Disabled' : `${duration / 1000} ${t('SECONDS')}`
})),
selected: [`${profile.settings.nextVideoNotificationDuration}`],
renderLabelText: () => {
selectedOption: {
label: profile.settings.nextVideoNotificationDuration === 0
? 'Disabled'
: `${profile.settings.nextVideoNotificationDuration / 1000} ${t('SECONDS')}`,
value: `${profile.settings.nextVideoNotificationDuration}`
},
title: () => {
return profile.settings.nextVideoNotificationDuration === 0 ?
'Disabled'
:
`${profile.settings.nextVideoNotificationDuration / 1000} ${t('SECONDS')}`;
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'Ctx',
args: {
action: 'UpdateSettings',
args: {
...profile.settings,
nextVideoNotificationDuration: parseInt(event.value, 10)
nextVideoNotificationDuration: parseInt(value, 10)
}
}
});

View file

@ -77,15 +77,18 @@ const useStreamingServerSettingsInputs = (streamingServer) => {
value: address,
}))
],
selected: [streamingServer.settings.content.remoteHttps],
onSelect: (event) => {
selectedOption: {
label: streamingServer.settings.content.remoteHttps || t('SETTINGS_DISABLED'),
value: streamingServer.settings.content.remoteHttps
},
onSelect: (value) => {
core.transport.dispatch({
action: 'StreamingServer',
args: {
action: 'UpdateSettings',
args: {
...streamingServer.settings.content,
remoteHttps: event.value,
remoteHttps: value,
}
}
});
@ -103,18 +106,21 @@ const useStreamingServerSettingsInputs = (streamingServer) => {
label: cacheSizeToString(size),
value: JSON.stringify(size)
})),
selected: [JSON.stringify(streamingServer.settings.content.cacheSize)],
renderLabelText: () => {
selectedOption: {
label: cacheSizeToString(streamingServer.settings.content.cacheSize),
value: JSON.stringify(streamingServer.settings.content.cacheSize)
},
title: () => {
return cacheSizeToString(streamingServer.settings.content.cacheSize);
},
onSelect: (event) => {
onSelect: (value) => {
core.transport.dispatch({
action: 'StreamingServer',
args: {
action: 'UpdateSettings',
args: {
...streamingServer.settings.content,
cacheSize: JSON.parse(event.value),
cacheSize: JSON.parse(value),
}
}
});
@ -152,15 +158,20 @@ const useStreamingServerSettingsInputs = (streamingServer) => {
:
[]
),
selected: [JSON.stringify(selectedTorrentProfile)],
onSelect: (event) => {
selectedOption: {
label: isCustomTorrentProfileSelected
? 'custom'
: Object.keys(TORRENT_PROFILES).find((profileName) => JSON.stringify(TORRENT_PROFILES[profileName]) === JSON.stringify(selectedTorrentProfile)),
value: JSON.stringify(selectedTorrentProfile)
},
onSelect: (value) => {
core.transport.dispatch({
action: 'StreamingServer',
args: {
action: 'UpdateSettings',
args: {
...streamingServer.settings.content,
...JSON.parse(event.value),
...JSON.parse(value),
}
}
});
@ -183,15 +194,18 @@ const useStreamingServerSettingsInputs = (streamingServer) => {
value: name,
}))
],
selected: [streamingServer.settings.content.transcodeProfile],
onSelect: (event) => {
selectedOption: {
label: streamingServer.settings.content.transcodeProfile || t('SETTINGS_DISABLED'),
value: streamingServer.settings.content.transcodeProfile
},
onSelect: (value) => {
core.transport.dispatch({
action: 'StreamingServer',
args: {
action: 'UpdateSettings',
args: {
...streamingServer.settings.content,
transcodeProfile: event.value,
transcodeProfile: value,
}
}
});