mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 14:55:37 +00:00
fix(desktop): polish editor chrome
This commit is contained in:
+19
-17
@@ -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
@@ -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,
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user