aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar André Oliveira <37463445+SpecialAro@users.noreply.github.com>2024-05-06 14:56:26 +0100
committerLibravatar GitHub <noreply@github.com>2024-05-06 19:26:26 +0530
commitfd8885b869808936ab58c492e9ce602bfe3c3713 (patch)
treef71737871033539fa54f5504f4c6234829e8cd28
parentRefactor context menu to be more consistent across all contexts (#1745) (diff)
downloadferdium-app-fd8885b869808936ab58c492e9ce602bfe3c3713.tar.gz
ferdium-app-fd8885b869808936ab58c492e9ce602bfe3c3713.tar.zst
ferdium-app-fd8885b869808936ab58c492e9ce602bfe3c3713.zip
feat: default download path as a user preference (#1746)
-rw-r--r--src/components/settings/settings/EditSettingsForm.tsx125
-rw-r--r--src/config.ts1
-rw-r--r--src/containers/settings/EditSettingsScreen.tsx14
-rw-r--r--src/electron/ipc-api/download.ts10
-rw-r--r--src/i18n/locales/en-US.json4
-rw-r--r--src/index.ts12
6 files changed, 129 insertions, 37 deletions
diff --git a/src/components/settings/settings/EditSettingsForm.tsx b/src/components/settings/settings/EditSettingsForm.tsx
index c3e8d46a0..2900aa2af 100644
--- a/src/components/settings/settings/EditSettingsForm.tsx
+++ b/src/components/settings/settings/EditSettingsForm.tsx
@@ -1,5 +1,6 @@
1import { systemPreferences } from '@electron/remote'; 1import { systemPreferences } from '@electron/remote';
2import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js'; 2import { mdiGithub, mdiOpenInNew, mdiPowerPlug } from '@mdi/js';
3import { ipcRenderer } from 'electron';
3import { noop } from 'lodash'; 4import { noop } from 'lodash';
4import { observer } from 'mobx-react'; 5import { observer } from 'mobx-react';
5import prettyBytes from 'pretty-bytes'; 6import prettyBytes from 'pretty-bytes';
@@ -191,6 +192,14 @@ const messages = defineMessages({
191 id: 'settings.app.subheadlineCache', 192 id: 'settings.app.subheadlineCache',
192 defaultMessage: 'Cache', 193 defaultMessage: 'Cache',
193 }, 194 },
195 subheadlineUserAgent: {
196 id: 'settings.app.subheadlineUserAgent',
197 defaultMessage: 'User Agent',
198 },
199 subheadlineDownloads: {
200 id: 'settings.app.subheadlineDownloads',
201 defaultMessage: 'Downloads',
202 },
194 cacheInfo: { 203 cacheInfo: {
195 id: 'settings.app.cacheInfo', 204 id: 'settings.app.cacheInfo',
196 defaultMessage: 'Ferdium cache is currently using {size} of disk space.', 205 defaultMessage: 'Ferdium cache is currently using {size} of disk space.',
@@ -281,6 +290,10 @@ const messages = defineMessages({
281 id: 'settings.app.buttonOpenFerdiumCertsFolder', 290 id: 'settings.app.buttonOpenFerdiumCertsFolder',
282 defaultMessage: 'Open certificates folder', 291 defaultMessage: 'Open certificates folder',
283 }, 292 },
293 buttonOpenFolderSelector: {
294 id: 'settings.app.buttonOpenFolderSelector',
295 defaultMessage: 'Open folder selector',
296 },
284}); 297});
285 298
286const Hr = (): ReactElement => ( 299const Hr = (): ReactElement => (
@@ -1034,49 +1047,87 @@ class EditSettingsForm extends Component<IProps, IState> {
1034 1047
1035 <Hr /> 1048 <Hr />
1036 1049
1037 <Input 1050 <div className="settings__settings-group">
1038 placeholder="User Agent" 1051 <H3>{intl.formatMessage(messages.subheadlineDownloads)}</H3>
1039 onChange={e => this.submit(e)} 1052
1040 {...form.$('userAgentPref').bind()} 1053 <Input
1041 /> 1054 placeholder="Default download folder"
1042 <p className="settings__help"> 1055 onChange={e => {
1043 {intl.formatMessage(globalMessages.userAgentHelp)} 1056 this.submit(e);
1044 </p> 1057 }}
1045 <p className="settings__help"> 1058 {...form.$('downloadFolderPath').bind()}
1046 {intl.formatMessage(messages.appRestartRequired)} 1059 />
1047 </p> 1060
1061 <Button
1062 buttonType="secondary"
1063 label={intl.formatMessage(
1064 messages.buttonOpenFolderSelector,
1065 )}
1066 className="settings__open-settings-cache-button"
1067 onClick={e => {
1068 ipcRenderer
1069 .invoke('download-folder-select')
1070 .then(path => {
1071 if (path) {
1072 form.$('downloadFolderPath').set(path);
1073 this.submit(e);
1074 }
1075 })
1076 .catch(console.error);
1077 }}
1078 disabled={isClearingAllCache}
1079 loaded={!isClearingAllCache}
1080 />
1081 </div>
1048 1082
1049 <Hr /> 1083 <Hr />
1050 1084
1051 <div className="settings__settings-group"> 1085 <div className="settings__settings-group">
1052 <H3>{intl.formatMessage(messages.subheadlineCache)}</H3> 1086 <Input
1053 <p> 1087 placeholder="User Agent"
1054 {intl.formatMessage(messages.cacheInfo, { 1088 onChange={e => this.submit(e)}
1055 size: cacheSize, 1089 {...form.$('userAgentPref').bind()}
1056 })} 1090 />
1091
1092 <p className="settings__help">
1093 {intl.formatMessage(globalMessages.userAgentHelp)}
1057 </p> 1094 </p>
1058 {notCleared && ( 1095 <p className="settings__help">
1059 <p>{intl.formatMessage(messages.cacheNotCleared)}</p> 1096 {intl.formatMessage(messages.appRestartRequired)}
1060 )} 1097 </p>
1098
1099 <Hr />
1100
1061 <div className="settings__settings-group"> 1101 <div className="settings__settings-group">
1062 <div className="settings__open-settings-cache-container"> 1102 <H3>{intl.formatMessage(messages.subheadlineCache)}</H3>
1063 <Button 1103 <p>
1064 buttonType="secondary" 1104 {intl.formatMessage(messages.cacheInfo, {
1065 label={intl.formatMessage(globalMessages.clearCache)} 1105 size: cacheSize,
1066 className="settings__open-settings-cache-button" 1106 })}
1067 onClick={() => { 1107 </p>
1068 onClearAllCache(); 1108 {notCleared && (
1069 this.onClearCacheClicked(); 1109 <p>{intl.formatMessage(messages.cacheNotCleared)}</p>
1070 }} 1110 )}
1071 disabled={isClearingAllCache} 1111 <div className="settings__settings-group">
1072 loaded={!isClearingAllCache} 1112 <div className="settings__open-settings-cache-container">
1073 /> 1113 <Button
1074 <Button 1114 buttonType="secondary"
1075 buttonType="secondary" 1115 label={intl.formatMessage(globalMessages.clearCache)}
1076 label="Open Process Manager" 1116 className="settings__open-settings-cache-button"
1077 className="settings__open-settings-cache-button" 1117 onClick={() => {
1078 onClick={openProcessManager} 1118 onClearAllCache();
1079 /> 1119 this.onClearCacheClicked();
1120 }}
1121 disabled={isClearingAllCache}
1122 loaded={!isClearingAllCache}
1123 />
1124 <Button
1125 buttonType="secondary"
1126 label="Open Process Manager"
1127 className="settings__open-settings-cache-button"
1128 onClick={openProcessManager}
1129 />
1130 </div>
1080 </div> 1131 </div>
1081 </div> 1132 </div>
1082 </div> 1133 </div>
diff --git a/src/config.ts b/src/config.ts
index 348b4b85d..0034b00a6 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -401,6 +401,7 @@ export const DEFAULT_APP_SETTINGS = {
401 automaticUpdates: true, 401 automaticUpdates: true,
402 universalDarkMode: true, 402 universalDarkMode: true,
403 userAgentPref: '', 403 userAgentPref: '',
404 downloadFolderPath: '',
404 adaptableDarkMode: true, 405 adaptableDarkMode: true,
405 accentColor: DEFAULT_ACCENT_COLOR, 406 accentColor: DEFAULT_ACCENT_COLOR,
406 progressbarAccentColor: DEFAULT_ACCENT_COLOR, 407 progressbarAccentColor: DEFAULT_ACCENT_COLOR,
diff --git a/src/containers/settings/EditSettingsScreen.tsx b/src/containers/settings/EditSettingsScreen.tsx
index fdd9bd8bc..a596e53a3 100644
--- a/src/containers/settings/EditSettingsScreen.tsx
+++ b/src/containers/settings/EditSettingsScreen.tsx
@@ -341,6 +341,11 @@ const messages = defineMessages({
341 id: 'settings.app.form.keepAllWorkspacesLoaded', 341 id: 'settings.app.form.keepAllWorkspacesLoaded',
342 defaultMessage: 'Keep all workspaces loaded', 342 defaultMessage: 'Keep all workspaces loaded',
343 }, 343 },
344 downloadFolderPath: {
345 id: 'settings.app.form.downloadFolderPath',
346 defaultMessage:
347 'Default download folder (leave blank to be prompted for each download)',
348 },
344}); 349});
345 350
346interface EditSettingsScreenProps extends StoresProps, WrappedComponentProps {} 351interface EditSettingsScreenProps extends StoresProps, WrappedComponentProps {}
@@ -430,6 +435,7 @@ class EditSettingsScreen extends Component<
430 scheduledDNDStart: settingsData.scheduledDNDStart, 435 scheduledDNDStart: settingsData.scheduledDNDStart,
431 scheduledDNDEnd: settingsData.scheduledDNDEnd, 436 scheduledDNDEnd: settingsData.scheduledDNDEnd,
432 enableGPUAcceleration: Boolean(settingsData.enableGPUAcceleration), 437 enableGPUAcceleration: Boolean(settingsData.enableGPUAcceleration),
438 downloadFolderPath: String(settingsData.downloadFolderPath),
433 enableGlobalHideShortcut: Boolean( 439 enableGlobalHideShortcut: Boolean(
434 settingsData.enableGlobalHideShortcut, 440 settingsData.enableGlobalHideShortcut,
435 ), 441 ),
@@ -982,6 +988,14 @@ class EditSettingsScreen extends Component<
982 default: DEFAULT_APP_SETTINGS.userAgentPref, 988 default: DEFAULT_APP_SETTINGS.userAgentPref,
983 placeholder: defaultUserAgent(), 989 placeholder: defaultUserAgent(),
984 }, 990 },
991 downloadFolderPath: {
992 label: intl.formatMessage(messages.downloadFolderPath),
993 value: ifUndefined<string>(
994 settings.all.app.downloadFolderPath,
995 DEFAULT_APP_SETTINGS.downloadFolderPath,
996 ),
997 default: DEFAULT_APP_SETTINGS.userAgentPref,
998 },
985 darkMode: { 999 darkMode: {
986 label: intl.formatMessage(messages.darkMode), 1000 label: intl.formatMessage(messages.darkMode),
987 value: ifUndefined<boolean>( 1001 value: ifUndefined<boolean>(
diff --git a/src/electron/ipc-api/download.ts b/src/electron/ipc-api/download.ts
index d749cb889..a306ba68d 100644
--- a/src/electron/ipc-api/download.ts
+++ b/src/electron/ipc-api/download.ts
@@ -52,4 +52,14 @@ export default (params: { mainWindow: BrowserWindow }) => {
52 } 52 }
53 }, 53 },
54 ); 54 );
55
56 ipcMain.handle('download-folder-select', async () => {
57 const result = await dialog.showOpenDialog(params.mainWindow, {
58 properties: ['openDirectory'],
59 });
60
61 if (result.canceled) return null;
62
63 return result.filePaths[0];
64 });
55}; 65};
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index 3947b2e5f..a91a58725 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -194,6 +194,7 @@
194 "settings.app.buttonOpenFerdiumCertsFolder": "Open certificates folder", 194 "settings.app.buttonOpenFerdiumCertsFolder": "Open certificates folder",
195 "settings.app.buttonOpenFerdiumProfileFolder": "Open Profile folder", 195 "settings.app.buttonOpenFerdiumProfileFolder": "Open Profile folder",
196 "settings.app.buttonOpenFerdiumServiceRecipesFolder": "Open Service Recipes folder", 196 "settings.app.buttonOpenFerdiumServiceRecipesFolder": "Open Service Recipes folder",
197 "settings.app.buttonOpenFolderSelector": "Open folder selector",
197 "settings.app.buttonOpenImportExport": "Import / Export", 198 "settings.app.buttonOpenImportExport": "Import / Export",
198 "settings.app.buttonSearchForUpdate": "Check for updates", 199 "settings.app.buttonSearchForUpdate": "Check for updates",
199 "settings.app.buttonShowChangelog": "Show changelog", 200 "settings.app.buttonShowChangelog": "Show changelog",
@@ -213,6 +214,7 @@
213 "settings.app.form.confirmOnQuit": "Confirm when quitting Ferdium", 214 "settings.app.form.confirmOnQuit": "Confirm when quitting Ferdium",
214 "settings.app.form.customTodoServer": "Custom Todo Server", 215 "settings.app.form.customTodoServer": "Custom Todo Server",
215 "settings.app.form.darkMode": "Enable Dark Mode", 216 "settings.app.form.darkMode": "Enable Dark Mode",
217 "settings.app.form.downloadFolderPath": "Default download folder (leave blank to be prompted for each download)",
216 "settings.app.form.enableGPUAcceleration": "Enable GPU Acceleration", 218 "settings.app.form.enableGPUAcceleration": "Enable GPU Acceleration",
217 "settings.app.form.enableGlobalHideShortcut": "Enable Global shortcut to hide Ferdium", 219 "settings.app.form.enableGlobalHideShortcut": "Enable Global shortcut to hide Ferdium",
218 "settings.app.form.enableLock": "Enable Password Lock", 220 "settings.app.form.enableLock": "Enable Password Lock",
@@ -308,7 +310,9 @@
308 "settings.app.servicesUpdateStatusUpToDate": "Your services are up-to-date", 310 "settings.app.servicesUpdateStatusUpToDate": "Your services are up-to-date",
309 "settings.app.spellCheckerLanguageInfo": "Ferdium uses your Mac's built-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.", 311 "settings.app.spellCheckerLanguageInfo": "Ferdium uses your Mac's built-in spellchecker to check for typos. If you want to change the languages the spellchecker checks for, you can do so in your Mac's System Preferences.",
310 "settings.app.subheadlineCache": "Cache", 312 "settings.app.subheadlineCache": "Cache",
313 "settings.app.subheadlineDownloads": "Downloads",
311 "settings.app.subheadlineFerdiumProfile": "Ferdium Profile", 314 "settings.app.subheadlineFerdiumProfile": "Ferdium Profile",
315 "settings.app.subheadlineUserAgent": "User Agent",
312 "settings.app.todoServerInfo": "This server will be used for the \"Ferdium Todo\" feature.", 316 "settings.app.todoServerInfo": "This server will be used for the \"Ferdium Todo\" feature.",
313 "settings.app.translationHelp": "Help us to translate Ferdium into your language.", 317 "settings.app.translationHelp": "Help us to translate Ferdium into your language.",
314 "settings.app.universalDarkModeInfo": "Universal Dark Mode tries to dynamically generate dark mode styles for services that are otherwise not currently supported.", 318 "settings.app.universalDarkModeInfo": "Universal Dark Mode tries to dynamically generate dark mode styles for services that are otherwise not currently supported.",
diff --git a/src/index.ts b/src/index.ts
index cccf0ef66..09e411e13 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -245,6 +245,18 @@ const createWindow = () => {
245 openExternalUrl(url); 245 openExternalUrl(url);
246 return { action: 'deny' }; 246 return { action: 'deny' };
247 }); 247 });
248
249 // Handle will download event from main process (prevent download dialog)
250 contents.session.on('will-download', (_e, item) => {
251 const downloadFolderPath = retrieveSettingValue(
252 'downloadFolderPath',
253 DEFAULT_APP_SETTINGS.downloadFolderPath,
254 ) as string;
255
256 if (downloadFolderPath !== '') {
257 item.setSavePath(join(downloadFolderPath, item.getFilename()));
258 }
259 });
248 } 260 }
249 }); 261 });
250 262