Merges: main

This commit is contained in:
sauravniraula 2025-05-12 23:55:13 +05:45
commit 2ed0bad688
No known key found for this signature in database
GPG key ID: 60FCC1B5A5E83326
5 changed files with 44 additions and 23 deletions

View file

@ -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
View 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;
}
});
}

View file

@ -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),
});

View 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"

View file

@ -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"
/>