generated from tpl/obsidian-sample-plugin
216 lines
5.4 KiB
Svelte
216 lines
5.4 KiB
Svelte
<script lang="ts">
|
|
import { STATUS_IN_PROGRESS, STATUS_READ } from "@src/const";
|
|
import type BookTrackerPlugin from "@src/main";
|
|
import { getMetadataContext } from "@ui/stores/metadata.svelte";
|
|
import { getSettingsContext } from "@ui/stores/settings.svelte";
|
|
import { getLinkpath } from "obsidian";
|
|
import type { ShelfSettings } from "@ui/code-blocks/ShelfCodeBlock";
|
|
import { Dot, Flame, Star, StarHalf } from "lucide-svelte";
|
|
import RatingInput from "./RatingInput.svelte";
|
|
import OpenFileLink from "./OpenFileLink.svelte";
|
|
|
|
interface Props {
|
|
plugin: BookTrackerPlugin;
|
|
settings: ShelfSettings;
|
|
}
|
|
|
|
const { plugin, settings }: Props = $props();
|
|
|
|
const settingsStore = getSettingsContext();
|
|
const metadataStore = getMetadataContext();
|
|
</script>
|
|
|
|
<div class="book-details-list">
|
|
{#each metadataStore.metadata as book}
|
|
{@const coverPath = book.frontmatter[settings.coverProperty]}
|
|
{@const title = book.frontmatter[settings.titleProperty]}
|
|
{@const subtitle = settings.subtitleProperty
|
|
? book.frontmatter[settings.subtitleProperty]
|
|
: undefined}
|
|
{@const authors = book.frontmatter[settings.authorsProperty]}
|
|
{@const description = settings.descriptionProperty
|
|
? book.frontmatter[settings.descriptionProperty]
|
|
: undefined}
|
|
{@const seriesTitle = settings.seriesTitleProperty
|
|
? book.frontmatter[settings.seriesTitleProperty]
|
|
: undefined}
|
|
{@const seriesNumber = settings.seriesNumberProperty
|
|
? book.frontmatter[settings.seriesNumberProperty]
|
|
: undefined}
|
|
{@const startDate =
|
|
book.frontmatter[settingsStore.settings.startDateProperty]}
|
|
{@const endDate =
|
|
book.frontmatter[settingsStore.settings.endDateProperty]}
|
|
{@const rating =
|
|
book.frontmatter[settingsStore.settings.ratingProperty] ?? 0}
|
|
{@const spice =
|
|
book.frontmatter[settingsStore.settings.spiceProperty] ?? 0}
|
|
|
|
<div class="book-details">
|
|
<img
|
|
src={plugin.app.vault.getResourcePath(
|
|
plugin.app.vault.getFileByPath(coverPath)!,
|
|
)}
|
|
alt={title}
|
|
/>
|
|
<div class="book-info">
|
|
<OpenFileLink file={book.file}>
|
|
<h2 class="book-title">
|
|
{title}
|
|
</h2>
|
|
</OpenFileLink>
|
|
{#if subtitle}
|
|
<p class="subtitle">{subtitle}</p>
|
|
{/if}
|
|
<p class="authors">By: {authors.join(", ")}</p>
|
|
{#if seriesTitle}
|
|
<p class="series">
|
|
<span class="series-title">{seriesTitle}</span>
|
|
{#if seriesNumber}
|
|
<span class="series-number">#{seriesNumber}</span>
|
|
{/if}
|
|
</p>
|
|
{/if}
|
|
{#if description}
|
|
<hr />
|
|
<p class="description">{@html description}</p>
|
|
<hr />
|
|
{/if}
|
|
<div class="footer">
|
|
{#if settings.statusFilter === STATUS_IN_PROGRESS || settings.statusFilter === STATUS_READ}
|
|
<p class="start-date">
|
|
Started:
|
|
<datetime datetime={startDate}>{startDate}</datetime
|
|
>
|
|
</p>
|
|
{/if}
|
|
{#if settings.statusFilter === STATUS_IN_PROGRESS}
|
|
<Dot color="var(--text-muted)" />
|
|
<p class="current-page">
|
|
Current Page: {plugin.readingLog.getLastEntryForBook(
|
|
book.file.basename,
|
|
)?.pagesReadTotal ?? 0}
|
|
</p>
|
|
{/if}
|
|
{#if settings.statusFilter === STATUS_READ}
|
|
{@const iconSize = 18}
|
|
<Dot color="var(--text-muted)" />
|
|
<p class="end-date">
|
|
Finished:
|
|
<datetime datetime={endDate}>{endDate}</datetime>
|
|
</p>
|
|
<Dot color="var(--text-muted)" />
|
|
<RatingInput value={rating} disabled {iconSize}>
|
|
{#snippet inactive()}
|
|
<Star
|
|
color="var(--background-modifier-border)"
|
|
/>
|
|
{/snippet}
|
|
{#snippet active()}
|
|
<Star
|
|
color="var(--color-yellow)"
|
|
fill="rgba(var(--color-yellow-rgb), 0.2)"
|
|
/>
|
|
{/snippet}
|
|
{#snippet partial()}
|
|
<Star
|
|
color="var(--background-modifier-border)"
|
|
/>
|
|
<StarHalf
|
|
color="var(--color-yellow)"
|
|
fill="rgba(var(--color-yellow-rgb), 0.2)"
|
|
/>
|
|
{/snippet}
|
|
</RatingInput>
|
|
<RatingInput value={spice} disabled {iconSize}>
|
|
{#snippet inactive()}
|
|
<Flame
|
|
color="var(--background-modifier-border)"
|
|
/>
|
|
{/snippet}
|
|
{#snippet active()}
|
|
<Flame
|
|
color="var(--color-red)"
|
|
fill="rgba(var(--color-red-rgb), 0.2)"
|
|
/>
|
|
{/snippet}
|
|
</RatingInput>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
@use "../styles/breakpoints";
|
|
|
|
.book-details-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-4-6);
|
|
|
|
.book-details {
|
|
display: flex;
|
|
align-items: start;
|
|
gap: 1rem;
|
|
background-color: var(--background-secondary);
|
|
border-radius: var(--radius-l);
|
|
|
|
img {
|
|
border-radius: var(--radius-l);
|
|
max-width: 30%;
|
|
}
|
|
|
|
.book-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--size-4-2);
|
|
padding: var(--size-4-4);
|
|
|
|
h2,
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
hr {
|
|
margin: var(--size-4-2) 0;
|
|
}
|
|
|
|
.authors,
|
|
.series {
|
|
font-size: var(--font-small);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.description {
|
|
max-height: 30rem;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.footer {
|
|
font-size: var(--font-smaller);
|
|
color: var(--text-muted);
|
|
display: flex;
|
|
gap: var(--size-2-2);
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
}
|
|
}
|
|
|
|
container: book-details-list / inline-size;
|
|
@container book-details-list (width < 600px) {
|
|
.book-details {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
img {
|
|
max-height: 30rem;
|
|
max-width: 100%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|