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

137 lines
3.0 KiB
Svelte

<script lang="ts">
import type { ReadingLogEntry } from "@src/types";
import type { App } from "obsidian";
import { BookSuggest } from "@ui/suggesters";
interface Props {
app: App;
entry?: ReadingLogEntry;
onSubmit?: (entry: ReadingLogEntry) => void;
}
let { app, 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 ?? new Date());
// 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?.({
book,
pagesRead,
pagesReadTotal,
pagesRemaining,
createdAt: new Date(createdAt),
});
}
function bookSuggest(el: HTMLInputElement) {
new BookSuggest(app, el);
}
</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>
<input
type="text"
name="book"
id="book"
bind:value={book}
disabled={editMode}
use:bookSuggest
/>
<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}
disabled={editMode}
/>
</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>