Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit 2c8f6c1

Browse files
committed
chat scrolls to bottom! and trying to do "since"
1 parent e461efa commit 2c8f6c1

File tree

1 file changed

+103
-105
lines changed

1 file changed

+103
-105
lines changed

src/routes/Chat.tsx

Lines changed: 103 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
/* refresh skip */
22

33
import { TagItem } from "@mutinywallet/mutiny-wasm";
4-
import {
5-
cache,
6-
createAsync,
7-
revalidate,
8-
useNavigate,
9-
useParams
10-
} from "@solidjs/router";
4+
import { createAsync, useNavigate, useParams } from "@solidjs/router";
115
import {
126
createEffect,
7+
createMemo,
138
createResource,
149
createSignal,
1510
For,
1611
Match,
1712
onCleanup,
13+
onMount,
1814
Show,
1915
Suspense,
2016
Switch
@@ -40,7 +36,7 @@ import {
4036
} from "~/components";
4137
import { ParsedParams, toParsedParams } from "~/logic/waila";
4238
import { useMegaStore } from "~/state/megaStore";
43-
import { timeAgo } from "~/utils";
39+
import { createDeepSignal, timeAgo } from "~/utils";
4440

4541
type CombinedMessagesAndActivity =
4642
| { kind: "message"; content: FakeDirectMessage }
@@ -182,6 +178,72 @@ function SingleMessage(props: {
182178
);
183179
}
184180

181+
function MessageList(props: {
182+
convo: CombinedMessagesAndActivity[];
183+
contact: TagItem;
184+
}) {
185+
let scrollRef: HTMLDivElement;
186+
187+
onMount(() => {
188+
scrollRef.scrollIntoView();
189+
});
190+
191+
// Details modal stuff
192+
const [detailsOpen, setDetailsOpen] = createSignal(false);
193+
const [detailsKind, setDetailsKind] = createSignal<HackActivityType>();
194+
const [detailsId, setDetailsId] = createSignal("");
195+
196+
function openDetailsModal(id: string, kind: HackActivityType) {
197+
console.log("Opening details modal: ", id, kind);
198+
199+
if (!id) {
200+
console.warn("No id provided to openDetailsModal");
201+
return;
202+
}
203+
204+
setDetailsId(id);
205+
setDetailsKind(kind);
206+
setDetailsOpen(true);
207+
}
208+
209+
return (
210+
<>
211+
<div class="flex flex-col-reverse justify-end gap-4">
212+
<For each={props.convo}>
213+
{(combined, index) => (
214+
<>
215+
<Show when={combined.kind === "activity"}>
216+
<div class="rounded-lg bg-m-grey-800 px-4 pt-4">
217+
<UnifiedActivityItem
218+
item={combined.content as IActivityItem}
219+
onClick={openDetailsModal}
220+
/>
221+
</div>
222+
</Show>
223+
<Show when={combined.kind === "message"}>
224+
<SingleMessage
225+
dm={combined.content as FakeDirectMessage}
226+
counterPartyNpub={props.contact.npub || ""}
227+
counterPartyContactId={props.contact.id}
228+
/>
229+
</Show>
230+
</>
231+
)}
232+
</For>
233+
</div>
234+
<div ref={(el) => (scrollRef = el)} id="scroll-to-me" />
235+
<Show when={detailsId() && detailsKind()}>
236+
<ActivityDetailsModal
237+
open={detailsOpen()}
238+
kind={detailsKind()}
239+
id={detailsId()}
240+
setOpen={setDetailsOpen}
241+
/>
242+
</Show>
243+
</>
244+
);
245+
}
246+
185247
export function Chat() {
186248
const params = useParams();
187249
const [state, actions] = useMegaStore();
@@ -193,24 +255,41 @@ export function Chat() {
193255
return state.mutiny_wallet?.get_tag_item(params.id);
194256
});
195257

258+
const [lastFetch, setLastFetch] = createSignal(0n);
259+
196260
const [convo, { refetch }] = createResource(
197261
contact,
198-
async (contact: TagItem) => {
262+
async (contact: TagItem, info) => {
199263
// if (!contact() || !contact()?.npub) return undefined;
200264
if (!contact.npub) return [];
201265
try {
202266
const activity = await state.mutiny_wallet?.get_label_activity(
203267
params.id
204268
);
205269
console.log("activity", activity);
270+
const refetchingTimestamp = info.refetching as bigint;
271+
console.log("refetching since", refetchingTimestamp);
206272
const convo = await state.mutiny_wallet?.get_dm_conversation(
207273
// Mutinynet npub, for testing
208274
// "npub1qf8e8cvfp60ywrah984zgsn8veggcrsv2cvttdr47tgz05ypf5yszwx308",
209275
contact.npub,
210276
20n,
211-
undefined
277+
refetchingTimestamp ? refetchingTimestamp : undefined
212278
);
213279

280+
const lastConvo = info.value as CombinedMessagesAndActivity[];
281+
if (
282+
lastConvo &&
283+
lastConvo.length === convo.length + activity.length
284+
) {
285+
console.log("no new messages or activity");
286+
return lastConvo;
287+
}
288+
289+
console.log("dms", convo);
290+
291+
setLastFetch(BigInt(Math.floor(Date.now() / 1000)));
292+
214293
const dms = convo as FakeDirectMessage[];
215294
const acts = activity as IActivityItem[];
216295

@@ -248,14 +327,14 @@ export function Chat() {
248327
return b_time - a_time;
249328
});
250329

251-
return combined.reverse() as CombinedMessagesAndActivity[];
252-
253-
// return combined as FakeDirectMessage[];
254-
return [];
330+
return combined as CombinedMessagesAndActivity[];
255331
} catch (e) {
256332
console.error("error getting convo:", e);
257333
return [];
258334
}
335+
},
336+
{
337+
storage: createDeepSignal
259338
}
260339
);
261340

@@ -270,33 +349,16 @@ export function Chat() {
270349
);
271350
console.log("dmResult:", dmResult);
272351
setMessageValue("");
273-
refetch();
274-
chatScrollRef?.scrollTo({
275-
top: chatScrollRef.scrollHeight
276-
});
352+
refetch(lastFetch());
277353
} catch (e) {
278354
console.error("error sending dm:", e);
279355
}
280356
setSending(false);
281357
}
282358

283-
let chatScrollRef: HTMLDivElement | null = null;
284-
285-
// For some reason I can't do scrolling here, but it works in send message
286-
287-
// createEffect(() => {
288-
// if (convo.latest?.length && chatScrollRef) {
289-
// console.log("scrolling");
290-
291-
// chatScrollRef?.scrollTo({
292-
// top: chatScrollRef.scrollHeight
293-
// });
294-
// }
295-
// });
296-
297359
createEffect(() => {
298360
const interval = setInterval(() => {
299-
refetch();
361+
refetch(lastFetch());
300362
}, 5000); // Poll every 5 seconds
301363
onCleanup(() => {
302364
clearInterval(interval);
@@ -344,24 +406,6 @@ export function Chat() {
344406
});
345407
}
346408

347-
// Details modal stuff
348-
const [detailsOpen, setDetailsOpen] = createSignal(false);
349-
const [detailsKind, setDetailsKind] = createSignal<HackActivityType>();
350-
const [detailsId, setDetailsId] = createSignal("");
351-
352-
function openDetailsModal(id: string, kind: HackActivityType) {
353-
console.log("Opening details modal: ", id, kind);
354-
355-
if (!id) {
356-
console.warn("No id provided to openDetailsModal");
357-
return;
358-
}
359-
360-
setDetailsId(id);
361-
setDetailsKind(kind);
362-
setDetailsOpen(true);
363-
}
364-
365409
return (
366410
<Transition
367411
mode="outin"
@@ -393,10 +437,7 @@ export function Chat() {
393437
>
394438
<MutinyWalletGuard>
395439
<main class="mx-auto grid h-[100dvh] w-full max-w-[600px] grid-cols-1 grid-rows-[minmax(10px,1fr)_4rem] flex-col overflow-y-hidden safe-top safe-bottom">
396-
<div
397-
class="overflow-y-auto"
398-
ref={(el) => (chatScrollRef = el)}
399-
>
440+
<div class="overflow-y-auto">
400441
<div class="fixed top-0 z-50 flex w-full flex-col gap-2 bg-m-grey-975/70 p-4 backdrop-blur-lg">
401442
{/* <BackLink href="/" /> */}
402443
<BackPop default="/search" />
@@ -411,51 +452,16 @@ export function Chat() {
411452
{/* <pre class="whitespace-pre-wrap break-all">
412453
{JSON.stringify(convo(), null, 2)}
413454
</pre> */}
414-
<div class="flex flex-col gap-4 p-4">
455+
<div class="p-4">
415456
<Suspense>
416457
<Show when={contact()}>
417458
<Suspense fallback={<LoadingShimmer />}>
418-
<For each={convo.latest}>
419-
{(combined) => (
420-
<>
421-
<Show
422-
when={
423-
combined.kind ===
424-
"activity"
425-
}
426-
>
427-
<div class="rounded-lg bg-m-grey-800 px-4 pt-4">
428-
<UnifiedActivityItem
429-
item={
430-
combined.content as IActivityItem
431-
}
432-
onClick={
433-
openDetailsModal
434-
}
435-
/>
436-
</div>
437-
</Show>
438-
<Show
439-
when={
440-
combined.kind ===
441-
"message"
442-
}
443-
>
444-
<SingleMessage
445-
dm={
446-
combined.content as FakeDirectMessage
447-
}
448-
counterPartyNpub={
449-
contact()!.npub!
450-
}
451-
counterPartyContactId={
452-
params.id
453-
}
454-
/>
455-
</Show>
456-
</>
457-
)}
458-
</For>
459+
<Show when={convo.latest}>
460+
<MessageList
461+
convo={convo.latest}
462+
contact={contact()!}
463+
/>
464+
</Show>
459465
</Suspense>
460466
</Show>
461467
</Suspense>
@@ -511,14 +517,6 @@ export function Chat() {
511517
</div>
512518
</div>
513519
</main>
514-
<Show when={detailsId() && detailsKind()}>
515-
<ActivityDetailsModal
516-
open={detailsOpen()}
517-
kind={detailsKind()}
518-
id={detailsId()}
519-
setOpen={setDetailsOpen}
520-
/>
521-
</Show>
522520
</MutinyWalletGuard>
523521
</Transition>
524522
);

0 commit comments

Comments
 (0)