feat(image-viewer): integrate ImageViewer component and update FolderPicker layout

- Added ImageViewer component to the App for displaying processed images.
- Updated FolderPicker layout for improved user guidance and aesthetics.
- Refactored ShortcutItem and Shortcuts components for better structure and clarity.
- Introduced ItemModal component for future use.
This commit is contained in:
2025-04-14 09:25:53 +02:00
parent 664918f431
commit 55614b34c7
6 changed files with 85 additions and 58 deletions

View File

@ -5,6 +5,7 @@ import { Login } from "./Login";
import { ProtectedRoute } from "./ProtectedRoute"; import { ProtectedRoute } from "./ProtectedRoute";
import { Search } from "./Search"; import { Search } from "./Search";
import { Settings } from "./Settings"; import { Settings } from "./Settings";
import { ImageViewer } from "./components/ImageViewer";
export const App = () => { export const App = () => {
createEffect(() => { createEffect(() => {
@ -19,6 +20,8 @@ export const App = () => {
}); });
return ( return (
<>
<ImageViewer />
<Router> <Router>
<Route path="/login" component={Login} /> <Route path="/login" component={Login} />
@ -27,5 +30,6 @@ export const App = () => {
<Route path="/settings" component={Settings} /> <Route path="/settings" component={Settings} />
</Route> </Route>
</Router> </Router>
</>
); );
}; };

View File

@ -1,19 +1,21 @@
import { listen } from "@tauri-apps/api/event"; import { listen } from "@tauri-apps/api/event";
import { createEffect, createSignal } from "solid-js"; import { createEffect } from "solid-js";
import { sendImage } from "../network"; import { sendImage } from "../network";
import { FolderPicker } from "./folder-picker/FolderPicker";
export function ImageViewer() { export function ImageViewer() {
const [latestImage, setLatestImage] = createSignal<string | null>(null); // const [latestImage, setLatestImage] = createSignal<string | null>(null);
createEffect(() => { createEffect(async () => {
// Listen for PNG processing events // Listen for PNG processing events
const unlisten = listen("png-processed", (event) => { const unlisten = listen("png-processed", async (event) => {
console.log("Received processed PNG", event); console.log("Received processed PNG", event);
const base64Data = event.payload as string; const base64Data = event.payload as string;
setLatestImage(`data:image/png;base64,${base64Data}`); // setLatestImage(`data:image/png;base64,${base64Data}`);
sendImage("test-image.png", base64Data); const result = await sendImage("test-image.png", base64Data);
window.location.reload();
console.log("DBG: ", result);
}); });
return () => { return () => {
@ -21,20 +23,22 @@ export function ImageViewer() {
}; };
}); });
return ( return null;
<div>
<FolderPicker />
{latestImage() && ( // return (
<div class="mt-4"> // <div>
<h3>Latest Processed Image:</h3> // <FolderPicker />
<img
src={latestImage() || undefined} // {latestImage() && (
alt="Latest processed" // <div class="mt-4">
class="max-w-md" // <h3>Latest Processed Image:</h3>
/> // <img
</div> // src={latestImage() || undefined}
)} // alt="Latest processed"
</div> // class="max-w-md"
); // />
// </div>
// )}
// </div>
// );
} }

View File

@ -27,21 +27,26 @@ export function FolderPicker() {
}; };
return ( return (
<div class="flex flex-col items-center gap-4"> <div class="flex flex-col items-start gap-2">
<p class="text-sm text-neutral-700">
Select the folder where your screenshots are stored. We'll watch
this folder for any changes and process any new screenshots.
</p>
<div class="flex items-center gap-2">
<button <button
type="button" type="button"
onClick={handleFolderSelect} onClick={handleFolderSelect}
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors" class="bg-neutral-100 border border-neutral-300 rounded-md px-2 py-1"
> >
Select Folder Select folder
</button> </button>
{selectedPath() && ( {selectedPath() && (
<div class="text-left max-w-md"> <div class="text-left max-w-md">
<p class="font-semibold">Selected folder:</p>
<p class="text-sm break-all">{selectedPath()}</p> <p class="text-sm break-all">{selectedPath()}</p>
</div> </div>
)} )}
</div> </div>
</div>
); );
} }

View File

@ -0,0 +1,7 @@
export const ItemModal = () => {
return (
<div class="fixed inset-4 bg-white border border-neutral-300">
ItemModal
</div>
);
};

View File

@ -18,7 +18,7 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
return ( return (
<For each={sortedKeys}> <For each={sortedKeys}>
{(key) => ( {(key) => (
<kbd class="px-2 py-1 text-sm font-semibold rounded shadow-sm bg-neutral-100 border-neutral-300 text-neutral-900 "> <kbd class="px-2 py-1 text-sm font-semibold rounded bg-neutral-100 border border-neutral-300 text-neutral-900 ">
{formatKey(key)} {formatKey(key)}
</kbd> </kbd>
)} )}
@ -27,15 +27,15 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
}; };
return ( return (
<div class="flex items-center justify-between p-4 rounded-lg bg-neutral-5"> <div class="flex">
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
{props.isEditing ? ( {props.isEditing ? (
<> <>
<div class="flex gap-1 min-w-[120px] justify-end"> <div class="flex gap-1 min-w-[144px]">
{props.currentKeys.length > 0 ? ( {props.currentKeys.length > 0 ? (
renderKeys(props.currentKeys) renderKeys(props.currentKeys)
) : ( ) : (
<span class="italic text-neutral-500"> <span class="text-neutral-500">
Press keys... Press keys...
</span> </span>
)} )}
@ -45,14 +45,14 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
type="button" type="button"
onClick={props.onSave} onClick={props.onSave}
disabled={props.currentKeys.length < 2} disabled={props.currentKeys.length < 2}
class="px-3 py-1 text-sm rounded bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed" class="px-3 py-1 text-sm rounded bg-neutral-900 text-white"
> >
Save Save
</button> </button>
<button <button
type="button" type="button"
onClick={props.onCancel} onClick={props.onCancel}
class="p-1 rounded text-neutral-500 hover:text-neutral-700 hover:bg-neutral-200 " class="p-1 rounded text-neutral-500"
> >
<IconX class="w-4 h-4" /> <IconX class="w-4 h-4" />
</button> </button>
@ -66,7 +66,7 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
<button <button
type="button" type="button"
onClick={props.onEdit} onClick={props.onEdit}
class="px-3 py-1 text-sm rounded bg-neutral-200 text-neutral-700 hover:bg-neutral-300 " class="px-3 py-1 text-sm rounded bg-neutral-200 text-neutral-700 "
> >
Edit Edit
</button> </button>

View File

@ -58,6 +58,12 @@ export const Shortcuts = () => {
}; };
return ( return (
<div class="flex flex-col gap-2 mt-4">
<p class="text-sm text-neutral-700">
Set up a to quickly open Haystack search. This shortcut also
reloads items when updates happen (we should definetely fix
that)
</p>
<ShortcutItem <ShortcutItem
shortcut={shortcut()} shortcut={shortcut()}
isEditing={isEditing()} isEditing={isEditing()}
@ -66,5 +72,6 @@ export const Shortcuts = () => {
onSave={onSaveShortcut} onSave={onSaveShortcut}
onCancel={onCancelShortcut} onCancel={onCancelShortcut}
/> />
</div>
); );
}; };