fix(web): address settings document review

This commit is contained in:
Yichen Jiang
2026-08-04 17:31:36 +08:00
parent e31b7221e7
commit 4f717f2da7
42 changed files with 219 additions and 115 deletions

View File

@@ -21,7 +21,7 @@ export type SettingsDocumentActionProps =
PropsRuntime<'settings.action'> & PropsLocale<'settings'> & SettingsDocumentActionInjected
/**
* Render the open-document action only after Host metadata confirms a local file.
* Render the open-document action only after Host metadata confirms document availability.
* @param props - header owner props, localized copy, and injected document state.
* @returns the action, or null while unavailable or unresolved.
*/
@@ -29,8 +29,8 @@ export function SettingsDocumentAction({ controller, useSnapshot, t }: SettingsD
const state = useSnapshot(snapshot => snapshot)
useEffect(() => {
if (state.status === 'idle') void controller.load()
}, [controller, state.status])
void controller.load()
}, [controller])
if (state.status !== 'ready') return null

View File

@@ -17,7 +17,7 @@ import { CloseLabel, HeaderContent, TriggerContent } from './chrome.tsx'
import { GeneralSection } from './GeneralSection.tsx'
import { SettingsDocumentAction } from './SettingsDocumentAction.tsx'
import type { SettingsDocumentActionInjected } from './SettingsDocumentAction.tsx'
import { SettingsDocumentStore } from './settings-document-store.ts'
import { refreshDocumentIfLoaded, SettingsDocumentStore } from './settings-document-store.ts'
import type { WelcomeNoticeInjected } from './WelcomeNotice.tsx'
import { WelcomeNotice } from './WelcomeNotice.tsx'
import { refreshWelcomeIfLoaded, WelcomeNoticeStore } from './welcome-store.ts'
@@ -90,10 +90,13 @@ export function apply(ctx: ClientContext): void {
}
const disposers = [
ctx.on('settings/changed', refresh),
ctx.on('connection/reset', () => { refresh() }),
ctx.on('connection/reset', () => {
refresh()
refreshDocumentIfLoaded(documentController)
}),
]
return () => { for (const dispose of disposers) dispose() }
}, 'ui-settings-general: welcome invalidations')
}, 'ui-settings-general: metadata invalidations')
ctx.effect(() => {
const trigger = deferRegistration(ctx.slots, 'settings.trigger', TriggerContent, () =>
ctx.slots.register({ name: 'settings.trigger', locale: NS }, TriggerContent))

View File

@@ -5,7 +5,7 @@ import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client
/** Browser state of the Host-owned settings document. */
export interface SettingsDocumentState {
/** Metadata-loading phase; unavailable means the provider has no local file or the read failed. */
/** Metadata-loading phase; unavailable means the provider has no local document or the read failed. */
status: 'idle' | 'loading' | 'ready' | 'unavailable'
/** Whether one native-open request is in flight. */
opening: boolean
@@ -32,7 +32,7 @@ export class SettingsDocumentStore {
constructor(private readonly api: Pick<IApiClient, 'settings'>) {}
/**
* Load the current provider's optional local document path.
* Load whether the current provider owns a local document.
* @returns after the latest metadata response updates the store.
*/
async load(): Promise<void> {
@@ -52,7 +52,7 @@ export class SettingsDocumentStore {
return
}
this.store.update((state) => {
state.status = result.value.documentPath === undefined ? 'unavailable' : 'ready'
state.status = result.value.hasDocument ? 'ready' : 'unavailable'
state.error = null
})
} catch (error) {
@@ -85,3 +85,12 @@ export class SettingsDocumentStore {
}
}
}
/**
* Refresh document availability after reconnect only when a surface has already requested it.
* @param controller - optional loopback document state owner.
*/
export function refreshDocumentIfLoaded(controller: SettingsDocumentStore | undefined): void {
if (controller === undefined || controller.store.getSnapshot().status === 'idle') return
void controller.load()
}