Various AT Protocol integrations with obsidian
at main 72 lines 1.9 kB view raw
1import type { Client } from "@atcute/client"; 2import { getProfile } from "../lib"; 3 4export interface ProfileData { 5 did: string; 6 handle: string; 7 displayName?: string; 8 avatar?: string; 9} 10 11export async function fetchProfileData(client: Client, actor: string): Promise<ProfileData | null> { 12 try { 13 const resp = await getProfile(client, actor); 14 if (!resp.ok) return null; 15 16 return { 17 did: resp.data.did, 18 handle: resp.data.handle, 19 displayName: resp.data.displayName, 20 avatar: resp.data.avatar, 21 }; 22 } catch (e) { 23 console.error("Failed to fetch profile:", e); 24 return null; 25 } 26} 27 28export function renderProfileIcon( 29 container: HTMLElement, 30 profile: ProfileData | null, 31 onClick?: () => void 32): HTMLElement { 33 const wrapper = container.createEl("div", { cls: "atmosphere-profile-icon" }); 34 35 if (!profile) { 36 // Fallback when no profile data 37 const placeholder = wrapper.createEl("div", { cls: "atmosphere-avatar-placeholder" }); 38 placeholder.createEl("span", { text: "?" }); 39 return wrapper; 40 } 41 42 const avatarBtn = wrapper.createEl("button", { cls: "atmosphere-avatar-btn" }); 43 44 if (profile.avatar) { 45 const img = avatarBtn.createEl("img", { cls: "atmosphere-avatar-img" }); 46 img.src = profile.avatar; 47 img.alt = profile.displayName || profile.handle; 48 } else { 49 // Fallback initials 50 const initials = (profile.displayName || profile.handle) 51 .split(" ") 52 .map(w => w[0]) 53 .slice(0, 2) 54 .join("") 55 .toUpperCase(); 56 avatarBtn.createEl("span", { text: initials, cls: "atmosphere-avatar-initials" }); 57 } 58 59 const info = wrapper.createEl("div", { cls: "atmosphere-profile-info" }); 60 61 if (profile.displayName) { 62 info.createEl("span", { text: profile.displayName, cls: "atmosphere-profile-name" }); 63 } 64 65 info.createEl("span", { text: `@${profile.handle}`, cls: "atmosphere-profile-handle" }); 66 67 if (onClick) { 68 avatarBtn.addEventListener("click", onClick); 69 } 70 71 return wrapper; 72}