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:
@ -5,6 +5,7 @@ import { Login } from "./Login";
|
||||
import { ProtectedRoute } from "./ProtectedRoute";
|
||||
import { Search } from "./Search";
|
||||
import { Settings } from "./Settings";
|
||||
import { ImageViewer } from "./components/ImageViewer";
|
||||
|
||||
export const App = () => {
|
||||
createEffect(() => {
|
||||
@ -19,6 +20,8 @@ export const App = () => {
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<ImageViewer />
|
||||
<Router>
|
||||
<Route path="/login" component={Login} />
|
||||
|
||||
@ -27,5 +30,6 @@ export const App = () => {
|
||||
<Route path="/settings" component={Settings} />
|
||||
</Route>
|
||||
</Router>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,19 +1,21 @@
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { createEffect, createSignal } from "solid-js";
|
||||
import { createEffect } from "solid-js";
|
||||
import { sendImage } from "../network";
|
||||
import { FolderPicker } from "./folder-picker/FolderPicker";
|
||||
|
||||
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
|
||||
const unlisten = listen("png-processed", (event) => {
|
||||
const unlisten = listen("png-processed", async (event) => {
|
||||
console.log("Received processed PNG", event);
|
||||
const base64Data = event.payload as string;
|
||||
|
||||
setLatestImage(`data:image/png;base64,${base64Data}`);
|
||||
sendImage("test-image.png", base64Data);
|
||||
// setLatestImage(`data:image/png;base64,${base64Data}`);
|
||||
const result = await sendImage("test-image.png", base64Data);
|
||||
|
||||
window.location.reload();
|
||||
console.log("DBG: ", result);
|
||||
});
|
||||
|
||||
return () => {
|
||||
@ -21,20 +23,22 @@ export function ImageViewer() {
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FolderPicker />
|
||||
return null;
|
||||
|
||||
{latestImage() && (
|
||||
<div class="mt-4">
|
||||
<h3>Latest Processed Image:</h3>
|
||||
<img
|
||||
src={latestImage() || undefined}
|
||||
alt="Latest processed"
|
||||
class="max-w-md"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
// return (
|
||||
// <div>
|
||||
// <FolderPicker />
|
||||
|
||||
// {latestImage() && (
|
||||
// <div class="mt-4">
|
||||
// <h3>Latest Processed Image:</h3>
|
||||
// <img
|
||||
// src={latestImage() || undefined}
|
||||
// alt="Latest processed"
|
||||
// class="max-w-md"
|
||||
// />
|
||||
// </div>
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
}
|
||||
|
@ -27,21 +27,26 @@ export function FolderPicker() {
|
||||
};
|
||||
|
||||
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
|
||||
type="button"
|
||||
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>
|
||||
|
||||
{selectedPath() && (
|
||||
<div class="text-left max-w-md">
|
||||
<p class="font-semibold">Selected folder:</p>
|
||||
<p class="text-sm break-all">{selectedPath()}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
7
frontend/src/components/item-modal/ItemModal.tsx
Normal file
7
frontend/src/components/item-modal/ItemModal.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
export const ItemModal = () => {
|
||||
return (
|
||||
<div class="fixed inset-4 bg-white border border-neutral-300">
|
||||
ItemModal
|
||||
</div>
|
||||
);
|
||||
};
|
@ -18,7 +18,7 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
|
||||
return (
|
||||
<For each={sortedKeys}>
|
||||
{(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)}
|
||||
</kbd>
|
||||
)}
|
||||
@ -27,15 +27,15 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
|
||||
};
|
||||
|
||||
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">
|
||||
{props.isEditing ? (
|
||||
<>
|
||||
<div class="flex gap-1 min-w-[120px] justify-end">
|
||||
<div class="flex gap-1 min-w-[144px]">
|
||||
{props.currentKeys.length > 0 ? (
|
||||
renderKeys(props.currentKeys)
|
||||
) : (
|
||||
<span class="italic text-neutral-500">
|
||||
<span class="text-neutral-500">
|
||||
Press keys...
|
||||
</span>
|
||||
)}
|
||||
@ -45,14 +45,14 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
|
||||
type="button"
|
||||
onClick={props.onSave}
|
||||
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
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
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" />
|
||||
</button>
|
||||
@ -66,7 +66,7 @@ export const ShortcutItem: Component<ShortcutItemProps> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
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
|
||||
</button>
|
||||
|
@ -58,6 +58,12 @@ export const Shortcuts = () => {
|
||||
};
|
||||
|
||||
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
|
||||
shortcut={shortcut()}
|
||||
isEditing={isEditing()}
|
||||
@ -66,5 +72,6 @@ export const Shortcuts = () => {
|
||||
onSave={onSaveShortcut}
|
||||
onCancel={onCancelShortcut}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user