瀏覽代碼

add export support.

oldj 4 年之前
父節點
當前提交
bde32286a5

+ 1 - 0
scripts/make.js

@@ -112,6 +112,7 @@ const makeDefault = async () => {
   await builder.build({
     //targets: Platform.MAC.createTarget(),
     //...TARGET_PLATFORMS_configs.mac,
+    //...TARGET_PLATFORMS_configs.win,
     ...TARGET_PLATFORMS_configs.all,
     config: {
       ...cfg_common,

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

@@ -39,6 +39,7 @@ export default {
   download: 'Download',
   edit: 'Edit',
   export: 'Export',
+  export_done: 'The export is complete.',
   fail: 'Fail!',
   feedback: 'Feedback',
   file: 'File',
@@ -63,6 +64,7 @@ export default {
   hour: 'hour',
   hours: 'hours',
   import: 'Import',
+  import_done: 'The import is complete.',
   is_latest_version_inform: 'Great, you are running the latest version!',
   language: 'Language',
   last_refresh: 'Last refresh: ',

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

@@ -41,6 +41,7 @@ const lang: LanguageDict = {
   download: '下载',
   edit: '编辑',
   export: '导出',
+  export_done: '导出已完成。',
   fail: '操作失败!',
   feedback: '意见反馈',
   file: '文件',
@@ -65,6 +66,7 @@ const lang: LanguageDict = {
   hour: '小时',
   hours: '小时',
   import: '导入',
+  import_done: '导入已完成。',
   is_latest_version_inform: '太棒了,你正在运行的是最新版本!',
   language: '语言',
   last_refresh: '最后刷新:',

+ 39 - 0
src/main/actions/export.ts

@@ -0,0 +1,39 @@
+/**
+ * export
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import getI18N from '@main/core/getI18N'
+import { swhdb } from '@main/data'
+import { dialog } from 'electron'
+import { promises as fs } from 'fs'
+import * as path from 'path'
+import version from '@root/version.json'
+
+export default async (): Promise<string | false> => {
+  let { lang } = await getI18N()
+
+  let result = await dialog.showSaveDialog({
+    title: lang.import,
+    defaultPath: path.join(global.last_path || '', 'swh_data.json'),
+    properties: [
+      'createDirectory',
+      'showOverwriteConfirmation',
+    ],
+  })
+
+  if (result.canceled || !result.filePath) {
+    return false
+  }
+
+  let target_dir = result.filePath
+
+  let data = await swhdb.toJSON()
+  await fs.writeFile(target_dir, JSON.stringify({
+    data,
+    version,
+  }), 'utf-8')
+
+  return target_dir
+}

+ 31 - 0
src/main/actions/import.ts

@@ -0,0 +1,31 @@
+/**
+ * import
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { dialog } from 'electron'
+import getI18N from '@main/core/getI18N'
+
+export default async () => {
+  let { lang } = await getI18N()
+
+  let result = await dialog.showOpenDialog({
+    title: lang.import,
+    defaultPath: global.last_path,
+    filters: [
+      { name: 'JSON', extensions: ['json'] },
+      { name: 'All Files', extensions: ['*'] },
+    ],
+    properties: [
+      'openDirectory',
+    ],
+  })
+
+  if (result.canceled) {
+    return false
+  }
+
+  let paths = result.filePaths
+  console.log(paths)
+}

+ 2 - 0
src/main/actions/index.ts

@@ -43,6 +43,8 @@ export { default as showItemInFolder } from './showItemInFolder'
 export { default as updateTrayTitle } from './updateTrayTitle'
 export { default as checkUpdate } from './checkUpdate'
 export { default as closeMainWindow } from './closeMainWindow'
+export { default as exportData } from './export'
+export { default as importData } from './import'
 export { default as quit } from './quit'
 
 export { default as migrateCheck } from './migrate/checkIfMigration'

+ 17 - 0
src/main/core/getI18N.ts

@@ -0,0 +1,17 @@
+/**
+ * getLang
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { configGet } from '@main/actions'
+import { LocaleName } from '@root/common/i18n'
+import { I18N } from '@root/common/i18n'
+
+export default async (locale?: LocaleName): Promise<I18N> => {
+  if (!locale) {
+    locale = await configGet('locale')
+  }
+
+  return new I18N(locale)
+}

+ 1 - 0
src/main/types.d.ts

@@ -29,6 +29,7 @@ declare global {
       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;
+      last_path?: string; // the last path opened by SwitchHosts
     }
   }
 }

+ 41 - 1
src/renderer/components/TopBar/ConfigMenu.tsx

@@ -9,7 +9,17 @@ import { Button, Menu, MenuButton, MenuDivider, MenuItem, MenuList, useToast } f
 import { actions, agent } from '@renderer/core/agent'
 import { feedback_url, homepage_url } from '@root/common/constants'
 import React from 'react'
-import { BiCog, BiExit, BiHomeCircle, BiInfoCircle, BiMessageDetail, BiRefresh, BiSliderAlt } from 'react-icons/bi'
+import {
+  BiCog,
+  BiExit,
+  BiHomeCircle,
+  BiInfoCircle,
+  BiMessageDetail,
+  BiRefresh,
+  BiSliderAlt,
+  BiExport,
+  BiImport,
+} from 'react-icons/bi'
 
 interface Props {
 
@@ -69,6 +79,36 @@ const ConfigMenu = (props: Props) => {
 
         <MenuDivider/>
 
+        <MenuItem
+          icon={<BiExport/>}
+          onClick={async () => {
+            let r = await actions.exportData()
+            if (r === false) {
+              toast({
+                status: 'error',
+                description: lang.fail,
+                isClosable: true,
+              })
+            } else {
+              toast({
+                status: 'success',
+                description: lang.export_done,
+                isClosable: true,
+              })
+            }
+          }}
+        >
+          {lang.export}
+        </MenuItem>
+        <MenuItem
+          icon={<BiImport/>}
+          onClick={() => agent.broadcast('show_preferences')}
+        >
+          {lang.import}
+        </MenuItem>
+
+        <MenuDivider/>
+
         <MenuItem
           icon={<BiSliderAlt/>}
           onClick={() => agent.broadcast('show_preferences')}