Merge pull request #365 from decaf-dev/dev

1.46.0
This commit is contained in:
DecafDev 2024-09-13 19:58:32 -06:00 committed by GitHub
commit 68484ea77a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 682 additions and 313 deletions

View file

@ -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",

View file

@ -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": {

View file

@ -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,

View file

@ -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 = (

View file

@ -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<string, unknown>) {
@ -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,

View file

@ -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<string, unknown>) {
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<string, unknown>;
}
}

View file

@ -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) {
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 (value) {
this.plugin.settings.viewOrder.push(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;
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];
}
}

View file

@ -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;
@ -98,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" : ""}`;
</script>
<div
@ -186,7 +187,7 @@
box-shadow: 0 0 0 3px var(--background-modifier-border-focus);
}
.vault-explorer-list-item__title--screen-size-sm {
.vault-explorer-list-item__title--full {
width: 100%;
}
@ -201,7 +202,7 @@
width: 50%;
}
.vault-explorer-list-item__tags--screen-size-sm {
.vault-explorer-list-item__tags--full {
width: 100%;
}
</style>

View file

@ -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)}
<ListItem
{enablePremiumFeatures}
{showTags}
displayName={fileRenderData.displayName}
extension={fileRenderData.extension}
baseName={fileRenderData.baseName}

View file

@ -1,7 +1,6 @@
<script lang="ts">
import { onMount } from "svelte";
import { openContextMenu } from "../services/context-menu";
import { formatAsBearTimeString } from "../services/time-string";
import { FileRenderData } from "../types";
import store from "src/svelte/shared/services/store";
import VaultExplorerPlugin from "src/main";
@ -37,22 +36,20 @@
label: "Name",
classNames: "vault-explorer-table-view__title-text",
},
{ key: "extension", label: "Extension" },
{ key: "basePath", label: "Folder" },
{
key: "tags",
label: "Tags",
},
{
key: "createdMillis",
label: "Created",
format: (value: unknown) => formatAsBearTimeString(value as number),
},
{
key: "modifiedMillis",
label: "Modified",
format: (value: unknown) => formatAsBearTimeString(value as number),
},
// {
// key: "createdMillis",
// label: "Created",
// format: (value: unknown) => formatAsBearTimeString(value as number),
// },
// {
// key: "modifiedMillis",
// label: "Modified",
// format: (value: unknown) => formatAsBearTimeString(value as number),
// },
];
store.plugin.subscribe((p) => {
@ -172,7 +169,7 @@
{#if column.key == "tags"}
<Wrap spacingX="sm" spacingY="sm">
{#each asStringArray(value) as tag}
<Tag name={tag} variant="unstyled" />
<Tag name={tag} />
{/each}
</Wrap>
{:else if column.key == "baseName"}
@ -225,9 +222,9 @@
.vault-explorer-table-view th:nth-child(2),
.vault-explorer-table-view td:nth-child(2) {
min-width: 125px;
width: 125px;
max-width: 125px;
min-width: 300px;
width: 300px;
max-width: 300px;
overflow: hidden;
}

View file

@ -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 droppedIndex = viewOrder.findIndex((view) => view === id);
const dropped = viewOrder.find((view) => view === id);
const draggedView = Object.entries(views).find(
([key]) => key === dragId,
);
if (!dragged || !dropped || draggedIndex === -1 || droppedIndex === -1)
return;
const droppedView = Object.entries(views).find(([key]) => key === type);
let newViewOrder = [...viewOrder];
newViewOrder[draggedIndex] = dropped;
newViewOrder[droppedIndex] = dragged;
viewOrder = newViewOrder;
// 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;
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
</script>
<div class="vault-explorer" bind:this={ref}>
@ -921,30 +1001,20 @@
{/if}
<Wrap align="center" spacingY="sm" justify="space-between">
<div class="vault-explorer-view-select">
<!-- <Stack spacing="sm"> -->
<TabList
initialSelectedIndex={viewOrder.findIndex(
(view) => view === currentView,
)}
>
{#each viewOrder as view}
<Tab
draggable={true}
on:click={() => (currentView = view)}
on:dragstart={(e) => handleViewDragStart(e, view)}
on:dragover={handleViewDragOver}
on:drop={(e) => handleViewDrop(e, view)}
>{getDisplayNameForView(view)}</Tab
>
{/each}
</TabList>
<!-- <IconButton
iconId="ellipsis-vertical"
ariaLabel="View options"
noPadding
on:click={() => {}}
/> -->
<!-- </Stack> -->
{#if currentView !== null}
<TabList initialSelectedIndex={views[currentView].order}>
{#each orderedViews as view}
<Tab
draggable={true}
on:click={() => (currentView = view)}
on:dragstart={(e) => handleViewDragStart(e, view)}
on:dragover={handleViewDragOver}
on:drop={(e) => handleViewDrop(e, view)}
>{getDisplayNameForView(view)}</Tab
>
{/each}
</TabList>
{/if}
</div>
<Flex>
{#if searchFilter.isEnabled}
@ -982,7 +1052,6 @@
<ListView
data={renderData}
{isSmallScreenSize}
showTags={showListViewTags}
{startIndex}
{pageLength}
{enablePremiumFeatures}

View file

@ -2,8 +2,6 @@ import { TExplorerView } from "src/types";
export const getDisplayNameForView = (view: TExplorerView) => {
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}`);
}
}
};

View file

@ -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") &&

View file

@ -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";

311
src/types/types-1.45.0.ts Normal file
View file

@ -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;
}

View file

@ -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"
}

View file

@ -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"
}