Add random colors and designs to bookshelf

This commit is contained in:
Evan Fiordeliso 2025-07-05 00:05:50 -04:00
parent b5b9a3fd31
commit cfcde1dc5c
16 changed files with 270 additions and 112 deletions

View File

@ -1,3 +1,5 @@
import type { IN_PROGRESS_STATE, READ_STATE, TO_BE_READ_STATE } from "./const";
export interface Author { export interface Author {
name: string; name: string;
description: string; description: string;
@ -21,3 +23,9 @@ export interface Book {
isbn: string; isbn: string;
isbn13: string; isbn13: string;
} }
export type ToBeReadState = typeof TO_BE_READ_STATE;
export type InProgressState = typeof IN_PROGRESS_STATE;
export type ReadState = typeof READ_STATE;
export type ReadingState = ToBeReadState | InProgressState | ReadState;

View File

@ -1,131 +1,194 @@
<script lang="ts"> <script lang="ts">
import { READ_STATE } from "@src/const";
import type BookTrackerPlugin from "@src/main";
import type { ReadingState } from "@src/types";
import Book from "@ui/components/bookshelf/Book.svelte"; import Book from "@ui/components/bookshelf/Book.svelte";
import Bookshelf from "@ui/components/bookshelf/Bookshelf.svelte"; import Bookshelf from "@ui/components/bookshelf/Bookshelf.svelte";
import BookStack from "@ui/components/bookshelf/BookStack.svelte"; import BookStack from "@ui/components/bookshelf/BookStack.svelte";
import BookStackElement from "@ui/components/bookshelf/BookStackElement.svelte"; import BookStackElement from "@ui/components/bookshelf/BookStackElement.svelte";
import {
createMetadata,
setMetadataContext,
} from "@ui/stores/metadata.svelte";
import {
createSettings,
setSettingsContext,
} from "@ui/stores/settings.svelte";
import { COLOR_NAMES } from "@utils/color";
import { randomElement } from "@utils/rand";
import { onDestroy } from "svelte";
interface Props {
plugin: BookTrackerPlugin;
source: string;
}
const { plugin }: Props = $props();
const settingsStore = createSettings(plugin);
setSettingsContext(settingsStore);
let stateFilter: ReadingState = $state(READ_STATE);
const metadataStore = createMetadata(plugin, stateFilter);
setMetadataContext(metadataStore);
const designs = [
"default",
"colored-spine",
"dual-top-bands",
"split-bands",
] as const;
function randomDesign() {
return randomElement(designs);
}
function randomColor() {
return randomElement(COLOR_NAMES);
}
onDestroy(() => metadataStore.destroy());
</script> </script>
<Bookshelf> <Bookshelf>
<Book <Book
title="Hello World" title="Hello World"
color="purple"
width={1120} width={1120}
design="colored-spine" color={randomColor()}
design={randomDesign()}
/>
<Book
title="White Space"
width={700}
color={randomColor()}
design={randomDesign()}
/> />
<Book title="White Space" width={700} design="split-bands" color="pink" />
<Book <Book
title="The Art of Computer Programming Vol 1" title="The Art of Computer Programming Vol 1"
width={1156} width={1156}
design="dual-top-bands" color={randomColor()}
color="cyan" design={randomDesign()}
/> />
<Book <Book
title="Cascading Style Sheets" title="Cascading Style Sheets"
subtitle="Guide to Design" subtitle="Guide to Design"
width={560} width={560}
color={randomColor()}
design={randomDesign()}
orientation="tilted" orientation="tilted"
/> />
<Book <Book
title="HTML5" title="HTML5"
subtitle="Welcome to the Web" subtitle="Welcome to the Web"
width={1350} width={1350}
design="colored-spine" color={randomColor()}
design={randomDesign()}
/> />
<BookStack totalChildren={2}> <BookStack totalChildren={2}>
<BookStackElement <BookStackElement
title="Coding for Dummies" title="Coding for Dummies"
subtitle="JS tutorial" subtitle="JS tutorial"
color="blue" color={randomColor()}
design="colored-spine" design={randomDesign()}
/> />
<BookStackElement <BookStackElement
title="Coding for Dummies" title="Coding for Dummies"
subtitle="C# tutorial" subtitle="C# tutorial"
color="pink" color={randomColor()}
design="dual-top-bands" design={randomDesign()}
/> />
</BookStack> </BookStack>
<Book <Book
title="CoffeeScript" title="CoffeeScript"
subtitle="The JS Alternative" subtitle="The JS Alternative"
author="The Dev Guy" author="The Dev Guy"
design="split-bands" color={randomColor()}
color="green" design={randomDesign()}
orientation="on-display" orientation="on-display"
/> />
<Book <Book
title="Cheat Sheet" title="Cheat Sheet"
subtitle="Guide to Design" subtitle="Guide to Design"
color="blue"
design="split-bands"
width={870} width={870}
color={randomColor()}
design={randomDesign()}
/> />
<Book <Book
title="Psychology of Colors" title="Psychology of Colors"
color="pink"
design="dual-top-bands"
width={540} width={540}
color={randomColor()}
design={randomDesign()}
/> />
<Book <Book
title="TypeScript" title="TypeScript"
subtitle="Intro JS to type checking" subtitle="Intro JS to type checking"
color="cyan"
design="colored-spine"
width={1130} width={1130}
color={randomColor()}
design={randomDesign()}
/>
<Book
title="Testing"
width={10}
color={randomColor()}
design={randomDesign()}
/> />
<Book title="Testing" width={10} />
<Book <Book
title="JavaScript" title="JavaScript"
subtitle="The Definitive Guide" subtitle="The Definitive Guide"
author="David Flanagan" author="David Flanagan"
design="split-bands" color={randomColor()}
color="purple" design={randomDesign()}
orientation="on-display" orientation="on-display"
/> />
<Book title="Pragmatic Programmer" color="red" /> <Book
<Book title="White Space" color="yellow" design="split-bands" /> title="Pragmatic Programmer"
color={randomColor()}
design={randomDesign()}
/>
<Book title="White Space" color={randomColor()} design={randomDesign()} />
<Book <Book
title="W3 Schools" title="W3 Schools"
subtitle="The best around" subtitle="The best around"
color="blue" color={randomColor()}
design="split-bands" design={randomDesign()}
orientation="tilted" orientation="tilted"
/> />
<Book <Book
title="UI/UX" title="UI/UX"
subtitle="Guide to Mobile Development" subtitle="Guide to Mobile Development"
author="John Doe" author="John Doe"
color="purple" color={randomColor()}
design={randomDesign()}
orientation="on-display" orientation="on-display"
design="dual-top-bands"
/> />
<Book <Book
title="Clean Code" title="Clean Code"
color="orange" color={randomColor()}
design={randomDesign()}
orientation="tilted" orientation="tilted"
design="dual-top-bands"
/> />
<Book title="Docs for Devs" /> <Book title="Docs for Devs" color={randomColor()} design={randomDesign()} />
<BookStack totalChildren={4}> <BookStack totalChildren={4}>
<BookStackElement <BookStackElement
title="The Art of Computer Programming Vol 1" title="The Art of Computer Programming Vol 1"
color="green" color={randomColor()}
design="dual-top-bands" design={randomDesign()}
/> />
<BookStackElement <BookStackElement
title="The Art of Computer Programming Vol 2" title="The Art of Computer Programming Vol 2"
color="red" color={randomColor()}
design="dual-top-bands" design={randomDesign()}
/> />
<BookStackElement <BookStackElement
title="The Art of Computer Programming Vol 3" title="The Art of Computer Programming Vol 3"
color="blue" color={randomColor()}
design="dual-top-bands" design={randomDesign()}
/> />
<BookStackElement <BookStackElement
title="The Art of Computer Programming Vol 4a" title="The Art of Computer Programming Vol 4a"
color="pink" color={randomColor()}
design="dual-top-bands" design={randomDesign()}
/> />
</BookStack> </BookStack>
</Bookshelf> </Bookshelf>

View File

@ -56,7 +56,6 @@
); );
const verifiedWidth = $derived(widthCheck(width)); const verifiedWidth = $derived(widthCheck(width));
const textColor = $derived(color.contrastColor.hex);
</script> </script>
{#if orientation} {#if orientation}
@ -85,19 +84,19 @@
</BookOnDisplay> </BookOnDisplay>
{/if} {/if}
{:else if design === "split-bands"} {:else if design === "split-bands"}
<BookSplitBands color={color.hex} width={verifiedWidth} {textColor}> <BookSplitBands color={color.hex} width={verifiedWidth}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookSplitBands> </BookSplitBands>
{:else if design === "dual-top-bands"} {:else if design === "dual-top-bands"}
<BookDualTopBands color={color.hex} width={verifiedWidth} {textColor}> <BookDualTopBands color={color.hex} width={verifiedWidth}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookDualTopBands> </BookDualTopBands>
{:else if design === "colored-spine"} {:else if design === "colored-spine"}
<BookColoredSpine color={color.hex} width={verifiedWidth} {textColor}> <BookColoredSpine color={color.hex} width={verifiedWidth}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookColoredSpine> </BookColoredSpine>
{:else} {:else}
<BookDefault color={color.hex} width={verifiedWidth} {textColor}> <BookDefault color={color.hex} width={verifiedWidth}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookDefault> </BookDefault>
{/if} {/if}

View File

@ -25,24 +25,23 @@
? Color.fromName(colorRaw).darken() ? Color.fromName(colorRaw).darken()
: Color.fromCSSColor(colorRaw), : Color.fromCSSColor(colorRaw),
); );
const textColor = $derived(color.contrastColor.hex);
</script> </script>
<li class="bookshelf__bookstack-elem"> <li class="bookshelf__bookstack-elem">
{#if design === "split-bands"} {#if design === "split-bands"}
<BookStackSplitBands color={color.hex} {textColor}> <BookStackSplitBands color={color.hex}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookStackSplitBands> </BookStackSplitBands>
{:else if design === "dual-top-bands"} {:else if design === "dual-top-bands"}
<BookStackDualTopBands color={color.hex} {textColor}> <BookStackDualTopBands color={color.hex}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookStackDualTopBands> </BookStackDualTopBands>
{:else if design === "colored-spine"} {:else if design === "colored-spine"}
<BookStackColoredSpine color={color.hex} {textColor}> <BookStackColoredSpine color={color.hex}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookStackColoredSpine> </BookStackColoredSpine>
{:else} {:else}
<BookStackDefault color={color.hex} {textColor}> <BookStackDefault color={color.hex}>
<BookText {title} {subtitle} /> <BookText {title} {subtitle} />
</BookStackDefault> </BookStackDefault>
{/if} {/if}

View File

@ -19,6 +19,7 @@ $bookEdge: 2px;
display: inline-flex; display: inline-flex;
flex-flow: column nowrap; flex-flow: column nowrap;
list-style: none; list-style: none;
margin: 0;
padding: 0; padding: 0;
.bookshelf__bookStack-outOfStock { .bookshelf__bookStack-outOfStock {
@ -40,6 +41,8 @@ $bookEdge: 2px;
.bookshelf__bookstack-elem { .bookshelf__bookstack-elem {
margin-inline-start: 0; margin-inline-start: 0;
margin: 0;
padding: 0;
.bookshelf__book-wrapper { .bookshelf__book-wrapper {
width: 100%; width: 100%;

View File

@ -1,19 +1,28 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
width?: number; width?: number;
textColor?: string;
} }
let { children, color = "green", width = 40, textColor }: Props = $props(); let { children, color = "green", width = 40 }: Props = $props();
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const backgroundColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={color}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-background-color={backgroundColor.css()}
style:--book-width={width + "px"} style:--book-width={width + "px"}
style:width={width + "px"} style:width={width + "px"}
style:color={textColor} style:color={textColor}
@ -24,13 +33,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:before { &:before {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-background-color);
height: 100%; height: 100%;
width: calc(var(--book-width)); width: calc(var(--book-width));
border-radius: 4px; border-radius: 4px;

View File

@ -1,19 +1,27 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: ColorName | string; color?: string;
width?: number; width?: number;
textColor?: string;
} }
let { children, color = "green", width = 40, textColor }: Props = $props(); let { children, color = "green", width = 40 }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-width={width + "px"} style:--book-width={width + "px"}
style:width={width + "px"} style:width={width + "px"}
style:color={textColor} style:color={textColor}
@ -24,8 +32,8 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
:global(.bookshelf__book-content) { :global(.bookshelf__book-content) {
height: calc(var(--book-width)); height: calc(var(--book-width));

View File

@ -1,19 +1,29 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
width?: number; width?: number;
textColor?: string;
} }
let { children, color = "green", width = 40, textColor }: Props = $props(); let { children, color = "green", width = 40 }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const bandColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-band-color={bandColor.css()}
style:--book-width={width + "px"} style:--book-width={width + "px"}
style:width={width + "px"} style:width={width + "px"}
style:color={textColor} style:color={textColor}
@ -24,13 +34,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:after { &:after {
content: ""; content: "";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 20px; height: 20px;
width: calc(100% + 4px); width: calc(100% + 4px);
@ -42,7 +52,7 @@
&:before { &:before {
content: ""; content: "";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 20px; height: 20px;
width: calc(100% + 4px); width: calc(100% + 4px);

View File

@ -1,19 +1,29 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
width?: number; width?: number;
textColor?: string;
} }
let { children, color = "green", width = 40, textColor }: Props = $props(); let { children, color = "green", width = 40 }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const bandColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-band-color={bandColor.css()}
style:--book-width={width + "px"} style:--book-width={width + "px"}
style:width={width + "px"} style:width={width + "px"}
style:color={textColor} style:color={textColor}
@ -24,13 +34,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:after { &:after {
content: ""; content: "";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 20px; height: 20px;
width: calc(100% + 4px); width: calc(100% + 4px);
@ -42,7 +52,7 @@
&:before { &:before {
content: ""; content: "";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 20px; height: 20px;
width: calc(100% + 4px); width: calc(100% + 4px);

View File

@ -1,18 +1,26 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
textColor?: string;
} }
let { children, color = "green", textColor }: Props = $props(); let { children, color = "green" }: Props = $props();
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const backgroundColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-background-color={backgroundColor.css()}
style:color={textColor} style:color={textColor}
> >
{@render children?.()} {@render children?.()}
@ -21,13 +29,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:before { &:before {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-background-color);
height: 40px; height: 40px;
width: calc(100% + 4px); width: calc(100% + 4px);
border-radius: 4px; border-radius: 4px;

View File

@ -1,18 +1,26 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
textColor?: string;
} }
let { children, color = "green", textColor }: Props = $props(); let { children, color = "green" }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:color={textColor} style:color={textColor}
> >
{@render children?.()} {@render children?.()}
@ -21,7 +29,7 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
} }
</style> </style>

View File

@ -1,18 +1,28 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
textColor?: string;
} }
let { children, color = "green", textColor }: Props = $props(); let { children, color = "green" }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const bandColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-band-color={bandColor.css()}
style:color={textColor} style:color={textColor}
> >
{@render children?.()} {@render children?.()}
@ -21,13 +31,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:after { &:after {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 40px; height: 40px;
width: 10px; width: 10px;
@ -39,7 +49,7 @@
&:before { &:before {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 40px; height: 40px;
width: 15px; width: 15px;

View File

@ -1,18 +1,28 @@
<script lang="ts"> <script lang="ts">
import type { Snippet } from "svelte"; import type { Snippet } from "svelte";
import chroma from "chroma-js";
import { Color } from "@utils/color";
interface Props { interface Props {
children?: Snippet; children?: Snippet;
color?: string; color?: string;
textColor?: string;
} }
let { children, color = "green", textColor }: Props = $props(); let { children, color = "green" }: Props = $props();
const backgroundColor = $derived(chroma(color));
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
const bandColor = $derived(chroma(color).mix("black", 0.14));
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
</script> </script>
<div <div
class="bookshelf__book-wrapper" class="bookshelf__book-wrapper"
style:--book-color={color} style:--book-color={backgroundColor.css()}
style:--book-border-left-color={borderLeftColor.css()}
style:--book-border-right-color={borderRightColor.css()}
style:--book-band-color={bandColor.css()}
style:color={textColor} style:color={textColor}
> >
{@render children?.()} {@render children?.()}
@ -21,13 +31,13 @@
<style lang="scss"> <style lang="scss">
div { div {
background: var(--book-color); background: var(--book-color);
border-left: 2px solid color-mix(in srgb, var(--book-color), white 4%); border-left: 2px solid var(--book-border-left-color);
border-right: 2px solid color-mix(in srgb, var(--book-color), black 4%); border-right: 2px solid var(--book-border-right-color);
&:after { &:after {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 40px; height: 40px;
width: 20px; width: 20px;
@ -39,7 +49,7 @@
&:before { &:before {
content: " "; content: " ";
display: block; display: block;
background: color-mix(in srgb, var(--book-color), black 14%); background: var(--book-band-color);
height: 40px; height: 40px;
width: 20px; width: 20px;

View File

@ -51,7 +51,6 @@
books.set(key, bookCount + 1); books.set(key, bookCount + 1);
} }
console.log(pages);
if (isMonthly && typeof store.filterMonth === "number") { if (isMonthly && typeof store.filterMonth === "number") {
// @ts-expect-error Moment is provided by Obsidian // @ts-expect-error Moment is provided by Obsidian
const daysInMonth = moment() const daysInMonth = moment()
@ -65,7 +64,6 @@
} }
} }
} }
console.log(pages);
const labels = Array.from(books.keys()) const labels = Array.from(books.keys())
.sort((a, b) => a - b) .sort((a, b) => a - b)

View File

@ -4,6 +4,7 @@ import { getContext, setContext } from "svelte";
import { getSettingsContext } from "./settings.svelte"; import { getSettingsContext } from "./settings.svelte";
import type BookTrackerPlugin from "@src/main"; import type BookTrackerPlugin from "@src/main";
import { createDateFilter, type DateFilterStore } from "./date-filter.svelte"; import { createDateFilter, type DateFilterStore } from "./date-filter.svelte";
import type { ReadingState } from "@src/types";
export type FileMetadata = { export type FileMetadata = {
file: TFile; file: TFile;
@ -20,23 +21,30 @@ interface MetadataStore extends DateFilterStore {
destroy(): void; destroy(): void;
} }
export function createMetadata(plugin: BookTrackerPlugin): MetadataStore { export function createMetadata(
const settings = getSettingsContext().settings; plugin: BookTrackerPlugin,
state: ReadingState = READ_STATE
): MetadataStore {
const settingsStore = getSettingsContext();
const initialMetadata: FileMetadata[] = []; let metadata: FileMetadata[] = $state([]);
for (const file of plugin.app.vault.getMarkdownFiles()) { $effect(() => {
const frontmatter = const newMetadata: FileMetadata[] = [];
plugin.app.metadataCache.getFileCache(file)?.frontmatter ?? {};
if (frontmatter[settings.statusProperty] !== READ_STATE) { for (const file of plugin.app.vault.getMarkdownFiles()) {
continue; const frontmatter =
plugin.app.metadataCache.getFileCache(file)?.frontmatter ?? {};
if (frontmatter[settingsStore.settings.statusProperty] !== state) {
continue;
}
newMetadata.push({ file, frontmatter });
} }
initialMetadata.push({ file, frontmatter }); metadata = newMetadata;
} });
let metadata = $state(initialMetadata);
function onChanged(file: TFile, _data: string, cache: CachedMetadata) { function onChanged(file: TFile, _data: string, cache: CachedMetadata) {
metadata = metadata.map((f) => { metadata = metadata.map((f) => {

7
src/utils/rand.ts Normal file
View File

@ -0,0 +1,7 @@
export function randomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
export function randomElement<T>(arr: T[] | ReadonlyArray<T>): T {
return arr[randomInt(0, arr.length - 1)];
}