feat: add Tauri desktop app support and terminal management

This commit is contained in:
Mohamed Boudra
2026-01-20 10:09:35 +07:00
parent 12f617dd10
commit d9c487dd54
125 changed files with 8906 additions and 1049 deletions
+104
View File
@@ -0,0 +1,104 @@
import { Platform } from "react-native";
import { useState, useEffect } from "react";
import { getIsTauriMac, TAURI_TRAFFIC_LIGHT_WIDTH, TAURI_TRAFFIC_LIGHT_HEIGHT } from "@/constants/layout";
let tauriWindow: any = null;
async function getTauriWindow() {
if (tauriWindow) return tauriWindow;
if (!getIsTauriMac()) return null;
try {
const { getCurrentWindow } = await import("@tauri-apps/api/window");
tauriWindow = getCurrentWindow();
return tauriWindow;
} catch {
return null;
}
}
export async function startDragging() {
const win = await getTauriWindow();
if (win) {
await win.startDragging();
}
}
export async function toggleMaximize() {
const win = await getTauriWindow();
if (win) {
await win.toggleMaximize();
}
}
// Returns event handlers for drag region behavior
export function useTauriDragHandlers() {
if (Platform.OS !== "web" || !getIsTauriMac()) {
return {};
}
return {
onMouseDown: (e: React.MouseEvent) => {
// Only handle left click, ignore if clicking on interactive elements
if (e.button !== 0) return;
const target = e.target as HTMLElement;
if (target.closest("button, a, input, [role='button']")) return;
// Prevent text selection when dragging
e.preventDefault();
// Start dragging on mouse down
startDragging();
},
onDoubleClick: (e: React.MouseEvent) => {
// Ignore if clicking on interactive elements
const target = e.target as HTMLElement;
if (target.closest("button, a, input, [role='button']")) return;
e.preventDefault();
toggleMaximize();
},
};
}
// Hook that returns traffic light padding, accounting for fullscreen state
// In fullscreen, traffic lights are hidden so no padding is needed
export function useTrafficLightPadding(): { left: number; top: number } {
const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => {
if (Platform.OS !== "web" || !getIsTauriMac()) return;
let unlisten: (() => void) | undefined;
async function setup() {
const win = await getTauriWindow();
if (!win) return;
// Check initial fullscreen state
const fullscreen = await win.isFullscreen();
setIsFullscreen(fullscreen);
// Listen for resize events which include fullscreen changes
unlisten = await win.onResized(async () => {
const fs = await win.isFullscreen();
setIsFullscreen(fs);
});
}
setup();
return () => {
unlisten?.();
};
}, []);
if (!getIsTauriMac() || isFullscreen) {
return { left: 0, top: 0 };
}
return {
left: TAURI_TRAFFIC_LIGHT_WIDTH,
top: TAURI_TRAFFIC_LIGHT_HEIGHT,
};
}