Replace polling with websocket live sync

This commit is contained in:
2026-04-02 02:31:59 +03:00
parent 9a3785deb9
commit c04847b21c
15 changed files with 596 additions and 28 deletions

View File

@@ -1,4 +1,4 @@
import { FormEvent, useEffect, useMemo, useState } from 'react';
import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
import type { DashboardSnapshot, ProxyServiceRecord, SystemSettings, UpdateSystemInput } from './shared/contracts';
import type { PanelLanguage, PanelPreferences, PanelTheme } from './lib/panelPreferences';
import { getPanelText, getThemeLabel } from './lib/panelText';
@@ -21,12 +21,25 @@ export default function SystemTab({
const [error, setError] = useState('');
const [isSaving, setIsSaving] = useState(false);
const [removeServiceId, setRemoveServiceId] = useState<string | null>(null);
const lastAppliedSystemKey = useRef(serializeSystemSettings(cloneSystemSettings(snapshot.system)));
const text = getPanelText(preferences.language);
useEffect(() => {
setDraft(cloneSystemSettings(snapshot.system));
setError('');
}, [snapshot.system]);
const incomingDraft = cloneSystemSettings(snapshot.system);
const incomingKey = serializeSystemSettings(incomingDraft);
const draftKey = serializeSystemSettings(draft);
if (incomingKey === lastAppliedSystemKey.current) {
return;
}
if (draftKey === lastAppliedSystemKey.current || draftKey === incomingKey) {
setDraft(incomingDraft);
setError('');
}
lastAppliedSystemKey.current = incomingKey;
}, [draft, snapshot.system]);
const linkedUsersByService = useMemo(() => {
const result = new Map<string, string[]>();
@@ -249,6 +262,7 @@ export default function SystemTab({
className="button-secondary"
onClick={() => {
setDraft(cloneSystemSettings(snapshot.system));
lastAppliedSystemKey.current = serializeSystemSettings(cloneSystemSettings(snapshot.system));
setError('');
}}
>
@@ -344,3 +358,7 @@ function createServiceDraft(existingServices: ProxyServiceRecord[]): ProxyServic
assignable: true,
};
}
function serializeSystemSettings(system: UpdateSystemInput): string {
return JSON.stringify(system);
}