diff --git a/src/components/sticky.tsx b/src/components/sticky.tsx
deleted file mode 100644
index a8dae9d..0000000
--- a/src/components/sticky.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { createSignal, JSX, onCleanup, onMount } from "solid-js";
-
-export const StickyOverlay = (props: { children?: JSX.Element }) => {
- const [filterStuck, setFilterStuck] = createSignal(false);
-
- return (
- <>
-
{
- onMount(() => {
- const observer = new IntersectionObserver(
- ([entry]) => setFilterStuck(!entry.isIntersecting),
- {
- rootMargin: "-8px 0px 0px 0px",
- threshold: 0,
- },
- );
-
- observer.observe(trigger);
-
- onCleanup(() => {
- observer.unobserve(trigger);
- observer.disconnect();
- });
- });
- }}
- class="pointer-events-none h-0"
- aria-hidden="true"
- />
-
-
- {props.children}
-
- >
- );
-};
diff --git a/src/utils/keyboard.ts b/src/utils/keyboard.ts
new file mode 100644
index 0000000..16d0bca
--- /dev/null
+++ b/src/utils/keyboard.ts
@@ -0,0 +1,16 @@
+import { onCleanup } from "solid-js";
+
+export const useFilterShortcut = (getRef: () => HTMLInputElement | undefined) => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (
+ e.key === "/" &&
+ !["INPUT", "TEXTAREA"].includes((e.target as HTMLElement)?.tagName) &&
+ !document.querySelector("[data-modal]")
+ ) {
+ e.preventDefault();
+ getRef()?.focus();
+ }
+ };
+ document.addEventListener("keydown", handleKeyDown);
+ onCleanup(() => document.removeEventListener("keydown", handleKeyDown));
+};
diff --git a/src/views/collection.tsx b/src/views/collection.tsx
index 2df0e08..ab5599f 100644
--- a/src/views/collection.tsx
+++ b/src/views/collection.tsx
@@ -4,7 +4,7 @@ import { $type, ActorIdentifier, InferXRPCBodyOutput } from "@atcute/lexicons";
import * as TID from "@atcute/tid";
import { Title } from "@solidjs/meta";
import { A, useBeforeLeave, useParams, useSearchParams } from "@solidjs/router";
-import { createMemo, createResource, createSignal, For, onCleanup, onMount, Show } from "solid-js";
+import { createMemo, createResource, createSignal, For, onMount, Show } from "solid-js";
import { createStore } from "solid-js/store";
import { agent } from "../auth/state";
import { Button } from "../components/button.jsx";
@@ -17,6 +17,7 @@ import Tooltip from "../components/tooltip.jsx";
import { canHover } from "../layout.jsx";
import { resolvePDS } from "../utils/api.js";
import { localDateFromTimestamp } from "../utils/date.js";
+import { useFilterShortcut } from "../utils/keyboard.js";
import {
clearCollectionCache,
getCollectionCache,
@@ -104,18 +105,7 @@ const CollectionView = () => {
});
}
- const handleKeyDown = (e: KeyboardEvent) => {
- if (
- e.key === "/" &&
- !["INPUT", "TEXTAREA"].includes((e.target as HTMLElement)?.tagName) &&
- !document.querySelector("[data-modal]")
- ) {
- e.preventDefault();
- filterInputRef?.focus();
- }
- };
- document.addEventListener("keydown", handleKeyDown);
- onCleanup(() => document.removeEventListener("keydown", handleKeyDown));
+ useFilterShortcut(() => filterInputRef);
});
useBeforeLeave((e) => {
diff --git a/src/views/labels.tsx b/src/views/labels.tsx
index da96acb..1d6d2e9 100644
--- a/src/views/labels.tsx
+++ b/src/views/labels.tsx
@@ -8,10 +8,11 @@ import { createMemo, createSignal, For, onMount, Show } from "solid-js";
import { Button } from "../components/button.jsx";
import DidHoverCard from "../components/hover-card/did.jsx";
import RecordHoverCard from "../components/hover-card/record.jsx";
-import { StickyOverlay } from "../components/sticky.jsx";
import { TextInput } from "../components/text-input.jsx";
+import { canHover } from "../layout.jsx";
import { labelerCache, resolveHandle, resolvePDS } from "../utils/api.js";
import { localDateFromTimestamp } from "../utils/date.js";
+import { useFilterShortcut } from "../utils/keyboard.js";
const LABELS_PER_PAGE = 50;
const DEFAULT_LABELER_DID = "did:plc:ar7c4by46qjdydhdevvrndac";
@@ -67,6 +68,7 @@ export const LabelView = () => {
let rpc: Client | undefined;
let formRef!: HTMLFormElement;
+ let filterInputRef: HTMLInputElement | undefined;
const filteredLabels = createMemo(() => {
const filterValue = filter().trim();
@@ -116,6 +118,8 @@ export const LabelView = () => {
const hasSearched = createMemo(() => Boolean(searchParams.uriPatterns));
onMount(async () => {
+ useFilterShortcut(() => filterInputRef);
+
if (searchParams.did && searchParams.uriPatterns) {
const formData = new FormData();
formData.append("did", searchParams.did.toString());
@@ -128,7 +132,7 @@ export const LabelView = () => {
let did = formData.get("did")?.toString()?.trim() || DEFAULT_LABELER_DID;
const uriPatterns = formData.get("uriPatterns")?.toString()?.trim();
- if (!did || !uriPatterns) {
+ if (!uriPatterns) {
setError("Please provide both DID and URI patterns");
return;
}
@@ -244,43 +248,7 @@ export const LabelView = () => {
-
-
-
setFilter(e.currentTarget.value)}
- class="min-w-0 grow text-sm placeholder:text-xs"
- />
-
- 0}>
-
- {filteredLabels().length}/{labels().length}
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -312,6 +280,65 @@ export const LabelView = () => {
+
+
+
{
+ const input = e.currentTarget.querySelector("input");
+ if (e.target !== input) input?.focus();
+ }}
+ >
+
+ setFilter(e.currentTarget.value)}
+ />
+
+
+ /
+
+
+
+
+
+
+
+
+
+ {filteredLabels().length}
+ /
+
+ {labels().length} labels
+
+
+
+
+
+
+
+
+
+
>
diff --git a/src/views/repo.tsx b/src/views/repo.tsx
index 5445924..6e2c19f 100644
--- a/src/views/repo.tsx
+++ b/src/views/repo.tsx
@@ -9,7 +9,6 @@ import {
createSignal,
ErrorBoundary,
For,
- onCleanup,
onMount,
Show,
Suspense,
@@ -42,6 +41,7 @@ import {
validateHandle,
} from "../utils/api.js";
import { detectDidKeyType, detectKeyType } from "../utils/key.js";
+import { useFilterShortcut } from "../utils/keyboard.js";
import { BlobView } from "./blob.jsx";
import { PlcLogView } from "./logs.jsx";
import { plcDirectory } from "./settings.jsx";
@@ -80,19 +80,7 @@ export const RepoView = () => {
});
onMount(() => {
- const handleKeyDown = (e: KeyboardEvent) => {
- if (
- e.key === "/" &&
- !["INPUT", "TEXTAREA"].includes((e.target as HTMLElement)?.tagName) &&
- !document.querySelector("[data-modal]")
- ) {
- e.preventDefault();
- filterInputRef?.focus();
- }
- };
-
- document.addEventListener("keydown", handleKeyDown);
- onCleanup(() => document.removeEventListener("keydown", handleKeyDown));
+ useFilterShortcut(() => filterInputRef);
});
const RepoTab = (props: {