diff --git a/src/components/ProfileActions.svelte b/src/components/ProfileActions.svelte index 5d27bb8..9e2a00b 100644 --- a/src/components/ProfileActions.svelte +++ b/src/components/ProfileActions.svelte @@ -135,7 +135,7 @@ bind:position={actionsPos} placement="bottom-end" > - {#if !blockedByTarget} + {#if !blockedByTarget && !userBlocked} {@render dropdownItem( follow ? 'heroicons:user-minus-20-solid' : 'heroicons:user-plus-20-solid', follow ? 'unfollow' : 'follow', diff --git a/src/components/SettingsModerationTab.svelte b/src/components/SettingsModerationTab.svelte index 1d72d54..91ed3e4 100644 --- a/src/components/SettingsModerationTab.svelte +++ b/src/components/SettingsModerationTab.svelte @@ -3,17 +3,21 @@ import VirtualList from '@tutorlatin/svelte-tiny-virtual-list'; import type { Did } from '@atcute/lexicons'; import type { Preferences } from '$lib/at/pocket'; + import { allBacklinks, createBlock, deleteBlock, clients } from '$lib/state.svelte'; + import { blockSource } from '$lib'; interface Props { mutes: Did[]; currentPrefs: Preferences | null; onAddMute: (did: Did) => void; onRemoveMute: (did: Did) => void; + selectedAccount: Did | null; } - let { mutes, currentPrefs, onAddMute, onRemoveMute }: Props = $props(); + let { mutes, currentPrefs, onAddMute, onRemoveMute, selectedAccount }: Props = $props(); let newMuteInput = $state(''); + let newBlockInput = $state(''); const handleAddMute = () => { if (!newMuteInput.trim()) return; @@ -21,6 +25,36 @@ onAddMute(did); newMuteInput = ''; }; + + const blocks = $derived.by(() => { + if (!selectedAccount) return []; + const blockMap = allBacklinks.get(blockSource); + if (!blockMap) return []; + const blockedDids: Did[] = []; + for (const [subjectUri, didMap] of blockMap) { + if (didMap.has(selectedAccount)) { + const did = subjectUri.replace('at://', '') as Did; + blockedDids.push(did); + } + } + return blockedDids; + }); + + const handleAddBlock = async () => { + if (!newBlockInput.trim() || !selectedAccount) return; + const client = clients.get(selectedAccount); + if (!client) return; + const did = newBlockInput.trim() as Did; + await createBlock(client, did); + newBlockInput = ''; + }; + + const handleRemoveBlock = async (did: Did) => { + if (!selectedAccount) return; + const client = clients.get(selectedAccount); + if (!client) return; + await deleteBlock(client, did); + };
@@ -57,9 +91,38 @@ {/if}
- {#if currentPrefs} -

- last synced: {new Date(currentPrefs.updatedAt).toLocaleString()} -

- {/if} + +
+

blocked accounts

+
+
+ + +
+ {#if blocks.length > 0} +
+ + {#snippet item({ index, style }: { index: number; style: string })} + handleRemoveBlock(blocks[index])} + /> + {/snippet} + +
+ {:else} +

no blocked accounts

+ {/if} +
+
diff --git a/src/components/SettingsView.svelte b/src/components/SettingsView.svelte index cb6816e..48172f4 100644 --- a/src/components/SettingsView.svelte +++ b/src/components/SettingsView.svelte @@ -163,6 +163,7 @@ {currentPrefs} onAddMute={handleAddMute} onRemoveMute={handleRemoveMute} + {selectedAccount} /> {:else if tab === 'style'}