浏览代码

Merge branch 'feature/check-server' into develop

oldj 4 年之前
父节点
当前提交
0740fa5ef3

+ 2 - 1
app/package.json

@@ -1,5 +1,6 @@
 {
 {
-  "name": "SwitchHosts",
+  "name": "switchhosts",
+  "productName": "SwitchHosts",
   "version": "4.0.0",
   "version": "4.0.0",
   "description": "Switch hosts quickly!",
   "description": "Switch hosts quickly!",
   "main": "./main.js",
   "main": "./main.js",

+ 1 - 1
src/main/actions/checkUpdate.ts

@@ -14,7 +14,7 @@ export default async (): Promise<boolean | null> => {
   // Check the latest version, also used for anonymous statistics of DAU,
   // Check the latest version, also used for anonymous statistics of DAU,
   // no personal information will be sent.
   // no personal information will be sent.
 
 
-  let r = await GET(`${server_url}/api/check/`)
+  let r = await GET(`${server_url}/api/check/`, { sid: global.session_id })
   if (r.status !== 200 || !r.data?.success) {
   if (r.status !== 200 || !r.data?.success) {
     return null
     return null
   }
   }

+ 9 - 0
src/main/actions/closeMainWindow.ts

@@ -0,0 +1,9 @@
+/**
+ * @author: oldj
+ * @homepage: https://oldj.net
+ */
+
+export default async () => {
+  let win = global.main_win
+  win && win.isClosable() && win.close()
+}

+ 1 - 0
src/main/actions/cmd/getHistoryList.ts

@@ -3,6 +3,7 @@
  * @author: oldj
  * @author: oldj
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
+
 import { cfgdb } from '@main/data'
 import { cfgdb } from '@main/data'
 import { ICommandRunResult } from '@root/common/data'
 import { ICommandRunResult } from '@root/common/data'
 
 

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

@@ -42,6 +42,7 @@ export { default as openUrl } from './openUrl'
 export { default as showItemInFolder } from './showItemInFolder'
 export { default as showItemInFolder } from './showItemInFolder'
 export { default as updateTrayTitle } from './updateTrayTitle'
 export { default as updateTrayTitle } from './updateTrayTitle'
 export { default as checkUpdate } from './checkUpdate'
 export { default as checkUpdate } from './checkUpdate'
+export { default as closeMainWindow } from './closeMainWindow'
 export { default as quit } from './quit'
 export { default as quit } from './quit'
 
 
 export { default as migrateCheck } from './migrate/checkIfMigration'
 export { default as migrateCheck } from './migrate/checkIfMigration'

+ 11 - 7
src/main/libs/cron.ts

@@ -48,20 +48,24 @@ const checkRefresh = async () => {
   broadcast('reload_list')
   broadcast('reload_list')
 }
 }
 
 
-const check = async () => {
-  checkRefresh()
-    .catch(e => console.error(e))
-
+const checkServer = async () => {
   let ts = (new Date()).getTime()
   let ts = (new Date()).getTime()
   if (!ts_last_server_check || (ts - ts_last_server_check) > 3600 * 1000) {
   if (!ts_last_server_check || (ts - ts_last_server_check) > 3600 * 1000) {
-    checkUpdate()
-      .catch(e => console.error(e))
+    await checkUpdate()
     ts_last_server_check = ts
     ts_last_server_check = ts
   }
   }
 }
 }
 
 
+const check = async () => {
+  checkRefresh()
+    .catch(e => console.error(e))
+
+  checkServer()
+    .catch(e => console.error(e))
+}
+
 export const start = () => {
 export const start = () => {
-  setTimeout(checkUpdate, 5000)
+  setTimeout(checkServer, 5000)
 
 
   clearInterval(t)
   clearInterval(t)
   t = setInterval(check, 60 * 1000)
   t = setInterval(check, 60 * 1000)

+ 4 - 4
src/main/libs/getIndex.ts

@@ -1,13 +1,13 @@
-import isDev from '@main/libs/isDev'
-import path from 'path'
-import * as url from 'url'
-
 /**
 /**
  * getIndex
  * getIndex
  * @author: oldj
  * @author: oldj
  * @homepage: https://oldj.net
  * @homepage: https://oldj.net
  */
  */
 
 
+import isDev from '@main/libs/isDev'
+import path from 'path'
+import * as url from 'url'
+
 export default (): string => {
 export default (): string => {
   let index: string
   let index: string
   if (isDev()) {
   if (isDev()) {

+ 4 - 4
src/main/libs/request.ts

@@ -9,10 +9,6 @@ import axios, { AxiosRequestConfig } from 'axios'
 import querystring from 'querystring'
 import querystring from 'querystring'
 import version from '@root/version.json'
 import version from '@root/version.json'
 
 
-const default_headers = {
-  'user-agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 SwitchHosts/${version.join('.')}`,
-}
-
 interface IParams {
 interface IParams {
   [key: string]: string | string[] | number;
   [key: string]: string | string[] | number;
 }
 }
@@ -31,6 +27,10 @@ export const GET = async (url: string, params: IParams | null = null, options: I
     url += (url.includes('?') ? '&' : '?') + s
     url += (url.includes('?') ? '&' : '?') + s
   }
   }
 
 
+  const default_headers = {
+    'user-agent': `${global.ua} SwitchHosts/${version.join('.')}`,
+  }
+
   let configs: AxiosRequestConfig = {
   let configs: AxiosRequestConfig = {
     timeout: options.timeout || 30000,
     timeout: options.timeout || 30000,
     headers: {
     headers: {

+ 0 - 1
src/main/libs/safePSWD.ts

@@ -4,7 +4,6 @@
  * @blog https://oldj.net
  * @blog https://oldj.net
  */
  */
 
 
-
 export default (pswd: string): string => {
 export default (pswd: string): string => {
   return pswd
   return pswd
     .replace(/\\/g, '\\\\')
     .replace(/\\/g, '\\\\')

+ 9 - 2
src/main/main.ts

@@ -6,12 +6,13 @@ import '@main/data'
 import * as cron from '@main/libs/cron'
 import * as cron from '@main/libs/cron'
 import getIndex from '@main/libs/getIndex'
 import getIndex from '@main/libs/getIndex'
 import isDev from '@main/libs/isDev'
 import isDev from '@main/libs/isDev'
-import '@main/tray'
 import { makeMainMenu } from '@main/libs/menu'
 import { makeMainMenu } from '@main/libs/menu'
+import '@main/tray'
 import version from '@root/version.json'
 import version from '@root/version.json'
 import { app, BrowserWindow } from 'electron'
 import { app, BrowserWindow } from 'electron'
-import * as path from 'path'
 import windowStateKeeper from 'electron-window-state'
 import windowStateKeeper from 'electron-window-state'
+import * as path from 'path'
+import { v4 as uuid4 } from 'uuid'
 
 
 let win: BrowserWindow | null
 let win: BrowserWindow | null
 let is_will_quit: boolean = false
 let is_will_quit: boolean = false
@@ -43,6 +44,11 @@ const createWindow = async () => {
 
 
   main_window_state.manage(win)
   main_window_state.manage(win)
 
 
+  const ses = win.webContents.session
+  // console.log(ses.getUserAgent())
+  global.ua = ses.getUserAgent()
+  global.main_win = win
+
   if (configs.hide_at_launch) {
   if (configs.hide_at_launch) {
     win.hide()
     win.hide()
   }
   }
@@ -108,6 +114,7 @@ const onActive = async () => {
 
 
 app.on('ready', async () => {
 app.on('ready', async () => {
   console.log(`VERSION: ${version.join('.')}`)
   console.log(`VERSION: ${version.join('.')}`)
+  global.session_id = uuid4()
   await createWindow()
   await createWindow()
   cron.start()
   cron.start()
 })
 })

+ 2 - 2
src/main/tray/index.ts

@@ -60,7 +60,7 @@ const makeTray = async () => {
       {
       {
         label: lang._app_name,
         label: lang._app_name,
         toolTip: lang.show_main_window,
         toolTip: lang.show_main_window,
-        click() {
+        click () {
           broadcast('active_main_window')
           broadcast('active_main_window')
         },
         },
       },
       },
@@ -71,7 +71,7 @@ const makeTray = async () => {
       { type: 'separator' },
       { type: 'separator' },
       {
       {
         label: lang.toggle_dock_icon,
         label: lang.toggle_dock_icon,
-        async click() {
+        async click () {
           let hide_dock_icon = await configGet('hide_dock_icon')
           let hide_dock_icon = await configGet('hide_dock_icon')
           hide_dock_icon = !hide_dock_icon
           hide_dock_icon = !hide_dock_icon
           await configSet('hide_dock_icon', hide_dock_icon)
           await configSet('hide_dock_icon', hide_dock_icon)

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

@@ -5,6 +5,7 @@
  */
  */
 
 
 import SwhDb from '@main/utils/db'
 import SwhDb from '@main/utils/db'
+import { BrowserWindow } from 'electron'
 import * as actions from './actions'
 import * as actions from './actions'
 
 
 export type Actions = typeof actions
 export type Actions = typeof actions
@@ -25,6 +26,9 @@ declare global {
       db_dir?: string;
       db_dir?: string;
       swhdb: SwhDb;
       swhdb: SwhDb;
       cfgdb: SwhDb;
       cfgdb: SwhDb;
+      ua: string; // user agent
+      session_id: string; // A random value, refreshed every time the app starts, used to identify different startup sessions.
+      main_win: BrowserWindow;
     }
     }
   }
   }
 }
 }

+ 2 - 14
src/renderer/components/TopBar/ConfigMenu.tsx

@@ -5,23 +5,10 @@
  */
  */
 
 
 import { useModel } from '@@/plugin-model/useModel'
 import { useModel } from '@@/plugin-model/useModel'
+import { Button, Menu, MenuButton, MenuDivider, MenuItem, MenuList, useToast } from '@chakra-ui/react'
 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 { useToast } from '@chakra-ui/react'
 import React from 'react'
 import React from 'react'
-import {
-  Menu,
-  MenuButton,
-  MenuList,
-  MenuItem,
-  MenuItemOption,
-  MenuGroup,
-  MenuOptionGroup,
-  MenuIcon,
-  MenuCommand,
-  MenuDivider,
-  Button, Flex,
-} from '@chakra-ui/react'
 import { BiCog, BiExit, BiHomeCircle, BiInfoCircle, BiMessageDetail, BiRefresh, BiSliderAlt } from 'react-icons/bi'
 import { BiCog, BiExit, BiHomeCircle, BiInfoCircle, BiMessageDetail, BiRefresh, BiSliderAlt } from 'react-icons/bi'
 
 
 interface Props {
 interface Props {
@@ -37,6 +24,7 @@ const ConfigMenu = (props: Props) => {
       <MenuButton
       <MenuButton
         as={Button}
         as={Button}
         variant="ghost"
         variant="ghost"
+        width="35px"
       >
       >
         <BiCog/>
         <BiCog/>
       </MenuButton>
       </MenuButton>

+ 22 - 9
src/renderer/components/TopBar/index.less

@@ -6,34 +6,47 @@
 
 
   background: var(--swh-top-bar-bg);
   background: var(--swh-top-bar-bg);
   border-bottom: 1px solid var(--swh-border-color-0);
   border-bottom: 1px solid var(--swh-border-color-0);
-  display: grid;
-  grid-template-columns: @w 1fr @w;
+  display: flex;
+  width: 100%;
   padding: 0 @p;
   padding: 0 @p;
+  align-items: center;
+  align-content: center;
   -webkit-user-select: none;
   -webkit-user-select: none;
-  -webkit-app-region: drag;
 
 
-  .hosts_title {
+  .title {
     max-width: calc(100vw - (@w + @p) * 2);
     max-width: calc(100vw - (@w + @p) * 2);
     overflow: hidden;
     overflow: hidden;
     white-space: nowrap;
     white-space: nowrap;
     text-overflow: ellipsis;
     text-overflow: ellipsis;
+    margin: 0 auto;
   }
   }
+}
+
+.title_wrapper {
+  width: 100%;
+  height: 100%;
+  display: flex;
+
+  .win-drag;
+}
 
 
+.left, .right {
 }
 }
 
 
 .left {
 .left {
+  left: 10px;
+}
 
 
+.right {
+  right: 10px;
 }
 }
 
 
 :global(.platform-darwin) {
 :global(.platform-darwin) {
-  .left {
-    padding-left: 60px;
+  .root {
+    padding-left: 80px;
   }
   }
 }
 }
 
 
-.right {
-  text-align: right;
-}
 
 
 .read_only {
 .read_only {
   color: var(--swh-font-color-weak);
   color: var(--swh-font-color-weak);

+ 22 - 13
src/renderer/components/TopBar/index.tsx

@@ -5,14 +5,14 @@
  */
  */
 
 
 import { useModel } from '@@/plugin-model/useModel'
 import { useModel } from '@@/plugin-model/useModel'
-import { Box, Center, 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'
 import ConfigMenu from '@renderer/components/TopBar/ConfigMenu'
 import ConfigMenu from '@renderer/components/TopBar/ConfigMenu'
-import { 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 React, { useEffect, useState } from 'react'
 import React, { useEffect, useState } from 'react'
-import { BiHistory, BiPlus, BiSidebar, BiSliderAlt, BiCog } from 'react-icons/bi'
+import { BiHistory, BiPlus, BiSidebar, BiX } from 'react-icons/bi'
 import styles from './index.less'
 import styles from './index.less'
 
 
 interface IProps {
 interface IProps {
@@ -27,6 +27,7 @@ export default (props: IProps) => {
 
 
   const show_toggle_switch = !show_left_panel && current_hosts && !isHostsInTrashcan(current_hosts.id)
   const show_toggle_switch = !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 !== 'darwin'
 
 
   useEffect(() => {
   useEffect(() => {
     setIsOn(!!current_hosts?.on)
     setIsOn(!!current_hosts?.on)
@@ -58,8 +59,8 @@ export default (props: IProps) => {
         />
         />
       </Flex>
       </Flex>
 
 
-      <Center className={styles.hosts_title}>
-        <HStack>
+      <Box className={styles.title_wrapper}>
+        <HStack className={styles.title} k>
           {current_hosts ? (
           {current_hosts ? (
             <>
             <>
                 <span className={styles.hosts_icon}>
                 <span className={styles.hosts_icon}>
@@ -84,9 +85,13 @@ export default (props: IProps) => {
             <span className={styles.read_only}>{lang.read_only}</span>
             <span className={styles.read_only}>{lang.read_only}</span>
           ) : null}
           ) : null}
         </HStack>
         </HStack>
-      </Center>
+      </Box>
 
 
-      <Flex align="center" justifyContent="flex-end">
+      <Flex
+        align="center"
+        justifyContent="flex-end"
+        className={styles.right}
+      >
         {show_toggle_switch ? (
         {show_toggle_switch ? (
           <Box mr={3}>
           <Box mr={3}>
             <SwitchButton on={is_on} onChange={on => {
             <SwitchButton on={is_on} onChange={on => {
@@ -103,13 +108,17 @@ export default (props: IProps) => {
           />
           />
         ) : null}
         ) : null}
 
 
-        {/*<IconButton*/}
-        {/*  aria-label="Toggle preference panel"*/}
-        {/*  icon={<BiSliderAlt/>}*/}
-        {/*  variant="ghost"*/}
-        {/*  onClick={() => agent.broadcast('show_preferences')}*/}
-        {/*/>*/}
         <ConfigMenu/>
         <ConfigMenu/>
+
+        {show_close_button ? (
+          <IconButton
+            aria-label="Close window"
+            fontSize="20px"
+            icon={<BiX/>}
+            variant="ghost"
+            onClick={() => actions.closeMainWindow()}
+          />
+        ) : null}
       </Flex>
       </Flex>
     </div>
     </div>
   )
   )

+ 4 - 0
src/renderer/styles/common.less

@@ -8,3 +8,7 @@ html, body {
   box-sizing: border-box;
   box-sizing: border-box;
   color: var(--swh-font-color);
   color: var(--swh-font-color);
 }
 }
+
+.win-drag {
+  -webkit-app-region: drag;
+}

+ 1 - 1
src/version.json

@@ -1 +1 @@
-[4, 0, 0, 6015]
+[4, 0, 0, 6019]