mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-04-13 08:00:30 +08:00
feat: support user agent config per sub (#1712)
* feat: add user agent support in profile configuration * Introduced a new user agent field in profile settings, allowing users to specify a custom user agent. * Updated relevant components and localization files to support the new user agent feature. * Added a new pnpm workspace configuration for built dependencies. * feat: enhance profile settings with user agent input and toggle functionality * Added a user agent input field to the advanced profile settings. * Implemented toggle icons for showing/hiding advanced settings. * Updated layout to accommodate the new user agent input alongside the existing auth token field. * chore: remove pnpm workspace configuration for built dependencies
This commit is contained in:
parent
07dd85db84
commit
2a4b9f4e5b
@ -248,6 +248,7 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
allowFixedInterval: item.allowFixedInterval || false,
|
allowFixedInterval: item.allowFixedInterval || false,
|
||||||
autoUpdate: item.autoUpdate ?? false,
|
autoUpdate: item.autoUpdate ?? false,
|
||||||
authToken: item.authToken,
|
authToken: item.authToken,
|
||||||
|
userAgent: item.userAgent,
|
||||||
updated: new Date().getTime(),
|
updated: new Date().getTime(),
|
||||||
updateTimeout: item.updateTimeout || 5
|
updateTimeout: item.updateTimeout || 5
|
||||||
}
|
}
|
||||||
@ -268,7 +269,7 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
const baseOptions: Omit<FetchOptions, 'useProxy' | 'timeout'> = {
|
const baseOptions: Omit<FetchOptions, 'useProxy' | 'timeout'> = {
|
||||||
url: item.url,
|
url: item.url,
|
||||||
mixedPort,
|
mixedPort,
|
||||||
userAgent: userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`,
|
userAgent: item.userAgent || userAgent || `mihomo.party/v${app.getVersion()} (clash.meta)`,
|
||||||
authToken: item.authToken,
|
authToken: item.authToken,
|
||||||
substore: newItem.substore || false
|
substore: newItem.substore || false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,6 +108,17 @@ const EditInfoModal: React.FC<Props> = (props) => {
|
|||||||
placeholder={t('profiles.editInfo.authTokenPlaceholder')}
|
placeholder={t('profiles.editInfo.authTokenPlaceholder')}
|
||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
<SettingItem title={t('profiles.editInfo.userAgent')}>
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
className={cn(inputWidth)}
|
||||||
|
value={values.userAgent || ''}
|
||||||
|
onValueChange={(v) => {
|
||||||
|
setValues({ ...values, userAgent: v || undefined })
|
||||||
|
}}
|
||||||
|
placeholder={t('profiles.editInfo.userAgentPlaceholder')}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
<SettingItem title={t('profiles.editInfo.useProxy')}>
|
<SettingItem title={t('profiles.editInfo.useProxy')}>
|
||||||
<Switch
|
<Switch
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -496,6 +496,8 @@
|
|||||||
"profiles.editInfo.url": "Subscription URL",
|
"profiles.editInfo.url": "Subscription URL",
|
||||||
"profiles.editInfo.authToken": "Authorization Token",
|
"profiles.editInfo.authToken": "Authorization Token",
|
||||||
"profiles.editInfo.authTokenPlaceholder": "Bearer token or other auth header value",
|
"profiles.editInfo.authTokenPlaceholder": "Bearer token or other auth header value",
|
||||||
|
"profiles.editInfo.userAgent": "User Agent",
|
||||||
|
"profiles.editInfo.userAgentPlaceholder": "Leave empty to use global User Agent",
|
||||||
"profiles.editInfo.useProxy": "Use Proxy to Update",
|
"profiles.editInfo.useProxy": "Use Proxy to Update",
|
||||||
"profiles.editInfo.interval": "Upd. Interval",
|
"profiles.editInfo.interval": "Upd. Interval",
|
||||||
"profiles.editInfo.intervalPlaceholder": "e.g.: 30 or '0 * * * *'",
|
"profiles.editInfo.intervalPlaceholder": "e.g.: 30 or '0 * * * *'",
|
||||||
|
|||||||
@ -471,6 +471,8 @@
|
|||||||
"profiles.editInfo.title": "ویرایش اطلاعات",
|
"profiles.editInfo.title": "ویرایش اطلاعات",
|
||||||
"profiles.editInfo.name": "نام",
|
"profiles.editInfo.name": "نام",
|
||||||
"profiles.editInfo.url": "آدرس اشتراک",
|
"profiles.editInfo.url": "آدرس اشتراک",
|
||||||
|
"profiles.editInfo.userAgent": "User Agent",
|
||||||
|
"profiles.editInfo.userAgentPlaceholder": "برای استفاده از User Agent جهانی خالی بگذارید",
|
||||||
"profiles.editInfo.useProxy": "استفاده از پراکسی برای بهروزرسانی",
|
"profiles.editInfo.useProxy": "استفاده از پراکسی برای بهروزرسانی",
|
||||||
"profiles.editInfo.interval": "فاصله بهروزرسانی",
|
"profiles.editInfo.interval": "فاصله بهروزرسانی",
|
||||||
"profiles.editInfo.fixedInterval": "فاصله بهروزرسانی ثابت",
|
"profiles.editInfo.fixedInterval": "فاصله بهروزرسانی ثابت",
|
||||||
|
|||||||
@ -473,6 +473,8 @@
|
|||||||
"profiles.editInfo.title": "Редактировать информацию",
|
"profiles.editInfo.title": "Редактировать информацию",
|
||||||
"profiles.editInfo.name": "Имя",
|
"profiles.editInfo.name": "Имя",
|
||||||
"profiles.editInfo.url": "URL подписки",
|
"profiles.editInfo.url": "URL подписки",
|
||||||
|
"profiles.editInfo.userAgent": "User Agent",
|
||||||
|
"profiles.editInfo.userAgentPlaceholder": "Оставьте пустым для глобального User Agent",
|
||||||
"profiles.editInfo.useProxy": "Использовать прокси для обновления",
|
"profiles.editInfo.useProxy": "Использовать прокси для обновления",
|
||||||
"profiles.editInfo.interval": "Интервал обн.",
|
"profiles.editInfo.interval": "Интервал обн.",
|
||||||
"profiles.editInfo.fixedInterval": "Фиксированный интервал обновления",
|
"profiles.editInfo.fixedInterval": "Фиксированный интервал обновления",
|
||||||
|
|||||||
@ -501,6 +501,8 @@
|
|||||||
"profiles.editInfo.url": "订阅地址",
|
"profiles.editInfo.url": "订阅地址",
|
||||||
"profiles.editInfo.authToken": "授权令牌",
|
"profiles.editInfo.authToken": "授权令牌",
|
||||||
"profiles.editInfo.authTokenPlaceholder": "Bearer token 或其他认证头值",
|
"profiles.editInfo.authTokenPlaceholder": "Bearer token 或其他认证头值",
|
||||||
|
"profiles.editInfo.userAgent": "User Agent",
|
||||||
|
"profiles.editInfo.userAgentPlaceholder": "留空则使用全局 User Agent",
|
||||||
"profiles.editInfo.useProxy": "使用代理更新",
|
"profiles.editInfo.useProxy": "使用代理更新",
|
||||||
"profiles.editInfo.interval": "更新间隔",
|
"profiles.editInfo.interval": "更新间隔",
|
||||||
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
||||||
|
|||||||
@ -501,6 +501,8 @@
|
|||||||
"profiles.editInfo.url": "訂閱地址",
|
"profiles.editInfo.url": "訂閱地址",
|
||||||
"profiles.editInfo.authToken": "授權令牌",
|
"profiles.editInfo.authToken": "授權令牌",
|
||||||
"profiles.editInfo.authTokenPlaceholder": "Bearer token 或其他認證頭值",
|
"profiles.editInfo.authTokenPlaceholder": "Bearer token 或其他認證頭值",
|
||||||
|
"profiles.editInfo.userAgent": "User Agent",
|
||||||
|
"profiles.editInfo.userAgentPlaceholder": "留空則使用全局 User Agent",
|
||||||
"profiles.editInfo.useProxy": "使用代理更新",
|
"profiles.editInfo.useProxy": "使用代理更新",
|
||||||
"profiles.editInfo.interval": "更新間隔",
|
"profiles.editInfo.interval": "更新間隔",
|
||||||
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
"profiles.editInfo.intervalPlaceholder": "例如:30 或 '0 * * * *'",
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import { useAppConfig } from '@renderer/hooks/use-app-config'
|
|||||||
import { getFilePath, readTextFile, subStoreCollections, subStoreSubs } from '@renderer/utils/ipc'
|
import { getFilePath, readTextFile, subStoreCollections, subStoreSubs } from '@renderer/utils/ipc'
|
||||||
import type { KeyboardEvent } from 'react'
|
import type { KeyboardEvent } from 'react'
|
||||||
import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { MdContentPaste } from 'react-icons/md'
|
import { MdContentPaste, MdUnfoldMore, MdUnfoldLess } from 'react-icons/md'
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
closestCenter,
|
closestCenter,
|
||||||
@ -53,6 +53,7 @@ const Profiles: React.FC = () => {
|
|||||||
const [sortedItems, setSortedItems] = useState(items)
|
const [sortedItems, setSortedItems] = useState(items)
|
||||||
const [useProxy, setUseProxy] = useState(false)
|
const [useProxy, setUseProxy] = useState(false)
|
||||||
const [authToken, setAuthToken] = useState('')
|
const [authToken, setAuthToken] = useState('')
|
||||||
|
const [userAgent, setUserAgent] = useState('')
|
||||||
const [showAdvanced, setShowAdvanced] = useState(false)
|
const [showAdvanced, setShowAdvanced] = useState(false)
|
||||||
const [subStoreImporting, setSubStoreImporting] = useState(false)
|
const [subStoreImporting, setSubStoreImporting] = useState(false)
|
||||||
const [importing, setImporting] = useState(false)
|
const [importing, setImporting] = useState(false)
|
||||||
@ -135,10 +136,12 @@ const Profiles: React.FC = () => {
|
|||||||
type: 'remote',
|
type: 'remote',
|
||||||
url,
|
url,
|
||||||
useProxy,
|
useProxy,
|
||||||
authToken: authToken || undefined
|
authToken: authToken || undefined,
|
||||||
|
userAgent: userAgent || undefined
|
||||||
})
|
})
|
||||||
setUrl('')
|
setUrl('')
|
||||||
setAuthToken('')
|
setAuthToken('')
|
||||||
|
setUserAgent('')
|
||||||
setImporting(false)
|
setImporting(false)
|
||||||
}
|
}
|
||||||
const pageRef = useRef<HTMLDivElement>(null)
|
const pageRef = useRef<HTMLDivElement>(null)
|
||||||
@ -300,7 +303,11 @@ const Profiles: React.FC = () => {
|
|||||||
isIconOnly
|
isIconOnly
|
||||||
onPress={() => setShowAdvanced(!showAdvanced)}
|
onPress={() => setShowAdvanced(!showAdvanced)}
|
||||||
>
|
>
|
||||||
🔑
|
{showAdvanced ? (
|
||||||
|
<MdUnfoldLess className="text-lg" />
|
||||||
|
) : (
|
||||||
|
<MdUnfoldMore className="text-lg" />
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Button
|
<Button
|
||||||
@ -426,6 +433,7 @@ const Profiles: React.FC = () => {
|
|||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
{showAdvanced && (
|
{showAdvanced && (
|
||||||
|
<div className="flex gap-2">
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
size="sm"
|
||||||
type="password"
|
type="password"
|
||||||
@ -433,9 +441,17 @@ const Profiles: React.FC = () => {
|
|||||||
value={authToken}
|
value={authToken}
|
||||||
onValueChange={setAuthToken}
|
onValueChange={setAuthToken}
|
||||||
onKeyUp={handleInputKeyUp}
|
onKeyUp={handleInputKeyUp}
|
||||||
className="w-full"
|
className="flex-1"
|
||||||
startContent={<span className="text-default-400 text-sm">🔑</span>}
|
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
placeholder={t('profiles.editInfo.userAgentPlaceholder')}
|
||||||
|
value={userAgent}
|
||||||
|
onValueChange={setUserAgent}
|
||||||
|
onKeyUp={handleInputKeyUp}
|
||||||
|
className="flex-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|||||||
1
src/shared/types.d.ts
vendored
1
src/shared/types.d.ts
vendored
@ -519,6 +519,7 @@ interface IProfileItem {
|
|||||||
allowFixedInterval?: boolean
|
allowFixedInterval?: boolean
|
||||||
autoUpdate?: boolean
|
autoUpdate?: boolean
|
||||||
authToken?: string
|
authToken?: string
|
||||||
|
userAgent?: string
|
||||||
updateTimeout?: number
|
updateTimeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user