mirror of
https://github.com/willchen96/mike.git
synced 2026-07-24 23:41:04 +02:00
Takes frontend/npm run lint from 23 errors / 40 warnings to 0 errors / 40 warnings, then removes continue-on-error from the CI lint step so it gates merges. Errors fixed outright: - @typescript-eslint/no-explicit-any (5, ChatView.tsx): dropped redundant (msg as any) casts — Message already declares files, workflow, and error with the exact shapes the props expect. - react/no-unescaped-entities (1, support/page.tsx): "We'll" -> "We'll". Targeted disables (17, all react-hooks/set-state-in-effect): every site is an intentional effect-driven state pattern — SSR/hydration mount gates (Modal, useSelectedModel), reset-on-prop/identity-change (CaseLawPanel x3, ChatView chat switch, CitationQuotesHeader, ChatHistoryContext logout, useFetchDocxBytes), sync fast paths of async fetch/check effects (CaseLawPanel, MfaLoginGate x2), DOM-measured state (ChatView scroll button, message-visibility restore), and timed UI latches (PreResponseWrapper, TRChatPanel, AskInputPopup auto-submit). Rewriting any of them would change runtime behavior, so each carries a // eslint-disable-next-line with a one-line reason instead of a fix or a repo-wide rule change. CI: lint step is now blocking; comments updated to say the backlog is at zero. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { ALLOWED_MODEL_IDS, DEFAULT_MODEL_ID } from "../components/assistant/ModelToggle";
|
|
|
|
const STORAGE_KEY = "mike.selectedModel";
|
|
|
|
function readStored(): string {
|
|
if (typeof window === "undefined") return DEFAULT_MODEL_ID;
|
|
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
if (raw && ALLOWED_MODEL_IDS.has(raw)) return raw;
|
|
return DEFAULT_MODEL_ID;
|
|
}
|
|
|
|
export function useSelectedModel(): [string, (id: string) => void] {
|
|
const [model, setModelState] = useState<string>(DEFAULT_MODEL_ID);
|
|
|
|
useEffect(() => {
|
|
// eslint-disable-next-line react-hooks/set-state-in-effect -- hydration-safe localStorage read; SSR must render the default model
|
|
setModelState(readStored());
|
|
}, []);
|
|
|
|
const setModel = useCallback((id: string) => {
|
|
const next = ALLOWED_MODEL_IDS.has(id) ? id : DEFAULT_MODEL_ID;
|
|
setModelState(next);
|
|
if (typeof window !== "undefined") {
|
|
window.localStorage.setItem(STORAGE_KEY, next);
|
|
}
|
|
}, []);
|
|
|
|
return [model, setModel];
|
|
}
|