generated from tpl/obsidian-sample-plugin
			Add sync toggle to reading log editor, use previous entry as opposed to last ever entry, and reorganize files
This commit is contained in:
		
							parent
							
								
									0ef651d661
								
							
						
					
					
						commit
						8b19f1ea03
					
				| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"id": "obsidian-book-tracker",
 | 
						"id": "obsidian-book-tracker",
 | 
				
			||||||
	"name": "Book Tracker",
 | 
						"name": "Book Tracker",
 | 
				
			||||||
	"version": "1.7.0",
 | 
						"version": "1.7.1",
 | 
				
			||||||
	"minAppVersion": "0.15.0",
 | 
						"minAppVersion": "0.15.0",
 | 
				
			||||||
	"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
 | 
						"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
 | 
				
			||||||
	"author": "FiFiTiDo",
 | 
						"author": "FiFiTiDo",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"name": "obsidian-book-tracker",
 | 
						"name": "obsidian-book-tracker",
 | 
				
			||||||
	"version": "1.7.0",
 | 
						"version": "1.7.1",
 | 
				
			||||||
	"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
 | 
						"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
 | 
				
			||||||
	"main": "main.js",
 | 
						"main": "main.js",
 | 
				
			||||||
	"scripts": {
 | 
						"scripts": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						interface Props {
 | 
				
			||||||
 | 
							id?: string;
 | 
				
			||||||
 | 
							name?: string;
 | 
				
			||||||
 | 
							value?: string;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let { id, name, value = $bindable() }: Props = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<input {id} {name} type="text" bind:value />
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						interface Props {
 | 
				
			||||||
 | 
							id?: string;
 | 
				
			||||||
 | 
							name?: string;
 | 
				
			||||||
 | 
							checked?: boolean;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let { id, name, checked = $bindable() }: Props = $props();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div
 | 
				
			||||||
 | 
						class="checkbox-container"
 | 
				
			||||||
 | 
						class:is-enabled={checked}
 | 
				
			||||||
 | 
						onclick={() => (checked = !checked)}
 | 
				
			||||||
 | 
						onkeypress={(e) => e.key === "Space" && (checked = !checked)}
 | 
				
			||||||
 | 
						role="switch"
 | 
				
			||||||
 | 
						aria-checked={checked}
 | 
				
			||||||
 | 
						tabindex="0"
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
						<input {id} {name} type="checkbox" bind:checked tabindex="0" />
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { ComponentProps } from "svelte";
 | 
						import type { ComponentProps } from "svelte";
 | 
				
			||||||
	import Item from "./Item.svelte";
 | 
						import Item from "./Item.svelte";
 | 
				
			||||||
	import FileSuggest from "../suggesters/FileSuggest.svelte";
 | 
						import FileSuggest from "../form/suggesters/FileSuggest.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
						type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
				
			||||||
		id: string;
 | 
							id: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { ComponentProps } from "svelte";
 | 
						import type { ComponentProps } from "svelte";
 | 
				
			||||||
	import Item from "./Item.svelte";
 | 
						import Item from "./Item.svelte";
 | 
				
			||||||
	import FolderSuggest from "../suggesters/FolderSuggest.svelte";
 | 
						import FolderSuggest from "../form/suggesters/FolderSuggest.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
						type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
				
			||||||
		id: string;
 | 
							id: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { ComponentProps } from "svelte";
 | 
						import type { ComponentProps } from "svelte";
 | 
				
			||||||
	import Item from "./Item.svelte";
 | 
						import Item from "./Item.svelte";
 | 
				
			||||||
	import PropertySuggest from "../suggesters/PropertySuggest.svelte";
 | 
						import PropertySuggest from "../form/suggesters/PropertySuggest.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
						type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
				
			||||||
		id: string;
 | 
							id: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { ComponentProps } from "svelte";
 | 
						import type { ComponentProps } from "svelte";
 | 
				
			||||||
	import Item from "./Item.svelte";
 | 
						import Item from "./Item.svelte";
 | 
				
			||||||
 | 
						import TextControl from "../form/TextControl.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
						type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
				
			||||||
		id?: string;
 | 
							id?: string;
 | 
				
			||||||
| 
						 | 
					@ -12,6 +13,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<Item {name} {description}>
 | 
					<Item {name} {description}>
 | 
				
			||||||
	{#snippet control()}
 | 
						{#snippet control()}
 | 
				
			||||||
		<input {id} type="text" bind:value />
 | 
							<TextControl {id} bind:value />
 | 
				
			||||||
	{/snippet}
 | 
						{/snippet}
 | 
				
			||||||
</Item>
 | 
					</Item>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { ComponentProps } from "svelte";
 | 
						import type { ComponentProps } from "svelte";
 | 
				
			||||||
	import Item from "./Item.svelte";
 | 
						import Item from "./Item.svelte";
 | 
				
			||||||
 | 
						import ToggleControl from "../form/ToggleControl.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
						type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
				
			||||||
		id?: string;
 | 
							id?: string;
 | 
				
			||||||
| 
						 | 
					@ -12,15 +13,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<Item {name} {description}>
 | 
					<Item {name} {description}>
 | 
				
			||||||
	{#snippet control()}
 | 
						{#snippet control()}
 | 
				
			||||||
		<!-- svelte-ignore a11y_no_static_element_interactions -->
 | 
							<ToggleControl {id} bind:checked />
 | 
				
			||||||
		<!-- svelte-ignore a11y_click_events_have_key_events -->
 | 
					 | 
				
			||||||
		<!-- input only covers part of the toggle element. onclick here covers the rest -->
 | 
					 | 
				
			||||||
		<div
 | 
					 | 
				
			||||||
			class="checkbox-container"
 | 
					 | 
				
			||||||
			class:is-enabled={checked}
 | 
					 | 
				
			||||||
			onclick={() => (checked = !checked)}
 | 
					 | 
				
			||||||
		>
 | 
					 | 
				
			||||||
			<input {id} type="checkbox" bind:checked tabindex="0" />
 | 
					 | 
				
			||||||
		</div>
 | 
					 | 
				
			||||||
	{/snippet}
 | 
						{/snippet}
 | 
				
			||||||
</Item>
 | 
					</Item>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type BookTrackerPlugin from "@src/main";
 | 
						import type BookTrackerPlugin from "@src/main";
 | 
				
			||||||
	import type { ReadingLogEntry } from "@utils/ReadingLog";
 | 
						import type { ReadingLogEntry } from "@utils/ReadingLog";
 | 
				
			||||||
	import FileSuggest from "@ui/components/suggesters/FileSuggest.svelte";
 | 
						import FileSuggest from "@ui/components/form/suggesters/FileSuggest.svelte";
 | 
				
			||||||
	import { v4 as uuidv4 } from "uuid";
 | 
						import { v4 as uuidv4 } from "uuid";
 | 
				
			||||||
	import { createPrevious } from "@ui/stores/previous.svelte";
 | 
						import { createPrevious } from "@ui/stores/previous.svelte";
 | 
				
			||||||
	import { createMetadata } from "@ui/stores/metadata.svelte";
 | 
						import { createMetadata } from "@ui/stores/metadata.svelte";
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
		setReadingLogContext,
 | 
							setReadingLogContext,
 | 
				
			||||||
	} from "@ui/stores/reading-log.svelte";
 | 
						} from "@ui/stores/reading-log.svelte";
 | 
				
			||||||
	import { onDestroy } from "svelte";
 | 
						import { onDestroy } from "svelte";
 | 
				
			||||||
 | 
						import ToggleControl from "@ui/components/form/ToggleControl.svelte";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const INPUT_DATETIME_FORMAT = "YYYY-MM-DDTHH:mm";
 | 
						const INPUT_DATETIME_FORMAT = "YYYY-MM-DDTHH:mm";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,13 +44,24 @@
 | 
				
			||||||
	const bookMetadata = $derived(
 | 
						const bookMetadata = $derived(
 | 
				
			||||||
		metadataStore.metadata.find((m) => m.file.basename === book),
 | 
							metadataStore.metadata.find((m) => m.file.basename === book),
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
	const lastEntryIndex = $derived(
 | 
						const previousEntry = $derived.by(() => {
 | 
				
			||||||
		readingLogStore.entries.findLastIndex((e) => e.book === book),
 | 
							const index = readingLogStore.entries.findIndex(
 | 
				
			||||||
	);
 | 
								(e) => e.id === entry?.id,
 | 
				
			||||||
	const lastEntry = $derived(
 | 
					 | 
				
			||||||
		lastEntryIndex !== -1 ? readingLogStore.entries[lastEntryIndex] : null,
 | 
					 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let data = readingLogStore.entries;
 | 
				
			||||||
 | 
							if (index !== -1) {
 | 
				
			||||||
 | 
								data = data.slice(0, index);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const previousEntryIndex = data.findLastIndex((e) => e.book === book);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return previousEntryIndex !== -1
 | 
				
			||||||
 | 
								? readingLogStore.entries[previousEntryIndex]
 | 
				
			||||||
 | 
								: null;
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let syncPageCounts = $state(true);
 | 
				
			||||||
	const pageCount = $derived(bookMetadata?.book.pageCount ?? 0);
 | 
						const pageCount = $derived(bookMetadata?.book.pageCount ?? 0);
 | 
				
			||||||
	let pagesRead = $state(entry?.pagesRead ?? 0);
 | 
						let pagesRead = $state(entry?.pagesRead ?? 0);
 | 
				
			||||||
	const pagesReadPrev = createPrevious(() => pagesRead);
 | 
						const pagesReadPrev = createPrevious(() => pagesRead);
 | 
				
			||||||
| 
						 | 
					@ -61,20 +73,24 @@
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$effect(() => {
 | 
						$effect(() => {
 | 
				
			||||||
		pagesReadTotal = (lastEntry?.pagesReadTotal ?? 0) + pagesRead;
 | 
							if (!syncPageCounts) return;
 | 
				
			||||||
 | 
							pagesReadTotal = (previousEntry?.pagesReadTotal ?? 0) + pagesRead;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$effect(() => {
 | 
						$effect(() => {
 | 
				
			||||||
 | 
							if (!syncPageCounts) return;
 | 
				
			||||||
		const diff = pagesRead - (pagesReadPrev.value ?? 0);
 | 
							const diff = pagesRead - (pagesReadPrev.value ?? 0);
 | 
				
			||||||
		pagesRead = pagesRead;
 | 
							pagesRead = pagesRead;
 | 
				
			||||||
		pagesReadTotal = pagesReadTotal + diff;
 | 
							pagesReadTotal = pagesReadTotal + diff;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$effect(() => {
 | 
						$effect(() => {
 | 
				
			||||||
 | 
							if (!syncPageCounts) return;
 | 
				
			||||||
		pagesRemaining = pageCount - pagesReadTotal;
 | 
							pagesRemaining = pageCount - pagesReadTotal;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$effect(() => {
 | 
						$effect(() => {
 | 
				
			||||||
 | 
							if (!syncPageCounts) return;
 | 
				
			||||||
		pagesReadTotal = Math.max(pagesReadTotal, pagesRead);
 | 
							pagesReadTotal = Math.max(pagesReadTotal, pagesRead);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,6 +154,12 @@
 | 
				
			||||||
				id="pagesRemaining"
 | 
									id="pagesRemaining"
 | 
				
			||||||
				bind:value={pagesRemaining}
 | 
									bind:value={pagesRemaining}
 | 
				
			||||||
			/>
 | 
								/>
 | 
				
			||||||
 | 
								<label for="syncPageCounts">Sync Page Counts</label>
 | 
				
			||||||
 | 
								<ToggleControl
 | 
				
			||||||
 | 
									name="syncPageCounts"
 | 
				
			||||||
 | 
									id="syncPageCounts"
 | 
				
			||||||
 | 
									bind:checked={syncPageCounts}
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
			<label for="createdAt">Created At</label>
 | 
								<label for="createdAt">Created At</label>
 | 
				
			||||||
			<input
 | 
								<input
 | 
				
			||||||
				type="datetime-local"
 | 
									type="datetime-local"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,5 +11,6 @@
 | 
				
			||||||
	"1.5.0": "0.15.0",
 | 
						"1.5.0": "0.15.0",
 | 
				
			||||||
	"1.6.0": "0.15.0",
 | 
						"1.6.0": "0.15.0",
 | 
				
			||||||
	"1.6.1": "0.15.0",
 | 
						"1.6.1": "0.15.0",
 | 
				
			||||||
	"1.7.0": "0.15.0"
 | 
						"1.7.0": "0.15.0",
 | 
				
			||||||
 | 
						"1.7.1": "0.15.0"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue