diff --git a/client/src/javascript/components/general/form-elements/FilesystemBrowserTextbox.tsx b/client/src/javascript/components/general/form-elements/FilesystemBrowserTextbox.tsx index f508c14f..dd2c0f6f 100644 --- a/client/src/javascript/components/general/form-elements/FilesystemBrowserTextbox.tsx +++ b/client/src/javascript/components/general/form-elements/FilesystemBrowserTextbox.tsx @@ -27,7 +27,10 @@ const FilesystemBrowserTextbox: FC = ({ onChange, }: FilesystemBrowserTextboxProps) => { const [destination, setDestination] = useState( - suggested ?? SettingStore.floodSettings.torrentDestination ?? SettingStore.clientSettings?.directoryDefault ?? '', + suggested ?? + SettingStore.floodSettings.torrentDestinations?.[''] ?? + SettingStore.clientSettings?.directoryDefault ?? + '', ); const [isDirectoryListOpen, setIsDirectoryListOpen] = useState(false); diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.tsx b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.tsx index fda779f1..ca8146c6 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.tsx +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.tsx @@ -73,10 +73,12 @@ const AddTorrentsByFile: FC = () => { return; } + const tagsArray = tags != null ? tags.split(',') : undefined; + TorrentActions.addTorrentsByFiles({ files: filesData as [string, ...string[]], destination, - tags: tags != null ? tags.split(',') : undefined, + tags: tagsArray, isBasePath, isCompleted, start, @@ -87,6 +89,7 @@ const AddTorrentsByFile: FC = () => { saveAddTorrentsUserPreferences({ start, destination, + tags: tagsArray, tab: 'by-file', }); }} diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByURL.tsx b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByURL.tsx index 4b3f1a06..77790082 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByURL.tsx +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByURL.tsx @@ -93,6 +93,8 @@ const AddTorrentsByURL: FC = () => { } : undefined; + const tags = formData.tags != null ? formData.tags.split(',') : undefined; + TorrentActions.addTorrentsByUrls({ urls: urls as [string, ...string[]], cookies: processedCookies, @@ -100,7 +102,7 @@ const AddTorrentsByURL: FC = () => { isBasePath: formData.isBasePath, isCompleted: formData.isCompleted, start: formData.start, - tags: formData.tags != null ? formData.tags.split(',') : undefined, + tags, }).then(() => { UIStore.dismissModal(); }); @@ -108,6 +110,7 @@ const AddTorrentsByURL: FC = () => { saveAddTorrentsUserPreferences({ start: formData.start, destination: formData.destination, + tags, tab: 'by-url', }); }} diff --git a/client/src/javascript/components/torrent-list/TorrentList.tsx b/client/src/javascript/components/torrent-list/TorrentList.tsx index 83ae8514..798b122b 100644 --- a/client/src/javascript/components/torrent-list/TorrentList.tsx +++ b/client/src/javascript/components/torrent-list/TorrentList.tsx @@ -36,7 +36,7 @@ const TorrentDropzone: FC<{children: ReactNode}> = ({children}: {children: React TorrentActions.addTorrentsByFiles({ files: filesData as [string, ...string[]], destination: - SettingStore.floodSettings.torrentDestination || SettingStore.clientSettings?.directoryDefault || '', + SettingStore.floodSettings.torrentDestinations?.[''] ?? SettingStore.clientSettings?.directoryDefault ?? '', isBasePath: false, start: SettingStore.floodSettings.startTorrentsOnLoad, }); diff --git a/client/src/javascript/util/userPreferences.ts b/client/src/javascript/util/userPreferences.ts index 4875f529..e4bc254b 100644 --- a/client/src/javascript/util/userPreferences.ts +++ b/client/src/javascript/util/userPreferences.ts @@ -1,14 +1,18 @@ import type {FloodSettings} from '@shared/types/FloodSettings'; +import type {TorrentProperties} from '@shared/types/Torrent'; import SettingActions from '../actions/SettingActions'; +import SettingStore from '../stores/SettingStore'; export const saveAddTorrentsUserPreferences = ({ start, destination, + tags, tab, }: { start?: FloodSettings['startTorrentsOnLoad']; - destination?: FloodSettings['torrentDestination']; + destination?: string; + tags?: TorrentProperties['tags']; tab?: FloodSettings['UITorrentsAddTab']; }) => { const changedSettings: Partial = {}; @@ -18,7 +22,15 @@ export const saveAddTorrentsUserPreferences = ({ } if (destination != null && destination !== '') { - changedSettings.torrentDestination = destination; + if (changedSettings.torrentDestinations == null) { + changedSettings.torrentDestinations = SettingStore.floodSettings.torrentDestinations || {}; + } + + if (typeof tags?.[0] === 'string') { + changedSettings.torrentDestinations[tags[0]] = destination; + } else { + changedSettings.torrentDestinations[''] = destination; + } } if (tab != null) { diff --git a/server/routes/api/index.test.ts b/server/routes/api/index.test.ts index f5853d61..b4d990e2 100644 --- a/server/routes/api/index.test.ts +++ b/server/routes/api/index.test.ts @@ -11,7 +11,9 @@ const authToken = `jwt=${getAuthToken('_config')}`; const settings: Partial = { startTorrentsOnLoad: false, - torrentDestination: '/home/download/test', + torrentDestinations: { + '': '/home/download/test', + }, }; describe('PATCH /api/settings', () => { diff --git a/server/routes/api/torrents.ts b/server/routes/api/torrents.ts index 8006b262..041a2f90 100644 --- a/server/routes/api/torrents.ts +++ b/server/routes/api/torrents.ts @@ -27,28 +27,26 @@ import {getTempPath} from '../../models/TemporaryStorage'; const getDestination = async ( services: Express.Request['services'], - {destination}: {destination?: string}, + {destination, tags}: {destination?: string; tags?: Array}, ): Promise => { let autoDestination = destination === '' ? undefined : destination; + // Use preferred destination of the first tag + if (autoDestination == null) { + await services?.settingService.get('torrentDestinations').then( + ({torrentDestinations}) => { + autoDestination = torrentDestinations?.[tags?.[0] ?? '']; + }, + () => undefined, + ); + } + // Use default destination of torrent client if (autoDestination == null) { const {directoryDefault} = (await services?.clientGatewayService?.getClientSettings().catch(() => undefined)) || {}; autoDestination = directoryDefault; } - // Use last download destination - if (autoDestination == null) { - await services?.settingService.get('torrentDestination').then( - ({torrentDestination}) => { - if (torrentDestination != null) { - autoDestination = torrentDestination; - } - }, - () => undefined, - ); - } - let sanitizedPath: string | null = null; try { sanitizedPath = sanitizePath(autoDestination); @@ -112,6 +110,7 @@ router.post('/add-urls', async (req, r const finalDestination = await getDestination(req.services, { destination, + tags, }); if (finalDestination == null) { @@ -162,6 +161,7 @@ router.post('/add-files', async (req, const finalDestination = await getDestination(req.services, { destination, + tags, }); if (finalDestination == null) { diff --git a/shared/types/FloodSettings.ts b/shared/types/FloodSettings.ts index cc6f10b9..985a8014 100644 --- a/shared/types/FloodSettings.ts +++ b/shared/types/FloodSettings.ts @@ -30,8 +30,10 @@ export interface FloodSettings { // Last selection state of "Start Torrent" toggle startTorrentsOnLoad: boolean; - // Last used download destination - torrentDestination?: string; + // Preferred download destinations by tags + // currently set to the last used download destinations + // value of property '' is the default preferred destination + torrentDestinations?: Record; // Tag selector preference UITagSelectorMode?: 'single' | 'multi';