Skip to content

Commit

Permalink
Customize title bar (#1184)
Browse files Browse the repository at this point in the history
* add basic title bar

* add title bar actions

* fix layout

* update title bar

* update layout

* fix title bar for macOS

* UI

* setup menu for macOS

* fix title bar logo
  • Loading branch information
an-lee authored Nov 17, 2024
1 parent b8167a9 commit 8bebf20
Show file tree
Hide file tree
Showing 27 changed files with 771 additions and 277 deletions.
6 changes: 5 additions & 1 deletion enjoy/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,9 @@
"logoutAndRemoveAllPersonalSettings": "Logout and remove all personal settings",
"hotkeys": "Hotkeys",
"player": "Player",
"quit": "Quit",
"quitApp": "Quit APP",
"quitAppDescription": "Are you sure to quit Enjoy app?",
"openPreferences": "Open preferences",
"openCopilot": "Open copilot",
"playOrPause": "Play or pause",
Expand Down Expand Up @@ -929,5 +931,7 @@
"compressMediaBeforeAdding": "Compress media before adding",
"keepOriginalMedia": "Keep original media",
"myPronunciation": "My pronunciation",
"originalPronunciation": "Original pronunciation"
"originalPronunciation": "Original pronunciation",
"reloadApp": "reload app",
"exit": "Exit"
}
6 changes: 5 additions & 1 deletion enjoy/src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@
"hotkeys": "快捷键",
"system": "系统",
"player": "播放器",
"quit": "退出",
"quitApp": "退出应用",
"quitAppDescription": "确定要退出 Enjoy 应用吗?",
"openPreferences": "打开设置",
"openCopilot": "打开 Copilot",
"playOrPause": "播放/暂停",
Expand Down Expand Up @@ -929,5 +931,7 @@
"compressMediaBeforeAdding": "添加前压缩媒体",
"keepOriginalMedia": "保存原始媒体",
"myPronunciation": "我的发音",
"originalPronunciation": "原始发音"
"originalPronunciation": "原始发音",
"reloadApp": "重载应用",
"exit": "退出"
}
6 changes: 6 additions & 0 deletions enjoy/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
.scroll {
@apply scrollbar-thin scrollbar-thumb-primary scrollbar-track-secondary;
}
.draggable-region {
-webkit-app-region: drag;
}
.non-draggable-region {
-webkit-app-region: no-drag;
}
}

body {
Expand Down
104 changes: 102 additions & 2 deletions enjoy/src/main/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import dict from "./dict";
import mdict from "./mdict";
import decompresser from "./decompresser";
import { UserSetting } from "@main/db/models";
import { platform } from "os";
import { t } from "i18next";

const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -520,14 +522,77 @@ ${log}
preload: path.join(__dirname, "preload.js"),
spellcheck: false,
},
frame: false,
titleBarStyle: "hidden",
titleBarOverlay: process.platform === "darwin",
trafficLightPosition: {
x: 10,
y: 8,
},
useContentSize: true,
});

mainWindow.on("ready-to-show", () => {
mainWindow.show();
});

mainWindow.on("resize", () => {
mainWindow.webContents.send("window-on-resize", mainWindow.getBounds());
mainWindow.webContents.send("window-on-change", {
event: "resize",
state: mainWindow.getBounds(),
});
});

mainWindow.on("enter-full-screen", () => {
mainWindow.webContents.send("window-on-change", { event: "enter-full-screen" });
});

mainWindow.on("leave-full-screen", () => {
mainWindow.webContents.send("window-on-change", { event: "leave-full-screen" });
});

mainWindow.on("maximize", () => {
mainWindow.webContents.send("window-on-change", { event: "maximize" });
});

mainWindow.on("unmaximize", () => {
mainWindow.webContents.send("window-on-change", { event: "unmaximize" });
});

ipcMain.handle("window-is-maximized", () => {
return mainWindow.isMaximized();
});

ipcMain.handle("window-toggle-maximized", () => {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
} else {
mainWindow.maximize();
}
});

ipcMain.handle("window-maximize", () => {
mainWindow.maximize();
});

ipcMain.handle("window-unmaximize", () => {
mainWindow.unmaximize();
});

ipcMain.handle("window-fullscreen", () => {
mainWindow.setFullScreen(true);
});

ipcMain.handle("window-unfullscreen", () => {
mainWindow.setFullScreen(false);
});

ipcMain.handle("window-minimize", () => {
mainWindow.minimize();
});

ipcMain.handle("window-close", () => {
app.quit();
});

mainWindow.webContents.setWindowOpenHandler(() => {
Expand Down Expand Up @@ -571,7 +636,42 @@ ${log}
// mainWindow.webContents.openDevTools();
}

Menu.setApplicationMenu(null);
if (platform() === "darwin") {
const menu = Menu.buildFromTemplate([
{
label: app.name,
submenu: [
{ role: "about" },
{ type: "separator" },
{ role: "hide" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit" },
],
},
{
label: "&Help",
submenu: [
{
label: "Check for Updates...",
click: () => {
shell.openExternal("https://1000h.org/enjoy-app/install.html");
},
},
{
label: "Report Issue...",
click: () => {
shell.openExternal(`${REPO_URL}/issues/new`)
}
}
]
}
])

Menu.setApplicationMenu(menu);
} else {
Menu.setApplicationMenu(null);
}

main.win = mainWindow;
};
Expand Down
45 changes: 40 additions & 5 deletions enjoy/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,49 @@ contextBridge.exposeInMainWorld("__ENJOY_APP__", {
version,
},
window: {
onResize: (
isFullScreen: () => {
return ipcRenderer.invoke("window-is-full-screen");
},
toggleFullscreen: () => {
return ipcRenderer.invoke("window-fullscreen");
},
isMaximized: () => {
return ipcRenderer.invoke("window-is-maximized");
},
toggleMaximized: () => {
return ipcRenderer.invoke("window-toggle-maximized");
},
maximize: () => {
return ipcRenderer.invoke("window-maximize");
},
unmaximize: () => {
return ipcRenderer.invoke("window-unmaximize");
},
fullscreen: () => {
return ipcRenderer.invoke("window-fullscreen");
},
unfullscreen: () => {
return ipcRenderer.invoke("window-unfullscreen");
},
minimize: () => {
return ipcRenderer.invoke("window-minimize");
},
close: () => {
return ipcRenderer.invoke("window-close");
},
onChange: (
callback: (
event: IpcRendererEvent,
bounds: { x: number; y: number; width: number; height: number }
state: { event: string; state: any }
) => void
) => ipcRenderer.on("window-on-resize", callback),
removeListeners: () => {
ipcRenderer.removeAllListeners("window-on-resize");
) => ipcRenderer.on("window-on-change", callback),
removeListener: (
listener: (event: IpcRendererEvent, ...args: any[]) => void
) => {
ipcRenderer.removeListener("window-on-change", listener);
},
removeAllListeners: () => {
ipcRenderer.removeAllListeners("window-on-change");
},
},
system: {
Expand Down
4 changes: 2 additions & 2 deletions enjoy/src/renderer/components/chats/chat-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ export const ChatSession = (props: {

if (!chatId) {
return (
<div className="flex items-center justify-center h-screen">
<div className="flex items-center justify-center h-[calc(100vh-2rem)]">
<span className="text-muted-foreground">{t("noChatSelected")}</span>
</div>
);
}

return (
<ScrollArea className="h-screen relative">
<ScrollArea className="h-[calc(100vh-2rem)] relative">
<ChatSessionProvider chatId={chatId}>
<ChatHeader
sidePanelCollapsed={sidePanelCollapsed}
Expand Down
2 changes: 1 addition & 1 deletion enjoy/src/renderer/components/copilots/copilot-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const CopilotSession = () => {
const { currentChat } = useContext(CopilotProviderContext);

return (
<ScrollArea className="h-screen relative">
<ScrollArea className="h-[calc(100vh-2rem)] relative">
{currentChat?.id ? (
<ChatSessionProvider chatId={currentChat.id}>
<CopilotHeader />
Expand Down
1 change: 1 addition & 0 deletions enjoy/src/renderer/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from "./users";
export * from "./videos";
export * from "./widgets";
export * from "./login";
export * from "./layouts";
2 changes: 2 additions & 0 deletions enjoy/src/renderer/components/layouts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./layout";
export * from "./title-bar";
66 changes: 66 additions & 0 deletions enjoy/src/renderer/components/layouts/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Outlet } from "react-router-dom";
import {
AppSettingsProviderContext,
CopilotProviderContext,
} from "@renderer/context";
import { useContext } from "react";
import { CopilotSession, TitleBar, Sidebar } from "@renderer/components";
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@renderer/components/ui";

export const Layout = () => {
const { initialized } = useContext(AppSettingsProviderContext);
const { active, setActive } = useContext(CopilotProviderContext);

if (initialized) {
return (
<div className="h-screen flex flex-col">
<TitleBar />
<ResizablePanelGroup
direction="horizontal"
className="flex-1 h-full w-full"
data-testid="layout-home"
>
<ResizablePanel id="main-panel" order={1} minSize={50}>
<div className="flex flex-start">
<Sidebar />
<div className="flex-1 border-l overflow-x-hidden overflow-y-auto h-[calc(100vh-2rem)]">
<Outlet />
</div>
</div>
</ResizablePanel>
{active && (
<>
<ResizableHandle />
<ResizablePanel
id="copilot-panel"
order={2}
collapsible={true}
defaultSize={30}
maxSize={50}
minSize={15}
onCollapse={() => setActive(false)}
>
<div className="h-[calc(100vh-2rem)]">
<CopilotSession />
</div>
</ResizablePanel>
</>
)}
</ResizablePanelGroup>
</div>
);
} else {
return (
<div className="h-screen flex flex-col w-full">
<TitleBar />
<div className="flex-1 h-[calc(100vh-2rem)] overflow-y-auto">
<Outlet />
</div>
</div>
);
}
};
Loading

0 comments on commit 8bebf20

Please sign in to comment.