From afe2a8953f30a44605356844dd0141d40a05e856 Mon Sep 17 00:00:00 2001 From: Franz Geffke Date: Tue, 26 Sep 2023 10:26:27 +0100 Subject: [PATCH] client-web: drop usage of followingUserIds --- README.md | 2 +- client-web/index.html | 2 +- client-web/src/components/event.tsx | 2 +- client-web/src/components/event/user.tsx | 4 +- client-web/src/components/feeds.tsx | 22 +-- client-web/src/components/popular-users.tsx | 7 +- client-web/src/components/user-icon.tsx | 14 +- client-web/src/components/user-info.tsx | 128 --------------- client-web/src/components/user.tsx | 164 +++++++++++++++++--- client-web/src/layouts/primary.tsx | 3 +- client-web/src/lib/user-properties.ts | 1 - client-web/src/routes/following.tsx | 2 +- client-web/src/routes/lists.tsx | 6 +- client-web/src/routes/profile.tsx | 2 +- client-web/src/routes/user-profile.tsx | 2 +- client-web/src/state/base-types.ts | 2 - client-web/src/state/client.ts | 17 -- packages/web/src/worker/worker.test.ts | 2 +- packages/web/src/worker/worker.ts | 8 - 19 files changed, 178 insertions(+), 212 deletions(-) delete mode 100644 client-web/src/components/user-info.tsx diff --git a/README.md b/README.md index 7a82d9f..801b02e 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ const event = NewContactList({ { key: "5276ac499c9c6a353634d3d2cb6f4ada5167c3b886108ab4ddeb8ddf7b0fff70", relayUrl: "wss://nostr.rocks", - petname: "nostros", + petname: "nostrop", }, ], }); diff --git a/client-web/index.html b/client-web/index.html index 99af9e6..9ca1ed6 100644 --- a/client-web/index.html +++ b/client-web/index.html @@ -4,7 +4,7 @@ - NostrOS + NostrOP diff --git a/client-web/src/components/event.tsx b/client-web/src/components/event.tsx index b4d4251..3cb092c 100644 --- a/client-web/src/components/event.tsx +++ b/client-web/src/components/event.tsx @@ -236,7 +236,7 @@ export function Event({ data, level }: EventProps) { /> )} - + {/* BODY */} diff --git a/client-web/src/components/event/user.tsx b/client-web/src/components/event/user.tsx index 30dace1..99bbdf3 100644 --- a/client-web/src/components/event/user.tsx +++ b/client-web/src/components/event/user.tsx @@ -11,7 +11,7 @@ export function EventUser({ data }: EventUserProps) { {data.user && data.user.pubkey ? ( [ - state.status, - state.followingUserIds, - state.keypairIsLoaded, - state.keypair, - ] - ); + const [status, keypairIsLoaded, keypair] = useNClient((state) => [ + state.status, + state.keypairIsLoaded, + state.keypair, + ]); const isInitDone = useRef(false); @@ -76,7 +73,12 @@ export function EventsFeeds() { if (feedName === "global") { activeFilters.current = filterDefault(); } else if (feedName === "following") { - activeFilters.current = filterByAuthor(followingUserIds); + const following = await useNClient.getState().getAllUsersFollowing(); + if (following) { + activeFilters.current = filterByAuthor( + following?.map((f) => f.user.pubkey) + ); + } } else if (feedName === "mentions") { activeFilters.current = filterByMentions([keypair.publicKey]); } else { @@ -105,7 +107,7 @@ export function EventsFeeds() { 0} + showFollowing={true} showMentions={keypairIsLoaded} changeFeed={changeFeed} /> diff --git a/client-web/src/components/popular-users.tsx b/client-web/src/components/popular-users.tsx index 4c72b9f..04a7d3f 100644 --- a/client-web/src/components/popular-users.tsx +++ b/client-web/src/components/popular-users.tsx @@ -9,8 +9,8 @@ import { } from "@chakra-ui/react"; import { UserRecord } from "@nostr-ts/common"; import { useEffect, useRef, useState } from "react"; -import { UserInfo } from "./user-info"; import { useNClient } from "../state/client"; +import { User } from "./user"; export function PopularUsersList() { const [users, setUsers] = useState([]); @@ -102,14 +102,13 @@ export function PopularUsersList() { {users.length > 0 ? users.map((user, index) => ( - [ - state.followingUserIds.find((f) => f === user.pubkey), - ]); - const picture = user.data && user.data.picture ? user.data.picture : ""; return ( @@ -75,12 +70,11 @@ export function UserIcon({ {title} - (""); - - useEffect(() => { - const npub = encodeBech32(BECH32_PREFIX.PublicKeys, [ - { - type: 0, - value: pubkey, - }, - ]); - setProfileLink(`/p/${npub}`); - }, [pubkey]); - - // const mentionsLink = `/mentions/${user.pubkey}?relays=${relayUrls.join(",")}`; - - const { isOpen, onOpen, onClose } = useDisclosure(); - - return ( - <> - {showBanner && banner && ( - - banner - - )} - - - - {picture === "" ? ( - - ) : ( - - )} - - - - - {displayName} - - {!displayNameEqName && {name}} - - - - {showBlock && ( - - )} - - {showFollowing && ( - - )} - - - {showAbout && about && {about}} - - - - ); -} diff --git a/client-web/src/components/user.tsx b/client-web/src/components/user.tsx index 042bd18..0df943a 100644 --- a/client-web/src/components/user.tsx +++ b/client-web/src/components/user.tsx @@ -1,26 +1,152 @@ -import { UserBase } from "@nostr-ts/common"; +import { + Avatar as ChakraAvatar, + Spacer, + Button, + Box, + Image, + Text, + HStack, + useDisclosure, + Menu, + MenuButton, + MenuItem, + MenuList, + IconButton, + Icon, +} from "@chakra-ui/react"; +import { Link } from "react-router-dom"; import { useNClient } from "../state/client"; -import { UserInfo } from "./user-info"; -import { UserOptions } from "../lib/user-properties"; +import { UserInfoProps } from "../lib/user-properties"; +import { BECH32_PREFIX, encodeBech32 } from "@nostr-ts/common"; +import CancelIcon from "mdi-react/CancelIcon"; +import AccountMultipleIcon from "mdi-react/AccountMultipleIcon"; +import PlaylistEditIcon from "mdi-react/PlaylistEditIcon"; +import DotsVerticalCircleOutlineIcon from "mdi-react/DotsVerticalCircleOutlineIcon"; +import { ListAssignmentModal } from "./list-assignment-modal"; +import { useEffect, useState } from "react"; +import Avatar from "boring-avatars"; export function User({ - user, - options, -}: { - user: UserBase; - options: UserOptions; -}) { - const [following] = useNClient((state) => [ - state.followingUserIds.find((f) => f === user.pubkey), - ]); + user: { pubkey, data }, + opts: { + showAbout, + showBanner, + showFollowing, + showBlock, + relayUrls, + isBlocked, + }, +}: UserInfoProps) { + const name = data && data.name ? data.name : "Anonymous"; + 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; + + const displayNameEqName = displayName === name; + + const [profileLink, setProfileLink] = useState(""); + const [following, setFollowing] = useState(false); + + useEffect(() => { + const npub = encodeBech32(BECH32_PREFIX.PublicKeys, [ + { + type: 0, + value: pubkey, + }, + ]); + setProfileLink(`/p/${npub}`); + }, [pubkey]); + + const loadFollowingStatus = async () => { + const following = await useNClient.getState().followingUser(pubkey); + setFollowing(following); + }; + + // const mentionsLink = `/mentions/${user.pubkey}?relays=${relayUrls.join(",")}`; + + const { isOpen, onOpen, onClose } = useDisclosure(); return ( - + <> + {showBanner && banner && ( + + banner + + )} + + + + {picture === "" ? ( + + ) : ( + + )} + + + + + {displayName} + + {!displayNameEqName && {name}} + + + + + + } + > + Actions + + + {showBlock && ( + } + onClick={() => + isBlocked + ? useNClient.getState().unblockUser(pubkey) + : useNClient.getState().blockUser({ + pubkey: pubkey, + relayUrls, + }) + } + > + {isBlocked ? "Unblock" : "Block"} + + )} + } onClick={onOpen}> + Lists + + {showFollowing && ( + } + onClick={() => + following + ? useNClient.getState().unfollowUser(pubkey) + : useNClient.getState().followUser({ + pubkey: pubkey, + relayUrls, + }) + } + > + {following ? "Unfollow" : "Follow"} + + )} + + + + + {showAbout && about && {about}} + + + ); } diff --git a/client-web/src/layouts/primary.tsx b/client-web/src/layouts/primary.tsx index c63afab..0113848 100644 --- a/client-web/src/layouts/primary.tsx +++ b/client-web/src/layouts/primary.tsx @@ -18,6 +18,7 @@ import LanDisconnectIcon from "mdi-react/LanDisconnectIcon"; import FormatListBulletedIcon from "mdi-react/FormatListBulletedIcon"; import AccountKeyIcon from "mdi-react/AccountKeyIcon"; import AccountMultipleIcon from "mdi-react/AccountMultipleIcon"; +import PlaylistEditIcon from "mdi-react/PlaylistEditIcon"; import AccountEditIcon from "mdi-react/AccountEditIcon"; import { ConnectModal } from "../components/connect-modal"; import Logo from "../assets/logo.svg"; @@ -73,7 +74,7 @@ export function PrimaryLayout() { } + leftIcon={} /> {publicKey && publicKey !== "" && ( diff --git a/client-web/src/lib/user-properties.ts b/client-web/src/lib/user-properties.ts index 793267f..3ba25e3 100644 --- a/client-web/src/lib/user-properties.ts +++ b/client-web/src/lib/user-properties.ts @@ -3,7 +3,6 @@ import { UserBase } from "@nostr-ts/common"; export interface UserOptions { showAbout?: boolean; showBanner?: boolean; - following?: boolean; showFollowing?: boolean; /** * Show block button diff --git a/client-web/src/routes/following.tsx b/client-web/src/routes/following.tsx index 816447e..f3cdba2 100644 --- a/client-web/src/routes/following.tsx +++ b/client-web/src/routes/following.tsx @@ -131,7 +131,7 @@ export function FollowingUsersRoute() { ([]); @@ -95,7 +95,7 @@ export function ListsRoute() { - diff --git a/client-web/src/state/base-types.ts b/client-web/src/state/base-types.ts index 7368ca4..58408c8 100644 --- a/client-web/src/state/base-types.ts +++ b/client-web/src/state/base-types.ts @@ -68,8 +68,6 @@ export interface NClientBase { followUser(payload: UserPublicKeyAndRelays): Promise; unfollowUser(pubkey: string): Promise; followingUser(pubkey: string): Promise; - // For reactive updates - followingUserIds: string[]; getAllUsersFollowing(): Promise; unfollowUser(pubkey: string): Promise; blockUser(payload: UserPublicKeyAndRelays): void; diff --git a/client-web/src/state/client.ts b/client-web/src/state/client.ts index 1082a6a..0a1035a 100644 --- a/client-web/src/state/client.ts +++ b/client-web/src/state/client.ts @@ -104,9 +104,6 @@ export const useNClient = create((set, get) => ({ set({ status: payload.data as SystemStatus }); console.log(`Status changed to ${payload.data}`); break; - case "following:update": - set({ followingUserIds: payload.data as string[] }); - break; default: console.log(`Unsupported payload type: ${payload.type}`); } @@ -120,11 +117,6 @@ export const useNClient = create((set, get) => ({ worker.addEventListener("message", throttledEvents); await get().store.init(); - - const following = await get().store.getAllUsersFollowing(); - if (following) { - set({ followingUserIds: following.map((u) => u.user.pubkey) }); - } } catch (err) { console.error("Initialization failed:", err); } @@ -777,23 +769,14 @@ export const useNClient = create((set, get) => ({ }, followUser: async (payload: { pubkey: string; relayUrls: string[] }) => { await get().store.followUser(payload.pubkey); - const folowing = await get().store.getAllUsersFollowing(); - if (folowing) { - set({ followingUserIds: folowing.map((u) => u.user.pubkey) }); - } }, unfollowUser: async (pubkey: string) => { await get().store.unfollowUser(pubkey); - const folowing = await get().store.getAllUsersFollowing(); - if (folowing) { - set({ followingUserIds: folowing.map((u) => u.user.pubkey) }); - } }, followingUser: async (pubkey: string) => { const userData = await get().store.getUser(pubkey); return userData?.following || false; }, - followingUserIds: [], getAllUsersFollowing: async () => { return get().store.getAllUsersFollowing(); }, diff --git a/packages/web/src/worker/worker.test.ts b/packages/web/src/worker/worker.test.ts index 614e8f8..a5b59bb 100644 --- a/packages/web/src/worker/worker.test.ts +++ b/packages/web/src/worker/worker.test.ts @@ -10,7 +10,7 @@ import { NWorker } from "./worker"; import "fake-indexeddb/auto"; import { ONE_DAY, ONE_HOUR, ONE_MINUTE } from "./worker-extra"; -indexedDB.deleteDatabase("nostros"); +indexedDB.deleteDatabase("nostrop"); const keypair = generateClientKeys(); diff --git a/packages/web/src/worker/worker.ts b/packages/web/src/worker/worker.ts index da96077..c8b50f9 100644 --- a/packages/web/src/worker/worker.ts +++ b/packages/web/src/worker/worker.ts @@ -356,14 +356,6 @@ export class NWorker { } } - if (this.options.isInWebWorker) { - const msg: WorkerEventFollowingUpdate = { - type: "following:update", - data: contacts.map((c) => c.key), - }; - postMessage(msg); - } - await this.requestInformation( { source: "users",