This commit is contained in:
Dmytro Kondakov
2025-02-22 16:30:41 +01:00
commit 531b126cf5
45 changed files with 6210 additions and 0 deletions

1
src/App.css Normal file
View File

@@ -0,0 +1 @@

45
src/App.tsx Normal file
View File

@@ -0,0 +1,45 @@
import { FolderPicker } from "./components/FolderPicker";
import { listen } from "@tauri-apps/api/event";
import { createEffect, createSignal } from "solid-js";
import { TitleBar } from "./components/TitleBar";
function App() {
const [latestImage, setLatestImage] = createSignal<string | null>(null);
createEffect(() => {
// Listen for PNG processing events
const unlisten = listen("png-processed", (event) => {
console.log("Received processed PNG");
const base64Data = event.payload as string;
setLatestImage(`data:image/png;base64,${base64Data}`);
});
return () => {
unlisten.then((fn) => fn()); // Cleanup listener
};
});
return (
<>
<TitleBar />
<main class="container pt-8">
<h1>Pick screenshots folder</h1>
<FolderPicker />
{/* Display the latest processed image */}
{latestImage() && (
<div class="mt-4">
<h3>Latest Processed Image:</h3>
<img
src={latestImage() || undefined}
alt="Latest processed"
class="max-w-md"
/>
</div>
)}
</main>
</>
);
}
export default App;

1
src/assets/logo.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 155.3"><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" fill="#76b3e1"/><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="27.5" y1="3" x2="152" y2="63.5"><stop offset=".1" stop-color="#76b3e1"/><stop offset=".3" stop-color="#dcf2fd"/><stop offset="1" stop-color="#76b3e1"/></linearGradient><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" opacity=".3" fill="url(#a)"/><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" fill="#518ac8"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="95.8" y1="32.6" x2="74" y2="105.2"><stop offset="0" stop-color="#76b3e1"/><stop offset=".5" stop-color="#4377bb"/><stop offset="1" stop-color="#1f3b77"/></linearGradient><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" opacity=".3" fill="url(#b)"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="18.4" y1="64.2" x2="144.3" y2="149.8"><stop offset="0" stop-color="#315aa9"/><stop offset=".5" stop-color="#518ac8"/><stop offset="1" stop-color="#315aa9"/></linearGradient><path d="M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z" fill="url(#c)"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="75.2" y1="74.5" x2="24.4" y2="260.8"><stop offset="0" stop-color="#4377bb"/><stop offset=".5" stop-color="#1a336b"/><stop offset="1" stop-color="#1a336b"/></linearGradient><path d="M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z" fill="url(#d)"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,48 @@
import { createSignal } from "solid-js";
import { open } from "@tauri-apps/plugin-dialog";
import { invoke } from "@tauri-apps/api/core";
export function FolderPicker() {
const [selectedPath, setSelectedPath] = createSignal<string>("");
const [status, setStatus] = createSignal<string>("");
const handleFolderSelect = async () => {
try {
const selected = await open({
directory: true,
multiple: false,
});
if (selected) {
setSelectedPath(selected as string);
// Send the path to Rust
const response = await invoke("handle_selected_folder", {
path: selected,
});
setStatus(`Folder processed: ${response}`);
}
} catch (error) {
setStatus(`Error: ${error}`);
}
};
return (
<div class="flex flex-col items-center gap-4">
<button
onClick={handleFolderSelect}
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
>
Select Folder
</button>
{selectedPath() && (
<div class="text-left max-w-md">
<p class="font-semibold">Selected folder:</p>
<p class="text-sm break-all">{selectedPath()}</p>
</div>
)}
{status() && <p class="text-sm text-gray-600">{status()}</p>}
</div>
);
}

View File

@@ -0,0 +1,7 @@
export function TitleBar() {
return (
<div class="h-8 bg-[#1a1a1a] flex items-center px-4" data-tauri-drag-region>
<div class="text-white text-sm">Haystack</div>
</div>
);
}

19
src/index.css Normal file
View File

@@ -0,0 +1,19 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

6
src/index.tsx Normal file
View File

@@ -0,0 +1,6 @@
/* @refresh reload */
import { render } from "solid-js/web";
import App from "./App";
import "./index.css";
render(() => <App />, document.getElementById("root") as HTMLElement);

1
src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />