From db732fd8a6d9f3c5bfb606c27174b65e070fa62b Mon Sep 17 00:00:00 2001 From: Evan Fiordeliso Date: Sat, 5 Jul 2025 15:06:39 -0400 Subject: [PATCH] Rename bookshelf code block to shelf and add table view --- src/main.ts | 4 +- src/ui/code-blocks/BookshelfCodeBlock.ts | 35 --- .../code-blocks/BookshelfCodeBlockView.svelte | 166 ---------- src/ui/code-blocks/ShelfCodeBlock.ts | 46 +++ src/ui/code-blocks/ShelfCodeBlockView.svelte | 289 ++++++++++++++++++ src/ui/components/DateFilter.svelte | 46 +++ src/ui/components/Rating.svelte | 186 +++++++++++ src/ui/stores/date-filter.svelte.ts | 26 +- 8 files changed, 583 insertions(+), 215 deletions(-) delete mode 100644 src/ui/code-blocks/BookshelfCodeBlock.ts delete mode 100644 src/ui/code-blocks/BookshelfCodeBlockView.svelte create mode 100644 src/ui/code-blocks/ShelfCodeBlock.ts create mode 100644 src/ui/code-blocks/ShelfCodeBlockView.svelte create mode 100644 src/ui/components/DateFilter.svelte create mode 100644 src/ui/components/Rating.svelte diff --git a/src/main.ts b/src/main.ts index 8a79dbb..f91c3fb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -22,7 +22,7 @@ import { BackupReadingLogCommand } from "@commands/CreateReadingLogBackupCommand import { RestoreReadingLogBackupCommand } from "@commands/RestoreReadingLogBackupCommand"; import { Goodreads } from "@data-sources/Goodreads"; import { CreateBookFromGoodreadsUrlCommand } from "@commands/CreateBookFromGoodreadsUrlCommand"; -import { registerBookshelfCodeBlockProcessor } from "@ui/code-blocks/BookshelfCodeBlock"; +import { registerShelfCodeBlockProcessor } from "@ui/code-blocks/ShelfCodeBlock"; export default class BookTrackerPlugin extends Plugin { public settings: BookTrackerPluginSettings; @@ -86,7 +86,7 @@ export default class BookTrackerPlugin extends Plugin { registerReadingLogCodeBlockProcessor(this); registerReadingStatsCodeBlockProcessor(this); - registerBookshelfCodeBlockProcessor(this); + registerShelfCodeBlockProcessor(this); } onunload() {} diff --git a/src/ui/code-blocks/BookshelfCodeBlock.ts b/src/ui/code-blocks/BookshelfCodeBlock.ts deleted file mode 100644 index 35cc4fd..0000000 --- a/src/ui/code-blocks/BookshelfCodeBlock.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { registerCodeBlockRenderer } from "."; -import { SvelteCodeBlockRenderer } from "./SvelteCodeBlockRenderer"; -import BookshelfCodeBlockView from "./BookshelfCodeBlockView.svelte"; -import type BookTrackerPlugin from "@src/main"; -import z from "zod/v4"; - -export function registerBookshelfCodeBlockProcessor( - plugin: BookTrackerPlugin -): void { - registerCodeBlockRenderer( - plugin, - "bookshelf", - (source, el) => new BookshelfCodeBlockRenderer(plugin, source, el) - ); -} - -export const BookshelfSettingsSchema = z.object({ - titleProperty: z.string(), - subtitleProperty: z.optional(z.string()), - authorsProperty: z.string(), -}); - -export class BookshelfCodeBlockRenderer extends SvelteCodeBlockRenderer< - typeof BookshelfCodeBlockView -> { - constructor( - plugin: BookTrackerPlugin, - source: string, - contentEl: HTMLElement - ) { - super(contentEl, BookshelfCodeBlockView, { props: { plugin, source } }); - } - - onunload() {} -} diff --git a/src/ui/code-blocks/BookshelfCodeBlockView.svelte b/src/ui/code-blocks/BookshelfCodeBlockView.svelte deleted file mode 100644 index 5e0fd9a..0000000 --- a/src/ui/code-blocks/BookshelfCodeBlockView.svelte +++ /dev/null @@ -1,166 +0,0 @@ - - - - {#each books as book} - {#if Array.isArray(book)} - - {#each book as bookData} - - plugin.app.workspace.openLinkText( - bookData.file.path, - "", - true, - )} - /> - {/each} - - {:else} - - plugin.app.workspace.openLinkText(book.file.path, "", true)} - /> - {/if} - {/each} - diff --git a/src/ui/code-blocks/ShelfCodeBlock.ts b/src/ui/code-blocks/ShelfCodeBlock.ts new file mode 100644 index 0000000..89ffaf7 --- /dev/null +++ b/src/ui/code-blocks/ShelfCodeBlock.ts @@ -0,0 +1,46 @@ +import { registerCodeBlockRenderer } from "."; +import { SvelteCodeBlockRenderer } from "./SvelteCodeBlockRenderer"; +import ShelfCodeBockView from "./ShelfCodeBlockView.svelte"; +import type BookTrackerPlugin from "@src/main"; +import z from "zod/v4"; +import { STATUS_IN_PROGRESS, STATUS_READ, STATUS_TO_BE_READ } from "@src/const"; + +export function registerShelfCodeBlockProcessor( + plugin: BookTrackerPlugin +): void { + registerCodeBlockRenderer( + plugin, + "shelf", + (source, el) => new ShelfCodeBlockRenderer(plugin, source, el) + ); +} + +export const SHELF_VIEWS = ["table", "bookshelf"] as const; +export type ShelfView = (typeof SHELF_VIEWS)[number]; + +export const ShelfSettingsSchema = z.object({ + statusFilter: z + .enum([STATUS_TO_BE_READ, STATUS_IN_PROGRESS, STATUS_READ]) + .default(STATUS_TO_BE_READ), + defaultView: z.enum(SHELF_VIEWS).default("table"), + coverProperty: z.string(), + titleProperty: z.string(), + subtitleProperty: z.optional(z.string()), + authorsProperty: z.string(), + seriesTitleProperty: z.optional(z.string()), + seriesNumberProperty: z.optional(z.string()), +}); + +export class ShelfCodeBlockRenderer extends SvelteCodeBlockRenderer< + typeof ShelfCodeBockView +> { + constructor( + plugin: BookTrackerPlugin, + source: string, + contentEl: HTMLElement + ) { + super(contentEl, ShelfCodeBockView, { props: { plugin, source } }); + } + + onunload() {} +} diff --git a/src/ui/code-blocks/ShelfCodeBlockView.svelte b/src/ui/code-blocks/ShelfCodeBlockView.svelte new file mode 100644 index 0000000..02a9971 --- /dev/null +++ b/src/ui/code-blocks/ShelfCodeBlockView.svelte @@ -0,0 +1,289 @@ + + +
+
+ + {#if settings.statusFilter === STATUS_READ} + + {/if} +
+ {#if view === "bookshelf"} + + {#each books as book} + {#if Array.isArray(book)} + + {#each book as bookData} + + plugin.app.workspace.openLinkText( + bookData.file.path, + "", + true, + )} + /> + {/each} + + {:else} + + plugin.app.workspace.openLinkText( + book.file.path, + "", + true, + )} + /> + {/if} + {/each} + + {:else if view === "table"} + + + + + + + {#if settings.seriesTitleProperty} + + {/if} + {#if settings.seriesNumberProperty} + + {/if} + {#if settings.statusFilter === STATUS_IN_PROGRESS || settings.statusFilter === STATUS_READ} + + {/if} + {#if settings.statusFilter === STATUS_READ} + + + {/if} + + + + {#each metadataStore.metadata as book} + + + + + {#if settings.seriesTitleProperty} + + {/if} + {#if settings.seriesNumberProperty} + + {/if} + {#if settings.statusFilter === STATUS_IN_PROGRESS || settings.statusFilter === STATUS_READ} + + {/if} + {#if settings.statusFilter === STATUS_READ} + + + {/if} + + {/each} + +
CoverTitleAuthorsSeries#Start DateEnd DateRating
+ {book.frontmatter[settings.titleProperty]} + {book.frontmatter[settings.titleProperty]} + {book.frontmatter[settings.authorsProperty].join( + ", ", + )} + + {book.frontmatter[settings.seriesTitleProperty]} + + {book.frontmatter[ + settings.seriesNumberProperty + ]} + + {book.frontmatter[ + settingsStore.settings.startDateProperty + ]} + + {book.frontmatter[ + settingsStore.settings.endDateProperty + ]} + + +
+ {/if} +
+ + diff --git a/src/ui/components/DateFilter.svelte b/src/ui/components/DateFilter.svelte new file mode 100644 index 0000000..b3b9842 --- /dev/null +++ b/src/ui/components/DateFilter.svelte @@ -0,0 +1,46 @@ + + + +{#if store.filterYear !== ALL_TIME} + +{/if} diff --git a/src/ui/components/Rating.svelte b/src/ui/components/Rating.svelte new file mode 100644 index 0000000..902ca38 --- /dev/null +++ b/src/ui/components/Rating.svelte @@ -0,0 +1,186 @@ + + +{rating} + + diff --git a/src/ui/stores/date-filter.svelte.ts b/src/ui/stores/date-filter.svelte.ts index 66824c5..cfaa74e 100644 --- a/src/ui/stores/date-filter.svelte.ts +++ b/src/ui/stores/date-filter.svelte.ts @@ -22,21 +22,23 @@ export function createDateFilter( initialMonth ? today.getMonth() + 1 : ALL_TIME ); const filteredData = $derived.by(() => { - return data().filter((item) => { - const date = selector(item); - if (filterYear !== ALL_TIME) { - if (date.year() !== filterYear) { - return false; + return data() + .filter((item) => { + const date = selector(item); + if (filterYear !== ALL_TIME) { + if (date.year() !== filterYear) { + return false; + } } - } - if (filterMonth !== ALL_TIME) { - if (date.month() !== filterMonth - 1) { - return false; + if (filterMonth !== ALL_TIME) { + if (date.month() !== filterMonth - 1) { + return false; + } } - } - return true; - }); + return true; + }) + .sort((a, b) => selector(a).diff(selector(b))); }); const filterYears = $derived.by(() => {