feat: custom title bar that is more compact
This commit is contained in:
173
src/main/main.ts
173
src/main/main.ts
@@ -8,6 +8,7 @@ import { eq } from 'drizzle-orm';
|
||||
import { getMediaEngine } from './engine/MediaEngine';
|
||||
import { getPostEngine } from './engine/PostEngine';
|
||||
import { PreviewServer } from './engine/PreviewServer';
|
||||
import { APP_MENU_ACTION_EVENT_MAP, APP_MENU_GROUPS, type AppMenuAction, type AppMenuItemDefinition } from './shared/menuCommands';
|
||||
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
let previewServer: PreviewServer | null = null;
|
||||
@@ -58,7 +59,7 @@ function createWindow(): void {
|
||||
symbolColor: '#cccccc',
|
||||
height: 34,
|
||||
},
|
||||
autoHideMenuBar: true,
|
||||
autoHideMenuBar: false,
|
||||
}),
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
@@ -169,32 +170,67 @@ async function startPreviewServerOnAppStart(): Promise<void> {
|
||||
}
|
||||
|
||||
function createApplicationMenu(): Menu {
|
||||
const commandDefinitions = APP_MENU_GROUPS
|
||||
.flatMap(group => group.items)
|
||||
.filter(item => !item.separator)
|
||||
.reduce<Record<string, AppMenuItemDefinition>>((acc, item) => {
|
||||
acc[item.action] = item;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const triggerMenuAction = (action: AppMenuAction): void => {
|
||||
const channel = APP_MENU_ACTION_EVENT_MAP[action];
|
||||
if (channel) {
|
||||
mainWindow?.webContents.send(channel);
|
||||
}
|
||||
};
|
||||
|
||||
const buildSharedMenuItem = (action: AppMenuAction): MenuItemConstructorOptions => {
|
||||
const definition = commandDefinitions[action];
|
||||
if (!definition) {
|
||||
throw new Error(`Unknown shared menu action: ${action}`);
|
||||
}
|
||||
|
||||
if (definition.role) {
|
||||
return {
|
||||
label: definition.label,
|
||||
role: definition.role,
|
||||
accelerator: definition.accelerator,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
label: definition.label,
|
||||
accelerator: definition.accelerator,
|
||||
click: () => {
|
||||
triggerMenuAction(action);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const buildSharedGroupMenuItems = (groupLabel: string): MenuItemConstructorOptions[] => {
|
||||
const group = APP_MENU_GROUPS.find(item => item.label === groupLabel);
|
||||
if (!group) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return group.items.map((item) => {
|
||||
if (item.separator) {
|
||||
return { type: 'separator' };
|
||||
}
|
||||
|
||||
return buildSharedMenuItem(item.action as AppMenuAction);
|
||||
});
|
||||
};
|
||||
|
||||
const template: MenuItemConstructorOptions[] = [
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'New Post',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:newPost');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Import Media...',
|
||||
accelerator: 'CmdOrCtrl+I',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:importMedia');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('newPost'),
|
||||
buildSharedMenuItem('importMedia'),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Save',
|
||||
accelerator: 'CmdOrCtrl+S',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:save');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('save'),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Open in Browser',
|
||||
@@ -226,65 +262,12 @@ function createApplicationMenu(): Menu {
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{ role: 'undo' },
|
||||
{ role: 'redo' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'cut' },
|
||||
{ role: 'copy' },
|
||||
{ role: 'paste' },
|
||||
{ role: 'delete' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'selectAll' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Find',
|
||||
accelerator: 'CmdOrCtrl+F',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:find');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Replace',
|
||||
accelerator: 'CmdOrCtrl+H',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:replace');
|
||||
},
|
||||
},
|
||||
],
|
||||
submenu: buildSharedGroupMenuItems('Edit'),
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Posts',
|
||||
accelerator: 'CmdOrCtrl+1',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:viewPosts');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Media',
|
||||
accelerator: 'CmdOrCtrl+2',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:viewMedia');
|
||||
},
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Toggle Sidebar',
|
||||
accelerator: 'CmdOrCtrl+B',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:toggleSidebar');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Toggle Panel',
|
||||
accelerator: 'CmdOrCtrl+J',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:togglePanel');
|
||||
},
|
||||
},
|
||||
...buildSharedGroupMenuItems('View'),
|
||||
{ type: 'separator' },
|
||||
{ role: 'reload' },
|
||||
{ role: 'forceReload' },
|
||||
@@ -306,13 +289,7 @@ function createApplicationMenu(): Menu {
|
||||
{
|
||||
label: 'Blog',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Publish Selected',
|
||||
accelerator: 'CmdOrCtrl+Shift+P',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:publishSelected');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('publishSelected'),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Preview Post',
|
||||
@@ -328,36 +305,16 @@ function createApplicationMenu(): Menu {
|
||||
},
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Rebuild Database from Files',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:rebuildDatabase');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Reindex Search Text',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:reindexText');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('rebuildDatabase'),
|
||||
buildSharedMenuItem('reindexText'),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Metadata Diff Tool',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:metadataDiff');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('metadataDiff'),
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About Blogging Desktop Server',
|
||||
click: () => {
|
||||
mainWindow?.webContents.send('menu:about');
|
||||
},
|
||||
},
|
||||
buildSharedMenuItem('about'),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'View on GitHub',
|
||||
|
||||
Reference in New Issue
Block a user