diff --git a/manifest.json b/manifest.json
index 08d3ec9..2c810d7 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"id": "obsidian-book-tracker",
"name": "Book Tracker",
- "version": "1.1.0",
+ "version": "1.2.0",
"minAppVersion": "0.15.0",
"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
"author": "FiFiTiDo",
diff --git a/package.json b/package.json
index cbde538..7ecc852 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "obsidian-book-tracker",
- "version": "1.1.0",
+ "version": "1.2.0",
"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
"main": "main.js",
"scripts": {
diff --git a/src/main.ts b/src/main.ts
index e83485c..6212094 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -25,6 +25,7 @@ import { CreateBookFromGoodreadsUrlCommand } from "@commands/CreateBookFromGoodr
import { registerShelfCodeBlockProcessor } from "@ui/code-blocks/ShelfCodeBlock";
import { ReloadReadingLogCommand } from "@commands/ReloadReadingLogCommand";
import { registerReadingCalendarCodeBlockProcessor } from "@ui/code-blocks/ReadingCalendarCodeBlock";
+import { registerAToZChallengeCodeBlockProcessor } from "@ui/code-blocks/AToZChallengeCodeBlock";
export default class BookTrackerPlugin extends Plugin {
public settings: BookTrackerPluginSettings;
@@ -91,6 +92,7 @@ export default class BookTrackerPlugin extends Plugin {
registerReadingStatsCodeBlockProcessor(this);
registerShelfCodeBlockProcessor(this);
registerReadingCalendarCodeBlockProcessor(this);
+ registerAToZChallengeCodeBlockProcessor(this);
}
onunload() {}
diff --git a/src/ui/code-blocks/AToZChallengeCodeBlock.ts b/src/ui/code-blocks/AToZChallengeCodeBlock.ts
new file mode 100644
index 0000000..9083b7e
--- /dev/null
+++ b/src/ui/code-blocks/AToZChallengeCodeBlock.ts
@@ -0,0 +1,26 @@
+import { registerCodeBlockRenderer } from ".";
+import { SvelteCodeBlockRenderer } from "./SvelteCodeBlockRenderer";
+import AToZChallengeCodeBlockView from "./AToZChallengeCodeBlockView.svelte";
+import type BookTrackerPlugin from "@src/main";
+import z from "zod/v4";
+
+export function registerAToZChallengeCodeBlockProcessor(
+ plugin: BookTrackerPlugin
+): void {
+ registerCodeBlockRenderer(
+ plugin,
+ "a-to-z-challenge",
+ (source, el) =>
+ new SvelteCodeBlockRenderer(
+ AToZChallengeCodeBlockView,
+ plugin,
+ source,
+ el
+ )
+ );
+}
+
+export const AToZChallengeSettingsSchema = z.object({
+ coverProperty: z.string(),
+ titleProperty: z.string(),
+});
diff --git a/src/ui/code-blocks/AToZChallengeCodeBlockView.svelte b/src/ui/code-blocks/AToZChallengeCodeBlockView.svelte
new file mode 100644
index 0000000..404495a
--- /dev/null
+++ b/src/ui/code-blocks/AToZChallengeCodeBlockView.svelte
@@ -0,0 +1,194 @@
+
+
+
+
+
+
Started: {startDate.format("YYYY-MM-DD")}
+
Ended: {endDate?.format("YYYY-MM-DD") ?? "N/A"}
+
+
+ {#each alphabet as letter}
+
+ {#if items[letter]}
+ {@const item = items[letter]}
+
+
+
+ {:else}
+
{letter}
+ {/if}
+
+ {/each}
+
+
+
+
diff --git a/src/ui/code-blocks/ReadingCalendarCodeBlock.ts b/src/ui/code-blocks/ReadingCalendarCodeBlock.ts
index 41a800a..76daedb 100644
--- a/src/ui/code-blocks/ReadingCalendarCodeBlock.ts
+++ b/src/ui/code-blocks/ReadingCalendarCodeBlock.ts
@@ -9,7 +9,7 @@ export function registerReadingCalendarCodeBlockProcessor(
): void {
registerCodeBlockRenderer(
plugin,
- "readingcalendar",
+ "reading-calendar",
(source, el) =>
new SvelteCodeBlockRenderer(
ReadingCalendarCodeBlockView,
diff --git a/src/ui/code-blocks/ReadingCalendarCodeBlockView.svelte b/src/ui/code-blocks/ReadingCalendarCodeBlockView.svelte
index 2593779..fbfe071 100644
--- a/src/ui/code-blocks/ReadingCalendarCodeBlockView.svelte
+++ b/src/ui/code-blocks/ReadingCalendarCodeBlockView.svelte
@@ -24,7 +24,9 @@
const settingsStore = createSettings(plugin);
setSettingsContext(settingsStore);
- const metadataStore = createMetadata(plugin, null);
+ const metadataStore = createMetadata(plugin, {
+ statusFilter: null,
+ });
setMetadataContext(metadataStore);
const readingLog = createReadingLog(plugin.readingLog);
diff --git a/src/ui/code-blocks/ReadingLogCodeBlock.ts b/src/ui/code-blocks/ReadingLogCodeBlock.ts
index 710834f..b0b215e 100644
--- a/src/ui/code-blocks/ReadingLogCodeBlock.ts
+++ b/src/ui/code-blocks/ReadingLogCodeBlock.ts
@@ -8,7 +8,7 @@ export function registerReadingLogCodeBlockProcessor(
): void {
registerCodeBlockRenderer(
plugin,
- "readinglog",
+ "reading-log",
(source, el) =>
new SvelteCodeBlockRenderer(
ReadingLogCodeBlockView,
diff --git a/src/ui/code-blocks/ReadingStatsCodeBlock.ts b/src/ui/code-blocks/ReadingStatsCodeBlock.ts
index 939de04..3e62830 100644
--- a/src/ui/code-blocks/ReadingStatsCodeBlock.ts
+++ b/src/ui/code-blocks/ReadingStatsCodeBlock.ts
@@ -10,7 +10,7 @@ export function registerReadingStatsCodeBlockProcessor(
): void {
registerCodeBlockRenderer(
plugin,
- "readingstats",
+ "reading-stats",
(source, el) =>
new SvelteCodeBlockRenderer(
ReadingStatsCodeBlockView,
diff --git a/src/ui/code-blocks/ShelfCodeBlockView.svelte b/src/ui/code-blocks/ShelfCodeBlockView.svelte
index f275d02..0b6e08a 100644
--- a/src/ui/code-blocks/ShelfCodeBlockView.svelte
+++ b/src/ui/code-blocks/ShelfCodeBlockView.svelte
@@ -26,7 +26,10 @@
const settingsStore = createSettings(plugin);
setSettingsContext(settingsStore);
- const metadataStore = createMetadata(plugin, settings.statusFilter, true);
+ const metadataStore = createMetadata(plugin, {
+ statusFilter: settings.statusFilter,
+ initialMonth: true,
+ });
setMetadataContext(metadataStore);
let view = $state(settings.defaultView);
diff --git a/src/ui/modals/ReadingLogEntryEditModalView.svelte b/src/ui/modals/ReadingLogEntryEditModalView.svelte
index 6b8adf5..8f4e824 100644
--- a/src/ui/modals/ReadingLogEntryEditModalView.svelte
+++ b/src/ui/modals/ReadingLogEntryEditModalView.svelte
@@ -23,7 +23,9 @@
const settingsStore = createSettings(plugin);
setSettingsContext(settingsStore);
- const metadataStore = createMetadata(plugin, null);
+ const metadataStore = createMetadata(plugin, {
+ statusFilter: null,
+ });
let editMode = $derived(entry !== undefined);
let book = $state(entry?.book ?? "");
diff --git a/src/ui/stores/date-filter.svelte.ts b/src/ui/stores/date-filter.svelte.ts
index 51cd0da..b779420 100644
--- a/src/ui/stores/date-filter.svelte.ts
+++ b/src/ui/stores/date-filter.svelte.ts
@@ -9,17 +9,56 @@ export interface DateFilterStore {
get filterMonths(): { label: string; value: number }[];
}
+export interface DateFilterStoreOptions {
+ /**
+ * If true, the filter month will be set to the current month
+ * If a number is provided, the filter month will be set to the provided month
+ *
+ * @default false
+ */
+ initialMonth?: boolean | number;
+
+ /**
+ * If true, the filter year will be set to the current year
+ * If a number is provided, the filter year will be set to the provided year
+ *
+ * @default true
+ */
+ initialYear?: boolean | number;
+
+ /**
+ * If true, the month filter will be disabled
+ *
+ * @default false
+ */
+ disableMonthFilter?: boolean;
+}
+
export function createDateFilter(
data: () => T[],
selector: (item: T) => Moment,
- initialMonth?: boolean
+ {
+ initialMonth = false,
+ initialYear = true,
+ disableMonthFilter = false,
+ }: DateFilterStoreOptions
): DateFilterStore & {
filteredData: T[];
} {
const today = new Date();
- let filterYear: number | typeof ALL_TIME = $state(today.getFullYear());
+ let filterYear: number | typeof ALL_TIME = $state(
+ typeof initialYear === "number"
+ ? initialYear
+ : initialYear
+ ? today.getFullYear()
+ : ALL_TIME
+ );
let filterMonth: number | typeof ALL_TIME = $state(
- initialMonth ? today.getMonth() + 1 : ALL_TIME
+ typeof initialMonth === "number"
+ ? initialMonth
+ : initialMonth
+ ? today.getMonth() + 1
+ : ALL_TIME
);
const filteredData = $derived.by(() => {
return data()
@@ -30,7 +69,7 @@ export function createDateFilter(
return false;
}
- if (filterMonth !== ALL_TIME) {
+ if (filterMonth !== ALL_TIME && !disableMonthFilter) {
if (date.month() !== filterMonth - 1) {
return false;
}
diff --git a/src/ui/stores/metadata.svelte.ts b/src/ui/stores/metadata.svelte.ts
index 51c64f1..3fa0de4 100644
--- a/src/ui/stores/metadata.svelte.ts
+++ b/src/ui/stores/metadata.svelte.ts
@@ -7,7 +7,11 @@ import {
setSettingsContext,
} from "./settings.svelte";
import type BookTrackerPlugin from "@src/main";
-import { createDateFilter, type DateFilterStore } from "./date-filter.svelte";
+import {
+ createDateFilter,
+ type DateFilterStore,
+ type DateFilterStoreOptions,
+} from "./date-filter.svelte";
import type { ReadingState } from "@src/types";
import type { BookTrackerPluginSettings } from "@ui/settings";
@@ -49,10 +53,16 @@ function getMetadata(
return metadata;
}
+interface MetadataStoreOptions extends DateFilterStoreOptions {
+ /**
+ * The reading state to filter by
+ */
+ statusFilter?: ReadingState | null;
+}
+
export function createMetadata(
plugin: BookTrackerPlugin,
- statusFilter: ReadingState | null = STATUS_READ,
- initialMonth?: boolean
+ { statusFilter = STATUS_READ, ...dateFilterOpts }: MetadataStoreOptions = {}
): MetadataStore {
let settingsStore = getSettingsContext();
if (!settingsStore) {
@@ -97,7 +107,7 @@ export function createMetadata(
f.frontmatter[settingsStore.settings.endDateProperty]
);
},
- initialMonth
+ dateFilterOpts
);
return {
diff --git a/src/ui/stores/reading-log.svelte.ts b/src/ui/stores/reading-log.svelte.ts
index dc95da5..f5ed19a 100644
--- a/src/ui/stores/reading-log.svelte.ts
+++ b/src/ui/stores/reading-log.svelte.ts
@@ -18,7 +18,7 @@ export function createReadingLog(readingLog: ReadingLog): ReadingLogStore {
const dateFilter = createDateFilter(
() => entries,
(entry) => entry.createdAt,
- true
+ { initialMonth: true }
);
async function addEntry(entry: ReadingLogEntry): Promise {
diff --git a/versions.json b/versions.json
index 908e85c..8846fba 100644
--- a/versions.json
+++ b/versions.json
@@ -1,4 +1,5 @@
{
"1.0.0": "0.15.0",
- "1.1.0": "0.15.0"
+ "1.1.0": "0.15.0",
+ "1.2.0": "0.15.0"
}
\ No newline at end of file