feat: mute/unmute on profile

This commit is contained in:
2023-07-30 11:07:22 +02:00
parent 249de1d9be
commit 811b1ceaec
7 changed files with 93 additions and 10 deletions

View File

@ -151,7 +151,7 @@ export function ChatMessage({
pubkey={ev.pubkey} pubkey={ev.pubkey}
profile={profile} profile={profile}
/> />
<Text content={ev.content} tags={ev.tags} /> <Text tags={ev.tags} content={ev.content} />
{(hasReactions || hasZaps) && ( {(hasReactions || hasZaps) && (
<div className="message-reactions"> <div className="message-reactions">
{hasZaps && ( {hasZaps && (

View File

@ -16,7 +16,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) {
if (pub) { if (pub) {
const newFollows = tags.filter((t) => t.at(1) !== pubkey); const newFollows = tags.filter((t) => t.at(1) !== pubkey);
const ev = await pub.generic((eb) => { 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) { for (const t of newFollows) {
eb.tag(t); eb.tag(t);
} }
@ -24,7 +24,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) {
}); });
console.debug(ev); console.debug(ev);
System.BroadcastEvent(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) { if (pub) {
const newFollows = [...tags, ["p", pubkey]]; const newFollows = [...tags, ["p", pubkey]];
const ev = await pub.generic((eb) => { 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) { for (const tag of newFollows) {
eb.tag(tag); eb.tag(tag);
} }
@ -41,7 +41,7 @@ export function LoggedInFollowButton({ pubkey }: { pubkey: string }) {
}); });
console.debug(ev); console.debug(ev);
System.BroadcastEvent(ev); System.BroadcastEvent(ev);
Login.setFollows(newFollows, unixNow()); Login.setFollows(newFollows, login.follows.content, unixNow());
} }
} }

View File

@ -357,3 +357,17 @@
height: 18px; height: 18px;
border-radius: unset; 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;
}

View File

@ -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 (
<AsyncButton
disabled={login.muted.timestamp === 0}
type="button"
className="btn delete-button"
onClick={isMuted ? unmute : mute}
>
{isMuted ? "Unmute" : "Mute"}
</AsyncButton>
);
}
export function MuteButton({ pubkey }: { pubkey: string }) {
const login = useLogin();
return login?.pubkey ? (
<LoggedInMuteButton loggedIn={login.pubkey} pubkey={pubkey} />
) : null;
}

View File

@ -65,11 +65,10 @@ export function useLoginEvents(pubkey?: string, leaveOpen = false) {
setUserEmojis(ev.tags); setUserEmojis(ev.tags);
} }
if (ev?.kind === MUTED) { if (ev?.kind === MUTED) {
// todo: decrypt ev.content tags Login.setMuted(ev.tags, ev.content, ev.created_at);
Login.setMuted(ev.tags, ev.created_at);
} }
if (ev?.kind === EventKind.ContactList) { 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) { if (ev?.kind === EventKind.Relays) {
Login.setRelays(ev.tags, ev.created_at); Login.setRelays(ev.tags, ev.created_at);

View File

@ -12,6 +12,7 @@ export enum LoginType {
interface ReplaceableTags { interface ReplaceableTags {
tags: Array<string[]>; tags: Array<string[]>;
content: "";
timestamp: number; timestamp: number;
} }
@ -72,11 +73,12 @@ export class LoginStore extends ExternalStore<LoginSession | undefined> {
return this.#session ? { ...this.#session } : undefined; return this.#session ? { ...this.#session } : undefined;
} }
setFollows(follows: Array<string>, ts: number) { setFollows(follows: Array<string>, content: string, ts: number) {
if (this.#session.follows.timestamp >= ts) { if (this.#session.follows.timestamp >= ts) {
return; return;
} }
this.#session.follows.tags = follows; this.#session.follows.tags = follows;
this.#session.follows.content = content;
this.#session.follows.timestamp = ts; this.#session.follows.timestamp = ts;
this.#save(); this.#save();
} }
@ -86,11 +88,12 @@ export class LoginStore extends ExternalStore<LoginSession | undefined> {
this.#save(); this.#save();
} }
setMuted(muted: Array<string[]>, ts: number) { setMuted(muted: Array<string[]>, content: string, ts: number) {
if (this.#session.muted.timestamp >= ts) { if (this.#session.muted.timestamp >= ts) {
return; return;
} }
this.#session.muted.tags = muted; this.#session.muted.tags = muted;
this.#session.muted.content = content;
this.#session.muted.timestamp = ts; this.#session.muted.timestamp = ts;
this.#save(); this.#save();
} }

View File

@ -15,6 +15,7 @@ import { Icon } from "element/icon";
import { SendZapsDialog } from "element/send-zap"; import { SendZapsDialog } from "element/send-zap";
import { VideoTile } from "element/video-tile"; import { VideoTile } from "element/video-tile";
import { FollowButton } from "element/follow-button"; import { FollowButton } from "element/follow-button";
import { MuteButton } from "element/mute-button";
import { useProfile } from "hooks/profile"; import { useProfile } from "hooks/profile";
import useTopZappers from "hooks/top-zappers"; import useTopZappers from "hooks/top-zappers";
import { Text } from "element/text"; import { Text } from "element/text";
@ -131,6 +132,7 @@ export function ProfilePage() {
/> />
)} )}
<FollowButton pubkey={link.id} /> <FollowButton pubkey={link.id} />
<MuteButton pubkey={link.id} />
</div> </div>
<div className="profile-information"> <div className="profile-information">
{profile?.name && <h1 className="name">{profile.name}</h1>} {profile?.name && <h1 className="name">{profile.name}</h1>}