AT protocol bookmarking platforms in obsidian
at client-cache 113 lines 3.2 kB view raw
1import { Modal, Notice } from "obsidian"; 2import type ATmarkPlugin from "../main"; 3import { createMarginCollection } from "../lib"; 4 5export class CreateMarginCollectionModal 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 margin collection" }); 21 22 if (!this.plugin.client) { 23 // contentEl.createEl("p", { text: "Not Logged In. Please Login Using Settings." }); 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 iconGroup = form.createEl("div", { cls: "atmark-form-group" }); 38 iconGroup.createEl("label", { text: "Icon (optional)", attr: { for: "collection-icon" } }); 39 const iconInput = iconGroup.createEl("input", { 40 type: "text", 41 cls: "atmark-input", 42 attr: { id: "collection-icon" }, 43 }); 44 45 const descGroup = form.createEl("div", { cls: "atmark-form-group" }); 46 descGroup.createEl("label", { text: "Description", attr: { for: "collection-desc" } }); 47 const descInput = descGroup.createEl("textarea", { 48 cls: "atmark-textarea", 49 attr: { id: "collection-desc", placeholder: "Optional description", rows: "3" }, 50 }); 51 52 const actions = form.createEl("div", { cls: "atmark-modal-actions" }); 53 54 const cancelBtn = actions.createEl("button", { 55 text: "Cancel", 56 cls: "atmark-btn atmark-btn-secondary", 57 type: "button", 58 }); 59 cancelBtn.addEventListener("click", () => this.close()); 60 61 const createBtn = actions.createEl("button", { 62 text: "Create", 63 cls: "atmark-btn atmark-btn-primary", 64 type: "submit", 65 }); 66 67 form.addEventListener("submit", (e) => { 68 e.preventDefault(); 69 void this.handleSubmit(nameInput, iconInput, descInput, createBtn); 70 }); 71 72 nameInput.focus(); 73 } 74 75 private async handleSubmit( 76 nameInput: HTMLInputElement, 77 iconInput: HTMLInputElement, 78 descInput: HTMLTextAreaElement, 79 createBtn: HTMLButtonElement 80 ) { 81 const name = nameInput.value.trim(); 82 if (!name) { 83 new Notice("Please enter a collection name"); 84 return; 85 } 86 87 createBtn.disabled = true; 88 createBtn.textContent = "Creating..."; 89 90 try { 91 await createMarginCollection( 92 this.plugin.client, 93 this.plugin.settings.identifier, 94 name, 95 descInput.value.trim() || undefined, 96 iconInput.value.trim() || undefined 97 ); 98 99 new Notice(`Created collection "${name}"`); 100 this.close(); 101 this.onSuccess?.(); 102 } catch (err) { 103 const message = err instanceof Error ? err.message : String(err); 104 new Notice(`Failed to create collection: ${message}`); 105 createBtn.disabled = false; 106 createBtn.textContent = "Create"; 107 } 108 } 109 110 onClose() { 111 this.contentEl.empty(); 112 } 113}