1
0
Эх сурвалжийг харах

Update models with Jotai atoms.

oldj 2 жил өмнө
parent
commit
7c5a570eaf
41 өөрчлөгдсөн 956 нэмэгдсэн , 587 устгасан
  1. 633 180
      package-lock.json
  2. 73 65
      package.json
  3. 1 1
      src/common/events.ts
  4. 1 7
      src/main/actions/cmd/changeDataDir.ts
  5. 3 5
      src/renderer/components/About/AboutContent.tsx
  6. 3 10
      src/renderer/components/About/index.tsx
  7. 11 25
      src/renderer/components/EditHostsInfo.tsx
  8. 3 5
      src/renderer/components/Editor/HostsEditor.tsx
  9. 8 18
      src/renderer/components/History.tsx
  10. 2 2
      src/renderer/components/Lang.tsx
  11. 6 10
      src/renderer/components/LeftPanel/SystemHostsItem.tsx
  12. 6 10
      src/renderer/components/LeftPanel/Trashcan.tsx
  13. 5 6
      src/renderer/components/LeftPanel/TrashcanItem.tsx
  14. 4 3
      src/renderer/components/LeftPanel/index.tsx
  15. 4 3
      src/renderer/components/List/ListItem.tsx
  16. 7 6
      src/renderer/components/List/index.tsx
  17. 3 5
      src/renderer/components/Loading.tsx
  18. 1 4
      src/renderer/components/MainPanel/index.tsx
  19. 6 14
      src/renderer/components/Pref/Advanced.tsx
  20. 2 2
      src/renderer/components/Pref/Commands.tsx
  21. 2 2
      src/renderer/components/Pref/CommandsHistory.tsx
  22. 14 31
      src/renderer/components/Pref/General.tsx
  23. 3 5
      src/renderer/components/Pref/Proxy.tsx
  24. 5 6
      src/renderer/components/Pref/index.tsx
  25. 6 7
      src/renderer/components/SetWriteMode.tsx
  26. 2 2
      src/renderer/components/StatusBar.tsx
  27. 3 5
      src/renderer/components/SudoPasswordInput.tsx
  28. 13 32
      src/renderer/components/TopBar/ConfigMenu.tsx
  29. 4 3
      src/renderer/components/TopBar/ImportFromUrl.tsx
  30. 11 15
      src/renderer/components/TopBar/index.tsx
  31. 17 21
      src/renderer/components/Transfer.tsx
  32. 3 6
      src/renderer/models/useConfigs.ts
  33. 4 6
      src/renderer/models/useHostsData.ts
  34. 7 6
      src/renderer/models/useI18n.ts
  35. 17 42
      src/renderer/pages/find.tsx
  36. 8 8
      src/renderer/pages/index.tsx
  37. 7 8
      src/renderer/pages/tray.tsx
  38. 14 0
      src/renderer/stores/configs.ts
  39. 18 0
      src/renderer/stores/hosts_data.ts
  40. 15 0
      src/renderer/stores/i18n.ts
  41. 1 1
      src/version.json

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 633 - 180
package-lock.json


+ 73 - 65
package.json

@@ -19,74 +19,82 @@
     "make:win": "cross-env SKIP_NOTARIZATION=1 cross-env MAKE_FOR=win npm run make"
     "make:win": "cross-env SKIP_NOTARIZATION=1 cross-env MAKE_FOR=win npm run make"
   },
   },
   "dependencies": {
   "dependencies": {
-    "axios": "^0.27.2",
-    "compare-versions": "^4.1.3",
-    "dayjs": "^1.11.2",
-    "electron-window-state": "^5.0.3",
-    "express": "^4.18.1",
-    "lodash": "^4.17.21",
-    "md5": "^2.3.0",
-    "md5-file": "^5.0.0",
-    "mkdirp": "^1.0.4",
-    "potdb": "^2.3.3",
-    "tslib": "^2.4.0",
-    "uuid": "^8.3.2"
+    "axios": "0.27.2",
+    "compare-versions": "4.1.3",
+    "dayjs": "1.11.2",
+    "electron-window-state": "5.0.3",
+    "express": "4.18.1",
+    "lodash": "4.17.21",
+    "md5": "2.3.0",
+    "md5-file": "5.0.0",
+    "mkdirp": "1.0.4",
+    "potdb": "2.3.3",
+    "tslib": "2.4.0",
+    "uuid": "8.3.2"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@babel/plugin-proposal-class-properties": "^7.17.12",
-    "@babel/plugin-proposal-decorators": "^7.18.2",
-    "@babel/preset-env": "^7.18.2",
-    "@babel/preset-typescript": "^7.17.12",
-    "@chakra-ui/react": "^2.1.2",
-    "@emotion/react": "^11.9.0",
-    "@emotion/styled": "^11.8.1",
-    "@types/assert": "^1.5.6",
-    "@types/codemirror": "^5.60.5",
-    "@types/express": "^4.17.13",
-    "@types/lodash": "^4.14.182",
-    "@types/md5": "^2.3.2",
-    "@types/mkdirp": "^1.0.2",
-    "@types/mocha": "^9.1.1",
-    "@types/node": "^17.0.35",
-    "@types/react": "^18.0.9",
-    "@types/react-dom": "^18.0.5",
-    "@types/react-window": "^1.8.5",
-    "@types/uuid": "^8.3.4",
+    "@babel/plugin-proposal-class-properties": "7.17.12",
+    "@babel/plugin-proposal-decorators": "7.18.2",
+    "@babel/preset-env": "7.18.2",
+    "@babel/preset-typescript": "7.17.12",
+    "@chakra-ui/react": "2.1.2",
+    "@emotion/react": "11.9.0",
+    "@emotion/styled": "11.8.1",
+    "@types/assert": "1.5.6",
+    "@types/codemirror": "5.60.5",
+    "@types/express": "4.17.13",
+    "@types/lodash": "4.14.182",
+    "@types/md5": "2.3.2",
+    "@types/mkdirp": "1.0.2",
+    "@types/mocha": "9.1.1",
+    "@types/node": "17.0.35",
+    "@types/react": "18.0.9",
+    "@types/react-dom": "18.0.5",
+    "@types/react-window": "1.8.5",
+    "@types/uuid": "8.3.4",
     "@umijs/preset-react": "2.x",
     "@umijs/preset-react": "2.x",
-    "@umijs/test": "^3.5.24",
-    "ahooks": "^3.4.0",
-    "babel-loader": "^8.2.5",
-    "clsx": "^1.1.1",
-    "codemirror": "^5.65.4",
-    "concurrently": "^7.2.1",
-    "copy-webpack-plugin": "^11.0.0",
-    "cross-env": "^7.0.3",
-    "dotenv": "^16.0.1",
-    "electron": "^19.1.8",
-    "electron-builder": "^23.0.9",
-    "electron-notarize": "^1.2.1",
-    "espower-typescript": "^10.0.0",
-    "execa": "^6.1.0",
-    "fork-ts-checker-webpack-plugin": "^7.2.11",
-    "fs-extra": "^10.1.0",
-    "mocha": "^10.0.0",
-    "power-assert": "^1.6.1",
-    "prettier": "^2.6.2",
-    "pretty-bytes": "^6.0.0",
-    "react": "^18.1.0",
-    "react-dom": "^18.1.0",
-    "react-icons": "^4.3.1",
-    "react-window": "^1.8.7",
-    "smooth-scroll-into-view-if-needed": "^1.1.33",
-    "ts-node": "^10.8.0",
-    "tsconfig-paths-webpack-plugin": "^3.5.2",
-    "typescript": "^4.7.2",
-    "umi": "^3.5.35",
-    "webpack": "^5.72.1",
-    "webpack-cli": "^4.9.2",
-    "webpack-merge": "^5.8.0",
-    "webpack-node-externals": "^3.0.0",
-    "yorkie": "^2.0.0"
+    "@umijs/test": "3.5.24",
+    "@vitejs/plugin-react": "3.0.1",
+    "ahooks": "3.4.0",
+    "babel-loader": "8.2.5",
+    "clsx": "1.1.1",
+    "codemirror": "5.65.4",
+    "concurrently": "7.2.1",
+    "copy-webpack-plugin": "11.0.0",
+    "cross-env": "7.0.3",
+    "dotenv": "16.0.1",
+    "electron": "19.1.8",
+    "electron-builder": "23.0.9",
+    "electron-notarize": "1.2.1",
+    "espower-typescript": "10.0.0",
+    "execa": "6.1.0",
+    "fork-ts-checker-webpack-plugin": "7.2.11",
+    "fs-extra": "10.1.0",
+    "jotai": "2.0.0",
+    "mocha": "10.0.0",
+    "power-assert": "1.6.1",
+    "prettier": "2.6.2",
+    "pretty-bytes": "6.0.0",
+    "react": "18.1.0",
+    "react-dom": "18.1.0",
+    "react-icons": "4.3.1",
+    "react-router-dom": "6.8.0",
+    "react-window": "1.8.7",
+    "sass": "1.58.0",
+    "smooth-scroll-into-view-if-needed": "1.1.33",
+    "ts-node": "10.8.0",
+    "tsconfig-paths-webpack-plugin": "3.5.2",
+    "typescript": "4.7.2",
+    "umi": "3.5.35",
+    "vite": "4.0.4",
+    "vite-plugin-static-copy": "0.13.0",
+    "vite-plugin-svgr": "2.4.0",
+    "vite-tsconfig-paths": "4.0.5",
+    "webpack": "5.72.1",
+    "webpack-cli": "4.9.2",
+    "webpack-merge": "5.8.0",
+    "webpack-node-externals": "3.0.0",
+    "yorkie": "2.0.0"
   },
   },
   "build": {
   "build": {
     "afterSign": "scripts/notarize.js"
     "afterSign": "scripts/notarize.js"

+ 1 - 1
src/common/events.ts

@@ -31,7 +31,7 @@ export default {
   toggle_comment: 'toggle_comment',
   toggle_comment: 'toggle_comment',
   toggle_developer_tools: 'toggle_developer_tools',
   toggle_developer_tools: 'toggle_developer_tools',
   toggle_item: 'toggle_item',
   toggle_item: 'toggle_item',
-  toggle_left_pannel: 'toggle_left_pannel',
+  toggle_left_panel: 'toggle_left_panel',
   tray_list_updated: 'tray:list_updated',
   tray_list_updated: 'tray:list_updated',
   write_hosts_to_system: 'write_hosts_to_system',
   write_hosts_to_system: 'write_hosts_to_system',
 }
 }

+ 1 - 7
src/main/actions/cmd/changeDataDir.ts

@@ -3,13 +3,7 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import {
-  app,
-  BrowserWindow,
-  dialog,
-  OpenDialogOptions,
-  OpenDialogReturnValue,
-} from 'electron'
+import { app, BrowserWindow, dialog, OpenDialogOptions, OpenDialogReturnValue } from 'electron'
 import { localdb } from '@main/data'
 import { localdb } from '@main/data'
 import getDataFolder, { getDefaultDataDir } from '@main/libs/getDataDir'
 import getDataFolder, { getDefaultDataDir } from '@main/libs/getDataDir'
 import getI18N from '@main/core/getI18N'
 import getI18N from '@main/core/getI18N'

+ 3 - 5
src/renderer/components/About/AboutContent.tsx

@@ -4,20 +4,18 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { Box, HStack, Image, VStack } from '@chakra-ui/react'
 import { Box, HStack, Image, VStack } from '@chakra-ui/react'
 import { default as Link } from '@renderer/components/BrowserLink'
 import { default as Link } from '@renderer/components/BrowserLink'
 import logo from '@root/assets/[email protected]'
 import logo from '@root/assets/[email protected]'
 import acknowledgements from '@root/common/acknowledgements'
 import acknowledgements from '@root/common/acknowledgements'
 import { homepage_url, source_url } from '@root/common/constants'
 import { homepage_url, source_url } from '@root/common/constants'
+import useI18n from '@root/renderer/models/useI18n'
 import version from '@root/version.json'
 import version from '@root/version.json'
 import React from 'react'
 import React from 'react'
 import styles from './AboutContent.less'
 import styles from './AboutContent.less'
 
 
-interface Props {}
-
-const AboutContent = (props: Props) => {
-  const { lang } = useModel('useI18n')
+const AboutContent = () => {
+  const { lang } = useI18n()
   const version_str = version.slice(0, 3).join('.') + ` (${version[3]})`
   const version_str = version.slice(0, 3).join('.') + ` (${version[3]})`
 
 
   return (
   return (

+ 3 - 10
src/renderer/components/About/index.tsx

@@ -4,24 +4,17 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
-import {
-  Button,
-  Modal,
-  ModalBody,
-  ModalContent,
-  ModalFooter,
-  ModalOverlay,
-} from '@chakra-ui/react'
+import { Button, Modal, ModalBody, ModalContent, ModalFooter, ModalOverlay } from '@chakra-ui/react'
 import AboutContent from '@renderer/components/About/AboutContent'
 import AboutContent from '@renderer/components/About/AboutContent'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import events from '@root/common/events'
 import events from '@root/common/events'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 import styles from './index.less'
 import styles from './index.less'
+import useI18n from '@renderer/models/useI18n'
 
 
 const About = () => {
 const About = () => {
   const [is_open, setIsOpen] = useState(false)
   const [is_open, setIsOpen] = useState(false)
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
 
 
   const onClose = () => setIsOpen(false)
   const onClose = () => setIsOpen(false)
 
 

+ 11 - 25
src/renderer/components/EditHostsInfo.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -37,13 +36,14 @@ import lodash from 'lodash'
 import React, { useRef, useState } from 'react'
 import React, { useRef, useState } from 'react'
 import { BiEdit, BiTrash } from 'react-icons/bi'
 import { BiEdit, BiTrash } from 'react-icons/bi'
 import { v4 as uuidv4 } from 'uuid'
 import { v4 as uuidv4 } from 'uuid'
+import useHostsData from '../models/useHostsData'
+import useI18n from '../models/useI18n'
 import styles from './EditHostsInfo.less'
 import styles from './EditHostsInfo.less'
 
 
 const EditHostsInfo = () => {
 const EditHostsInfo = () => {
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
   const [hosts, setHosts] = useState<IHostsListObject | null>(null)
   const [hosts, setHosts] = useState<IHostsListObject | null>(null)
-  const { hosts_data, setList, current_hosts, setCurrentHosts } =
-    useModel('useHostsData')
+  const { hosts_data, setList, current_hosts, setCurrentHosts } = useHostsData()
   const [is_show, setIsShow] = useState(false)
   const [is_show, setIsShow] = useState(false)
   const [is_add, setIsAdd] = useState(true)
   const [is_add, setIsAdd] = useState(true)
   const [is_refreshing, setIsRefreshing] = useState(false)
   const [is_refreshing, setIsRefreshing] = useState(false)
@@ -77,10 +77,7 @@ const EditHostsInfo = () => {
       agent.broadcast(events.select_hosts, h.id, 1000)
       agent.broadcast(events.select_hosts, h.id, 1000)
     } else if (data && data.id) {
     } else if (data && data.id) {
       // edit
       // edit
-      let h: IHostsListObject | undefined = hostsFn.findItemById(
-        hosts_data.list,
-        data.id,
-      )
+      let h: IHostsListObject | undefined = hostsFn.findItemById(hosts_data.list, data.id)
       if (h) {
       if (h) {
         Object.assign(h, data)
         Object.assign(h, data)
         await setList([...hosts_data.list])
         await setList([...hosts_data.list])
@@ -95,8 +92,8 @@ const EditHostsInfo = () => {
         return
         return
       }
       }
     } else {
     } else {
-      // unknow error
-      alert('unknow error!')
+      // unknown error
+      alert('unknown error!')
     }
     }
 
 
     setIsShow(false)
     setIsShow(false)
@@ -147,9 +144,7 @@ const EditHostsInfo = () => {
           <div>
           <div>
             <Select
             <Select
               value={hosts?.refresh_interval || 0}
               value={hosts?.refresh_interval || 0}
-              onChange={(e) =>
-                onUpdate({ refresh_interval: parseInt(e.target.value) || 0 })
-              }
+              onChange={(e) => onUpdate({ refresh_interval: parseInt(e.target.value) || 0 })}
               style={{ minWidth: 120 }}
               style={{ minWidth: 120 }}
             >
             >
               <option value={0}>{lang.never}</option>
               <option value={0}>{lang.never}</option>
@@ -231,9 +226,7 @@ const EditHostsInfo = () => {
     const list = hostsFn.flatten(hosts_data.list)
     const list = hostsFn.flatten(hosts_data.list)
 
 
     let source_list: IHostsListObject[] = list
     let source_list: IHostsListObject[] = list
-      .filter(
-        (item) => !item.type || item.type === 'local' || item.type === 'remote',
-      )
+      .filter((item) => !item.type || item.type === 'local' || item.type === 'remote')
       .map((item) => {
       .map((item) => {
         let o = { ...item }
         let o = { ...item }
         o.key = o.id
         o.key = o.id
@@ -263,9 +256,7 @@ const EditHostsInfo = () => {
         <FormLabel>{lang.choice_mode}</FormLabel>
         <FormLabel>{lang.choice_mode}</FormLabel>
         <RadioGroup
         <RadioGroup
           value={(hosts?.folder_mode || 0).toString()}
           value={(hosts?.folder_mode || 0).toString()}
-          onChange={(v: string) =>
-            onUpdate({ folder_mode: (parseInt(v) || 0) as FolderModeType })
-          }
+          onChange={(v: string) => onUpdate({ folder_mode: (parseInt(v) || 0) as FolderModeType })}
         >
         >
           <HStack spacing={3}>
           <HStack spacing={3}>
             <Radio value="0">{lang.choice_mode_default}</Radio>
             <Radio value="0">{lang.choice_mode_default}</Radio>
@@ -312,12 +303,7 @@ const EditHostsInfo = () => {
   )
   )
 
 
   return (
   return (
-    <Drawer
-      initialFocusRef={ipt_title_ref}
-      isOpen={is_show}
-      onClose={onCancel}
-      size="lg"
-    >
+    <Drawer initialFocusRef={ipt_title_ref} isOpen={is_show} onClose={onCancel} size="lg">
       <DrawerOverlay />
       <DrawerOverlay />
       <DrawerContent>
       <DrawerContent>
         <DrawerHeader>
         <DrawerHeader>

+ 3 - 5
src/renderer/components/Editor/HostsEditor.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import StatusBar from '@renderer/components/StatusBar'
 import StatusBar from '@renderer/components/StatusBar'
 import { actions, agent } from '@renderer/core/agent'
 import { actions, agent } from '@renderer/core/agent'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
@@ -21,13 +20,12 @@ import React, { useEffect, useRef, useState } from 'react'
 import modeHosts from './cm_hl'
 import modeHosts from './cm_hl'
 import './codemirror.less'
 import './codemirror.less'
 import styles from './HostsEditor.less'
 import styles from './HostsEditor.less'
+import useHostsData from '@renderer/models/useHostsData'
 
 
 modeHosts()
 modeHosts()
 
 
-interface Props {}
-
-const HostsEditor = (props: Props) => {
-  const { current_hosts, hosts_data, isReadOnly } = useModel('useHostsData')
+const HostsEditor = () => {
+  const { current_hosts, hosts_data, isReadOnly } = useHostsData()
   const [hosts_id, setHostsId] = useState(current_hosts?.id || '0')
   const [hosts_id, setHostsId] = useState(current_hosts?.id || '0')
   const [content, setContent] = useState('')
   const [content, setContent] = useState('')
   const [is_read_only, setIsReadOnly] = useState(true)
   const [is_read_only, setIsReadOnly] = useState(true)

+ 8 - 18
src/renderer/components/History.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -35,6 +34,8 @@ import dayjs from 'dayjs'
 import prettyBytes from 'pretty-bytes'
 import prettyBytes from 'pretty-bytes'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 import { BiDetail, BiHelpCircle, BiHistory, BiTrash } from 'react-icons/bi'
 import { BiDetail, BiHelpCircle, BiHistory, BiTrash } from 'react-icons/bi'
+import useConfigs from '../models/useConfigs'
+import useI18n from '../models/useI18n'
 import styles from './History.less'
 import styles from './History.less'
 
 
 interface IHistoryProps {
 interface IHistoryProps {
@@ -45,7 +46,7 @@ interface IHistoryProps {
 
 
 const HistoryList = (props: IHistoryProps): React.ReactElement => {
 const HistoryList = (props: IHistoryProps): React.ReactElement => {
   const { list, selected_item, setSelectedItem } = props
   const { list, selected_item, setSelectedItem } = props
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
 
 
   if (list.length === 0) {
   if (list.length === 0) {
     return (
     return (
@@ -60,13 +61,7 @@ const HistoryList = (props: IHistoryProps): React.ReactElement => {
       <Box flex={1} mr={3} borderWidth="1px" borderRadius="md">
       <Box flex={1} mr={3} borderWidth="1px" borderRadius="md">
         <HostsViewer content={selected_item ? selected_item.content : ''} />
         <HostsViewer content={selected_item ? selected_item.content : ''} />
       </Box>
       </Box>
-      <List
-        w="200px"
-        h="100%"
-        overflow="auto"
-        borderWidth="1px"
-        borderRadius="md"
-      >
+      <List w="200px" h="100%" overflow="auto" borderWidth="1px" borderRadius="md">
         {list.map((item) => (
         {list.map((item) => (
           <ListItem
           <ListItem
             key={item.id}
             key={item.id}
@@ -81,9 +76,7 @@ const HistoryList = (props: IHistoryProps): React.ReactElement => {
                 <BiDetail />
                 <BiDetail />
               </Box>
               </Box>
               <VStack align="left" spacing={0}>
               <VStack align="left" spacing={0}>
-                <Box>
-                  {dayjs(item.add_time_ms).format('YYYY-MM-DD HH:mm:ss')}
-                </Box>
+                <Box>{dayjs(item.add_time_ms).format('YYYY-MM-DD HH:mm:ss')}</Box>
                 <HStack lineHeight="14px" fontSize="9px" opacity={0.6}>
                 <HStack lineHeight="14px" fontSize="9px" opacity={0.6}>
                   <Box>{item.content.split('\n').length} lines</Box>
                   <Box>{item.content.split('\n').length} lines</Box>
                   <Box>{prettyBytes(item.content.length)}</Box>
                   <Box>{prettyBytes(item.content.length)}</Box>
@@ -107,14 +100,14 @@ const Loading = (): React.ReactElement => {
 }
 }
 
 
 const History = () => {
 const History = () => {
-  const { configs, updateConfigs } = useModel('useConfigs')
+  const { configs, updateConfigs } = useConfigs()
   const [is_open, setIsOpen] = useState(false)
   const [is_open, setIsOpen] = useState(false)
   const [is_loading, setIsLoading] = useState(false)
   const [is_loading, setIsLoading] = useState(false)
   const [list, setList] = useState<IHostsHistoryObject[]>([])
   const [list, setList] = useState<IHostsHistoryObject[]>([])
   const [selected_item, setSelectedItem] = useState<IHostsHistoryObject>()
   const [selected_item, setSelectedItem] = useState<IHostsHistoryObject>()
   // const btn_close = useRef(null)
   // const btn_close = useRef(null)
 
 
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
 
 
   const loadData = async () => {
   const loadData = async () => {
     setIsLoading(true)
     setIsLoading(true)
@@ -213,10 +206,7 @@ const History = () => {
                 ))}
                 ))}
               </Select>
               </Select>
             </Box>
             </Box>
-            <Tooltip
-              label={lang.system_hosts_history_help}
-              aria-label="A tooltip"
-            >
+            <Tooltip label={lang.system_hosts_history_help} aria-label="A tooltip">
               <Box ml={3}>
               <Box ml={3}>
                 <BiHelpCircle />
                 <BiHelpCircle />
               </Box>
               </Box>

+ 2 - 2
src/renderer/components/Lang.tsx

@@ -4,9 +4,9 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { LocaleName } from '@root/common/i18n'
 import { LocaleName } from '@root/common/i18n'
 import React from 'react'
 import React from 'react'
+import useI18n from '@renderer/models/useI18n'
 
 
 interface Props {
 interface Props {
   locale: LocaleName
   locale: LocaleName
@@ -14,7 +14,7 @@ interface Props {
 }
 }
 
 
 const Lang = (props: Props): React.ReactElement | null => {
 const Lang = (props: Props): React.ReactElement | null => {
-  const { locale } = useModel('useI18n')
+  const { locale } = useI18n()
 
 
   if (locale !== props.locale) {
   if (locale !== props.locale) {
     return null
     return null

+ 6 - 10
src/renderer/components/LeftPanel/SystemHostsItem.tsx

@@ -4,17 +4,16 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import ItemIcon from '@renderer/components/ItemIcon'
 import ItemIcon from '@renderer/components/ItemIcon'
 import clsx from 'clsx'
 import clsx from 'clsx'
 import React from 'react'
 import React from 'react'
 import styles from './SystemHostsItem.less'
 import styles from './SystemHostsItem.less'
+import useI18n from '@renderer/models/useI18n'
+import useHostsData from '@renderer/models/useHostsData'
 
 
-interface Props {}
-
-const SystemHostsItem = (props: Props) => {
-  const { i18n } = useModel('useI18n')
-  const { current_hosts, setCurrentHosts } = useModel('useHostsData')
+const SystemHostsItem = () => {
+  const { i18n } = useI18n()
+  const { current_hosts, setCurrentHosts } = useHostsData()
 
 
   const is_selected = !current_hosts
   const is_selected = !current_hosts
 
 
@@ -23,10 +22,7 @@ const SystemHostsItem = (props: Props) => {
   }
   }
 
 
   return (
   return (
-    <div
-      className={clsx(styles.root, is_selected && styles.selected)}
-      onClick={showSystemHosts}
-    >
+    <div className={clsx(styles.root, is_selected && styles.selected)} onClick={showSystemHosts}>
       <span className={styles.icon}>
       <span className={styles.icon}>
         <ItemIcon type="system" />
         <ItemIcon type="system" />
       </span>
       </span>

+ 6 - 10
src/renderer/components/LeftPanel/Trashcan.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { Center } from '@chakra-ui/react'
 import { Center } from '@chakra-ui/react'
 import TrashcanItem from '@renderer/components/LeftPanel/TrashcanItem'
 import TrashcanItem from '@renderer/components/LeftPanel/TrashcanItem'
 import list_styles from '@renderer/components/List/index.less'
 import list_styles from '@renderer/components/List/index.less'
@@ -13,13 +12,12 @@ import { ITrashcanListObject } from '@root/common/data'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import { BiChevronRight } from 'react-icons/bi'
 import { BiChevronRight } from 'react-icons/bi'
 import styles from './Trashcan.less'
 import styles from './Trashcan.less'
+import useI18n from '@renderer/models/useI18n'
+import useHostsData from '@renderer/models/useHostsData'
 
 
-interface Props {}
-
-const Trashcan = (props: Props) => {
-  const { lang } = useModel('useI18n')
-  const { hosts_data, current_hosts, setCurrentHosts } =
-    useModel('useHostsData')
+const Trashcan = () => {
+  const { lang } = useI18n()
+  const { hosts_data, current_hosts, setCurrentHosts } = useHostsData()
   const [trash_list, setTrashList] = useState<ITrashcanListObject[]>([])
   const [trash_list, setTrashList] = useState<ITrashcanListObject[]>([])
   const [is_collapsed, setIsCollapsed] = useState(true)
   const [is_collapsed, setIsCollapsed] = useState(true)
 
 
@@ -66,9 +64,7 @@ const Trashcan = (props: Props) => {
     <div className={styles.root}>
     <div className={styles.root}>
       <Tree
       <Tree
         data={trash_list}
         data={trash_list}
-        nodeRender={(item) => (
-          <TrashcanItem data={item as ITrashcanListObject} />
-        )}
+        nodeRender={(item) => <TrashcanItem data={item as ITrashcanListObject} />}
         collapseArrow={
         collapseArrow={
           <Center w="20px" h="20px">
           <Center w="20px" h="20px">
             <BiChevronRight />
             <BiChevronRight />

+ 5 - 6
src/renderer/components/LeftPanel/TrashcanItem.tsx

@@ -4,15 +4,16 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import ItemIcon from '@renderer/components/ItemIcon'
 import ItemIcon from '@renderer/components/ItemIcon'
 import list_item_styles from '@renderer/components/List/ListItem.less'
 import list_item_styles from '@renderer/components/List/ListItem.less'
 import { actions } from '@renderer/core/agent'
 import { actions } from '@renderer/core/agent'
 import { PopupMenu } from '@renderer/core/PopupMenu'
 import { PopupMenu } from '@renderer/core/PopupMenu'
 import { ITrashcanListObject } from '@root/common/data'
 import { ITrashcanListObject } from '@root/common/data'
+import useI18n from '@root/renderer/models/useI18n'
 import clsx from 'clsx'
 import clsx from 'clsx'
 import React from 'react'
 import React from 'react'
 import styles from './TrashcanItem.less'
 import styles from './TrashcanItem.less'
+import useHostsData from '@renderer/models/useHostsData'
 
 
 interface Props {
 interface Props {
   data: ITrashcanListObject
   data: ITrashcanListObject
@@ -20,8 +21,8 @@ interface Props {
 
 
 const TrashcanItem = (props: Props) => {
 const TrashcanItem = (props: Props) => {
   const { data } = props
   const { data } = props
-  const { lang } = useModel('useI18n')
-  const { hosts_data, loadHostsData } = useModel('useHostsData')
+  const { lang } = useI18n()
+  const { hosts_data, loadHostsData } = useHostsData()
 
 
   const onSelect = (i: any) => {
   const onSelect = (i: any) => {
     console.log(i)
     console.log(i)
@@ -87,9 +88,7 @@ const TrashcanItem = (props: Props) => {
 
 
         {data.data.title || lang.untitled}
         {data.data.title || lang.untitled}
 
 
-        {data.is_root ? (
-          <span className={styles.count}>{data.children?.length || 0}</span>
-        ) : null}
+        {data.is_root ? <span className={styles.count}>{data.children?.length || 0}</span> : null}
       </div>
       </div>
     </div>
     </div>
   )
   )

+ 4 - 3
src/renderer/components/LeftPanel/index.tsx

@@ -4,22 +4,23 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import Trashcan from '@renderer/components/LeftPanel/Trashcan'
 import Trashcan from '@renderer/components/LeftPanel/Trashcan'
 import List from '@renderer/components/List'
 import List from '@renderer/components/List'
 import { agent } from '@renderer/core/agent'
 import { agent } from '@renderer/core/agent'
 import { PopupMenu } from '@renderer/core/PopupMenu'
 import { PopupMenu } from '@renderer/core/PopupMenu'
 import events from '@root/common/events'
 import events from '@root/common/events'
+import useI18n from '@root/renderer/models/useI18n'
 import React from 'react'
 import React from 'react'
 import styles from './index.less'
 import styles from './index.less'
+import useHostsData from '@renderer/models/useHostsData'
 
 
 interface Props {
 interface Props {
   width: number
   width: number
 }
 }
 
 
 const Index = (props: Props) => {
 const Index = (props: Props) => {
-  const { lang } = useModel('useI18n')
-  const { hosts_data } = useModel('useHostsData')
+  const { lang } = useI18n()
+  const { hosts_data } = useHostsData()
 
 
   const menu = new PopupMenu([
   const menu = new PopupMenu([
     {
     {

+ 4 - 3
src/renderer/components/List/ListItem.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import ItemIcon from '@renderer/components/ItemIcon'
 import ItemIcon from '@renderer/components/ItemIcon'
 import SwitchButton from '@renderer/components/SwitchButton'
 import SwitchButton from '@renderer/components/SwitchButton'
 import { actions, agent } from '@renderer/core/agent'
 import { actions, agent } from '@renderer/core/agent'
@@ -19,6 +18,8 @@ import scrollIntoView from 'smooth-scroll-into-view-if-needed'
 import styles from './ListItem.less'
 import styles from './ListItem.less'
 import events from '@root/common/events'
 import events from '@root/common/events'
 import { IMenuItemOption } from '@root/common/types'
 import { IMenuItemOption } from '@root/common/types'
+import useI18n from '@renderer/models/useI18n'
+import useHostsData from '@renderer/models/useHostsData'
 
 
 interface Props {
 interface Props {
   data: IHostsListObject
   data: IHostsListObject
@@ -28,8 +29,8 @@ interface Props {
 
 
 const ListItem = (props: Props) => {
 const ListItem = (props: Props) => {
   const { data, is_tray, selected_ids } = props
   const { data, is_tray, selected_ids } = props
-  const { lang, i18n } = useModel('useI18n')
-  const { hosts_data, setList, current_hosts, setCurrentHosts } = useModel('useHostsData')
+  const { lang, i18n } = useI18n()
+  const { hosts_data, setList, current_hosts, setCurrentHosts } = useHostsData()
   const [is_collapsed, setIsCollapsed] = useState(!!data.is_collapsed)
   const [is_collapsed, setIsCollapsed] = useState(!!data.is_collapsed)
   const [is_on, setIsOn] = useState(data.on)
   const [is_on, setIsOn] = useState(data.on)
   const el = useRef<HTMLDivElement>(null)
   const el = useRef<HTMLDivElement>(null)

+ 7 - 6
src/renderer/components/List/index.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { Center, useToast } from '@chakra-ui/react'
 import { Center, useToast } from '@chakra-ui/react'
 import { IHostsWriteOptions } from '@main/types'
 import { IHostsWriteOptions } from '@main/types'
 import ItemIcon from '@renderer/components/ItemIcon'
 import ItemIcon from '@renderer/components/ItemIcon'
@@ -15,11 +14,14 @@ import { IHostsListObject } from '@root/common/data'
 import events from '@root/common/events'
 import events from '@root/common/events'
 import { findItemById, getNextSelectedItem, setOnStateOfItem } from '@root/common/hostsFn'
 import { findItemById, getNextSelectedItem, setOnStateOfItem } from '@root/common/hostsFn'
 import { IFindShowSourceParam } from '@root/common/types'
 import { IFindShowSourceParam } from '@root/common/types'
+import useI18n from '@root/renderer/models/useI18n'
 import clsx from 'clsx'
 import clsx from 'clsx'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import { BiChevronRight } from 'react-icons/bi'
 import { BiChevronRight } from 'react-icons/bi'
 import styles from './index.less'
 import styles from './index.less'
 import ListItem from './ListItem'
 import ListItem from './ListItem'
+import useConfigs from '@renderer/models/useConfigs'
+import useHostsData from '@root/renderer/models/useHostsData'
 
 
 interface Props {
 interface Props {
   is_tray?: boolean
   is_tray?: boolean
@@ -27,10 +29,9 @@ interface Props {
 
 
 const List = (props: Props) => {
 const List = (props: Props) => {
   const { is_tray } = props
   const { is_tray } = props
-  const { hosts_data, loadHostsData, setList, current_hosts, setCurrentHosts } =
-    useModel('useHostsData')
-  const { configs } = useModel('useConfigs')
-  const { lang } = useModel('useI18n')
+  const { hosts_data, loadHostsData, setList, current_hosts, setCurrentHosts } = useHostsData()
+  const { configs } = useConfigs()
+  const { lang } = useI18n()
   const [selected_ids, setSelectedIds] = useState<string[]>([current_hosts?.id || '0'])
   const [selected_ids, setSelectedIds] = useState<string[]>([current_hosts?.id || '0'])
   const [show_list, setShowList] = useState<IHostsListObject[]>([])
   const [show_list, setShowList] = useState<IHostsListObject[]>([])
   const toast = useToast()
   const toast = useToast()
@@ -112,7 +113,7 @@ const List = (props: Props) => {
           agent.broadcast(events.show_sudo_password_input, list)
           agent.broadcast(events.show_sudo_password_input, list)
         }
         }
         // } else {
         // } else {
-        // body = result.message || 'Unknow error!'
+        // body = result.message || 'Unknown error!'
         err_desc = lang.no_access_to_hosts
         err_desc = lang.no_access_to_hosts
       }
       }
 
 

+ 3 - 5
src/renderer/components/Loading.tsx

@@ -4,14 +4,12 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import React from 'react'
 import React from 'react'
 import styles from './Loading.less'
 import styles from './Loading.less'
+import useI18n from '@renderer/models/useI18n'
 
 
-interface Props {}
-
-const Loading = (props: Props) => {
-  const { i18n } = useModel('useI18n')
+const Loading = () => {
+  const { i18n } = useI18n()
 
 
   return <div className={styles.root}>{i18n.lang.loading}</div>
   return <div className={styles.root}>{i18n.lang.loading}</div>
 }
 }

+ 1 - 4
src/renderer/components/MainPanel/index.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import HostsEditor from '@renderer/components/Editor/HostsEditor'
 import HostsEditor from '@renderer/components/Editor/HostsEditor'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import events from '@root/common/events'
 import events from '@root/common/events'
@@ -12,9 +11,7 @@ import React from 'react'
 import styles from './index.less'
 import styles from './index.less'
 import { useToast } from '@chakra-ui/react'
 import { useToast } from '@chakra-ui/react'
 
 
-interface Props {}
-
-const MainPanel = (props: Props) => {
+const MainPanel = () => {
   const toast = useToast()
   const toast = useToast()
 
 
   useOnBroadcast(events.cmd_run_result, (result) => {
   useOnBroadcast(events.cmd_run_result, (result) => {

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

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Button,
   Button,
   Checkbox,
   Checkbox,
@@ -18,6 +17,7 @@ import {
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import { actions } from '@renderer/core/agent'
 import { actions } from '@renderer/core/agent'
 import { ConfigsType } from '@root/common/default_configs'
 import { ConfigsType } from '@root/common/default_configs'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import styles from './styles.less'
 import styles from './styles.less'
 
 
@@ -28,7 +28,7 @@ interface IProps {
 
 
 const PathLink = (props: { link: string }) => {
 const PathLink = (props: { link: string }) => {
   const { link } = props
   const { link } = props
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
 
 
   return (
   return (
     <Tooltip label={lang.click_to_open}>
     <Tooltip label={lang.click_to_open}>
@@ -49,19 +49,15 @@ const PathLink = (props: { link: string }) => {
 
 
 const Advanced = (props: IProps) => {
 const Advanced = (props: IProps) => {
   const { data, onChange } = props
   const { data, onChange } = props
-  const { i18n, lang } = useModel('useI18n')
+  const { i18n, lang } = useI18n()
   const [hosts_path, setHostsPath] = useState('')
   const [hosts_path, setHostsPath] = useState('')
   const [data_dir, setDataDir] = useState('')
   const [data_dir, setDataDir] = useState('')
   const [default_data_dir, setDefaultDataDir] = useState('')
   const [default_data_dir, setDefaultDataDir] = useState('')
 
 
   useEffect(() => {
   useEffect(() => {
-    actions
-      .getPathOfSystemHosts()
-      .then((hosts_path) => setHostsPath(hosts_path))
+    actions.getPathOfSystemHosts().then((hosts_path) => setHostsPath(hosts_path))
     actions.getDataDir().then((data_dir) => setDataDir(data_dir))
     actions.getDataDir().then((data_dir) => setDataDir(data_dir))
-    actions
-      .getDefaultDataDir()
-      .then((default_data_dir) => setDefaultDataDir(default_data_dir))
+    actions.getDefaultDataDir().then((default_data_dir) => setDefaultDataDir(default_data_dir))
   }, [])
   }, [])
 
 
   return (
   return (
@@ -102,11 +98,7 @@ const Advanced = (props: IProps) => {
             <Button
             <Button
               variant="link"
               variant="link"
               onClick={async () => {
               onClick={async () => {
-                if (
-                  !confirm(
-                    i18n.trans('reset_data_dir_confirm', [default_data_dir]),
-                  )
-                ) {
+                if (!confirm(i18n.trans('reset_data_dir_confirm', [default_data_dir]))) {
                   return
                   return
                 }
                 }
                 let r = await actions.cmdChangeDataDir(true)
                 let r = await actions.cmdChangeDataDir(true)

+ 2 - 2
src/renderer/components/Pref/Commands.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -16,6 +15,7 @@ import {
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import CommandsHistory from '@renderer/components/Pref/CommandsHistory'
 import CommandsHistory from '@renderer/components/Pref/CommandsHistory'
 import { ConfigsType } from '@root/common/default_configs'
 import { ConfigsType } from '@root/common/default_configs'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 
 
 interface IProps {
 interface IProps {
@@ -25,7 +25,7 @@ interface IProps {
 
 
 const Commands = (props: IProps) => {
 const Commands = (props: IProps) => {
   const { data, onChange } = props
   const { data, onChange } = props
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
   const [show_history, setShowHistory] = useState(false)
   const [show_history, setShowHistory] = useState(false)
 
 
   const toggleShowHistory = () => {
   const toggleShowHistory = () => {

+ 2 - 2
src/renderer/components/Pref/CommandsHistory.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Alert,
   Alert,
   AlertDescription,
   AlertDescription,
@@ -20,6 +19,7 @@ import {
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import { actions } from '@renderer/core/agent'
 import { actions } from '@renderer/core/agent'
 import { ICommandRunResult } from '@root/common/data'
 import { ICommandRunResult } from '@root/common/data'
+import useI18n from '@root/renderer/models/useI18n'
 import dayjs from 'dayjs'
 import dayjs from 'dayjs'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import { BiTrash } from 'react-icons/bi'
 import { BiTrash } from 'react-icons/bi'
@@ -31,7 +31,7 @@ interface Props {
 const CommandsHistory = (props: Props) => {
 const CommandsHistory = (props: Props) => {
   const { is_show } = props
   const { is_show } = props
   const [list, setList] = useState<ICommandRunResult[]>([])
   const [list, setList] = useState<ICommandRunResult[]>([])
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
 
 
   const loadData = async () => {
   const loadData = async () => {
     let data = await actions.cmdGetHistoryList()
     let data = await actions.cmdGetHistoryList()

+ 14 - 31
src/renderer/components/Pref/General.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Checkbox,
   Checkbox,
@@ -15,13 +14,14 @@ import {
   Radio,
   Radio,
   RadioGroup,
   RadioGroup,
   Select,
   Select,
-  VStack,
   Stack,
   Stack,
+  VStack,
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import { agent } from '@renderer/core/agent'
 import { agent } from '@renderer/core/agent'
 import { http_api_port } from '@root/common/constants'
 import { http_api_port } from '@root/common/constants'
 import { ConfigsType, ThemeType } from '@root/common/default_configs'
 import { ConfigsType, ThemeType } from '@root/common/default_configs'
 import { LocaleName } from '@root/common/i18n'
 import { LocaleName } from '@root/common/i18n'
+import useI18n from '@root/renderer/models/useI18n'
 import React from 'react'
 import React from 'react'
 
 
 interface IProps {
 interface IProps {
@@ -31,7 +31,7 @@ interface IProps {
 
 
 const General = (props: IProps) => {
 const General = (props: IProps) => {
   const { data, onChange } = props
   const { data, onChange } = props
-  const { i18n, lang } = useModel('useI18n')
+  const { i18n, lang } = useI18n()
   const { platform } = agent
   const { platform } = agent
 
 
   const label_width = 20
   const label_width = 20
@@ -92,8 +92,7 @@ const General = (props: IProps) => {
             </RadioGroup>
             </RadioGroup>
             <FormHelperText maxW={'350px'}>
             <FormHelperText maxW={'350px'}>
               {data.write_mode === 'append' && lang.write_mode_append_help}
               {data.write_mode === 'append' && lang.write_mode_append_help}
-              {data.write_mode === 'overwrite' &&
-                lang.write_mode_overwrite_help}
+              {data.write_mode === 'overwrite' && lang.write_mode_overwrite_help}
             </FormHelperText>
             </FormHelperText>
           </VStack>
           </VStack>
         </HStack>
         </HStack>
@@ -107,9 +106,7 @@ const General = (props: IProps) => {
               value={data.choice_mode.toString()}
               value={data.choice_mode.toString()}
               onChange={(v) =>
               onChange={(v) =>
                 onChange({
                 onChange({
-                  choice_mode: parseInt(
-                    v.toString(),
-                  ) as ConfigsType['choice_mode'],
+                  choice_mode: parseInt(v.toString()) as ConfigsType['choice_mode'],
                 })
                 })
               }
               }
             >
             >
@@ -122,9 +119,7 @@ const General = (props: IProps) => {
                 </Radio>
                 </Radio>
               </HStack>
               </HStack>
             </RadioGroup>
             </RadioGroup>
-            <FormHelperText maxW={'350px'}>
-              {lang.choice_mode_desc}
-            </FormHelperText>
+            <FormHelperText maxW={'350px'}>{lang.choice_mode_desc}</FormHelperText>
           </VStack>
           </VStack>
         </HStack>
         </HStack>
       </FormControl>
       </FormControl>
@@ -134,9 +129,7 @@ const General = (props: IProps) => {
           <HStack>
           <HStack>
             <Checkbox
             <Checkbox
               isChecked={data.show_title_on_tray}
               isChecked={data.show_title_on_tray}
-              onChange={(e) =>
-                onChange({ show_title_on_tray: e.target.checked })
-              }
+              onChange={(e) => onChange({ show_title_on_tray: e.target.checked })}
             >
             >
               {lang.show_title_on_tray}
               {lang.show_title_on_tray}
             </Checkbox>
             </Checkbox>
@@ -185,25 +178,19 @@ const General = (props: IProps) => {
         <VStack align="left">
         <VStack align="left">
           <Checkbox
           <Checkbox
             isChecked={data.remove_duplicate_records}
             isChecked={data.remove_duplicate_records}
-            onChange={(e) =>
-              onChange({ remove_duplicate_records: e.target.checked })
-            }
+            onChange={(e) => onChange({ remove_duplicate_records: e.target.checked })}
           >
           >
             {lang.remove_duplicate_records}
             {lang.remove_duplicate_records}
           </Checkbox>
           </Checkbox>
-          <FormHelperText pl="20px">
-            {lang.remove_duplicate_records_desc}
-          </FormHelperText>
+          <FormHelperText pl="20px">{lang.remove_duplicate_records_desc}</FormHelperText>
         </VStack>
         </VStack>
       </FormControl>
       </FormControl>
 
 
       <FormControl>
       <FormControl>
         <VStack align="left">
         <VStack align="left">
           <Checkbox
           <Checkbox
-              isChecked={data.tray_mini_window}
-              onChange={(e) =>
-                  onChange({ tray_mini_window: e.target.checked })
-              }
+            isChecked={data.tray_mini_window}
+            onChange={(e) => onChange({ tray_mini_window: e.target.checked })}
           >
           >
             {lang.tray_mini_window}
             {lang.tray_mini_window}
           </Checkbox>
           </Checkbox>
@@ -213,10 +200,8 @@ const General = (props: IProps) => {
       <FormControl>
       <FormControl>
         <VStack align="left">
         <VStack align="left">
           <Checkbox
           <Checkbox
-              isChecked={data.multi_chose_folder_switch_all}
-              onChange={(e) =>
-                  onChange({ multi_chose_folder_switch_all: e.target.checked })
-              }
+            isChecked={data.multi_chose_folder_switch_all}
+            onChange={(e) => onChange({ multi_chose_folder_switch_all: e.target.checked })}
           >
           >
             {lang.multi_chose_folder_switch_all}
             {lang.multi_chose_folder_switch_all}
           </Checkbox>
           </Checkbox>
@@ -238,9 +223,7 @@ const General = (props: IProps) => {
             <Checkbox
             <Checkbox
               isDisabled={!data.http_api_on}
               isDisabled={!data.http_api_on}
               isChecked={data.http_api_only_local}
               isChecked={data.http_api_only_local}
-              onChange={(e) =>
-                onChange({ http_api_only_local: e.target.checked })
-              }
+              onChange={(e) => onChange({ http_api_only_local: e.target.checked })}
             >
             >
               {lang.http_api_only_local}
               {lang.http_api_only_local}
             </Checkbox>
             </Checkbox>

+ 3 - 5
src/renderer/components/Pref/Proxy.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Checkbox,
   Checkbox,
   FormControl,
   FormControl,
@@ -17,6 +16,7 @@ import {
   VStack,
   VStack,
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import { ConfigsType, ProtocolType } from '@root/common/default_configs'
 import { ConfigsType, ProtocolType } from '@root/common/default_configs'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 
 
 interface IProps {
 interface IProps {
@@ -26,7 +26,7 @@ interface IProps {
 
 
 const General = (props: IProps) => {
 const General = (props: IProps) => {
   const { data, onChange } = props
   const { data, onChange } = props
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
   const [is_use, setIsUse] = useState(data.use_proxy)
   const [is_use, setIsUse] = useState(data.use_proxy)
 
 
   const label_width = 20
   const label_width = 20
@@ -55,9 +55,7 @@ const General = (props: IProps) => {
             w="200px"
             w="200px"
             isDisabled={!is_use}
             isDisabled={!is_use}
             value={data.proxy_protocol}
             value={data.proxy_protocol}
-            onChange={(e) =>
-              onChange({ proxy_protocol: e.target.value as ProtocolType })
-            }
+            onChange={(e) => onChange({ proxy_protocol: e.target.value as ProtocolType })}
           >
           >
             <option value="http">HTTP</option>
             <option value="http">HTTP</option>
             <option value="https">HTTPS</option>
             <option value="https">HTTPS</option>

+ 5 - 6
src/renderer/components/Pref/index.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -27,6 +26,8 @@ import { agent } from '@renderer/core/agent'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import { ConfigsType } from '@root/common/default_configs'
 import { ConfigsType } from '@root/common/default_configs'
 import events from '@root/common/events'
 import events from '@root/common/events'
+import useConfigs from '@root/renderer/models/useConfigs'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import { BiSliderAlt } from 'react-icons/bi'
 import { BiSliderAlt } from 'react-icons/bi'
 import Advanced from './Advanced'
 import Advanced from './Advanced'
@@ -34,13 +35,11 @@ import Commands from './Commands'
 import General from './General'
 import General from './General'
 import styles from './styles.less'
 import styles from './styles.less'
 
 
-interface Props {}
-
-const PreferencePanel = (props: Props) => {
+const PreferencePanel = () => {
   const [is_open, setIsOpen] = useState(false)
   const [is_open, setIsOpen] = useState(false)
-  const { configs, updateConfigs } = useModel('useConfigs')
+  const { configs, updateConfigs } = useConfigs()
   const [data, setData] = useState<ConfigsType | null>(configs)
   const [data, setData] = useState<ConfigsType | null>(configs)
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
   const { colorMode, setColorMode } = useColorMode()
   const { colorMode, setColorMode } = useColorMode()
 
 
   const onClose = () => {
   const onClose = () => {

+ 6 - 7
src/renderer/components/SetWriteMode.tsx

@@ -3,7 +3,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -23,6 +22,8 @@ import events from '@root/common/events'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 import styles from './SetWriteMode.less'
 import styles from './SetWriteMode.less'
 import { WriteModeType } from '@root/common/default_configs'
 import { WriteModeType } from '@root/common/default_configs'
+import useI18n from '@renderer/models/useI18n'
+import useConfigs from '../models/useConfigs'
 
 
 interface Props {}
 interface Props {}
 
 
@@ -31,15 +32,13 @@ interface IPendingData {
   on: boolean
   on: boolean
 }
 }
 
 
-const SetWriteMode = (props: Props) => {
-  const { updateConfigs } = useModel('useConfigs')
-  const { lang } = useModel('useI18n')
+const SetWriteMode = () => {
+  const { updateConfigs } = useConfigs()
+  const { lang } = useI18n()
   const [is_show, setIsShow] = useState(false)
   const [is_show, setIsShow] = useState(false)
   const ipt_ref = React.useRef<HTMLInputElement>(null)
   const ipt_ref = React.useRef<HTMLInputElement>(null)
   const [write_mode, setWriteMode] = useState<WriteModeType>(null)
   const [write_mode, setWriteMode] = useState<WriteModeType>(null)
-  const [pending_data, setPendingData] = useState<IPendingData | undefined>(
-    undefined,
-  )
+  const [pending_data, setPendingData] = useState<IPendingData | undefined>(undefined)
 
 
   const onCancel = () => {
   const onCancel = () => {
     setIsShow(false)
     setIsShow(false)

+ 2 - 2
src/renderer/components/StatusBar.tsx

@@ -4,11 +4,11 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { Box, Flex, HStack, Spacer } from '@chakra-ui/react'
 import { Box, Flex, HStack, Spacer } from '@chakra-ui/react'
 import React from 'react'
 import React from 'react'
 import prettyBytes from 'pretty-bytes'
 import prettyBytes from 'pretty-bytes'
 import styles from './StatusBar.less'
 import styles from './StatusBar.less'
+import useI18n from '../models/useI18n'
 
 
 interface Props {
 interface Props {
   line_count: number
   line_count: number
@@ -18,7 +18,7 @@ interface Props {
 
 
 const StatusBar = (props: Props) => {
 const StatusBar = (props: Props) => {
   const { line_count, bytes, read_only } = props
   const { line_count, bytes, read_only } = props
-  const { i18n } = useModel('useI18n')
+  const { i18n } = useI18n()
 
 
   return (
   return (
     <Flex className={styles.root} px="10px" userSelect="none">
     <Flex className={styles.root} px="10px" userSelect="none">

+ 3 - 5
src/renderer/components/SudoPasswordInput.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Button,
   Button,
   Input,
   Input,
@@ -20,12 +19,11 @@ import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import { IHostsListObject } from '@root/common/data'
 import { IHostsListObject } from '@root/common/data'
 import events from '@root/common/events'
 import events from '@root/common/events'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
+import useI18n from '../models/useI18n'
 import styles from './SudoPasswordInput.less'
 import styles from './SudoPasswordInput.less'
 
 
-interface Props {}
-
-const SudoPasswordInput = (props: Props) => {
-  const { lang } = useModel('useI18n')
+const SudoPasswordInput = () => {
+  const { lang } = useI18n()
   const [is_show, setIsShow] = useState(false)
   const [is_show, setIsShow] = useState(false)
   const [pswd, setPswd] = useState('')
   const [pswd, setPswd] = useState('')
   const [tmp_list, setTmpList] = useState<IHostsListObject[] | undefined>()
   const [tmp_list, setTmpList] = useState<IHostsListObject[] | undefined>()

+ 13 - 32
src/renderer/components/TopBar/ConfigMenu.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Button,
   Button,
   Menu,
   Menu,
@@ -18,6 +17,8 @@ import ImportFromUrl from '@renderer/components/TopBar/ImportFromUrl'
 import { actions, agent } from '@renderer/core/agent'
 import { actions, agent } from '@renderer/core/agent'
 import { feedback_url, homepage_url } from '@root/common/constants'
 import { feedback_url, homepage_url } from '@root/common/constants'
 import events from '@root/common/events'
 import events from '@root/common/events'
+import useHostsData from '@root/renderer/models/useHostsData'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 import {
 import {
   BiCog,
   BiCog,
@@ -33,11 +34,9 @@ import {
 } from 'react-icons/bi'
 } from 'react-icons/bi'
 import styles from './ConfigMenu.less'
 import styles from './ConfigMenu.less'
 
 
-interface Props {}
-
-const ConfigMenu = (props: Props) => {
-  const { lang } = useModel('useI18n')
-  const { loadHostsData, setCurrentHosts } = useModel('useHostsData')
+const ConfigMenu = () => {
+  const { lang } = useI18n()
+  const { loadHostsData, setCurrentHosts } = useHostsData()
   const [show_import_from_url, setShowImportFromUrl] = useState(false)
   const [show_import_from_url, setShowImportFromUrl] = useState(false)
   const toast = useToast()
   const toast = useToast()
 
 
@@ -50,13 +49,10 @@ const ConfigMenu = (props: Props) => {
         <MenuList
         <MenuList
           borderColor="var(--swh-border-color-0)"
           borderColor="var(--swh-border-color-0)"
           className={styles.menu_list}
           className={styles.menu_list}
-          maxH={"calc(100vh - 80px)"}
-          overflowY={"scroll"}
+          maxH={'calc(100vh - 80px)'}
+          overflowY={'scroll'}
         >
         >
-          <MenuItem
-            icon={<BiInfoCircle />}
-            onClick={() => agent.broadcast(events.show_about)}
-          >
+          <MenuItem icon={<BiInfoCircle />} onClick={() => agent.broadcast(events.show_about)}>
             {lang.about}
             {lang.about}
           </MenuItem>
           </MenuItem>
 
 
@@ -85,16 +81,10 @@ const ConfigMenu = (props: Props) => {
           >
           >
             {lang.check_update}
             {lang.check_update}
           </MenuItem>
           </MenuItem>
-          <MenuItem
-            icon={<BiMessageDetail />}
-            onClick={() => actions.openUrl(feedback_url)}
-          >
+          <MenuItem icon={<BiMessageDetail />} onClick={() => actions.openUrl(feedback_url)}>
             {lang.feedback}
             {lang.feedback}
           </MenuItem>
           </MenuItem>
-          <MenuItem
-            icon={<BiHomeCircle />}
-            onClick={() => actions.openUrl(homepage_url)}
-          >
+          <MenuItem icon={<BiHomeCircle />} onClick={() => actions.openUrl(homepage_url)}>
             {lang.homepage}
             {lang.homepage}
           </MenuItem>
           </MenuItem>
 
 
@@ -164,16 +154,10 @@ const ConfigMenu = (props: Props) => {
 
 
           <MenuDivider />
           <MenuDivider />
 
 
-          <MenuItem
-            icon={<BiSliderAlt />}
-            onClick={() => agent.broadcast(events.show_preferences)}
-          >
+          <MenuItem icon={<BiSliderAlt />} onClick={() => agent.broadcast(events.show_preferences)}>
             {lang.preferences}
             {lang.preferences}
           </MenuItem>
           </MenuItem>
-          <MenuItem
-            icon={<BiWrench />}
-            onClick={() => actions.cmdToggleDevTools()}
-          >
+          <MenuItem icon={<BiWrench />} onClick={() => actions.cmdToggleDevTools()}>
             {lang.toggle_developer_tools}
             {lang.toggle_developer_tools}
           </MenuItem>
           </MenuItem>
 
 
@@ -184,10 +168,7 @@ const ConfigMenu = (props: Props) => {
           </MenuItem>
           </MenuItem>
         </MenuList>
         </MenuList>
       </Menu>
       </Menu>
-      <ImportFromUrl
-        is_show={show_import_from_url}
-        setIsShow={setShowImportFromUrl}
-      />
+      <ImportFromUrl is_show={show_import_from_url} setIsShow={setShowImportFromUrl} />
     </>
     </>
   )
   )
 }
 }

+ 4 - 3
src/renderer/components/TopBar/ImportFromUrl.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Button,
   Button,
   Input,
   Input,
@@ -18,6 +17,8 @@ import {
   useToast,
   useToast,
 } from '@chakra-ui/react'
 } from '@chakra-ui/react'
 import { actions } from '@renderer/core/agent'
 import { actions } from '@renderer/core/agent'
+import useHostsData from '@root/renderer/models/useHostsData'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useRef, useState } from 'react'
 import React, { useRef, useState } from 'react'
 import styles from './ImportFromUrl.less'
 import styles from './ImportFromUrl.less'
 
 
@@ -28,8 +29,8 @@ interface Props {
 
 
 const ImportFromUrl = (props: Props) => {
 const ImportFromUrl = (props: Props) => {
   const { is_show, setIsShow } = props
   const { is_show, setIsShow } = props
-  const { lang } = useModel('useI18n')
-  const { loadHostsData, setCurrentHosts } = useModel('useHostsData')
+  const { lang } = useI18n()
+  const { loadHostsData, setCurrentHosts } = useHostsData()
   const [url, setUrl] = useState('')
   const [url, setUrl] = useState('')
   const ipt_ref = React.useRef<HTMLInputElement>(null)
   const ipt_ref = React.useRef<HTMLInputElement>(null)
   const toast = useToast()
   const toast = useToast()

+ 11 - 15
src/renderer/components/TopBar/index.tsx

@@ -4,7 +4,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import { Box, Flex, HStack, IconButton } from '@chakra-ui/react'
 import { Box, Flex, HStack, IconButton } from '@chakra-ui/react'
 import ItemIcon from '@renderer/components/ItemIcon'
 import ItemIcon from '@renderer/components/ItemIcon'
 import SwitchButton from '@renderer/components/SwitchButton'
 import SwitchButton from '@renderer/components/SwitchButton'
@@ -12,6 +11,8 @@ import ConfigMenu from '@renderer/components/TopBar/ConfigMenu'
 import { actions, agent } from '@renderer/core/agent'
 import { actions, agent } from '@renderer/core/agent'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import events from '@root/common/events'
 import events from '@root/common/events'
+import useHostsData from '@root/renderer/models/useHostsData'
+import useI18n from '@root/renderer/models/useI18n'
 import React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
 import { BiHistory, BiPlus, BiSidebar, BiX } from 'react-icons/bi'
 import { BiHistory, BiPlus, BiSidebar, BiX } from 'react-icons/bi'
 import styles from './index.less'
 import styles from './index.less'
@@ -23,15 +24,16 @@ interface IProps {
 
 
 export default (props: IProps) => {
 export default (props: IProps) => {
   const { show_left_panel, use_system_window_frame } = props
   const { show_left_panel, use_system_window_frame } = props
-  const { lang } = useModel('useI18n')
-  const { isHostsInTrashcan, current_hosts, isReadOnly } =
-    useModel('useHostsData')
+  const { lang } = useI18n()
+  const { isHostsInTrashcan, current_hosts, isReadOnly } = useHostsData()
   const [is_on, setIsOn] = useState(!!current_hosts?.on)
   const [is_on, setIsOn] = useState(!!current_hosts?.on)
 
 
   const show_toggle_switch =
   const show_toggle_switch =
     !show_left_panel && current_hosts && !isHostsInTrashcan(current_hosts.id)
     !show_left_panel && current_hosts && !isHostsInTrashcan(current_hosts.id)
   const show_history = !current_hosts
   const show_history = !current_hosts
-  const show_close_button = agent.platform === 'linux' && !use_system_window_frame || agent.platform !== 'darwin' && agent.platform !== 'linux'
+  const show_close_button =
+    (agent.platform === 'linux' && !use_system_window_frame) ||
+    (agent.platform !== 'darwin' && agent.platform !== 'linux')
 
 
   useEffect(() => {
   useEffect(() => {
     setIsOn(!!current_hosts?.on)
     setIsOn(!!current_hosts?.on)
@@ -54,7 +56,7 @@ export default (props: IProps) => {
           aria-label="Toggle sidebar"
           aria-label="Toggle sidebar"
           icon={<BiSidebar />}
           icon={<BiSidebar />}
           onClick={() => {
           onClick={() => {
-            agent.broadcast(events.toggle_left_pannel, !show_left_panel)
+            agent.broadcast(events.toggle_left_panel, !show_left_panel)
           }}
           }}
           variant="ghost"
           variant="ghost"
           mr={1}
           mr={1}
@@ -72,14 +74,9 @@ export default (props: IProps) => {
           {current_hosts ? (
           {current_hosts ? (
             <>
             <>
               <span className={styles.hosts_icon}>
               <span className={styles.hosts_icon}>
-                <ItemIcon
-                  type={current_hosts.type}
-                  is_collapsed={!current_hosts.folder_open}
-                />
-              </span>
-              <span className={styles.hosts_title}>
-                {current_hosts.title || lang.untitled}
+                <ItemIcon type={current_hosts.type} is_collapsed={!current_hosts.folder_open} />
               </span>
               </span>
+              <span className={styles.hosts_title}>{current_hosts.title || lang.untitled}</span>
             </>
             </>
           ) : (
           ) : (
             <>
             <>
@@ -102,8 +99,7 @@ export default (props: IProps) => {
             <SwitchButton
             <SwitchButton
               on={is_on}
               on={is_on}
               onChange={(on) => {
               onChange={(on) => {
-                current_hosts &&
-                  agent.broadcast(events.toggle_item, current_hosts.id, on)
+                current_hosts && agent.broadcast(events.toggle_item, current_hosts.id, on)
               }}
               }}
             />
             />
           </Box>
           </Box>

+ 17 - 21
src/renderer/components/Transfer.tsx

@@ -4,12 +4,12 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
-import { IoArrowForward, IoArrowBack } from 'react-icons/io5'
+import { IoArrowBack, IoArrowForward } from 'react-icons/io5'
 import { Box, Center, Grid, IconButton, VStack } from '@chakra-ui/react'
 import { Box, Center, Grid, IconButton, VStack } from '@chakra-ui/react'
 import React, { useState } from 'react'
 import React, { useState } from 'react'
 import clsx from 'clsx'
 import clsx from 'clsx'
 import styles from './Transfer.less'
 import styles from './Transfer.less'
+import useI18n from '../models/useI18n'
 
 
 type IdType = string
 type IdType = string
 
 
@@ -34,19 +34,17 @@ interface Props {
 
 
 const Transfer = (props: Props) => {
 const Transfer = (props: Props) => {
   const { dataSource, targetKeys, render, onChange } = props
   const { dataSource, targetKeys, render, onChange } = props
-  const { lang } = useModel('useI18n')
+  const { lang } = useI18n()
   const [right_keys, setRightKeys] = useState<IdType[]>(targetKeys)
   const [right_keys, setRightKeys] = useState<IdType[]>(targetKeys)
-  const [left_selectd_keys, setLeftSelectedKeys] = useState<IdType[]>([])
-  const [right_selectd_keys, setRightSelectedKeys] = useState<IdType[]>([])
+  const [left_selected_keys, setLeftSelectedKeys] = useState<IdType[]>([])
+  const [right_selected_keys, setRightSelectedKeys] = useState<IdType[]>([])
 
 
   const List = (list_props: IListProps) => {
   const List = (list_props: IListProps) => {
     const { data, selected_keys, setSelectedKeys } = list_props
     const { data, selected_keys, setSelectedKeys } = list_props
 
 
     const toggleSelect = (id: IdType) => {
     const toggleSelect = (id: IdType) => {
       setSelectedKeys(
       setSelectedKeys(
-        selected_keys.includes(id)
-          ? selected_keys.filter((i) => i != id)
-          : [...selected_keys, id],
+        selected_keys.includes(id) ? selected_keys.filter((i) => i != id) : [...selected_keys, id],
       )
       )
     }
     }
 
 
@@ -73,14 +71,14 @@ const Transfer = (props: Props) => {
   }
   }
 
 
   const moveLeftToRight = () => {
   const moveLeftToRight = () => {
-    let result = [...right_keys, ...left_selectd_keys]
+    let result = [...right_keys, ...left_selected_keys]
     setRightKeys(result)
     setRightKeys(result)
     setLeftSelectedKeys([])
     setLeftSelectedKeys([])
     onChange && onChange(result)
     onChange && onChange(result)
   }
   }
 
 
   const moveRightToLeft = () => {
   const moveRightToLeft = () => {
-    let result = right_keys.filter((i) => !right_selectd_keys.includes(i))
+    let result = right_keys.filter((i) => !right_selected_keys.includes(i))
     setRightKeys(result)
     setRightKeys(result)
     setRightSelectedKeys([])
     setRightSelectedKeys([])
     onChange && onChange(result)
     onChange && onChange(result)
@@ -94,15 +92,15 @@ const Transfer = (props: Props) => {
             {lang.all}{' '}
             {lang.all}{' '}
             <span>
             <span>
               (
               (
-              {left_selectd_keys.length === 0
+              {left_selected_keys.length === 0
                 ? dataSource.length
                 ? dataSource.length
-                : `${left_selectd_keys.length}/${dataSource.length}`}
+                : `${left_selected_keys.length}/${dataSource.length}`}
               )
               )
             </span>
             </span>
           </Box>
           </Box>
           <List
           <List
             data={dataSource.filter((i) => !right_keys.includes(i.id))}
             data={dataSource.filter((i) => !right_keys.includes(i.id))}
-            selected_keys={left_selectd_keys}
+            selected_keys={left_selected_keys}
             setSelectedKeys={setLeftSelectedKeys}
             setSelectedKeys={setLeftSelectedKeys}
           />
           />
         </Box>
         </Box>
@@ -113,7 +111,7 @@ const Transfer = (props: Props) => {
               variant="outline"
               variant="outline"
               aria-label="Move to right"
               aria-label="Move to right"
               icon={<IoArrowForward />}
               icon={<IoArrowForward />}
-              isDisabled={left_selectd_keys.length === 0}
+              isDisabled={left_selected_keys.length === 0}
               onClick={moveLeftToRight}
               onClick={moveLeftToRight}
             />
             />
             <IconButton
             <IconButton
@@ -121,7 +119,7 @@ const Transfer = (props: Props) => {
               variant="outline"
               variant="outline"
               aria-label="Move to left"
               aria-label="Move to left"
               icon={<IoArrowBack />}
               icon={<IoArrowBack />}
-              isDisabled={right_selectd_keys.length === 0}
+              isDisabled={right_selected_keys.length === 0}
               onClick={moveRightToLeft}
               onClick={moveRightToLeft}
             />
             />
           </VStack>
           </VStack>
@@ -131,19 +129,17 @@ const Transfer = (props: Props) => {
             {lang.selected}{' '}
             {lang.selected}{' '}
             <span>
             <span>
               (
               (
-              {right_selectd_keys.length === 0
+              {right_selected_keys.length === 0
                 ? right_keys.length
                 ? right_keys.length
-                : `${right_selectd_keys.length}/${right_keys.length}`}
+                : `${right_selected_keys.length}/${right_keys.length}`}
               )
               )
             </span>
             </span>
           </Box>
           </Box>
           <List
           <List
             data={
             data={
-              right_keys.map((id) =>
-                dataSource.find((i) => i.id === id),
-              ) as ITransferSourceObject[]
+              right_keys.map((id) => dataSource.find((i) => i.id === id)) as ITransferSourceObject[]
             }
             }
-            selected_keys={right_selectd_keys}
+            selected_keys={right_selected_keys}
             setSelectedKeys={setRightSelectedKeys}
             setSelectedKeys={setRightSelectedKeys}
           />
           />
         </Box>
         </Box>

+ 3 - 6
src/renderer/models/useConfigs.ts

@@ -6,10 +6,11 @@
 
 
 import { actions } from '@renderer/core/agent'
 import { actions } from '@renderer/core/agent'
 import { ConfigsType } from '@root/common/default_configs'
 import { ConfigsType } from '@root/common/default_configs'
-import { useEffect, useState } from 'react'
+import { useAtom } from 'jotai'
+import { configs_atom } from '@renderer/stores/configs'
 
 
 export default function useConfigs() {
 export default function useConfigs() {
-  const [configs, setConfigs] = useState<ConfigsType | null>(null)
+  const [configs, setConfigs] = useAtom(configs_atom)
 
 
   const loadConfigs = async () => {
   const loadConfigs = async () => {
     setConfigs(await actions.configAll())
     setConfigs(await actions.configAll())
@@ -23,10 +24,6 @@ export default function useConfigs() {
     await actions.configUpdate(new_configs)
     await actions.configUpdate(new_configs)
   }
   }
 
 
-  useEffect(() => {
-    loadConfigs()
-  }, [])
-
   return {
   return {
     configs,
     configs,
     loadConfigs,
     loadConfigs,

+ 4 - 6
src/renderer/models/useHostsData.ts

@@ -8,14 +8,12 @@ import { actions } from '@renderer/core/agent'
 import { IHostsBasicData, IHostsListObject, VersionType } from '@root/common/data'
 import { IHostsBasicData, IHostsListObject, VersionType } from '@root/common/data'
 import version from '@root/version.json'
 import version from '@root/version.json'
 import { useState } from 'react'
 import { useState } from 'react'
+import { useAtom } from 'jotai'
+import { current_hosts_atom, hosts_data_atom } from '@renderer/stores/hosts_data'
 
 
 export default function useHostsData() {
 export default function useHostsData() {
-  const [hosts_data, setHostsData] = useState<IHostsBasicData>({
-    list: [],
-    trashcan: [],
-    version: version as VersionType,
-  })
-  const [current_hosts, setCurrentHosts] = useState<IHostsListObject | null>(null)
+  const [hosts_data, setHostsData] = useAtom(hosts_data_atom)
+  const [current_hosts, setCurrentHosts] = useAtom(current_hosts_atom)
 
 
   const loadHostsData = async () => {
   const loadHostsData = async () => {
     setHostsData(await actions.getBasicData())
     setHostsData(await actions.getBasicData())

+ 7 - 6
src/renderer/models/useI18n.ts

@@ -4,18 +4,19 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { I18N, LocaleName } from '@root/common/i18n'
-import { useState } from 'react'
+import { LocaleName } from '@root/common/i18n'
+import { useAtom } from 'jotai'
+import { i18n_atom, lang_atom, locale_atom } from '@renderer/stores/i18n'
 
 
 export default function useI18n() {
 export default function useI18n() {
-  const [locale, setLocale] = useState<LocaleName>('en')
-
-  const i18n = new I18N(locale)
+  const [locale, setLocale] = useAtom(locale_atom)
+  const [i18n] = useAtom(i18n_atom)
+  const [lang] = useAtom(lang_atom)
 
 
   return {
   return {
     locale,
     locale,
     setLocale: (locale?: LocaleName) => setLocale(locale || 'en'),
     setLocale: (locale?: LocaleName) => setLocale(locale || 'en'),
     i18n,
     i18n,
-    lang: i18n.lang,
+    lang,
   }
   }
 }
 }

+ 17 - 42
src/renderer/pages/find.tsx

@@ -3,7 +3,6 @@
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
-import { useModel } from '@@/plugin-model/useModel'
 import {
 import {
   Box,
   Box,
   Button,
   Button,
@@ -25,11 +24,7 @@ import { PopupMenu } from '@renderer/core/PopupMenu'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import useOnBroadcast from '@renderer/core/useOnBroadcast'
 import { HostsType } from '@root/common/data'
 import { HostsType } from '@root/common/data'
 import events from '@root/common/events'
 import events from '@root/common/events'
-import {
-  IFindItem,
-  IFindPosition,
-  IFindShowSourceParam,
-} from '@root/common/types'
+import { IFindItem, IFindPosition, IFindShowSourceParam } from '@root/common/types'
 import { useDebounce, useDebounceFn } from 'ahooks'
 import { useDebounce, useDebounceFn } from 'ahooks'
 import clsx from 'clsx'
 import clsx from 'clsx'
 import lodash from 'lodash'
 import lodash from 'lodash'
@@ -42,10 +37,10 @@ import {
 } from 'react-icons/io5'
 } from 'react-icons/io5'
 import { FixedSizeList as List, ListChildComponentProps } from 'react-window'
 import { FixedSizeList as List, ListChildComponentProps } from 'react-window'
 import scrollIntoView from 'smooth-scroll-into-view-if-needed'
 import scrollIntoView from 'smooth-scroll-into-view-if-needed'
+import useConfigs from '../models/useConfigs'
+import useI18n from '../models/useI18n'
 import styles from './find.less'
 import styles from './find.less'
 
 
-interface Props {}
-
 interface IFindPositionShow extends IFindPosition {
 interface IFindPositionShow extends IFindPosition {
   item_id: string
   item_id: string
   item_title: string
   item_title: string
@@ -55,9 +50,9 @@ interface IFindPositionShow extends IFindPosition {
   is_readonly?: boolean
   is_readonly?: boolean
 }
 }
 
 
-const find = (props: Props) => {
-  const { lang, i18n, setLocale } = useModel('useI18n')
-  const { configs, loadConfigs } = useModel('useConfigs')
+const find = () => {
+  const { lang, i18n, setLocale } = useI18n()
+  const { configs, loadConfigs } = useConfigs()
   const { colorMode, setColorMode } = useColorMode()
   const { colorMode, setColorMode } = useColorMode()
   const [keyword, setKeyword] = useState('')
   const [keyword, setKeyword] = useState('')
   const [replace_to, setReplaceTo] = useState('')
   const [replace_to, setReplaceTo] = useState('')
@@ -231,9 +226,7 @@ const find = (props: Props) => {
     for (let item of find_result) {
     for (let item of find_result) {
       let { item_id, item_type, splitters } = item
       let { item_id, item_type, splitters } = item
       if (item_type !== 'local' || splitters.length === 0) continue
       if (item_type !== 'local' || splitters.length === 0) continue
-      const content = splitters
-        .map((sp) => `${sp.before}${replace_to}${sp.after}`)
-        .join('')
+      const content = splitters.map((sp) => `${sp.before}${replace_to}${sp.after}`).join('')
       await actions.setHostsContent(item_id, content)
       await actions.setHostsContent(item_id, content)
       agent.broadcast(events.hosts_refreshed_by_id, item_id)
       agent.broadcast(events.hosts_refreshed_by_id, item_id)
     }
     }
@@ -256,11 +249,7 @@ const find = (props: Props) => {
     const is_selected = current_result_idx === row_data.index
     const is_selected = current_result_idx === row_data.index
 
 
     useEffect(() => {
     useEffect(() => {
-      if (
-        el.current &&
-        is_selected &&
-        current_result_idx !== last_scroll_result_idx
-      ) {
+      if (el.current && is_selected && current_result_idx !== last_scroll_result_idx) {
         setlastScrollResultIdx(current_result_idx)
         setlastScrollResultIdx(current_result_idx)
         scrollIntoView(el.current, {
         scrollIntoView(el.current, {
           behavior: 'smooth',
           behavior: 'smooth',
@@ -288,9 +277,7 @@ const find = (props: Props) => {
         title={lang.to_show_source}
         title={lang.to_show_source}
       >
       >
         <div className={styles.result_content}>
         <div className={styles.result_content}>
-          {data.is_readonly ? (
-            <span className={styles.read_only}>{lang.read_only}</span>
-          ) : null}
+          {data.is_readonly ? <span className={styles.read_only}>{lang.read_only}</span> : null}
           <span>{data.before}</span>
           <span>{data.before}</span>
           <span className={styles.highlight}>{data.match}</span>
           <span className={styles.highlight}>{data.match}</span>
           <span>{data.after}</span>
           <span>{data.after}</span>
@@ -400,16 +387,10 @@ const find = (props: Props) => {
           spacing={4}
           spacing={4}
           // justifyContent="flex-start"
           // justifyContent="flex-start"
         >
         >
-          <Checkbox
-            checked={is_regexp}
-            onChange={(e) => setIsRegExp(e.target.checked)}
-          >
+          <Checkbox checked={is_regexp} onChange={(e) => setIsRegExp(e.target.checked)}>
             {lang.regexp}
             {lang.regexp}
           </Checkbox>
           </Checkbox>
-          <Checkbox
-            checked={is_ignore_case}
-            onChange={(e) => setIsIgnoreCase(e.target.checked)}
-          >
+          <Checkbox checked={is_ignore_case} onChange={(e) => setIsIgnoreCase(e.target.checked)}>
             {lang.ignore_case}
             {lang.ignore_case}
           </Checkbox>
           </Checkbox>
         </HStack>
         </HStack>
@@ -430,9 +411,7 @@ const find = (props: Props) => {
         >
         >
           <List
           <List
             width={'100%'}
             width={'100%'}
-            height={
-              ref_result_box.current ? ref_result_box.current.clientHeight : 0
-            }
+            height={ref_result_box.current ? ref_result_box.current.clientHeight : 0}
             itemCount={find_positions.length}
             itemCount={find_positions.length}
             itemSize={28}
             itemSize={28}
           >
           >
@@ -451,10 +430,9 @@ const find = (props: Props) => {
             <Spinner />
             <Spinner />
           ) : (
           ) : (
             <span>
             <span>
-              {i18n.trans(
-                find_positions.length > 1 ? 'items_found' : 'item_found',
-                [find_positions.length.toLocaleString()],
-              )}
+              {i18n.trans(find_positions.length > 1 ? 'items_found' : 'item_found', [
+                find_positions.length.toLocaleString(),
+              ])}
             </span>
             </span>
           )}
           )}
           <Spacer />
           <Spacer />
@@ -470,9 +448,7 @@ const find = (props: Props) => {
             size="sm"
             size="sm"
             variant="solid"
             variant="solid"
             colorScheme="blue"
             colorScheme="blue"
-            isDisabled={
-              is_searching || find_positions.length === 0 || !can_replace
-            }
+            isDisabled={is_searching || find_positions.length === 0 || !can_replace}
             onClick={replaceOne}
             onClick={replaceOne}
           >
           >
             {lang.replace}
             {lang.replace}
@@ -499,8 +475,7 @@ const find = (props: Props) => {
               icon={<IoArrowForwardOutline />}
               icon={<IoArrowForwardOutline />}
               onClick={() => {
               onClick={() => {
                 let idx = current_result_idx + 1
                 let idx = current_result_idx + 1
-                if (idx > find_positions.length - 1)
-                  idx = find_positions.length - 1
+                if (idx > find_positions.length - 1) idx = find_positions.length - 1
                 setCurrentResultIdx(idx)
                 setCurrentResultIdx(idx)
               }}
               }}
               isDisabled={current_result_idx >= find_positions.length - 1}
               isDisabled={current_result_idx >= find_positions.length - 1}

+ 8 - 8
src/renderer/pages/index.tsx

@@ -1,5 +1,4 @@
-import { useModel } from '@@/plugin-model/useModel'
-import { useToast, Button } from '@chakra-ui/react'
+import { Button, useToast } from '@chakra-ui/react'
 import About from '@renderer/components/About'
 import About from '@renderer/components/About'
 import EditHostsInfo from '@renderer/components/EditHostsInfo'
 import EditHostsInfo from '@renderer/components/EditHostsInfo'
 import History from '@renderer/components/History'
 import History from '@renderer/components/History'
@@ -17,12 +16,15 @@ import React, { useEffect, useState } from 'react'
 import TopBar from '../components/TopBar'
 import TopBar from '../components/TopBar'
 import styles from './index.less'
 import styles from './index.less'
 import SetWriteMode from '@renderer/components/SetWriteMode'
 import SetWriteMode from '@renderer/components/SetWriteMode'
+import useI18n from '../models/useI18n'
+import useConfigs from '@renderer/models/useConfigs'
+import useHostsData from '../models/useHostsData'
 
 
 export default () => {
 export default () => {
   const [loading, setLoading] = useState(true)
   const [loading, setLoading] = useState(true)
-  const { i18n, lang, setLocale } = useModel('useI18n')
-  const { loadHostsData } = useModel('useHostsData')
-  const { configs } = useModel('useConfigs')
+  const { i18n, lang, setLocale } = useI18n()
+  const { loadHostsData } = useHostsData()
+  const { configs } = useConfigs()
   const [left_width, setLeftWidth] = useState(0)
   const [left_width, setLeftWidth] = useState(0)
   const [left_show, setLeftShow] = useState(true)
   const [left_show, setLeftShow] = useState(true)
   const [use_system_window_frame, setSystemFrame] = useState(false)
   const [use_system_window_frame, setSystemFrame] = useState(false)
@@ -73,9 +75,7 @@ export default () => {
     onConfigsUpdate().catch((e) => console.error(e))
     onConfigsUpdate().catch((e) => console.error(e))
   }, [configs])
   }, [configs])
 
 
-  useOnBroadcast(events.toggle_left_pannel, (show: boolean) =>
-    setLeftShow(show),
-  )
+  useOnBroadcast(events.toggle_left_panel, (show: boolean) => setLeftShow(show))
 
 
   useOnBroadcast(
   useOnBroadcast(
     events.new_version,
     events.new_version,

+ 7 - 8
src/renderer/pages/tray.tsx

@@ -1,4 +1,3 @@
-import { useModel } from '@@/plugin-model/useModel'
 import { useColorMode } from '@chakra-ui/react'
 import { useColorMode } from '@chakra-ui/react'
 import List from '@renderer/components/List'
 import List from '@renderer/components/List'
 import { agent } from '@renderer/core/agent'
 import { agent } from '@renderer/core/agent'
@@ -7,11 +6,14 @@ import events from '@root/common/events'
 import React, { useEffect } from 'react'
 import React, { useEffect } from 'react'
 import { BiArea } from 'react-icons/bi'
 import { BiArea } from 'react-icons/bi'
 import styles from './tray.less'
 import styles from './tray.less'
+import useI18n from '@renderer/models/useI18n'
+import useConfigs from '@renderer/models/useConfigs'
+import useHostsData from '@renderer/models/useHostsData'
 
 
 export default () => {
 export default () => {
-  const { loadHostsData } = useModel('useHostsData')
-  const { setLocale } = useModel('useI18n')
-  const { configs, loadConfigs } = useModel('useConfigs')
+  const { loadHostsData } = useHostsData()
+  const { setLocale } = useI18n()
+  const { configs, loadConfigs } = useConfigs()
   const { colorMode, setColorMode } = useColorMode()
   const { colorMode, setColorMode } = useColorMode()
 
 
   const update = () => {
   const update = () => {
@@ -26,10 +28,7 @@ export default () => {
 
 
     let cls = document.body.className
     let cls = document.body.className
     document.body.className = cls.replace(/\btheme-\w+/gi, '')
     document.body.className = cls.replace(/\btheme-\w+/gi, '')
-    document.body.classList.add(
-      `platform-${agent.platform}`,
-      `theme-${configs.theme}`,
-    )
+    document.body.classList.add(`platform-${agent.platform}`, `theme-${configs.theme}`)
   }
   }
 
 
   useEffect(update, [configs])
   useEffect(update, [configs])

+ 14 - 0
src/renderer/stores/configs.ts

@@ -0,0 +1,14 @@
+/**
+ * configs.ts
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { ConfigsType } from '@root/common/default_configs'
+import { actions } from '@renderer/core/agent'
+import { atom } from 'jotai'
+
+export const configs_atom = atom<ConfigsType | null>(null)
+configs_atom.onMount = (setAtom) => {
+  actions.configAll().then(setAtom)
+}

+ 18 - 0
src/renderer/stores/hosts_data.ts

@@ -0,0 +1,18 @@
+/**
+ * hosts_data.ts
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { actions } from '@renderer/core/agent'
+import { IHostsBasicData, IHostsListObject, VersionType } from '@root/common/data'
+import { atom } from 'jotai'
+import version from '@root/version.json'
+
+export const hosts_data_atom = atom<IHostsBasicData>({
+  list: [],
+  trashcan: [],
+  version: version as VersionType,
+})
+
+export const current_hosts_atom = atom<IHostsListObject | null>(null)

+ 15 - 0
src/renderer/stores/i18n.ts

@@ -0,0 +1,15 @@
+/**
+ * i18n.ts
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+import { I18N, LocaleName } from '@root/common/i18n'
+import { atom } from 'jotai'
+
+let _locale = localStorage.getItem('locale') as LocaleName | undefined
+
+export const locale_atom = atom<LocaleName>(_locale || 'en')
+export const i18n_atom = atom((get) => new I18N(get(locale_atom)))
+export const is_half_width_atom = atom((get) => get(i18n_atom).lang.colon.startsWith(':'))
+export const lang_atom = atom((get) => get(i18n_atom).lang)

+ 1 - 1
src/version.json

@@ -1 +1 @@
-[4, 1, 2, 6086]
+[4, 1, 2, 6088]

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно