tauri - cleanup

This commit is contained in:
babayaga 2025-09-18 12:44:22 +02:00
parent 18d5c6f8f5
commit 45c0ba14aa
12 changed files with 222 additions and 163 deletions

Binary file not shown.

View File

@ -7,7 +7,7 @@
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"dist": "npm run tauri build",
"dist": "npm run tauri build -- --debug",
"tauri": "tauri"
},
"dependencies": {

View File

@ -1,2 +1,3 @@
npm run dist
cp src-tauri/target/release/tauri-app.exe ../../dist/win-64
# cp src-tauri/target/release/tauri-app.exe ../../dist/win-64
cp src-tauri/target/debug/tauri-app.exe ../../dist/win-64

View File

@ -117,11 +117,11 @@ dependencies = [
[[package]]
name = "async-io"
version = "2.5.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca"
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
dependencies = [
"async-lock",
"autocfg",
"cfg-if",
"concurrent-queue",
"futures-io",
@ -130,7 +130,7 @@ dependencies = [
"polling",
"rustix",
"slab",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
]
[[package]]
@ -146,9 +146,9 @@ dependencies = [
[[package]]
name = "async-process"
version = "2.4.0"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00"
checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
dependencies = [
"async-channel",
"async-io",
@ -175,9 +175,9 @@ dependencies = [
[[package]]
name = "async-signal"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1"
checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
dependencies = [
"async-io",
"async-lock",
@ -188,7 +188,7 @@ dependencies = [
"rustix",
"signal-hook-registry",
"slab",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
]
[[package]]
@ -2837,16 +2837,16 @@ dependencies = [
[[package]]
name = "polling"
version = "3.10.0"
version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829"
checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix",
"windows-sys 0.60.2",
"windows-sys 0.61.0",
]
[[package]]

View File

@ -18,9 +18,9 @@ crate-type = ["staticlib", "cdylib", "rlib"]
tauri-build = { version = "2", features = [] }
[dependencies]
tauri = { version = "2", features = ["protocol-asset"] }
tauri-plugin-opener = "2.0.0"
tauri-plugin-dialog = "2.0.0"
tauri = { version = "2", features = ["protocol-asset", "devtools"] }
tauri-plugin-opener = "2.5.0"
tauri-plugin-dialog = "2.4.0"
tauri-plugin-fs = "2.0.0"
tauri-plugin-http = "2.0.0"
serde = { version = "1", features = ["derive"] }

View File

@ -65,7 +65,7 @@ fn submit_prompt(prompt: &str, files: Vec<String>, dst: &str, window: tauri::Win
#[tauri::command]
fn log_error_to_console(error: &str) {
eprintln!("[WebView ERROR forwarded from JS]: {}", error);
eprintln!("[WebView ERROR forwarded]: {}", error);
}
#[tauri::command]
@ -305,6 +305,12 @@ pub fn run() {
generate_image_via_backend
])
.setup(|app| {
#[cfg(debug_assertions)] // only include this code on debug builds
{
let window = app.get_webview_window("main").unwrap();
window.open_devtools();
}
let app_handle = app.handle().clone();
// Listen for stdin commands from images.ts

View File

@ -4,3 +4,4 @@
fn main() {
tauri_app_lib::run()
}

View File

@ -52,6 +52,28 @@ function App() {
await tauriApi.addDebugMessage(message, level, data);
};
const addImageFromUrl = async (url: string) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
const blob = await response.blob();
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result as string;
const newImageFile: ImageFile = {
path: `url_${Date.now()}.jpg`,
src: base64data,
};
setFiles(prevFiles => [...prevFiles, newImageFile]);
};
} catch (error) {
console.error('Failed to add image from URL:', error);
}
};
useTauriListeners({
setPrompt,
setDst,
@ -427,6 +449,7 @@ function App() {
isGenerating={isGenerating}
saveAndClose={saveAndClose}
submit={submit}
addImageFromUrl={addImageFromUrl}
/>
{/* Debug Panel */}

View File

@ -43,7 +43,7 @@ const DebugPanel: React.FC<DebugPanelProps> = ({
onClick={() => sendIPCMessage('test-message', { content: 'Hello from GUI', timestamp: Date.now() })}
className="glass-button text-sm px-4 py-2 rounded-lg border-blue-400/50 text-blue-600 hover:bg-blue-500/20"
>
Send IPC
Send IPC - DEPRECATED
</button>
<button
onClick={clearDebugMessages}

View File

@ -104,11 +104,11 @@ export default function ImageGallery({
<div className="flex flex-col">
{/* Main Image Display - Compact */}
<div className="flex items-center justify-center rounded-lg mb-4">
<div className="relative max-w-full max-h-[200px] flex items-center justify-center">
<div className="relative w-full h-[200px] flex items-center justify-center">
<img
src={currentImage.src}
alt={currentImage.path}
className={`max-w-full max-h-full object-contain rounded-lg shadow-lg border-2 transition-all duration-300 cursor-pointer ${
className={`h-[200px] object-contain rounded-lg shadow-lg border-2 transition-all duration-300 cursor-pointer ${
isSelected
? 'border-blue-400 shadow-blue-400/30'
: isGenerated
@ -118,10 +118,10 @@ export default function ImageGallery({
onDoubleClick={() => openLightbox(currentIndex)}
title="Double-click for fullscreen"
/>
<div className="absolute top-2 left-2 flex flex-col gap-2">
{/* Compact overlays */}
{isGenerated && isSelected && (
<div className="absolute top-2 left-2 bg-blue-500 text-white px-2 py-1 rounded text-xs font-semibold shadow-lg flex items-center gap-1">
<div className="bg-blue-500 text-white px-2 py-1 rounded text-xs font-semibold shadow-lg flex items-center gap-1">
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
@ -130,12 +130,13 @@ export default function ImageGallery({
)}
{isGenerated && !isSelected && (
<div className="absolute top-2 left-2 bg-green-500 text-white px-2 py-1 rounded text-xs font-semibold shadow-lg">
<div className="bg-green-500 text-white px-2 py-1 rounded text-xs font-semibold shadow-lg">
</div>
)}
</div>
</div>
</div>
{/* Compact Image Info */}
<div className="text-center mb-3">
@ -217,7 +218,7 @@ export default function ImageGallery({
className="fixed inset-0 bg-black/95 z-[9999] flex items-center justify-center"
onClick={() => setLightboxOpen(false)}
>
<div className="relative max-w-[95vw] max-h-[95vh] flex items-center justify-center">
<div className="relative w-full h-full flex items-center justify-center">
{lightboxLoaded ? (
<img
src={images[currentIndex].src}

View File

@ -17,6 +17,7 @@ interface PromptFormProps {
isGenerating: boolean;
saveAndClose: () => void;
submit: () => void;
addImageFromUrl: (url: string) => void;
}
const PromptForm: React.FC<PromptFormProps> = ({
@ -34,6 +35,7 @@ const PromptForm: React.FC<PromptFormProps> = ({
isGenerating,
saveAndClose,
submit,
addImageFromUrl,
}) => {
return (
<form
@ -86,13 +88,25 @@ const PromptForm: React.FC<PromptFormProps> = ({
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Source Images
</label>
<div className="flex gap-3">
<button
type="button"
onClick={openFilePicker}
className="w-full glass-button font-semibold py-4 px-6 rounded-xl border-dashed border-2 border-slate-300/50 dark:border-slate-600/50 hover:border-slate-400/60 dark:hover:border-slate-500/60"
className="w-full glass-button font-semibold py-4 px-6 rounded-xl border-dashed border-2 border-slate-300/50 dark:border-slate-600/50 hover:border-slate-400/60 dark:hover-border-slate-500/60"
>
📸 Select Images to Edit
</button>
<button
type="button"
onClick={() => addImageFromUrl('https://picsum.photos/640/640')}
className="glass-button font-semibold py-4 px-5 rounded-xl whitespace-nowrap"
title="Add random image from URL"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
</button>
</div>
</div>
</div>

View File

@ -9,6 +9,7 @@ let writeFile: any;
let BaseDirectory: any;
let listen: any;
let getCurrentWindow: any;
let fetch: any;
let isTauri = false;
const isBrowser = typeof window !== 'undefined';
@ -36,10 +37,17 @@ const apiInitializationPromise = (async () => {
readFile = fsApi.readFile;
writeFile = fsApi.writeFile;
BaseDirectory = fsApi.BaseDirectory;
const httpApi = await import('@tauri-apps/plugin-http');
fetch = httpApi.fetch;
} catch (e) {
console.warn('Tauri APIs not available, running in browser mode.');
isTauri = false;
}
if (isBrowser && !fetch) {
fetch = window.fetch;
}
})();
export const ensureTauriApi = async () => {
@ -68,6 +76,11 @@ export { invoke, isTauri };
export const tauriApi = {
ensureTauriApi,
isTauri: () => isTauri,
fetch: async (...args: Parameters<typeof window.fetch>): Promise<Response> => {
await ensureTauriApi();
const fetchFn = fetch || window.fetch;
return fetchFn(...args);
},
listen: async (...args: Parameters<typeof listen>) => {
await ensureTauriApi();
return listen ? listen(...args) : () => {};