Remove book folder setting and only rely on the tbr folder and read folder settings

This commit is contained in:
Evan Fiordeliso 2025-08-23 16:14:38 -04:00
parent 1191347105
commit 0ef651d661
14 changed files with 57 additions and 61 deletions

View File

@ -1,7 +1,7 @@
{
"id": "obsidian-book-tracker",
"name": "Book Tracker",
"version": "1.6.1",
"version": "1.7.0",
"minAppVersion": "0.15.0",
"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
"author": "FiFiTiDo",

View File

@ -1,6 +1,6 @@
{
"name": "obsidian-book-tracker",
"version": "1.6.1",
"version": "1.7.0",
"description": "Simplifies tracking your reading progress and managing your book collection in Obsidian.",
"main": "main.js",
"scripts": {

View File

@ -13,6 +13,6 @@
<Item {name} {description}>
{#snippet control()}
<FileSuggest {id} asString bind:value />
<FileSuggest {id} bind:value />
{/snippet}
</Item>

View File

@ -13,6 +13,6 @@
<Item {name} {description}>
{#snippet control()}
<FolderSuggest {id} asString bind:value />
<FolderSuggest {id} bind:value />
{/snippet}
</Item>

View File

@ -20,6 +20,6 @@
<Item {name} {description}>
{#snippet control()}
<PropertySuggest {id} asString bind:value {accepts} />
<PropertySuggest {id} bind:value {accepts} />
{/snippet}
</Item>

View File

@ -3,42 +3,39 @@
import TextInputSuggest, { type Item } from "./TextInputSuggest.svelte";
import type { StringKeys } from "@utils/types";
import { getAppContext } from "@ui/stores/app";
import { isInAnyFolder } from "@utils/fs";
type Props = {
id: string;
asString?: boolean;
property?: StringKeys<TFile>;
inFolder?: string;
value?: TFile | string;
folderFilter?: string[];
value?: string;
disabled?: boolean;
onSelected?: (fileOrPath: TFile | string) => void;
onSelected?: (propertyValue: string) => void;
};
let {
id,
asString,
property = "path",
inFolder,
folderFilter,
value = $bindable(),
disabled,
onSelected,
}: Props = $props();
const app = getAppContext();
let items: Item<TFile | string>[] = $state([]);
let items: Item<string>[] = $state([]);
function handleChange(query: string) {
items = app.vault
.getMarkdownFiles()
.filter(
(f) =>
(inFolder === undefined || f.path.startsWith(inFolder)) &&
(folderFilter === undefined ||
isInAnyFolder(f, folderFilter)) &&
f[property].toLowerCase().includes(query.toLowerCase()),
)
.map((f) => ({
text: f[property],
value: asString ? f[property] : f,
}));
.map((f) => f[property]);
}
</script>

View File

@ -3,22 +3,21 @@
import TextInputSuggest, { type Item } from "./TextInputSuggest.svelte";
import type { StringKeys } from "@utils/types";
import { getAppContext } from "@ui/stores/app";
import { isInAnyFolder } from "@utils/fs";
type Props = {
id: string;
asString?: boolean;
property?: StringKeys<TFolder>;
inFolder?: string;
value?: TFolder | string;
folderFilter?: string[];
value?: string;
disabled?: boolean;
onSelected?: (folderOrPath: TFolder | string) => void;
onSelected?: (propertyValue: string) => void;
};
let {
id,
asString,
property = "path",
inFolder,
folderFilter,
value = $bindable(),
disabled,
onSelected,
@ -32,13 +31,11 @@
.getAllFolders()
.filter(
(f) =>
(inFolder === undefined || f.path.startsWith(inFolder)) &&
(folderFilter === undefined ||
isInAnyFolder(f, folderFilter)) &&
f[property].toLowerCase().includes(query.toLowerCase()),
)
.map((f) => ({
text: f[property],
value: asString ? f[property] : f,
}));
.map((f) => f[property]);
}
</script>

View File

@ -12,16 +12,14 @@
type Props = {
id: string;
asString?: boolean;
value?: Property | string;
value?: string;
accepts?: string[];
disabled?: boolean;
onSelected?: (propertyOrName: Property | string) => void;
onSelected?: (propertyName: string) => void;
};
let {
id,
asString,
value = $bindable(),
accepts,
disabled,
@ -29,7 +27,7 @@
}: Props = $props();
const app = getAppContext();
let items: Item<Property | string>[] = $state([]);
let items: Item<string>[] = $state([]);
async function handleChange(query: string) {
const typesContent = await app.vault.adapter.read(
@ -45,10 +43,7 @@
return name.toLowerCase().includes(query.toLowerCase());
})
.map(([name, type]) => ({
text: name,
value: asString ? name : { name, type },
}));
.map(([name, _]) => name);
}
</script>

View File

@ -1,8 +1,10 @@
<script lang="ts" module>
export type Item<T> = {
text: string;
value: T;
};
export type Item<T> =
| {
label: string;
value: T;
}
| (T extends string ? T : never);
</script>
<script lang="ts">
@ -26,7 +28,7 @@
let {
id,
items,
items: itemsProp,
value = $bindable(),
loading = false,
suggestion,
@ -35,6 +37,12 @@
onSelected,
}: Props = $props();
const items = $derived(
itemsProp.map((item) =>
typeof item === "string" ? { label: item, value: item } : item,
),
);
let query = $state("");
let expanded = $state(false);
let selectedIndex = $state(0);
@ -53,7 +61,7 @@
const idx = findIndex(value);
if (idx !== -1) {
const item = items[idx];
query = item.text;
query = item.label;
selectedIndex = idx;
}
});
@ -99,7 +107,7 @@
async function selectItem(index: number) {
const item = items[index];
if (!item) return;
const { text: newQuery, value: newValue } = item;
const { label: newQuery, value: newValue } = item;
selectedIndex = index;
expanded = false;
query = newQuery;
@ -195,7 +203,7 @@
{#if suggestion}
{@render suggestion(item)}
{:else}
{item.text}
{item.label}
{/if}
</li>
{/each}

View File

@ -108,9 +108,11 @@
<label for="book">Book</label>
<FileSuggest
id="book"
asString
property="basename"
inFolder={plugin.settings.bookFolder}
folderFilter={[
plugin.settings.tbrFolder,
plugin.settings.readBooksFolder,
]}
bind:value={book}
/>
<label for="pagesRead">Pages Read</label>

View File

@ -170,35 +170,29 @@
<div class="obt-settings">
<Header title="Folders" />
<FolderSuggestItem
id="book-folder"
name="Book Folder"
description="Select the folder where book entries are stored."
bind:value={settingsStore.settings.bookFolder}
/>
<FolderSuggestItem
id="tbr-folder"
name="To Be Read Folder"
description="Select the folder to use for To Be Read entries"
description="The folder to use for To Be Read or Currently Reading book entries."
bind:value={settingsStore.settings.tbrFolder}
/>
<FolderSuggestItem
id="read-folder"
name="Read Books Folder"
description="Select the folder to use for Read entries."
description="The folder to use for Read book entries."
bind:value={settingsStore.settings.readBooksFolder}
/>
<ToggleItem
id="organize-read-books"
name="Organize Read Books"
description="Organize read books into folders based on the date read."
description="Whether to automatically organize read books into folders, based on the date read, when finishing a book."
bind:checked={settingsStore.settings.organizeReadBooks}
/>
<Header title="Book Creation" />
<FileSuggestItem
id="template-file"
name="Template File"
description="Select the template file to use for new book entries."
description="The template file to use when creating new book entries."
bind:value={settingsStore.settings.templateFile}
/>
<TextInputItem

View File

@ -1,5 +1,4 @@
export interface BookTrackerSettings {
bookFolder: string;
tbrFolder: string;
readBooksFolder: string;
organizeReadBooks: boolean;
@ -34,7 +33,6 @@ export interface BookTrackerSettings {
}
export const DEFAULT_SETTINGS: BookTrackerSettings = {
bookFolder: "books",
tbrFolder: "books/tbr",
readBooksFolder: "books/read",
organizeReadBooks: true,

View File

@ -1,4 +1,4 @@
import { normalizePath, type Vault } from "obsidian";
import { normalizePath, TAbstractFile, type Vault } from "obsidian";
/**
* A simple analog of Node.js's `path.join(...)`.
@ -52,3 +52,7 @@ export async function mkdirRecursive(
await vault.adapter.mkdir(stack.pop()!);
}
}
export function isInAnyFolder(file: TAbstractFile, folders: string[]): boolean {
return folders.some((folder) => file.path.startsWith(folder));
}

View File

@ -10,5 +10,6 @@
"1.4.2": "0.15.0",
"1.5.0": "0.15.0",
"1.6.0": "0.15.0",
"1.6.1": "0.15.0"
"1.6.1": "0.15.0",
"1.7.0": "0.15.0"
}