mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
87aea21184
There was still some flicker when nohover took effect before the tab view actually switched. Now, we override the active tab in the tabbar when the app is switching tabs. We also override active tab behavior so that the close button is always visible while nohover is in effect. This effectively removes the flickering
194 lines
7.0 KiB
TypeScript
194 lines
7.0 KiB
TypeScript
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { App } from "@/app/app";
|
|
import {
|
|
registerControlShiftStateUpdateHandler,
|
|
registerElectronReinjectKeyHandler,
|
|
registerGlobalKeys,
|
|
} from "@/app/store/keymodel";
|
|
import { modalsModel } from "@/app/store/modalmodel";
|
|
import { FileService } from "@/app/store/services";
|
|
import { RpcApi } from "@/app/store/wshclientapi";
|
|
import { initWshrpc, TabRpcClient } from "@/app/store/wshrpcutil";
|
|
import { loadMonaco } from "@/app/view/codeeditor/codeeditor";
|
|
import { getLayoutModelForStaticTab } from "@/layout/index";
|
|
import {
|
|
atoms,
|
|
countersClear,
|
|
countersPrint,
|
|
getApi,
|
|
globalStore,
|
|
initGlobal,
|
|
initGlobalWaveEventSubs,
|
|
loadConnStatus,
|
|
overrideStaticTabAtom,
|
|
pushFlashError,
|
|
pushNotification,
|
|
removeNotificationById,
|
|
subscribeToConnEvents,
|
|
} from "@/store/global";
|
|
import * as WOS from "@/store/wos";
|
|
import { loadFonts } from "@/util/fontutil";
|
|
import { setKeyUtilPlatform } from "@/util/keyutil";
|
|
import { createElement } from "react";
|
|
import { createRoot } from "react-dom/client";
|
|
|
|
const platform = getApi().getPlatform();
|
|
document.title = `Wave Terminal`;
|
|
let savedInitOpts: WaveInitOpts = null;
|
|
|
|
(window as any).WOS = WOS;
|
|
(window as any).globalStore = globalStore;
|
|
(window as any).globalAtoms = atoms;
|
|
(window as any).RpcApi = RpcApi;
|
|
(window as any).isFullScreen = false;
|
|
(window as any).countersPrint = countersPrint;
|
|
(window as any).countersClear = countersClear;
|
|
(window as any).getLayoutModelForStaticTab = getLayoutModelForStaticTab;
|
|
(window as any).pushFlashError = pushFlashError;
|
|
(window as any).pushNotification = pushNotification;
|
|
(window as any).removeNotificationById = removeNotificationById;
|
|
(window as any).modalsModel = modalsModel;
|
|
|
|
async function initBare() {
|
|
getApi().sendLog("Init Bare");
|
|
document.body.style.visibility = "hidden";
|
|
document.body.style.opacity = "0";
|
|
document.body.classList.add("is-transparent");
|
|
getApi().onWaveInit(initWaveWrap);
|
|
setKeyUtilPlatform(platform);
|
|
loadFonts();
|
|
document.fonts.ready.then(() => {
|
|
console.log("Init Bare Done");
|
|
getApi().setWindowInitStatus("ready");
|
|
});
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", initBare);
|
|
|
|
async function initWaveWrap(initOpts: WaveInitOpts) {
|
|
try {
|
|
if (savedInitOpts) {
|
|
await reinitWave();
|
|
return;
|
|
}
|
|
savedInitOpts = initOpts;
|
|
await initWave(initOpts);
|
|
} catch (e) {
|
|
getApi().sendLog("Error in initWave " + e.message);
|
|
console.error("Error in initWave", e);
|
|
} finally {
|
|
document.body.style.visibility = null;
|
|
document.body.style.opacity = null;
|
|
document.body.classList.remove("is-transparent");
|
|
}
|
|
}
|
|
|
|
async function reinitWave() {
|
|
console.log("Reinit Wave");
|
|
getApi().sendLog("Reinit Wave");
|
|
|
|
// We use this hack to prevent a flicker of the previously-hovered tab when this view was last active. This class is set in setActiveTab in global.ts. See tab.scss for where this class is used.
|
|
// Also overrides the staticTabAtom to the new tab id so that the active tab is set correctly.
|
|
globalStore.set(overrideStaticTabAtom, savedInitOpts.tabId);
|
|
setTimeout(() => {
|
|
document.body.classList.remove("nohover");
|
|
}, 100);
|
|
|
|
const client = await WOS.reloadWaveObject<Client>(WOS.makeORef("client", savedInitOpts.clientId));
|
|
const waveWindow = await WOS.reloadWaveObject<WaveWindow>(WOS.makeORef("window", savedInitOpts.windowId));
|
|
const ws = await WOS.reloadWaveObject<Workspace>(WOS.makeORef("workspace", waveWindow.workspaceid));
|
|
const initialTab = await WOS.reloadWaveObject<Tab>(WOS.makeORef("tab", savedInitOpts.tabId));
|
|
await WOS.reloadWaveObject<LayoutState>(WOS.makeORef("layout", initialTab.layoutstate));
|
|
reloadAllWorkspaceTabs(ws);
|
|
document.title = `Wave Terminal - ${initialTab.name}`; // TODO update with tab name change
|
|
getApi().setWindowInitStatus("wave-ready");
|
|
globalStore.set(atoms.reinitVersion, globalStore.get(atoms.reinitVersion) + 1);
|
|
globalStore.set(atoms.updaterStatusAtom, getApi().getUpdaterStatus());
|
|
}
|
|
|
|
function reloadAllWorkspaceTabs(ws: Workspace) {
|
|
if (ws == null || ws.tabids == null) {
|
|
return;
|
|
}
|
|
ws.tabids.forEach((tabid) => {
|
|
WOS.reloadWaveObject<Tab>(WOS.makeORef("tab", tabid));
|
|
});
|
|
}
|
|
|
|
function loadAllWorkspaceTabs(ws: Workspace) {
|
|
if (ws == null || ws.tabids == null) {
|
|
return;
|
|
}
|
|
ws.tabids.forEach((tabid) => {
|
|
WOS.getObjectValue<Tab>(WOS.makeORef("tab", tabid));
|
|
});
|
|
}
|
|
|
|
async function initWave(initOpts: WaveInitOpts) {
|
|
getApi().sendLog("Init Wave " + JSON.stringify(initOpts));
|
|
console.log(
|
|
"Wave Init",
|
|
"tabid",
|
|
initOpts.tabId,
|
|
"clientid",
|
|
initOpts.clientId,
|
|
"windowid",
|
|
initOpts.windowId,
|
|
"platform",
|
|
platform
|
|
);
|
|
initGlobal({
|
|
tabId: initOpts.tabId,
|
|
clientId: initOpts.clientId,
|
|
windowId: initOpts.windowId,
|
|
platform,
|
|
environment: "renderer",
|
|
});
|
|
(window as any).globalAtoms = atoms;
|
|
|
|
// Init WPS event handlers
|
|
const globalWS = initWshrpc(initOpts.tabId);
|
|
(window as any).globalWS = globalWS;
|
|
(window as any).TabRpcClient = TabRpcClient;
|
|
await loadConnStatus();
|
|
initGlobalWaveEventSubs();
|
|
subscribeToConnEvents();
|
|
|
|
// ensures client/window/workspace are loaded into the cache before rendering
|
|
const [client, waveWindow, initialTab] = await Promise.all([
|
|
WOS.loadAndPinWaveObject<Client>(WOS.makeORef("client", initOpts.clientId)),
|
|
WOS.loadAndPinWaveObject<WaveWindow>(WOS.makeORef("window", initOpts.windowId)),
|
|
WOS.loadAndPinWaveObject<Tab>(WOS.makeORef("tab", initOpts.tabId)),
|
|
]);
|
|
const [ws, layoutState] = await Promise.all([
|
|
WOS.loadAndPinWaveObject<Workspace>(WOS.makeORef("workspace", waveWindow.workspaceid)),
|
|
WOS.reloadWaveObject<LayoutState>(WOS.makeORef("layout", initialTab.layoutstate)),
|
|
]);
|
|
loadAllWorkspaceTabs(ws);
|
|
WOS.wpsSubscribeToObject(WOS.makeORef("workspace", waveWindow.workspaceid));
|
|
|
|
document.title = `Wave Terminal - ${initialTab.name}`; // TODO update with tab name change
|
|
|
|
registerGlobalKeys();
|
|
registerElectronReinjectKeyHandler();
|
|
registerControlShiftStateUpdateHandler();
|
|
setTimeout(loadMonaco, 30);
|
|
const fullConfig = await FileService.GetFullConfig();
|
|
console.log("fullconfig", fullConfig);
|
|
globalStore.set(atoms.fullConfigAtom, fullConfig);
|
|
console.log("Wave First Render");
|
|
let firstRenderResolveFn: () => void = null;
|
|
let firstRenderPromise = new Promise<void>((resolve) => {
|
|
firstRenderResolveFn = resolve;
|
|
});
|
|
const reactElem = createElement(App, { onFirstRender: firstRenderResolveFn }, null);
|
|
const elem = document.getElementById("main");
|
|
const root = createRoot(elem);
|
|
root.render(reactElem);
|
|
await firstRenderPromise;
|
|
console.log("Wave First Render Done");
|
|
getApi().setWindowInitStatus("wave-ready");
|
|
}
|