mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-28 00:34:59 +03:00
chore(frontend): update dependencies and adapt to oxlint 1.79
npm install was failing with ERESOLVE: the lockfile pinned storybook 10.5.7 and vitest 4.1.10 as peers while package.json asked for ^10.5.9 and ^4.1.11, and npm would not move either. Neither npm update, a targeted install, nor --package-lock-only broke the cycle, so node_modules and package-lock.json were regenerated from scratch (601 packages, 0 vulnerabilities). oxlint 1.79.0 then promoted five React Compiler rules into the correctness category, flagging 101 pre-existing sites. 1.78.0 exits 0 on the same tree, so nothing in our code changed - the rule set grew. They are fixed rather than suppressed: - refs (31): latest-value ref writes moved out of render into an effect. onlineClientsRef turned out to be write-only and is gone; expireDiffRef and trafficDiffRef were replaced by reading the values directly. - set-state-in-effect (55): reset-on-open modals now adjust state during render; where an effect mixed a synchronous reset with an async fetch, the reset moved to render and the effect kept only the request. useMediaQuery became useSyncExternalStore. - preserve-manual-memoization (11): optional-chained deps the compiler cannot match, hoisted to locals or dropped where the memo wrapped a string concat. - purity (3): Date.now() in render replaced by a state-backed clock, which also refreshes the expiry tag every 60s instead of freezing it until the next unrelated re-render. - immutability (1): applyClientStatsEvent merged websocket traffic into DBInbound rows in place; it now rebuilds only the rows it touches. Two things fell out of that. clientCount is derived with useMemo instead of an imperative rebuildClientCount() called from five sites, which also fixes a staleness bug where changing the expiry or traffic threshold left the counts alone until some later rebuild. statsVersion existed only to force a re-render after an in-place mutation, is meaningless now that rows are replaced, and nothing read it, so it is removed. Also adds a lint:fix script - oxlint --fix was previously only reachable through the lint-staged hook.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Modal, Tag } from 'antd';
|
||||
|
||||
@@ -40,6 +41,15 @@ export default function InboundStatsModal({
|
||||
onClose,
|
||||
}: InboundStatsModalProps) {
|
||||
const { t } = useTranslation();
|
||||
// The expiry tag colours against the current time; a state-backed clock keeps
|
||||
// render pure and still refreshes the tag while the modal stays open.
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const id = window.setInterval(() => setNow(Date.now()), 60_000);
|
||||
return () => window.clearInterval(id);
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
@@ -143,7 +153,7 @@ export default function InboundStatsModal({
|
||||
<div className="stat-row">
|
||||
<span className="stat-label">{t('pages.inbounds.expireDate')}</span>
|
||||
{record.expiryTime > 0 ? (
|
||||
<Tag color={ColorUtils.usageColor(Date.now(), expireDiff, record._expiryTime)}>
|
||||
<Tag color={ColorUtils.usageColor(now, expireDiff, record._expiryTime)}>
|
||||
{IntlUtil.formatRelativeTime(record.expiryTime)}
|
||||
</Tag>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user