AT protocol bookmarking platforms in obsidian
at client-cache 103 lines 2.7 kB view raw
1import { Modal, Notice } from "obsidian"; 2import type ATmarkPlugin from "../main"; 3import { createCollection } from "../lib"; 4 5export class CreateCollectionModal extends Modal { 6 plugin: ATmarkPlugin; 7 onSuccess?: () => void; 8 9 constructor(plugin: ATmarkPlugin, onSuccess?: () => void) { 10 super(plugin.app); 11 this.plugin = plugin; 12 this.onSuccess = onSuccess; 13 } 14 15 onOpen() { 16 const { contentEl } = this; 17 contentEl.empty(); 18 contentEl.addClass("atmark-modal"); 19 20 contentEl.createEl("h2", { text: "New collection" }); 21 22 if (!this.plugin.client) { 23 contentEl.createEl("p", { text: "Not connected." }); 24 return; 25 } 26 27 const form = contentEl.createEl("form", { cls: "atmark-form" }); 28 29 const nameGroup = form.createEl("div", { cls: "atmark-form-group" }); 30 nameGroup.createEl("label", { text: "Name", attr: { for: "collection-name" } }); 31 const nameInput = nameGroup.createEl("input", { 32 type: "text", 33 cls: "atmark-input", 34 attr: { id: "collection-name", placeholder: "Collection name", required: "true" }, 35 }); 36 37 const descGroup = form.createEl("div", { cls: "atmark-form-group" }); 38 descGroup.createEl("label", { text: "Description", attr: { for: "collection-desc" } }); 39 const descInput = descGroup.createEl("textarea", { 40 cls: "atmark-textarea", 41 attr: { id: "collection-desc", placeholder: "Optional description", rows: "3" }, 42 }); 43 44 const actions = form.createEl("div", { cls: "atmark-modal-actions" }); 45 46 const cancelBtn = actions.createEl("button", { 47 text: "Cancel", 48 cls: "atmark-btn atmark-btn-secondary", 49 type: "button", 50 }); 51 cancelBtn.addEventListener("click", () => this.close()); 52 53 const createBtn = actions.createEl("button", { 54 text: "Create", 55 cls: "atmark-btn atmark-btn-primary", 56 type: "submit", 57 }); 58 59 form.addEventListener("submit", (e) => { 60 e.preventDefault(); 61 void this.handleSubmit(nameInput, descInput, createBtn); 62 }); 63 64 nameInput.focus(); 65 } 66 67 private async handleSubmit( 68 nameInput: HTMLInputElement, 69 descInput: HTMLTextAreaElement, 70 createBtn: HTMLButtonElement 71 ) { 72 const name = nameInput.value.trim(); 73 if (!name) { 74 new Notice("Please enter a collection name"); 75 return; 76 } 77 78 createBtn.disabled = true; 79 createBtn.textContent = "Creating..."; 80 81 try { 82 await createCollection( 83 this.plugin.client, 84 this.plugin.settings.identifier, 85 name, 86 descInput.value.trim() 87 ); 88 89 new Notice(`Created collection "${name}"`); 90 this.close(); 91 this.onSuccess?.(); 92 } catch (err) { 93 const message = err instanceof Error ? err.message : String(err); 94 new Notice(`Failed to create collection: ${message}`); 95 createBtn.disabled = false; 96 createBtn.textContent = "Create"; 97 } 98 } 99 100 onClose() { 101 this.contentEl.empty(); 102 } 103}