AT protocol bookmarking platforms in obsidian

fix lint

+86 -70
+35 -27
src/components/createCollectionModal.ts
··· 17 17 contentEl.empty(); 18 18 contentEl.addClass("semble-collection-modal"); 19 19 20 - contentEl.createEl("h2", { text: "New Collection" }); 20 + contentEl.createEl("h2", { text: "New collection" }); 21 21 22 22 if (!this.plugin.client) { 23 23 contentEl.createEl("p", { text: "Not connected." }); ··· 59 59 type: "submit", 60 60 }); 61 61 62 - form.addEventListener("submit", async (e) => { 62 + form.addEventListener("submit", (e) => { 63 63 e.preventDefault(); 64 + void this.handleSubmit(nameInput, descInput, createBtn); 65 + }); 64 66 65 - const name = nameInput.value.trim(); 66 - if (!name) { 67 - new Notice("Please enter a collection name"); 68 - return; 69 - } 67 + // Focus name input 68 + nameInput.focus(); 69 + } 70 70 71 - createBtn.disabled = true; 72 - createBtn.textContent = "Creating..."; 71 + private async handleSubmit( 72 + nameInput: HTMLInputElement, 73 + descInput: HTMLTextAreaElement, 74 + createBtn: HTMLButtonElement 75 + ) { 76 + const name = nameInput.value.trim(); 77 + if (!name) { 78 + new Notice("Please enter a collection name"); 79 + return; 80 + } 73 81 74 - try { 75 - await createCollection( 76 - this.plugin.client!, 77 - this.plugin.settings.identifier, 78 - name, 79 - descInput.value.trim() 80 - ); 82 + createBtn.disabled = true; 83 + createBtn.textContent = "Creating..."; 81 84 82 - new Notice(`Created collection "${name}"`); 83 - this.close(); 84 - this.onSuccess?.(); 85 - } catch (e) { 86 - new Notice(`Failed to create collection: ${e}`); 87 - createBtn.disabled = false; 88 - createBtn.textContent = "Create"; 89 - } 90 - }); 85 + try { 86 + await createCollection( 87 + this.plugin.client!, 88 + this.plugin.settings.identifier, 89 + name, 90 + descInput.value.trim() 91 + ); 91 92 92 - // Focus name input 93 - nameInput.focus(); 93 + new Notice(`Created collection "${name}"`); 94 + this.close(); 95 + this.onSuccess?.(); 96 + } catch (err) { 97 + const message = err instanceof Error ? err.message : String(err); 98 + new Notice(`Failed to create collection: ${message}`); 99 + createBtn.disabled = false; 100 + createBtn.textContent = "Create"; 101 + } 94 102 } 95 103 96 104 onClose() {
+20 -17
src/components/editCardModal.ts
··· 42 42 contentEl.empty(); 43 43 contentEl.addClass("semble-collection-modal"); 44 44 45 - contentEl.createEl("h2", { text: "Edit Collections" }); 45 + contentEl.createEl("h2", { text: "Edit collections" }); 46 46 47 47 if (!this.plugin.client) { 48 48 contentEl.createEl("p", { text: "Not connected." }); ··· 89 89 })); 90 90 91 91 this.renderCollectionList(contentEl); 92 - } catch (e) { 92 + } catch (err) { 93 93 loading.remove(); 94 - contentEl.createEl("p", { text: `Error: ${e}`, cls: "semble-error" }); 94 + const message = err instanceof Error ? err.message : String(err); 95 + contentEl.createEl("p", { text: `Error: ${message}`, cls: "semble-error" }); 95 96 } 96 97 } 97 98 ··· 119 120 const actions = contentEl.createEl("div", { cls: "semble-modal-actions" }); 120 121 121 122 const deleteBtn = actions.createEl("button", { text: "Delete", cls: "semble-btn semble-btn-danger" }); 122 - deleteBtn.addEventListener("click", () => this.confirmDelete(contentEl)); 123 + deleteBtn.addEventListener("click", () => { this.confirmDelete(contentEl); }); 123 124 124 - const spacer = actions.createEl("div", { cls: "semble-spacer" }); 125 + actions.createEl("div", { cls: "semble-spacer" }); 125 126 126 127 const cancelBtn = actions.createEl("button", { text: "Cancel", cls: "semble-btn semble-btn-secondary" }); 127 - cancelBtn.addEventListener("click", () => this.close()); 128 + cancelBtn.addEventListener("click", () => { this.close(); }); 128 129 129 130 const saveBtn = actions.createEl("button", { text: "Save", cls: "semble-btn semble-btn-primary" }); 130 131 saveBtn.id = "semble-save-btn"; 131 132 saveBtn.disabled = true; 132 - saveBtn.addEventListener("click", () => this.saveChanges()); 133 + saveBtn.addEventListener("click", () => { void this.saveChanges(); }); 133 134 } 134 135 135 136 private confirmDelete(contentEl: HTMLElement) { 136 137 contentEl.empty(); 137 - contentEl.createEl("h2", { text: "Delete Card" }); 138 + contentEl.createEl("h2", { text: "Delete card" }); 138 139 contentEl.createEl("p", { text: "Delete this card?", cls: "semble-warning-text" }); 139 140 140 141 const actions = contentEl.createEl("div", { cls: "semble-modal-actions" }); ··· 142 143 const cancelBtn = actions.createEl("button", { text: "Cancel", cls: "semble-btn semble-btn-secondary" }); 143 144 cancelBtn.addEventListener("click", () => { 144 145 // Re-render the modal 145 - this.onOpen(); 146 + void this.onOpen(); 146 147 }); 147 148 148 149 const confirmBtn = actions.createEl("button", { text: "Delete", cls: "semble-btn semble-btn-danger" }); 149 - confirmBtn.addEventListener("click", () => this.deleteCard()); 150 + confirmBtn.addEventListener("click", () => { void this.deleteCard(); }); 150 151 } 151 152 152 153 private async deleteCard() { ··· 160 161 const rkey = this.cardUri.split("/").pop(); 161 162 if (!rkey) { 162 163 contentEl.empty(); 163 - contentEl.createEl("p", { text: "Invalid card URI.", cls: "semble-error" }); 164 + contentEl.createEl("p", { text: "Invalid card uri.", cls: "semble-error" }); 164 165 return; 165 166 } 166 167 ··· 174 175 new Notice("Card deleted"); 175 176 this.close(); 176 177 this.onSuccess?.(); 177 - } catch (e) { 178 + } catch (err) { 178 179 contentEl.empty(); 179 - contentEl.createEl("p", { text: `Failed to delete: ${e}`, cls: "semble-error" }); 180 + const message = err instanceof Error ? err.message : String(err); 181 + contentEl.createEl("p", { text: `Failed to delete: ${message}`, cls: "semble-error" }); 180 182 } 181 183 } 182 184 183 185 private updateSaveButton() { 184 - const saveBtn = document.getElementById("semble-save-btn") as HTMLButtonElement; 186 + const saveBtn = document.getElementById("semble-save-btn") as HTMLButtonElement | null; 185 187 if (!saveBtn) return; 186 188 187 189 // Check if any changes were made ··· 235 237 this.cardUri, 236 238 this.cardCid, 237 239 state.collection.uri, 238 - collectionResp.data.cid as string 240 + String(collectionResp.data.cid) 239 241 ); 240 242 } 241 243 ··· 251 253 252 254 this.close(); 253 255 this.onSuccess?.(); 254 - } catch (e) { 256 + } catch (err) { 255 257 contentEl.empty(); 256 - contentEl.createEl("p", { text: `Failed to save: ${e}`, cls: "semble-error" }); 258 + const message = err instanceof Error ? err.message : String(err); 259 + contentEl.createEl("p", { text: `Failed to save: ${message}`, cls: "semble-error" }); 257 260 } 258 261 } 259 262
+16 -13
src/views/cards.ts
··· 51 51 setCollection(uri: string | null, name: string) { 52 52 this.collectionUri = uri; 53 53 this.collectionName = name; 54 - this.render(); 54 + void this.render(); 55 55 } 56 56 57 57 async onOpen() { ··· 84 84 const links = allLinks.filter((link) => link.value.collection.uri === collectionUri); 85 85 86 86 // Get cards in collection 87 - const cardUris = new Set(links.map((link) => link.value.card.uri as string)); 88 - const cards = allCards.filter((card) => cardUris.has(card.uri as string)); 87 + const cardUris = new Set(links.map((link) => String(link.value.card.uri))); 88 + const cards = allCards.filter((card) => cardUris.has(String(card.uri))); 89 89 90 90 return cards; 91 91 } ··· 111 111 } else { 112 112 cards = await this.getAllCards(); 113 113 } 114 - } catch (e) { 114 + } catch (err) { 115 115 loading.remove(); 116 - container.createEl("p", { text: `Failed to load cards: ${e}`, cls: "semble-error" }); 116 + const message = err instanceof Error ? err.message : String(err); 117 + container.createEl("p", { text: `Failed to load cards: ${message}`, cls: "semble-error" }); 117 118 return; 118 119 } 119 120 120 121 const collectionsResp = await getCollections(this.plugin.client, this.plugin.settings.identifier); 121 122 if (!collectionsResp.ok) { 122 123 loading.remove(); 123 - container.createEl("p", { text: `Failed to load collections: ${collectionsResp.data?.error}`, cls: "semble-error" }); 124 + const errorMsg = collectionsResp.data?.error ? String(collectionsResp.data.error) : "Unknown error"; 125 + container.createEl("p", { text: `Failed to load collections: ${errorMsg}`, cls: "semble-error" }); 124 126 return; 125 127 } 126 128 const collections = collectionsResp.data?.records as unknown as CollectionRecord[]; ··· 139 141 for (const record of cards) { 140 142 try { 141 143 this.renderCard(grid, record); 142 - } catch (e) { 143 - console.log(JSON.stringify(record.value, null, 2)); 144 - console.error(`Failed to render card ${record.uri}: ${e}`); 144 + } catch (err) { 145 + const message = err instanceof Error ? err.message : String(err); 146 + console.error(`Failed to render card ${record.uri}: ${message}`); 145 147 } 146 148 } 147 - } catch (e) { 149 + } catch (err) { 148 150 loading.remove(); 149 - container.createEl("p", { text: `Failed to load: ${e}`, cls: "semble-error" }); 151 + const message = err instanceof Error ? err.message : String(err); 152 + container.createEl("p", { text: `Failed to load: ${message}`, cls: "semble-error" }); 150 153 } 151 154 } 152 155 ··· 159 162 const backBtn = nav.createEl("button", { cls: "semble-back-btn" }); 160 163 setIcon(backBtn, "arrow-left"); 161 164 backBtn.addEventListener("click", () => { 162 - this.plugin.activateView(VIEW_TYPE_SEMBLE_COLLECTIONS); 165 + void this.plugin.activateView(VIEW_TYPE_SEMBLE_COLLECTIONS); 163 166 }); 164 167 165 168 nav.createEl("span", { text: "Semble", cls: "semble-brand" }); ··· 208 211 addBtn.addEventListener("click", (e) => { 209 212 e.stopPropagation(); 210 213 new EditCardModal(this.plugin, record.uri, record.cid, () => { 211 - this.render(); 214 + void this.render(); 212 215 }).open(); 213 216 }); 214 217
+15 -13
src/views/collections.ts
··· 26 26 } 27 27 28 28 getDisplayText() { 29 - return "Semble Collections"; 29 + return "Semble collections"; 30 30 } 31 31 32 32 getIcon() { ··· 45 45 const view = leaf.view as SembleCardsView; 46 46 view.setCollection(uri, name); 47 47 48 - workspace.revealLeaf(leaf); 48 + void workspace.revealLeaf(leaf); 49 49 } 50 50 51 51 async render() { ··· 76 76 77 77 const createBtn = toolbar.createEl("button", { cls: "semble-create-btn" }); 78 78 setIcon(createBtn, "plus"); 79 - createBtn.createEl("span", { text: "New Collection" }); 79 + createBtn.createEl("span", { text: "New collection" }); 80 80 createBtn.addEventListener("click", () => { 81 - new CreateCollectionModal(this.plugin, () => this.render()).open(); 81 + new CreateCollectionModal(this.plugin, () => { void this.render(); }).open(); 82 82 }); 83 83 84 84 const allCardsBtn = toolbar.createEl("button", { cls: "semble-toolbar-btn" }); 85 85 setIcon(allCardsBtn, "layers"); 86 - allCardsBtn.createEl("span", { text: "All Cards" }); 86 + allCardsBtn.createEl("span", { text: "All cards" }); 87 87 allCardsBtn.addEventListener("click", () => { 88 - this.plugin.activateView(VIEW_TYPE_SEMBLE_CARDS); 88 + void this.plugin.activateView(VIEW_TYPE_SEMBLE_CARDS); 89 89 }); 90 90 91 91 const loading = container.createEl("p", { text: "Loading..." }); ··· 95 95 loading.remove(); 96 96 97 97 if (!resp.ok) { 98 - container.createEl("p", { text: `Error: ${resp.data?.error}`, cls: "semble-error" }); 98 + const errorMsg = resp.data?.error ? String(resp.data.error) : "Unknown error"; 99 + container.createEl("p", { text: `Error: ${errorMsg}`, cls: "semble-error" }); 99 100 return; 100 101 } 101 102 ··· 113 114 const card = grid.createEl("div", { cls: "semble-card" }); 114 115 115 116 card.addEventListener("click", () => { 116 - this.plugin.openCollection(record.uri, col.name); 117 + void this.plugin.openCollection(record.uri, col.name); 117 118 }); 118 119 119 - const header = card.createEl("div", { cls: "semble-card-header" }); 120 - header.createEl("span", { text: col.name, cls: "semble-card-title" }); 120 + const cardHeader = card.createEl("div", { cls: "semble-card-header" }); 121 + cardHeader.createEl("span", { text: col.name, cls: "semble-card-title" }); 121 122 122 - const accessIcon = header.createEl("span", { 123 + const accessIcon = cardHeader.createEl("span", { 123 124 cls: `semble-access-icon semble-access-${col.accessType.toLowerCase()}`, 124 125 attr: { "aria-label": col.accessType }, 125 126 }); ··· 143 144 }); 144 145 } 145 146 } 146 - } catch (e) { 147 + } catch (err) { 147 148 loading.remove(); 148 - container.createEl("p", { text: `Failed to load: ${e}`, cls: "semble-error" }); 149 + const message = err instanceof Error ? err.message : String(err); 150 + container.createEl("p", { text: `Failed to load: ${message}`, cls: "semble-error" }); 149 151 } 150 152 } 151 153