Skip to content

Commit

Permalink
Initialization constant
Browse files Browse the repository at this point in the history
  • Loading branch information
pompurin404 committed Aug 5, 2024
1 parent 1aad740 commit 8d7ae19
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 46 deletions.
7 changes: 6 additions & 1 deletion src/main/config/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ export async function addProfileItem(item: Partial<IProfileItem>): Promise<void>
export function removeProfileItem(id: string): void {
profileConfig.items = profileConfig.items?.filter((item) => item.id !== id)
if (profileConfig.current === id) {
profileConfig.current = profileConfig.items[0]?.id
if (profileConfig.items.length > 0) {
profileConfig.current = profileConfig.items[0]?.id
} else {
profileConfig.current = undefined
}
}
fs.writeFileSync(profileConfigPath(), yaml.stringify(profileConfig))
fs.rmSync(profilePath(id))
window?.webContents.send('profileConfigUpdated')
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta charset="UTF-8" lang="zh" />
<title>Mihomo Party</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
Expand Down
122 changes: 107 additions & 15 deletions src/renderer/src/components/profiles/profile-item.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,131 @@
import { Button, Card, CardBody, CardFooter, Progress } from '@nextui-org/react'
import {
Button,
Card,
CardBody,
CardFooter,
Dropdown,
DropdownItem,
DropdownMenu,
DropdownTrigger,
Progress
} from '@nextui-org/react'
import { calcPercent, calcTraffic } from '@renderer/utils/calc'
import React from 'react'
import { IoMdRefresh } from 'react-icons/io'
import { IoMdMore, IoMdRefresh } from 'react-icons/io'
import dayjs from 'dayjs'
import React, { Key, useMemo } from 'react'

interface Props {
info: IProfileItem
isCurrent: boolean
removeProfileItem: (id: string) => Promise<void>
mutateProfileConfig: () => void
onClick: () => Promise<void>
}

interface MenuItem {
key: string
label: string
showDivider: boolean
color: 'default' | 'danger'
className: string
}
const ProfileItem: React.FC<Props> = (props) => {
const { info, onClick, isCurrent } = props
const { info, removeProfileItem, mutateProfileConfig, onClick, isCurrent } = props
const extra = info?.extra
const usage = (extra?.upload ?? 0) + (extra?.download ?? 0)
const total = extra?.total ?? 0

const menuItems: MenuItem[] = useMemo(() => {
const list = [
{
key: 'edit',
label: '编辑文件',
showDivider: true,
color: 'default',
className: ''
} as MenuItem,
{
key: 'delete',
label: '删除',
showDivider: false,
color: 'danger',
className: 'text-danger'
} as MenuItem
]
if (info.home) {
list.unshift({
key: 'home',
label: '主页',
showDivider: false,
color: 'default',
className: ''
} as MenuItem)
}
return list
}, [info])

const onMenuAction = (key: Key): void => {
switch (key) {
case 'edit':
break
case 'delete': {
removeProfileItem(info.id)
mutateProfileConfig()
break
}

case 'home': {
open(info.home)
break
}
}
}

return (
<Card fullWidth isPressable onPress={onClick} className={isCurrent ? 'bg-primary' : ''}>
<CardBody>
<CardBody className="pb-1">
<div className="flex justify-between h-[32px]">
<h3 className="select-none text-ellipsis whitespace-nowrap overflow-hidden text-md font-bold leading-[32px]">
{info?.name}
</h3>
<Button isIconOnly size="sm" variant="light" color="default">
<IoMdRefresh color="default" className="text-[24px]" />
</Button>
<div className="flex">
<Button isIconOnly size="sm" variant="light" color="default">
<IoMdRefresh color="default" className="text-[24px]" />
</Button>
<Dropdown>
<DropdownTrigger>
<Button isIconOnly size="sm" variant="light" color="default">
<IoMdMore color="default" className="text-[24px]" />
</Button>
</DropdownTrigger>
<DropdownMenu onAction={onMenuAction}>
{menuItems.map((item) => (
<DropdownItem
showDivider={item.showDivider}
key={item.key}
color={item.color}
className={item.className}
>
{item.label}
</DropdownItem>
))}
</DropdownMenu>
</Dropdown>
</div>
</div>
<div className="mt-2 flex justify-between">
<small>{extra ? `${calcTraffic(usage)}/${calcTraffic(total)}` : undefined}</small>
<small>{dayjs(info.updated).fromNow()}</small>
</div>
</CardBody>
<CardFooter className="pt-1">
<Progress
classNames={{ indicator: 'bg-foreground', label: 'select-none' }}
label={extra ? `${calcTraffic(usage)}/${calcTraffic(total)}` : undefined}
value={calcPercent(extra?.upload, extra?.download, extra?.total)}
className="max-w-md"
/>
<CardFooter className="pt-0">
{extra && (
<Progress
className="w-full"
classNames={{ indicator: 'bg-foreground', label: 'select-none' }}
value={calcPercent(extra?.upload, extra?.download, extra?.total)}
/>
)}
</CardFooter>
</Card>
)
Expand Down
28 changes: 20 additions & 8 deletions src/renderer/src/components/sider/profile-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { useProfileConfig } from '@renderer/hooks/use-profile-config'
import { useLocation, useNavigate } from 'react-router-dom'
import { calcTraffic, calcPercent } from '@renderer/utils/calc'
import { IoMdRefresh } from 'react-icons/io'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'
import dayjs from 'dayjs'

dayjs.extend(relativeTime)
dayjs.locale('zh-cn')

const ProfileCard: React.FC = () => {
const navigate = useNavigate()
Expand All @@ -16,6 +22,7 @@ const ProfileCard: React.FC = () => {
type: 'local',
name: '空白订阅'
}

const extra = info?.extra
const usage = (extra?.upload ?? 0) + (extra?.download ?? 0)
const total = extra?.total ?? 0
Expand All @@ -27,7 +34,7 @@ const ProfileCard: React.FC = () => {
isPressable
onPress={() => navigate('/profiles')}
>
<CardBody>
<CardBody className="pb-1">
<div className="flex justify-between h-[32px]">
<h3 className="select-none text-ellipsis whitespace-nowrap overflow-hidden text-md font-bold leading-[32px]">
{info?.name}
Expand All @@ -36,14 +43,19 @@ const ProfileCard: React.FC = () => {
<IoMdRefresh color="default" className="text-[24px]" />
</Button>
</div>
<div className="mt-2 flex justify-between">
<small>{extra ? `${calcTraffic(usage)}/${calcTraffic(total)}` : undefined}</small>
<small>{dayjs(info.updated).fromNow()}</small>
</div>
</CardBody>
<CardFooter className="pt-1">
<Progress
classNames={{ indicator: 'bg-foreground', label: 'select-none' }}
label={extra ? `${calcTraffic(usage)}/${calcTraffic(total)}` : undefined}
value={calcPercent(extra?.upload, extra?.download, extra?.total)}
className="max-w-md"
/>
<CardFooter className="pt-0">
{extra && (
<Progress
className="w-full"
classNames={{ indicator: 'bg-foreground', label: 'select-none' }}
value={calcPercent(extra?.upload, extra?.download, extra?.total)}
/>
)}
</CardFooter>
</Card>
)
Expand Down
10 changes: 3 additions & 7 deletions src/renderer/src/components/sider/tun-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-c
import BorderSwitch from '@renderer/components/base/border-swtich'
import { TbDeviceIpadHorizontalBolt } from 'react-icons/tb'
import { useLocation, useNavigate } from 'react-router-dom'
import {
platform,
encryptString,
patchMihomoConfig,
isEncryptionAvailable
} from '@renderer/utils/ipc'
import { encryptString, patchMihomoConfig, isEncryptionAvailable } from '@renderer/utils/ipc'
import { platform } from '@renderer/utils/init'
import React, { useState } from 'react'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import BasePasswordModal from '../base/base-password-modal'
Expand All @@ -24,7 +20,7 @@ const TunSwitcher: React.FC = () => {
const { enable } = tun || {}

const onChange = async (enable: boolean): Promise<void> => {
if (enable && (await platform()) !== 'win32') {
if (enable && platform !== 'win32') {
const encryptionAvailable = await isEncryptionAvailable()
if (!appConfig?.encryptedPassword && encryptionAvailable) {
setOpenPasswordModal(true)
Expand Down
26 changes: 14 additions & 12 deletions src/renderer/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ import ReactDOM from 'react-dom/client'
import { HashRouter } from 'react-router-dom'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
import { NextUIProvider } from '@nextui-org/react'
import '@renderer/utils/init'
import { init } from '@renderer/utils/init'
import '@renderer/assets/main.css'
import App from '@renderer/App'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<NextUIProvider>
<NextThemesProvider attribute="class" defaultTheme="dark">
<HashRouter>
<App />
</HashRouter>
</NextThemesProvider>
</NextUIProvider>
</React.StrictMode>
)
init().then(() => {
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<NextUIProvider>
<NextThemesProvider attribute="class" defaultTheme="dark">
<HashRouter>
<App />
</HashRouter>
</NextThemesProvider>
</NextUIProvider>
</React.StrictMode>
)
})
10 changes: 9 additions & 1 deletion src/renderer/src/pages/profiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { useState } from 'react'
import { MdContentPaste } from 'react-icons/md'

const Profiles: React.FC = () => {
const { profileConfig, addProfileItem, changeCurrentProfile } = useProfileConfig()
const {
profileConfig,
addProfileItem,
removeProfileItem,
changeCurrentProfile,
mutateProfileConfig
} = useProfileConfig()
const { current, items } = profileConfig || {}
const [importing, setImporting] = useState(false)
const [url, setUrl] = useState('')
Expand Down Expand Up @@ -55,6 +61,8 @@ const Profiles: React.FC = () => {
<ProfileItem
key={item.id}
isCurrent={item.id === current}
removeProfileItem={removeProfileItem}
mutateProfileConfig={mutateProfileConfig}
info={item}
onClick={async () => {
await changeCurrentProfile(item.id)
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/src/utils/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { getPlatform } from './ipc'
const originError = console.error
const originWarn = console.warn
console.error = function (...args: any[]): void {
Expand All @@ -13,3 +15,9 @@ console.warn = function (...args): void {
}
originWarn.call(console, args)
}

export let platform: NodeJS.Platform

export async function init(): Promise<void> {
platform = await getPlatform()
}
2 changes: 1 addition & 1 deletion src/renderer/src/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export async function encryptString(str: string): Promise<Buffer> {
return await window.electron.ipcRenderer.invoke('encryptString', str)
}

export async function platform(): Promise<NodeJS.Platform> {
export async function getPlatform(): Promise<NodeJS.Platform> {
return await window.electron.ipcRenderer.invoke('platform')
}

Expand Down

0 comments on commit 8d7ae19

Please sign in to comment.