AT protocol bookmarking platforms in obsidian
at client-cache 102 lines 2.8 kB view raw
1import { getSubscribedPublications } from "lib/standardsite"; 2import ATmarkPlugin from "main"; 3import { ItemView, WorkspaceLeaf } from "obsidian"; 4import { SiteStandardPublication } from "@atcute/standard-site"; 5import { ATRecord } from "lib"; 6 7export const VIEW_STANDARD_FEED = "standard-site-feed"; 8 9export class StandardFeedView extends ItemView { 10 plugin: ATmarkPlugin; 11 12 constructor(leaf: WorkspaceLeaf, plugin: ATmarkPlugin) { 13 super(leaf); 14 this.plugin = plugin; 15 } 16 17 getViewType() { 18 return VIEW_STANDARD_FEED; 19 } 20 21 getDisplayText() { 22 return "Feed"; 23 } 24 25 getIcon() { 26 return "rss"; 27 } 28 29 async onOpen() { 30 await this.render(); 31 } 32 33 async render() { 34 const container = this.contentEl; 35 container.empty(); 36 container.addClass("standard-site-view"); 37 this.renderHeader(container); 38 39 const loading = container.createEl("p", { text: "Loading feed..." }); 40 41 try { 42 const pubs = await getSubscribedPublications(this.plugin.client, this.plugin.settings.identifier); 43 loading.remove(); 44 45 if (pubs.length === 0) { 46 container.createEl("p", { text: "No subscriptions found. Subscribe to publications first." }); 47 return; 48 } 49 50 const list = container.createEl("div", { cls: "standard-site-list" }); 51 52 for (const pub of pubs) { 53 this.renderPublicationCard(list, pub); 54 } 55 } catch (error) { 56 loading.remove(); 57 const message = error instanceof Error ? error.message : String(error); 58 container.createEl("p", { text: `Failed to load feed: ${message}`, cls: "standard-site-error" }); 59 } 60 } 61 62 private renderPublicationCard(container: HTMLElement, pub: ATRecord<SiteStandardPublication.Main>) { 63 const card = container.createEl("div", { cls: "standard-site-publication" }); 64 65 // Header with name 66 const header = card.createEl("div", { cls: "standard-site-publication-header" }); 67 header.createEl("h3", { 68 text: pub.value.name, 69 cls: "standard-site-publication-name" 70 }); 71 72 // Body 73 const body = card.createEl("div", { cls: "standard-site-publication-body" }); 74 75 // URL 76 const urlLine = body.createEl("div", { cls: "standard-site-publication-url" }); 77 const link = urlLine.createEl("a", { text: pub.value.url, href: pub.value.url }); 78 link.setAttr("target", "_blank"); 79 80 // Description 81 if (pub.value.description) { 82 body.createEl("p", { 83 text: pub.value.description, 84 cls: "standard-site-publication-description" 85 }); 86 } 87 88 // Make card clickable 89 card.addClass("clickable"); 90 card.addEventListener("click", (e) => { 91 // Don't trigger if clicking the link 92 if ((e.target as HTMLElement).tagName !== "A") { 93 window.open(pub.value.url, "_blank"); 94 } 95 }); 96 } 97 98 renderHeader(container: HTMLElement) { 99 const header = container.createEl("div", { cls: "standard-site-header" }); 100 header.createEl("h2", { text: "Subscriptions" }); 101 } 102}