gix bug again

This commit is contained in:
2026-05-09 21:07:37 +07:00
parent 0f4d402a95
commit afef2ee1c1
+38 -79
View File
@@ -6,14 +6,7 @@ import type { AppConfigUpdate, MediaMtxConfigView } from "@/types/api";
import { apiJson } from "@/utils/api"; import { apiJson } from "@/utils/api";
export default function Settings() { export default function Settings() {
const { const { config, isLoading, error, load } = useConfigStore();
config,
isLoading,
error,
load,
setSchedulerEnabled,
updateSchedule,
} = useConfigStore();
const [rtspUrl, setRtspUrl] = useState(""); const [rtspUrl, setRtspUrl] = useState("");
const [mtx, setMtx] = useState<MediaMtxConfigView | null>(null); const [mtx, setMtx] = useState<MediaMtxConfigView | null>(null);
@@ -31,6 +24,8 @@ export default function Settings() {
const [recordingsDir, setRecordingsDir] = useState(""); const [recordingsDir, setRecordingsDir] = useState("");
const [apiPort, setApiPort] = useState("8008"); const [apiPort, setApiPort] = useState("8008");
const [recordDeleteAfterDays, setRecordDeleteAfterDays] = useState("7"); const [recordDeleteAfterDays, setRecordDeleteAfterDays] = useState("7");
const [recordEnabled, setRecordEnabled] = useState(false);
const [schedulerEnabled, setSchedulerEnabledState] = useState(true);
const loadMtx = async () => { const loadMtx = async () => {
setMtxBusy(true); setMtxBusy(true);
@@ -38,7 +33,9 @@ export default function Settings() {
try { try {
const data = await apiJson<MediaMtxConfigView>("/mediamtx/config", { method: "GET" }); const data = await apiJson<MediaMtxConfigView>("/mediamtx/config", { method: "GET" });
setMtx(data); setMtx(data);
setRecordDeleteAfterDays(String(data.record_delete_after_days ?? 7)); setRecordEnabled(Boolean(data.record_enabled));
const d = data.record_delete_after_days;
setRecordDeleteAfterDays(d === 1 || d === 3 || d === 7 ? String(d) : "7");
} catch (e) { } catch (e) {
if (typeof e === "object" && e && "status" in e) { if (typeof e === "object" && e && "status" in e) {
const ex = e as { status: number; bodyText?: string }; const ex = e as { status: number; bodyText?: string };
@@ -61,6 +58,7 @@ export default function Settings() {
setWeekdaysFrom(schedule.weekdays_from); setWeekdaysFrom(schedule.weekdays_from);
setWeekdaysTo(schedule.weekdays_to); setWeekdaysTo(schedule.weekdays_to);
setWeekendAllDay(schedule.weekend_all_day); setWeekendAllDay(schedule.weekend_all_day);
setSchedulerEnabledState(Boolean(schedule.enabled));
}, [schedule]); }, [schedule]);
useEffect(() => { useEffect(() => {
@@ -100,15 +98,7 @@ export default function Settings() {
} }
}; };
const onSaveSchedule = async () => { const onSaveAll = async () => {
await updateSchedule({
weekdays_from: weekdaysFrom,
weekdays_to: weekdaysTo,
weekend_all_day: weekendAllDay,
});
};
const onSaveBasicConfig = async () => {
setMtxBusy(true); setMtxBusy(true);
setMtxError(null); setMtxError(null);
setRestartMsg(null); setRestartMsg(null);
@@ -125,15 +115,35 @@ export default function Settings() {
method: "POST", method: "POST",
body: JSON.stringify(payload), body: JSON.stringify(payload),
}); });
await apiJson("/mediamtx/record-delete-after", {
method: "POST",
body: JSON.stringify({ days: Number(recordDeleteAfterDays) }),
});
await apiJson("/scheduler/schedule", {
method: "POST",
body: JSON.stringify({
weekdays_from: weekdaysFrom,
weekdays_to: weekdaysTo,
weekend_all_day: weekendAllDay,
}),
});
await apiJson("/scheduler/enabled", {
method: "POST",
body: JSON.stringify({ enabled: schedulerEnabled }),
});
await apiJson("/mediamtx/recording", {
method: "POST",
body: JSON.stringify({ enabled: recordEnabled }),
});
await load(); await load();
await loadMtx(); await loadMtx();
setRestartMsg("Lưu config.json thành công"); setRestartMsg("Lưu config.json và mediamtx.yml thành công");
} catch (e) { } catch (e) {
if (typeof e === "object" && e && "status" in e) { if (typeof e === "object" && e && "status" in e) {
const ex = e as { status: number; bodyText?: string }; const ex = e as { status: number; bodyText?: string };
setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`); setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
} else { } else {
setMtxError("failed_to_save_config"); setMtxError("failed_to_save_all");
} }
} finally { } finally {
setMtxBusy(false); setMtxBusy(false);
@@ -161,49 +171,6 @@ export default function Settings() {
} }
}; };
const onToggleRecord = async (enabled: boolean) => {
setMtxBusy(true);
setMtxError(null);
try {
const data = await apiJson<MediaMtxConfigView>("/mediamtx/recording", {
method: "POST",
body: JSON.stringify({ enabled }),
});
setMtx(data);
} catch (e) {
if (typeof e === "object" && e && "status" in e) {
const ex = e as { status: number; bodyText?: string };
setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
} else {
setMtxError("failed_to_toggle_recording");
}
} finally {
setMtxBusy(false);
}
};
const onChangeRecordDeleteAfter = async (days: number) => {
setMtxBusy(true);
setMtxError(null);
try {
const data = await apiJson<MediaMtxConfigView>("/mediamtx/record-delete-after", {
method: "POST",
body: JSON.stringify({ days }),
});
setMtx(data);
setRecordDeleteAfterDays(String(data.record_delete_after_days ?? days));
} catch (e) {
if (typeof e === "object" && e && "status" in e) {
const ex = e as { status: number; bodyText?: string };
setMtxError(`http_${ex.status}${ex.bodyText ? `: ${ex.bodyText}` : ""}`);
} else {
setMtxError("failed_to_update_record_delete_after");
}
} finally {
setMtxBusy(false);
}
};
const onRestartDocker = async () => { const onRestartDocker = async () => {
setMtxBusy(true); setMtxBusy(true);
setRestartMsg(null); setRestartMsg(null);
@@ -371,19 +338,19 @@ export default function Settings() {
</div> </div>
<button <button
type="button" type="button"
onClick={() => void onSaveBasicConfig()} onClick={() => void onSaveAll()}
disabled={mtxBusy} disabled={mtxBusy}
className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60" className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60"
> >
Save Config Save All
</button> </button>
</div> </div>
<label className="flex items-center gap-2 text-sm text-zinc-200"> <label className="flex items-center gap-2 text-sm text-zinc-200">
<input <input
type="checkbox" type="checkbox"
checked={Boolean(mtx?.record_enabled)} checked={recordEnabled}
onChange={(e) => void onToggleRecord(e.target.checked)} onChange={(e) => setRecordEnabled(e.target.checked)}
className="h-4 w-4 rounded border-zinc-700 bg-zinc-950" className="h-4 w-4 rounded border-zinc-700 bg-zinc-950"
/> />
MediaMTX record (pathDefaults.record) MediaMTX record (pathDefaults.record)
@@ -392,8 +359,8 @@ export default function Settings() {
<div> <div>
<label className="text-xs text-zinc-400">recordDeleteAfter</label> <label className="text-xs text-zinc-400">recordDeleteAfter</label>
<select <select
value={String(mtx?.record_delete_after_days ?? recordDeleteAfterDays)} value={recordDeleteAfterDays}
onChange={(e) => void onChangeRecordDeleteAfter(Number(e.target.value))} onChange={(e) => setRecordDeleteAfterDays(e.target.value)}
disabled={mtxBusy} disabled={mtxBusy}
className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100 disabled:opacity-60" className="mt-1 h-9 w-full rounded-md border border-zinc-800 bg-zinc-950 px-3 text-sm text-zinc-100 disabled:opacity-60"
> >
@@ -406,8 +373,8 @@ export default function Settings() {
<label className="flex items-center gap-2 text-sm text-zinc-200"> <label className="flex items-center gap-2 text-sm text-zinc-200">
<input <input
type="checkbox" type="checkbox"
checked={Boolean(schedule?.enabled)} checked={schedulerEnabled}
onChange={(e) => void setSchedulerEnabled(e.target.checked)} onChange={(e) => setSchedulerEnabledState(e.target.checked)}
className="h-4 w-4 rounded border-zinc-700 bg-zinc-950" className="h-4 w-4 rounded border-zinc-700 bg-zinc-950"
/> />
Enable scheduler Enable scheduler
@@ -444,14 +411,6 @@ export default function Settings() {
Weekend: record all day Weekend: record all day
</label> </label>
<button
type="button"
onClick={() => void onSaveSchedule()}
disabled={isLoading}
className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-950/40 px-3 py-2 text-sm text-zinc-200 transition hover:bg-zinc-900 disabled:cursor-not-allowed disabled:opacity-60"
>
Save
</button>
<button <button
type="button" type="button"
onClick={() => void onRestartDocker()} onClick={() => void onRestartDocker()}