Various AT Protocol integrations with obsidian
20
fork

Configure Feed

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

refresh on card/collection/tag changes

+24 -40
+2 -2
src/sources/bookmark.ts
··· 194 194 })); 195 195 } 196 196 197 - renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, plugin: AtmospherePlugin): void { 197 + renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, onDataChange: () => void, plugin: AtmospherePlugin): void { 198 198 const section = container.createEl("div", { cls: "atmosphere-filter-section" }); 199 199 200 200 const titleRow = section.createEl("div", { cls: "atmosphere-filter-title-row" }); ··· 203 203 const createBtn = titleRow.createEl("button", { cls: "atmosphere-filter-create-btn" }); 204 204 setIcon(createBtn, "plus"); 205 205 createBtn.addEventListener("click", () => { 206 - new CreateTagModal(plugin, onChange).open(); 206 + new CreateTagModal(plugin, onDataChange).open(); 207 207 }); 208 208 209 209 const chips = section.createEl("div", { cls: "atmosphere-filter-chips" });
+2 -2
src/sources/margin.ts
··· 238 238 return filters; 239 239 } 240 240 241 - renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, plugin: AtmospherePlugin): void { 241 + renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, onDataChange: () => void, plugin: AtmospherePlugin): void { 242 242 const collectionsSection = container.createEl("div", { cls: "atmosphere-filter-section" }); 243 243 244 244 const collectionsTitleRow = collectionsSection.createEl("div", { cls: "atmosphere-filter-title-row" }); ··· 247 247 const createCollectionBtn = collectionsTitleRow.createEl("button", { cls: "atmosphere-filter-create-btn" }); 248 248 setIcon(createCollectionBtn, "plus"); 249 249 createCollectionBtn.addEventListener("click", () => { 250 - new CreateMarginCollectionModal(plugin, onChange).open(); 250 + new CreateMarginCollectionModal(plugin, onDataChange).open(); 251 251 }); 252 252 253 253 const collectionsChips = collectionsSection.createEl("div", { cls: "atmosphere-filter-chips" });
+2 -4
src/sources/semble.ts
··· 215 215 })); 216 216 } 217 217 218 - renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, plugin: AtmospherePlugin): void { 218 + renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, onDataChange: () => void, plugin: AtmospherePlugin): void { 219 219 const section = container.createEl("div", { cls: "atmosphere-filter-section" }); 220 220 221 221 const titleRow = section.createEl("div", { cls: "atmosphere-filter-title-row" }); ··· 224 224 const createBtn = titleRow.createEl("button", { cls: "atmosphere-filter-create-btn" }); 225 225 setIcon(createBtn, "plus"); 226 226 createBtn.addEventListener("click", () => { 227 - new CreateCollectionModal(plugin, onChange).open(); 227 + new CreateCollectionModal(plugin, onDataChange).open(); 228 228 }); 229 229 230 230 const chips = section.createEl("div", { cls: "atmosphere-filter-chips" }); ··· 238 238 onChange(); 239 239 }); 240 240 241 - // Get collections synchronously - note: this is a limitation 242 - // In a real app, we'd want to cache these or handle async properly 243 241 void this.getAvailableFilters().then(collections => { 244 242 for (const collection of collections) { 245 243 const chip = chips.createEl("button", {
+1 -1
src/sources/types.ts
··· 23 23 readonly name: "semble" | "bookmark" | "margin"; 24 24 fetchItems(filters: SourceFilter[], plugin: AtmospherePlugin): Promise<ATBookmarkItem[]>; 25 25 getAvailableFilters(): Promise<SourceFilter[]>; 26 - renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, plugin: AtmospherePlugin): void; 26 + renderFilterUI(container: HTMLElement, activeFilters: Map<string, SourceFilter>, onChange: () => void, onDataChange: () => void, plugin: AtmospherePlugin): void; 27 27 }
+5 -4
src/views/bookmarks.ts
··· 145 145 attr: { "aria-label": "Refresh bookmarks" } 146 146 }); 147 147 setIcon(refreshBtn, "refresh-cw"); 148 - refreshBtn.addEventListener("click", async () => { 148 + refreshBtn.addEventListener("click", () => { 149 149 refreshBtn.addClass("atmosphere-refresh-btn-spinning"); 150 - await this.refresh(); 150 + void this.refresh(); 151 151 refreshBtn.removeClass("atmosphere-refresh-btn-spinning"); 152 152 }); 153 153 ··· 158 158 filtersContainer, 159 159 sourceData.filters, 160 160 () => void this.render(), 161 + () => void this.refresh(), 161 162 this.plugin 162 163 ); 163 164 } ··· 172 173 return; 173 174 } 174 175 new CardDetailModal(this.plugin, item, () => { 175 - void this.render(); 176 + void this.refresh(); 176 177 }).open(); 177 178 }); 178 179 ··· 191 192 editBtn.addEventListener("click", (e) => { 192 193 e.stopPropagation(); 193 194 item.openEditModal(() => { 194 - void this.render(); 195 + void this.refresh(); 195 196 }); 196 197 }); 197 198 }
+12 -27
styles.css
··· 76 76 } 77 77 78 78 .atmosphere-refresh-btn { 79 - display: flex; 80 - align-items: center; 81 - justify-content: center; 82 - width: 32px; 83 - height: 32px; 84 - padding: 0; 85 79 background: transparent; 86 - border: 1px solid var(--background-modifier-border); 87 - border-radius: var(--radius-s); 88 - cursor: pointer; 80 + border: none; 89 81 color: var(--text-muted); 90 - transition: all 0.15s ease; 91 - flex-shrink: 0; 82 + cursor: pointer; 83 + padding: 4px; 84 + display: flex; 85 + align-items: center; 86 + opacity: 0.6; 87 + transition: opacity 0.15s ease; 92 88 } 93 89 94 90 .atmosphere-refresh-btn:hover { 95 - background: var(--background-modifier-hover); 96 - color: var(--text-normal); 97 - border-color: var(--background-modifier-border-hover); 91 + opacity: 1; 98 92 } 99 93 100 - .atmosphere-refresh-btn svg { 101 - width: 16px; 102 - height: 16px; 103 - } 104 - 105 - .atmosphere-refresh-btn-spinning svg { 106 - animation: atmosphere-spin 0.8s linear infinite; 94 + .atmosphere-refresh-btn-spinning { 95 + animation: atmosphere-spin 0.6s linear infinite; 107 96 } 108 97 109 98 @keyframes atmosphere-spin { 110 - from { 111 - transform: rotate(0deg); 112 - } 113 - to { 114 - transform: rotate(360deg); 115 - } 99 + from { transform: rotate(0deg); } 100 + to { transform: rotate(360deg); } 116 101 } 117 102 118 103 .atmosphere-filters {