Merges: main
This commit is contained in:
commit
2ed0bad688
5 changed files with 44 additions and 23 deletions
|
|
@ -4,7 +4,7 @@ import { setupSlideMetadataHandlers } from "./slide_metadata";
|
|||
import { setupReadFile } from "./read_file";
|
||||
import { setupFooterHandlers } from "./footer_handlers";
|
||||
import { setupThemeHandlers } from "./theme_handlers";
|
||||
|
||||
import { setupUploadImage } from "./upload_image";
|
||||
export function setupIpcHandlers() {
|
||||
setupExportHandlers();
|
||||
setupUserConfigHandlers();
|
||||
|
|
@ -12,4 +12,5 @@ export function setupIpcHandlers() {
|
|||
setupReadFile();
|
||||
setupFooterHandlers();
|
||||
setupThemeHandlers();
|
||||
setupUploadImage();
|
||||
}
|
||||
28
app/ipc/upload_image.ts
Normal file
28
app/ipc/upload_image.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { ipcMain } from "electron";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import crypto from "crypto";
|
||||
import { userDataDir } from "../utils/constants";
|
||||
|
||||
export function setupUploadImage() {
|
||||
ipcMain.handle("upload-image", async (_, file: Buffer) => {
|
||||
try {
|
||||
// Create uploads directory if it doesn't exist
|
||||
const uploadsDir = path.join(userDataDir, "uploads");
|
||||
fs.mkdirSync(uploadsDir, { recursive: true });
|
||||
|
||||
// Generate unique filename
|
||||
const filename = `${crypto.randomBytes(16).toString('hex')}.png`;
|
||||
const filePath = path.join(uploadsDir, filename);
|
||||
|
||||
// Write file to disk
|
||||
await fs.writeFileSync(filePath, file);
|
||||
|
||||
// Return the relative path that can be used in the frontend
|
||||
return filePath;
|
||||
} catch (error) {
|
||||
console.error("Error saving image:", error);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -19,4 +19,5 @@ contextBridge.exposeInMainWorld('electron', {
|
|||
setFooter: (userId: string, properties: any) => ipcRenderer.invoke("set-footer", userId, properties),
|
||||
getTheme: (userId: string) => ipcRenderer.invoke("get-theme", userId),
|
||||
setTheme: (userId: string, themeData: any) => ipcRenderer.invoke("set-theme", userId, themeData),
|
||||
uploadImage: (file: Buffer) => ipcRenderer.invoke("upload-image", file),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"setup:env": "npm install && cd servers/fastapi && poetry install && cd ../../servers/nextjs && npm install",
|
||||
"build:ts": "rm -rf app_dist && tsc",
|
||||
"build:css": "tailwindcss -i ./resources/ui/assets/css/tailwind.import.css -o ./resources/ui/assets/css/tailwind.css --watch",
|
||||
"build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && mv out ../../resources/nextjs",
|
||||
"build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && cp -r out ../../resources/nextjs",
|
||||
"build:fastapi": "rm -rf resources/fastapi && cd servers/fastapi && .venv/bin/pyinstaller --distpath ../../resources server.spec",
|
||||
"build:electron": "rm -rf app_dist && tsc && node build.js",
|
||||
"clean:build": "rm -rf resources/nextjs && rm -rf resources/fastapi && rm -rf app_dist"
|
||||
|
|
|
|||
|
|
@ -7,15 +7,12 @@ import {
|
|||
SheetTitle,
|
||||
} from "@/components/ui/sheet";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
Search,
|
||||
Wand2,
|
||||
Upload,
|
||||
Edit,
|
||||
Crop,
|
||||
Move,
|
||||
Maximize,
|
||||
} from "lucide-react";
|
||||
|
|
@ -38,6 +35,7 @@ import {
|
|||
} from "@/components/ui/popover";
|
||||
import ToolTip from "@/components/ToolTip";
|
||||
import { getEnv } from "@/utils/constant";
|
||||
import { ipcRenderer } from "electron";
|
||||
|
||||
interface ImageEditorProps {
|
||||
initialImage: string | null;
|
||||
|
|
@ -234,8 +232,6 @@ const ImageEditor = ({
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const handleFileUpload = async (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
|
|
@ -263,23 +259,20 @@ const ImageEditor = ({
|
|||
setIsUploading(true);
|
||||
setUploadError(null);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
const response = await fetch("/api/user-upload", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
// Convert file to buffer
|
||||
const buffer = await file.arrayBuffer();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Upload failed");
|
||||
}
|
||||
// Send to electron main process
|
||||
// @ts-ignore
|
||||
const relativePath = await window.electron.uploadImage(Buffer.from(buffer));
|
||||
|
||||
const data = await response.json();
|
||||
setUploadedImageUrl(data.url);
|
||||
// Update state with the returned path
|
||||
setUploadedImageUrl(relativePath);
|
||||
} catch (err) {
|
||||
const error_message = "Failed to upload image. Please try again.";
|
||||
|
||||
setUploadError(error_message);
|
||||
console.error("Upload error:", err);
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
|
|
@ -503,7 +496,7 @@ const ImageEditor = ({
|
|||
|
||||
<div className="mt-6">
|
||||
<Tabs defaultValue="generate" className="w-full">
|
||||
<TabsList className="grid bg-blue-100 border border-blue-300 w-full grid-cols-3">
|
||||
<TabsList className="grid bg-blue-100 border border-blue-300 w-full grid-cols-2 mx-auto ">
|
||||
<TabsTrigger className="font-medium" value="generate">
|
||||
AI Generate
|
||||
</TabsTrigger>
|
||||
|
|
@ -560,9 +553,7 @@ const ImageEditor = ({
|
|||
<img
|
||||
src={
|
||||
image
|
||||
? image.startsWith("user")
|
||||
? `${BASE_URL}${image}`
|
||||
: image
|
||||
? `file://${image}`
|
||||
: ""
|
||||
}
|
||||
alt={`Preview ${index + 1}`}
|
||||
|
|
@ -643,7 +634,7 @@ const ImageEditor = ({
|
|||
className="cursor-pointer group w-full h-full"
|
||||
>
|
||||
<img
|
||||
src={uploadedImageUrl}
|
||||
src={`file://${uploadedImageUrl}`}
|
||||
alt="Uploaded preview"
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform"
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue