From 811b1ceaec3d1172c861ebd1de4cbab8173ea2a8 Mon Sep 17 00:00:00 2001 From: verbiricha Date: Sun, 30 Jul 2023 11:07:22 +0200 Subject: [PATCH] feat: mute/unmute on profile --- src/element/chat-message.tsx | 2 +- src/element/follow-button.tsx | 8 ++--- src/element/live-chat.css | 14 ++++++++ src/element/mute-button.tsx | 65 +++++++++++++++++++++++++++++++++++ src/hooks/login.ts | 5 ++- src/login.ts | 7 ++-- src/pages/profile-page.tsx | 2 ++ 7 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 src/element/mute-button.tsx diff --git a/src/element/chat-message.tsx b/src/element/chat-message.tsx index b8e11cd..8bb84b8 100644 --- a/src/element/chat-message.tsx +++ b/src/element/chat-message.tsx @@ -151,7 +151,7 @@ export function ChatMessage({ pubkey={ev.pubkey} profile={profile} /> - + {(hasReactions || hasZaps) && (
{hasZaps && ( diff --git a/src/element/follow-button.tsx b/src/element/follow-button.tsx index f11a7eb..06b3fc7 100644 --- a/src/element/follow-button.tsx +++ b/src/element/follow-button.tsx @@ -16,7 +16,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) { if (pub) { const newFollows = tags.filter((t) => t.at(1) !== pubkey); const ev = await pub.generic((eb) => { - eb.kind(EventKind.ContactList).content(JSON.stringify(login.relays)); + eb.kind(EventKind.ContactList).content(login.follows.content); for (const t of newFollows) { eb.tag(t); } @@ -24,7 +24,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) { }); console.debug(ev); System.BroadcastEvent(ev); - Login.setFollows(newFollows, unixNow()); + Login.setFollows(newFollows, login.follows.content, unixNow()); } } @@ -33,7 +33,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) { if (pub) { const newFollows = [...tags, ["p", pubkey]]; const ev = await pub.generic((eb) => { - eb.kind(EventKind.ContactList).content(JSON.stringify(login.relays)); + eb.kind(EventKind.ContactList).content(login.follows.content); for (const tag of newFollows) { eb.tag(tag); } @@ -41,7 +41,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) { }); console.debug(ev); System.BroadcastEvent(ev); - Login.setFollows(newFollows, unixNow()); + Login.setFollows(newFollows, login.follows.content, unixNow()); } } diff --git a/src/element/live-chat.css b/src/element/live-chat.css index 02924fc..1f86b85 100644 --- a/src/element/live-chat.css +++ b/src/element/live-chat.css @@ -357,3 +357,17 @@ height: 18px; border-radius: unset; } + +.message .message-container { + display: flex; + flex-wrap: wrap; + gap: 4px; +} + +.message .message-container .markdown p { + font-size: 14px; +} + +.message .message-container .markdown > p { + margin: 0; +} diff --git a/src/element/mute-button.tsx b/src/element/mute-button.tsx new file mode 100644 index 0000000..cc75eda --- /dev/null +++ b/src/element/mute-button.tsx @@ -0,0 +1,65 @@ +import { unixNow } from "@snort/shared"; + +import { useLogin } from "hooks/login"; +import AsyncButton from "element/async-button"; +import { Login, System } from "index"; +import { MUTED } from "const"; + +export function LoggedInMuteButton({ pubkey }: { pubkey: string }) { + const login = useLogin(); + const tags = login.muted.tags; + const muted = tags.filter((t) => t.at(0) === "p"); + const isMuted = muted.find((t) => t.at(1) === pubkey); + + async function unmute() { + const pub = login?.publisher(); + if (pub) { + const newMuted = tags.filter((t) => t.at(1) !== pubkey); + const ev = await pub.generic((eb) => { + eb.kind(MUTED).content(login.muted.content); + for (const t of newMuted) { + eb.tag(t); + } + return eb; + }); + console.debug(ev); + System.BroadcastEvent(ev); + Login.setMuted(newMuted, login.muted.content, unixNow()); + } + } + + async function mute() { + const pub = login?.publisher(); + if (pub) { + const newMuted = [...tags, ["p", pubkey]]; + const ev = await pub.generic((eb) => { + eb.kind(MUTED).content(login.muted.content); + for (const tag of newMuted) { + eb.tag(tag); + } + return eb; + }); + console.debug(ev); + System.BroadcastEvent(ev); + Login.setMuted(newMuted, login.muted.content, unixNow()); + } + } + + return ( + + {isMuted ? "Unmute" : "Mute"} + + ); +} + +export function MuteButton({ pubkey }: { pubkey: string }) { + const login = useLogin(); + return login?.pubkey ? ( + + ) : null; +} diff --git a/src/hooks/login.ts b/src/hooks/login.ts index 14db575..9b383aa 100644 --- a/src/hooks/login.ts +++ b/src/hooks/login.ts @@ -65,11 +65,10 @@ export function useLoginEvents(pubkey?: string, leaveOpen = false) { setUserEmojis(ev.tags); } if (ev?.kind === MUTED) { - // todo: decrypt ev.content tags - Login.setMuted(ev.tags, ev.created_at); + Login.setMuted(ev.tags, ev.content, ev.created_at); } if (ev?.kind === EventKind.ContactList) { - Login.setFollows(ev.tags, ev.created_at); + Login.setFollows(ev.tags, ev.content, ev.created_at); } if (ev?.kind === EventKind.Relays) { Login.setRelays(ev.tags, ev.created_at); diff --git a/src/login.ts b/src/login.ts index 4a64bab..573c68f 100644 --- a/src/login.ts +++ b/src/login.ts @@ -12,6 +12,7 @@ export enum LoginType { interface ReplaceableTags { tags: Array; + content: ""; timestamp: number; } @@ -72,11 +73,12 @@ export class LoginStore extends ExternalStore { return this.#session ? { ...this.#session } : undefined; } - setFollows(follows: Array, ts: number) { + setFollows(follows: Array, content: string, ts: number) { if (this.#session.follows.timestamp >= ts) { return; } this.#session.follows.tags = follows; + this.#session.follows.content = content; this.#session.follows.timestamp = ts; this.#save(); } @@ -86,11 +88,12 @@ export class LoginStore extends ExternalStore { this.#save(); } - setMuted(muted: Array, ts: number) { + setMuted(muted: Array, content: string, ts: number) { if (this.#session.muted.timestamp >= ts) { return; } this.#session.muted.tags = muted; + this.#session.muted.content = content; this.#session.muted.timestamp = ts; this.#save(); } diff --git a/src/pages/profile-page.tsx b/src/pages/profile-page.tsx index 34dab78..75864fd 100644 --- a/src/pages/profile-page.tsx +++ b/src/pages/profile-page.tsx @@ -15,6 +15,7 @@ import { Icon } from "element/icon"; import { SendZapsDialog } from "element/send-zap"; import { VideoTile } from "element/video-tile"; import { FollowButton } from "element/follow-button"; +import { MuteButton } from "element/mute-button"; import { useProfile } from "hooks/profile"; import useTopZappers from "hooks/top-zappers"; import { Text } from "element/text"; @@ -131,6 +132,7 @@ export function ProfilePage() { /> )} +
{profile?.name &&

{profile.name}

}