electron#Menu TypeScript Examples

The following examples show how to use electron#Menu. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From electron-playground with MIT License 6 votes vote down vote up
export function setupMenu() {
  type MenuItemsType = MenuItemConstructorOptions[]
  const menuOption: MenuItemsType = [
    {
      label: '操作',
      submenu: [
        { role: 'about' },
        {
          label: 'check update',
          click() {
            appUpdater.manualCheck()
          },
        },
        { role: 'hide' },
        { role: 'hideOthers' },
        { role: 'quit' },
      ],
    },
    {role: 'editMenu'},
    {role: 'fileMenu'},
    {role: 'viewMenu'},
    {role: 'windowMenu'},
    // TODO: 待添加,访问官网文档,访问github,上报issue等
    // {
    //   label: 'Help',
    //   submenu: [
    //   ]
    // },
  ]
  const handleOption = Menu.buildFromTemplate(menuOption) // 构造MenuItem的选项数组。
  // 设置菜单
  // Menu.setApplicationMenu(null)
  Menu.setApplicationMenu(handleOption)

}
Example #2
Source File: main.ts    From animation-editor with MIT License 6 votes vote down vote up
app.on("ready", () => {
	Menu.setApplicationMenu(electronMenu);

	session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
		callback({
			responseHeaders: {
				...details.responseHeaders,
				// DevTools don't work when unsafe-eval is present. Commenting this out until I figure out
				// how to add a CSP without breaking DevTools or something else.
				//
				// "Content-Security-Policy": [
				// 	"default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self';",
				// ],

				// See https://developer.chrome.com/blog/enabling-shared-array-buffer/
				"Cross-Origin-Embedder-Policy": "require-corp",
				"Cross-Origin-Opener-Policy": "same-origin",
			},
		});
	});

	createElectronWindow();
});
Example #3
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Builds a menu applicable to an image.
   *
   * @return {Menu}  The `Menu`
   */
  private buildMenuForImage(menuInfo: IOnContextMenuInfo): Menu {
    const menu = new Menu();
    if (this.isSrcUrlValid(menuInfo)) {
      this.addImageItems(menu, menuInfo);
    }
    this.addInspectElement(menu, menuInfo);
    this.addDeveloperTools(menu, menuInfo);
    this.processMenu(menu, menuInfo);
    return menu;
  }
Example #4
Source File: menu.ts    From simulator with Apache License 2.0 6 votes vote down vote up
buildMenu(): Menu {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate();

    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

    return menu;
  }
Example #5
Source File: menu.ts    From amazon-chime-sdk-classroom-demo with Apache License 2.0 6 votes vote down vote up
buildMenu() {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate();

    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

    return menu;
  }
Example #6
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Builds a menu applicable to a text input field.
   *
   * @return {Menu}  The `Menu`
   */
  buildMenuForTextInput(menuInfo: IOnContextMenuInfo): Menu {
    const menu = new Menu();
    this.addSpellingItems(menu, menuInfo);
    this.addSearchItems(menu, menuInfo);
    this.addCut(menu, menuInfo);
    this.addCopy(menu, menuInfo);
    this.addPaste(menu, menuInfo);
    this.addInspectElement(menu, menuInfo);
    this.addDeveloperTools(menu, menuInfo);
    this.processMenu(menu, menuInfo);
    return menu;
  }
Example #7
Source File: menu.ts    From excalidraw-desktop with MIT License 6 votes vote down vote up
setupMenu = (activeWindow: BrowserWindow, options = {}) => {
  const isDarwin = process.platform === "darwin";
  const defaultMenuItems: MenuItem[] = Menu.getApplicationMenu().items;
  const menuTemplate = [];
  if (isDarwin) {
    defaultMenuItems.shift();
    menuTemplate.push({
      label: APP_NAME,
      submenu: [
        {
          label: `About ${APP_NAME}`,
          enabled: true,
          click: () => openAboutWindow(),
        },
      ],
    });
    menuTemplate.push(...defaultMenuItems);
  } else {
    defaultMenuItems.pop();
    menuTemplate.push(...defaultMenuItems);
    menuTemplate.push({
      label: "Help",
      submenu: [
        {
          label: `About ${APP_NAME}`,
          enabled: true,
          click: () => openAboutWindow(),
        },
      ],
    });
  }

  // TODO: Remove default menu items that aren't relevant
  const appMenu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(appMenu);
}
Example #8
Source File: index.ts    From electron-playground with MIT License 6 votes vote down vote up
// 设置顶部APP图标的操作和图标
export function setUpTray() {
  const lightIcon = path.join(__dirname, '..', '..', 'resources', 'tray', 'StatusIcon_light.png')
  const darkIcon = path.join(__dirname, '..', '..', 'resources', 'tray', 'StatusIcon_dark.png')

  tray = new Tray(nativeTheme.shouldUseDarkColors ? darkIcon : lightIcon)

  const contextMenu = Menu.buildFromTemplate([
    {
      label: '打开Playground',
      click: () => {
        restoreMainWindow()
      },
    },
    {
      label: '退出',
      click: () => {
        app.quit()
      },
    },
  ])
  tray.setToolTip('Electron-Playground')
  tray.setContextMenu(contextMenu)

  nativeTheme.on('updated', () => {
    tray.setImage(nativeTheme.shouldUseDarkColors ? darkIcon : lightIcon)
  })

  // windows下双击托盘图标打开app
  tray.on('double-click', () => {
    restoreMainWindow()
  })
}
Example #9
Source File: TrayMenu.ts    From wiregui with MIT License 6 votes vote down vote up
constructor(private readonly window: BrowserWindow, isDevelopement: boolean) {
    this.tunnels = [];
    this.isQuitting = false;

    const iconName = "icon_tray";
    const iconActiveName = "icon_tray_active";
    const isWin32 = process.platform === "win32";

    this.icon = nativeImage.createFromPath(getIconsPath(`${iconName}.${isWin32 ? "ico" : "png"}`, isDevelopement));
    this.iconActive = nativeImage.createFromPath(getIconsPath(`${iconActiveName}.${isWin32 ? "ico" : "png"}`, isDevelopement));

    this.tray = new Tray(this.icon);
    this.tray.setToolTip("Wire GUI");
    this.contextMenu = Menu.buildFromTemplate(this.mountTrayMenuItems());
    this.tray.setContextMenu(this.contextMenu);

    ipcMain.on("WgConfigStateChange", (event, args: TunnelInfo[]) => {
      this.tunnels = args;

      this.contextMenu = Menu.buildFromTemplate(this.mountTrayMenuItems());
      this.tray.setContextMenu(this.contextMenu);

      // When calling setContextMenu alongside setImage
      // For some reason electron reloads the tray image
      // With this hack this doesn't happen
      setTimeout(() => {
        this.tray.setImage(this.tunnels.some(tunnel => tunnel.active) ? this.iconActive : this.icon);
      }, 100);
    });

    window.on("close", (event) => {
      if (!this.isQuitting) {
        event.preventDefault();
        window.hide();
      }
      return false;
    });
  }
Example #10
Source File: ViewerHandler.ts    From viewer with MIT License 6 votes vote down vote up
/**
   * Changes due to connectivity status
   * @param connectivityStatus
   */
  public async setConnectivity(
    connectivityStatus: InternetConnectivityStatus
  ): Promise<void> {
    const downloadMenuItem =
      Menu.getApplicationMenu()?.getMenuItemById("download-menu-item");
    if (connectivityStatus === InternetConnectivityStatus.Offline) {
      // offline, disable the download menu item
      if (downloadMenuItem) {
        downloadMenuItem.enabled = false;
      }
    } else if (connectivityStatus === InternetConnectivityStatus.Online) {
      if (!ViewerHandler._authInitialized) {
        // we are online now and were not before so configure the auth backend
        const clientId = getAppEnvVar("CLIENT_ID") ?? "";
        const scope = getAppEnvVar("SCOPE") ?? "";
        const redirectUri = getAppEnvVar("REDIRECT_URI");
        const issuerUrl = getAppEnvVar("ISSUER_URL");

        const authClient = new ElectronMainAuthorization({
          clientId,
          scope,
          redirectUri: redirectUri || undefined, // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing
          issuerUrl: issuerUrl || undefined, // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing
        });
        await authClient.signInSilent();
        IModelHost.authorizationClient = authClient;
        ViewerHandler._authInitialized = true;
      }
      if (downloadMenuItem) {
        // online so enable the download menu item
        downloadMenuItem.enabled = true;
      }
    }
  }
Example #11
Source File: main.ts    From StraxUI with MIT License 6 votes vote down vote up
function createMenu(): void {
  const menuTemplate = [{
    label: app.getName(),
    submenu: [
      { label: 'About ' + app.getName(), selector: 'orderFrontStandardAboutPanel:' },
      {
        label: 'Quit', accelerator: 'Command+Q', click: function (): void {
          app.quit();
        }
      }
    ]
  }, {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      { label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' }
    ]
  }];
  Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate));
}
Example #12
Source File: index.ts    From Protoman with MIT License 6 votes vote down vote up
async function createWindow(): Promise<void> {
  const screenWidth = screen.getPrimaryDisplay().workAreaSize.width;
  const bounds = config.get('winBounds') as Rectangle;
  //default value
  let width = screenWidth * WIDTH_RATIO;
  let height = screenWidth * WIDTH_RATIO * ASPECT_RATIO;
  //if some value
  if (bounds != undefined) {
    width = bounds.width;
    height = bounds.height;
  }
  console.log('saved bounds ', bounds);
  window = new BrowserWindow({
    width: width,
    height: height,
    webPreferences: {
      nodeIntegration: true,
    },
  });
  initializeEvents();
  Menu.setApplicationMenu(makeMenu());
  window.loadFile(path.join(__dirname, 'index.html'));

  window.on('close', () => {
    console.log('closing the window');
    console.log('save window bounds');
    config.set('winBounds', window.getBounds());
  });
  checkUpdateAndNotify(window);
}
Example #13
Source File: uniShell.ts    From kaiheila-universal with MIT License 6 votes vote down vote up
private initializeTray(): void {
    // Initialize Tray
    if (isMac) {
      const img = nativeImage.createFromPath(this.iconPath).resize({
        width: 16,
        height: 16,
      })
      img.setTemplateImage(true)
      this.tray = new Tray(img)
    } else {
      this.tray = new Tray(this.iconPath)
    }
    this.tray.setToolTip('开黑啦')
    this.tray.setContextMenu(Menu.buildFromTemplate(this.trayMenuTemplate))
    this.tray.on('click', (): void => {
      this.mainWindow.show()
    })
  }
Example #14
Source File: menu.ts    From mysterium-vpn-desktop with MIT License 6 votes vote down vote up
createMenu = (): Menu => {
    const template: MenuItemConstructorOptions[] = [
        {
            label: packageJson.productName,
            submenu: [
                { role: "about" },
                { type: "separator" },
                { role: "hide" },
                { role: "hideOthers" },
                { role: "unhide" },
                { type: "separator" },
                { role: "quit" },
            ],
        },
        {
            label: "Edit",
            submenu: [{ role: "copy" }, { role: "paste" }],
        },
        {
            role: "window",
            submenu: [{ role: "minimize" }, { role: "close" }],
        },
    ]
    return Menu.buildFromTemplate(template)
}
Example #15
Source File: menu.ts    From deskreen with GNU Affero General Public License v3.0 6 votes vote down vote up
setupDevelopmentEnvironment(): void {
    this.mainWindow.webContents.on('context-menu', (_, props) => {
      const { x, y } = props;

      Menu.buildFromTemplate([
        {
          label: 'Inspect element',
          click: () => {
            this.mainWindow.webContents.inspectElement(x, y);
          },
        },
      ]).popup({ window: this.mainWindow });
    });
  }
Example #16
Source File: main.ts    From tabby with MIT License 6 votes vote down vote up
function createWindow(): void {

  win = new BrowserWindow({
    width: 1280,
    height: 720,
    minWidth: 1280,
    minHeight: 720,
    webPreferences: {
      nodeIntegration: true,
      allowRunningInsecureContent: (serve) ? true : false,
    },
  });

  if (process.platform !== 'darwin') {
    Menu.setApplicationMenu(null);
  }

  if (serve) {
    require('electron-reload')(__dirname, {
      electron: require(`${__dirname}/node_modules/electron`)
    });
    win.loadURL('http://localhost:4200');
  } else {
    win.loadURL(url.format({
      pathname: path.join(__dirname, 'dist/index.html'),
      protocol: 'file:',
      slashes: true
    }));
  }
}
Example #17
Source File: menu.ts    From deskreen with GNU Affero General Public License v3.0 6 votes vote down vote up
buildMenu() {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    if (process.platform === 'darwin') {
      const menu = Menu.buildFromTemplate(this.buildDarwinTemplate());
      Menu.setApplicationMenu(menu);
    } else {
      // for production, no menu for non MacOS app
      Menu.setApplicationMenu(null);
    }
  }
Example #18
Source File: desktop.ts    From shadowsocks-electron with GNU General Public License v3.0 6 votes vote down vote up
async contextMenu(actions: contextAction[]): Promise<ServiceResult> {
    return new Promise(resolve => {
      const templates = actions.map(action => {
        let a: Electron.MenuItemConstructorOptions = {
          ...action
        };
        a.click = (function(this: any) {
          resolve({
            code: 200,
            result: this.action
          });
        }).bind(a);

        return a;
      })
      Menu.buildFromTemplate(templates).popup();
    });
  }
Example #19
Source File: menu.ts    From Oratio with MIT License 6 votes vote down vote up
setupDevelopmentEnvironment(): void {
    this.mainWindow.webContents.on('context-menu', (_, props) => {
      const { x, y } = props;

      Menu.buildFromTemplate([
        {
          label: 'Inspect element',
          click: () => {
            this.mainWindow.webContents.inspectElement(x, y);
          },
        },
      ]).popup({ window: this.mainWindow });
    });
  }
Example #20
Source File: main.ts    From wiregui with MIT License 6 votes vote down vote up
createWindow = (): void => {
  // Enforce single instance.
  const gotTheLock = app.requestSingleInstanceLock();
  if (!gotTheLock) {
    app.quit();
    return;
  }

  // Create the browser window.
  const mainWindow = new BrowserWindow({
    height: 850,
    width: 1200,
    minHeight: 600,
    minWidth: 800,
    webPreferences: {
      contextIsolation: false,
      nodeIntegration: true,
    },
    icon: getIconsPath("icon.png", isDevelopement),
  });

  // and load the index.html of the app.
  mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);

  if (isDevelopement) {
    // Open the DevTools if in development mode.
    mainWindow.webContents.openDevTools();
  }

  // Create custom menus
  const trayMenu = new TrayMenu(mainWindow, isDevelopement);
  const menuBar = new MenuBar(mainWindow, trayMenu);
  const template = menuBar.generateTemplate();

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}
Example #21
Source File: index.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Rebuild or create menubar from the latest menu template, will be call after some method change the menuTemplate
   * You don't need to call this after calling method like insertMenu, it will be call automatically.
   */
  public async buildMenu(): Promise<void> {
    const latestTemplate = (await this.getCurrentMenuItemConstructorOptions(this.menuTemplate)) ?? [];
    try {
      const menu = Menu.buildFromTemplate(latestTemplate);
      Menu.setApplicationMenu(menu);
    } catch (error) {
      logger.error(`buildMenu() failed: ${(error as Error).message} ${(error as Error).stack ?? ''}\n${JSON.stringify(latestTemplate)}`);
    }
  }
Example #22
Source File: cz88-context.ts    From kliveide with MIT License 6 votes vote down vote up
/**
   * When the application state changes, you can update the menus
   */
  updateMenuStatus(state: AppState): void {
    const menu = Menu.getApplicationMenu();
    const softReset = menu.getMenuItemById(SOFT_RESET);
    if (softReset) {
      // --- Soft reset is available only if the machine is started, paused, or stopped.
      softReset.enabled = state.emulatorPanel.executionState > 0;
    }

    // --- Select the current LCD dimension
    const lcdType = menu.getMenuItemById(menuIdFromMachineId(recentLcdType));
    if (lcdType) {
      lcdType.checked = true;
    }

    // --- Select the current keyboard layout
    const keyboardId = `cz88_${
      state.emulatorPanel.keyboardLayout ?? "uk"
    }_layout`;
    const keyboardItem = menu.getMenuItemById(keyboardId);
    if (keyboardItem) {
      keyboardItem.checked = true;
    }

    // --- Enable/disable commands requiring a running machine
    const bothShifts = menu.getMenuItemById(PRESS_SHIFTS);
    if (bothShifts) {
      bothShifts.enabled = state.emulatorPanel.executionState === 1;
    }
    const batLow = menu.getMenuItemById(BATTERY_LOW);
    if (batLow) {
      batLow.enabled = state.emulatorPanel.executionState === 1;
    }
  }
Example #23
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Creates an instance of ContextMenuBuilder
   *
   * @param   webContents  The hosting window's WebView
   * @param   processMenu If passed, this method will be passed the menu to change
   *                                it prior to display. Signature: (menu, info) => menu
   */
  constructor(webContents: WebContents, processMenu = (m: Menu) => m) {
    this.processMenu = processMenu;
    this.stringTable = { ...contextMenuStringTable };
    this.webContents = webContents;
  }
Example #24
Source File: menu.ts    From ExpressLRS-Configurator with GNU General Public License v3.0 6 votes vote down vote up
buildMenu(): Menu | null {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    // const template =
    //   process.platform === 'darwin'
    //     ? this.buildDarwinTemplate()
    //     : this.buildDefaultTemplate();

    const template =
      process.platform === 'darwin' ? this.buildDarwinTemplate() : null;

    if (template !== null) {
      const menu = Menu.buildFromTemplate(template);
      Menu.setApplicationMenu(menu);
      return menu;
    }
    Menu.setApplicationMenu(null);
    return null;
  }
Example #25
Source File: background.ts    From IYUU-GUI with GNU Affero General Public License v3.0 6 votes vote down vote up
function initTray() {
  tray = new Tray(path.join(__static, 'assets/iyuu.png'))
  const contextMenu = Menu.buildFromTemplate([
    {
      label: '退出', click: () => {
        app.quit()
      }
    }
  ])

  tray.on('click', () => {
    win && win.show();
  })

  // Call this again for Linux because we modified the context menu
  tray.setContextMenu(contextMenu)
}
Example #26
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the "Inspect Element" menu item.
   */
  addInspectElement(menu: Menu, menuInfo: IOnContextMenuInfo, needsSeparator = true): Menu {
    if (needsSeparator) {
      this.addSeparator(menu);
    }
    const inspect = new MenuItem({
      label: this.stringTable.inspectElement(),
      click: () => this.webContents.inspectElement(menuInfo.x, menuInfo.y),
    });
    menu.append(inspect);
    return menu;
  }
Example #27
Source File: menu.ts    From Oratio with MIT License 6 votes vote down vote up
buildMenu(): Menu {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate();

    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

    return menu;
  }
Example #28
Source File: contextMenuBuilder.ts    From TidGi-Desktop with Mozilla Public License 2.0 6 votes vote down vote up
/**
   * Adds the Paste menu item.
   */
  addPaste(menu: Menu, menuInfo: IOnContextMenuInfo): Menu {
    menu.append(
      new MenuItem({
        label: this.stringTable.paste(),
        accelerator: 'CommandOrControl+V',
        enabled: menuInfo?.editFlags?.canPaste,
        click: () => this.webContents.paste(),
      }),
    );
    return menu;
  }
Example #29
Source File: main.ts    From uivonim with GNU Affero General Public License v3.0 5 votes vote down vote up
app.on('ready', async () => {
  const menuTemplate = [
    {
      label: 'Window',
      submenu: [
        {
          role: 'togglefullscreen',
        },
        {
          label: 'Maximize',
          click: () => win.maximize(),
        },
      ],
    },
    {
      role: 'help',
      submenu: [
        {
          label: 'Developer Tools',
          accelerator: 'CmdOrCtrl+|',
          click: () => win.webContents.toggleDevTools(),
        },
      ] as any,
    } as any,
  ]

  if (process.platform === 'darwin')
    menuTemplate.unshift({
      label: 'uivonim',
      submenu: [
        {
          role: 'about',
        },
        {
          type: 'separator',
        },
        {
          // using 'role: hide' adds cmd+h keybinding which overrides vim keybinds
          label: 'Hide uivonim',
          click: () => app.hide(),
        },
        {
          type: 'separator',
        },
        {
          role: 'quit' as any,
        },
      ] as any,
    } as any)

  Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate))

  win = new BrowserWindow({
    width: 950,
    height: 700,
    minWidth: 600,
    minHeight: 400,
    frame: true,
    titleBarStyle: 'hidden',
    backgroundColor: '#222',
    autoHideMenuBar: true,
    webPreferences: {
      // See https://github.com/reZach/secure-electron-template/blob/21eeb45cbafc7542b417e2dc58734ae158c7b3f1/app/electron/main.js#L63-L67
      nodeIntegration: false,
      nodeIntegrationInWorker: false,
      nodeIntegrationInSubFrames: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js'),
    },
  })

  win.loadURL(`file:///${__dirname}/index.html`)
  comscan.register((ch, msg) => win.webContents.send(ch, msg))

  if (process.env.NODE_ENV !== 'production' && !app.isPackaged)
    win.webContents.openDevTools()
  win.webContents.on('did-finish-load', async () => await afterReadyThings())
})