Browse Source

Allows to change the data storage directory.

oldj 3 years ago
parent
commit
e357b4af88

+ 3 - 0
src/common/i18n/languages/en.ts

@@ -13,6 +13,7 @@ export default {
   auto_refresh: 'Auto refresh',
   btn_cancel: 'Cancel',
   btn_ok: 'OK',
+  change: 'Change',
   check_update: 'Check update',
   choice_mode: 'Choice mode',
   choice_mode_default: 'Default',
@@ -99,6 +100,8 @@ export default {
   move_items_to_trashcan: 'Move {0} items to trashcan',
   move_to_trashcan: 'Move to trashcan',
   need_to_relaunch: 'Need to relaunch',
+  need_to_relaunch_after_setting_changed:
+    'The setting has been changed and will take effect after the app is restarted.',
   never: 'Never',
   new: 'New',
   new_version_found: 'New version found',

+ 3 - 0
src/common/i18n/languages/fr.ts

@@ -13,6 +13,7 @@ export default {
   auto_refresh: 'Rafraîchissement automatique',
   btn_cancel: 'Annuler',
   btn_ok: 'OK',
+  change: 'Changer',
   check_update: 'Vérifier les mises à jour',
   choice_mode: 'Choice mode',
   choice_mode_default: 'Défaut',
@@ -99,6 +100,8 @@ export default {
   move_items_to_trashcan: 'Déplacer {0} éléments dans la corbeille',
   move_to_trashcan: 'Déplacer dans la corbeille',
   need_to_relaunch: 'Besoin de redémarrer',
+  need_to_relaunch_after_setting_changed:
+    "Le paramètre a été modifié et prendra effet après le redémarrage de l'application.",
   never: 'Jamais',
   new: 'Nouveau',
   new_version_found: 'Nouvelle version trouvée',

+ 2 - 0
src/common/i18n/languages/zh.ts

@@ -15,6 +15,7 @@ const lang: LanguageDict = {
   auto_refresh: '自动刷新',
   btn_cancel: '取消',
   btn_ok: '确定',
+  change: '更改',
   check_update: '检查更新',
   choice_mode: '选择模式',
   choice_mode_default: '默认',
@@ -98,6 +99,7 @@ const lang: LanguageDict = {
   move_items_to_trashcan: '移动 {0} 项到回收站',
   move_to_trashcan: '移到回收站',
   need_to_relaunch: '需要重启',
+  need_to_relaunch_after_setting_changed: '设置已更改,应用重启后生效。',
   never: '从不',
   new: '新建',
   new_version_found: '发现新版本',

+ 38 - 0
src/main/actions/cmd/changeDataDir.ts

@@ -0,0 +1,38 @@
+/**
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { app, dialog } from 'electron'
+import { localdb } from '@main/data'
+import getDataFolder from '@main/libs/getDataDir'
+import getI18N from '@main/core/getI18N'
+
+export default async (): Promise<string | undefined> => {
+  let { lang } = await getI18N()
+  let current_dir = getDataFolder()
+
+  let r = await dialog.showOpenDialog({
+    title: '选择数据目录',
+    defaultPath: current_dir,
+    properties: ['openDirectory', 'createDirectory'],
+  })
+
+  if (r.canceled) {
+    return
+  }
+
+  let dir = r.filePaths[0]
+  if (!dir || dir === current_dir) {
+    return
+  }
+
+  await localdb.dict.local.set('data_dir', dir)
+  dialog.showMessageBoxSync({
+    message: lang.need_to_relaunch_after_setting_changed,
+  })
+  app.relaunch()
+  app.exit(0)
+
+  return dir
+}

+ 8 - 0
src/main/actions/getDataDir.ts

@@ -0,0 +1,8 @@
+/**
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import getDataDir from '@main/libs/getDataDir'
+
+export default async () => getDataDir()

+ 0 - 8
src/main/actions/getDataFolder.ts

@@ -1,8 +0,0 @@
-/**
- * @author: oldj
- * @homepage: https://oldj.net
- */
-
-import getDataFolder from '@main/libs/getDataFolder'
-
-export default async () => getDataFolder()

+ 8 - 0
src/main/actions/getDefaultDataDir.ts

@@ -0,0 +1,8 @@
+/**
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { getDefaultDataDir } from '@main/libs/getDataDir'
+
+export default async () => getDefaultDataDir()

+ 3 - 1
src/main/actions/index.ts

@@ -6,8 +6,9 @@
 
 export { default as ping } from './ping'
 
-export { default as getDataFolder } from './getDataFolder'
+export { default as getDataFolder } from './getDataDir'
 export { default as getBasicData } from './getBasicData'
+export { default as getDefaultDataFolder } from './getDefaultDataDir'
 
 export { default as configGet } from './config/get'
 export { default as configSet } from './config/set'
@@ -40,6 +41,7 @@ export { default as cmdDeleteHistory } from './cmd/deleteHistory'
 export { default as cmdClearHistory } from './cmd/clearHistory'
 export { default as cmdFocusMainWindow } from './cmd/focusMainWindow'
 export { default as cmdToggleDevTools } from './cmd/toggleDevTools'
+export { default as cmdChangeDataDir } from './cmd/changeDataDir'
 
 export { default as openUrl } from './openUrl'
 export { default as showItemInFolder } from './showItemInFolder'

+ 1 - 1
src/main/actions/migrate/checkIfMigration.ts

@@ -5,7 +5,7 @@
  * @homepage: https://oldj.net
  */
 
-import getDataFolder from '@main/libs/getDataFolder'
+import getDataFolder from '@main/libs/getDataDir'
 import { isDir } from '@main/utils/fs2'
 import * as fs from 'fs'
 import * as path from 'path'

+ 1 - 1
src/main/actions/migrate/migrateData.ts

@@ -7,7 +7,7 @@
 // migrate data from v3 to v4
 
 import importV3Data from '@main/actions/migrate/importV3Data'
-import getDataFolder from '@main/libs/getDataFolder'
+import getDataFolder from '@main/libs/getDataDir'
 import { IHostsBasicData, VersionType } from '@root/common/data'
 import { cleanHostsList } from '@root/common/hostsFn'
 import version from '@root/version.json'

+ 23 - 19
src/main/data/index.ts

@@ -4,26 +4,27 @@
  * @homepage: https://oldj.net
  */
 
-import getDataFolder from '@main/libs/getDataFolder'
-import { app } from 'electron'
 import * as path from 'path'
 import PotDb from 'potdb'
+import { app } from 'electron'
+import getDataFolder from '@main/libs/getDataDir'
+import getConfigFolder from '@main/libs/getConfigDir'
 
-let swhdb: PotDb
-let cfgdb: PotDb
 let localdb: PotDb
+let cfgdb: PotDb
+let swhdb: PotDb
 
-if (!global.swhdb) {
-  let db_dir: string = path.join(getDataFolder(), 'data')
-  swhdb = new PotDb(db_dir)
-  console.log(`data db: ${swhdb.dir}`)
-  global.swhdb = swhdb
+if (!global.localdb) {
+  let db_dir: string = path.join(app.getPath('userData'), 'swh_local')
+  localdb = new PotDb(db_dir)
+  console.log(`local db: ${localdb.dir}`)
+  global.localdb = localdb
 } else {
-  swhdb = global.swhdb
+  localdb = global.localdb
 }
 
 if (!global.cfgdb) {
-  let db_dir: string = path.join(getDataFolder(), 'config')
+  let db_dir: string = path.join(getConfigFolder(), 'config')
   cfgdb = new PotDb(db_dir)
   console.log(`config db: ${cfgdb.dir}`)
   global.cfgdb = cfgdb
@@ -31,13 +32,16 @@ if (!global.cfgdb) {
   cfgdb = global.cfgdb
 }
 
-if (!global.localdb) {
-  let db_dir: string = path.join(app.getPath('userData'), 'swh_local')
-  localdb = new PotDb(db_dir)
-  console.log(`local db: ${localdb.dir}`)
-  global.localdb = localdb
-} else {
-  localdb = global.localdb
+async function getSwhDb(): Promise<PotDb> {
+  if (!swhdb) {
+    global.data_dir = await localdb.dict.local.get('data_dir')
+    let db_dir: string = path.join(getDataFolder(), 'data')
+    swhdb = new PotDb(db_dir)
+    console.log(`data db: ${swhdb.dir}`)
+    global.swhdb = swhdb
+  }
+
+  return swhdb
 }
 
-export { swhdb, cfgdb, localdb }
+export { localdb, cfgdb, swhdb, getSwhDb }

+ 1 - 1
src/main/libs/getDataFolder.ts → src/main/libs/getConfigDir.ts

@@ -9,5 +9,5 @@ import { homedir } from 'os'
 export default (): string => {
   // todo data folder should be current working dir for portable version
 
-  return global.db_dir || path.join(homedir(), '.SwitchHosts')
+  return path.join(homedir(), '.SwitchHosts')
 }

+ 17 - 0
src/main/libs/getDataDir.ts

@@ -0,0 +1,17 @@
+/**
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import * as path from 'path'
+import { homedir } from 'os'
+
+export function getDefaultDataDir() {
+  return path.join(homedir(), '.SwitchHosts')
+}
+
+export default (): string => {
+  // todo data folder should be current working dir for portable version
+
+  return global.data_dir || getDefaultDataDir()
+}

+ 2 - 0
src/main/main.ts

@@ -17,10 +17,12 @@ import { app, BrowserWindow, ipcMain, nativeTheme } from 'electron'
 import windowStateKeeper from 'electron-window-state'
 import * as path from 'path'
 import { v4 as uuid4 } from 'uuid'
+import { getSwhDb } from '@main/data'
 
 let win: BrowserWindow | null
 
 const createWindow = async () => {
+  await getSwhDb()
   const configs = await configAll()
 
   let main_window_state = windowStateKeeper({

+ 12 - 16
src/main/types.d.ts

@@ -23,20 +23,16 @@ export interface IHostsWriteOptions {
 }
 
 declare global {
-  namespace NodeJS {
-    interface Global {
-      db_dir?: string
-      swhdb: SwhDb
-      cfgdb: SwhDb
-      localdb: SwhDb
-      ua: string // user agent
-      session_id: string // A random value, refreshed every time the app starts, used to identify different startup sessions.
-      main_win: BrowserWindow
-      find_win?: BrowserWindow | null
-      last_path?: string // the last path opened by SwitchHosts
-      tracer: Tracer
-      is_will_quit?: boolean
-      system_locale?: LocaleName
-    }
-  }
+  var data_dir: string | undefined
+  var swhdb: SwhDb
+  var cfgdb: SwhDb
+  var localdb: SwhDb
+  var ua: string // user agent
+  var session_id: string // A random value, refreshed every time the app starts, used to identify different startup sessions.
+  var main_win: BrowserWindow
+  var find_win: BrowserWindow | null
+  var last_path: string // the last path opened by SwitchHosts
+  var tracer: Tracer
+  var is_will_quit: boolean
+  var system_locale: LocaleName
 }

+ 14 - 1
src/renderer/components/Pref/Advanced.tsx

@@ -6,10 +6,12 @@
 
 import { useModel } from '@@/plugin-model/useModel'
 import {
+  Button,
   Checkbox,
   FormControl,
   FormHelperText,
   FormLabel,
+  HStack,
   Link,
   Tooltip,
   VStack,
@@ -80,7 +82,18 @@ const Advanced = (props: IProps) => {
       <FormControl>
         <FormLabel>{lang.where_is_my_data}</FormLabel>
         <FormHelperText mb={2}>{lang.your_data_is}</FormHelperText>
-        <PathLink link={data_path} />
+        <HStack>
+          <PathLink link={data_path} />
+          <Button
+            variant="link"
+            onClick={async () => {
+              let r = await actions.cmdChangeDataDir()
+              console.log(r)
+            }}
+          >
+            {lang.change}
+          </Button>
+        </HStack>
       </FormControl>
     </VStack>
   )