diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 81df196..43fb4b4 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,5 +1,4 @@ import esbuildSvelte from "esbuild-svelte"; -import sveltePreprocess from "svelte-preprocess"; import esbuild from "esbuild"; import process from "process"; import { builtinModules } from "node:module"; @@ -19,7 +18,7 @@ const context = await esbuild.context({ css: "injected", ...(prod ? {} : { enableSourcemap: true }), }, - preprocess: sveltePreprocess(...(prod ? [] : [{ sourceMap: true }])), + sourceMap: !prod, filterWarnings: (warning) => warning.code !== "css-unused-selector", }), ], diff --git a/package-lock.json b/package-lock.json index bc2aa92..9ac1b42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,16 +23,16 @@ "esbuild": "^0.24.0", "esbuild-svelte": "^0.9.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.43.0", + "eslint-plugin-svelte": "^2.45.1", "globals": "^15.13.0", "obsidian": "latest", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", - "svelte": "^4.2.12", + "svelte": "^5.0.0", "svelte-eslint-parser": "^0.43.0", - "svelte-preprocess": "^6.0.3", + "tsafe": "^1.8.5", "tslib": "^2.6.2", - "typescript": "^5.3.3", + "typescript": "^5.5.0", "typescript-eslint": "^8.18.0" } }, @@ -1114,6 +1114,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-typescript": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz", + "integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": ">=8.9.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1249,20 +1259,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1309,20 +1305,6 @@ "node": ">= 8" } }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1628,6 +1610,13 @@ "node": "*" } }, + "node_modules/esm-env": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.1.tgz", + "integrity": "sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==", + "dev": true, + "license": "MIT" + }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", @@ -1675,6 +1664,17 @@ "node": ">=0.10" } }, + "node_modules/esrap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.3.0.tgz", + "integrity": "sha512-LPT4X5Ur2sGnkQscwgWXRPVDuQrbuJbrStLmVXVXd+lGQ/HoYmcAa47t0Egzw1bYHwhF0w+6DTkxL1Xctp10XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@typescript-eslint/types": "^8.2.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -1698,16 +1698,6 @@ "node": ">=4.0" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -2108,13 +2098,6 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2308,18 +2291,6 @@ "node": ">=8" } }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2658,29 +2629,28 @@ } }, "node_modules/svelte": { - "version": "4.2.19", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", - "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.14.2.tgz", + "integrity": "sha512-OxNh82bYjbutXNSZSPQspZzzmVzlRyNbiz0a6KrpOWvQ9LBUUZifXyeKhfl73LgyQC9UbsnVS9M55nQzqekMTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "acorn-typescript": "^1.4.13", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "esm-env": "^1.2.1", + "esrap": "^1.2.3", + "is-reference": "^3.0.3", "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/svelte-eslint-parser": { @@ -2746,62 +2716,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/svelte-preprocess": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-6.0.3.tgz", - "integrity": "sha512-PLG2k05qHdhmRG7zR/dyo5qKvakhm8IJ+hD2eFRQmMLHp7X3eJnjeupUtvuRpbNiF31RjVw45W+abDwHEmP5OA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.10.2", - "coffeescript": "^2.5.1", - "less": "^3.11.3 || ^4.0.0", - "postcss": "^7 || ^8", - "postcss-load-config": ">=3", - "pug": "^3.0.0", - "sass": "^1.26.8", - "stylus": ">=0.55", - "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.100 || ^5.0.0", - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "coffeescript": { - "optional": true - }, - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "postcss-load-config": { - "optional": true - }, - "pug": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2828,6 +2742,12 @@ "typescript": ">=4.2.0" } }, + "node_modules/tsafe": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/tsafe/-/tsafe-1.8.5.tgz", + "integrity": "sha512-LFWTWQrW6rwSY+IBNFl2ridGfUzVsPwrZ26T4KUJww/py8rzaQ/SY+MIz6YROozpUCaRcuISqagmlwub9YT9kw==", + "dev": true + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2969,6 +2889,13 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", + "dev": true, + "license": "MIT" } } } diff --git a/package.json b/package.json index fa12517..dcdfa70 100644 --- a/package.json +++ b/package.json @@ -24,16 +24,16 @@ "esbuild": "^0.24.0", "esbuild-svelte": "^0.9.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.43.0", + "eslint-plugin-svelte": "^2.45.1", "globals": "^15.13.0", "obsidian": "latest", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", - "svelte": "^4.2.12", + "svelte": "^5.0.0", "svelte-eslint-parser": "^0.43.0", - "svelte-preprocess": "^6.0.3", + "tsafe": "^1.8.5", "tslib": "^2.6.2", - "typescript": "^5.3.3", + "typescript": "^5.5.0", "typescript-eslint": "^8.18.0" }, "dependencies": { diff --git a/src/components/Card.svelte b/src/components/Card.svelte index 37a1864..2f56134 100644 --- a/src/components/Card.svelte +++ b/src/components/Card.svelte @@ -6,16 +6,21 @@ setIcon, TFile, } from "obsidian"; - import { createEventDispatcher, onMount } from "svelte"; + import { onMount } from "svelte"; import { skipNextTransition, app, view, settings } from "./store"; import { TitleDisplayMode } from "../settings"; - import type { Child } from "svelte-eslint-parser/lib/parser/compat"; + import { assert, is } from "tsafe"; - export let file: TFile; - let displayFilename: boolean = true; + interface Props { + file: TFile; + updateLayoutNextTick: () => void; + } + + let { file, updateLayoutNextTick }: Props = $props(); let contentDiv: HTMLElement; - let pinned: boolean; - $: pinned = $settings.pinnedFiles.includes(file.path); + let pinned: boolean = $derived($settings.pinnedFiles.includes(file.path)); + // This will depend both on the settings and the content of the file + let displayFilename: boolean = $state(true); function postProcessor( element: HTMLElement, @@ -52,7 +57,6 @@ element.children[i].getElementsByClassName("internal-embed").length || element.children[i].className.includes("block-language-dataview") ) { - console.log("Adding shadow to embed note"); element.children[i].appendChild( document.createElement("div"), ).className = "embed-shadow"; @@ -89,9 +93,11 @@ const lastElText = element.children[lastBlockIndex].lastChild?.textContent; if (lastElText != null) { + const lastChild = element.children[lastBlockIndex].lastChild; + assert(!is(lastChild)); + assert(!is(lastElText)); const cut = Math.min(50, 200 - (charCount - lastElText.length)); - (element.children[lastBlockIndex].lastChild as Child).textContent = - `${lastElText.slice(0, cut)} ...`; + lastChild.textContent = `${lastElText.slice(0, cut)} ...`; } } @@ -102,13 +108,16 @@ MarkdownPreviewRenderer.unregisterPostProcessor(postProcessor); }; - const togglePin = async () => { + const togglePin = async (e: Event) => { + e.stopPropagation(); $settings.pinnedFiles = pinned ? $settings.pinnedFiles.filter((f) => f !== file.path) : [...$settings.pinnedFiles, file.path]; + updateLayoutNextTick(); }; - const trashFile = async () => { + const trashFile = async (e: Event) => { + e.stopPropagation(); await file.vault.trash(file, true); }; @@ -119,38 +128,44 @@ const trashIcon = (element: HTMLElement) => setIcon(element, "trash"); const folderIcon = (element: HTMLElement) => setIcon(element, "folder"); - const dispatch = createEventDispatcher(); - onMount(async () => { - await renderFile(contentDiv); - dispatch("loaded"); + onMount(() => { + (async () => { + await renderFile(contentDiv); + updateLayoutNextTick(); + })(); + return () => updateLayoutNextTick(); });
{#if displayFilename}

{file.basename}

{/if} -
+
{#if file.parent != null && file.parent.path !== "/"} -
{file.parent.path}
+
+ {file.parent.path} +
{/if}
@@ -203,7 +218,7 @@ /* Images embeds alone in a paragraph */ .card :global(p:has(> span.image-embed):not(:has(br)) span.image-embed) { display: block; - & img { + & :global(img) { display: block; } } @@ -235,7 +250,7 @@ border-color: var(--background-modifier-border-hover); } - .card h3 { + .card :global(h3) { word-wrap: break-word; } diff --git a/src/components/Root.svelte b/src/components/Root.svelte index 797ae83..2df2f92 100644 --- a/src/components/Root.svelte +++ b/src/components/Root.svelte @@ -1,6 +1,6 @@ -
- +
{#each $tags as tag} - {/each}
-
+
{#each $displayedFiles as file (file.path + file.stat.mtime)} - notesGrid.layout()} /> + {/each}
diff --git a/src/main.ts b/src/main.ts index 4305ddc..68aa382 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,10 +35,7 @@ export default class CardsViewPlugin extends Plugin { }, }); - this.registerView( - VIEW_TYPE, - (leaf) => new CardsViewPluginView(this.settings, leaf), - ); + this.registerView(VIEW_TYPE, (leaf) => new CardsViewPluginView(leaf)); this.app.workspace.onLayoutReady(() => { if (this.settings.launchOnStart) { diff --git a/src/view.ts b/src/view.ts index 167a559..96c66a4 100644 --- a/src/view.ts +++ b/src/view.ts @@ -1,20 +1,12 @@ -import { ItemView, TAbstractFile, TFile, WorkspaceLeaf } from "obsidian"; -import type { CardsViewSettings } from "./settings"; +import { ItemView, TAbstractFile, TFile } from "obsidian"; import Root from "./components/Root.svelte"; import store, { Sort } from "./components/store"; import { get } from "svelte/store"; +import { mount } from "svelte"; export const VIEW_TYPE = "cards-view"; export class CardsViewPluginView extends ItemView { - private settings: CardsViewSettings; - private svelteRoot?: Root; - - constructor(settings: CardsViewSettings, leaf: WorkspaceLeaf) { - super(leaf); - this.settings = settings; - } - getViewType() { return VIEW_TYPE; } @@ -69,7 +61,7 @@ export class CardsViewPluginView extends ItemView { ), ); - this.svelteRoot = new Root({ + mount(Root, { target: viewContent, });