mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 12:22:34 +03:00
* chore(lint): batch 4 of #12146 — resolve the react-hooks compiler violations in shared/components Real refactors (no suppressions, no eslint-disable) for the 21 react-hooks/* violations across the 11 src/shared/components files of this batch: - set-state-in-effect (prop/state mirror or modal open/close reset): replaced with guarded render-time adjustments (react.dev "You Might Not Need an Effect" prev-tracking pattern) — KiroAuthModal, ModelSelectModal, ProxyConfigModal, OAuthModal (provider-change, close and open resets; ref invalidation split into ref-only effects), RequestLoggerDetail.sections (liveDetail mirror), ComboCompressionModeSelect (initialCompressionMode mirror). - set-state-in-effect (fetch+set effects calling component-scope functions): moved the async loader inside the effect (ModelSelectModal fetchCombos/fetchProviderNodes/fetchCustomModels, PricingModal loadPricing, useProviderDailyUsage fetchRows — now with a cancelled guard) or wrapped the call in an effect-local async runner (ReasoningRoutingRules load, UsageStats fetchStats, OAuthModal startOAuthFlow) with every setState on the async path. - OAuthModal device-code countdown: deviceCodeSecondsRemaining state deleted and derived from deviceCodeExpiresAt plus a `now` tick state updated by the interval (re-anchored when polling starts). - Sidebar localStorage hydration: reads moved into useSyncExternalStore snapshots (server snapshot null) applied via render-time adjustment; skipInitialActiveExpansion ref converted to state; the active-section expansion effect became a render-time adjustment keyed on the old effect deps; persistence consolidated into one saveToStorage effect (removes the saves that ran inside setState updaters and drops a pre-existing eslint-disable for exhaustive-deps). - immutability (use-before-declare): PricingModal loadPricing inlined into its effect; ProxyConfigModal resetFields hoisted above the load effect as a dependency-free useCallback. - exhaustive-deps (ProxyConfigModal): effect now depends on the stable resetFields and on hoisted translated strings (socks5HiddenError, levelGlobalLabel) instead of the `t` identity. - preserve-manual-memoization (UsageStats sortedAccounts): optional chains destructured into locals so the memo deps match the usage. config/quality/eslint-suppressions.json: removed every react-hooks/* entry for the 11 files (other-rule entries preserved). Validation: eslint gate (--suppressions-location, --max-warnings 0) green on all 11 files; typecheck:core clean; node unit sweep 373/373; vitest sweep 547/550 with the 3 fails being 5s-timeout flakes under parallel load (all pass isolated 8/8, one in an untouched file). Refs #12146 * test(mutation): register search-432-plan-limit-cooldown in tap.testFiles The test (merged with the DuckDuckGo cooldown fix) covers accountFallback.ts and auth.ts but was not listed, so check:mutation-test-coverage --strict reds any PR whose merge ref includes it. Base also merged in.
This commit is contained in:
committed by
GitHub
parent
7f49b342b5
commit
bbbcc79384
@@ -148,64 +148,68 @@ export default function ModelSelectModal({
|
||||
const [testProgress, setTestProgress] = useState<{ done: number; total: number } | null>(null);
|
||||
const [modelTestStatus, setModelTestStatus] = useState<Record<string, "ok" | "error">>({});
|
||||
|
||||
const fetchCombos = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/combos");
|
||||
if (!res.ok) throw new Error(`Failed to fetch combos: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setCombos(data.combos || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching combos:", error);
|
||||
setCombos([]);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) fetchCombos();
|
||||
if (!isOpen) return;
|
||||
const fetchCombos = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/combos");
|
||||
if (!res.ok) throw new Error(`Failed to fetch combos: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setCombos(data.combos || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching combos:", error);
|
||||
setCombos([]);
|
||||
}
|
||||
};
|
||||
fetchCombos();
|
||||
}, [isOpen]);
|
||||
|
||||
// Reset provider-test bookkeeping whenever the modal closes so the next
|
||||
// open starts from a clean selection / progress state.
|
||||
// open starts from a clean selection / progress state (render-time
|
||||
// adjustment per react.dev "You Might Not Need an Effect").
|
||||
const [prevIsOpen, setPrevIsOpen] = useState(isOpen);
|
||||
if (isOpen !== prevIsOpen) {
|
||||
setPrevIsOpen(isOpen);
|
||||
if (!isOpen) {
|
||||
setSelectedProviderIds(new Set());
|
||||
setTestingProviders(false);
|
||||
setTestProgress(null);
|
||||
setModelTestStatus({});
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) return;
|
||||
setSelectedProviderIds(new Set());
|
||||
setTestingProviders(false);
|
||||
setTestProgress(null);
|
||||
setModelTestStatus({});
|
||||
if (!isOpen) return;
|
||||
const fetchProviderNodes = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/provider-nodes");
|
||||
if (!res.ok) throw new Error(`Failed to fetch provider nodes: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setProviderNodes(data.nodes || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching provider nodes:", error);
|
||||
setProviderNodes([]);
|
||||
}
|
||||
};
|
||||
fetchProviderNodes();
|
||||
}, [isOpen]);
|
||||
|
||||
const fetchProviderNodes = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/provider-nodes");
|
||||
if (!res.ok) throw new Error(`Failed to fetch provider nodes: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setProviderNodes(data.nodes || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching provider nodes:", error);
|
||||
setProviderNodes([]);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) fetchProviderNodes();
|
||||
}, [isOpen]);
|
||||
|
||||
const fetchCustomModels = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/provider-models");
|
||||
if (!res.ok) throw new Error(`Failed to fetch custom models: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setCustomModels(data.models || {});
|
||||
// #9203: keep the unified hidden-model map in sync with the model list.
|
||||
setHiddenModelsByProvider(parseHiddenModelsByProvider(data.hiddenModelsByProvider));
|
||||
} catch (error) {
|
||||
console.error("Error fetching custom models:", error);
|
||||
setCustomModels({});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) fetchCustomModels();
|
||||
if (!isOpen) return;
|
||||
const fetchCustomModels = async () => {
|
||||
try {
|
||||
const res = await fetch("/api/provider-models");
|
||||
if (!res.ok) throw new Error(`Failed to fetch custom models: ${res.status}`);
|
||||
const data = await res.json();
|
||||
setCustomModels(data.models || {});
|
||||
// #9203: keep the unified hidden-model map in sync with the model list.
|
||||
setHiddenModelsByProvider(parseHiddenModelsByProvider(data.hiddenModelsByProvider));
|
||||
} catch (error) {
|
||||
console.error("Error fetching custom models:", error);
|
||||
setCustomModels({});
|
||||
}
|
||||
};
|
||||
fetchCustomModels();
|
||||
}, [isOpen]);
|
||||
|
||||
// Fetch the live model catalog for one custom provider from its connection's
|
||||
|
||||
Reference in New Issue
Block a user