Restructure the Electron application by separating concerns into new modules (windows, ipc, sentinel), introduce TypeScript types for IPC, and update build configurations and entry points for desktop applications. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9203795e-937a-4306-b81d-b4d5c78c240e Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 714c0a0f-ae39-4276-a53a-1f68eb5443fa Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7c94b7a0-29c7-4f2e-94ef-44b2153872b7/9203795e-937a-4306-b81d-b4d5c78c240e/CdxgfN4 Replit-Helium-Checkpoint-Created: true
97 lines
2.3 KiB
TypeScript
97 lines
2.3 KiB
TypeScript
import { useState, CSSProperties, useEffect } from "react";
|
|
import type { AeBridge } from "../types/preload";
|
|
|
|
interface TitleBarProps {
|
|
title?: string;
|
|
}
|
|
|
|
export default function TitleBar({ title = "AeThex Terminal" }: TitleBarProps) {
|
|
const [pinned, setPinned] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const bridge = window.aeBridge;
|
|
if (bridge?.isPinned) {
|
|
bridge.isPinned().then(setPinned).catch(() => {});
|
|
}
|
|
}, []);
|
|
|
|
const call = async (method: keyof AeBridge) => {
|
|
const api = window.aeBridge;
|
|
if (!api || typeof api[method] !== "function") return;
|
|
const fn = api[method] as () => Promise<boolean>;
|
|
const res = await fn();
|
|
if (method === "togglePin") setPinned(res);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
height: 36,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
padding: "0 12px",
|
|
background: "#050814",
|
|
color: "#9ca3af",
|
|
WebkitAppRegion: "drag",
|
|
borderBottom: "1px solid #0f172a",
|
|
letterSpacing: "0.08em",
|
|
fontSize: 12,
|
|
} as CSSProperties}
|
|
>
|
|
<div style={{ fontFamily: "Space Mono, monospace" }}>{title}</div>
|
|
<div
|
|
style={{
|
|
marginLeft: "auto",
|
|
display: "flex",
|
|
gap: 8,
|
|
WebkitAppRegion: "no-drag",
|
|
} as CSSProperties}
|
|
>
|
|
<button
|
|
onClick={() => call("togglePin")}
|
|
style={btnStyle(pinned ? "#38bdf8" : "#1f2937")}
|
|
title="Pin / Unpin"
|
|
>
|
|
{pinned ? "📌" : "Pin"}
|
|
</button>
|
|
<button
|
|
onClick={() => call("minimize")}
|
|
style={btnStyle("#1f2937")}
|
|
title="Minimize"
|
|
>
|
|
—
|
|
</button>
|
|
<button
|
|
onClick={() => call("maximize")}
|
|
style={btnStyle("#1f2937")}
|
|
title="Maximize / Restore"
|
|
>
|
|
▢
|
|
</button>
|
|
<button
|
|
onClick={() => call("close")}
|
|
style={btnStyle("#ef4444")}
|
|
title="Close"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function btnStyle(bg: string): CSSProperties {
|
|
return {
|
|
border: "1px solid #111827",
|
|
background: bg,
|
|
color: "#e5e7eb",
|
|
borderRadius: 6,
|
|
padding: "4px 8px",
|
|
cursor: "pointer",
|
|
fontSize: 12,
|
|
minWidth: 36,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
};
|
|
}
|