obsidian-book-tracker/src/ui/modals/ReadingLogEntryEditModalVie...

142 lines
3.2 KiB
Svelte

<script lang="ts">
import type BookTrackerPlugin from "@src/main";
import type { ReadingLogEntry } from "@utils/ReadingLog";
import FileSuggest from "@ui/components/suggesters/FileSuggest.svelte";
import { v4 as uuidv4 } from "uuid";
const INPUT_DATETIME_FORMAT = "YYYY-MM-DDTHH:mm";
interface Props {
plugin: BookTrackerPlugin;
entry?: ReadingLogEntry;
onSubmit?: (entry: ReadingLogEntry) => void;
}
let { plugin, entry, onSubmit }: Props = $props();
let editMode = $derived(entry !== undefined);
let book = $state(entry?.book ?? "");
let pagesRead = $state(entry?.pagesRead ?? 0);
let pagesReadTotal = $state(entry?.pagesReadTotal ?? 0);
let pagesRemaining = $state(entry?.pagesRemaining ?? 0);
let createdAt = $state(
entry?.createdAt?.format(INPUT_DATETIME_FORMAT) ??
// @ts-expect-error Moment is provided by Obsidian
moment().format(INPUT_DATETIME_FORMAT),
);
// Source: https://github.com/sveltejs/svelte/discussions/14220#discussioncomment-11188219
function watch<T>(
getter: () => T,
effectCallback: (t: T | undefined) => void,
) {
let previous: T | undefined = undefined;
$effect(() => {
const current = getter(); // add $state.snapshot for deep reactivity
const cleanup = effectCallback(previous);
previous = current;
return cleanup;
});
}
watch(
() => pagesRead,
(prev) => {
if (prev !== pagesRead && prev !== undefined) {
const diff = pagesRead - prev;
pagesReadTotal = pagesReadTotal + diff;
pagesRemaining = pagesRemaining - diff;
}
},
);
function onsubmit(ev: SubmitEvent) {
ev.preventDefault();
onSubmit?.({
id: entry?.id ?? uuidv4(),
book,
pagesRead,
pagesReadTotal,
pagesRemaining,
// @ts-expect-error Moment is provided by Obsidian
createdAt: moment(createdAt),
});
}
</script>
<div class="obt-reading-log-entry-editor">
<h2>{editMode ? "Edit" : "Create"} Reading Log Entry</h2>
<form {onsubmit}>
<div class="fields">
<label for="book">Book</label>
<FileSuggest
id="book"
app={plugin.app}
asString
property="basename"
inFolder={plugin.settings.bookFolder}
bind:value={book}
/>
<label for="pagesRead">Pages Read</label>
<input
type="number"
name="pagesRead"
id="pagesRead"
bind:value={pagesRead}
/>
<label for="pagesReadTotal">Pages Read Total</label>
<input
type="number"
name="pagesReadTotal"
id="pagesReadTotal"
bind:value={pagesReadTotal}
/>
<label for="pagesRemaining">Pages Remaining</label>
<input
type="number"
name="pagesRemaining"
id="pagesRemaining"
bind:value={pagesRemaining}
/>
<label for="createdAt">Created At</label>
<input
type="datetime-local"
name="createdAt"
id="createdAt"
bind:value={createdAt}
/>
</div>
<button type="submit">Submit</button>
</form>
</div>
<style lang="scss">
.obt-reading-log-entry-editor {
margin-bottom: var(--size-4-4);
h2 {
margin-bottom: var(--size-4-6);
}
form {
display: flex;
flex-direction: column;
gap: var(--size-4-4);
.fields {
display: grid;
grid-template-columns: max-content 1fr;
gap: var(--size-4-4);
align-items: center;
input:disabled {
color: var(--text-muted);
cursor: not-allowed;
}
}
}
}
</style>