(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 124 lines 3.5 kB view raw
1import { atom } from "nanostores"; 2import { getPreferences, updatePreferences } from "../api/client"; 3import type { 4 LabelerSubscription, 5 LabelPreference, 6 LabelVisibility, 7} from "../types"; 8 9export interface Preferences { 10 externalLinkSkippedHostnames: string[]; 11 subscribedLabelers: LabelerSubscription[]; 12 labelPreferences: LabelPreference[]; 13 disableExternalLinkWarning: boolean; 14 enableCommunityBookmarks: boolean; 15} 16 17export const $preferences = atom<Preferences>({ 18 externalLinkSkippedHostnames: [], 19 subscribedLabelers: [], 20 labelPreferences: [], 21 disableExternalLinkWarning: false, 22 enableCommunityBookmarks: true, 23}); 24 25export async function loadPreferences() { 26 const prefs = await getPreferences(); 27 $preferences.set({ 28 externalLinkSkippedHostnames: prefs.externalLinkSkippedHostnames || [], 29 subscribedLabelers: prefs.subscribedLabelers || [], 30 labelPreferences: prefs.labelPreferences || [], 31 disableExternalLinkWarning: !!prefs.disableExternalLinkWarning, 32 enableCommunityBookmarks: !!prefs.enableCommunityBookmarks, 33 }); 34} 35 36export async function addSkippedHostname(hostname: string) { 37 const current = $preferences.get(); 38 if (current.externalLinkSkippedHostnames.includes(hostname)) return; 39 40 const updated = { 41 ...current, 42 externalLinkSkippedHostnames: [ 43 ...current.externalLinkSkippedHostnames, 44 hostname, 45 ], 46 }; 47 $preferences.set(updated); 48 await updatePreferences(updated); 49} 50 51export async function addLabeler(did: string) { 52 const current = $preferences.get(); 53 if (current.subscribedLabelers.some((l) => l.did === did)) return; 54 55 const updated = { 56 ...current, 57 subscribedLabelers: [...current.subscribedLabelers, { did }], 58 }; 59 $preferences.set(updated); 60 await updatePreferences(updated); 61} 62 63export async function removeLabeler(did: string) { 64 const current = $preferences.get(); 65 const updated = { 66 ...current, 67 subscribedLabelers: current.subscribedLabelers.filter((l) => l.did !== did), 68 }; 69 $preferences.set(updated); 70 await updatePreferences(updated); 71} 72 73export async function setLabelVisibility( 74 labelerDid: string, 75 label: string, 76 visibility: LabelVisibility, 77) { 78 const current = $preferences.get(); 79 const filtered = current.labelPreferences.filter( 80 (p) => !(p.labelerDid === labelerDid && p.label === label), 81 ); 82 const newPrefs = 83 visibility === "warn" 84 ? filtered 85 : [...filtered, { labelerDid, label, visibility }]; 86 const updated = { ...current, labelPreferences: newPrefs }; 87 $preferences.set(updated); 88 await updatePreferences(updated); 89} 90 91export function getLabelVisibility( 92 labelerDid: string, 93 label: string, 94): LabelVisibility { 95 const prefs = $preferences.get(); 96 const pref = prefs.labelPreferences.find( 97 (p) => p.labelerDid === labelerDid && p.label === label, 98 ); 99 return pref?.visibility || "warn"; 100} 101 102export async function setDisableExternalLinkWarning(disabled: boolean) { 103 const current = $preferences.get(); 104 if (current.disableExternalLinkWarning === disabled) return; 105 106 const updated = { 107 ...current, 108 disableExternalLinkWarning: disabled, 109 }; 110 $preferences.set(updated); 111 await updatePreferences(updated); 112} 113 114export async function setEnableCommunityBookmarks(enabled: boolean) { 115 const current = $preferences.get(); 116 if (current.enableCommunityBookmarks === enabled) return; 117 118 const updated = { 119 ...current, 120 enableCommunityBookmarks: enabled, 121 }; 122 $preferences.set(updated); 123 await updatePreferences(updated); 124}