import BookTrackerPlugin from "@src/main"; import { App, PluginSettingTab, Setting } from "obsidian"; import { FileSuggest } from "./suggesters/file"; import { FolderSuggest } from "./suggesters/folder"; import { FieldSuggest } from "./suggesters/field"; export interface BookTrackerPluginSettings { templateFile: string; tbrDirectory: string; fileNameFormat: string; downloadCovers: boolean; coverDirectory: string; groupCoversByFirstLetter: boolean; overwriteExistingCovers: boolean; statusProperty: string; startDateProperty: string; endDateProperty: string; ratingProperty: string; pageLengthProperty: string; readingLogDirectory: string; } export const DEFAULT_SETTINGS: BookTrackerPluginSettings = { templateFile: "", tbrDirectory: "books/tbr", fileNameFormat: "{{title}} - {{authors}}", downloadCovers: false, coverDirectory: "images/covers", groupCoversByFirstLetter: true, overwriteExistingCovers: false, statusProperty: "status", startDateProperty: "startDate", endDateProperty: "endDate", ratingProperty: "rating", pageLengthProperty: "pageLength", readingLogDirectory: "reading-logs", }; export class BookTrackerSettingTab extends PluginSettingTab { constructor(app: App, private plugin: BookTrackerPlugin) { super(app, plugin); } heading(text: string): void { const header = document.createDocumentFragment(); header.createEl("h2", { text }); new Setting(this.containerEl).setHeading().setName(text); } display(): void { this.containerEl.empty(); this.containerEl.classList.add("obt-settings"); this.heading("Book Creation Settings"); this.templateFileSetting(); this.tbrDirectorySetting(); this.fileNameFormatSetting(); this.heading("Cover Download Settings"); this.downloadCoversSetting(); this.coverDirectorySetting(); this.groupCoversByFirstLetterSetting(); this.overwriteExistingCoversSetting(); this.heading("Reading Progress Settings"); this.statusPropertySetting(); this.startDatePropertySetting(); this.endDatePropertySetting(); this.ratingPropertySetting(); this.pageLengthPropertySetting(); this.readingLogDirectorySetting(); } readingLogDirectorySetting() { return new Setting(this.containerEl) .setName("Reading Log Directory") .setDesc("Select the directory where reading logs will be stored") .addSearch((cb) => { try { new FolderSuggest(this.app, cb.inputEl); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("reading-logs") .setValue(this.plugin.settings.readingLogDirectory) .onChange(async (value) => { this.plugin.settings.readingLogDirectory = value; await this.plugin.saveSettings(); }); }); } pageLengthPropertySetting() { return new Setting(this.containerEl) .setName("Page Length Property") .setDesc( "Property used to track the total number of pages in a book." ) .addSearch((cb) => { try { new FieldSuggest(this.app, cb.inputEl, ["number"]); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("pageLength") .setValue(this.plugin.settings.pageLengthProperty) .onChange(async (value) => { this.plugin.settings.pageLengthProperty = value; await this.plugin.saveSettings(); }); }); } ratingPropertySetting() { return new Setting(this.containerEl) .setName("Rating Property") .setDesc("Property used to track the rating of a book.") .addSearch((cb) => { try { new FieldSuggest(this.app, cb.inputEl, ["number"]); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("rating") .setValue(this.plugin.settings.ratingProperty) .onChange(async (value) => { this.plugin.settings.ratingProperty = value; await this.plugin.saveSettings(); }); }); } endDatePropertySetting() { return new Setting(this.containerEl) .setName("End Date Property") .setDesc("Property used to track the end date of reading a book.") .addSearch((cb) => { try { new FieldSuggest(this.app, cb.inputEl, ["date"]); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("endDate") .setValue(this.plugin.settings.endDateProperty) .onChange(async (value) => { this.plugin.settings.endDateProperty = value; await this.plugin.saveSettings(); }); }); } startDatePropertySetting() { return new Setting(this.containerEl) .setName("Start Date Property") .setDesc("Property used to track the start date of reading a book.") .addSearch((cb) => { try { new FieldSuggest(this.app, cb.inputEl, ["date"]); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("startDate") .setValue(this.plugin.settings.startDateProperty) .onChange(async (value) => { this.plugin.settings.startDateProperty = value; await this.plugin.saveSettings(); }); }); } statusPropertySetting() { return new Setting(this.containerEl) .setName("Status Property") .setDesc("Property used to track the reading status of a book.") .addSearch((cb) => { try { new FieldSuggest(this.app, cb.inputEl, ["text"]); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("status") .setValue(this.plugin.settings.statusProperty) .onChange(async (value) => { this.plugin.settings.statusProperty = value; await this.plugin.saveSettings(); }); }); } overwriteExistingCoversSetting() { return new Setting(this.containerEl) .setName("Overwrite Existing Covers") .setDesc("Overwrite existing book covers when downloading new ones") .addToggle((cb) => { cb.setValue( this.plugin.settings.overwriteExistingCovers ).onChange(async (value) => { this.plugin.settings.overwriteExistingCovers = value; await this.plugin.saveSettings(); }); }); } groupCoversByFirstLetterSetting() { return new Setting(this.containerEl) .setName("Group Covers by First Letter") .setDesc( "Organize downloaded book covers into subdirectories based on the first letter of the book title" ) .addToggle((cb) => { cb.setValue( this.plugin.settings.groupCoversByFirstLetter ).onChange(async (value) => { this.plugin.settings.groupCoversByFirstLetter = value; await this.plugin.saveSettings(); }); }); } coverDirectorySetting() { return new Setting(this.containerEl) .setName("Cover Directory") .setDesc( "Select the directory where downloaded book covers will be stored" ) .addSearch((cb) => { try { new FolderSuggest(this.app, cb.inputEl); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("images/covers") .setValue(this.plugin.settings.coverDirectory) .onChange(async (value) => { this.plugin.settings.coverDirectory = value; await this.plugin.saveSettings(); }); }); } downloadCoversSetting() { return new Setting(this.containerEl) .setName("Download Covers") .setDesc( "Automatically download book covers when creating new entries" ) .addToggle((cb) => { cb.setValue(this.plugin.settings.downloadCovers).onChange( async (value) => { this.plugin.settings.downloadCovers = value; await this.plugin.saveSettings(); } ); }); } fileNameFormatSetting() { const fileNameFormatDesc = document.createDocumentFragment(); fileNameFormatDesc.createDiv({ text: "Format for the file name of new book entries.", }); fileNameFormatDesc.createDiv({ text: "Use {{title}} and {{authors}} as placeholders.", }); new Setting(this.containerEl) .setName("File Name Format") .setDesc(fileNameFormatDesc) .addText((cb) => { cb.setPlaceholder("{{title}} - {{authors}}") .setValue(this.plugin.settings.fileNameFormat) .onChange(async (value) => { this.plugin.settings.fileNameFormat = value; await this.plugin.saveSettings(); }); }); } tbrDirectorySetting() { return new Setting(this.containerEl) .setName("To Be Read Directory") .setDesc( "Select the directory where new book entries will be created" ) .addSearch((cb) => { try { new FolderSuggest(this.app, cb.inputEl); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } const { containerEl } = this; cb.setPlaceholder("books/tbr") .setValue(this.plugin.settings.tbrDirectory) .onChange(async (value) => { this.plugin.settings.tbrDirectory = value; await this.plugin.saveSettings(); }); }); } templateFileSetting() { return new Setting(this.containerEl) .setName("Template File") .setDesc("Select the template file to use for new book entries") .addSearch((cb) => { try { new FileSuggest(this.app, cb.inputEl); } catch { // If the suggest fails, we can just ignore it. // This might happen if the plugin is not fully loaded yet. } cb.setPlaceholder("templates/book-template") .setValue(this.plugin.settings.templateFile) .onChange(async (value) => { this.plugin.settings.templateFile = value; await this.plugin.saveSettings(); }); }); } }