Bump version and auto-generate sing-box HWIDs
This commit is contained in:
105
src/app/App.tsx
105
src/app/App.tsx
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useRef, useState, type CSSProperties } from 'react';
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { Cpu, FileCode2, Fingerprint, FolderOpen, Gauge, Link2, ShieldAlert, Trash2, Wand2 } from 'lucide-react';
|
||||
import { Cpu, FileCode2, FolderOpen, Gauge, Link2, ShieldAlert, Trash2, Wand2 } from 'lucide-react';
|
||||
import {
|
||||
applyProfiles,
|
||||
fetchSingBoxSubscription,
|
||||
@@ -19,7 +19,6 @@ import {
|
||||
pingSingBoxServer,
|
||||
restartAsAdmin,
|
||||
saveProfile,
|
||||
saveSingBoxDeviceHwid,
|
||||
saveSingBoxSubscription,
|
||||
saveTarget,
|
||||
selectSingBoxServer,
|
||||
@@ -45,7 +44,7 @@ import { serviceControlState } from './viewModel';
|
||||
|
||||
type DraftItemType = Extract<ProfileItemType, 'process' | 'folder' | 'exe'>;
|
||||
type ProxiFyreAction = 'start' | 'stop' | 'restart' | 'install' | 'uninstall';
|
||||
type SingBoxAction = 'start' | 'stop' | 'install' | 'uninstall' | 'fetch' | 'forget' | 'identity' | 'generate' | 'ping';
|
||||
type SingBoxAction = 'start' | 'stop' | 'install' | 'uninstall' | 'fetch' | 'forget' | 'generate' | 'ping';
|
||||
type RouteMode = 'external' | 'local-singbox';
|
||||
type ServiceVisualState = 'active' | 'settling' | null;
|
||||
type PanelId = 'summary' | 'proxifyre' | 'proxy';
|
||||
@@ -185,7 +184,6 @@ export function App() {
|
||||
const [singBoxStatus, setSingBoxStatus] = useState<LocalSingBoxStatusResponse | null>(null);
|
||||
const [singBoxSetupStatus, setSingBoxSetupStatus] = useState<SingBoxSetupStatus | null>(null);
|
||||
const [subscriptionInput, setSubscriptionInput] = useState('');
|
||||
const [deviceHwidInput, setDeviceHwidInput] = useState('');
|
||||
const [serverPings, setServerPings] = useState<Record<string, PingServerResponse>>({});
|
||||
const [proxyCheck, setProxyCheck] = useState<ProxyTargetCheckResponse | null>(null);
|
||||
const [adminStatus, setAdminStatus] = useState<AdminStatusResponse | null>(null);
|
||||
@@ -713,7 +711,6 @@ export function App() {
|
||||
|
||||
async function syncSingBoxSubscription() {
|
||||
const subscriptionUrl = subscriptionInput.trim();
|
||||
const deviceHwid = deviceHwidInput.trim();
|
||||
if (!subscriptionUrl && !singBoxStatus?.config.hasSubscription) {
|
||||
showNotice({
|
||||
kind: 'error',
|
||||
@@ -726,15 +723,12 @@ export function App() {
|
||||
setSingBoxAction('fetch');
|
||||
try {
|
||||
if (subscriptionUrl) {
|
||||
await saveSingBoxSubscription(subscriptionUrl, deviceHwid || undefined);
|
||||
} else if (deviceHwid) {
|
||||
await saveSingBoxDeviceHwid(deviceHwid);
|
||||
await saveSingBoxSubscription(subscriptionUrl);
|
||||
}
|
||||
const status = await fetchSingBoxSubscription();
|
||||
setSingBoxStatus(status);
|
||||
setComponents((current) => upsertComponent(current, status.component));
|
||||
setSubscriptionInput('');
|
||||
setDeviceHwidInput('');
|
||||
setServerPings({});
|
||||
setProxyCheck(null);
|
||||
showNotice({
|
||||
@@ -753,64 +747,6 @@ export function App() {
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSingBoxDeviceHwidData() {
|
||||
const deviceHwid = deviceHwidInput.trim();
|
||||
if (!deviceHwid) {
|
||||
showNotice({
|
||||
kind: 'error',
|
||||
title: 'HWID не указан',
|
||||
text: 'Вставь hard ID устройства для заголовка X-Hwid.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setSingBoxAction('identity');
|
||||
try {
|
||||
const status = await saveSingBoxDeviceHwid(deviceHwid);
|
||||
setSingBoxStatus(status);
|
||||
setComponents((current) => upsertComponent(current, status.component));
|
||||
setDeviceHwidInput('');
|
||||
showNotice({
|
||||
kind: 'success',
|
||||
title: 'HWID сохранен',
|
||||
text: status.config.deviceHwidDisplay
|
||||
? `Для подписки будет отправляться X-Hwid: ${status.config.deviceHwidDisplay}`
|
||||
: 'Для подписки будет отправляться X-Hwid.',
|
||||
});
|
||||
} catch (error) {
|
||||
showNotice({
|
||||
kind: 'error',
|
||||
title: 'HWID не сохранен',
|
||||
text: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setSingBoxAction(null);
|
||||
}
|
||||
}
|
||||
|
||||
async function forgetSingBoxDeviceHwidData() {
|
||||
setSingBoxAction('identity');
|
||||
try {
|
||||
const status = await saveSingBoxDeviceHwid(undefined);
|
||||
setSingBoxStatus(status);
|
||||
setComponents((current) => upsertComponent(current, status.component));
|
||||
setDeviceHwidInput('');
|
||||
showNotice({
|
||||
kind: 'info',
|
||||
title: 'HWID очищен',
|
||||
text: 'Заголовок X-Hwid больше не будет отправляться при загрузке подписки.',
|
||||
});
|
||||
} catch (error) {
|
||||
showNotice({
|
||||
kind: 'error',
|
||||
title: 'HWID не очищен',
|
||||
text: errorMessage(error),
|
||||
});
|
||||
} finally {
|
||||
setSingBoxAction(null);
|
||||
}
|
||||
}
|
||||
|
||||
async function forgetSingBoxSubscriptionData() {
|
||||
setSingBoxAction('forget');
|
||||
setIsSingBoxMenuOpen(false);
|
||||
@@ -823,7 +759,7 @@ export function App() {
|
||||
showNotice({
|
||||
kind: 'info',
|
||||
title: 'Подписка очищена',
|
||||
text: 'Ссылка, HWID, cache и выбранный сервер Local sing-box удалены.',
|
||||
text: 'Ссылка, cache и выбранный сервер Local sing-box удалены.',
|
||||
});
|
||||
} catch (error) {
|
||||
showNotice({
|
||||
@@ -1492,38 +1428,6 @@ export function App() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="subscription-line identity-line">
|
||||
<span className="subscription-icon" aria-hidden="true">
|
||||
<Fingerprint size={18} strokeWidth={1.9} />
|
||||
</span>
|
||||
<input
|
||||
value={deviceHwidInput}
|
||||
onChange={(event) => setDeviceHwidInput(event.target.value)}
|
||||
placeholder={singBoxStatus?.config.deviceHwidDisplay ?? 'X-Hwid hard ID'}
|
||||
spellCheck={false}
|
||||
aria-label="Hard ID устройства для X-Hwid"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => void saveSingBoxDeviceHwidData()}
|
||||
loading={singBoxAction === 'identity'}
|
||||
loadingLabel="Сохраняю"
|
||||
variant="neutral"
|
||||
disabled={Boolean(singBoxAction) || !deviceHwidInput.trim()}
|
||||
>
|
||||
{singBoxStatus?.config.hasDeviceHwid ? 'Заменить' : 'Сохранить'}
|
||||
</Button>
|
||||
<IconButton
|
||||
type="button"
|
||||
variant="danger"
|
||||
onClick={() => void forgetSingBoxDeviceHwidData()}
|
||||
disabled={Boolean(singBoxAction) || !singBoxStatus?.config.hasDeviceHwid}
|
||||
label="Очистить hard ID устройства"
|
||||
tooltip="Очистить HWID"
|
||||
icon={<Trash2 size={18} strokeWidth={1.9} />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="singbox-workspace-head">
|
||||
<span>Серверы подписки</span>
|
||||
<div className="singbox-workspace-actions">
|
||||
@@ -2662,7 +2566,6 @@ function singBoxDetailLines(
|
||||
`Файл: ${component?.path ?? 'не найден'}`,
|
||||
`Конфиг: ${status?.generatedConfigPath ?? 'не создан'}`,
|
||||
`Подписка: ${status?.config.subscriptionDisplayUrl ?? (status?.config.hasSubscription ? 'сохранена' : 'не загружена')}`,
|
||||
`X-Hwid: ${status?.config.deviceHwidDisplay ?? (status?.config.hasDeviceHwid ? 'сохранен' : 'не задан')}`,
|
||||
`Состав: ${setupDetails}`,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user