eigent/electron/main/appShellReadinessGate.ts
Douglas Lai 8f4f575db9
feat: add native menus, shortcuts, and window chrome (#1858)
Co-authored-by: 4pmtong <web_chentong@163.com>
2026-08-21 20:39:55 +08:00

54 lines
1.9 KiB
TypeScript

// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
export interface AppShellReadinessGateOptions {
announceReadyProbe: () => void;
}
/**
* Rejects lifecycle messages from a document until Electron confirms that the
* current navigation finished loading. The probe asks a renderer that may have
* announced readiness too early to repeat its announcement after that gate
* opens.
*/
export class AppShellReadinessGate {
private documentLoaded = false;
private readonly announceReadyProbe: () => void;
constructor({ announceReadyProbe }: AppShellReadinessGateOptions) {
this.announceReadyProbe = announceReadyProbe;
}
markDocumentLoading(): void {
this.documentLoaded = false;
}
markDocumentLoaded(): void {
this.documentLoaded = true;
this.announceReadyProbe();
}
markDocumentLoadFailed(isMainFrame: boolean, errorCode: number): boolean {
// Electron -3 is ERR_ABORTED/USER_CANCELLED. The current main document is
// still usable when a provisional navigation is replaced or a subframe
// fails, so neither event may close the app-shell readiness gate.
if (!isMainFrame || errorCode === -3) return false;
this.markDocumentLoading();
return true;
}
canAcceptReady(): boolean {
return this.documentLoaded;
}
}