Compare commits

..

37 commits

Author SHA1 Message Date
DecafDev
c8a4c5fd29
Merge pull request #387 from decaf-dev/dev
1.47.4
2025-05-02 21:02:32 -06:00
DecafDev
2360454f4a chore: bump version 2025-05-02 21:02:11 -06:00
DecafDev
2df4bca0e4 chore: use node 22 2025-05-02 21:01:53 -06:00
DecafDev
239dd7903f
Merge pull request #386 from decaf-dev/dev
v1.47.3
2025-05-02 20:48:17 -06:00
DecafDev
911695e190 chore: bump version 2025-05-02 20:47:30 -06:00
DecafDev
afca3eeba9 fix: use correct types for moment.js 2025-05-02 20:47:14 -06:00
DecafDev
5ebfc3fcbb
Merge pull request #385 from decaf-dev/dev
1.47.2
2025-05-02 20:36:39 -06:00
DecafDev
993763879a chore: bump version 2025-05-02 20:34:34 -06:00
DecafDev
6254e435a3 fix: resolve crash on date input 2025-05-02 20:34:07 -06:00
DecafDev
9ac4be6382
Merge pull request #384 from decaf-dev/dev
chore: bump version
2025-05-02 20:27:08 -06:00
DecafDev
dd90bd4ff1 chore: bump version 2025-05-02 20:26:44 -06:00
DecafDev
38f8c8225f
Merge pull request #383 from decaf-dev/dev
Fix build errors
2025-05-02 20:24:01 -06:00
DecafDev
f73d6b45d4 fix: resolve moment errors 2025-05-02 20:20:37 -06:00
DecafDev
2198f4a256 chore: remove bad characters 2025-05-02 20:07:08 -06:00
DecafDev
09f6f1666a chore: use new mount syntax for Svelte 5 2025-05-02 20:06:30 -06:00
DecafDev
9bbff4d12b
Merge pull request #382 from decaf-dev/dev
chore: resolve build error
2025-05-02 20:01:01 -06:00
DecafDev
369dfad524 chore: resolve build error 2025-05-02 19:59:51 -06:00
DecafDev
34fe421424
v1.47.0 (#381)
* feat: upgrade typescript and svelte

* refactor: remove unnecessary svelte tsconfig change in pipeline

* refactor: change to type-only import

* Refactor/svelte 5 (#379)

* feat: upgrade typescript and svelte

* refactor: remove unnecessary svelte tsconfig change in pipeline

* refactor: change to type-only import

* fix: resolve compiler errors

* feat: remove premium features (#380)

* chore: bump version

* chore: disable trailing commas

* chore: format with prettier

* chore: update to latest packages

* ci: use node 18
2025-05-02 19:57:16 -06:00
DecafDev
8b118bd675 ci: use node 18 2025-05-02 19:54:57 -06:00
DecafDev
f5920d2802 chore: update to latest packages 2025-05-02 19:54:45 -06:00
DecafDev
4f1bb2c8c1 chore: format with prettier 2025-05-02 19:53:09 -06:00
DecafDev
6e68f4e905 chore: disable trailing commas 2025-05-02 19:52:49 -06:00
DecafDev
2bd9b85c1c chore: bump version 2025-05-02 19:42:49 -06:00
DecafDev
c79f52e900
feat: remove premium features (#380) 2025-03-30 08:42:12 -06:00
DecafDev
4cb716297c Merge branch 'dev' of github.com:decaf-dev/obsidian-vault-explorer into dev 2025-03-30 08:30:44 -06:00
DecafDev
dcb24cba4d
Refactor/svelte 5 (#379)
* feat: upgrade typescript and svelte

* refactor: remove unnecessary svelte tsconfig change in pipeline

* refactor: change to type-only import

* fix: resolve compiler errors
2025-03-30 08:30:34 -06:00
DecafDev
bba710b495 refactor: change to type-only import 2025-01-11 18:45:57 -07:00
DecafDev
2099586ffa refactor: remove unnecessary svelte tsconfig change in pipeline 2025-01-11 18:44:42 -07:00
DecafDev
e592e25fec feat: upgrade typescript and svelte 2025-01-11 18:44:31 -07:00
DecafDev
68484ea77a
Merge pull request #365 from decaf-dev/dev
1.46.0
2024-09-13 19:58:32 -06:00
DecafDev
20b61f54bd
Merge pull request #364 from decaf-dev/simplify-table
feat: simplify table columns
2024-09-13 19:55:21 -06:00
DecafDev
7910830b9f feat: simplify table columns 2024-09-13 19:54:20 -06:00
DecafDev
fe867df46b
Merge pull request #363 from decaf-dev/fix-show-tags
Fix show tags
2024-09-13 18:50:25 -06:00
DecafDev
c6b6d98655 fix: show full width when showTags setting is disabled 2024-09-13 18:48:05 -06:00
DecafDev
e2738516fa fix: resolve show tags not always working 2024-09-13 18:46:15 -06:00
DecafDev
8627704dd8
Merge pull request #362 from decaf-dev/simplify-code
feat: simplify view order
2024-09-13 18:43:33 -06:00
DecafDev
32b2e444e6 feat: simplify view order 2024-09-13 18:42:31 -06:00
171 changed files with 3777 additions and 2758 deletions

View file

@ -14,7 +14,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: "16.x"
node-version: "22"
- uses: oven-sh/setup-bun@v1
with:
@ -23,12 +23,6 @@ jobs:
- name: Install dependencies
run: bun install
- name: Fix tsconfig.json
run: |
sed -i '/"esModuleInterop"/d' node_modules/@tsconfig/svelte/tsconfig.json
sed -i '/"verbatimModuleSyntax"/d' node_modules/@tsconfig/svelte/tsconfig.json
sed -i '/"moduleResolution"/c\ "moduleResolution": "node",' node_modules/@tsconfig/svelte/tsconfig.json
- name: Build
id: build
run: bun run build

8
.prettierignore Normal file
View file

@ -0,0 +1,8 @@
# Ignore markdown files
*.md
**/*.md
# Other common files to ignore
node_modules/
dist/
.git/

View file

@ -1,9 +1,8 @@
{
"tabWidth": 4,
"useTabs": true,
"endOfLine": "lf",
"charset": "utf-8",
"insertFinalNewline": false,
"semi": true,
"quotes": "double"
"tabWidth": 4,
"useTabs": true,
"endOfLine": "lf",
"semi": true,
"singleQuote": false,
"trailingComma": "none"
}

View file

@ -21,7 +21,6 @@ Vault Explorer is a work in progress. Please check the GitHub repository and doc
- [Screenshots](#screenshots)
- [Installation](#installation)
- [Usage](#usage)
- [Premium](#premium)
- [Features](#features)
- [Network use](#network-use)
- [Contributing](#contributing)
@ -79,12 +78,6 @@ Vault Explorer is a work in progress. Please check the GitHub repository and doc
Click the compass button on the left-hand sidebar to open the vault explorer view.
## Premium
Premium features are available to users who purchase a [Vault Explorer license](https://vaultexplorer.com/docs/premium/).
Please do not share your license key with anyone. Shared license keys will be deactivated.
## Features
| Name | Categories | Documented |

View file

@ -3,5 +3,5 @@ export default {
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
debug: jest.fn(),
debug: jest.fn()
};

View file

@ -13,46 +13,60 @@ const DATE_TIME_SHORT_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/;
*/
const DATE_TIME_FULL_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/;
export const moment = jest.fn((date: string, _formats: string[], _strict?: boolean) => {
const parsedDate = new Date(date);
const mockMoment: unknown = {
isValid: jest.fn(() => DATE_REGEX.test(date) || DATE_TIME_SHORT_REGEX.test(date) || DATE_TIME_FULL_REGEX.test(date)),
startOf: jest.fn((unit) => {
if (unit === "day") {
parsedDate.setUTCHours(0, 0, 0, 0);
}
return mockMoment;
}),
set: jest.fn(({ hour, minute, second }) => {
parsedDate.setUTCHours(hour, minute, second);
return mockMoment;
}),
valueOf: jest.fn(() => parsedDate.getTime()),
isSame: jest.fn((other, unit) => {
if (unit === 'day') {
const otherDate = new Date(other);
return (
parsedDate.getUTCFullYear() === otherDate.getUTCFullYear() &&
parsedDate.getUTCMonth() === otherDate.getUTCMonth() &&
parsedDate.getUTCDate() === otherDate.getUTCDate()
);
}
return parsedDate.getTime() === new Date(other).getTime();
}),
isBefore: jest.fn((other, unit) => {
if (unit === 'day') {
const otherDate = new Date(other);
return parsedDate < otherDate && parsedDate.getUTCDate() !== otherDate.getUTCDate();
}
return parsedDate.getTime() < new Date(other).getTime();
}),
isAfter: jest.fn((other, unit) => {
if (unit === 'day') {
const otherDate = new Date(other);
return parsedDate > otherDate && parsedDate.getUTCDate() !== otherDate.getUTCDate();
}
return parsedDate.getTime() > new Date(other).getTime();
}),
};
return mockMoment;
});
export const moment = jest.fn(
(date: string, _formats: string[], _strict?: boolean) => {
const parsedDate = new Date(date);
const mockMoment: unknown = {
isValid: jest.fn(
() =>
DATE_REGEX.test(date) ||
DATE_TIME_SHORT_REGEX.test(date) ||
DATE_TIME_FULL_REGEX.test(date)
),
startOf: jest.fn((unit) => {
if (unit === "day") {
parsedDate.setUTCHours(0, 0, 0, 0);
}
return mockMoment;
}),
set: jest.fn(({ hour, minute, second }) => {
parsedDate.setUTCHours(hour, minute, second);
return mockMoment;
}),
valueOf: jest.fn(() => parsedDate.getTime()),
isSame: jest.fn((other, unit) => {
if (unit === "day") {
const otherDate = new Date(other);
return (
parsedDate.getUTCFullYear() ===
otherDate.getUTCFullYear() &&
parsedDate.getUTCMonth() === otherDate.getUTCMonth() &&
parsedDate.getUTCDate() === otherDate.getUTCDate()
);
}
return parsedDate.getTime() === new Date(other).getTime();
}),
isBefore: jest.fn((other, unit) => {
if (unit === "day") {
const otherDate = new Date(other);
return (
parsedDate < otherDate &&
parsedDate.getUTCDate() !== otherDate.getUTCDate()
);
}
return parsedDate.getTime() < new Date(other).getTime();
}),
isAfter: jest.fn((other, unit) => {
if (unit === "day") {
const otherDate = new Date(other);
return (
parsedDate > otherDate &&
parsedDate.getUTCDate() !== otherDate.getUTCDate()
);
}
return parsedDate.getTime() > new Date(other).getTime();
})
};
return mockMoment;
}
);

BIN
bun.lockb

Binary file not shown.

View file

@ -1,10 +1,10 @@
import esbuild from "esbuild";
import process from "process";
import builtins from "builtin-modules";
import esbuild from "esbuild";
import esbuildSvelte from "esbuild-svelte";
import fs from "fs";
import path from "path";
import esbuildSvelte from "esbuild-svelte";
import sveltePreprocess from "svelte-preprocess";
import process from "process";
import { sveltePreprocess } from "svelte-preprocess";
const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
@ -29,12 +29,12 @@ const rebuildPlugin = {
);
} catch (err) {}
});
},
}
};
const context = await esbuild.context({
banner: {
js: banner,
js: banner
},
entryPoints: ["src/main.ts"],
bundle: true,
@ -52,7 +52,7 @@ const context = await esbuild.context({
"@lezer/common",
"@lezer/highlight",
"@lezer/lr",
...builtins,
...builtins
],
format: "cjs",
target: "es2018",
@ -64,9 +64,9 @@ const context = await esbuild.context({
rebuildPlugin,
esbuildSvelte({
compilerOptions: { css: "external" },
preprocess: sveltePreprocess(),
}),
],
preprocess: sveltePreprocess()
})
]
});
if (prod) {

View file

@ -3,6 +3,6 @@ module.exports = {
preset: "ts-jest",
testEnvironment: "node",
moduleNameMapper: {
"^src/(.*)$": "<rootDir>/src/$1",
},
"^src/(.*)$": "<rootDir>/src/$1"
}
};

View file

@ -1,7 +1,7 @@
{
"id": "vault-explorer",
"name": "Vault Explorer",
"version": "1.45.0",
"version": "1.47.4",
"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.47.4",
"description": "Explore your vault in visual format",
"main": "main.js",
"scripts": {
@ -10,37 +10,39 @@
"compile": "tsc -noEmit -skipLibCheck",
"check": "svelte-check --tsconfig ./tsconfig.json",
"test": "jest --config jest.config.js",
"lint": "eslint --ext .ts,.js,.svelte ."
"lint": "eslint --ext .ts,.js,.svelte .",
"format": "prettier --write --ignore-path .prettierignore ."
},
"keywords": [],
"author": "DecafDev",
"license": "MIT",
"devDependencies": {
"@tsconfig/svelte": "^5.0.4",
"@types/bun": "latest",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.17.0",
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"esbuild-svelte": "^0.8.0",
"@types/bun": "^1.2.11",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.16",
"@types/node": "^22.15.3",
"@typescript-eslint/eslint-plugin": "8.31.1",
"@typescript-eslint/parser": "8.31.1",
"builtin-modules": "^5.0.0",
"esbuild": "^0.25.3",
"esbuild-svelte": "^0.9.2",
"jest": "^29.7.0",
"obsidian": "latest",
"svelte-check": "^3.8.4",
"svelte-preprocess": "^5.1.4",
"ts-auto-guard": "^5.0.0",
"ts-jest": "^29.1.4",
"tslib": "2.4.0",
"typescript": "4.7.4"
"obsidian": "^1.8.7",
"prettier": "^3.5.3",
"svelte-check": "^4.1.7",
"svelte-preprocess": "^6.0.3",
"ts-auto-guard": "^5.0.1",
"ts-jest": "^29.3.2",
"tslib": "2.8.1",
"typescript": "^5.8.3"
},
"dependencies": {
"crypto": "^1.0.1",
"idb": "^8.0.0",
"idb": "^8.0.2",
"js-logger": "^1.6.1",
"lodash": "^4.17.21",
"nanoid": "^5.0.7",
"svelte": "^4.2.15"
"nanoid": "^5.1.5",
"svelte": "^5.28.2"
}
}

View file

@ -1,5 +1,5 @@
import { LOG_LEVEL_WARN } from "./logger/constants";
import { VaultExplorerPluginSettings, TExplorerView } from "./types";
import { type VaultExplorerPluginSettings, TExplorerView } from "./types";
export const VAULT_EXPLORER_VIEW = "vault-explorer";
@ -14,71 +14,66 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
modifiedDate: "",
custom1: "",
custom2: "",
custom3: "",
custom3: ""
},
filters: {
search: {
isEnabled: true,
value: "",
value: ""
},
sort: {
isEnabled: true,
value: "file-name-asc",
value: "file-name-asc"
},
custom: {
isEnabled: true,
selectedGroupId: "",
groups: [],
},
groups: []
}
},
views: {
dashboard: {
isEnabled: false,
},
grid: {
isEnabled: true,
order: 0,
coverImageFit: "cover",
coverImageSources: [
{
type: "image-property",
isEnabled: true,
isEnabled: true
},
{
type: "url-property",
isEnabled: true,
isEnabled: true
},
{
type: "frontmatter",
isEnabled: true,
isEnabled: true
},
{
type: "body",
isEnabled: true,
},
isEnabled: true
}
],
loadSocialMediaImage: true,
loadSocialMediaImage: true
},
list: {
isEnabled: true,
showTags: true,
},
table: {
isEnabled: false,
order: 1,
showTags: true
},
feed: {
isEnabled: true,
order: 2,
removeH1: true,
collapseStyle: "no-new-lines",
lineClampLarge: 5,
lineClampMedium: 3,
lineClampSmall: 2,
lineClampSmall: 2
},
recommended: {
table: {
isEnabled: false,
},
related: {
isEnabled: false,
},
order: 3
}
},
confirmBeforeDelete: true,
currentView: TExplorerView.GRID,
@ -88,13 +83,7 @@ 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,
logLevel: LOG_LEVEL_WARN
};

View file

@ -1,5 +1,5 @@
import Logger from "js-logger";
import { PluginEvent, EventCallback } from "./types";
import { PluginEvent, type EventCallback } from "./types";
export default class EventManager {
private static instance: EventManager;
@ -40,7 +40,7 @@ export default class EventManager {
Logger.trace({
fileName: "event-manager.ts",
functionName: "emit",
message: "called",
message: "called"
});
if (!this.eventListeners[eventName]) {
@ -48,7 +48,7 @@ export default class EventManager {
{
fileName: "event-manager.ts",
functionName: "emit",
message: "no event listeners found for event. returning...",
message: "no event listeners found for event. returning..."
},
{ eventName }
);
@ -59,7 +59,7 @@ export default class EventManager {
{
fileName: "event-manager.ts",
functionName: "emit",
message: "emiting event",
message: "emiting event"
},
{ eventName }
);

View file

@ -14,7 +14,6 @@ export enum PluginEvent {
FEED_CONTENT_SETTING_CHANGE = "feed-content-setting-change",
COVER_IMAGE_SOURCE_SETTING_CHANGE = "cover-image-source-setting-change",
PROPERTY_SETTING_CHANGE = "property-setting-change",
LICENSE_KEY_VALIDATION_CHANGE = "license-key-validation-change",
CLOCK_UPDATES_SETTING_CHANGE = "clock-updates-setting-change",
FILTER_TOGGLE_SETTING_CHANGE = "filter-toggle-setting-change",
SCROLL_BUTTONS_SETTING_CHANGE = "scroll-buttons-setting-change",
@ -22,7 +21,7 @@ export enum PluginEvent {
FILE_ICONS_SETTING_CHANGE = "file-icons-setting-change",
LOAD_BODY_TAGS_SETTING_CHANGE = "load-body-tags-setting-change",
LOAD_SOCIAL_MEDIA_IMAGE_SETTING_CHANGE = "load-social-media-image-setting-change",
SHOW_TAGS_SETTING_CHANGE = "show-tags-setting-change",
SHOW_TAGS_SETTING_CHANGE = "show-tags-setting-change"
}
export type EventCallback = (...data: unknown[]) => void;

View file

@ -1,14 +1,19 @@
export const moveFocus = (direction: "previous" | "next") => {
const focusedEl = document.activeElement;
if (focusedEl instanceof HTMLElement) {
const rootEl = focusedEl.closest('.vault-explorer, .vault-explorer-property-filter-app');
const rootEl = focusedEl.closest(
".vault-explorer, .vault-explorer-property-filter-app"
);
if (!rootEl) return;
const inputEls = rootEl.querySelectorAll('a, button, input, select, textarea, [role="button"], [role="link"]')
const inputEls = rootEl.querySelectorAll(
'a, button, input, select, textarea, [role="button"], [role="link"]'
);
const focusableEls = Array.from(inputEls).filter(isElementTabble);
const currentIndex = focusableEls.indexOf(focusedEl);
const newIndex = direction === "previous" ? currentIndex - 1 : currentIndex + 1;
const newIndex =
direction === "previous" ? currentIndex - 1 : currentIndex + 1;
if (newIndex >= 0 && newIndex < focusableEls.length) {
(focusableEls[newIndex] as HTMLElement).focus();
} else if (newIndex > focusableEls.length - 1) {
@ -19,6 +24,9 @@ export const moveFocus = (direction: "previous" | "next") => {
}
function isElementTabble(element: Element) {
return element.getAttribute('disabled') == null && element.getAttribute('tabindex') !== '-1';
return (
element.getAttribute("disabled") == null &&
element.getAttribute("tabindex") !== "-1"
);
}
}
};

View file

@ -1,7 +1,13 @@
import Logger, { ILogLevel } from "js-logger";
import { LOG_LEVEL_OFF, LOG_LEVEL_ERROR, LOG_LEVEL_WARN, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_TRACE } from "./constants";
import { FormattedLogMessage, LogMessageHeader } from "./types";
import Logger, { type ILogLevel } from "js-logger";
import {
LOG_LEVEL_DEBUG,
LOG_LEVEL_ERROR,
LOG_LEVEL_INFO,
LOG_LEVEL_OFF,
LOG_LEVEL_TRACE,
LOG_LEVEL_WARN
} from "./constants";
import type { FormattedLogMessage, LogMessageHeader } from "./types";
export const logLevelToString = (level: ILogLevel) => {
switch (level) {
@ -20,7 +26,7 @@ export const logLevelToString = (level: ILogLevel) => {
default:
throw new Error("Unhandled log level");
}
}
};
export const stringToLogLevel = (value: string) => {
switch (value) {
@ -39,16 +45,21 @@ export const stringToLogLevel = (value: string) => {
default:
throw new Error(`Unhandled log level: ${value}`);
}
}
};
export const formatMessageForLogger = (...args: unknown[]): FormattedLogMessage => {
export const formatMessageForLogger = (
...args: unknown[]
): FormattedLogMessage => {
const head: unknown = args[0];
const body = args[1] as unknown as Record<string, unknown>;
if (typeof args[0] == "object") {
const headers = head as LogMessageHeader;
const { fileName, functionName, message } = headers;
return { message: `[${fileName}:${functionName}] ${message}`, data: body };
return {
message: `[${fileName}:${functionName}] ${message}`,
data: body
};
} else {
return { message: String(head), data: body };
}
}
};

View file

@ -1,26 +1,24 @@
import { Plugin, TAbstractFile, TFile, TFolder } from "obsidian";
import VaultExplorerView from "./obsidian/vault-explorer-view";
import VaultExplorerSettingsTab from "./obsidian/vault-explorer-settings-tab";
import VaultExplorerView from "./obsidian/vault-explorer-view";
import { VaultExplorerPluginSettings } from "./types";
import Logger from "js-logger";
import {
DEFAULT_SETTINGS,
HOVER_LINK_SOURCE_ID,
VAULT_EXPLORER_VIEW,
VAULT_EXPLORER_VIEW
} from "./constants";
import _ from "lodash";
import EventManager from "./event/event-manager";
import { preformMigrations } from "./migrations";
import Logger from "js-logger";
import { formatMessageForLogger, stringToLogLevel } from "./logger";
import { moveFocus } from "./focus-utils";
import { PluginEvent } from "./event/types";
import { isVersionLessThan } from "./utils";
import License from "./svelte/shared/services/license";
import { moveFocus } from "./focus-utils";
import { formatMessageForLogger, stringToLogLevel } from "./logger";
import { preformMigrations } from "./migrations";
import "./styles.css";
import { clearSMICache } from "./svelte/app/services/smi-cache";
import store from "./svelte/shared/services/store";
import "./styles.css";
import type { VaultExplorerPluginSettings } from "./types";
import { isVersionLessThan } from "./utils";
export default class VaultExplorerPlugin extends Plugin {
settings: VaultExplorerPluginSettings = DEFAULT_SETTINGS;
@ -32,8 +30,6 @@ export default class VaultExplorerPlugin extends Plugin {
store.plugin.set(this);
await License.getInstance().loadStoredKey();
this.registerView(
VAULT_EXPLORER_VIEW,
(leaf) => new VaultExplorerView(leaf, this)
@ -48,13 +44,13 @@ export default class VaultExplorerPlugin extends Plugin {
name: "Open vault explorer view",
callback: async () => {
this.openVaultExplorerView();
},
}
});
this.registerEvents();
this.registerHoverLinkSource(HOVER_LINK_SOURCE_ID, {
display: this.manifest.name,
defaultMod: true,
defaultMod: true
});
this.addSettingTab(new VaultExplorerSettingsTab(this.app, this));
@ -203,11 +199,6 @@ export default class VaultExplorerPlugin extends Plugin {
//Clean up the old device id from the versioning system
const LOCAL_STORAGE_ID = "vault-explorer-id";
localStorage.removeItem(LOCAL_STORAGE_ID);
//Clean up the old device id from the versioning system
const LOCAL_STORAGE_LICENSE_KEY =
"vault-explorer-license-key";
localStorage.removeItem(LOCAL_STORAGE_LICENSE_KEY);
}
if (isVersionLessThan(loadedVersion, "1.37.1")) {
console.log("Clearing image cache");
@ -232,13 +223,13 @@ export default class VaultExplorerPlugin extends Plugin {
Logger.trace({
fileName: "main.ts",
functionName: "saveSettings",
message: "called",
message: "called"
});
Logger.debug(
{
fileName: "main.ts",
functionName: "saveSettings",
message: "saving settings",
message: "saving settings"
},
this.settings
);
@ -253,7 +244,7 @@ export default class VaultExplorerPlugin extends Plugin {
} else {
this.app.workspace.getLeaf("tab").setViewState({
type: VAULT_EXPLORER_VIEW,
active: true,
active: true
});
}
}

View file

@ -1,16 +1,11 @@
import Migrate_0_4_0 from "./migrate_0_4_0";
import Migrate_1_1_0 from "./migrate_1_1_0";
import Migrate_1_0_0 from "./migrate_1_0_0";
import Migrate_1_2_1 from "./migrate_1_2_1";
import Migrate_1_3_0 from "./migrate_1_3_0";
import Migrate_1_6_0 from "./migrate_1_6_0";
import Migrate_1_6_1 from "./migrate_1_6_1";
import Migrate_1_9_0 from "./migrate_1_9_0";
import Migrate_1_10_0 from "./migrate_1_10_0";
import Migrate_1_13_0 from "./migrate_1_13_0";
import Migrate_1_14_0 from "./migrate_1_14_0";
import Migrate_1_15_0 from "./migrate_1_15_0";
import Migrate_1_17_0 from "./migrate_1_17_0";
import Migrate_1_13_0 from "./migrate_1_13_0";
import Migrate_1_10_0 from "./migrate_1_10_0";
import Migrate_1_1_0 from "./migrate_1_1_0";
import Migrate_1_21_0 from "./migrate_1_21_0";
import Migrate_1_22_0 from "./migrate_1_22_0";
import Migrate_1_23_0 from "./migrate_1_23_0";
@ -18,8 +13,12 @@ import Migrate_1_23_1 from "./migrate_1_23_1";
import Migrate_1_24_0 from "./migrate_1_24_0";
import Migrate_1_25_0 from "./migrate_1_25_0";
import Migrate_1_26_0 from "./migrate_1_26_0";
import Migrate_1_2_1 from "./migrate_1_2_1";
import Migrate_1_3_0 from "./migrate_1_3_0";
import Migrate_1_6_0 from "./migrate_1_6_0";
import Migrate_1_6_1 from "./migrate_1_6_1";
import Migrate_1_9_0 from "./migrate_1_9_0";
import { TMigration } from "./types";
import { isVersionLessThan } from "src/utils";
import Migrate_1_27_0 from "./migrate_1_27_0";
import Migrate_1_29_0 from "./migrate_1_29_0";
@ -33,168 +32,175 @@ 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";
import type { TMigration } from "./types";
const migrations: TMigration[] = [
{
from: "0.3.3",
to: "0.4.0",
migrate: Migrate_0_4_0,
migrate: Migrate_0_4_0
},
{
from: "0.5.5",
to: "1.0.0",
migrate: Migrate_1_0_0,
migrate: Migrate_1_0_0
},
{
from: "1.0.1",
to: "1.1.0",
migrate: Migrate_1_1_0,
migrate: Migrate_1_1_0
},
{
from: "1.2.0",
to: "1.2.1",
migrate: Migrate_1_2_1,
migrate: Migrate_1_2_1
},
{
from: "1.2.1",
to: "1.3.0",
migrate: Migrate_1_3_0,
migrate: Migrate_1_3_0
},
{
from: "1.5.0",
to: "1.6.0",
migrate: Migrate_1_6_0,
migrate: Migrate_1_6_0
},
{
from: "1.6.0",
to: "1.6.1",
migrate: Migrate_1_6_1,
migrate: Migrate_1_6_1
},
{
from: "1.8.1",
to: "1.9.0",
migrate: Migrate_1_9_0,
migrate: Migrate_1_9_0
},
{
from: "1.9.1",
to: "1.10.0",
migrate: Migrate_1_10_0,
migrate: Migrate_1_10_0
},
{
from: "1.12.1",
to: "1.13.0",
migrate: Migrate_1_13_0,
migrate: Migrate_1_13_0
},
{
from: "1.13.1",
to: "1.14.0",
migrate: Migrate_1_14_0,
migrate: Migrate_1_14_0
},
{
from: "1.14.2",
to: "1.15.0",
migrate: Migrate_1_15_0,
migrate: Migrate_1_15_0
},
{
from: "1.16.0",
to: "1.17.0",
migrate: Migrate_1_17_0,
migrate: Migrate_1_17_0
},
{
from: "1.20.0",
to: "1.21.0",
migrate: Migrate_1_21_0,
migrate: Migrate_1_21_0
},
{
from: "1.21.2",
to: "1.22.0",
migrate: Migrate_1_22_0,
migrate: Migrate_1_22_0
},
{
from: "1.22.0",
to: "1.23.0",
migrate: Migrate_1_23_0,
migrate: Migrate_1_23_0
},
{
from: "1.23.0",
to: "1.23.1",
migrate: Migrate_1_23_1,
migrate: Migrate_1_23_1
},
{
from: "1.23.2",
to: "1.24.0",
migrate: Migrate_1_24_0,
migrate: Migrate_1_24_0
},
{
from: "1.24.2",
to: "1.25.0",
migrate: Migrate_1_25_0,
migrate: Migrate_1_25_0
},
{
from: "1.25.2",
to: "1.26.0",
migrate: Migrate_1_26_0,
migrate: Migrate_1_26_0
},
{
from: "1.26.3",
to: "1.27.0",
migrate: Migrate_1_27_0,
migrate: Migrate_1_27_0
},
{
from: "1.28.0",
to: "1.29.0",
migrate: Migrate_1_29_0,
migrate: Migrate_1_29_0
},
{
from: "1.29.0",
to: "1.30.0",
migrate: Migrate_1_30_0,
migrate: Migrate_1_30_0
},
{
from: "1.30.5",
to: "1.31.0",
migrate: Migrate_1_31_0,
migrate: Migrate_1_31_0
},
{
from: "1.32.2",
to: "1.33.0",
migrate: Migrate_1_33_0,
migrate: Migrate_1_33_0
},
{
from: "1.36.3",
to: "1.37.0",
migrate: Migrate_1_37_0,
migrate: Migrate_1_37_0
},
{
from: "1.37.2",
to: "1.38.0",
migrate: Migrate_1_38_0,
migrate: Migrate_1_38_0
},
{
from: "1.38.0",
to: "1.39.0",
migrate: Migrate_1_39_0,
migrate: Migrate_1_39_0
},
{
from: "1.39.0",
to: "1.40.0",
migrate: Migrate_1_40_0,
migrate: Migrate_1_40_0
},
{
from: "1.40.2",
to: "1.41.0",
migrate: Migrate_1_41_0,
migrate: Migrate_1_41_0
},
{
from: "1.41.1",
to: "1.42.0",
migrate: Migrate_1_42_0,
migrate: Migrate_1_42_0
},
{
from: "1.44.6",
to: "1.45.0",
migrate: Migrate_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,10 +1,10 @@
import { VaultExplorerPluginSettings_0_5_5 } from "src/types/types-0.5.5";
import { VaultExplorerPluginSettings_0_3_3 } from "src/types/types-0.3.3";
import type { VaultExplorerPluginSettings_0_3_3 } from "src/types/types-0.3.3";
import type { VaultExplorerPluginSettings_0_5_5 } from "src/types/types-0.5.5";
import MigrationInterface from "./migration_interface";
export default class Migrate_0_4_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_0_3_3;
const typedData = data as unknown as VaultExplorerPluginSettings_0_3_3;
const newData: VaultExplorerPluginSettings_0_5_5 = {
...typedData,
filters: {
@ -13,8 +13,8 @@ export default class Migrate_0_4_0 implements MigrationInterface {
...typedData.filters.properties,
groups: []
}
},
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,11 +1,11 @@
import { VaultExplorerPluginSettings_0_5_5 } from "src/types/types-0.5.5";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_0_1 } from "src/types/types-1.0.1";
import { LOG_LEVEL_WARN } from "src/logger/constants";
import type { VaultExplorerPluginSettings_0_5_5 } from "src/types/types-0.5.5";
import type { VaultExplorerPluginSettings_1_0_1 } from "src/types/types-1.0.1";
import MigrationInterface from "./migration_interface";
export default class Migrate_1_0_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_0_5_5;
const typedData = data as unknown as VaultExplorerPluginSettings_0_5_5;
const newData: VaultExplorerPluginSettings_1_0_1 = {
...typedData,
logLevel: LOG_LEVEL_WARN,
@ -13,18 +13,18 @@ export default class Migrate_1_0_0 implements MigrationInterface {
...typedData.filters,
properties: {
...typedData.filters.properties,
groups: typedData.filters.properties.groups.map(group => {
groups: typedData.filters.properties.groups.map((group) => {
const { id, name, filters, isEnabled } = group;
return {
id,
name,
filters,
isEnabled
}
};
})
}
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,32 +1,35 @@
import { FilterRuleType_1_12_1, VaultExplorerPluginSettings_1_12_1 } from "src/types/types-1.12.1";
import {
FilterRuleType_1_12_1,
type VaultExplorerPluginSettings_1_12_1
} from "src/types/types-1.12.1";
import type { VaultExplorerPluginSettings_1_9_1 } from "src/types/types-1.9.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_9_1 } from "src/types/types-1.9.1";
export default class Migrate_1_10_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_9_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_9_1;
const newData: VaultExplorerPluginSettings_1_12_1 = {
...typedData,
filters: {
...typedData.filters,
custom: {
...typedData.filters.custom,
groups: typedData.filters.custom.groups.map(group => {
const rules = group.rules.map(rule => {
groups: typedData.filters.custom.groups.map((group) => {
const rules = group.rules.map((rule) => {
return {
...rule,
type: FilterRuleType_1_12_1.PROPERTY as any,
propertyType: rule.type as any,
}
propertyType: rule.type as any
};
});
return {
...group,
rules
}
};
})
}
}
}
};
delete (newData.filters as any).folder;
delete (newData.filters as any).properties;
for (const group of newData.filters.custom.groups as any) {

View file

@ -1,10 +1,10 @@
import { VaultExplorerPluginSettings_1_13_1 } from "src/types/types-1.13.1";
import type { VaultExplorerPluginSettings_1_12_1 } from "src/types/types-1.12.1";
import type { VaultExplorerPluginSettings_1_13_1 } from "src/types/types-1.13.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_12_1 } from "src/types/types-1.12.1";
export default class Migrate_1_13_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_12_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_12_1;
const newData: VaultExplorerPluginSettings_1_13_1 = {
...typedData,
views: {
@ -15,15 +15,15 @@ export default class Migrate_1_13_0 implements MigrationInterface {
...typedData.filters,
custom: {
...typedData.filters.custom,
groups: typedData.filters.custom.groups.map(group => {
groups: typedData.filters.custom.groups.map((group) => {
return {
...group,
isSticky: false
}
};
})
}
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,10 +1,10 @@
import { VaultExplorerPluginSettings_1_14_2 } from "src/types/types-1.14.2";
import type { VaultExplorerPluginSettings_1_13_1 } from "src/types/types-1.13.1";
import type { VaultExplorerPluginSettings_1_14_2 } from "src/types/types-1.14.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_13_1 } from "src/types/types-1.13.1";
export default class Migrate_1_14_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_13_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_13_1;
const newData: VaultExplorerPluginSettings_1_14_2 = {
...typedData,
filters: {
@ -28,10 +28,10 @@ export default class Migrate_1_14_0 implements MigrationInterface {
custom: {
isEnabled: true,
...typedData.filters.custom
},
}
},
enableScrollButtons: true,
}
enableScrollButtons: true
};
delete (newData.filters as any).onlyFavorites;
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,17 +1,20 @@
import { VaultExplorerPluginSettings_1_16_0, ViewType_1_16_0 } from "src/types/types-1.16.0";
import type { VaultExplorerPluginSettings_1_14_2 } from "src/types/types-1.14.2";
import {
type VaultExplorerPluginSettings_1_16_0,
ViewType_1_16_0
} from "src/types/types-1.16.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_14_2 } from "src/types/types-1.14.2";
export default class Migrate_1_15_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_14_2;
const typedData = data as unknown as VaultExplorerPluginSettings_1_14_2;
const newData: VaultExplorerPluginSettings_1_16_0 = {
...typedData,
views: {
...typedData.views,
order: [...typedData.views.order, ViewType_1_16_0.FEED],
order: [...typedData.views.order, ViewType_1_16_0.FEED]
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,7 +1,7 @@
import { TExplorerView } from "src/types";
import type { VaultExplorerPluginSettings_1_16_0 } from "src/types/types-1.16.0";
import type { VaultExplorerPluginSettings_1_20_0 } from "src/types/types-1.20.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_16_0 } from "src/types/types-1.16.0";
import { VaultExplorerPluginSettings_1_20_0 } from "src/types/types-1.20.0";
export default class Migrate_1_17_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -10,32 +10,32 @@ export default class Migrate_1_17_0 implements MigrationInterface {
...typedData,
views: {
dashboard: {
isEnabled: false,
isEnabled: false
},
grid: {
isEnabled: true,
isEnabled: true
},
list: {
isEnabled: true,
isEnabled: true
},
table: {
isEnabled: false,
isEnabled: false
},
feed: {
isEnabled: true,
isEnabled: true
},
recommended: {
isEnabled: false,
isEnabled: false
},
related: {
isEnabled: false,
},
isEnabled: false
}
},
viewOrder: typedData.views.order as unknown as TExplorerView[],
enableClockUpdates: typedData.views.enableClockUpdates,
currentView: typedData.views
.currentView as unknown as TExplorerView,
titleWrapping: typedData.views.titleWrapping,
titleWrapping: typedData.views.titleWrapping
};
delete (newData as any).views.order;
delete (newData as any).views.currentView;

View file

@ -1,17 +1,20 @@
import type { VaultExplorerPluginSettings_1_0_1 } from "src/types/types-1.0.1";
import {
type VaultExplorerPluginSettings_1_2_0,
ViewType_1_2_0
} from "src/types/types-1.2.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_0_1 } from "src/types/types-1.0.1";
import { VaultExplorerPluginSettings_1_2_0, ViewType_1_2_0 } from "src/types/types-1.2.0";
export default class Migrate_1_1_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_0_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_0_1;
const newData: VaultExplorerPluginSettings_1_2_0 = {
...typedData,
views: {
currentView: typedData.currentView as unknown as ViewType_1_2_0,
order: [ViewType_1_2_0.GRID, ViewType_1_2_0.LIST]
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_20_0 } from "src/types/types-1.20.0";
import type { VaultExplorerPluginSettings_1_21_2 } from "src/types/types-1.21.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_20_0 } from "src/types/types-1.20.0";
import { VaultExplorerPluginSettings_1_21_2 } from "src/types/types-1.21.2";
export default class Migrate_1_21_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_20_0;
const newData: VaultExplorerPluginSettings_1_21_2 = {
...typedData,
enableFileIcons: true,
enableFileIcons: true
};
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_21_2 } from "src/types/types-1.21.2";
import type { VaultExplorerPluginSettings_1_22_0 } from "src/types/types-1.22.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_21_2 } from "src/types/types-1.21.2";
import { VaultExplorerPluginSettings_1_22_0 } from "src/types/types-1.22.0";
export default class Migrate_1_22_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -9,10 +9,10 @@ export default class Migrate_1_22_0 implements MigrationInterface {
...typedData,
properties: {
...typedData.properties,
imageUrl: "",
imageUrl: ""
},
filterGroupsWidth: 300,
filterGroupsWrapping: "nowrap",
filterGroupsWrapping: "nowrap"
};
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_22_0 } from "src/types/types-1.22.0";
import type { VaultExplorerPluginSettings_1_23_0 } from "src/types/types-1.23.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_22_0 } from "src/types/types-1.22.0";
import { VaultExplorerPluginSettings_1_23_0 } from "src/types/types-1.23.0";
export default class Migrate_1_23_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -11,9 +11,9 @@ export default class Migrate_1_23_0 implements MigrationInterface {
...typedData.views,
grid: {
...typedData.views.grid,
fetchSocialMediaImage: false,
},
},
fetchSocialMediaImage: false
}
}
};
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_23_0 } from "src/types/types-1.23.0";
import type { VaultExplorerPluginSettings_1_23_2 } from "src/types/types-1.23.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_23_0 } from "src/types/types-1.23.0";
import { VaultExplorerPluginSettings_1_23_2 } from "src/types/types-1.23.2";
export default class Migrate_1_23_1 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_23_0;
const newData: VaultExplorerPluginSettings_1_23_2 = {
...typedData,
filterGroupsWidth: "100%",
filterGroupsWidth: "100%"
};
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_23_2 } from "src/types/types-1.23.2";
import type { VaultExplorerPluginSettings_1_24_2 } from "src/types/types-1.24.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_23_2 } from "src/types/types-1.23.2";
import { VaultExplorerPluginSettings_1_24_2 } from "src/types/types-1.24.2";
export default class Migrate_1_24_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -12,13 +12,13 @@ export default class Migrate_1_24_0 implements MigrationInterface {
grid: {
...typedData.views.grid,
loadSocialMediaImage:
typedData.views.grid.fetchSocialMediaImage,
typedData.views.grid.fetchSocialMediaImage
},
feed: {
...typedData.views.feed,
collapseContent: true,
},
},
collapseContent: true
}
}
};
delete (newData as any).views.grid.fetchSocialMediaImage;

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_24_2 } from "src/types/types-1.24.2";
import type { VaultExplorerPluginSettings_1_25_2 } from "src/types/types-1.25.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_24_2 } from "src/types/types-1.24.2";
import { VaultExplorerPluginSettings_1_25_2 } from "src/types/types-1.25.2";
export default class Migrate_1_25_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_24_2;
const newData: VaultExplorerPluginSettings_1_25_2 = {
...typedData,
fileInteractionStyle: "content",
fileInteractionStyle: "content"
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_25_2 } from "src/types/types-1.25.2";
import type { VaultExplorerPluginSettings_1_26_3 } from "src/types/types-1.26.3";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_25_2 } from "src/types/types-1.25.2";
import { VaultExplorerPluginSettings_1_26_3 } from "src/types/types-1.26.3";
export default class Migrate_1_26_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_25_2;
const newData: VaultExplorerPluginSettings_1_26_3 = {
...typedData,
configDir: ".vaultexplorer",
configDir: ".vaultexplorer"
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_26_3 } from "src/types/types-1.26.3";
import type { VaultExplorerPluginSettings_1_28_0 } from "src/types/types-1.28.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_26_3 } from "src/types/types-1.26.3";
import { VaultExplorerPluginSettings_1_28_0 } from "src/types/types-1.28.0";
export default class Migrate_1_27_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -15,9 +15,9 @@ export default class Migrate_1_27_0 implements MigrationInterface {
collapseStyle: "no-new-lines",
lineClampLarge: 5,
lineClampMedium: 3,
lineClampSmall: 2,
},
},
lineClampSmall: 2
}
}
};
delete (newData as any).views.feed.collapseContent;

View file

@ -1,7 +1,6 @@
import { VaultExplorerPluginSettings } from "src/types";
import type { VaultExplorerPluginSettings_1_28_0 } from "src/types/types-1.28.0";
import type { VaultExplorerPluginSettings_1_29_0 } from "src/types/types-1.29.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_28_0 } from "src/types/types-1.28.0";
import { VaultExplorerPluginSettings_1_29_0 } from "src/types/types-1.29.0";
export default class Migrate_1_29_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -12,13 +11,13 @@ export default class Migrate_1_29_0 implements MigrationInterface {
...typedData.views,
list: {
...typedData.views.list,
showTags: true,
showTags: true
},
grid: {
...typedData.views.grid,
loadSocialMediaImage: true,
},
},
loadSocialMediaImage: true
}
}
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,17 +1,17 @@
import type { VaultExplorerPluginSettings_1_2_0 } from "src/types/types-1.2.0";
import type { VaultExplorerPluginSettings_1_2_1 } from "src/types/types-1.2.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_2_0 } from "src/types/types-1.2.0";
import { VaultExplorerPluginSettings_1_2_1 } from "src/types/types-1.2.1";
export default class Migrate_1_2_1 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_2_0;
const typedData = data as unknown as VaultExplorerPluginSettings_1_2_0;
const newData: VaultExplorerPluginSettings_1_2_1 = {
...typedData,
views: {
...typedData.views,
titleWrapping: "normal"
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,6 +1,6 @@
import { VaultExplorerPluginSettings_1_30_5 } from "src/types/types-1.30.5";
import type { VaultExplorerPluginSettings_1_29_0 } from "src/types/types-1.29.0";
import type { VaultExplorerPluginSettings_1_30_5 } from "src/types/types-1.30.5";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_29_0 } from "src/types/types-1.29.0";
export default class Migrate_1_30_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -11,9 +11,9 @@ export default class Migrate_1_30_0 implements MigrationInterface {
...typedData.views,
grid: {
...typedData.views.grid,
coverImageSource: "frontmatter-and-body",
},
},
coverImageSource: "frontmatter-and-body"
}
}
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_30_5 } from "src/types/types-1.30.5";
import type { VaultExplorerPluginSettings_1_32_2 } from "src/types/types-1.32.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_30_5 } from "src/types/types-1.30.5";
import { VaultExplorerPluginSettings_1_32_2 } from "src/types/types-1.32.2";
export default class Migrate_1_31_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_30_5;
const newData: VaultExplorerPluginSettings_1_32_2 = {
...typedData,
shouldWrapFilterGroups: typedData.filterGroupsWrapping === "wrap",
shouldWrapFilterGroups: typedData.filterGroupsWrapping === "wrap"
};
delete (newData as any).filterGroupsWrapping;

View file

@ -1,12 +1,12 @@
import type { VaultExplorerPluginSettings_1_32_2 } from "src/types/types-1.32.2";
import type { VaultExplorerPluginSettings_1_36_3 } from "src/types/types-1.36.3";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_32_2 } from "src/types/types-1.32.2";
import { VaultExplorerPluginSettings_1_36_3 } from "src/types/types-1.36.3";
export default class Migrate_1_33_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_32_2;
const newData: VaultExplorerPluginSettings_1_36_3 = {
...typedData,
...typedData
};
delete (newData as any).fileInteractionStyle;

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_37_2 } from "src/types/types-1-37-0";
import type { VaultExplorerPluginSettings_1_36_3 } from "src/types/types-1.36.3";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_36_3 } from "src/types/types-1.36.3";
import { VaultExplorerPluginSettings_1_37_2 } from "src/types/types-1-37-0";
export default class Migrate_1_37_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -14,27 +14,27 @@ export default class Migrate_1_37_0 implements MigrationInterface {
coverImageSources: [
{
type: "image-property",
isEnabled: true,
isEnabled: true
},
{
type: "url-property",
isEnabled: true,
isEnabled: true
},
{
type: "frontmatter",
isEnabled: true,
isEnabled: true
},
{
type: "body",
isEnabled: true,
},
],
},
isEnabled: true
}
]
}
},
properties: {
...typedData.properties,
image: typedData.properties.imageUrl,
},
image: typedData.properties.imageUrl
}
};
delete (newData as any).enableScrollButtons;

View file

@ -1,13 +1,13 @@
import { VaultExplorerPluginSettings_1_37_2 } from "src/types/types-1-37-0";
import type { VaultExplorerPluginSettings_1_37_2 } from "src/types/types-1-37-0";
import type { VaultExplorerPluginSettings_1_38_0 } from "src/types/types-1.38.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_38_0 } from "src/types/types-1.38.0";
export default class Migrate_1_38_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_37_2;
const newData: VaultExplorerPluginSettings_1_38_0 = {
...typedData,
loadBodyTags: true,
loadBodyTags: true
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,9 +1,9 @@
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_38_0 } from "src/types/types-1.38.0";
import type { VaultExplorerPluginSettings_1_38_0 } from "src/types/types-1.38.0";
import {
TExplorerView_1_39_0,
VaultExplorerPluginSettings_1_39_0,
type VaultExplorerPluginSettings_1_39_0
} from "src/types/types-1.39.0";
import MigrationInterface from "./migration_interface";
export default class Migrate_1_39_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -14,14 +14,14 @@ export default class Migrate_1_39_0 implements MigrationInterface {
TExplorerView_1_39_0.GRID,
TExplorerView_1_39_0.LIST,
TExplorerView_1_39_0.TABLE,
TExplorerView_1_39_0.FEED,
TExplorerView_1_39_0.FEED
],
views: {
...typedData.views,
table: {
isEnabled: true,
},
},
isEnabled: true
}
}
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,25 +1,32 @@
import type { VaultExplorerPluginSettings_1_2_1 } from "src/types/types-1.2.1";
import type {
PropertyFilterGroup_1_5_0,
PropertyFilter_1_5_0,
VaultExplorerPluginSettings_1_5_0
} from "src/types/types-1.5.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_2_1 } from "src/types/types-1.2.1";
import { PropertyFilterGroup_1_5_0, PropertyFilter_1_5_0, VaultExplorerPluginSettings_1_5_0 } from "src/types/types-1.5.0";
export default class Migrate_1_3_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_2_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_2_1;
const groups = typedData.filters.properties.groups;
const updatedGroups: PropertyFilterGroup_1_5_0[] = groups.map(group => {
const updatedFilters: PropertyFilter_1_5_0[] = group.filters.map(filter => {
const updatedGroups: PropertyFilterGroup_1_5_0[] = groups.map(
(group) => {
const updatedFilters: PropertyFilter_1_5_0[] =
group.filters.map((filter) => {
return {
...filter,
type: filter.type as any,
matchWhenPropertyDNE: false
};
});
return {
...filter,
type: filter.type as any,
matchWhenPropertyDNE: false
}
});
return {
...group,
filters: updatedFilters
...group,
filters: updatedFilters
};
}
});
);
const newData: VaultExplorerPluginSettings_1_5_0 = {
...typedData,
@ -27,10 +34,10 @@ export default class Migrate_1_3_0 implements MigrationInterface {
...typedData.filters,
properties: {
...typedData.filters.properties,
groups: updatedGroups,
groups: updatedGroups
}
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,13 +1,13 @@
import type { VaultExplorerPluginSettings_1_39_0 } from "src/types/types-1.39.0";
import type { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_39_0 } from "src/types/types-1.39.0";
import { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2";
export default class Migrate_1_40_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = data as unknown as VaultExplorerPluginSettings_1_39_0;
const newData: VaultExplorerPluginSettings_1_40_2 = {
...typedData,
shouldCollapseFilters: false,
shouldCollapseFilters: false
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2";
import type { VaultExplorerPluginSettings_1_41_1 } from "src/types/types-1.41.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2";
import { VaultExplorerPluginSettings_1_41_1 } from "src/types/types-1.41.1";
export default class Migrate_1_41_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -9,15 +9,15 @@ export default class Migrate_1_41_0 implements MigrationInterface {
...typedData,
properties: {
...typedData.properties,
coverImageFit: "",
coverImageFit: ""
},
views: {
...typedData.views,
grid: {
...typedData.views.grid,
coverImageFit: "cover",
},
},
coverImageFit: "cover"
}
}
};
return newData as unknown as Record<string, unknown>;

View file

@ -1,6 +1,6 @@
import type { VaultExplorerPluginSettings_1_41_1 } from "src/types/types-1.41.1";
import type { VaultExplorerPluginSettings_1_44_6 } from "src/types/types-1.44.6";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_41_1 } from "src/types/types-1.41.1";
import { VaultExplorerPluginSettings_1_44_6 } from "src/types/types-1.44.6";
export default class Migrate_1_42_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -12,8 +12,8 @@ export default class Migrate_1_42_0 implements MigrationInterface {
image: typedData.properties.image || "image",
coverImageFit:
typedData.properties.coverImageFit || "image-fit",
url: typedData.properties.url || "url",
},
url: typedData.properties.url || "url"
}
};
delete (newData as any).filterGroupsWidth;
delete (newData as any).shouldWrapFilterGroups;

View file

@ -1,6 +1,7 @@
import { VaultExplorerPluginSettings_1_44_6 } from "src/types/types-1.44.6";
import { TExplorerView } from "src/types";
import type { VaultExplorerPluginSettings_1_44_6 } from "src/types/types-1.44.6";
import type { VaultExplorerPluginSettings_1_45_0 } from "src/types/types-1.45.0";
import MigrationInterface from "./migration_interface";
import { TExplorerView, VaultExplorerPluginSettings } from "src/types";
export default class Migrate_1_45_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
@ -20,10 +21,10 @@ 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,
viewOrder
};
return newData as unknown as Record<string, unknown>;
}

View file

@ -0,0 +1,42 @@
import { TExplorerView, type VaultExplorerPluginSettings } from "src/types";
import type { VaultExplorerPluginSettings_1_45_0 } from "src/types/types-1.45.0";
import MigrationInterface from "./migration_interface";
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

@ -1,10 +1,10 @@
import type { VaultExplorerPluginSettings_1_5_0 } from "src/types/types-1.5.0";
import type { VaultExplorerPluginSettings_1_6_0 } from "src/types/types-1.6.0";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_5_0 } from "src/types/types-1.5.0";
import { VaultExplorerPluginSettings_1_6_0 } from "src/types/types-1.6.0";
export default class Migrate_1_6_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_5_0;
const typedData = data as unknown as VaultExplorerPluginSettings_1_5_0;
const newData: VaultExplorerPluginSettings_1_6_0 = {
...typedData,
properties: {
@ -12,7 +12,7 @@ export default class Migrate_1_6_0 implements MigrationInterface {
creationDate: "",
modifiedDate: ""
}
}
};
return newData as unknown as Record<string, unknown>;
}
}

View file

@ -1,10 +1,10 @@
import type { VaultExplorerPluginSettings_1_6_0 } from "src/types/types-1.6.0";
import type { VaultExplorerPluginSettings_1_8_1 } from "src/types/types-1.8.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_6_0 } from "src/types/types-1.6.0";
import { VaultExplorerPluginSettings_1_8_1 } from "src/types/types-1.8.1";
export default class Migrate_1_6_1 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_6_0;
const typedData = data as unknown as VaultExplorerPluginSettings_1_6_0;
const newData: VaultExplorerPluginSettings_1_8_1 = {
...typedData,
properties: {
@ -12,7 +12,7 @@ export default class Migrate_1_6_1 implements MigrationInterface {
createdDate: "",
modifiedDate: ""
}
}
};
delete (newData.properties as any).creationDate;
return newData as unknown as Record<string, unknown>;
}

View file

@ -1,32 +1,33 @@
import type { VaultExplorerPluginSettings_1_8_1 } from "src/types/types-1.8.1";
import type { VaultExplorerPluginSettings_1_9_1 } from "src/types/types-1.9.1";
import MigrationInterface from "./migration_interface";
import { VaultExplorerPluginSettings_1_8_1 } from "src/types/types-1.8.1";
import { VaultExplorerPluginSettings_1_9_1 } from "src/types/types-1.9.1";
export default class Migrate_1_9_0 implements MigrationInterface {
migrate(data: Record<string, unknown>) {
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_8_1;
const typedData = data as unknown as VaultExplorerPluginSettings_1_8_1;
const newData: VaultExplorerPluginSettings_1_9_1 = {
...typedData,
filters: {
...typedData.filters,
custom: {
selectedGroupId: typedData.filters.properties.selectedGroupId,
groups: typedData.filters.properties.groups.map(group => {
const rules = group.filters.map(filter => {
selectedGroupId:
typedData.filters.properties.selectedGroupId,
groups: typedData.filters.properties.groups.map((group) => {
const rules = group.filters.map((filter) => {
return {
...filter,
valueData: "",
type: filter.type as any
}
};
});
return {
...group,
rules
}
};
})
}
}
}
};
delete (newData.filters as any).properties;
for (const group of newData.filters.custom.groups as any) {
delete group.filters;

View file

@ -1,3 +1,5 @@
export default abstract class MigrationInterface {
abstract migrate(previous: Record<string, unknown>): Record<string, unknown>;
abstract migrate(
previous: Record<string, unknown>
): Record<string, unknown>;
}

View file

@ -1,28 +1,33 @@
import { Modal } from "obsidian";
import CustomFilterApp from "../svelte/custom-filter-app/index.svelte";
import VaultExplorerPlugin from "src/main";
import { mount, unmount } from "svelte";
import CustomFilterApp from "../svelte/custom-filter-app/index.svelte";
export default class CustomFilterModal extends Modal {
component: CustomFilterApp | null;
customFilterApp: ReturnType<typeof mount> | null;
plugin: VaultExplorerPlugin;
constructor(plugin: VaultExplorerPlugin) {
super(plugin.app);
this.plugin = plugin;
this.component = null;
this.customFilterApp = null;
}
onOpen(): void {
const { contentEl } = this;
this.component = new CustomFilterApp({
target: contentEl,
this.customFilterApp = mount(CustomFilterApp, {
target: contentEl
});
}
onClose(): void {
const { contentEl } = this;
this.component?.$destroy();
if (this.customFilterApp) {
unmount(this.customFilterApp);
}
contentEl.empty();
}
}

View file

@ -1,3 +0,0 @@
.vault-explorer-premium-setting {
color: var(--text-accent);
}

View file

@ -4,4 +4,12 @@ export interface ObsidianProperty {
count: number;
}
export type ObsidianPropertyType = "text" | "multitext" | "date" | "datetime" | "checkbox" | "tags" | "aliases" | "number";
export type ObsidianPropertyType =
| "text"
| "multitext"
| "date"
| "datetime"
| "checkbox"
| "tags"
| "aliases"
| "number";

View file

@ -1,5 +1,5 @@
import { App } from "obsidian";
import { ObsidianProperty, ObsidianPropertyType } from "./types";
import type { ObsidianProperty, ObsidianPropertyType } from "./types";
/**
* Gets all Obsidian properties

View file

@ -1,38 +1,41 @@
import Logger from "js-logger";
import { App, PluginSettingTab, Setting, SliderComponent } from "obsidian";
import VaultExplorerPlugin from "src/main";
import {
getDropdownOptionsForProperties,
getObsidianPropertiesByType,
} from "./utils";
import { stringToLogLevel } from "src/logger";
import {
LOG_LEVEL_DEBUG,
LOG_LEVEL_ERROR,
LOG_LEVEL_INFO,
LOG_LEVEL_OFF,
LOG_LEVEL_TRACE,
LOG_LEVEL_WARN,
LOG_LEVEL_WARN
} from "src/logger/constants";
import Logger from "js-logger";
import { stringToLogLevel } from "src/logger";
import { CollapseStyle, CoverImageFit, TExplorerView } 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";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import type {
CollapseStyle,
CoverImageFit,
VaultExplorerPluginSettings
} from "src/types";
import {
getDropdownOptionsForProperties,
getObsidianPropertiesByType
} from "./utils";
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import { TExplorerView } from "src/types";
import ImageSourceApp from "../svelte/image-source-app/index.svelte";
import "./styles.css";
import { clearSMICache } from "src/svelte/app/services/smi-cache";
import { mount, unmount } from "svelte";
export default class VaultExplorerSettingsTab extends PluginSettingTab {
plugin: VaultExplorerPlugin;
licenseKeyApp: LicenseKeyApp | null;
imageSourceApp: ImageSourceApp | null;
imageSourceApp: ReturnType<typeof mount> | null;
constructor(app: App, plugin: VaultExplorerPlugin) {
super(app, plugin);
this.plugin = plugin;
this.licenseKeyApp = null;
this.imageSourceApp = null;
}
@ -92,7 +95,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
"50": "50",
"100": "100",
"250": "250",
"500": "500",
"500": "500"
})
.setValue(this.plugin.settings.pageSize.toString())
.onChange(async (value) => {
@ -158,25 +161,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 +183,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 +200,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 +217,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,39 +229,10 @@ 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({
target: containerEl,
this.imageSourceApp = mount(ImageSourceApp, {
target: containerEl
});
new Setting(containerEl)
@ -285,7 +262,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
cb
.addOptions({
cover: "Cover",
contain: "Contain",
contain: "Contain"
})
.setValue(this.plugin.settings.views.grid.coverImageFit)
.onChange(async (value) => {
@ -339,7 +316,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
cb
.addOptions({
"no-new-lines": "No new lines",
"no-extra-new-lines": "No extra new lines",
"no-extra-new-lines": "No extra new lines"
})
.setValue(this.plugin.settings.views.feed.collapseStyle)
.onChange(async (value) => {
@ -465,7 +442,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
dropdown
.addOptions(
getDropdownOptionsForProperties(textProperties, {
image: "image",
image: "image"
})
)
.setValue(this.plugin.settings.properties.image)
@ -487,7 +464,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
dropdown
.addOptions(
getDropdownOptionsForProperties(textProperties, {
"image-fit": "image-fit",
"image-fit": "image-fit"
})
)
.setValue(this.plugin.settings.properties.coverImageFit)
@ -509,7 +486,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
dropdown
.addOptions(
getDropdownOptionsForProperties(textProperties, {
url: "url",
url: "url"
})
)
.setValue(this.plugin.settings.properties.url)
@ -524,10 +501,10 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
const creationDateDesc = new DocumentFragment();
creationDateDesc.createDiv({
text: "Property used to store a creation date. This must be a date or datetime property.",
text: "Property used to store a creation date. This must be a date or datetime property."
});
creationDateDesc.createDiv({
text: "If set, the property will be preferred over the file's creation date.",
text: "If set, the property will be preferred over the file's creation date."
});
new Setting(containerEl)
@ -538,7 +515,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
.addOptions(
getDropdownOptionsForProperties([
...dateProperties,
...dateTimeProperties,
...dateTimeProperties
])
)
.setValue(this.plugin.settings.properties.createdDate)
@ -553,10 +530,10 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
const modificationDateDesc = new DocumentFragment();
modificationDateDesc.createDiv({
text: "Property used to store a modification date. This must be a date or datetime property.",
text: "Property used to store a modification date. This must be a date or datetime property."
});
modificationDateDesc.createDiv({
text: "If set, the property will be preferred over the file's modification date.",
text: "If set, the property will be preferred over the file's modification date."
});
new Setting(containerEl)
@ -567,7 +544,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
.addOptions(
getDropdownOptionsForProperties([
...dateProperties,
...dateTimeProperties,
...dateTimeProperties
])
)
.setValue(this.plugin.settings.properties.modifiedDate)
@ -649,12 +626,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
})
);
new Setting(containerEl).setName("Premium").setHeading();
this.licenseKeyApp = new LicenseKeyApp({
target: containerEl,
});
new Setting(containerEl).setName("Debugging").setHeading();
new Setting(containerEl)
.setName("Log level")
@ -668,7 +639,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
[LOG_LEVEL_WARN]: "Warn",
[LOG_LEVEL_INFO]: "Info",
[LOG_LEVEL_DEBUG]: "Debug",
[LOG_LEVEL_TRACE]: "Trace",
[LOG_LEVEL_TRACE]: "Trace"
});
cb.setValue(this.plugin.settings.logLevel).onChange(
async (value) => {
@ -683,11 +654,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
const configFolderDesc = new DocumentFragment();
configFolderDesc.createDiv({
text: "Set the plugin configuration folder.",
text: "Set the plugin configuration folder."
});
configFolderDesc.createDiv({
text: "Restart Obsidian after changing this setting.",
cls: "mod-warning",
cls: "mod-warning"
});
new Setting(containerEl)
@ -713,30 +684,52 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
}
onClose() {
this.licenseKeyApp?.$destroy();
this.imageSourceApp?.$destroy();
}
private updateViewOrder(view: TExplorerView, value: boolean) {
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;
} 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;
}
if (this.imageSourceApp) {
unmount(this.imageSourceApp);
}
}
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) {
viewToUpdate.order = maxOrder + 1;
} else {
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

@ -1,18 +1,19 @@
import { ItemView, WorkspaceLeaf } from "obsidian";
import { VAULT_EXPLORER_VIEW } from "src/constants";
import VaultExplorerApp from "../svelte/app/index.svelte";
import VaultExplorerPlugin from "src/main";
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import { mount, unmount } from "svelte";
import VaultExplorerApp from "../svelte/app/index.svelte";
export default class VaultExplorerView extends ItemView {
component: VaultExplorerApp | null;
vaultExplorerApp: ReturnType<typeof mount> | null;
plugin: VaultExplorerPlugin;
constructor(leaf: WorkspaceLeaf, plugin: VaultExplorerPlugin) {
super(leaf);
this.component = null;
this.vaultExplorerApp = null;
this.plugin = plugin;
this.navigation = true;
}
@ -43,12 +44,14 @@ export default class VaultExplorerView extends ItemView {
const containerEl = this.containerEl.children[1];
this.component = new VaultExplorerApp({
target: containerEl,
this.vaultExplorerApp = mount(VaultExplorerApp, {
target: containerEl
});
}
async onClose() {
this.component?.$destroy();
if (this.vaultExplorerApp) {
unmount(this.vaultExplorerApp);
}
}
}

View file

@ -1,11 +1,19 @@
<script lang="ts">
import { onMount } from "svelte";
import { CollapseStyle } from "src/types";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import store from "src/svelte/shared/services/store";
import { formatAsBearTimeString } from "../services/time-string";
import Icon from "src/svelte/shared/components/icon.svelte";
import Spacer from "src/svelte/shared/components/spacer.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import store from "src/svelte/shared/services/store";
import type { CollapseStyle } from "src/types";
import { onMount } from "svelte";
import { SCREEN_SIZE_LG, SCREEN_SIZE_MD } from "../constants";
import { openContextMenu } from "../services/context-menu";
import { getIconIdForFile } from "../services/file-icon";
import { openInCurrentTab } from "../services/open-file";
import { formatAsBearTimeString } from "../services/time-string";
import {
removeBoldMarkdown,
removeCodeBlocks,
@ -20,14 +28,6 @@
removeNewLines,
removeWikiLinks,
} from "../services/utils/content-utils";
import Icon from "src/svelte/shared/components/icon.svelte";
import { getIconIdForFile } from "../services/file-icon";
import { PluginEvent } from "src/event/types";
import { openInCurrentTab } from "../services/open-file";
import { openContextMenu } from "../services/context-menu";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
import { SCREEN_SIZE_LG, SCREEN_SIZE_MD } from "../constants";
import Spacer from "src/svelte/shared/components/spacer.svelte";
export let displayName: string;
export let baseName: string;
@ -35,7 +35,6 @@
export let path: string;
export let createdMillis: number;
export let content: string | null;
export let enablePremiumFeatures: boolean;
let ref: HTMLElement | null = null;
let enableFileIcons = false;
@ -147,14 +146,7 @@
function handleCardContextMenu(e: Event) {
const nativeEvent = e as MouseEvent;
const { app, settings } = plugin;
openContextMenu(
nativeEvent,
path,
app,
settings,
enablePremiumFeatures,
{},
);
openContextMenu(nativeEvent, path, app, settings, {});
}
function handleCardMouseOver(e: MouseEvent) {
@ -295,6 +287,7 @@
white-space: pre-wrap;
text-overflow: ellipsis;
-webkit-line-clamp: unset;
line-clamp: unset;
}
.vault-explorer-feed-card__title-text {

View file

@ -1,11 +1,10 @@
<script lang="ts">
import { FileRenderData } from "../types";
import type { FileRenderData } from "../types";
import FeedCard from "./feed-card.svelte";
export let data: FileRenderData[] = [];
export let startIndex;
export let pageLength;
export let enablePremiumFeatures: boolean;
let filteredItems: FileRenderData[] = [];
@ -24,7 +23,6 @@
<div class="vault-explorer-feed-view">
{#each filteredItems as fileRenderData (fileRenderData.id)}
<FeedCard
{enablePremiumFeatures}
displayName={fileRenderData.displayName}
extension={fileRenderData.extension}
baseName={fileRenderData.baseName}

View file

@ -1,10 +1,9 @@
<script lang="ts">
import { TFilterGroup } from "src/types";
import _ from "lodash";
import VaultExplorerPlugin from "src/main";
import store from "src/svelte/shared/services/store";
import FilterGroup from "./filter-group.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import store from "src/svelte/shared/services/store";
import type { TFilterGroup } from "src/types";
import FilterGroup from "./filter-group.svelte";
export let groups: TFilterGroup[] = [];

View file

@ -1,29 +1,29 @@
<script lang="ts">
import Tag from "../../shared/components/tag.svelte";
import Property from "../../shared/components/property.svelte";
import VaultExplorerPlugin from "src/main";
import store from "../../shared/services/store";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import { createEventDispatcher, onMount } from "svelte";
import Logger from "js-logger";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
import EventManager from "src/event/event-manager";
import Icon from "src/svelte/shared/components/icon.svelte";
import { getIconIdForFile } from "../services/file-icon";
import { PluginEvent } from "src/event/types";
import { openContextMenu } from "../services/context-menu";
import { openInCurrentTab } from "../services/open-file";
import { getDomainFromUrl } from "../services/utils/url-utils";
import Spacer from "src/svelte/shared/components/spacer.svelte";
import VaultExplorerPlugin from "src/main";
import Divider from "src/svelte/shared/components/divider.svelte";
import Icon from "src/svelte/shared/components/icon.svelte";
import Spacer from "src/svelte/shared/components/spacer.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import type { CoverImageFit } from "src/types";
import { createEventDispatcher, onMount } from "svelte";
import Property from "../../shared/components/property.svelte";
import Tag from "../../shared/components/tag.svelte";
import store from "../../shared/services/store";
import { openContextMenu } from "../services/context-menu";
import { fetchSocialMediaImage } from "../services/fetch-social-media-image";
import { getIconIdForFile } from "../services/file-icon";
import { openInCurrentTab } from "../services/open-file";
import {
getSMICacheEntry,
isSMICacheEntryExpired,
putSMICacheEntry,
} from "../services/smi-cache";
import { CoverImageFit } from "src/types";
import Logger from "js-logger";
import { getDomainFromUrl } from "../services/utils/url-utils";
type SocialMediaImageResult = {
status: "SUCCESS" | "NOT_FOUND" | "EXPIRED" | "NO_IMAGE";
@ -42,7 +42,6 @@
export let custom2: string | null;
export let custom3: string | null;
export let coverImageFit: CoverImageFit;
export let enablePremiumFeatures: boolean;
let plugin: VaultExplorerPlugin;
let enableFileIcons: boolean = false;
@ -110,21 +109,12 @@
const showCoverImageOptions = path.endsWith(".md");
const { app, settings } = plugin;
openContextMenu(
nativeEvent,
path,
app,
settings,
enablePremiumFeatures,
{
coverImageFit: showCoverImageOptions
? coverImageFit
: undefined,
onCoverImageFitChange: showCoverImageOptions
? handleCoverImageFitChange
: undefined,
},
);
openContextMenu(nativeEvent, path, app, settings, {
coverImageFit: showCoverImageOptions ? coverImageFit : undefined,
onCoverImageFitChange: showCoverImageOptions
? handleCoverImageFitChange
: undefined,
});
}
function handleCardMouseOver(e: MouseEvent) {

View file

@ -1,11 +1,10 @@
<script lang="ts">
import { FileRenderData } from "../types";
import type { FileRenderData } from "../types";
import GridCard from "./grid-card.svelte";
export let data: FileRenderData[];
export let startIndex: number;
export let pageLength: number;
export let enablePremiumFeatures: boolean;
let filteredItems: FileRenderData[] = [];
@ -25,7 +24,6 @@
<div class="vault-explorer-grid-view__container">
{#each filteredItems as fileRenderData (fileRenderData.id)}
<GridCard
{enablePremiumFeatures}
displayName={fileRenderData.displayName}
path={fileRenderData.path}
coverImageFit={fileRenderData.coverImageFit}

View file

@ -1,26 +1,26 @@
<script lang="ts">
import VaultExplorerPlugin from "src/main";
import store from "../../shared/services/store";
import Tag from "src/svelte/shared/components/tag.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import Icon from "src/svelte/shared/components/icon.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import { getIconIdForFile } from "../services/file-icon";
import { onMount } from "svelte";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import Icon from "src/svelte/shared/components/icon.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import Tag from "src/svelte/shared/components/tag.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import { onMount } from "svelte";
import store from "../../shared/services/store";
import { openContextMenu } from "../services/context-menu";
import { getIconIdForFile } from "../services/file-icon";
import { openInCurrentTab } from "../services/open-file";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
export let displayName: string;
export let baseName: string;
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;
let enableFileIcons: boolean = false;
let ref: HTMLElement | null = null;
@ -77,14 +77,7 @@
function handleItemContextMenu(e: Event) {
const nativeEvent = e as MouseEvent;
const { app, settings } = plugin;
openContextMenu(
nativeEvent,
path,
app,
settings,
enablePremiumFeatures,
{},
);
openContextMenu(nativeEvent, path, app, settings, {});
}
function handleItemMouseOver(e: MouseEvent) {
@ -98,8 +91,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 +179,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 +194,7 @@
width: 50%;
}
.vault-explorer-list-item__tags--screen-size-sm {
.vault-explorer-list-item__tags--full {
width: 100%;
}
</style>

View file

@ -1,14 +1,12 @@
<script lang="ts">
import ListItem from "./list-item.svelte";
import { FileRenderData } from "../types";
import type { FileRenderData } from "../types";
export let data: FileRenderData[];
export let startIndex: number;
export let pageLength: number;
export let showTags: boolean;
export let isSmallScreenSize: boolean;
export let enablePremiumFeatures: boolean;
let filteredItems: FileRenderData[] = [];
@ -27,8 +25,6 @@
<div class="vault-explorer-list-view">
{#each filteredItems as fileRenderData (fileRenderData.id)}
<ListItem
{enablePremiumFeatures}
{showTags}
displayName={fileRenderData.displayName}
extension={fileRenderData.extension}
baseName={fileRenderData.baseName}

View file

@ -48,7 +48,7 @@
handleClearClick();
}
}}
/>
></div>
{/if}
</div>
<IconButton

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { Menu } from "obsidian";
import IconButton from "src/svelte/shared/components/icon-button.svelte";
import { SortFilterOption } from "src/types";
import type { SortFilterOption } from "src/types";
import { createEventDispatcher } from "svelte";
export let value: SortFilterOption;

View file

@ -1,19 +1,18 @@
<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";
import Tag from "src/svelte/shared/components/tag.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import { openInCurrentTab } from "../services/open-file";
import { HOVER_LINK_SOURCE_ID } from "src/constants";
import Stack from "src/svelte/shared/components/stack.svelte";
import { getIconIdForFile } from "../services/file-icon";
import Icon from "src/svelte/shared/components/icon.svelte";
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import Icon from "src/svelte/shared/components/icon.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import Tag from "src/svelte/shared/components/tag.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import store from "src/svelte/shared/services/store";
import { onMount } from "svelte";
import { openContextMenu } from "../services/context-menu";
import { getIconIdForFile } from "../services/file-icon";
import { openInCurrentTab } from "../services/open-file";
import type { FileRenderData } from "../types";
interface TColumn {
key: string;
@ -25,7 +24,6 @@
export let data: FileRenderData[];
export let startIndex: number;
export let pageLength: number;
export let enablePremiumFeatures: boolean;
let filteredItems: FileRenderData[] = [];
let plugin: VaultExplorerPlugin | null = null;
@ -37,22 +35,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) => {
@ -103,14 +99,7 @@
const nativeEvent = e as MouseEvent;
const { app, settings } = plugin;
openContextMenu(
nativeEvent,
path,
app,
settings,
enablePremiumFeatures,
{},
);
openContextMenu(nativeEvent, path, app, settings, {});
}
function getValue(item: FileRenderData, column: TColumn): unknown {
@ -172,7 +161,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 +214,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

@ -2,62 +2,66 @@
// ============================================
// Imports
// ============================================
import Stack from "../shared/components/stack.svelte";
import Flex from "../shared/components/flex.svelte";
import TabList from "../shared/components/tab-list.svelte";
import Tab from "../shared/components/tab.svelte";
import Logger from "js-logger";
import _ from "lodash";
import { TFile } from "obsidian";
import {
import EventManager from "src/event/event-manager";
import { PluginEvent } from "src/event/types";
import VaultExplorerPlugin from "src/main";
import CustomFilterModal from "src/obsidian/custom-filter-modal";
import type {
CoverImageFit,
TCustomFilter,
TFeedView,
TGridView,
TListView,
TSearchFilter,
TSortFilter,
TExplorerView,
CoverImageFit,
TTableView
} from "src/types";
import store from "../shared/services/store";
import VaultExplorerPlugin from "src/main";
import GridView from "./components/grid-view.svelte";
import ListView from "./components/list-view.svelte";
import { filterBySearch } from "./services/filters/search-filter";
import { filterByGroups } from "./services/filters/custom/filter-by-groups";
import { formatFileDataForRender } from "./services/render-data";
import _ from "lodash";
import { TExplorerView } from "src/types";
import { onMount } from "svelte";
import EventManager from "src/event/event-manager";
import { getDisplayNameForView } from "./services/display-name";
import Flex from "../shared/components/flex.svelte";
import IconButton from "../shared/components/icon-button.svelte";
import Spacer from "../shared/components/spacer.svelte";
import Stack from "../shared/components/stack.svelte";
import TabList from "../shared/components/tab-list.svelte";
import Tab from "../shared/components/tab.svelte";
import Wrap from "../shared/components/wrap.svelte";
import store from "../shared/services/store";
import {
getStartOfLastWeekMillis,
getStartOfTodayMillis,
getStartOfThisWeekMillis,
getStartOfTodayMillis
} from "../shared/services/time-utils";
import { FileRenderData } from "./types";
import Logger from "js-logger";
import FeedView from "./components/feed-view.svelte";
import FilterGroupList from "./components/filter-group-list.svelte";
import GridView from "./components/grid-view.svelte";
import ListView from "./components/list-view.svelte";
import PaginationIndicator from "./components/pagination-indicator.svelte";
import SearchFilter from "./components/search-filter.svelte";
import SortFilter from "./components/sort-filter.svelte";
import TableView from "./components/table-view.svelte";
import { DEBOUNCE_INPUT_TIME, SCREEN_SIZE_MD } from "./constants";
import FeedView from "./components/feed-view.svelte";
import PaginationIndicator from "./components/pagination-indicator.svelte";
import Wrap from "../shared/components/wrap.svelte";
import {
RandomFileSortCache,
randomFileSortStore,
} from "./services/random-file-sort-store";
import {
FileContentCache,
fileContentStore,
} from "./services/file-content-store";
import { fileStore, LoadedFile } from "./services/file-store";
import IconButton from "../shared/components/icon-button.svelte";
import CustomFilterModal from "src/obsidian/custom-filter-modal";
import FilterGroupList from "./components/filter-group-list.svelte";
import { PluginEvent } from "src/event/types";
import { getDisplayNameForView } from "./services/display-name";
import {
favoritesStore,
TFavoritesCache,
type TFavoritesCache
} from "./services/favorites-store";
import TableView from "./components/table-view.svelte";
import Spacer from "../shared/components/spacer.svelte";
import License from "../shared/services/license";
import {
type FileContentCache,
fileContentStore
} from "./services/file-content-store";
import { fileStore, type LoadedFile } from "./services/file-store";
import { filterByGroups } from "./services/filters/custom/filter-by-groups";
import { filterBySearch } from "./services/filters/search-filter";
import {
type RandomFileSortCache,
randomFileSortStore
} from "./services/random-file-sort-store";
import { formatFileDataForRender } from "./services/render-data";
import type { FileRenderData } from "./types";
// ============================================
// Variables
@ -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,
value: "",
};
let sortFilter: TSortFilter = {
isEnabled: true,
value: "file-name-asc",
};
let customFilter: TCustomFilter = {
isEnabled: true,
groups: [],
selectedGroupId: "",
isEnabled: false,
value: ""
};
let currentView: TExplorerView | null = TExplorerView.GRID;
let sortFilter: TSortFilter = {
isEnabled: false,
value: "file-name-asc"
};
let customFilter: TCustomFilter = {
isEnabled: false,
selectedGroupId: "",
groups: []
};
let currentView: TExplorerView | null = null;
let frontmatterCacheTime: number = Date.now();
let propertySettingsTime: number = Date.now();
@ -95,26 +101,53 @@
let loadBodyTagsTime: number = Date.now();
let loadedFiles: LoadedFile[] = [];
let timeValuesUpdateInterval: NodeJS.Timer | null = null;
let timeValuesUpdateInterval: NodeJS.Timeout | null = null;
let favoritesCache: TFavoritesCache = new Map();
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
// ============================================
License.getInstance()
.getHasValidKeyStore()
.subscribe((hasValidKey) => {
enablePremiumFeatures = hasValidKey;
});
onMount(() => {
initialRender = false;
});
randomFileSortStore.subscribe((value) => {
randomSortCache = value;
@ -132,18 +165,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,12 +189,13 @@
fileContentStore.load(app);
randomFileSortStore.load(app);
});
onMount(() => {
function handleFilterToggleSettingChange() {
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleFilterToggleSettingChange",
message: "called",
message: "called"
});
searchFilter = plugin.settings.filters.search;
@ -169,13 +205,13 @@
EventManager.getInstance().on(
PluginEvent.FILTER_TOGGLE_SETTING_CHANGE,
handleFilterToggleSettingChange,
handleFilterToggleSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.FILTER_TOGGLE_SETTING_CHANGE,
handleFilterToggleSettingChange,
handleFilterToggleSettingChange
);
};
});
@ -185,7 +221,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleClockUpdatesSettingChange",
message: "called",
message: "called"
});
const isEnabled = plugin.settings.enableClockUpdates;
@ -201,7 +237,7 @@
EventManager.getInstance().on(
PluginEvent.CLOCK_UPDATES_SETTING_CHANGE,
handleClockUpdatesSettingChange,
handleClockUpdatesSettingChange
);
return () => {
@ -210,7 +246,7 @@
EventManager.getInstance().off(
PluginEvent.CLOCK_UPDATES_SETTING_CHANGE,
handleClockUpdatesSettingChange,
handleClockUpdatesSettingChange
);
};
});
@ -222,12 +258,12 @@
EventManager.getInstance().on(
PluginEvent.COLLAPSE_FILTERS_CHANGE,
handleToggleFiltersChange,
handleToggleFiltersChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.COLLAPSE_FILTERS_CHANGE,
handleToggleFiltersChange,
handleToggleFiltersChange
);
};
});
@ -237,19 +273,19 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handlePropertiesFilterUpdate",
message: "called",
message: "called"
});
customFilter.groups = plugin.settings.filters.custom.groups;
}
EventManager.getInstance().on(
PluginEvent.PROPERTIES_FILTER_UPDATE,
handlePropertiesFilterUpdate,
handlePropertiesFilterUpdate
);
return () => {
EventManager.getInstance().off(
PluginEvent.PROPERTIES_FILTER_UPDATE,
handlePropertiesFilterUpdate,
handlePropertiesFilterUpdate
);
};
});
@ -259,7 +295,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleCreateFile",
message: "called",
message: "called"
});
if (data.length > 0 && data[0] instanceof TFile) {
const newFile = data[0] as TFile;
@ -272,12 +308,12 @@
EventManager.getInstance().on(
PluginEvent.FILE_CREATE,
handleCreateFile,
handleCreateFile
);
return () => {
EventManager.getInstance().off(
PluginEvent.FILE_CREATE,
handleCreateFile,
handleCreateFile
);
};
});
@ -287,7 +323,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleDeleteFile",
message: "called",
message: "called"
});
if (data.length > 0 && typeof data[0] === "string") {
const path = data[0] as string;
@ -301,12 +337,12 @@
EventManager.getInstance().on(
PluginEvent.FILE_DELETE,
handleDeleteFile,
handleDeleteFile
);
return () => {
EventManager.getInstance().off(
PluginEvent.FILE_DELETE,
handleDeleteFile,
handleDeleteFile
);
};
});
@ -316,7 +352,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleFileRename",
message: "called",
message: "called"
});
if (data.length < 2) return;
if (typeof data[0] === "string" && data[1] instanceof TFile) {
@ -332,12 +368,12 @@
EventManager.getInstance().on(
PluginEvent.FILE_RENAME,
handleFileRename,
handleFileRename
);
return () => {
EventManager.getInstance().off(
PluginEvent.FILE_RENAME,
handleFileRename,
handleFileRename
);
};
});
@ -347,7 +383,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleFileModify",
message: "called",
message: "called"
});
if (data.length > 0 && data[0] instanceof TFile) {
const file = data[0] as TFile;
@ -359,12 +395,12 @@
EventManager.getInstance().on(
PluginEvent.FILE_MODIFY,
handleFileModify,
handleFileModify
);
return () => {
EventManager.getInstance().off(
PluginEvent.FILE_MODIFY,
handleFileModify,
handleFileModify
);
};
});
@ -374,7 +410,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleMetadataChange",
message: "called",
message: "called"
});
if (data.length > 0 && data[0] instanceof TFile) {
@ -384,12 +420,12 @@
EventManager.getInstance().on(
PluginEvent.METADATA_CHANGE,
handleMetadataChange,
handleMetadataChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.METADATA_CHANGE,
handleMetadataChange,
handleMetadataChange
);
};
});
@ -399,21 +435,24 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleViewToggleSettingChange",
message: "called",
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(
PluginEvent.VIEW_TOGGLE_SETTING_CHANGE,
handleViewToggleSettingChange,
handleViewToggleSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.VIEW_TOGGLE_SETTING_CHANGE,
handleViewToggleSettingChange,
handleViewToggleSettingChange
);
};
});
@ -423,7 +462,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handlePageSizeSettingChange",
message: "called",
message: "called"
});
pageSize = plugin.settings.pageSize;
@ -431,12 +470,12 @@
EventManager.getInstance().on(
PluginEvent.PAGE_SIZE_SETTING_CHANGE,
handlePageSizeSettingChange,
handlePageSizeSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.PAGE_SIZE_SETTING_CHANGE,
handlePageSizeSettingChange,
handlePageSizeSettingChange
);
};
});
@ -446,19 +485,19 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handlePropertySettingChange",
message: "called",
message: "called"
});
updatePropertySettingTime();
}
EventManager.getInstance().on(
PluginEvent.PROPERTY_SETTING_CHANGE,
handlePropertySettingChange,
handlePropertySettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.PROPERTY_SETTING_CHANGE,
handlePropertySettingChange,
handlePropertySettingChange
);
};
});
@ -468,7 +507,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleCoverImageFitSettingChange",
message: "called",
message: "called"
});
coverImageFitTime = Date.now();
@ -476,12 +515,12 @@
EventManager.getInstance().on(
PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE,
handleCoverImageFitSettingChange,
handleCoverImageFitSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE,
handleCoverImageFitSettingChange,
handleCoverImageFitSettingChange
);
};
});
@ -491,7 +530,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleCoverImageSourceSettingChange",
message: "called",
message: "called"
});
coverImageSourcesTime = Date.now();
@ -499,12 +538,12 @@
EventManager.getInstance().on(
PluginEvent.COVER_IMAGE_SOURCE_SETTING_CHANGE,
handleCoverImageSourceSettingChange,
handleCoverImageSourceSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.COVER_IMAGE_SOURCE_SETTING_CHANGE,
handleCoverImageSourceSettingChange,
handleCoverImageSourceSettingChange
);
};
});
@ -522,7 +561,7 @@
}
const leafEl = ref?.closest(
".workspace-leaf-content",
".workspace-leaf-content"
) as HTMLElement | null;
if (leafEl) {
checkLeafWidth(leafEl);
@ -543,7 +582,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "handleLoadBodyTagsSettingChange",
message: "called",
message: "called"
});
loadBodyTagsTime = Date.now();
@ -551,12 +590,12 @@
EventManager.getInstance().on(
PluginEvent.LOAD_BODY_TAGS_SETTING_CHANGE,
handleLoadBodyTagsSettingChange,
handleLoadBodyTagsSettingChange
);
return () => {
EventManager.getInstance().off(
PluginEvent.LOAD_BODY_TAGS_SETTING_CHANGE,
handleLoadBodyTagsSettingChange,
handleLoadBodyTagsSettingChange
);
};
});
@ -565,7 +604,6 @@
// Functions
// ============================================
const debounceSearchFilterChange = _.debounce((e) => {
if (searchFilter == null) return;
searchFilter.value = e.target.value;
}, DEBOUNCE_INPUT_TIME);
@ -577,7 +615,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "updateTimeValues",
message: "called",
message: "called"
});
startOfTodayMillis = getStartOfTodayMillis();
startOfThisWeekMillis = getStartOfThisWeekMillis();
@ -593,7 +631,7 @@
Logger.trace({
fileName: "app/index.svelte",
functionName: "updateFrontmatterCacheTime",
message: "called",
message: "called"
});
frontmatterCacheTime = Date.now();
}
@ -603,13 +641,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();
}
@ -639,7 +681,7 @@
return {
...group,
isSticky: newSticky,
isEnabled: newSticky,
isEnabled: newSticky
};
} else {
return { ...group, isEnabled: !group.isEnabled };
@ -661,30 +703,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) {
@ -735,7 +789,7 @@
nativeEvent.dataTransfer.setDragImage(
dragImage,
rect.width / 2,
rect.height / 2,
rect.height / 2
);
nativeEvent.target.addEventListener("dragend", () => {
@ -767,7 +821,7 @@
Logger.error({
fileName: "app/index.svelte",
functionName: "handleCoverImageFitChange",
message: "file not found. returning...",
message: "file not found. returning..."
});
return;
}
@ -805,7 +859,7 @@
path,
frontmatter,
content,
customFilter.groups,
customFilter.groups
);
});
}
@ -826,7 +880,7 @@
settings: plugin.settings,
fileId: id,
file,
fileContent: content,
fileContent: content
});
});
}
@ -874,7 +928,10 @@
sortFilter,
currentView,
customFilter,
viewOrder,
listView,
gridView,
tableView,
feedView,
shouldCollapseFilters,
saveSettings();
@ -891,6 +948,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 +994,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}
@ -975,32 +1038,19 @@
data={renderData}
{startIndex}
{pageLength}
{enablePremiumFeatures}
on:coverImageFitChange={handleCoverImageFitChange}
/>
{:else if currentView === "list"}
<ListView
data={renderData}
{isSmallScreenSize}
showTags={showListViewTags}
{startIndex}
{pageLength}
{enablePremiumFeatures}
/>
{:else if currentView === "table"}
<TableView
data={renderData}
{startIndex}
{pageLength}
{enablePremiumFeatures}
/>
<TableView data={renderData} {startIndex} {pageLength} />
{:else if currentView === "feed"}
<FeedView
data={renderData}
{startIndex}
{pageLength}
{enablePremiumFeatures}
/>
<FeedView data={renderData} {startIndex} {pageLength} />
{/if}
<PaginationIndicator
{startIndex}

View file

@ -1,15 +1,14 @@
import { App, Menu, Notice } from "obsidian";
import { CoverImageFit, VaultExplorerPluginSettings } from "src/types";
import { App, Menu } from "obsidian";
import type { CoverImageFit, VaultExplorerPluginSettings } from "src/types";
export const openContextMenu = (
e: MouseEvent,
filePath: string,
app: App,
settings: VaultExplorerPluginSettings,
enablePremiumFeatures: boolean,
{
coverImageFit,
onCoverImageFitChange,
onCoverImageFitChange
}: {
coverImageFit?: CoverImageFit;
onCoverImageFitChange?: (
@ -51,12 +50,6 @@ export const openContextMenu = (
menu.addItem((item) => {
item.setTitle("Delete");
item.onClick(async () => {
if (!enablePremiumFeatures) {
new Notice(
"This feature requires a premium Vault Explorer license."
);
return;
}
if (confirmBeforeDelete) {
if (confirm("Are you sure you want to delete this file?")) {
await deleteFile(app, filePath);
@ -78,7 +71,7 @@ const deleteFile = async (app: App, filePath: string) => {
const openToTheRight = (app: App, filePath: string) => {
app.workspace.openLinkText("", filePath, "split", {
active: false,
active: false
});
};
@ -87,8 +80,8 @@ const openInNewTab = (app: App, filePath: string) => {
type: "markdown",
active: false,
state: {
file: filePath,
},
file: filePath
}
});
};

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

@ -1,8 +1,8 @@
import Logger from "js-logger";
import _ from "lodash";
import { App, normalizePath, Notice } from "obsidian";
import { VaultExplorerPluginSettings } from "src/types";
import { Writable, writable } from "svelte/store";
import type { VaultExplorerPluginSettings } from "src/types";
import { type Writable, writable } from "svelte/store";
import { parseItems, stringifyItems } from "./utils/json-utils";
interface FavoritesItem {
@ -43,7 +43,7 @@ class FavoritesStore {
Logger.trace({
fileName: "favorites-store.ts",
functionName: "load",
message: "called",
message: "called"
});
const directoryExists = await app.vault.adapter.exists(
@ -80,7 +80,7 @@ class FavoritesStore {
{
fileName: "favorites-store.ts",
functionName: "load",
message: "loaded favorites cache",
message: "loaded favorites cache"
},
{ cache }
);
@ -90,7 +90,7 @@ class FavoritesStore {
{
fileName: "favorites-store.ts",
functionName: "load",
message: "error loading favorites cache",
message: "error loading favorites cache"
},
error.message
);
@ -102,7 +102,7 @@ class FavoritesStore {
Logger.trace({
fileName: "favorites-store.ts",
functionName: "update",
message: "called",
message: "called"
});
this.store.update((currentCache) => {
@ -117,7 +117,7 @@ class FavoritesStore {
Logger.trace({
fileName: "favorites-store.ts",
functionName: "onFileRename",
message: "called",
message: "called"
});
this.store.update((currentCache) => {
@ -136,7 +136,7 @@ class FavoritesStore {
Logger.trace({
fileName: "favorites-store.ts",
functionName: "onFileDelete",
message: "called",
message: "called"
});
this.store.update((currentCache) => {
@ -151,7 +151,7 @@ class FavoritesStore {
Logger.trace({
fileName: "favorites-store.ts",
functionName: "save",
message: "called",
message: "called"
});
if (!this.app) {
@ -166,7 +166,7 @@ class FavoritesStore {
const items = Array.from(cache.entries()).map(
([filePath, isFavorite]) => ({
filePath,
isFavorite,
isFavorite
})
);
@ -178,7 +178,7 @@ class FavoritesStore {
{
fileName: "favorites-store.ts",
functionName: "save",
message: "error saving favorites cache",
message: "error saving favorites cache"
},
error.message
);
@ -190,7 +190,7 @@ class FavoritesStore {
Logger.debug({
fileName: "favorites-store.ts",
functionName: "createConfigDir",
message: "called",
message: "called"
});
try {
@ -202,7 +202,7 @@ class FavoritesStore {
{
fileName: "favorites-store.ts",
functionName: "load",
message: "error creating config directory",
message: "error creating config directory"
},
error.message
);
@ -216,7 +216,7 @@ class FavoritesStore {
Logger.debug({
fileName: "favorites-store.ts",
functionName: "load",
message: "creating new file...",
message: "creating new file..."
});
const rawData = stringifyItems([]);
await app.vault.create(filePath, rawData);
@ -227,7 +227,7 @@ class FavoritesStore {
{
fileName: "favorites-store.ts",
functionName: "load",
message: "error creating favorites file",
message: "error creating favorites file"
},
error.message
);

View file

@ -5,7 +5,7 @@ export const fetchSocialMediaImage = async (url: string) => {
Logger.trace({
fileName: "fetch-social-media-image.ts",
functionName: "fetchSocialMediaImage",
message: "called",
message: "called"
});
try {
@ -13,8 +13,8 @@ export const fetchSocialMediaImage = async (url: string) => {
url,
method: "GET",
headers: {
Cookie: "", // Clear any cookies
},
Cookie: "" // Clear any cookies
}
});
const html = response.text;
@ -52,7 +52,7 @@ export const fetchSocialMediaImage = async (url: string) => {
{
fileName: "social-media-image.ts",
functionName: "fetchSocialMediaImage",
message: "found image",
message: "found image"
},
{ imageUrl }
);
@ -61,7 +61,7 @@ export const fetchSocialMediaImage = async (url: string) => {
{
fileName: "social-media-image.ts",
functionName: "fetchSocialMediaImage",
message: "no image found",
message: "no image found"
},
{ url }
);
@ -73,7 +73,7 @@ export const fetchSocialMediaImage = async (url: string) => {
{
fileName: "social-media-image.ts",
functionName: "fetchSocialMediaImage",
message: "failed to fetch",
message: "failed to fetch"
},
error
);

View file

@ -26,12 +26,12 @@ function createFileContentStore() {
const content = await app.vault.cachedRead(file);
return {
path: file.path,
content,
content
};
}
return {
path: file.path,
content: null,
content: null
};
})()
);
@ -93,7 +93,7 @@ function createFileContentStore() {
onFileCreate: handleFileCreate,
onFileModify: handleFileModify,
onFileRename: handleFileRename,
onFileDelete: handleFileDelete,
onFileDelete: handleFileDelete
};
}

View file

@ -16,7 +16,7 @@ function createFileStore() {
const files = app.vault.getFiles();
const loadedFiles: LoadedFile[] = files.map((file) => ({
id: generateRandomId(),
file,
file
}));
set(loadedFiles);
}
@ -24,7 +24,7 @@ function createFileStore() {
async function handleFileCreate(file: TFile) {
const newLoadedFile: LoadedFile = {
id: generateRandomId(),
file,
file
};
update((loadedFiles) => {
@ -39,7 +39,7 @@ function createFileStore() {
if (loadedFile.file.path === oldPath) {
return {
...loadedFile,
file: updatedFile,
file: updatedFile
};
}
return loadedFile;
@ -60,7 +60,7 @@ function createFileStore() {
subscribe,
onFileCreate: handleFileCreate,
onFileRename: handleFileRename,
onFileDelete: handleFileDelete,
onFileDelete: handleFileDelete
};
}

View file

@ -1,28 +1,28 @@
import { FrontMatterCache } from "obsidian";
import {
TFilterRule,
TFilterGroup,
DatePropertyFilterValue,
PropertyFilterRule,
FilterRuleType,
import type { FrontMatterCache } from "obsidian";
import type {
ContentFilterRule,
FileNameFilterRule,
FolderFilterRule,
ContentFilterRule,
PropertyFilterRule,
TFilterGroup,
TFilterRule
} from "src/types";
import { loadPropertyValue } from "src/svelte/shared/services/load-property-value";
import { matchTextPropertyFilter } from "./match-text-property-filter";
import { matchCheckboxPropertyFilter } from "./match-checkbox-property-filter";
import { matchListPropertyFilter } from "./match-list-property-filter";
import { matchDatePropertyFilter } from "./match-date-property-filter";
import { matchNumberPropertyFilter } from "./match-number-property-filter";
import {
getDateDaysAgo,
getDateDaysAhead,
getDateDaysAhead
} from "src/svelte/shared/services/time-utils";
import { matchFileNameFilter } from "./match-file-name-filter";
import { matchContentFilter } from "./match-content-filter";
import { matchFolderFilter } from "./match-folder-filter";
import { DatePropertyFilterValue, FilterRuleType } from "src/types";
import { removeFrontmatter } from "../../utils/content-utils";
import { matchCheckboxPropertyFilter } from "./match-checkbox-property-filter";
import { matchContentFilter } from "./match-content-filter";
import { matchDatePropertyFilter } from "./match-date-property-filter";
import { matchFileNameFilter } from "./match-file-name-filter";
import { matchFolderFilter } from "./match-folder-filter";
import { matchListPropertyFilter } from "./match-list-property-filter";
import { matchNumberPropertyFilter } from "./match-number-property-filter";
import { matchTextPropertyFilter } from "./match-text-property-filter";
export const filterByGroups = (
fileName: string,
@ -108,7 +108,7 @@ const filterByPropertyType = (
type,
matchWhenPropertyDNE,
propertyType,
propertyName,
propertyName
} = filter;
///The property is empty when the user has not chosen a property.
@ -260,7 +260,7 @@ const filterByFolder = (
const compare = filter.value.toLowerCase().trim();
const doesMatch = matchFolderFilter(value, compare, condition, {
includeSubfolders,
includeSubfolders
});
return doesMatch;
};

View file

@ -24,6 +24,8 @@ export const matchCheckboxPropertyFilter = (
return propertyValue === null;
default:
throw new Error(`CheckboxFilterCondition not supported: ${condition}`);
throw new Error(
`CheckboxFilterCondition not supported: ${condition}`
);
}
}
};

View file

@ -3,12 +3,24 @@ import { ContentFilterCondition } from "src/types";
export const matchContentFilter = (
content: string,
compare: string,
condition: ContentFilterCondition,
condition: ContentFilterCondition
): boolean => {
console.assert(content === content.toLowerCase(), `ContentFilter content "${content}" must be lowercase`);
console.assert(/^\s/.test(content) === false, `ContentFilter content "${content}" must not contain whitespace`);
console.assert(compare === compare.toLowerCase(), `ContentFilter compare "${compare}" must be lowercase`);
console.assert(/\s$/.test(compare) === false, `ContentFilter compare "${compare}" must not contain whitespace`);
console.assert(
content === content.toLowerCase(),
`ContentFilter content "${content}" must be lowercase`
);
console.assert(
/^\s/.test(content) === false,
`ContentFilter content "${content}" must not contain whitespace`
);
console.assert(
compare === compare.toLowerCase(),
`ContentFilter compare "${compare}" must be lowercase`
);
console.assert(
/\s$/.test(compare) === false,
`ContentFilter compare "${compare}" must not contain whitespace`
);
switch (condition) {
case ContentFilterCondition.CONTAINS:
@ -24,6 +36,8 @@ export const matchContentFilter = (
return content !== "";
default:
throw new Error(`ContentFilterCondition not supported: ${condition}`);
throw new Error(
`ContentFilterCondition not supported: ${condition}`
);
}
};

View file

@ -1,4 +1,7 @@
import { getMomentDate, isDateSupported } from "src/svelte/shared/services/time-utils";
import {
getMomentDate,
isDateSupported
} from "src/svelte/shared/services/time-utils";
import { DateFilterCondition } from "src/types";
export const matchDatePropertyFilter = (
@ -8,9 +11,15 @@ export const matchDatePropertyFilter = (
matchIfNull: boolean
) => {
if (propertyValue) {
console.assert(isDateSupported(propertyValue), `DatePropertyFilter propertyValue "${propertyValue}" must be supported date format`);
console.assert(
isDateSupported(propertyValue),
`DatePropertyFilter propertyValue "${propertyValue}" must be supported date format`
);
}
console.assert(isDateSupported(compare), `DatePropertyFilter compare "${compare}" must be supported date format`);
console.assert(
isDateSupported(compare),
`DatePropertyFilter compare "${compare}" must be supported date format`
);
switch (condition) {
case DateFilterCondition.IS: {
@ -34,10 +43,12 @@ export const matchDatePropertyFilter = (
const propertyValueDate = getMomentDate(propertyValue);
const compareDate = getMomentDate(compare);
return propertyValueDate.isAfter(compareDate, "day") || propertyValueDate.isSame(compareDate, "day");
return (
propertyValueDate.isAfter(compareDate, "day") ||
propertyValueDate.isSame(compareDate, "day")
);
}
case DateFilterCondition.IS_BEFORE: {
if (propertyValue === null) return matchIfNull;
@ -51,7 +62,10 @@ export const matchDatePropertyFilter = (
const propertyValueDate = getMomentDate(propertyValue);
const compareDate = getMomentDate(compare);
return propertyValueDate.isBefore(compareDate, "day") || propertyValueDate.isSame(compareDate, "day");
return (
propertyValueDate.isBefore(compareDate, "day") ||
propertyValueDate.isSame(compareDate, "day")
);
}
case DateFilterCondition.EXISTS:
@ -63,4 +77,4 @@ export const matchDatePropertyFilter = (
default:
throw new Error(`DateFilterCondition not supported: ${condition}`);
}
}
};

View file

@ -3,13 +3,25 @@ import { FileNameFilterCondition } from "src/types";
export const matchFileNameFilter = (
fileName: string,
compare: string,
condition: FileNameFilterCondition,
condition: FileNameFilterCondition
): boolean => {
console.assert(fileName === fileName.toLowerCase(), `FileNameFilter fileName "${fileName}" must be lowercase`);
console.assert(/^\s/.test(fileName) === false, `FileNameFilter fileName "${fileName}" must not contain whitespace`);
console.assert(
fileName === fileName.toLowerCase(),
`FileNameFilter fileName "${fileName}" must be lowercase`
);
console.assert(
/^\s/.test(fileName) === false,
`FileNameFilter fileName "${fileName}" must not contain whitespace`
);
console.assert(compare === compare.toLowerCase(), `FileNameFilter compare "${compare}" must be lowercase`);
console.assert(/\s$/.test(compare) === false, `FileNameFilter compare "${compare}" must not contain whitespace`);
console.assert(
compare === compare.toLowerCase(),
`FileNameFilter compare "${compare}" must be lowercase`
);
console.assert(
/\s$/.test(compare) === false,
`FileNameFilter compare "${compare}" must not contain whitespace`
);
switch (condition) {
case FileNameFilterCondition.IS:
@ -33,6 +45,8 @@ export const matchFileNameFilter = (
return fileName.endsWith(compare);
default:
throw new Error(`FileNameFilterCondition not supported: ${condition}`);
throw new Error(
`FileNameFilterCondition not supported: ${condition}`
);
}
};

View file

@ -8,10 +8,22 @@ export const matchFolderFilter = (
includeSubfolders: boolean;
}
): boolean => {
console.assert(filePath === filePath.toLowerCase(), `FolderFilter filePath "${filePath}" must be lowercase`);
console.assert(/^\s/.test(filePath) === false, `FolderFilter filePath "${filePath}" must not contain whitespace`);
console.assert(compare === compare.toLowerCase(), `FolderFilter compare "${compare}" must be lowercase`);
console.assert(/\s$/.test(compare) === false, `FolderFilter compare "${compare}" must not contain whitespace`);
console.assert(
filePath === filePath.toLowerCase(),
`FolderFilter filePath "${filePath}" must be lowercase`
);
console.assert(
/^\s/.test(filePath) === false,
`FolderFilter filePath "${filePath}" must not contain whitespace`
);
console.assert(
compare === compare.toLowerCase(),
`FolderFilter compare "${compare}" must be lowercase`
);
console.assert(
/\s$/.test(compare) === false,
`FolderFilter compare "${compare}" must not contain whitespace`
);
if (compare === "/") {
return true;
@ -31,6 +43,8 @@ export const matchFolderFilter = (
return filePath !== compare;
default:
throw new Error(`FolderFilterCondition not supported: ${condition}`);
throw new Error(
`FolderFilterCondition not supported: ${condition}`
);
}
};

View file

@ -7,14 +7,35 @@ export const matchListPropertyFilter = (
matchIfNull: boolean
) => {
if (propertyValue) {
console.assert(propertyValue.every(value => value.length > 0), `ListPropertyFilter propertyValue "${propertyValue}" must not contain empty strings`);
console.assert(propertyValue.every(value => value === value.toLowerCase()), `ListPropertyFilter propertyValue "${propertyValue}" must be lowercase`);
console.assert(propertyValue.every(value => /^\s/.test(value) === false), `ListPropertyFilter propertyValue "${propertyValue}" must not contain whitespace`);
console.assert(propertyValue.every(value => /\s$/.test(value) === false), `ListPropertyFilter propertyValue "${propertyValue}" must not contain whitespace`);
console.assert(
propertyValue.every((value) => value.length > 0),
`ListPropertyFilter propertyValue "${propertyValue}" must not contain empty strings`
);
console.assert(
propertyValue.every((value) => value === value.toLowerCase()),
`ListPropertyFilter propertyValue "${propertyValue}" must be lowercase`
);
console.assert(
propertyValue.every((value) => /^\s/.test(value) === false),
`ListPropertyFilter propertyValue "${propertyValue}" must not contain whitespace`
);
console.assert(
propertyValue.every((value) => /\s$/.test(value) === false),
`ListPropertyFilter propertyValue "${propertyValue}" must not contain whitespace`
);
}
console.assert(compare.every(value => value === value.toLowerCase()), `ListPropertyFilter compare "${compare}" must be lowercase`);
console.assert(compare.every(value => /^\s/.test(value) === false), `ListPropertyFilter compare "${compare}" must not contain whitespace`);
console.assert(compare.every(value => /\s$/.test(value) === false), `ListPropertyFilter compare "${compare}" must not contain whitespace`);
console.assert(
compare.every((value) => value === value.toLowerCase()),
`ListPropertyFilter compare "${compare}" must be lowercase`
);
console.assert(
compare.every((value) => /^\s/.test(value) === false),
`ListPropertyFilter compare "${compare}" must not contain whitespace`
);
console.assert(
compare.every((value) => /\s$/.test(value) === false),
`ListPropertyFilter compare "${compare}" must not contain whitespace`
);
switch (condition) {
case ListFilterCondition.CONTAINS:
@ -38,4 +59,4 @@ export const matchListPropertyFilter = (
default:
throw new Error(`ListFilterCondition not supported: ${condition}`);
}
}
};

View file

@ -44,6 +44,8 @@ export const matchNumberPropertyFilter = (
return propertyValue === null;
default:
throw new Error(`NumberFilterCondition not supported: ${condition}`);
throw new Error(
`NumberFilterCondition not supported: ${condition}`
);
}
};

View file

@ -7,13 +7,31 @@ export const matchTextPropertyFilter = (
matchIfNull: boolean
): boolean => {
if (propertyValue) {
console.assert(propertyValue === propertyValue.toLowerCase(), `TextFilter propertyValue "${propertyValue}" must be lowercase`);
console.assert(/^\s/.test(propertyValue) === false, `TextFilter propertyValue "${propertyValue}" must not contain whitespace`);
console.assert(/\s$/.test(propertyValue) === false, `TextFilter propertyValue "${propertyValue}" must not contain whitespace`);
console.assert(
propertyValue === propertyValue.toLowerCase(),
`TextFilter propertyValue "${propertyValue}" must be lowercase`
);
console.assert(
/^\s/.test(propertyValue) === false,
`TextFilter propertyValue "${propertyValue}" must not contain whitespace`
);
console.assert(
/\s$/.test(propertyValue) === false,
`TextFilter propertyValue "${propertyValue}" must not contain whitespace`
);
}
console.assert(compare === compare.toLowerCase(), `TextFilter compare "${compare}" must be lowercase`);
console.assert(/^\s/.test(compare) === false, `TextFilter compare "${compare}" must not contain whitespace`);
console.assert(/\s$/.test(compare) === false, `TextFilter compare "${compare}" must not contain whitespace`);
console.assert(
compare === compare.toLowerCase(),
`TextFilter compare "${compare}" must be lowercase`
);
console.assert(
/^\s/.test(compare) === false,
`TextFilter compare "${compare}" must not contain whitespace`
);
console.assert(
/\s$/.test(compare) === false,
`TextFilter compare "${compare}" must not contain whitespace`
);
switch (condition) {
case TextFilterCondition.IS:

View file

@ -1,4 +1,4 @@
import { FileRenderData } from "../../types";
import type { FileRenderData } from "../../types";
//TODO add tests
export const filterBySearch = (file: FileRenderData, value: string) => {

View file

@ -1,6 +1,6 @@
import {
EXTERNAL_EMBED_REGEX as EXTERNAL_EMBED_REGEX,
INTERNAL_EMBED_REGEX,
INTERNAL_EMBED_REGEX
} from "./constants";
export const getFirstInternalEmbed = (content: string) => {

View file

@ -1,7 +1,7 @@
import {
WIKI_LINK_REGEX,
INTERNAL_EMBED_REGEX,
EXTERNAL_EMBED_REGEX,
EXTERNAL_EMBED_REGEX
} from "./constants";
export const getWikiLinkTarget = (value: string) => {

View file

@ -2,7 +2,7 @@ import {
INTERNAL_EMBED_REGEX,
EXTERNAL_EMBED_REGEX,
URL_REGEX,
WIKI_LINK_REGEX,
WIKI_LINK_REGEX
} from "./constants";
export const isInternalEmbed = (value: string) => {

View file

@ -14,7 +14,7 @@ export const openInCurrentTab = (
plugin.app.workspace.setActiveLeaf(leaf);
} else {
plugin.app.workspace.openLinkText("", filePath, "tab", {
active: true,
active: true
});
}
};

View file

@ -1,5 +1,5 @@
import Logger from "js-logger";
import { App } from "obsidian";
import type { App } from "obsidian";
import { writable } from "svelte/store";
export type RandomFileSortCache = Map<string, number>;
@ -11,7 +11,7 @@ function createRandomFileSortStore() {
Logger.trace({
fileName: "random-file-sort-store.ts",
functionName: "load",
message: "called",
message: "called"
});
const files = app.vault.getFiles();
@ -59,7 +59,7 @@ function createRandomFileSortStore() {
subscribe,
onFileCreate: handleFileCreate,
onFileRename: handleFileRename,
onFileDelete: handleFileDelete,
onFileDelete: handleFileDelete
};
}

View file

@ -1,33 +1,33 @@
import { App, FrontMatterCache, TFile } from "obsidian";
import {
CoverImageFit,
PropertyType,
VaultExplorerPluginSettings,
} from "src/types";
import { FileRenderData } from "../types";
import Logger from "js-logger";
import { App, type FrontMatterCache, TFile } from "obsidian";
import {
FileTextProperties,
type FileTextProperties,
loadPropertyValue,
loadTextProperties,
loadTextProperties
} from "src/svelte/shared/services/load-property-value";
import {
isDateSupported,
getTimeMillis,
isDateSupported
} from "src/svelte/shared/services/time-utils";
import { isImageExtension } from "./utils/image-utils";
import { removeFrontmatter } from "./utils/content-utils";
import { getURIForWikiLinkTarget } from "./utils/wiki-link-utils";
import { isUrl, isWikiLink } from "./link-utils/link-validators";
import {
type CoverImageFit,
PropertyType,
type VaultExplorerPluginSettings
} from "src/types";
import type { FileRenderData } from "../types";
import {
getFirstExternalEmbed,
getFirstInternalEmbed
} from "./link-utils/link-getters";
import {
getExternalEmbedTarget,
getInternalEmbedTarget,
getWikiLinkTarget,
getWikiLinkTarget
} from "./link-utils/link-target-getters";
import {
getFirstExternalEmbed,
getFirstInternalEmbed,
} from "./link-utils/link-getters";
import { isUrl, isWikiLink } from "./link-utils/link-validators";
import { removeFrontmatter } from "./utils/content-utils";
import { isImageExtension } from "./utils/image-utils";
import { getURIForWikiLinkTarget } from "./utils/wiki-link-utils";
/**
* Formats the file's data for rendering
@ -45,7 +45,7 @@ export const formatFileDataForRender = ({
settings,
file,
fileId,
fileContent,
fileContent
}: {
app: App;
settings: VaultExplorerPluginSettings;
@ -67,7 +67,7 @@ export const formatFileDataForRender = ({
coverImageFit: coverImageFitProp,
custom1: custom1Prop,
custom2: custom2Prop,
custom3: custom3Prop,
custom3: custom3Prop
} = settings.properties;
let tags: string[] | null = loadPropertyValue<string[]>(
@ -240,7 +240,7 @@ export const formatFileDataForRender = ({
modifiedMillis,
custom1,
custom2,
custom3,
custom3
};
};

View file

@ -1,4 +1,4 @@
import { DBSchema, openDB } from "idb";
import { type DBSchema, openDB } from "idb";
import Logger from "js-logger";
import { Notice } from "obsidian";
@ -31,17 +31,17 @@ export const getSMICacheEntry = async (websiteUrl: string) => {
Logger.trace({
fileName: "smi-cache.ts",
functionName: "getSMICacheEntry",
message: "called",
message: "called"
});
Logger.debug(
{
fileName: "grid-card.svelte",
functionName: "getCachedSocialMediaUrl",
message: "getting cached entry",
message: "getting cached entry"
},
{
websiteUrl,
websiteUrl
}
);
const db = await openDatabase();
@ -58,18 +58,18 @@ export const putSMICacheEntry = async (url: string, smiUrl: string | null) => {
Logger.trace({
fileName: "smi-cache.ts",
functionName: "putSMICacheEntry",
message: "called",
message: "called"
});
Logger.debug(
{
fileName: "smi-cache.ts",
functionName: "putSMICacheEntry",
message: "putting entry",
message: "putting entry"
},
{
url,
smiUrl,
smiUrl
}
);
@ -77,7 +77,7 @@ export const putSMICacheEntry = async (url: string, smiUrl: string | null) => {
await db.put(STORE_NAME, {
url,
smiUrl,
timestamp: Date.now(),
timestamp: Date.now()
});
};
@ -85,7 +85,7 @@ export const clearSMICache = async () => {
Logger.trace({
fileName: "smi-cache.ts",
functionName: "clearSMICache",
message: "called",
message: "called"
});
try {
const db = await openDatabase();
@ -98,7 +98,7 @@ export const clearSMICache = async () => {
{
fileName: "smi-cache.ts",
functionName: "clearSMICache",
message: "failed to clear cache",
message: "failed to clear cache"
},
error.message
);
@ -109,6 +109,6 @@ const openDatabase = () => {
return openDB<SocialMediaImageDB>(DATABASE_NAME, 1, {
upgrade(db) {
db.createObjectStore(STORE_NAME, { keyPath: "url" });
},
}
});
};

View file

@ -1,4 +1,6 @@
import { moment } from "obsidian";
import { moment as _moment } from "obsidian";
const moment = _moment as unknown as typeof _moment.default;
export const formatAsBearTimeString = (milliseconds: number) => {
const now = moment();

View file

@ -6,7 +6,7 @@ const IMAGE_EXTENSIONS = [
"webp",
"svg",
"avif",
"bmp",
"bmp"
];
export const isImageExtension = (extension: string) => {

View file

@ -7,7 +7,7 @@ export const parseItems = <T>(rawData: string): T[] => {
export const stringifyItems = (items: unknown[]) => {
return JSON.stringify(
{
items,
items
},
null,
2

View file

@ -1,4 +1,4 @@
import { CoverImageFit } from "src/types";
import type { CoverImageFit } from "src/types";
export interface FileRenderData {
id: string;

View file

@ -1,8 +1,8 @@
<script lang="ts">
import {
ContentFilterCondition,
FilterCondition,
FilterOperator,
type FilterCondition,
type FilterOperator,
FilterRuleType,
} from "src/types";
import FilterRule from "./filter-rule.svelte";
@ -16,19 +16,8 @@
export let isEnabled: boolean;
import { createEventDispatcher } from "svelte";
import License from "src/svelte/shared/services/license";
import PremiumLink from "src/svelte/shared/components/premium-link.svelte";
import PremiumMessage from "src/svelte/shared/components/premium-message.svelte";
const dispatch = createEventDispatcher();
let hasValidLicenseKey = false;
License.getInstance()
.getHasValidKeyStore()
.subscribe((hasValidKey) => {
hasValidLicenseKey = hasValidKey;
});
function handleValueChange(e: Event) {
const value = (e.target as HTMLInputElement).value;
dispatch("ruleValueChange", { id, value });
@ -54,21 +43,12 @@
{#if condition !== ContentFilterCondition.IS_EMPTY && condition !== ContentFilterCondition.IS_NOT_EMPTY}
<input
type="text"
disabled={!hasValidLicenseKey}
placeholder="value"
{value}
on:input={handleValueChange}
/>
{/if}
</svelte:fragment>
<svelte:fragment slot="after-toggle">
{#if type === FilterRuleType.CONTENT && !hasValidLicenseKey}
<div>
<PremiumMessage />
<PremiumLink />
</div>
{/if}
</svelte:fragment>
</FilterRule>
<style>

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { FilterCondition, FilterOperator, FilterRuleType } from "src/types";
import { type FilterCondition, type FilterOperator, FilterRuleType } from "src/types";
import FilterRule from "./filter-rule.svelte";
export let index: number;

View file

@ -1,10 +1,10 @@
<script lang="ts">
import Stack from "src/svelte/shared/components/stack.svelte";
import PropertyFilter from "./property-filter.svelte";
import { TFilterRule, FilterRuleType, PropertyType } from "src/types";
import { type TFilterRule, FilterRuleType, PropertyType } from "src/types";
import ContentFilter from "./content-filter.svelte";
import FolderFilter from "./folder-filter.svelte";
import FileNameFilter from "./file-name-filter.svelte";
import FolderFilter from "./folder-filter.svelte";
import PropertyFilter from "./property-filter.svelte";
export let rules: TFilterRule[] = [];
</script>

View file

@ -1,25 +1,24 @@
<script lang="ts">
import { Menu } from "obsidian";
import IconButton from "src/svelte/shared/components/icon-button.svelte";
import Stack from "src/svelte/shared/components/stack.svelte";
import Switch from "src/svelte/shared/components/switch.svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import {
CheckboxFilterCondition,
ContentFilterCondition,
DateFilterCondition,
FilterCondition,
FilterOperator,
ListFilterCondition,
NumberFilterCondition,
TextFilterCondition,
PropertyType,
FileNameFilterCondition,
type FilterCondition,
type FilterOperator,
FilterRuleType,
FolderFilterCondition,
FileNameFilterCondition,
ContentFilterCondition,
ListFilterCondition,
NumberFilterCondition,
PropertyType,
TextFilterCondition,
} from "src/types";
import { createEventDispatcher } from "svelte";
import Wrap from "src/svelte/shared/components/wrap.svelte";
import License from "src/svelte/shared/services/license";
import { Menu } from "obsidian";
import {
getDisplayNameForFilterCondition,
getDisplayNameForFilterRuleType,
@ -33,16 +32,8 @@
export let condition: FilterCondition;
export let isEnabled: boolean;
let hasValidLicenseKey = false;
const dispatch = createEventDispatcher();
License.getInstance()
.getHasValidKeyStore()
.subscribe((hasValidKey) => {
hasValidLicenseKey = hasValidKey;
});
function handleActionsClick(e: CustomEvent) {
const nativeEvent = e.detail.nativeEvent as MouseEvent;
@ -141,11 +132,7 @@
{/each}
</select>
<slot name="before-condition"></slot>
<select
disabled={type === FilterRuleType.CONTENT && !hasValidLicenseKey}
value={condition}
on:change={handleConditionChange}
>
<select value={condition} on:change={handleConditionChange}>
{#each filterConditions as condition}
<option value={condition}>
{getDisplayNameForFilterCondition(condition)}

Some files were not shown because too many files have changed in this diff Show more