From 3c3a25bcfc90f62a147134743bf94ce461838afb Mon Sep 17 00:00:00 2001
From: John Costa
Date: Fri, 18 Jul 2025 11:46:12 +0100
Subject: [PATCH] feat: gallery for each category
---
frontend/src/App.tsx | 134 ++++++++++++++++-----------------
frontend/src/front/index.tsx | 9 ++-
frontend/src/gallery/index.tsx | 50 ++++++++++++
3 files changed, 123 insertions(+), 70 deletions(-)
create mode 100644 frontend/src/gallery/index.tsx
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 21c3ddd..8992848 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -4,14 +4,14 @@ import { listen } from "@tauri-apps/api/event";
import { readFile } from "@tauri-apps/plugin-fs";
import { platform } from "@tauri-apps/plugin-os";
import {
- type Component,
- type ParentProps,
- createEffect,
- onCleanup,
+ type Component,
+ type ParentProps,
+ createEffect,
+ onCleanup,
} from "solid-js";
import {
- type ShareEvent,
- listenForShareEvents,
+ type ShareEvent,
+ listenForShareEvents,
} from "tauri-plugin-sharetarget-api";
import { Login } from "./Login";
import { ProtectedRoute } from "./ProtectedRoute";
@@ -22,83 +22,83 @@ import { SearchImageContextProvider } from "./contexts/SearchImageContext";
import { sendImageFile } from "./network";
import { Image } from "./Image";
import { WithEntityDialog } from "./WithEntityDialog";
+import { Gallery } from "./gallery";
const currentPlatform = platform();
console.log("Current Platform: ", currentPlatform);
const AppWrapper: Component = ({ children }) => {
- return {children}
;
+ return {children}
;
};
export const App = () => {
- createEffect(() => {
- // TODO: Don't use window.location.href
- const unlisten = listen("focus-search", () => {
- window.location.href = "/";
- });
+ createEffect(() => {
+ // TODO: Don't use window.location.href
+ const unlisten = listen("focus-search", () => {
+ window.location.href = "/";
+ });
- onCleanup(() => {
- unlisten.then((fn) => fn());
- });
- });
+ onCleanup(() => {
+ unlisten.then((fn) => fn());
+ });
+ });
- createEffect(() => {
- if (currentPlatform !== "android") {
- return;
- }
+ createEffect(() => {
+ if (currentPlatform !== "android") {
+ return;
+ }
- let listener: PluginListener;
+ let listener: PluginListener;
- const setupListener = async () => {
- console.log("Setting up listener");
+ const setupListener = async () => {
+ console.log("Setting up listener");
- listener = await listenForShareEvents(
- async (intent: ShareEvent) => {
- console.log(intent);
- const contents = await readFile(intent.stream ?? "").catch(
- (error: Error) => {
- console.warn("fetching shared content failed:");
- throw error;
- },
- );
+ listener = await listenForShareEvents(async (intent: ShareEvent) => {
+ console.log(intent);
+ const contents = await readFile(intent.stream ?? "").catch(
+ (error: Error) => {
+ console.warn("fetching shared content failed:");
+ throw error;
+ },
+ );
- const f = new File([contents], intent.name ?? "no-name", {
- type: intent.content_type,
- });
+ const f = new File([contents], intent.name ?? "no-name", {
+ type: intent.content_type,
+ });
- sendImageFile(f.name, f);
- },
- );
- };
+ sendImageFile(f.name, f);
+ });
+ };
- setupListener();
- return () => {
- listener?.unregister();
- };
- });
+ setupListener();
+ return () => {
+ listener?.unregister();
+ };
+ });
- return (
-
-
-
-
-
+ return (
+
+
+
+
+
-
-
-
-
-
-
-
-
- {
- return ;
- }}
- />
-
-
- );
+
+
+
+
+
+
+
+
+
+ {
+ return ;
+ }}
+ />
+
+
+ );
};
diff --git a/frontend/src/front/index.tsx b/frontend/src/front/index.tsx
index 8ac4174..da070cc 100644
--- a/frontend/src/front/index.tsx
+++ b/frontend/src/front/index.tsx
@@ -1,9 +1,11 @@
-import { Component, createEffect, For } from "solid-js";
+import { Component, For } from "solid-js";
import {
SearchImageStore,
useSearchImageContext,
} from "../contexts/SearchImageContext";
+import { A } from "@solidjs/router";
+// TODO: lots of stuff to do with Entities, this could be seperated into a centralized place.
const CategoryColor: Record<
keyof ReturnType,
string
@@ -21,7 +23,8 @@ export const Categories: Component = () => {
{([category, group]) => (
- {
>
{category}s
{group.length}
-
+
)}
diff --git a/frontend/src/gallery/index.tsx b/frontend/src/gallery/index.tsx
new file mode 100644
index 0000000..228a3e3
--- /dev/null
+++ b/frontend/src/gallery/index.tsx
@@ -0,0 +1,50 @@
+import { Component, For, Show } from "solid-js";
+import { useParams } from "@solidjs/router";
+import { union, literal, safeParse, InferOutput, parse } from "valibot";
+import { useSearchImageContext } from "../contexts/SearchImageContext";
+import { SearchCard } from "../components/search-card/SearchCard";
+
+const entityValidator = union([
+ literal("event"),
+ literal("note"),
+ literal("location"),
+ literal("contact"),
+]);
+
+const EntityGallery: Component<{
+ entity: InferOutput;
+}> = (props) => {
+ // Just to be doubly sure.
+ parse(entityValidator, props.entity);
+
+ // These names are being silly. Entity or Category?
+ const { images } = useSearchImageContext();
+
+ const filteredCategories = () =>
+ images().filter((i) => i.type === props.entity);
+
+ return (
+
+
{props.entity}s
+
+
+ {(category) => }
+
+
+
+ );
+};
+
+export const Gallery: Component = () => {
+ const params = useParams();
+ const validated = safeParse(entityValidator, params.entity);
+
+ return (
+ Sorry, this entity is not supported
}
+ >
+
+
+ );
+};