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",
 | 
			
		||||
	"name": "Book Tracker",
 | 
			
		||||
	"version": "1.7.0",
 | 
			
		||||
	"version": "1.7.1",
 | 
			
		||||
	"minAppVersion": "0.15.0",
 | 
			
		||||
	"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
 | 
			
		||||
	"author": "FiFiTiDo",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
	"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.",
 | 
			
		||||
	"main": "main.js",
 | 
			
		||||
	"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">
 | 
			
		||||
	import type { ComponentProps } from "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"> & {
 | 
			
		||||
		id: string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import type { ComponentProps } from "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"> & {
 | 
			
		||||
		id: string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import type { ComponentProps } from "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"> & {
 | 
			
		||||
		id: string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import type { ComponentProps } from "svelte";
 | 
			
		||||
	import Item from "./Item.svelte";
 | 
			
		||||
	import TextControl from "../form/TextControl.svelte";
 | 
			
		||||
 | 
			
		||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
			
		||||
		id?: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +13,6 @@
 | 
			
		|||
 | 
			
		||||
<Item {name} {description}>
 | 
			
		||||
	{#snippet control()}
 | 
			
		||||
		<input {id} type="text" bind:value />
 | 
			
		||||
		<TextControl {id} bind:value />
 | 
			
		||||
	{/snippet}
 | 
			
		||||
</Item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import type { ComponentProps } from "svelte";
 | 
			
		||||
	import Item from "./Item.svelte";
 | 
			
		||||
	import ToggleControl from "../form/ToggleControl.svelte";
 | 
			
		||||
 | 
			
		||||
	type Props = Omit<ComponentProps<typeof Item>, "control"> & {
 | 
			
		||||
		id?: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -12,15 +13,6 @@
 | 
			
		|||
 | 
			
		||||
<Item {name} {description}>
 | 
			
		||||
	{#snippet control()}
 | 
			
		||||
		<!-- svelte-ignore a11y_no_static_element_interactions -->
 | 
			
		||||
		<!-- 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>
 | 
			
		||||
		<ToggleControl {id} bind:checked />
 | 
			
		||||
	{/snippet}
 | 
			
		||||
</Item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<script lang="ts">
 | 
			
		||||
	import type BookTrackerPlugin from "@src/main";
 | 
			
		||||
	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 { createPrevious } from "@ui/stores/previous.svelte";
 | 
			
		||||
	import { createMetadata } from "@ui/stores/metadata.svelte";
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
		setReadingLogContext,
 | 
			
		||||
	} from "@ui/stores/reading-log.svelte";
 | 
			
		||||
	import { onDestroy } from "svelte";
 | 
			
		||||
	import ToggleControl from "@ui/components/form/ToggleControl.svelte";
 | 
			
		||||
 | 
			
		||||
	const INPUT_DATETIME_FORMAT = "YYYY-MM-DDTHH:mm";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,13 +44,24 @@
 | 
			
		|||
	const bookMetadata = $derived(
 | 
			
		||||
		metadataStore.metadata.find((m) => m.file.basename === book),
 | 
			
		||||
	);
 | 
			
		||||
	const lastEntryIndex = $derived(
 | 
			
		||||
		readingLogStore.entries.findLastIndex((e) => e.book === book),
 | 
			
		||||
	);
 | 
			
		||||
	const lastEntry = $derived(
 | 
			
		||||
		lastEntryIndex !== -1 ? readingLogStore.entries[lastEntryIndex] : null,
 | 
			
		||||
	const previousEntry = $derived.by(() => {
 | 
			
		||||
		const index = readingLogStore.entries.findIndex(
 | 
			
		||||
			(e) => e.id === entry?.id,
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		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);
 | 
			
		||||
	let pagesRead = $state(entry?.pagesRead ?? 0);
 | 
			
		||||
	const pagesReadPrev = createPrevious(() => pagesRead);
 | 
			
		||||
| 
						 | 
				
			
			@ -61,20 +73,24 @@
 | 
			
		|||
	);
 | 
			
		||||
 | 
			
		||||
	$effect(() => {
 | 
			
		||||
		pagesReadTotal = (lastEntry?.pagesReadTotal ?? 0) + pagesRead;
 | 
			
		||||
		if (!syncPageCounts) return;
 | 
			
		||||
		pagesReadTotal = (previousEntry?.pagesReadTotal ?? 0) + pagesRead;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	$effect(() => {
 | 
			
		||||
		if (!syncPageCounts) return;
 | 
			
		||||
		const diff = pagesRead - (pagesReadPrev.value ?? 0);
 | 
			
		||||
		pagesRead = pagesRead;
 | 
			
		||||
		pagesReadTotal = pagesReadTotal + diff;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	$effect(() => {
 | 
			
		||||
		if (!syncPageCounts) return;
 | 
			
		||||
		pagesRemaining = pageCount - pagesReadTotal;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	$effect(() => {
 | 
			
		||||
		if (!syncPageCounts) return;
 | 
			
		||||
		pagesReadTotal = Math.max(pagesReadTotal, pagesRead);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +154,12 @@
 | 
			
		|||
				id="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>
 | 
			
		||||
			<input
 | 
			
		||||
				type="datetime-local"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,5 +11,6 @@
 | 
			
		|||
	"1.5.0": "0.15.0",
 | 
			
		||||
	"1.6.0": "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