preview: https://github.com/user-attachments/assets/6281c46d-eccf-4900-9d71-6027d447fa96
+75
-6
src/views/collection.tsx
+75
-6
src/views/collection.tsx
···
3
import { $type, ActorIdentifier, InferXRPCBodyOutput } from "@atcute/lexicons";
4
import * as TID from "@atcute/tid";
5
import { A, useParams } from "@solidjs/router";
6
-
import { createEffect, createResource, createSignal, For, Show, untrack } from "solid-js";
7
import { createStore } from "solid-js/store";
8
-
import { Button } from "../components/button.jsx";
9
import { JSONType, JSONValue } from "../components/json.jsx";
10
-
11
-
12
13
14
···
72
const [batchDelete, setBatchDelete] = createSignal(false);
73
const [lastSelected, setLastSelected] = createSignal<number>();
74
const [reverse, setReverse] = createSignal(false);
75
const did = params.repo;
76
let pds: string;
77
let rpc: Client;
78
79
const fetchRecords = async () => {
80
if (!pds) pds = await resolvePDS(did);
···
157
true,
158
);
159
160
return (
161
<Show when={records.length || response()}>
162
<div class="flex w-full flex-col items-center">
163
-
<div class="dark:bg-dark-500 sticky top-0 z-5 flex w-screen flex-col items-center justify-center gap-2 bg-neutral-100 pt-1 pb-3">
164
<div class="flex w-[22rem] items-center gap-2 sm:w-[24rem]">
165
<Show when={agent() && agent()?.sub === did}>
166
<div class="flex items-center gap-x-2">
···
221
</div>
222
<Show when={records.length > 1}>
223
<div class="flex w-[22rem] items-center justify-between gap-x-2 sm:w-[24rem]">
224
-
<Button
225
onClick={() => {
226
setReverse(!reverse());
···
3
import { $type, ActorIdentifier, InferXRPCBodyOutput } from "@atcute/lexicons";
4
import * as TID from "@atcute/tid";
5
import { A, useParams } from "@solidjs/router";
6
+
import { createEffect, createResource, createSignal, For, Show, untrack, onMount, onCleanup } from "solid-js";
7
import { createStore } from "solid-js/store";
8
+
import { Button, type ButtonProps } from "../components/button.jsx";
9
import { JSONType, JSONValue } from "../components/json.jsx";
10
+
import { agent } from "../components/login.jsx";
11
+
import { TextInput } from "../components/text-input.jsx";
12
13
14
···
72
const [batchDelete, setBatchDelete] = createSignal(false);
73
const [lastSelected, setLastSelected] = createSignal<number>();
74
const [reverse, setReverse] = createSignal(false);
75
+
const [filterStuck, setFilterStuck] = createSignal(false);
76
const did = params.repo;
77
let pds: string;
78
let rpc: Client;
79
+
let sticky!: HTMLDivElement;
80
81
const fetchRecords = async () => {
82
if (!pds) pds = await resolvePDS(did);
···
159
true,
160
);
161
162
+
const FilterButton = (props: ButtonProps) => {
163
+
return <Button
164
+
class="flex items-center gap-1 rounded-lg bg-white px-2 py-1.5 text-xs font-semibold border-[0.5px] border-neutral-300 dark:border-neutral-700 shadow-md"
165
+
classList={{
166
+
"dark:bg-dark-300 dark:hover:bg-dark-100 dark:active:bg-dark-100 bg-white hover:bg-neutral-50 active:bg-neutral-50": !filterStuck(),
167
+
"dark:bg-dark-100 dark:hover:bg-dark-50 dark:active:bg-dark-50 bg-neutral-50 hover:bg-neutral-200 active:bg-neutral-200": filterStuck()
168
+
}}
169
+
{...props}
170
+
/>
171
+
}
172
+
173
+
onMount(() => {
174
+
let ticking = false;
175
+
const tick = () => {
176
+
const topPx = parseFloat(getComputedStyle(sticky).top);
177
+
const { top } = sticky.getBoundingClientRect();
178
+
setFilterStuck(top <= topPx + 0.5);
179
+
ticking = false;
180
+
};
181
+
182
+
const onScroll = () => {
183
+
if (!ticking) {
184
+
ticking = true;
185
+
requestAnimationFrame(tick);
186
+
}
187
+
};
188
+
189
+
window.addEventListener("scroll", onScroll, { passive: true });
190
+
191
+
tick();
192
+
193
+
onCleanup(() => {
194
+
window.removeEventListener("scroll", onScroll);
195
+
});
196
+
});
197
+
198
return (
199
<Show when={records.length || response()}>
200
<div class="flex w-full flex-col items-center">
201
+
<div
202
+
ref={(el) => (sticky = el)}
203
+
class="sticky top-2 z-10 flex flex-col items-center justify-center gap-2 rounded-lg p-3 transition-colors"
204
+
classList={{
205
+
"bg-neutral-50 dark:bg-dark-300 border-[0.5px] border-neutral-300 dark:border-neutral-700 shadow-md": filterStuck(),
206
+
"bg-transparent border-transparent shadow-none -mt-2": !filterStuck(),
207
+
}}
208
+
>
209
<div class="flex w-[22rem] items-center gap-2 sm:w-[24rem]">
210
<Show when={agent() && agent()?.sub === did}>
211
<div class="flex items-center gap-x-2">
···
266
</div>
267
<Show when={records.length > 1}>
268
<div class="flex w-[22rem] items-center justify-between gap-x-2 sm:w-[24rem]">
269
+
<FilterButton
270
onClick={() => {
271
setReverse(!reverse());
272
+
setRecords([]);
273
+
274
+
275
+
276
+
277
+
278
+
class={`iconify ${reverse() ? "lucide--rotate-ccw" : "lucide--rotate-cw"} text-sm`}
279
+
></span>
280
+
Reverse
281
+
</FilterButton>
282
+
<div>
283
+
<Show when={batchDelete()}>
284
+
<span>{records.filter((rec) => rec.toDelete).length}</span>
285
+
286
+
287
+
288
+
289
+
<div class="flex w-[5rem] items-center justify-end">
290
+
<Show when={cursor()}>
291
+
<Show when={!response.loading}>
292
+
<FilterButton onClick={() => refetch()}>Load More</FilterButton>
293
+
</Show>
294
+
<Show when={response.loading}>
295
+
<div class="iconify lucide--loader-circle w-[5rem] animate-spin text-xl" />
History
2 rounds
2 comments
futur.blue
submitted
#1
1 commit
expand
collapse
prettier
expand 1 comment
closed without merging
futur.blue
submitted
#0
gonna try again with a patch I guess?