From 9175c76d7f03c0c62323202fdab3e4ab35854855 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Fri, 9 Jan 2026 09:00:32 -0500 Subject: Hide muted chats --- src/lib/nip51.ts | 47 ++++++++++++++++++++++++++++++++++++++++ src/locales/en.json | 2 ++ src/routes/(app)/dm/+page.svelte | 24 ++++++++++++++++---- 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/lib/nip51.ts diff --git a/src/lib/nip51.ts b/src/lib/nip51.ts new file mode 100644 index 00000000..142f0bbf --- /dev/null +++ b/src/lib/nip51.ts @@ -0,0 +1,47 @@ +import { SimplePool } from 'nostr-tools/pool'; +const pool = new SimplePool(); + +import { PUBLIC_DM_RELAYS } from '$env/static/public'; +const DM_RELAYS_LIST = PUBLIC_DM_RELAYS.split(','); + +// export const mute = async (pubkey: string, hidden: bool) => { + +// } + +// export const unmute = async (pubkey: string) => { + +// } + +export const mutedAccounts = async (user: object): Set => { + const { shown, hidden } = await getMuteLists(user); + let muted = new Set(); + for (const pubkey of shown) { + muted.add(pubkey); + } + for (const pubkey of hidden) { + muted.add(pubkey); + } + return muted; +} + +const getMuteLists = async (user: object): object => { + const listEvents = await pool.querySync( + DM_RELAYS_LIST, { kinds: [10000], "authors": [user.pubkey], limit: 1 } + ); + if (listEvents.length == 0) { + return { shown: [], hidden: [] }; + } + + let shown = []; + for (const tag of listEvents[0].tags) { + if (tag.length >= 2 && tag[0] == "p") { + shown.push(tag[1]); + } + } + + return { shown, hidden: [] }; +} + +// const publishMuteList = async (shown: Array, hidden: Array) => { + +// } diff --git a/src/locales/en.json b/src/locales/en.json index e7b8a90f..16e60d1f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -102,6 +102,8 @@ "findByPubkey": "Find by pubkey", "recipientMsg": "You are sending nostr messages to [R].", "sendMessage": "Send Message", + "mute": "Mute", + "unmute": "Unmute", "expiry": "Enable message expiry", "cantSendExpiring": "None of [R]'s DM relays support message expiry. You can't send expiring messages to them.", "fadedWarning": "To avoid metadata leaks, messages expire at a random time up to 2 days after you specify; each message has its own random expiry time. Messages which appear faded are close to expiring; nearby messages may be missing.", diff --git a/src/routes/(app)/dm/+page.svelte b/src/routes/(app)/dm/+page.svelte index 32b39def..336733e0 100644 --- a/src/routes/(app)/dm/+page.svelte +++ b/src/routes/(app)/dm/+page.svelte @@ -10,6 +10,7 @@ import { getMessageRumours } from '$lib/nip17'; import * as libnip17 from '$lib/nip17'; import { npubEncode, decode } from 'nostr-tools/nip19'; + import { mutedAccounts } from '$lib/nip51'; import { sign, getPrivateKey, pTagKeys } from '$lib/nostr'; import { t } from "$lib/translations"; import { theme } from "$lib/store"; @@ -17,6 +18,9 @@ let { data } = $props(); const { user } = data; + let muted = $state(new Set()); + mutedAccounts(user).then((m) => muted = m); + /// chat selection const usernameFromPubkey = async (pubkey: string): string => { const response = await fetch(`/api/users/${pubkey}`); @@ -129,9 +133,18 @@ let canSendExpiring = $state(false); let nostrUserInfo = $state({}); + const includesPubkey = (chats: object[], pubkey: string) => { + for (const c of chats) { + if (c.pubkey === pubkey) { + return true; + } + } + return false; + } + const selectChat = (c: object) => { selectedChat = c; - if (!chats.includes(c)) { + if (!includesPubkey(chats, c.pubkey)) { chats.unshift(c); } userInfo(selectedChat.pubkey).then(info => nostrUserInfo = info); @@ -394,9 +407,11 @@ {/if} {#if !creatingNewChat} {#each chats as c} - + {#if (selectedChat && selectedChat.pubkey === c.pubkey) || !(muted && muted.has(c.pubkey))} + + {/if} {/each} {:else if searchQuery !== ""}