Add book folder setting to improve book suggester filtering

This commit is contained in:
Evan Fiordeliso 2025-06-30 10:29:41 -04:00
parent 76de66ca80
commit 217f66acf9
7 changed files with 60 additions and 39 deletions

View File

@ -17,12 +17,7 @@ export class ReadingLogCodeBlockRenderer extends SvelteCodeBlockRenderer<
typeof ReadingLogCodeBlockView typeof ReadingLogCodeBlockView
> { > {
constructor(contentEl: HTMLElement, plugin: BookTrackerPlugin) { constructor(contentEl: HTMLElement, plugin: BookTrackerPlugin) {
super(contentEl, ReadingLogCodeBlockView, { super(contentEl, ReadingLogCodeBlockView, { props: { plugin } });
props: {
app: plugin.app,
readingLog: plugin.readingLog,
},
});
} }
onunload() {} onunload() {}

View File

@ -1,21 +1,19 @@
<script lang="ts"> <script lang="ts">
import type { ReadingLog } from "@utils/storage";
import type { ReadingLogEntry } from "@src/types"; import type { ReadingLogEntry } from "@src/types";
import type { App } from "obsidian";
import { Edit, Trash, Plus } from "lucide-svelte"; import { Edit, Trash, Plus } from "lucide-svelte";
import { ReadingLogEntryEditModal } from "@ui/modals"; import { ReadingLogEntryEditModal } from "@ui/modals";
import type BookTrackerPlugin from "@src/main";
const ALL_TIME = "ALL_TIME"; const ALL_TIME = "ALL_TIME";
interface Props { interface Props {
app: App; plugin: BookTrackerPlugin;
readingLog: ReadingLog;
} }
let { app, readingLog }: Props = $props(); let { plugin }: Props = $props();
function bookUri(book: string) { function bookUri(book: string) {
const v = encodeURIComponent(app.vault.getName()); const v = encodeURIComponent(plugin.app.vault.getName());
const f = encodeURIComponent(book + ".md"); const f = encodeURIComponent(book + ".md");
return `obsidian://open?vault=${v}&file=${f}`; return `obsidian://open?vault=${v}&file=${f}`;
} }
@ -26,14 +24,14 @@
} }
let entries = $state( let entries = $state(
readingLog.getEntries().map((entry, id) => ({ plugin.readingLog.getEntries().map((entry, id) => ({
...entry, ...entry,
id, id,
})), })),
); );
function reload() { function reload() {
entries = readingLog.getEntries().map((entry, id) => ({ entries = plugin.readingLog.getEntries().map((entry, id) => ({
...entry, ...entry,
id, id,
})); }));
@ -69,9 +67,9 @@
); );
function createEntry() { function createEntry() {
const modal = new ReadingLogEntryEditModal(app, async (entry) => { const modal = new ReadingLogEntryEditModal(plugin, async (entry) => {
modal.close(); modal.close();
await readingLog.addRawEntry(entry); await plugin.readingLog.addRawEntry(entry);
reload(); reload();
}); });
modal.open(); modal.open();
@ -79,10 +77,10 @@
function editEntry(i: number, entry: ReadingLogEntry) { function editEntry(i: number, entry: ReadingLogEntry) {
const modal = new ReadingLogEntryEditModal( const modal = new ReadingLogEntryEditModal(
app, plugin,
async (entry) => { async (entry) => {
modal.close(); modal.close();
await readingLog.updateEntry(i, entry); await plugin.readingLog.updateEntry(i, entry);
reload(); reload();
}, },
entry, entry,
@ -91,7 +89,7 @@
} }
async function deleteEntry(i: number) { async function deleteEntry(i: number) {
await readingLog.spliceEntry(i); await plugin.readingLog.spliceEntry(i);
reload(); reload();
} }
</script> </script>

View File

@ -7,6 +7,7 @@
id: string; id: string;
asString?: boolean; asString?: boolean;
value?: TFile | string; value?: TFile | string;
bookFolder?: string;
onSelected?: (fileOrPath: TFile | string) => void; onSelected?: (fileOrPath: TFile | string) => void;
}; };
@ -15,6 +16,7 @@
id, id,
asString, asString,
value = $bindable(), value = $bindable(),
bookFolder,
onSelected, onSelected,
}: Props = $props(); }: Props = $props();
@ -23,7 +25,10 @@
function handleChange(query: string) { function handleChange(query: string) {
items = app.vault items = app.vault
.getMarkdownFiles() .getMarkdownFiles()
.filter((f) => .filter(
(f) =>
(bookFolder === undefined ||
f.path.startsWith(bookFolder)) &&
f.basename.toLowerCase().includes(query.toLowerCase()), f.basename.toLowerCase().includes(query.toLowerCase()),
) )
.map((f) => ({ .map((f) => ({

View File

@ -1,18 +1,18 @@
import ReadingLogEntryEditModalView from "./ReadingLogEntryEditModalView.svelte"; import ReadingLogEntryEditModalView from "./ReadingLogEntryEditModalView.svelte";
import type { ReadingLogEntry } from "@src/types"; import type { ReadingLogEntry } from "@src/types";
import { App } from "obsidian";
import { SvelteModal } from "./SvelteModal"; import { SvelteModal } from "./SvelteModal";
import type BookTrackerPlugin from "@src/main";
export class ReadingLogEntryEditModal extends SvelteModal< export class ReadingLogEntryEditModal extends SvelteModal<
typeof ReadingLogEntryEditModalView typeof ReadingLogEntryEditModalView
> { > {
constructor( constructor(
app: App, plugin: BookTrackerPlugin,
onSubmit?: (entry: ReadingLogEntry) => void, onSubmit?: (entry: ReadingLogEntry) => void,
entry?: ReadingLogEntry entry?: ReadingLogEntry
) { ) {
super(app, ReadingLogEntryEditModalView, { super(plugin.app, ReadingLogEntryEditModalView, {
props: { app, entry, onSubmit }, props: { plugin, entry, onSubmit },
}); });
} }
} }

View File

@ -1,14 +1,14 @@
<script lang="ts"> <script lang="ts">
import type BookTrackerPlugin from "@src/main";
import type { ReadingLogEntry } from "@src/types"; import type { ReadingLogEntry } from "@src/types";
import BookSuggest from "@ui/components/suggesters/BookSuggest.svelte"; import BookSuggest from "@ui/components/suggesters/BookSuggest.svelte";
import type { App } from "obsidian";
interface Props { interface Props {
app: App; plugin: BookTrackerPlugin;
entry?: ReadingLogEntry; entry?: ReadingLogEntry;
onSubmit?: (entry: ReadingLogEntry) => void; onSubmit?: (entry: ReadingLogEntry) => void;
} }
let { app, entry, onSubmit }: Props = $props(); let { plugin, entry, onSubmit }: Props = $props();
let editMode = $derived(entry !== undefined); let editMode = $derived(entry !== undefined);
let book = $state(entry?.book ?? ""); let book = $state(entry?.book ?? "");
@ -61,7 +61,12 @@
<form {onsubmit}> <form {onsubmit}>
<div class="fields"> <div class="fields">
<label for="book">Book</label> <label for="book">Book</label>
<BookSuggest id="book" {app} bind:value={book} /> <BookSuggest
id="book"
app={plugin.app}
bookFolder={plugin.settings.bookFolder}
bind:value={book}
/>
<label for="pagesRead">Pages Read</label> <label for="pagesRead">Pages Read</label>
<input <input
type="number" type="number"

View File

@ -24,12 +24,26 @@
</script> </script>
<div class="obt-settings"> <div class="obt-settings">
<Header title="General Settings" />
<FolderSuggestItem
{app}
id="book-folder"
name="Book Folder"
description="Select the folder where book entries are stored."
bind:value={$settings.bookFolder}
/>
<ToggleItem
id="organize-read-books"
name="Organize Read Books"
description="Organize read books into folders based on the date read."
bind:checked={$settings.organizeReadBooks}
/>
<Header title="Book Creation Settings" /> <Header title="Book Creation Settings" />
<FileSuggestItem <FileSuggestItem
{app} {app}
id="template-file" id="template-file"
name="Template File" name="Template File"
description="Select the template file to use for new book entries" description="Select the template file to use for new book entries."
bind:value={$settings.templateFile} bind:value={$settings.templateFile}
/> />
<FolderSuggestItem <FolderSuggestItem
@ -51,26 +65,26 @@
<ToggleItem <ToggleItem
id="download-covers" id="download-covers"
name="Download Covers" name="Download Covers"
description="Automatically download book covers when creating new entries" description="Automatically download book covers when creating new entries."
bind:checked={$settings.downloadCovers} bind:checked={$settings.downloadCovers}
/> />
<FolderSuggestItem <FolderSuggestItem
{app} {app}
id="cover-folder" id="cover-folder"
name="Cover Folder" name="Cover Folder"
description="Select the folder to download covers to" description="Select the folder to download covers to."
bind:value={$settings.coverFolder} bind:value={$settings.coverFolder}
/> />
<ToggleItem <ToggleItem
id="group-covers" id="group-covers"
name="Group Covers by First Letter" name="Group Covers by First Letter"
description="Organize downloaded book covers into folders based on the first letter of the book title" description="Organize downloaded book covers into folders based on the first letter of the book title."
bind:checked={$settings.groupCoversByFirstLetter} bind:checked={$settings.groupCoversByFirstLetter}
/> />
<ToggleItem <ToggleItem
id="overwrite-covers" id="overwrite-covers"
name="Overwrite Existing Covers" name="Overwrite Existing Covers"
description="Overwrite existing covers when downloading new ones" description="Overwrite existing covers when downloading new ones."
bind:checked={$settings.overwriteExistingCovers} bind:checked={$settings.overwriteExistingCovers}
/> />
@ -79,7 +93,7 @@
{app} {app}
id="status-field" id="status-field"
name="Status Field" name="Status Field"
description="Select the folder to use for To Be Read entries" description="Select the folder to use for To Be Read entries."
bind:value={$settings.statusProperty} bind:value={$settings.statusProperty}
accepts={["text"]} accepts={["text"]}
/> />
@ -87,7 +101,7 @@
{app} {app}
id="start-date-field" id="start-date-field"
name="Start Date Field" name="Start Date Field"
description="Select the field to use for start date" description="Select the field to use for start date."
bind:value={$settings.startDateProperty} bind:value={$settings.startDateProperty}
accepts={["date"]} accepts={["date"]}
/> />
@ -95,7 +109,7 @@
{app} {app}
id="end-date-field" id="end-date-field"
name="End Date Field" name="End Date Field"
description="Select the field to use for end date" description="Select the field to use for end date."
bind:value={$settings.endDateProperty} bind:value={$settings.endDateProperty}
accepts={["date"]} accepts={["date"]}
/> />
@ -103,7 +117,7 @@
{app} {app}
id="rating-field" id="rating-field"
name="Rating Field" name="Rating Field"
description="Select the field to use for rating" description="Select the field to use for rating."
bind:value={$settings.ratingProperty} bind:value={$settings.ratingProperty}
accepts={["number"]} accepts={["number"]}
/> />
@ -111,7 +125,7 @@
{app} {app}
id="page-count-field" id="page-count-field"
name="Page Count Field" name="Page Count Field"
description="Select the field to use for page count" description="Select the field to use for page count."
bind:value={$settings.pageCountProperty} bind:value={$settings.pageCountProperty}
accepts={["number"]} accepts={["number"]}
/> />

View File

@ -1,4 +1,6 @@
export interface BookTrackerSettings { export interface BookTrackerSettings {
bookFolder: string;
organizeReadBooks: boolean;
templateFile: string; templateFile: string;
tbrFolder: string; tbrFolder: string;
fileNameFormat: string; fileNameFormat: string;
@ -14,6 +16,8 @@ export interface BookTrackerSettings {
} }
export const DEFAULT_SETTINGS: BookTrackerSettings = { export const DEFAULT_SETTINGS: BookTrackerSettings = {
bookFolder: "books",
organizeReadBooks: true,
templateFile: "", templateFile: "",
tbrFolder: "books/tbr", tbrFolder: "books/tbr",
fileNameFormat: "{{title}} - {{authors}}", fileNameFormat: "{{title}} - {{authors}}",