diff --git a/pytorrent/static/js/messages.js b/pytorrent/static/js/messages.js index 52d6781..b0c4c79 100644 --- a/pytorrent/static/js/messages.js +++ b/pytorrent/static/js/messages.js @@ -1,156 +1,150 @@ -// Note: User-facing toast and modal copy is centralized here. -const APP_MESSAGES = { - actions: { - raw_torrent: 'Add torrent', - add: 'Add torrent', - start: 'Start torrent', - pause: 'Pause torrent', - stop: 'Stop torrent', - resume: 'Resume torrent', - remove: 'Remove torrent', - erase: 'Delete torrent', - delete: 'Delete torrent', - move: 'Move torrent', - recheck: 'Force recheck', - reannounce: 'Reannounce', - set_label: 'Update label', - label: 'Update label' - }, +export const messagesSource = ` - toast: { - operationStarted: ({ action }) => `${actionLabel(action)} started`, + const APP_MESSAGES = { + actions: { + raw_torrent: 'Add torrent', + add: 'Add torrent', + start: 'Start torrent', + pause: 'Pause torrent', + stop: 'Stop torrent', + resume: 'Resume torrent', + remove: 'Remove torrent', + erase: 'Delete torrent', + delete: 'Delete torrent', + move: 'Move torrent', + recheck: 'Force recheck', + reannounce: 'Reannounce', + set_label: 'Update label', + label: 'Update label' + }, - operationDone: ({ action }) => `${actionLabel(action)} done`, + toast: { + operationStarted: ({ action }) => \`\${actionLabel(action)} started\`, - operationFailed: ({ action, error }) => - `${actionLabel(action)} failed: ${error || 'unknown error'}`, + operationDone: ({ action }) => \`\${actionLabel(action)} done\`, - actionQueued: ({ action, parts }) => - Number(parts || 1) > 1 - ? `${actionLabel(action)} queued in ${parts} parts` - : `${actionLabel(action)} queued`, + operationFailed: ({ action, error }) => + \`\${actionLabel(action)} failed: \${error || 'unknown error'}\`, - moveQueued: ({ parts, physical }) => - Number(parts || 1) > 1 - ? `Move queued in ${parts} parts` - : physical - ? 'Physical move queued' - : 'Move queued', + actionQueued: ({ action, parts }) => + Number(parts || 1) > 1 + ? \`\${actionLabel(action)} queued in \${parts} parts\` + : \`\${actionLabel(action)} queued\`, - addQueued: () => 'Torrent add queued', + moveQueued: ({ parts, physical }) => + Number(parts || 1) > 1 + ? \`Move queued in \${parts} parts\` + : physical + ? 'Physical move queued' + : 'Move queued', - addQueuedSkipped: ({ count }) => - `Torrent add queued, skipped ${count} duplicate torrent(s)`, + addQueued: () => 'Torrent add queued', - addTooLarge: () => - 'One or more .torrent files exceed the current rTorrent XML-RPC upload limit. Open rTorrent config and set network.xmlrpc.size_limit to e.g. 16M.', + addQueuedSkipped: ({ count }) => + \`Torrent add queued, skipped \${count} duplicate torrent(s)\`, - dropOnlyTorrents: () => 'Drop .torrent files only', + addTooLarge: () => + 'One or more .torrent files exceed the current rTorrent XML-RPC upload limit. Open rTorrent config and set network.xmlrpc.size_limit to e.g. 16M.', - droppedAddedSkipped: ({ queued, skipped }) => - `Added ${queued} torrent(s), skipped ${skipped} duplicate(s)`, + dropOnlyTorrents: () => 'Drop .torrent files only', - droppedAdded: ({ queued }) => `Added ${queued} torrent(s)`, + droppedAddedSkipped: ({ queued, skipped }) => + \`Added \${queued} torrent(s), skipped \${skipped} duplicate(s)\`, - droppedSkipped: ({ skipped }) => - `Skipped ${skipped} duplicate torrent(s)`, + droppedAdded: ({ queued }) => \`Added \${queued} torrent(s)\`, - droppedNone: () => 'No torrents were added', + droppedSkipped: ({ skipped }) => + \`Skipped \${skipped} duplicate torrent(s)\`, - noTorrentsSelected: () => 'No torrents selected', + droppedNone: () => 'No torrents were added', - noTorrentSelected: () => 'No torrent selected', + noTorrentsSelected: () => 'No torrents selected', - noFilesSelected: () => 'No files selected', + noTorrentSelected: () => 'No torrent selected', - downloadStarted: () => 'Download started', + noFilesSelected: () => 'No files selected', - chunkActionDone: ({ action }) => `${actionLabel(action)} done`, + downloadStarted: () => 'Download started', - trackerActionDone: ({ action }) => `${actionLabel(action)} done`, + chunkActionDone: ({ action }) => \`\${actionLabel(action)} done\`, - pathPickerUnavailable: () => 'Path picker is unavailable', + trackerActionDone: ({ action }) => \`\${actionLabel(action)} done\`, - pathEmpty: () => 'Path is empty', + pathPickerUnavailable: () => 'Path picker is unavailable', - columnsSaved: () => 'Columns saved', + pathEmpty: () => 'Path is empty', - recommendedColumnsApplied: () => 'Recommended columns applied', + columnsSaved: () => 'Columns saved', - jobLogsCleared: ({ deleted }) => - `Cleared ${deleted || 0} finished job log(s)`, + recommendedColumnsApplied: () => 'Recommended columns applied', - emergencyJobLogsCleared: ({ deleted }) => - `Emergency cleanup removed ${deleted || 0} job log(s)`, + jobLogsCleared: ({ deleted }) => + \`Cleared \${deleted || 0} finished job log(s)\`, - rtorrentConfigSaved: ({ updated }) => - `rTorrent config saved (${updated || 0})`, + emergencyJobLogsCleared: ({ deleted }) => + \`Emergency cleanup removed \${deleted || 0} job log(s)\`, - rtorrentConfigReset: ({ removed }) => - `rTorrent config reset (${removed || 0} override(s) removed)`, + rtorrentConfigSaved: ({ updated }) => + \`rTorrent config saved (\${updated || 0})\`, - automationLogsDeleted: ({ deleted }) => - `Automation logs deleted: ${deleted || 0}`, + rtorrentConfigReset: ({ removed }) => + \`rTorrent config reset (\${removed || 0} override(s) removed)\`, - cleanupDone: ({ deleted }) => `Cleanup done (${deleted})`, + automationLogsDeleted: ({ deleted }) => + \`Automation logs deleted: \${deleted || 0}\`, - plannerApplied: ({ dryRun, paused, resumed, limitsChanged }) => - `${dryRun ? 'Planner dry-run' : 'Planner applied'}: paused ${ - paused || 0 - }, resumed ${resumed || 0}, limits ${ - limitsChanged ? 'changed' : 'unchanged' - }`, + cleanupDone: ({ deleted }) => \`Cleanup done (\${deleted})\`, - rssQueued: ({ queued }) => `RSS queued ${queued || 0} item(s)`, + plannerApplied: ({ dryRun, paused, resumed, limitsChanged }) => + \`\${dryRun ? 'Planner dry-run' : 'Planner applied'}: paused \${paused || 0}, resumed \${resumed || 0}, limits \${limitsChanged ? 'changed' : 'unchanged'}\`, - smartQueueCheckQueued: () => - 'Smart Queue check queued. It will continue in the background.', + rssQueued: ({ queued }) => \`RSS queued \${queued || 0} item(s)\`, - automationForceRunDone: ({ count }) => - `Automation force run done (${count || 0} torrent item(s))`, + smartQueueCheckQueued: () => + 'Smart Queue check queued. It will continue in the background.', - automationsApplied: ({ count, batches }) => - batches - ? `Automations applied ${count || 0} torrent(s) in ${ - batches || 0 - } batch(es)` - : `Automations applied ${count || 0} item(s)`, + automationForceRunDone: ({ count }) => + \`Automation force run done (\${count || 0} torrent item(s))\`, - torrentStatsError: ({ error }) => `Torrent stats: ${error}`, + automationsApplied: ({ count, batches }) => + batches + ? \`Automations applied \${count || 0} torrent(s) in \${batches || 0} batch(es)\` + : \`Automations applied \${count || 0} item(s)\`, - startupConfigApplied: ({ count }) => - `Startup rTorrent config applied (${count || 0})`, + torrentStatsError: ({ error }) => \`Torrent stats: \${error}\`, - startupConfigFailed: ({ error }) => - `Startup rTorrent config: ${error}`, + startupConfigApplied: ({ count }) => + \`Startup rTorrent config applied (\${count || 0})\`, - plannerSocketResult: ({ paused, resumed, dryRun }) => - `Planner: paused ${paused || 0}, resumed ${resumed || 0}${ - dryRun ? ' dry-run' : '' - }` - } -}; + startupConfigFailed: ({ error }) => + \`Startup rTorrent config: \${error}\`, -function actionLabel(action) { - const key = String(action || '').trim(); + plannerSocketResult: ({ paused, resumed, dryRun }) => + \`Planner: paused \${paused || 0}, resumed \${resumed || 0}\${dryRun ? ' dry-run' : ''}\` + } + }; - if (APP_MESSAGES.actions[key]) { - return APP_MESSAGES.actions[key]; + function actionLabel(action) { + const key = String(action || '').trim(); + + if (APP_MESSAGES.actions[key]) { + return APP_MESSAGES.actions[key]; + } + + return key + ? key.replace(/[_-]+/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase()) + : 'Operation'; } - return key - ? key.replace(/[_-]+/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()) - : 'Operation'; -} + function appMessage(key, params = {}) { + const fn = key + .split('.') + .reduce((acc, part) => acc && acc[part], APP_MESSAGES); -function appMessage(key, params = {}) { - const fn = key - .split('.') - .reduce((acc, part) => acc && acc[part], APP_MESSAGES); + return typeof fn === 'function' ? fn(params) : String(fn || key); + } - return typeof fn === 'function' ? fn(params) : String(fn || key); -} - -function toastMessage(key, type = 'secondary', params = {}) { - toast(appMessage(key, params), type); -} \ No newline at end of file + function toastMessage(key, type = 'secondary', params = {}) { + toast(appMessage(key, params), type); + } +`; \ No newline at end of file