Skip to content

Commit

Permalink
client-web: less database usage; more responsive on busy events
Browse files Browse the repository at this point in the history
  • Loading branch information
franzos committed Sep 25, 2023
1 parent 517ef10 commit a6ab1d8
Show file tree
Hide file tree
Showing 26 changed files with 826 additions and 557 deletions.
3 changes: 2 additions & 1 deletion client-web/src/components/bottom-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export function BottomBar() {
let description = "";
let success = true;
if (event.data[0] === RELAY_MESSAGE_TYPE.NOTICE) {
description = event.data[1];
title = event.data[1];
description = `${event.meta.url}`;
} else if (event.data[0] === RELAY_MESSAGE_TYPE.OK) {
success = event.data[2];
title = success ? `Event accepted` : `Event rejected`;
Expand Down
58 changes: 28 additions & 30 deletions client-web/src/components/event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,39 @@ export function Event({ data, level }: EventProps) {
]);

const [replies, setReplies] = useState<LightProcessedEvent[]>();
const [contentIsVisible, makeContentVisible] = useState(true);
const [user, setUser] = useState<UserBase>({
pubkey: data.event.pubkey,
});
const [properties, setProperties] = useState<{
const [user, setUser] = useState<UserBase>(
data.user
? data.user
: {
pubkey: data.event.pubkey,
}
);

const content = extractEventContent(data.event.content);
const contentWarning = eventHasContentWarning(data.event);

let visible;
if (content?.text && !contentWarning) {
visible = true;
} else if (contentWarning) {
visible = false;
}

const properties: {
isLoaded: boolean;
contentWarning: string | undefined;
images: string[] | undefined;
videos: string[] | undefined;
text: string | undefined;
}>({
isLoaded: false,
contentWarning: undefined,
images: undefined,
videos: undefined,
text: undefined,
});
} = {
isLoaded: true,
contentWarning,
images: content.images,
videos: content.videos,
text: content.text,
};

const [contentIsVisible, makeContentVisible] = useState(visible);

const userOptions = {
showFollowing: true,
Expand All @@ -76,24 +92,6 @@ export function Event({ data, level }: EventProps) {

const toast = useToast();

useEffect(() => {
const content = extractEventContent(data.event.content);
const contentWarning = eventHasContentWarning(data.event);
if (content?.text && !contentWarning) {
makeContentVisible(true);
} else if (contentWarning) {
makeContentVisible(false);
}
const newProps = {
isLoaded: true,
contentWarning,
images: content?.images,
videos: content?.videos,
text: content?.text,
};
setProperties(newProps);
}, [data.event.content]);

useEffect(() => {
if (level === 0) {
const user = data.user
Expand Down
8 changes: 1 addition & 7 deletions client-web/src/components/event/card-footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from "@chakra-ui/react";
import { ReactionsCount } from "@nostr-ts/common";
import InformationOutlineIcon from "mdi-react/InformationOutlineIcon";
import { useState, useEffect } from "react";
import { filterReactions } from "../../lib/event-reactions-filter";
import { unixTimeToRelative } from "../../lib/relative-time";
import { EventActionButtons } from "./action-buttons";
Expand Down Expand Up @@ -59,12 +58,7 @@ export const EventCardFooter = ({

onAction,
}: CardFooterProps) => {
const [reactions, setReactions] = useState<ReactionsCount>({});

useEffect(() => {
const filtered = filterReactions(reactionsCount);
setReactions(filtered);
}, [reactionsCount]);
const reactions = filterReactions(reactionsCount);

return (
<CardFooter pl={4} pr={4} pt={2} pb={2}>
Expand Down
5 changes: 4 additions & 1 deletion client-web/src/components/event/nsfw-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export const NSFWContentToggle = ({
wordBreak="break-all"
onClick={() => setShowNSFWContent(true)}
>
Show content {contentWarning !== "" ? `(${contentWarning})` : `(NSFW)`}
Show content{" "}
{contentWarning && contentWarning !== ""
? `(${contentWarning})`
: `(NSFW)`}
</Button>
);
};
23 changes: 7 additions & 16 deletions client-web/src/components/events.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { useEffect, useRef } from "react";
import { Box, Button } from "@chakra-ui/react";
import { useNClient } from "../state/client";
import { Event } from "../components/event";

import { Virtuoso } from "react-virtuoso";

interface EventsProps {
Expand All @@ -11,13 +10,11 @@ interface EventsProps {
}

export function Events({ view, changingView }: EventsProps) {
const [events, eventsNewerCount, hasNewerEvents] = useNClient((state) => [
const [events, eventsNewerCount] = useNClient((state) => [
state.events[view] || [],
state.eventsNewer[view]?.length || 0,
state.hasNewerEvents,
]);
const throttleTimestamp = useRef(Date.now());
const [isLoading, setIsLoading] = useState(false);

const loadEvents = async () => {
if (
Expand All @@ -26,7 +23,6 @@ export function Events({ view, changingView }: EventsProps) {
) {
return;
}
setIsLoading(true);
throttleTimestamp.current = Date.now();

const nextQuery = useNClient.getState().nextQuery;
Expand Down Expand Up @@ -55,7 +51,6 @@ export function Events({ view, changingView }: EventsProps) {
} else {
await useNClient.getState().getEvents();
}
setIsLoading(false);
};

useEffect(() => {
Expand All @@ -64,11 +59,11 @@ export function Events({ view, changingView }: EventsProps) {
}
}, []);

useEffect(() => {
if (hasNewerEvents && hasNewerEvents.count > 0 && !isLoading) {
loadEvents();
}
}, [hasNewerEvents, isLoading]);
// useEffect(() => {
// if (hasNewerEvents && hasNewerEvents.count > 0 && !isLoading) {
// loadEvents();
// }
// }, [hasNewerEvents, isLoading]);

// const loadNewerEvents = async () => {
// setIsLoading(true);
Expand Down Expand Up @@ -121,10 +116,6 @@ export function Events({ view, changingView }: EventsProps) {
endReached={() => {
loadEvents();
}}
overscan={{
main: 4000,
reverse: 4000,
}}
/>
</>
);
Expand Down
11 changes: 9 additions & 2 deletions client-web/src/components/feeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export function EventsFeeds() {
// Set the default, "initial" view
isInitDone.current = true;

activeFilters.current = filterDefault();
setView("global");

await useNClient.getState().getEvents({
token: view,
query: {
Expand All @@ -47,6 +50,9 @@ export function EventsFeeds() {
};

useEffect(() => {
if (["online", "offline"].includes(useNClient.getState().status)) {
onMount();
}
return () => {
useNClient.getState().unsubscribeByToken(view);
};
Expand All @@ -63,7 +69,8 @@ export function EventsFeeds() {

const changeFeed = async (feedName: string) => {
changingView.current = true;
// useNClient.getState().setView(feedName);

await useNClient.getState().unsubscribeByToken(view);
setView(feedName);

if (feedName === "global") {
Expand All @@ -77,7 +84,7 @@ export function EventsFeeds() {
if (list && list.userPubkeys) {
activeFilters.current = filterByAuthor(list.userPubkeys);
} else {
console.warn("List not found.");
console.error("List not found.");
changingView.current = false;
return;
}
Expand Down
6 changes: 3 additions & 3 deletions client-web/src/components/user-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function UserInfo({
},
}: UserInfoProps) {
const name = data && data.name ? data.name : "Anonymous";
const displayName = data && data.display_name ? data.display_name : "";
const displayName = data && data.display_name ? data.display_name : name;
const picture = data && data.picture ? data.picture : "";
const banner = data && data.banner ? data.banner : undefined;
const about = data && data.about ? data.about : undefined;
Expand Down Expand Up @@ -76,9 +76,9 @@ export function UserInfo({
</Box>
<Box overflowWrap="anywhere" maxWidth={350}>
<Link to={profileLink}>
<Text size="sm">{name}</Text>
<Text size="sm">{displayName}</Text>
</Link>
{!displayNameEqName && <Text size="xs">{displayName}</Text>}
{!displayNameEqName && <Text fontSize={12}>{name}</Text>}
</Box>

<Spacer />
Expand Down
11 changes: 4 additions & 7 deletions client-web/src/lib/default-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ export function filterDefault(limit?: number) {
],
until: Math.round(Date.now() / 1000),
since: Math.round((Date.now() - 2 * 24 * 60 * 60 * 1000) / 1000),
limit: 50,
limit: limit ? limit : 15,
});
if (limit) {
filters.limit = limit;
}
return filters;
}

Expand All @@ -23,7 +20,7 @@ export function filterByAuthor(pubKeys: string[], limit?: number) {
authors: pubKeys,
until: Math.round(Date.now() / 1000),
since: Math.round((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000),
limit: 50,
limit: limit ? limit : 15,
});
if (limit) {
filters.limit = limit;
Expand All @@ -34,10 +31,10 @@ export function filterByAuthor(pubKeys: string[], limit?: number) {
export function filterByTags(tags: string[], limit?: number) {
const filters = new NFilters({
kinds: [NEVENT_KIND.SHORT_TEXT_NOTE, NEVENT_KIND.LONG_FORM_CONTENT],
tags,
["#t"]: tags,
until: Math.round(Date.now() / 1000),
since: Math.round((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000),
limit: 50,
limit: limit ? limit : 15,
});
if (limit) {
filters.limit = limit;
Expand Down
15 changes: 10 additions & 5 deletions client-web/src/routes/event.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Heading, Box, Grid, Progress } from "@chakra-ui/react";
import { LightProcessedEvent, decodeBech32 } from "@nostr-ts/common";
import { decodeBech32 } from "@nostr-ts/common";
import { useState, useEffect, useRef } from "react";
import { useNClient } from "../state/client";
import { useParams } from "react-router-dom";
Expand All @@ -12,26 +12,29 @@ export function EventRoute() {
const isInitDone = useRef<boolean>(false);

const eventId = useRef("");
const relayUrls = useRef<string[]>([]);
const eventLoadTimeout = useRef<number | null>(null);
const [hasTimeout, setHasTimeout] = useState<boolean>(false);
const [eventData, setEventData] = useState<LightProcessedEvent | null>(null);

// URL params
const { note } = useParams();

const view = `event-${note}`;

const [eventData] = useNClient((state) => [
state.events[view] ? state.events[view][0] : null,
]);

const getEvent = async (retryCount = 0) => {
await useNClient
.getState()
.getEvent(eventId.current, {
view,
retryCount,
relayUrls: relayUrls.current,
})
.then((r) => {
if (r) {
setEventData(r);
} else {
if (!r) {
console.log(`Could not get event. Retrying...`);
eventLoadTimeout.current = setTimeout(async () => {
if (retryCount > 20) {
Expand All @@ -56,6 +59,8 @@ export function EventRoute() {
if (item.type === 0) {
eventId.current = item.value as string;
break;
} else if (item.type === 1) {
relayUrls.current.push(item.value as string);
}
}
} catch (e) {
Expand Down
Loading

0 comments on commit a6ab1d8

Please sign in to comment.