generated from tpl/obsidian-sample-plugin
152 lines
3.5 KiB
Svelte
152 lines
3.5 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";
|
|
import { createPrevious } from "@ui/stores/previous.svelte";
|
|
import { createMetadata } from "@ui/stores/metadata.svelte";
|
|
import {
|
|
createSettings,
|
|
setSettingsContext,
|
|
} from "@ui/stores/settings.svelte";
|
|
import moment from "@external/moment";
|
|
import { setAppContext } from "@ui/stores/app";
|
|
|
|
const INPUT_DATETIME_FORMAT = "YYYY-MM-DDTHH:mm";
|
|
|
|
interface Props {
|
|
plugin: BookTrackerPlugin;
|
|
entry?: ReadingLogEntry;
|
|
onSubmit?: (entry: ReadingLogEntry) => void;
|
|
}
|
|
|
|
let { plugin, entry, onSubmit }: Props = $props();
|
|
setAppContext(plugin.app);
|
|
|
|
const settingsStore = createSettings(plugin);
|
|
setSettingsContext(settingsStore);
|
|
|
|
const metadataStore = createMetadata(plugin, {
|
|
statusFilter: null,
|
|
});
|
|
|
|
let editMode = $derived(entry !== undefined);
|
|
let book = $state(entry?.book ?? "");
|
|
let bookMetadata = $derived(
|
|
metadataStore.metadata.find((m) => m.file.basename === book),
|
|
);
|
|
let pagesRead = $state(entry?.pagesRead ?? 0);
|
|
let pagesReadPrev = createPrevious(() => pagesRead);
|
|
let pagesReadTotal = $state(entry?.pagesReadTotal ?? 0);
|
|
let pagesRemaining = $state(entry?.pagesRemaining ?? 0);
|
|
let createdAt = $state(
|
|
entry?.createdAt?.format(INPUT_DATETIME_FORMAT) ??
|
|
moment().format(INPUT_DATETIME_FORMAT),
|
|
);
|
|
|
|
$effect(() => {
|
|
const diff = pagesRead - (pagesReadPrev.value ?? 0);
|
|
pagesRead = pagesRead;
|
|
pagesReadTotal = pagesReadTotal + diff;
|
|
});
|
|
|
|
$effect(() => {
|
|
pagesRemaining = bookMetadata?.book.pageCount ?? 0 - pagesReadTotal;
|
|
});
|
|
|
|
$effect(() => {
|
|
pagesReadTotal = Math.max(pagesReadTotal, pagesRead);
|
|
});
|
|
|
|
$effect(() => {
|
|
pagesRemaining = Math.max(pagesRemaining, 0);
|
|
});
|
|
|
|
function onsubmit(ev: SubmitEvent) {
|
|
ev.preventDefault();
|
|
onSubmit?.({
|
|
id: entry?.id ?? uuidv4(),
|
|
book,
|
|
pagesRead,
|
|
pagesReadTotal,
|
|
pagesRemaining,
|
|
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"
|
|
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="text"
|
|
inputmode="numeric"
|
|
pattern="[0-9]*"
|
|
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>
|