Fix text not having fixed width and fix books having wrong title

This commit is contained in:
Evan Fiordeliso 2025-07-05 23:04:56 -04:00
parent 18aa687647
commit a1956078d8
5 changed files with 71 additions and 40 deletions

View File

@ -15,12 +15,13 @@
setSettingsContext, setSettingsContext,
} from "@ui/stores/settings.svelte"; } from "@ui/stores/settings.svelte";
import { COLOR_NAMES, type ColorName } from "@utils/color"; import { COLOR_NAMES, type ColorName } from "@utils/color";
import { randomElement, randomFloat, randomInt } from "@utils/rand"; import { randomElement, randomFloat } from "@utils/rand";
import { onDestroy } from "svelte"; import { onDestroy } from "svelte";
import { ShelfSettingsSchema } from "./ShelfCodeBlock"; import { ShelfSettingsSchema } from "./ShelfCodeBlock";
import { parseYaml, TFile } from "obsidian"; import { getLinkpath, parseYaml, TFile } from "obsidian";
import DateFilter from "@ui/components/DateFilter.svelte"; import DateFilter from "@ui/components/DateFilter.svelte";
import Rating from "@ui/components/Rating.svelte"; import Rating from "@ui/components/Rating.svelte";
import { v4 as uuidv4 } from "uuid";
interface Props { interface Props {
plugin: BookTrackerPlugin; plugin: BookTrackerPlugin;
@ -28,6 +29,7 @@
} }
interface BookData { interface BookData {
id: string;
title: string; title: string;
subtitle?: string; subtitle?: string;
author: string; author: string;
@ -38,6 +40,11 @@
file: TFile; file: TFile;
} }
interface BookStackData {
id: string;
books: BookData[];
}
const { plugin, source }: Props = $props(); const { plugin, source }: Props = $props();
const settings = ShelfSettingsSchema.parse(parseYaml(source)); const settings = ShelfSettingsSchema.parse(parseYaml(source));
@ -71,13 +78,13 @@
const randomStackChance = () => randomFloat() > 0.9; const randomStackChance = () => randomFloat() > 0.9;
function randomStackSize() { function randomStackSize() {
const n = randomFloat(); const n = randomFloat();
if (n < 0.2) { if (n < 0.15) {
return 5; return 5;
} else if (n < 0.5) { } else if (n < 0.3) {
return 4; return 4;
} else if (n < 0.8) { } else if (n < 0.5) {
return 3; return 3;
} else if (n < 0.98) { } else if (n < 0.8) {
return 2; return 2;
} else { } else {
return 1; return 1;
@ -86,6 +93,7 @@
function getBookData(metadata: FileMetadata): BookData { function getBookData(metadata: FileMetadata): BookData {
return { return {
id: metadata.file.path,
title: metadata.frontmatter[settings.titleProperty], title: metadata.frontmatter[settings.titleProperty],
subtitle: settings.subtitleProperty subtitle: settings.subtitleProperty
? metadata.frontmatter[settings.subtitleProperty] ? metadata.frontmatter[settings.subtitleProperty]
@ -102,29 +110,29 @@
} }
let view = $state(settings.defaultView); let view = $state(settings.defaultView);
const books = $derived.by(() => { let books: (BookData | BookStackData)[] = $state([]);
let books: (BookData | BookData[])[] = [];
$effect(() => {
let newBooks: (BookData | BookStackData)[] = [];
for (let i = 0; i < metadataStore.metadata.length; i++) { for (let i = 0; i < metadataStore.metadata.length; i++) {
if (randomStackChance()) { if (randomStackChance()) {
const booksRemaining = metadataStore.metadata.length - i; const booksRemaining = metadataStore.metadata.length - i;
const stackSize = randomInt( const stackSize = Math.min(booksRemaining, randomStackSize());
1,
Math.min(booksRemaining, randomStackSize()),
);
books.push( newBooks.push({
metadataStore.metadata id: uuidv4(),
books: metadataStore.metadata
.slice(i, i + stackSize) .slice(i, i + stackSize)
.map(getBookData), .map(getBookData),
); });
i += stackSize - 1; i += stackSize - 1;
} else { } else {
books.push(getBookData(metadataStore.metadata[i])); newBooks.push(getBookData(metadataStore.metadata[i]));
} }
} }
return books; books = newBooks;
}); });
onDestroy(() => metadataStore.destroy()); onDestroy(() => metadataStore.destroy());
@ -146,21 +154,19 @@
</div> </div>
{#if view === "bookshelf"} {#if view === "bookshelf"}
<Bookshelf> <Bookshelf>
{#each books as book} {#each books as book (book.id)}
{#if Array.isArray(book)} {#if "books" in book}
<BookStack totalChildren={book.length}> <BookStack totalChildren={book.books.length}>
{#each book as bookData} {#each book.books as bookData (bookData.id)}
<BookStackElement <BookStackElement
title={bookData.title} title={bookData.title}
subtitle={bookData.subtitle} subtitle={bookData.subtitle}
color={bookData.color} color={bookData.color}
design={bookData.design} design={bookData.design}
onClick={() => onClick={() =>
plugin.app.workspace.openLinkText( plugin.app.workspace
bookData.file.path, .getLeaf("tab")
"", .openFile(bookData.file)}
true,
)}
/> />
{/each} {/each}
</BookStack> </BookStack>
@ -174,11 +180,9 @@
design={book.design} design={book.design}
orientation={book.orientation} orientation={book.orientation}
onClick={() => onClick={() =>
plugin.app.workspace.openLinkText( plugin.app.workspace
book.file.path, .getLeaf("tab")
"", .openFile(book.file)}
true,
)}
/> />
{/if} {/if}
{/each} {/each}
@ -221,7 +225,11 @@
width="50" width="50"
/> />
</td> </td>
<td>{book.frontmatter[settings.titleProperty]}</td> <td>
<a href={getLinkpath(book.file.path)}>
{book.frontmatter[settings.titleProperty]}
</a>
</td>
<td> <td>
{book.frontmatter[settings.authorsProperty].join( {book.frontmatter[settings.authorsProperty].join(
", ", ", ",

View File

@ -151,7 +151,8 @@
z-index: 2; z-index: 2;
} }
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
height: calc(var(--book-width)); height: calc(var(--book-width));
} }
} }
@ -167,8 +168,12 @@
top: 26px; top: 26px;
} }
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
width: calc(200px - 61px) !important; width: calc(200px - 61px) !important;
}
:global(.bookshelf__book-content) {
margin: 40px var(--book-width); margin: 40px var(--book-width);
} }
} }
@ -187,8 +192,12 @@
bottom: 10px; bottom: 10px;
} }
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
width: calc(200px - 62px) !important; width: calc(200px - 62px) !important;
}
:global(.bookshelf__book-content) {
margin: 30px var(--book-width); margin: 30px var(--book-width);
} }
} }

View File

@ -107,8 +107,12 @@
right: 10px; right: 10px;
} }
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
width: calc(200px - 60px) !important; width: calc(200px - 60px) !important;
}
:global(.bookshelf__book-content) {
margin: 0 30px; margin: 0 30px;
} }
} }
@ -125,8 +129,12 @@
z-index: 2; z-index: 2;
} }
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
width: calc(200px - 31px) !important; width: calc(200px - 31px) !important;
}
:global(.bookshelf__book-content) {
margin: 0 31px; margin: 0 31px;
} }
} }

View File

@ -17,12 +17,13 @@
> >
{#if title} {#if title}
<h2 <h2
class="bookshelf__book-title" class="bookshelf__book-title fit-text"
class:wrap={allowWrap} class:wrap={allowWrap}
use:fitText={{ use:fitText={{
minFontSize: 12, minFontSize: 12,
maxFontSize: 16, maxFontSize: 16,
multiLine: allowWrap, multiLine: allowWrap,
detectMultiLine: false,
}} }}
> >
{title} {title}
@ -30,11 +31,12 @@
{/if} {/if}
{#if subtitle} {#if subtitle}
<h4 <h4
class="bookshelf__book-subtitle" class="bookshelf__book-subtitle fit-text"
use:fitText={{ use:fitText={{
minFontSize: 10, minFontSize: 10,
maxFontSize: 14, maxFontSize: 14,
multiLine: allowWrap, multiLine: allowWrap,
detectMultiLine: false,
}} }}
> >
{subtitle} {subtitle}

View File

@ -38,9 +38,13 @@
<style lang="scss"> <style lang="scss">
div { div {
:global(.bookshelf__book-content) { :global(.bookshelf__book-content),
:global(.fit-text) {
height: calc(var(--book-tilted-width)); height: calc(var(--book-tilted-width));
width: calc(200px - 60px); width: calc(200px - 60px);
}
:global(.bookshelf__book-content) {
margin: var(--book-tilted-top-margin) var(--book-tilted-width); margin: var(--book-tilted-top-margin) var(--book-tilted-width);
} }
} }