mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-26 20:50:30 +08:00
feat: Add inline support and missing translations
This commit is contained in:
parent
bb6021877d
commit
9d84c6ac9b
@ -256,7 +256,7 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
await patchAppConfig({ profileDisplayDate: 'update' })
|
await patchAppConfig({ profileDisplayDate: 'update' })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{extra.expire ? dayjs.unix(extra.expire).format('YYYY-MM-DD') : '长期有效'}
|
{extra.expire ? dayjs.unix(extra.expire).format('YYYY-MM-DD') : t('profiles.neverExpire')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -15,13 +15,15 @@ import { MdEditDocument } from 'react-icons/md'
|
|||||||
import dayjs from '@renderer/utils/dayjs'
|
import dayjs from '@renderer/utils/dayjs'
|
||||||
import { calcTraffic } from '@renderer/utils/calc'
|
import { calcTraffic } from '@renderer/utils/calc'
|
||||||
import { getHash } from '@renderer/utils/hash'
|
import { getHash } from '@renderer/utils/hash'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
const ProxyProvider: React.FC = () => {
|
const ProxyProvider: React.FC = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
const [showDetails, setShowDetails] = useState({
|
const [showDetails, setShowDetails] = useState({
|
||||||
show: false,
|
show: false,
|
||||||
path: '',
|
path: '',
|
||||||
type: '',
|
type: '',
|
||||||
title: ''
|
title: '',
|
||||||
|
privderType: ''
|
||||||
})
|
})
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showDetails.title) {
|
if (showDetails.title) {
|
||||||
@ -90,10 +92,11 @@ const ProxyProvider: React.FC = () => {
|
|||||||
path={showDetails.path}
|
path={showDetails.path}
|
||||||
type={showDetails.type}
|
type={showDetails.type}
|
||||||
title={showDetails.title}
|
title={showDetails.title}
|
||||||
onClose={() => setShowDetails({ show: false, path: '', type: '', title: '' })}
|
privderType={showDetails.privderType}
|
||||||
|
onClose={() => setShowDetails({ show: false, path: '', type: '', title: '', privderType: '' })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<SettingItem title="代理集合" divider>
|
<SettingItem title={t('resources.proxyProviders.title')} divider>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
color="primary"
|
color="primary"
|
||||||
@ -103,7 +106,7 @@ const ProxyProvider: React.FC = () => {
|
|||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
更新全部
|
{t('resources.proxyProviders.updateAll')}
|
||||||
</Button>
|
</Button>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
{providers.map((provider, index) => (
|
{providers.map((provider, index) => (
|
||||||
@ -124,12 +127,13 @@ const ProxyProvider: React.FC = () => {
|
|||||||
</Button> */}
|
</Button> */}
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title={provider.vehicleType == 'File' ? '编辑' : '查看'}
|
title={provider.vehicleType == 'File' ? t('common.editor.edit') : t('common.viewer.view')}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setShowDetails({
|
setShowDetails({
|
||||||
show: false,
|
show: false,
|
||||||
|
privderType: 'proxy-providers',
|
||||||
path: provider.name,
|
path: provider.name,
|
||||||
type: provider.vehicleType,
|
type: provider.vehicleType,
|
||||||
title: provider.name
|
title: provider.name
|
||||||
@ -144,7 +148,7 @@ const ProxyProvider: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title="更新"
|
title={t('common.updater.update')}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
@ -169,7 +173,7 @@ const ProxyProvider: React.FC = () => {
|
|||||||
<div className="h-[32px] leading-[32px] text-foreground-500">
|
<div className="h-[32px] leading-[32px] text-foreground-500">
|
||||||
{provider.subscriptionInfo.Expire
|
{provider.subscriptionInfo.Expire
|
||||||
? dayjs.unix(provider.subscriptionInfo.Expire).format('YYYY-MM-DD')
|
? dayjs.unix(provider.subscriptionInfo.Expire).format('YYYY-MM-DD')
|
||||||
: '长期有效'}
|
: t('profiles.neverExpire')}
|
||||||
</div>
|
</div>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -14,14 +14,17 @@ import { IoMdRefresh } from 'react-icons/io'
|
|||||||
import { CgLoadbarDoc } from 'react-icons/cg'
|
import { CgLoadbarDoc } from 'react-icons/cg'
|
||||||
import { MdEditDocument } from 'react-icons/md'
|
import { MdEditDocument } from 'react-icons/md'
|
||||||
import dayjs from '@renderer/utils/dayjs'
|
import dayjs from '@renderer/utils/dayjs'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
const RuleProvider: React.FC = () => {
|
const RuleProvider: React.FC = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
const [showDetails, setShowDetails] = useState({
|
const [showDetails, setShowDetails] = useState({
|
||||||
show: false,
|
show: false,
|
||||||
path: '',
|
path: '',
|
||||||
type: '',
|
type: '',
|
||||||
title: '',
|
title: '',
|
||||||
format: ''
|
format: '',
|
||||||
|
privderType: ''
|
||||||
})
|
})
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showDetails.title) {
|
if (showDetails.title) {
|
||||||
@ -89,10 +92,11 @@ const RuleProvider: React.FC = () => {
|
|||||||
type={showDetails.type}
|
type={showDetails.type}
|
||||||
title={showDetails.title}
|
title={showDetails.title}
|
||||||
format={showDetails.format}
|
format={showDetails.format}
|
||||||
onClose={() => setShowDetails({ show: false, path: '', type: '', title: '', format: '' })}
|
privderType={showDetails.privderType}
|
||||||
|
onClose={() => setShowDetails({ show: false, path: '', type: '', title: '', format: '', privderType: '' })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<SettingItem title="规则集合" divider>
|
<SettingItem title={t('resources.ruleProviders.title')} divider>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
color="primary"
|
color="primary"
|
||||||
@ -102,7 +106,7 @@ const RuleProvider: React.FC = () => {
|
|||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
更新全部
|
{t('resources.ruleProviders.updateAll')}
|
||||||
</Button>
|
</Button>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
{providers.map((provider, index) => (
|
{providers.map((provider, index) => (
|
||||||
@ -120,12 +124,13 @@ const RuleProvider: React.FC = () => {
|
|||||||
{provider.format !== 'MrsRule' && (
|
{provider.format !== 'MrsRule' && (
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title={provider.vehicleType == 'File' ? '编辑' : '查看'}
|
title={provider.vehicleType == 'File' ? t('common.editor.edit') : t('common.viewer.view')}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setShowDetails({
|
setShowDetails({
|
||||||
show: false,
|
show: false,
|
||||||
|
privderType: 'rule-providers',
|
||||||
path: provider.name,
|
path: provider.name,
|
||||||
type: provider.vehicleType,
|
type: provider.vehicleType,
|
||||||
title: provider.name,
|
title: provider.name,
|
||||||
@ -142,7 +147,7 @@ const RuleProvider: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title="更新"
|
title={t('common.updater.update')}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { BaseEditor } from '../base/base-editor'
|
import { BaseEditor } from '../base/base-editor'
|
||||||
import { getFileStr, setFileStr } from '@renderer/utils/ipc'
|
import { getFileStr, setFileStr } from '@renderer/utils/ipc'
|
||||||
|
import yaml from 'js-yaml'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
type Language = 'yaml' | 'javascript' | 'css' | 'json' | 'text'
|
type Language = 'yaml' | 'javascript' | 'css' | 'json' | 'text'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -9,15 +11,37 @@ interface Props {
|
|||||||
path: string
|
path: string
|
||||||
type: string
|
type: string
|
||||||
title: string
|
title: string
|
||||||
|
privderType: string
|
||||||
format?: string
|
format?: string
|
||||||
}
|
}
|
||||||
const Viewer: React.FC<Props> = (props) => {
|
const Viewer: React.FC<Props> = (props) => {
|
||||||
const { type, path, title, format, onClose } = props
|
const { t } = useTranslation()
|
||||||
|
const { type, path, title, format, privderType, onClose } = props
|
||||||
const [currData, setCurrData] = useState('')
|
const [currData, setCurrData] = useState('')
|
||||||
const language: Language = !format || format === 'YamlRule' ? 'yaml' : 'text'
|
let language: Language = !format || format === 'YamlRule' ? 'yaml' : 'text'
|
||||||
|
|
||||||
const getContent = async (): Promise<void> => {
|
const getContent = async (): Promise<void> => {
|
||||||
setCurrData(await getFileStr(path))
|
let fileContent: React.SetStateAction<string>
|
||||||
|
if (type === 'Inline') {
|
||||||
|
fileContent = await getFileStr('config.yaml')
|
||||||
|
language = 'yaml'
|
||||||
|
} else {
|
||||||
|
fileContent = await getFileStr(path)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsedYaml = yaml.load(fileContent)
|
||||||
|
if (privderType === 'proxy-providers') {
|
||||||
|
setCurrData(yaml.dump({
|
||||||
|
'proxies': parsedYaml[privderType][title].payload
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
setCurrData(yaml.dump({
|
||||||
|
'rules': parsedYaml[privderType][title].payload
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setCurrData(fileContent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -46,7 +70,7 @@ const Viewer: React.FC<Props> = (props) => {
|
|||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter className="pt-0">
|
<ModalFooter className="pt-0">
|
||||||
<Button size="sm" variant="light" onPress={onClose}>
|
<Button size="sm" variant="light" onPress={onClose}>
|
||||||
关闭
|
{t('common.close')}
|
||||||
</Button>
|
</Button>
|
||||||
{type == 'File' && (
|
{type == 'File' && (
|
||||||
<Button
|
<Button
|
||||||
@ -57,7 +81,7 @@ const Viewer: React.FC<Props> = (props) => {
|
|||||||
onClose()
|
onClose()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
保存
|
{t('common.save')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@ -350,6 +350,9 @@
|
|||||||
"profiles.traffic.remainingDays": "{{days}} days",
|
"profiles.traffic.remainingDays": "{{days}} days",
|
||||||
"profiles.traffic.lastUpdate": "Last updated: {{time}}",
|
"profiles.traffic.lastUpdate": "Last updated: {{time}}",
|
||||||
"profiles.notification.importSuccess": "Subscription imported successfully",
|
"profiles.notification.importSuccess": "Subscription imported successfully",
|
||||||
|
"resources.proxyProviders.title": "Proxy Providers",
|
||||||
|
"resources.proxyProviders.updateAll": "Update All",
|
||||||
|
"resources.ruleProviders.title": "Rule Providers",
|
||||||
"outbound.title": "Outbound Mode",
|
"outbound.title": "Outbound Mode",
|
||||||
"outbound.modes.rule": "Rule",
|
"outbound.modes.rule": "Rule",
|
||||||
"outbound.modes.global": "Global",
|
"outbound.modes.global": "Global",
|
||||||
|
|||||||
@ -350,6 +350,9 @@
|
|||||||
"profiles.openFile": "打开文件",
|
"profiles.openFile": "打开文件",
|
||||||
"profiles.home": "主页",
|
"profiles.home": "主页",
|
||||||
"profiles.notification.importSuccess": "订阅导入成功",
|
"profiles.notification.importSuccess": "订阅导入成功",
|
||||||
|
"resources.proxyProviders.title": "代理集合",
|
||||||
|
"resources.proxyProviders.updateAll": "更新全部",
|
||||||
|
"resources.ruleProviders.title": "规则集合",
|
||||||
"outbound.title": "出站模式",
|
"outbound.title": "出站模式",
|
||||||
"outbound.modes.rule": "规则",
|
"outbound.modes.rule": "规则",
|
||||||
"outbound.modes.global": "全局",
|
"outbound.modes.global": "全局",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user