From 32b2e444e649b1d9ae4ce947d0d3007d1022856f Mon Sep 17 00:00:00 2001 From: DecafDev <40307803+decaf-dev@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:42:31 -0600 Subject: [PATCH 1/4] feat: simplify view order --- manifest.json | 2 +- package.json | 2 +- src/constants.ts | 21 +- src/migrations/index.ts | 6 + src/migrations/migrate_1_45_0.ts | 5 +- src/migrations/migrate_1_46_0.ts | 42 +++ src/obsidian/vault-explorer-settings-tab.ts | 130 ++++---- src/svelte/app/index.svelte | 182 ++++++---- src/svelte/app/services/display-name.ts | 8 +- src/types/index.guard.ts | 39 +-- src/types/index.ts | 18 +- src/types/types-1.45.0.ts | 311 ++++++++++++++++++ .../plugins/vault-explorer/data.json | 183 +++++------ versions.json | 3 +- 14 files changed, 663 insertions(+), 289 deletions(-) create mode 100644 src/migrations/migrate_1_46_0.ts create mode 100644 src/types/types-1.45.0.ts diff --git a/manifest.json b/manifest.json index d7c1f578..d5a079c2 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "vault-explorer", "name": "Vault Explorer", - "version": "1.45.0", + "version": "1.46.0", "minAppVersion": "1.4.13", "description": "Explore your vault in visual format", "author": "DecafDev", diff --git a/package.json b/package.json index 6baa5cde..62041df9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-vault-explorer", - "version": "1.45.0", + "version": "1.46.0", "description": "Explore your vault in visual format", "main": "main.js", "scripts": { diff --git a/src/constants.ts b/src/constants.ts index c7aff152..3a0efdce 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -32,11 +32,9 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = { }, }, views: { - dashboard: { - isEnabled: false, - }, grid: { isEnabled: true, + order: 0, coverImageFit: "cover", coverImageSources: [ { @@ -60,24 +58,21 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = { }, list: { isEnabled: true, + order: 1, showTags: true, }, - table: { - isEnabled: false, - }, feed: { isEnabled: true, + order: 2, removeH1: true, collapseStyle: "no-new-lines", lineClampLarge: 5, lineClampMedium: 3, lineClampSmall: 2, }, - recommended: { - isEnabled: false, - }, - related: { + table: { isEnabled: false, + order: 3, }, }, confirmBeforeDelete: true, @@ -88,12 +83,6 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = { loadBodyTags: true, shouldCollapseFilters: false, pageSize: 25, - viewOrder: [ - TExplorerView.GRID, - TExplorerView.LIST, - TExplorerView.FEED, - TExplorerView.TABLE, - ], configDir: ".vaultexplorer", pluginVersion: null, logLevel: LOG_LEVEL_WARN, diff --git a/src/migrations/index.ts b/src/migrations/index.ts index b1e5a4a5..f8306274 100644 --- a/src/migrations/index.ts +++ b/src/migrations/index.ts @@ -33,6 +33,7 @@ import Migrate_1_40_0 from "./migrate_1_40_0"; import Migrate_1_41_0 from "./migrate_1_41_0"; import Migrate_1_42_0 from "./migrate_1_42_0"; import Migrate_1_45_0 from "./migrate_1_45_0"; +import Migrate_1_46_0 from "./migrate_1_46_0"; const migrations: TMigration[] = [ { @@ -195,6 +196,11 @@ const migrations: TMigration[] = [ to: "1.45.0", migrate: Migrate_1_45_0, }, + { + from: "1.45.0", + to: "1.46.0", + migrate: Migrate_1_46_0, + }, ]; export const preformMigrations = ( diff --git a/src/migrations/migrate_1_45_0.ts b/src/migrations/migrate_1_45_0.ts index 0b2541fe..03977a96 100644 --- a/src/migrations/migrate_1_45_0.ts +++ b/src/migrations/migrate_1_45_0.ts @@ -1,6 +1,7 @@ import { VaultExplorerPluginSettings_1_44_6 } from "src/types/types-1.44.6"; import MigrationInterface from "./migration_interface"; -import { TExplorerView, VaultExplorerPluginSettings } from "src/types"; +import { TExplorerView } from "src/types"; +import { VaultExplorerPluginSettings_1_45_0 } from "src/types/types-1.45.0"; export default class Migrate_1_45_0 implements MigrationInterface { migrate(data: Record) { @@ -20,7 +21,7 @@ export default class Migrate_1_45_0 implements MigrationInterface { viewOrder.push(TExplorerView.TABLE); } - const newData: VaultExplorerPluginSettings = { + const newData: VaultExplorerPluginSettings_1_45_0 = { ...typedData, confirmBeforeDelete: true, viewOrder, diff --git a/src/migrations/migrate_1_46_0.ts b/src/migrations/migrate_1_46_0.ts new file mode 100644 index 00000000..823e6d47 --- /dev/null +++ b/src/migrations/migrate_1_46_0.ts @@ -0,0 +1,42 @@ +import MigrationInterface from "./migration_interface"; +import { TExplorerView, VaultExplorerPluginSettings } from "src/types"; +import { VaultExplorerPluginSettings_1_45_0 } from "src/types/types-1.45.0"; + +export default class Migrate_1_46_0 implements MigrationInterface { + migrate(data: Record) { + const typedData = data as unknown as VaultExplorerPluginSettings_1_45_0; + + const newData: VaultExplorerPluginSettings = { + ...typedData, + views: { + ...typedData.views, + grid: { + ...typedData.views.grid, + isEnabled: true, + order: 0, + }, + list: { + ...typedData.views.list, + isEnabled: true, + order: 1, + }, + feed: { + ...typedData.views.feed, + isEnabled: true, + order: 2, + }, + table: { + ...typedData.views.table, + isEnabled: true, + order: 3, + }, + }, + currentView: TExplorerView.GRID, + }; + delete (newData as any).views.recommended; + delete (newData as any).views.related; + delete (newData as any).views.dashboard; + delete (newData as any).viewOrder; + return newData as unknown as Record; + } +} diff --git a/src/obsidian/vault-explorer-settings-tab.ts b/src/obsidian/vault-explorer-settings-tab.ts index 548896f7..db62ab25 100644 --- a/src/obsidian/vault-explorer-settings-tab.ts +++ b/src/obsidian/vault-explorer-settings-tab.ts @@ -14,7 +14,12 @@ import { } from "src/logger/constants"; import Logger from "js-logger"; import { stringToLogLevel } from "src/logger"; -import { CollapseStyle, CoverImageFit, TExplorerView } from "src/types"; +import { + CollapseStyle, + CoverImageFit, + TExplorerView, + VaultExplorerPluginSettings, +} from "src/types"; import EventManager from "src/event/event-manager"; import LicenseKeyApp from "../svelte/license-key-app/index.svelte"; import ImageSourceApp from "../svelte/image-source-app/index.svelte"; @@ -158,25 +163,16 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { new Setting(containerEl).setName("Views").setHeading(); - // new Setting(containerEl).setName("Dashboard view").addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.views.dashboard.isEnabled) - // .onChange(async (value) => { - // this.plugin.settings.views.dashboard.isEnabled = value; - // this.updateViewOrder(TExplorerView.DASHBOARD, value); - // await this.plugin.saveSettings(); - // EventManager.getInstance().emit( - // PluginEvent.VIEW_TOGGLE_SETTING_CHANGE - // ); - // }) - // ); - new Setting(containerEl).setName("Grid view").addToggle((toggle) => toggle .setValue(this.plugin.settings.views.grid.isEnabled) .onChange(async (value) => { this.plugin.settings.views.grid.isEnabled = value; - this.updateViewOrder(TExplorerView.GRID, value); + this.updateViewOrder( + this.plugin.settings, + TExplorerView.GRID, + value + ); await this.plugin.saveSettings(); EventManager.getInstance().emit( PluginEvent.VIEW_TOGGLE_SETTING_CHANGE @@ -189,7 +185,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { .setValue(this.plugin.settings.views.list.isEnabled) .onChange(async (value) => { this.plugin.settings.views.list.isEnabled = value; - this.updateViewOrder(TExplorerView.LIST, value); + this.updateViewOrder( + this.plugin.settings, + TExplorerView.LIST, + value + ); await this.plugin.saveSettings(); EventManager.getInstance().emit( PluginEvent.VIEW_TOGGLE_SETTING_CHANGE @@ -202,7 +202,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { .setValue(this.plugin.settings.views.feed.isEnabled) .onChange(async (value) => { this.plugin.settings.views.feed.isEnabled = value; - this.updateViewOrder(TExplorerView.FEED, value); + this.updateViewOrder( + this.plugin.settings, + TExplorerView.FEED, + value + ); await this.plugin.saveSettings(); EventManager.getInstance().emit( PluginEvent.VIEW_TOGGLE_SETTING_CHANGE @@ -215,7 +219,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { .setValue(this.plugin.settings.views.table.isEnabled) .onChange(async (value) => { this.plugin.settings.views.table.isEnabled = value; - this.updateViewOrder(TExplorerView.TABLE, value); + this.updateViewOrder( + this.plugin.settings, + TExplorerView.TABLE, + value + ); await this.plugin.saveSettings(); EventManager.getInstance().emit( PluginEvent.VIEW_TOGGLE_SETTING_CHANGE @@ -223,35 +231,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { }) ); - // new Setting(containerEl) - // .setName("Recommended view") - // .addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.views.recommended.isEnabled) - // .onChange(async (value) => { - // this.plugin.settings.views.recommended.isEnabled = - // value; - // this.updateViewOrder(TExplorerView.RECOMMENDED, value); - // await this.plugin.saveSettings(); - // EventManager.getInstance().emit( - // PluginEvent.VIEW_TOGGLE_SETTING_CHANGE - // ); - // }) - // ); - - // new Setting(containerEl).setName("Related view").addToggle((toggle) => - // toggle - // .setValue(this.plugin.settings.views.related.isEnabled) - // .onChange(async (value) => { - // this.plugin.settings.views.related.isEnabled = value; - // this.updateViewOrder(TExplorerView.RELATED, value); - // await this.plugin.saveSettings(); - // EventManager.getInstance().emit( - // PluginEvent.VIEW_TOGGLE_SETTING_CHANGE - // ); - // }) - // ); - new Setting(containerEl).setName("Grid view").setHeading(); this.imageSourceApp = new ImageSourceApp({ @@ -717,26 +696,47 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { this.imageSourceApp?.$destroy(); } - private updateViewOrder(view: TExplorerView, value: boolean) { - if (value) { - this.plugin.settings.viewOrder.push(view); + private updateViewOrder( + settings: VaultExplorerPluginSettings, + view: TExplorerView, + value: boolean + ) { + const views = { + [TExplorerView.GRID]: { ...settings.views.grid }, + [TExplorerView.LIST]: { ...settings.views.list }, + [TExplorerView.FEED]: { ...settings.views.feed }, + [TExplorerView.TABLE]: { ...settings.views.table }, + }; + + const maxOrder = Math.max( + views[TExplorerView.GRID].order, + views[TExplorerView.LIST].order, + views[TExplorerView.FEED].order, + views[TExplorerView.TABLE].order + ); + + const viewToUpdate = views[view]; - //If the user turned off all views, set the current view to the first view that is turned on - if (this.plugin.settings.currentView == null) - this.plugin.settings.currentView = view; + if (value) { + viewToUpdate.order = maxOrder + 1; } else { - const filtered = this.plugin.settings.viewOrder.filter( - (v) => v !== view - ); - this.plugin.settings.viewOrder = filtered; - - //If the user turned off the current view, set the current view to the first view - //that is turned on, otherwise set it to null - if (filtered.length > 0) { - this.plugin.settings.currentView = filtered[0]; - } else { - this.plugin.settings.currentView = null; - } + Object.values(views).forEach((view) => { + if (view.order > viewToUpdate.order) { + view.order--; + } + }); + viewToUpdate.order = -1; } + + const currentViewEntry = Object.entries(views).find( + (v) => v[1].order === 0 + ); + + this.plugin.settings.currentView = (currentViewEntry?.[0] ?? + null) as TExplorerView | null; + this.plugin.settings.views.grid = views[TExplorerView.GRID]; + this.plugin.settings.views.list = views[TExplorerView.LIST]; + this.plugin.settings.views.feed = views[TExplorerView.FEED]; + this.plugin.settings.views.table = views[TExplorerView.TABLE]; } } diff --git a/src/svelte/app/index.svelte b/src/svelte/app/index.svelte index de9a6ec3..d9382b64 100644 --- a/src/svelte/app/index.svelte +++ b/src/svelte/app/index.svelte @@ -13,6 +13,10 @@ TSortFilter, TExplorerView, CoverImageFit, + TGridView, + TFeedView, + TTableView, + TListView, } from "src/types"; import store from "../shared/services/store"; import VaultExplorerPlugin from "src/main"; @@ -65,28 +69,30 @@ let plugin: VaultExplorerPlugin; let ref: HTMLElement | null = null; - let startOfTodayMillis: number; - let startOfThisWeekMillis: number; - let startOfLastWeekMillis: number; + let startOfTodayMillis: number = -1; + let startOfThisWeekMillis: number = -1; + let startOfLastWeekMillis: number = -1; let shouldCollapseFilters: boolean = false; let pageSize: number = 0; let searchFilter: TSearchFilter = { - isEnabled: true, + isEnabled: false, value: "", }; + let sortFilter: TSortFilter = { - isEnabled: true, + isEnabled: false, value: "file-name-asc", }; + let customFilter: TCustomFilter = { - isEnabled: true, - groups: [], + isEnabled: false, selectedGroupId: "", + groups: [], }; - let currentView: TExplorerView | null = TExplorerView.GRID; + let currentView: TExplorerView | null = null; let frontmatterCacheTime: number = Date.now(); let propertySettingsTime: number = Date.now(); @@ -101,15 +107,49 @@ let contentCache: FileContentCache = new Map(); let randomSortCache: RandomFileSortCache = new Map(); - let viewOrder: TExplorerView[] = []; - let showListViewTags: boolean = false; let isSmallScreenSize: boolean = false; let enablePremiumFeatures: boolean = false; + //Views + let gridView: TGridView = { + isEnabled: true, + order: 0, + coverImageSources: [], + coverImageFit: "contain", + loadSocialMediaImage: false, + }; + + let listView: TListView = { + showTags: false, + isEnabled: true, + order: 1, + }; + + let feedView: TFeedView = { + isEnabled: true, + order: 2, + collapseStyle: "no-new-lines", + removeH1: true, + lineClampSmall: 2, + lineClampMedium: 3, + lineClampLarge: 5, + }; + + let tableView: TTableView = { + isEnabled: true, + order: 3, + }; + + let initialRender = true; + // ============================================ // Lifecycle hooks // ============================================ + onMount(() => { + initialRender = false; + }); + License.getInstance() .getHasValidKeyStore() .subscribe((hasValidKey) => { @@ -132,18 +172,20 @@ loadedFiles = value; }); - store.plugin.subscribe(async (p) => { + store.plugin.subscribe((p) => { plugin = p; const { app, settings } = plugin; - showListViewTags = settings.views.list.showTags; shouldCollapseFilters = settings.shouldCollapseFilters; pageSize = settings.pageSize; searchFilter = settings.filters.search; sortFilter = settings.filters.sort; currentView = settings.currentView; customFilter = settings.filters.custom; - viewOrder = settings.viewOrder; + gridView = settings.views.grid; + listView = settings.views.list; + tableView = settings.views.table; + feedView = settings.views.feed; if (settings.enableClockUpdates) { setTimeValuesUpdateInterval(); @@ -154,6 +196,7 @@ fileContentStore.load(app); randomFileSortStore.load(app); }); + onMount(() => { function handleFilterToggleSettingChange() { Logger.trace({ @@ -402,8 +445,11 @@ message: "called", }); - viewOrder = plugin.settings.viewOrder; currentView = plugin.settings.currentView; + gridView = plugin.settings.views.grid; + listView = plugin.settings.views.list; + tableView = plugin.settings.views.table; + feedView = plugin.settings.views.feed; } EventManager.getInstance().on( @@ -565,7 +611,6 @@ // Functions // ============================================ const debounceSearchFilterChange = _.debounce((e) => { - if (searchFilter == null) return; searchFilter.value = e.target.value; }, DEBOUNCE_INPUT_TIME); @@ -603,13 +648,17 @@ } async function saveSettings() { + if (initialRender) return; + plugin.settings.filters.search = searchFilter; plugin.settings.filters.sort = sortFilter; plugin.settings.currentView = currentView; plugin.settings.filters.custom = customFilter; - plugin.settings.viewOrder = viewOrder; plugin.settings.shouldCollapseFilters = shouldCollapseFilters; - plugin.settings.views.list.showTags = showListViewTags; + plugin.settings.views.list = listView; + plugin.settings.views.grid = gridView; + plugin.settings.views.table = tableView; + plugin.settings.views.feed = feedView; await plugin.saveSettings(); } @@ -661,30 +710,42 @@ nativeEvent.preventDefault(); } - function handleViewDragStart(e: CustomEvent, id: string) { + function handleViewDragStart(e: CustomEvent, type: TExplorerView) { const { nativeEvent } = e.detail; - nativeEvent.dataTransfer.setData("text", id); + nativeEvent.dataTransfer.setData("text", type); nativeEvent.dataTransfer.effectAllowed = "move"; } - function handleViewDrop(e: CustomEvent, id: string) { + function handleViewDrop(e: CustomEvent, type: TExplorerView) { const { nativeEvent } = e.detail; const dragId = nativeEvent.dataTransfer.getData("text"); nativeEvent.dataTransfer.dropEffect = "move"; - const draggedIndex = viewOrder.findIndex((view) => view === dragId); - const dragged = viewOrder.find((view) => view === dragId); + const views = { + [TExplorerView.GRID]: gridView, + [TExplorerView.LIST]: listView, + [TExplorerView.FEED]: feedView, + [TExplorerView.TABLE]: tableView, + }; + + const draggedView = Object.entries(views).find( + ([key]) => key === dragId, + ); - const droppedIndex = viewOrder.findIndex((view) => view === id); - const dropped = viewOrder.find((view) => view === id); + const droppedView = Object.entries(views).find(([key]) => key === type); - if (!dragged || !dropped || draggedIndex === -1 || droppedIndex === -1) - return; + // Ensure both dragged and dropped views are found + if (!draggedView || !droppedView) return; + + // Swap the order properties of the dragged and dropped views + const tempOrder = draggedView[1].order; + draggedView[1].order = droppedView[1].order; + droppedView[1].order = tempOrder; - let newViewOrder = [...viewOrder]; - newViewOrder[draggedIndex] = dropped; - newViewOrder[droppedIndex] = dragged; - viewOrder = newViewOrder; + gridView = views[TExplorerView.GRID]; + listView = views[TExplorerView.LIST]; + feedView = views[TExplorerView.FEED]; + tableView = views[TExplorerView.TABLE]; } function handleGroupDrop(e: CustomEvent) { @@ -874,7 +935,10 @@ sortFilter, currentView, customFilter, - viewOrder, + listView, + gridView, + tableView, + feedView, shouldCollapseFilters, saveSettings(); @@ -891,6 +955,22 @@ $: startIndex = (currentPage - 1) * pageSize; $: pageLength = Math.min(pageSize, renderData.length - startIndex); $: endIndex = startIndex + pageLength; + + let views: Record< + TExplorerView, + TGridView | TListView | TFeedView | TTableView + >; + $: views = { + [TExplorerView.GRID]: gridView, + [TExplorerView.LIST]: listView, + [TExplorerView.FEED]: feedView, + [TExplorerView.TABLE]: tableView, + }; + + $: orderedViews = Object.entries(views) + .filter((view) => view[1].order >= 0) // Filter out views with negative order values + .sort((a, b) => a[1].order - b[1].order) + .map((entry) => entry[0]) as TExplorerView[]; // Sort by order value
@@ -921,30 +1001,20 @@ {/if}
- - view === currentView, - )} - > - {#each viewOrder as view} - (currentView = view)} - on:dragstart={(e) => handleViewDragStart(e, view)} - on:dragover={handleViewDragOver} - on:drop={(e) => handleViewDrop(e, view)} - >{getDisplayNameForView(view)} - {/each} - - - + {#if currentView !== null} + + {#each orderedViews as view} + (currentView = view)} + on:dragstart={(e) => handleViewDragStart(e, view)} + on:dragover={handleViewDragOver} + on:drop={(e) => handleViewDrop(e, view)} + >{getDisplayNameForView(view)} + {/each} + + {/if}
{#if searchFilter.isEnabled} @@ -982,7 +1052,7 @@ { switch (view) { - case TExplorerView.DASHBOARD: - return "Dashboard"; case TExplorerView.GRID: return "Grid"; case TExplorerView.LIST: @@ -12,11 +10,7 @@ export const getDisplayNameForView = (view: TExplorerView) => { return "Feed"; case TExplorerView.TABLE: return "Table"; - case TExplorerView.RECOMMENDED: - return "Recommended"; - case TExplorerView.RELATED: - return "Related"; default: throw new Error(`Unhandled view type: ${TExplorerView}`); } -} +}; diff --git a/src/types/index.guard.ts b/src/types/index.guard.ts index 929a921e..3f3cd43d 100644 --- a/src/types/index.guard.ts +++ b/src/types/index.guard.ts @@ -573,14 +573,11 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore (typedObj["views"] !== null && typeof typedObj["views"] === "object" || typeof typedObj["views"] === "function") && - (typedObj["views"]["dashboard"] !== null && - typeof typedObj["views"]["dashboard"] === "object" || - typeof typedObj["views"]["dashboard"] === "function") && - typeof typedObj["views"]["dashboard"]["isEnabled"] === "boolean" && (typedObj["views"]["grid"] !== null && typeof typedObj["views"]["grid"] === "object" || typeof typedObj["views"]["grid"] === "function") && typeof typedObj["views"]["grid"]["isEnabled"] === "boolean" && + typeof typedObj["views"]["grid"]["order"] === "number" && Array.isArray(typedObj["views"]["grid"]["coverImageSources"]) && typedObj["views"]["grid"]["coverImageSources"].every((e: any) => (e !== null && @@ -599,29 +596,24 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore typeof typedObj["views"]["list"] === "object" || typeof typedObj["views"]["list"] === "function") && typeof typedObj["views"]["list"]["isEnabled"] === "boolean" && + typeof typedObj["views"]["list"]["order"] === "number" && typeof typedObj["views"]["list"]["showTags"] === "boolean" && - (typedObj["views"]["table"] !== null && - typeof typedObj["views"]["table"] === "object" || - typeof typedObj["views"]["table"] === "function") && - typeof typedObj["views"]["table"]["isEnabled"] === "boolean" && (typedObj["views"]["feed"] !== null && typeof typedObj["views"]["feed"] === "object" || typeof typedObj["views"]["feed"] === "function") && typeof typedObj["views"]["feed"]["isEnabled"] === "boolean" && + typeof typedObj["views"]["feed"]["order"] === "number" && (typedObj["views"]["feed"]["collapseStyle"] === "no-new-lines" || typedObj["views"]["feed"]["collapseStyle"] === "no-extra-new-lines") && typeof typedObj["views"]["feed"]["removeH1"] === "boolean" && typeof typedObj["views"]["feed"]["lineClampSmall"] === "number" && typeof typedObj["views"]["feed"]["lineClampMedium"] === "number" && typeof typedObj["views"]["feed"]["lineClampLarge"] === "number" && - (typedObj["views"]["recommended"] !== null && - typeof typedObj["views"]["recommended"] === "object" || - typeof typedObj["views"]["recommended"] === "function") && - typeof typedObj["views"]["recommended"]["isEnabled"] === "boolean" && - (typedObj["views"]["related"] !== null && - typeof typedObj["views"]["related"] === "object" || - typeof typedObj["views"]["related"] === "function") && - typeof typedObj["views"]["related"]["isEnabled"] === "boolean" && + (typedObj["views"]["table"] !== null && + typeof typedObj["views"]["table"] === "object" || + typeof typedObj["views"]["table"] === "function") && + typeof typedObj["views"]["table"]["isEnabled"] === "boolean" && + typeof typedObj["views"]["table"]["order"] === "number" && typeof typedObj["confirmBeforeDelete"] === "boolean" && (typedObj["titleWrapping"] === "normal" || typedObj["titleWrapping"] === "break-word") && @@ -629,25 +621,12 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore typeof typedObj["enableFileIcons"] === "boolean" && typeof typedObj["loadBodyTags"] === "boolean" && (typedObj["currentView"] === null || - typedObj["currentView"] === TExplorerView.DASHBOARD || typedObj["currentView"] === TExplorerView.GRID || typedObj["currentView"] === TExplorerView.LIST || typedObj["currentView"] === TExplorerView.FEED || - typedObj["currentView"] === TExplorerView.TABLE || - typedObj["currentView"] === TExplorerView.RECOMMENDED || - typedObj["currentView"] === TExplorerView.RELATED) && + typedObj["currentView"] === TExplorerView.TABLE) && typeof typedObj["pageSize"] === "number" && typeof typedObj["shouldCollapseFilters"] === "boolean" && - Array.isArray(typedObj["viewOrder"]) && - typedObj["viewOrder"].every((e: any) => - (e === TExplorerView.DASHBOARD || - e === TExplorerView.GRID || - e === TExplorerView.LIST || - e === TExplorerView.FEED || - e === TExplorerView.TABLE || - e === TExplorerView.RECOMMENDED || - e === TExplorerView.RELATED) - ) && typeof typedObj["configDir"] === "string" && (typedObj["pluginVersion"] === null || typeof typedObj["pluginVersion"] === "string") && diff --git a/src/types/index.ts b/src/types/index.ts index 24e61dc5..6c5d598a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -16,13 +16,10 @@ export interface VaultExplorerPluginSettings { custom: TCustomFilter; }; views: { - dashboard: TDashboardView; grid: TGridView; list: TListView; - table: TTableView; feed: TFeedView; - recommended: TRecommendedView; - related: TRelatedView; + table: TTableView; }; confirmBeforeDelete: boolean; titleWrapping: WordBreak; @@ -32,16 +29,14 @@ export interface VaultExplorerPluginSettings { currentView: TExplorerView | null; pageSize: number; shouldCollapseFilters: boolean; - viewOrder: TExplorerView[]; configDir: string; pluginVersion: string | null; logLevel: string; } -export type FileInteractionStyle = "title" | "content"; - interface BaseView { isEnabled: boolean; + order: number; } export interface TTableView extends BaseView {} @@ -69,8 +64,6 @@ export type CoverImageSourceType = | "frontmatter" | "body"; -export interface TDashboardView extends BaseView {} - export type CollapseStyle = "no-new-lines" | "no-extra-new-lines"; export interface TFeedView extends BaseView { @@ -81,10 +74,6 @@ export interface TFeedView extends BaseView { lineClampLarge: number; } -export interface TRecommendedView extends BaseView {} - -export interface TRelatedView extends BaseView {} - interface BaseFilter { isEnabled: boolean; } @@ -114,13 +103,10 @@ export type SortFilterOption = export type WordBreak = "normal" | "break-word"; export enum TExplorerView { - DASHBOARD = "dashboard", GRID = "grid", LIST = "list", FEED = "feed", TABLE = "table", - RECOMMENDED = "recommended", - RELATED = "related", } export type FilterOperator = "and" | "or"; diff --git a/src/types/types-1.45.0.ts b/src/types/types-1.45.0.ts new file mode 100644 index 00000000..9c0fe33b --- /dev/null +++ b/src/types/types-1.45.0.ts @@ -0,0 +1,311 @@ +export interface VaultExplorerPluginSettings_1_45_0 { + properties: { + url: string; + image: string; + coverImageFit: string; + createdDate: string; + modifiedDate: string; + custom1: string; + custom2: string; + custom3: string; + }; + filters: { + search: TSearchFilter; + sort: TSortFilter; + custom: TCustomFilter; + }; + views: { + dashboard: TDashboardView; + grid: TGridView; + list: TListView; + table: TTableView; + feed: TFeedView; + recommended: TRecommendedView; + related: TRelatedView; + }; + confirmBeforeDelete: boolean; + titleWrapping: WordBreak; + enableClockUpdates: boolean; + enableFileIcons: boolean; + loadBodyTags: boolean; + currentView: TExplorerView | null; + pageSize: number; + shouldCollapseFilters: boolean; + viewOrder: TExplorerView[]; + configDir: string; + pluginVersion: string | null; + logLevel: string; +} + +interface BaseView { + isEnabled: boolean; +} + +interface TTableView extends BaseView {} + +interface TListView extends BaseView { + showTags: boolean; +} + +interface TGridView extends BaseView { + coverImageSources: CoverImageSource[]; + coverImageFit: CoverImageFit; + loadSocialMediaImage: boolean; +} + +interface CoverImageSource { + type: CoverImageSourceType; + isEnabled: boolean; +} + +type CoverImageFit = "cover" | "contain"; + +type CoverImageSourceType = + | "image-property" + | "url-property" + | "frontmatter" + | "body"; + +interface TDashboardView extends BaseView {} + +type CollapseStyle = "no-new-lines" | "no-extra-new-lines"; + +interface TFeedView extends BaseView { + collapseStyle: CollapseStyle; + removeH1: boolean; + lineClampSmall: number; + lineClampMedium: number; + lineClampLarge: number; +} + +interface TRecommendedView extends BaseView {} + +interface TRelatedView extends BaseView {} + +interface BaseFilter { + isEnabled: boolean; +} + +interface TSearchFilter extends BaseFilter { + value: string; +} + +interface TSortFilter extends BaseFilter { + value: SortFilterOption; +} + +interface TCustomFilter extends BaseFilter { + selectedGroupId: string; + groups: TFilterGroup[]; +} + +type SortFilterOption = + | "file-name-asc" + | "file-name-desc" + | "modified-asc" + | "modified-desc" + | "created-asc" + | "created-desc" + | "random"; + +type WordBreak = "normal" | "break-word"; + +enum TExplorerView { + DASHBOARD = "dashboard", + GRID = "grid", + LIST = "list", + FEED = "feed", + TABLE = "table", + RECOMMENDED = "recommended", + RELATED = "related", +} + +type FilterOperator = "and" | "or"; + +enum TextFilterCondition { + IS = "is", + IS_NOT = "is-not", + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + STARTS_WITH = "starts-with", + ENDS_WITH = "ends-with", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +enum ListFilterCondition { + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +enum NumberFilterCondition { + IS_EQUAL = "is-equal", + IS_NOT_EQUAL = "is-not-equal", + IS_GREATER = "is-greater", + IS_LESS = "is-less", + IS_GREATER_OR_EQUAL = "is-greater-or-equal", + IS_LESS_OR_EQUAL = "is-less-or-equal", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +enum CheckboxFilterCondition { + IS = "is", + IS_NOT = "is-not", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +enum DateFilterCondition { + IS = "is", + IS_BEFORE = "is-before", + IS_AFTER = "is-after", + IS_ON_OR_BEFORE = "is-on-or-before", + IS_ON_OR_AFTER = "is-on-or-after", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +enum ContentFilterCondition { + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + IS_EMPTY = "is-empty", + IS_NOT_EMPTY = "is-not-empty", +} + +enum FolderFilterCondition { + IS = "is", + IS_NOT = "is-not", +} + +enum FileNameFilterCondition { + IS = "is", + IS_NOT = "is-not", + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + STARTS_WITH = "starts-with", + ENDS_WITH = "ends-with", +} + +type FilterCondition = + | TextFilterCondition + | NumberFilterCondition + | DateFilterCondition + | CheckboxFilterCondition + | ListFilterCondition + | ContentFilterCondition + | FolderFilterCondition + | FileNameFilterCondition; + +//This matches the Obsidian property types +enum PropertyType { + TEXT = "text", + NUMBER = "number", + LIST = "list", + CHECKBOX = "checkbox", + DATE = "date", + DATETIME = "datetime", +} + +enum FilterRuleType { + PROPERTY = "property", + FOLDER = "folder", + FILE_NAME = "file-name", + CONTENT = "content", +} + +enum DatePropertyFilterValue { + TODAY = "today", + TOMORROW = "tomorrow", + YESTERDAY = "yesterday", + ONE_WEEK_FROM_NOW = "one-week-from-now", + ONE_WEEK_AGO = "one-week-ago", + ONE_MONTH_FROM_NOW = "one-month-from-now", + ONE_MONTH_AGO = "one-month-ago", + CUSTOM = "custom", +} + +interface BaseFilterRule { + id: string; + operator: FilterOperator; + type: FilterRuleType; + condition: FilterCondition; + isEnabled: boolean; + value: string; + matchWhenPropertyDNE: boolean; +} + +interface TextPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.TEXT; + propertyName: string; + condition: TextFilterCondition; +} + +interface NumberPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.NUMBER; + propertyName: string; + condition: NumberFilterCondition; +} + +interface ListPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.LIST; + propertyName: string; + condition: ListFilterCondition; +} + +interface CheckboxPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.CHECKBOX; + propertyName: string; + condition: CheckboxFilterCondition; +} + +interface DatePropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.DATE | PropertyType.DATETIME; + propertyName: string; + condition: DateFilterCondition; + valueData: string; +} + +interface FolderFilterRule extends BaseFilterRule { + type: FilterRuleType.FOLDER; + condition: FolderFilterCondition; + includeSubfolders: boolean; +} + +interface FileNameFilterRule extends BaseFilterRule { + type: FilterRuleType.FILE_NAME; + condition: FileNameFilterCondition; +} + +interface ContentFilterRule extends BaseFilterRule { + type: FilterRuleType.CONTENT; + condition: ContentFilterCondition; +} + +type TFilterRule = + | PropertyFilterRule + | FolderFilterRule + | FileNameFilterRule + | ContentFilterRule; + +type PropertyFilterRule = + | TextPropertyFilterRule + | NumberPropertyFilterRule + | ListPropertyFilterRule + | CheckboxPropertyFilterRule + | DatePropertyFilterRule; + +interface TFilterGroup { + id: string; + name: string; + rules: TFilterRule[]; + isEnabled: boolean; + isSticky: boolean; +} diff --git a/test-vault/.obsidian/plugins/vault-explorer/data.json b/test-vault/.obsidian/plugins/vault-explorer/data.json index 3379dcfe..f406c9bc 100644 --- a/test-vault/.obsidian/plugins/vault-explorer/data.json +++ b/test-vault/.obsidian/plugins/vault-explorer/data.json @@ -1,95 +1,90 @@ { - "properties": { - "favorite": "favorite", - "url": "url", - "custom1": "category", - "custom2": "color", - "custom3": "size", - "creationDate": "creation", - "modifiedDate": "modification", - "createdDate": "creation", - "image": "image", - "coverImageFit": "image-fit" - }, - "filters": { - "search": { - "isEnabled": true, - "value": "" - }, - "sort": { - "isEnabled": true, - "value": "modified-desc" - }, - "custom": { - "isEnabled": true, - "selectedGroupId": "", - "groups": [] - }, - "properties": { - "groups": [] - } - }, - "views": { - "dashboard": { - "isEnabled": false - }, - "grid": { - "isEnabled": true, - "loadSocialMediaImage": true, - "coverImageSources": [ - { - "type": "image-property", - "isEnabled": true - }, - { - "type": "url-property", - "isEnabled": true - }, - { - "type": "frontmatter", - "isEnabled": true - }, - { - "type": "body", - "isEnabled": true - } - ], - "coverImageFit": "cover" - }, - "list": { - "isEnabled": true, - "showTags": true - }, - "table": { - "isEnabled": true - }, - "feed": { - "isEnabled": true, - "renderNewLineCharacters": false, - "collapseContent": true, - "removeLevel1Headers": true, - "collapseStyle": "no-new-lines", - "lineClampLarge": 5, - "lineClampMedium": 3, - "lineClampSmall": 2, - "removeH1": true - }, - "recommended": { - "isEnabled": false - }, - "related": { - "isEnabled": false - } - }, - "currentView": "grid", - "titleWrapping": "normal", - "enableClockUpdates": true, - "enableFileIcons": true, - "loadBodyTags": true, - "shouldCollapseFilters": false, - "pageSize": 25, - "viewOrder": ["grid", "list", "table", "feed"], - "configDir": ".vaultexplorer", - "pluginVersion": "1.44.2", - "logLevel": "trace" -} + "properties": { + "favorite": "favorite", + "url": "url", + "custom1": "category", + "custom2": "color", + "custom3": "size", + "creationDate": "creation", + "modifiedDate": "modification", + "createdDate": "creation", + "image": "image", + "coverImageFit": "image-fit" + }, + "filters": { + "search": { + "isEnabled": true, + "value": "" + }, + "sort": { + "isEnabled": true, + "value": "modified-desc" + }, + "custom": { + "isEnabled": true, + "selectedGroupId": "", + "groups": [] + }, + "properties": { + "groups": [] + } + }, + "views": { + "grid": { + "isEnabled": true, + "loadSocialMediaImage": true, + "coverImageSources": [ + { + "type": "image-property", + "isEnabled": true + }, + { + "type": "url-property", + "isEnabled": true + }, + { + "type": "frontmatter", + "isEnabled": true + }, + { + "type": "body", + "isEnabled": true + } + ], + "coverImageFit": "cover", + "order": 0 + }, + "list": { + "isEnabled": true, + "showTags": true, + "order": 1 + }, + "table": { + "isEnabled": true, + "order": 3 + }, + "feed": { + "isEnabled": true, + "renderNewLineCharacters": false, + "collapseContent": true, + "removeLevel1Headers": true, + "collapseStyle": "no-new-lines", + "lineClampLarge": 5, + "lineClampMedium": 3, + "lineClampSmall": 2, + "removeH1": true, + "order": 2 + } + }, + "confirmBeforeDelete": true, + "currentView": "list", + "titleWrapping": "normal", + "enableClockUpdates": true, + "enableFileIcons": true, + "loadBodyTags": true, + "shouldCollapseFilters": false, + "pageSize": 25, + "configDir": ".vaultexplorer", + "pluginVersion": "1.46.0", + "logLevel": "warn" +} \ No newline at end of file diff --git a/versions.json b/versions.json index 0e387f16..e637b8ed 100644 --- a/versions.json +++ b/versions.json @@ -148,5 +148,6 @@ "1.44.4": "1.4.13", "1.44.5": "1.4.13", "1.44.6": "1.4.13", - "1.45.0": "1.4.13" + "1.45.0": "1.4.13", + "1.46.0": "1.4.13" } From e2738516fa9c68161252a82cb085785706f9956c Mon Sep 17 00:00:00 2001 From: DecafDev <40307803+decaf-dev@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:46:15 -0600 Subject: [PATCH 2/4] fix: resolve show tags not always working --- src/svelte/app/components/list-item.svelte | 3 ++- src/svelte/app/components/list-view.svelte | 2 -- src/svelte/app/index.svelte | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/svelte/app/components/list-item.svelte b/src/svelte/app/components/list-item.svelte index fe1a8838..43654b7d 100644 --- a/src/svelte/app/components/list-item.svelte +++ b/src/svelte/app/components/list-item.svelte @@ -18,7 +18,8 @@ export let extension: string; export let path: string; export let tags: string[] | null; - export let showTags: boolean; + + let showTags: boolean; export let isSmallScreenSize: boolean; export let enablePremiumFeatures: boolean; diff --git a/src/svelte/app/components/list-view.svelte b/src/svelte/app/components/list-view.svelte index eed889e7..65fd3966 100644 --- a/src/svelte/app/components/list-view.svelte +++ b/src/svelte/app/components/list-view.svelte @@ -6,7 +6,6 @@ export let data: FileRenderData[]; export let startIndex: number; export let pageLength: number; - export let showTags: boolean; export let isSmallScreenSize: boolean; export let enablePremiumFeatures: boolean; @@ -28,7 +27,6 @@ {#each filteredItems as fileRenderData (fileRenderData.id)} Date: Fri, 13 Sep 2024 18:48:05 -0600 Subject: [PATCH 3/4] fix: show full width when showTags setting is disabled --- src/svelte/app/components/list-item.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/svelte/app/components/list-item.svelte b/src/svelte/app/components/list-item.svelte index 43654b7d..83ecbfa5 100644 --- a/src/svelte/app/components/list-item.svelte +++ b/src/svelte/app/components/list-item.svelte @@ -99,8 +99,8 @@ }); } - $: tagsClassName = `vault-explorer-list-item__tags ${isSmallScreenSize ? "vault-explorer-list-item__tags--screen-size-sm" : ""}`; - $: titleClassName = `vault-explorer-list-item__title ${isSmallScreenSize ? "vault-explorer-list-item__title--screen-size-sm" : ""}`; + $: tagsClassName = `vault-explorer-list-item__tags ${isSmallScreenSize ? "vault-explorer-list-item__tags--full" : ""}`; + $: titleClassName = `vault-explorer-list-item__title ${isSmallScreenSize || !showTags ? "vault-explorer-list-item__title--full" : ""}`;
From 7910830b9f0c7dac41cb546170f10b4afd5d9ab7 Mon Sep 17 00:00:00 2001 From: DecafDev <40307803+decaf-dev@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:54:20 -0600 Subject: [PATCH 4/4] feat: simplify table columns --- src/svelte/app/components/table-view.svelte | 31 ++++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/svelte/app/components/table-view.svelte b/src/svelte/app/components/table-view.svelte index 8cb3faa6..d262445c 100644 --- a/src/svelte/app/components/table-view.svelte +++ b/src/svelte/app/components/table-view.svelte @@ -1,7 +1,6 @@