fix(desktop): polish editor chrome

This commit is contained in:
webadderall
2026-03-28 23:24:34 +11:00
parent 9dd67717bc
commit bc54b2a8c9
5 changed files with 68 additions and 44 deletions
+19 -17
View File
@@ -179,25 +179,27 @@ function sendEditorMenuAction(
function setupApplicationMenu() {
const isMac = process.platform === "darwin";
const template: Electron.MenuItemConstructorOptions[] = [];
if (isMac) {
template.push({
label: app.name,
submenu: [
{ role: "about" },
{ type: "separator" },
{ role: "services" },
{ type: "separator" },
{ role: "hide" },
{ role: "hideOthers" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit" },
],
});
if (!isMac) {
Menu.setApplicationMenu(null);
return;
}
const template: Electron.MenuItemConstructorOptions[] = [];
template.push({
label: app.name,
submenu: [
{ role: "about" },
{ type: "separator" },
{ role: "services" },
{ type: "separator" },
{ role: "hide" },
{ role: "hideOthers" },
{ role: "unhide" },
{ type: "separator" },
{ role: "quit" },
],
});
template.push(
{
label: "File",
@@ -6,6 +6,7 @@
#include <mfreadwrite.h>
#include <d3d11.h>
#include <wrl/client.h>
#include <mutex>
#include <string>
#include <vector>
@@ -32,4 +33,5 @@ private:
int height_ = 0;
int fps_ = 60;
bool initialized_ = false;
std::mutex mutex_;
};
+10 -3
View File
@@ -397,11 +397,17 @@ export function hideUpdateToastWindow(): void {
export function createEditorWindow(): BrowserWindow {
const isMac = process.platform === "darwin";
const { width, height } = getScreen().getPrimaryDisplay().workAreaSize;
const { workArea, workAreaSize } = getScreen().getPrimaryDisplay();
const initialWidth = isMac ? Math.round(workAreaSize.width * 0.85) : workArea.width;
const initialHeight = isMac ? Math.round(workAreaSize.height * 0.85) : workArea.height;
const win = new BrowserWindow({
width: Math.round(width * 0.85),
height: Math.round(height * 0.85),
width: initialWidth,
height: initialHeight,
...(!isMac && {
x: workArea.x,
y: workArea.y,
}),
minWidth: 800,
minHeight: 600,
...(process.platform !== "darwin" && {
@@ -411,6 +417,7 @@ export function createEditorWindow(): BrowserWindow {
titleBarStyle: "hiddenInset",
trafficLightPosition: { x: 12, y: 12 },
}),
autoHideMenuBar: !isMac,
transparent: false,
resizable: true,
alwaysOnTop: false,
+7 -4
View File
@@ -19,6 +19,7 @@ const RECORDLY_ISSUES_URL = "https://github.com/webadderall/Recordly/issues";
const RECORDLY_X_URL = "https://x.com/webadderall";
const CONTACT_EMAIL = "youngchen3442@gmail.com";
export const APP_HEADER_ACTION_BUTTON_CLASS = "h-7 px-2 text-xs text-slate-400 hover:bg-white/10 hover:text-slate-200 transition-all gap-1.5";
export const APP_HEADER_ICON_BUTTON_CLASS = "h-7 w-7 p-0 text-slate-400 hover:bg-white/10 hover:text-slate-200 transition-all";
async function openExternalLink(url: string, errorMessage: string) {
try {
@@ -40,10 +41,11 @@ export function FeedbackDialog() {
<Button
variant="ghost"
size="sm"
className={APP_HEADER_ACTION_BUTTON_CLASS}
className={APP_HEADER_ICON_BUTTON_CLASS}
title={t("feedback.trigger", "Feedback")}
aria-label={t("feedback.trigger", "Feedback")}
>
<MessageSquareMore className="h-3.5 w-3.5" />
<span className="font-medium">{t("feedback.trigger", "Feedback")}</span>
</Button>
</DialogTrigger>
<DialogContent className="max-w-lg bg-[#09090b] border-white/10 [&>button]:text-slate-400 [&>button:hover]:text-white">
@@ -129,10 +131,11 @@ export function KeyboardShortcutsDialog() {
<Button
variant="ghost"
size="sm"
className={APP_HEADER_ACTION_BUTTON_CLASS}
className={APP_HEADER_ICON_BUTTON_CLASS}
title={t("keyboardShortcuts.trigger", "Shortcuts")}
aria-label={t("keyboardShortcuts.trigger", "Shortcuts")}
>
<Keyboard className="h-3.5 w-3.5" />
<span className="font-medium">{t("keyboardShortcuts.trigger", "Shortcuts")}</span>
</Button>
</DialogTrigger>
<DialogContent className="max-w-lg bg-[#09090b] border-white/10 [&>button]:text-slate-400 [&>button:hover]:text-white">
+30 -20
View File
@@ -4,7 +4,6 @@ import {
Captions,
Download,
FolderOpen,
Languages,
MousePointer2,
Redo2,
Save,
@@ -62,7 +61,7 @@ import {
} from "./projectPersistence";
import { type EditorEffectSection, SettingsPanel } from "./SettingsPanel";
import {
APP_HEADER_ACTION_BUTTON_CLASS,
APP_HEADER_ICON_BUTTON_CLASS,
FeedbackDialog,
KeyboardShortcutsDialog,
} from "./TutorialHelp";
@@ -289,18 +288,20 @@ function LanguageSwitcher() {
variant="ghost"
size="sm"
onClick={() => setLocale(next)}
className={APP_HEADER_ACTION_BUTTON_CLASS}
className="h-7 rounded-[5px] px-2 text-[11px] font-semibold leading-none text-slate-300 hover:bg-white/10 hover:text-white transition-all"
title={t("common.app.language", "Language")}
aria-label={t("common.app.language", "Language")}
>
<Languages className="h-4 w-4" />
<span className="font-medium">{labels[locale] ?? locale.toUpperCase()}</span>
<span className="leading-none">{labels[locale] ?? locale.toUpperCase()}</span>
</Button>
);
}
export default function VideoEditor() {
const { t } = useI18n();
const [appPlatform, setAppPlatform] = useState<string>(
typeof navigator !== "undefined" && /Mac/i.test(navigator.platform) ? "darwin" : "",
);
const initialEditorPreferences = useMemo(() => loadEditorPreferences(), []);
const [videoPath, setVideoPath] = useState<string | null>(null);
const [videoSourcePath, setVideoSourcePath] = useState<string | null>(null);
@@ -416,6 +417,7 @@ export default function VideoEditor() {
const [lastSavedSnapshot, setLastSavedSnapshot] = useState<EditorProjectData | null>(null);
const [showCropModal, setShowCropModal] = useState(false);
const [previewVersion, setPreviewVersion] = useState(0);
const headerLeftControlsPaddingClass = appPlatform === "darwin" ? "pl-[76px]" : "";
const videoPlaybackRef = useRef<VideoPlaybackRef>(null);
const projectBrowserTriggerRef = useRef<HTMLButtonElement | null>(null);
@@ -438,6 +440,12 @@ export default function VideoEditor() {
const cropSnapshotRef = useRef<CropRegion | null>(null);
const mp4SupportRequestRef = useRef(0);
const [historyVersion, setHistoryVersion] = useState(0);
useEffect(() => {
void window.electronAPI.getPlatform().then((platform) => {
setAppPlatform(platform);
});
}, []);
const [supportedMp4SourceDimensions, setSupportedMp4SourceDimensions] =
useState<SupportedMp4Dimensions>({
width: 1920,
@@ -2949,17 +2957,11 @@ export default function VideoEditor() {
return (
<div className="flex flex-col h-screen bg-[#111113] text-slate-200 overflow-hidden selection:bg-[#2563EB]/30">
<div
className="relative h-11 flex-shrink-0 bg-[#151518]/88 backdrop-blur-md border-b border-white/10 flex items-center justify-center px-8 z-50"
className="relative flex h-11 flex-shrink-0 items-center justify-between bg-[#151518]/88 px-5 backdrop-blur-md border-b border-white/10 z-50"
style={{ WebkitAppRegion: "drag" } as React.CSSProperties}
>
<div className="flex items-baseline gap-0">
<span className="text-sm font-semibold tracking-tight text-white/90">
{projectDisplayName}
</span>
<span className="text-xs font-medium tracking-tight text-slate-500">.recordly</span>
</div>
<div
className="absolute left-[88px] flex items-center gap-2"
className={`flex items-center gap-1.5 justify-self-start ${headerLeftControlsPaddingClass}`}
style={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
>
<LanguageSwitcher />
@@ -2968,7 +2970,7 @@ export default function VideoEditor() {
variant="ghost"
size="sm"
onClick={() => void openRecordingsFolder()}
className={`${APP_HEADER_ACTION_BUTTON_CLASS} px-2.5`}
className={APP_HEADER_ICON_BUTTON_CLASS}
title={t("common.app.manageRecordings", "Open recordings folder")}
aria-label={t("common.app.manageRecordings", "Open recordings folder")}
>
@@ -2977,11 +2979,6 @@ export default function VideoEditor() {
<KeyboardShortcutsDialog />
<FeedbackDialog />
<div className="ml-1 h-5 w-px bg-white/10" />
</div>
<div
className="absolute right-5 flex items-center gap-2 pr-3"
style={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
>
<Button
type="button"
variant="ghost"
@@ -3004,7 +3001,20 @@ export default function VideoEditor() {
>
<Redo2 className="h-4 w-4" />
</Button>
<div className="mx-1 h-5 w-px bg-white/10" />
</div>
<div
className="pointer-events-none absolute left-1/2 flex min-w-0 -translate-x-1/2 items-baseline justify-center gap-0"
style={{ WebkitAppRegion: "drag" } as React.CSSProperties}
>
<span className="text-sm font-semibold tracking-tight text-white/90">
{projectDisplayName}
</span>
<span className="text-xs font-medium tracking-tight text-slate-500">.recordly</span>
</div>
<div
className="flex items-center gap-2 justify-self-end pr-3"
style={{ WebkitAppRegion: "no-drag" } as React.CSSProperties}
>
<Button
ref={projectBrowserTriggerRef}
type="button"