Files
AFFiNE-Mirror/packages/frontend/electron/src/main/onboarding.ts
T
LongYinan fa8655e43e style: apply prefer-node-protocol lint rule (#5627)
it makes it perfectly clear that the package is a Node.js builtin module.
2024-01-19 03:47:08 +00:00

119 lines
3.4 KiB
TypeScript

import { join } from 'node:path';
import { BrowserWindow, type Display, screen } from 'electron';
import { isMacOS } from '../shared/utils';
import { mainWindowOrigin } from './constants';
// import { getExposedMeta } from './exposed';
import { logger } from './logger';
const getScreenSize = (display: Display) => {
const { width, height } = isMacOS() ? display.bounds : display.workArea;
return { width, height };
};
// todo: not all window need all of the exposed meta
const getWindowAdditionalArguments = async () => {
const { getExposedMeta } = await import('./exposed');
const mainExposedMeta = getExposedMeta();
return [
`--main-exposed-meta=` + JSON.stringify(mainExposedMeta),
`--window-name=onboarding`,
];
};
function fullscreenAndCenter(browserWindow: BrowserWindow) {
const position = browserWindow.getPosition();
const size = browserWindow.getSize();
const currentDisplay = screen.getDisplayNearestPoint({
x: position[0] + size[0] / 2,
y: position[1] + size[1] / 2,
});
if (!currentDisplay) return;
const { width, height } = getScreenSize(currentDisplay);
browserWindow.setSize(width, height);
browserWindow.center();
}
async function createOnboardingWindow(additionalArguments: string[]) {
logger.info('creating onboarding window');
// get user's screen size
const { width, height } = getScreenSize(screen.getPrimaryDisplay());
const browserWindow = new BrowserWindow({
width,
height,
frame: false,
show: false,
resizable: false,
closable: false,
minimizable: false,
movable: false,
titleBarStyle: 'hidden',
maximizable: false,
fullscreenable: false,
// skipTaskbar: true,
transparent: true,
hasShadow: false,
roundedCorners: false,
webPreferences: {
webgl: true,
preload: join(__dirname, './preload.js'),
additionalArguments: additionalArguments,
},
});
// workaround for the phantom title bar on windows when losing focus
// see https://github.com/electron/electron/issues/39959#issuecomment-1758736966
browserWindow.on('focus', () => {
browserWindow.setBackgroundColor('#00000000');
});
browserWindow.on('blur', () => {
browserWindow.setBackgroundColor('#00000000');
});
browserWindow.on('ready-to-show', () => {
// forcing zoom factor to 1 to avoid onboarding display issues
browserWindow.webContents.setZoomFactor(1);
fullscreenAndCenter(browserWindow);
// TODO: add a timeout to avoid flickering, window is ready, but dom is not ready
setTimeout(() => {
browserWindow.show();
}, 300);
});
// When moved to another screen, resize to fit the screen
browserWindow.on('moved', () => {
fullscreenAndCenter(browserWindow);
});
await browserWindow.loadURL(
`${mainWindowOrigin}${mainWindowOrigin.endsWith('/') ? '' : '/'}onboarding`
);
return browserWindow;
}
let onBoardingWindow$: Promise<BrowserWindow> | undefined;
export async function getOrCreateOnboardingWindow() {
const additionalArguments = await getWindowAdditionalArguments();
if (
!onBoardingWindow$ ||
(await onBoardingWindow$.then(w => w.isDestroyed()))
) {
onBoardingWindow$ = createOnboardingWindow(additionalArguments);
}
return onBoardingWindow$;
}
export async function getOnboardingWindow() {
if (!onBoardingWindow$) return;
const window = await onBoardingWindow$;
if (window.isDestroyed()) return;
return window;
}