feat(FN-4673): complete Step 1 — defer copilot auto-open

Fusion-Task-Id: FN-4673
Fusion-Task-Lineage: 165601b1-c20c-40d5-addb-3c42d710d66d
This commit is contained in:
Fusion
2026-05-15 15:03:31 -07:00
committed by gsxdsm
parent caf32fc55b
commit 87af2ce991
2 changed files with 46 additions and 2 deletions

View File

@@ -611,6 +611,7 @@ export function ModelOnboardingModal({
const modalRef = useRef<HTMLDivElement | null>(null);
const pollIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const [loginOutcomes, setLoginOutcomes] = useState<Record<string, LoginOutcome>>({});
const lastAutoCopiedDeviceCodesRef = useRef<Record<string, string>>({});
const [isGithubSkipped, setIsGithubSkipped] = useState<boolean>(() => {
const state = getOnboardingState();
return state?.stepData?.github?.skipped === true;
@@ -633,6 +634,20 @@ export function ModelOnboardingModal({
content.scrollTop = 0;
}, [step]);
useEffect(() => {
const copilotDeviceCode = deviceCodes["github-copilot"];
if (!copilotDeviceCode?.userCode) {
return;
}
if (lastAutoCopiedDeviceCodesRef.current["github-copilot"] === copilotDeviceCode.userCode) {
return;
}
lastAutoCopiedDeviceCodesRef.current["github-copilot"] = copilotDeviceCode.userCode;
void navigator.clipboard?.writeText(copilotDeviceCode.userCode);
}, [deviceCodes]);
// Initialize skippedProviders from persisted state
const [skippedProviders, setSkippedProviders] = useState<Record<string, boolean>>(
() => {
@@ -1084,6 +1099,11 @@ export function ModelOnboardingModal({
});
const clearAuthLoginUiState = () => {
if (providerId in lastAutoCopiedDeviceCodesRef.current) {
const next = { ...lastAutoCopiedDeviceCodesRef.current };
delete next[providerId];
lastAutoCopiedDeviceCodesRef.current = next;
}
setLoginInstructions((prev) => {
if (!(providerId in prev)) {
return prev;
@@ -1136,7 +1156,9 @@ export function ModelOnboardingModal({
if (deviceCode && providerId === "github-copilot") {
setDeviceCodes((prev) => ({ ...prev, [providerId]: deviceCode }));
}
window.open(appendTokenQuery(deviceCode?.verificationUri ?? url), "_blank");
if (providerId !== "github-copilot" || !deviceCode) {
window.open(appendTokenQuery(deviceCode?.verificationUri ?? url), "_blank");
}
// Poll for auth completion
pollIntervalRef.current = setInterval(async () => {

View File

@@ -546,6 +546,7 @@ export function SettingsModal({
const [apiKeyInputs, setApiKeyInputs] = useState<Record<string, string>>({});
const [apiKeyErrors, setApiKeyErrors] = useState<Record<string, string>>({});
const pollIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const lastAutoCopiedDeviceCodesRef = useRef<Record<string, string>>({});
// Model state
const [availableModels, setAvailableModels] = useState<ModelInfo[]>([]);
@@ -993,6 +994,11 @@ export function SettingsModal({
}, []);
const clearAuthLoginUiState = useCallback((providerId: string) => {
if (providerId in lastAutoCopiedDeviceCodesRef.current) {
const next = { ...lastAutoCopiedDeviceCodesRef.current };
delete next[providerId];
lastAutoCopiedDeviceCodesRef.current = next;
}
setLoginInstructions((prev) => {
if (!(providerId in prev)) {
return prev;
@@ -1027,6 +1033,20 @@ export function SettingsModal({
});
}, []);
useEffect(() => {
const copilotDeviceCode = deviceCodes["github-copilot"];
if (!copilotDeviceCode?.userCode) {
return;
}
if (lastAutoCopiedDeviceCodesRef.current["github-copilot"] === copilotDeviceCode.userCode) {
return;
}
lastAutoCopiedDeviceCodesRef.current["github-copilot"] = copilotDeviceCode.userCode;
void navigator.clipboard?.writeText(copilotDeviceCode.userCode);
}, [deviceCodes]);
const handleLogin = useCallback(async (providerId: string) => {
const provider = authProviders.find((entry) => entry.id === providerId);
if (provider?.requiresManualCode === true) {
@@ -1056,7 +1076,9 @@ export function SettingsModal({
if (deviceCode && providerId === "github-copilot") {
setDeviceCodes((prev) => ({ ...prev, [providerId]: deviceCode }));
}
window.open(appendTokenQuery(deviceCode?.verificationUri ?? url), "_blank");
if (providerId !== "github-copilot" || !deviceCode) {
window.open(appendTokenQuery(deviceCode?.verificationUri ?? url), "_blank");
}
// Poll for auth completion every 2 seconds
pollIntervalRef.current = setInterval(async () => {