mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
Add cover image fit (#310)
* chore: bump version * feat: add cover image fit setting * feat: render cover image * feat: add cover image to context menu * refactor: add default fit into description * fix: only show cover image options for markdown files
This commit is contained in:
parent
0c22fe5ca6
commit
2bf5c1302c
18 changed files with 545 additions and 13 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "vault-explorer",
|
||||
"name": "Vault Explorer",
|
||||
"version": "1.40.2",
|
||||
"version": "1.41.0",
|
||||
"minAppVersion": "1.4.13",
|
||||
"description": "Explore your vault in visual format",
|
||||
"author": "DecafDev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-vault-explorer",
|
||||
"version": "1.40.2",
|
||||
"version": "1.41.0",
|
||||
"description": "Explore your vault in visual format",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
|||
favorite: "",
|
||||
url: "",
|
||||
image: "",
|
||||
coverImageFit: "",
|
||||
createdDate: "",
|
||||
modifiedDate: "",
|
||||
custom1: "",
|
||||
|
|
@ -45,6 +46,7 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
|||
},
|
||||
grid: {
|
||||
isEnabled: true,
|
||||
coverImageFit: "cover",
|
||||
coverImageSources: [
|
||||
{
|
||||
type: "image-property",
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export enum PluginEvent {
|
|||
FOLDER_DELETE = "folder-delete",
|
||||
FOLDER_CREATE = "folder-create",
|
||||
PAGE_SIZE_SETTING_CHANGE = "page-size-setting-change",
|
||||
COVER_IMAGE_FIT_SETTING_CHANGE = "cover-image-fit-setting-change",
|
||||
FEED_CONTENT_SETTING_CHANGE = "feed-content-setting-change",
|
||||
COVER_IMAGE_SOURCE_SETTING_CHANGE = "cover-image-source-setting-change",
|
||||
PROPERTY_SETTING_CHANGE = "property-setting-change",
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import Migrate_1_37_0 from "./migrate_1_37_0";
|
|||
import Migrate_1_38_0 from "./migrate_1_38_0";
|
||||
import Migrate_1_39_0 from "./migrate_1_39_0";
|
||||
import Migrate_1_40_0 from "./migrate_1_40_0";
|
||||
import Migrate_1_41_0 from "./migrate_1_41_0";
|
||||
|
||||
const migrations: TMigration[] = [
|
||||
{
|
||||
|
|
@ -177,6 +178,11 @@ const migrations: TMigration[] = [
|
|||
to: "1.40.0",
|
||||
migrate: Migrate_1_40_0,
|
||||
},
|
||||
{
|
||||
from: "1.40.2",
|
||||
to: "1.41.0",
|
||||
migrate: Migrate_1_41_0,
|
||||
},
|
||||
];
|
||||
|
||||
export const preformMigrations = (
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import MigrationInterface from "./migration_interface";
|
||||
import { VaultExplorerPluginSettings_1_39_0 } from "src/types/types-1.39.0";
|
||||
import { VaultExplorerPluginSettings } from "src/types";
|
||||
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 = {
|
||||
const newData: VaultExplorerPluginSettings_1_40_2 = {
|
||||
...typedData,
|
||||
shouldCollapseFilters: false,
|
||||
};
|
||||
|
|
|
|||
25
src/migrations/migrate_1_41_0.ts
Normal file
25
src/migrations/migrate_1_41_0.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { VaultExplorerPluginSettings } from "src/types";
|
||||
import MigrationInterface from "./migration_interface";
|
||||
import { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2";
|
||||
|
||||
export default class Migrate_1_41_0 implements MigrationInterface {
|
||||
migrate(data: Record<string, unknown>) {
|
||||
const typedData = data as unknown as VaultExplorerPluginSettings_1_40_2;
|
||||
const newData: VaultExplorerPluginSettings = {
|
||||
...typedData,
|
||||
properties: {
|
||||
...typedData.properties,
|
||||
coverImageFit: "",
|
||||
},
|
||||
views: {
|
||||
...typedData.views,
|
||||
grid: {
|
||||
...typedData.views.grid,
|
||||
coverImageFit: "cover",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return newData as unknown as Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from "src/logger/constants";
|
||||
import Logger from "js-logger";
|
||||
import { stringToLogLevel } from "src/logger";
|
||||
import { CollapseStyle, TExplorerView } from "src/types";
|
||||
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";
|
||||
|
|
@ -312,6 +312,26 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Cover image fit")
|
||||
.setDesc("Set the default cover image fit")
|
||||
.addDropdown((cb) =>
|
||||
cb
|
||||
.addOptions({
|
||||
cover: "Cover",
|
||||
contain: "Contain",
|
||||
})
|
||||
.setValue(this.plugin.settings.views.grid.coverImageFit)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.views.grid.coverImageFit =
|
||||
value as CoverImageFit;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl).setName("List view").setHeading();
|
||||
|
||||
new Setting(containerEl)
|
||||
|
|
@ -443,9 +463,9 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Image property")
|
||||
.setName("Cover image property")
|
||||
.setDesc(
|
||||
"Property used to store an image. This must be a text property."
|
||||
"Property used to store a cover image. This must be a text property."
|
||||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
|
|
@ -460,6 +480,24 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Cover image fit property")
|
||||
.setDesc(
|
||||
"Property used to store the cover image fit. This must be a text property."
|
||||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOptions(getDropdownOptionsForProperties(textProperties))
|
||||
.setValue(this.plugin.settings.properties.coverImageFit)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.properties.coverImageFit = value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.PROPERTY_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("URL property")
|
||||
.setDesc(
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
isSocialMediaImageEntryExpired,
|
||||
putSocialMediaImageUrl,
|
||||
} from "../services/social-media-image-cache";
|
||||
import { CoverImageFit } from "src/types";
|
||||
|
||||
export let displayName: string;
|
||||
export let path: string;
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
export let custom2: string | null;
|
||||
export let custom3: string | null;
|
||||
export let isFavorite: boolean | null;
|
||||
export let coverImageFit: CoverImageFit;
|
||||
|
||||
let plugin: VaultExplorerPlugin;
|
||||
let enableFileIcons: boolean = false;
|
||||
|
|
@ -136,11 +138,21 @@
|
|||
dispatch("favoritePropertyChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleCoverImageFitChange(filePath: string, value: CoverImageFit) {
|
||||
dispatch("coverImageFitChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleCardContextMenu(e: Event) {
|
||||
const nativeEvent = e as MouseEvent;
|
||||
|
||||
const showCoverImageOptions = path.endsWith(".md");
|
||||
openContextMenu(plugin, path, nativeEvent, {
|
||||
isFavorite,
|
||||
coverImageFit: showCoverImageOptions ? coverImageFit : undefined,
|
||||
onFavoriteChange: handleFavoriteChange,
|
||||
onCoverImageFitChange: showCoverImageOptions
|
||||
? handleCoverImageFitChange
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +220,9 @@
|
|||
<img
|
||||
class="vault-explorer-grid-card__image"
|
||||
src={imgSrc}
|
||||
style="display: {isCoverImageLoaded ? 'block' : 'none'};"
|
||||
style="display: {isCoverImageLoaded
|
||||
? 'block'
|
||||
: 'none'}; object-fit: {coverImageFit};"
|
||||
on:load={handleImageLoad}
|
||||
on:error={handleImageError}
|
||||
/>
|
||||
|
|
@ -335,7 +349,6 @@
|
|||
.vault-explorer-grid-card__image {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
object-fit: cover;
|
||||
border-top-left-radius: var(--radius-m);
|
||||
border-top-right-radius: var(--radius-m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
<GridCard
|
||||
displayName={fileRenderData.displayName}
|
||||
path={fileRenderData.path}
|
||||
coverImageFit={fileRenderData.coverImageFit}
|
||||
baseName={fileRenderData.baseName}
|
||||
extension={fileRenderData.extension}
|
||||
imageUrl={fileRenderData.imageUrl}
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
custom3={fileRenderData.custom3}
|
||||
isFavorite={fileRenderData.isFavorite}
|
||||
on:favoritePropertyChange
|
||||
on:coverImageFitChange
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
TSortFilter,
|
||||
TTimestampFilter,
|
||||
TExplorerView,
|
||||
CoverImageFit,
|
||||
} from "src/types";
|
||||
import store from "../shared/services/store";
|
||||
import VaultExplorerPlugin from "src/main";
|
||||
|
|
@ -104,6 +105,7 @@
|
|||
let frontmatterCacheTime: number = Date.now();
|
||||
let propertySettingsTime: number = Date.now();
|
||||
let coverImageSourcesTime: number = Date.now();
|
||||
let coverImageFitTime: number = Date.now();
|
||||
let loadBodyTagsTime: number = Date.now();
|
||||
|
||||
let loadedFiles: LoadedFile[] = [];
|
||||
|
|
@ -471,6 +473,29 @@
|
|||
};
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
function handleCoverImageFitSettingChange() {
|
||||
Logger.trace({
|
||||
fileName: "app/index.svelte",
|
||||
functionName: "handleCoverImageFitSettingChange",
|
||||
message: "called",
|
||||
});
|
||||
|
||||
coverImageFitTime = Date.now();
|
||||
}
|
||||
|
||||
EventManager.getInstance().on(
|
||||
PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE,
|
||||
handleCoverImageFitSettingChange,
|
||||
);
|
||||
return () => {
|
||||
EventManager.getInstance().off(
|
||||
PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE,
|
||||
handleCoverImageFitSettingChange,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
function handleCoverImageSourceSettingChange() {
|
||||
Logger.trace({
|
||||
|
|
@ -759,6 +784,43 @@
|
|||
debounceFavoriteFilterChange(value);
|
||||
}
|
||||
|
||||
function handleCoverImageFitChange(e: CustomEvent) {
|
||||
const { filePath, value } = e.detail as {
|
||||
filePath: string;
|
||||
value: CoverImageFit;
|
||||
};
|
||||
|
||||
console.log(filePath, value);
|
||||
|
||||
const { properties } = plugin.settings;
|
||||
const { coverImageFit: coverImageFitProperty } = properties;
|
||||
|
||||
//If the favorite property is not set, return
|
||||
if (coverImageFitProperty === "") {
|
||||
new Notice(
|
||||
"Vault Explorer: Please set a cover image fit property in the plugin settings to use this feature",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const file = plugin.app.vault.getFileByPath(filePath);
|
||||
if (!file) {
|
||||
Logger.error({
|
||||
fileName: "app/index.svelte",
|
||||
functionName: "handleCoverImageFitChange",
|
||||
message: "file not found. returning...",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.extension === "md") {
|
||||
plugin.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
frontmatter[coverImageFitProperty] = value;
|
||||
return frontmatter;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleFavoritePropertyChange(e: CustomEvent) {
|
||||
const { filePath, value } = e.detail as {
|
||||
filePath: string;
|
||||
|
|
@ -771,7 +833,7 @@
|
|||
//If the favorite property is not set, return
|
||||
if (favoritePropertyName === "") {
|
||||
new Notice(
|
||||
"Please select a favorite property in the Vault Explorer settings to use this feature",
|
||||
"Vault Explorer: Please set a favorite property in the plugin settings to use this feature",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -827,7 +889,12 @@
|
|||
}
|
||||
|
||||
let formatted: FileRenderData[] = [];
|
||||
$: if (propertySettingsTime || coverImageSourcesTime || loadBodyTagsTime) {
|
||||
$: if (
|
||||
propertySettingsTime ||
|
||||
coverImageSourcesTime ||
|
||||
loadBodyTagsTime ||
|
||||
coverImageFitTime
|
||||
) {
|
||||
formatted = filteredCustom.map((loadedFile) => {
|
||||
const { id, file } = loadedFile;
|
||||
const frontmatter =
|
||||
|
|
@ -1047,6 +1114,7 @@
|
|||
{startIndex}
|
||||
{pageLength}
|
||||
on:favoritePropertyChange={handleFavoritePropertyChange}
|
||||
on:coverImageFitChange={handleCoverImageFitChange}
|
||||
/>
|
||||
{:else if currentView === "list"}
|
||||
<ListView
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Menu } from "obsidian";
|
||||
import VaultExplorerPlugin from "src/main";
|
||||
import { CoverImageFit } from "src/types";
|
||||
|
||||
export const openContextMenu = (
|
||||
plugin: VaultExplorerPlugin,
|
||||
|
|
@ -7,10 +8,17 @@ export const openContextMenu = (
|
|||
e: MouseEvent,
|
||||
{
|
||||
isFavorite,
|
||||
coverImageFit,
|
||||
onFavoriteChange,
|
||||
onCoverImageFitChange,
|
||||
}: {
|
||||
isFavorite: boolean | null;
|
||||
coverImageFit?: CoverImageFit;
|
||||
onFavoriteChange: (filePath: string, value: boolean) => void;
|
||||
onCoverImageFitChange?: (
|
||||
filePath: string,
|
||||
value: CoverImageFit
|
||||
) => void;
|
||||
}
|
||||
) => {
|
||||
const menu = new Menu();
|
||||
|
|
@ -37,6 +45,19 @@ export const openContextMenu = (
|
|||
onFavoriteChange(filePath, newValue);
|
||||
});
|
||||
});
|
||||
if (coverImageFit !== undefined && onCoverImageFitChange !== undefined) {
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Cover image fit: cover");
|
||||
item.setChecked(coverImageFit === "cover");
|
||||
item.onClick(() => onCoverImageFitChange(filePath, "cover"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Cover image fit: contain");
|
||||
item.setChecked(coverImageFit === "contain");
|
||||
item.onClick(() => onCoverImageFitChange(filePath, "contain"));
|
||||
});
|
||||
}
|
||||
menu.showAtMouseEvent(e);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { App, FrontMatterCache, TFile } from "obsidian";
|
||||
import { PropertyType, VaultExplorerPluginSettings } from "src/types";
|
||||
import {
|
||||
CoverImageFit,
|
||||
PropertyType,
|
||||
VaultExplorerPluginSettings,
|
||||
} from "src/types";
|
||||
import { FileRenderData } from "../types";
|
||||
import Logger from "js-logger";
|
||||
import {
|
||||
|
|
@ -62,6 +66,7 @@ export const formatFileDataForRender = ({
|
|||
modifiedDate: modifiedDateProp,
|
||||
url: urlProp,
|
||||
image: imageProp,
|
||||
coverImageFit: coverImageFitProp,
|
||||
favorite: favoriteProp,
|
||||
custom1: custom1Prop,
|
||||
custom2: custom2Prop,
|
||||
|
|
@ -103,6 +108,15 @@ export const formatFileDataForRender = ({
|
|||
isFavorite = fileFavorite;
|
||||
}
|
||||
|
||||
let coverImageFit: CoverImageFit | null = loadPropertyValue<string>(
|
||||
fileFrontmatter,
|
||||
coverImageFitProp,
|
||||
PropertyType.TEXT
|
||||
) as CoverImageFit | null;
|
||||
if (coverImageFit === null) {
|
||||
coverImageFit = settings.views.grid.coverImageFit;
|
||||
}
|
||||
|
||||
const creationDate: string | null = loadPropertyValue<string>(
|
||||
fileFrontmatter,
|
||||
createdDateProp,
|
||||
|
|
@ -230,6 +244,7 @@ export const formatFileDataForRender = ({
|
|||
displayName,
|
||||
path,
|
||||
baseName: basename,
|
||||
coverImageFit,
|
||||
basePath,
|
||||
extension,
|
||||
url,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { CoverImageFit } from "src/types";
|
||||
|
||||
export interface FileRenderData {
|
||||
id: string;
|
||||
displayName: string;
|
||||
|
|
@ -5,6 +7,7 @@ export interface FileRenderData {
|
|||
basePath: string;
|
||||
extension: string;
|
||||
baseName: string;
|
||||
coverImageFit: CoverImageFit;
|
||||
content: string | null;
|
||||
url: string | null;
|
||||
imageUrl: string | null;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
typeof typedObj["properties"]["favorite"] === "string" &&
|
||||
typeof typedObj["properties"]["url"] === "string" &&
|
||||
typeof typedObj["properties"]["image"] === "string" &&
|
||||
typeof typedObj["properties"]["coverImageFit"] === "string" &&
|
||||
typeof typedObj["properties"]["createdDate"] === "string" &&
|
||||
typeof typedObj["properties"]["modifiedDate"] === "string" &&
|
||||
typeof typedObj["properties"]["custom1"] === "string" &&
|
||||
|
|
@ -606,6 +607,10 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
e["type"] === "body") &&
|
||||
typeof e["isEnabled"] === "boolean"
|
||||
) &&
|
||||
(typedObj["views"]["grid"]["coverImageFit"] === "cover" ||
|
||||
typedObj["views"]["grid"]["coverImageFit"] === "contain" ||
|
||||
typedObj["views"]["grid"]["coverImageFit"] === "scale-down" ||
|
||||
typedObj["views"]["grid"]["coverImageFit"] === "none") &&
|
||||
typeof typedObj["views"]["grid"]["loadSocialMediaImage"] === "boolean" &&
|
||||
(typedObj["views"]["list"] !== null &&
|
||||
typeof typedObj["views"]["list"] === "object" ||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export interface VaultExplorerPluginSettings {
|
|||
favorite: string;
|
||||
url: string;
|
||||
image: string;
|
||||
coverImageFit: string;
|
||||
createdDate: string;
|
||||
modifiedDate: string;
|
||||
custom1: string;
|
||||
|
|
@ -55,6 +56,7 @@ export interface TListView extends BaseView {
|
|||
|
||||
export interface TGridView extends BaseView {
|
||||
coverImageSources: CoverImageSource[];
|
||||
coverImageFit: CoverImageFit;
|
||||
loadSocialMediaImage: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +65,8 @@ export interface CoverImageSource {
|
|||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
export type CoverImageFit = "cover" | "contain";
|
||||
|
||||
export type CoverImageSourceType =
|
||||
| "image-property"
|
||||
| "url-property"
|
||||
|
|
|
|||
328
src/types/types-1.40.2.ts
Normal file
328
src/types/types-1.40.2.ts
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
export interface VaultExplorerPluginSettings_1_40_2 {
|
||||
properties: {
|
||||
favorite: string;
|
||||
url: string;
|
||||
image: string;
|
||||
createdDate: string;
|
||||
modifiedDate: string;
|
||||
custom1: string;
|
||||
custom2: string;
|
||||
custom3: string;
|
||||
};
|
||||
filters: {
|
||||
search: TSearchFilter;
|
||||
favorites: TFavoritesFilter;
|
||||
sort: TSortFilter;
|
||||
timestamp: TTimestampFilter;
|
||||
custom: TCustomFilter;
|
||||
};
|
||||
views: {
|
||||
dashboard: TDashboardView;
|
||||
grid: TGridView;
|
||||
list: TListView;
|
||||
table: TTableView;
|
||||
feed: TFeedView;
|
||||
recommended: TRecommendedView;
|
||||
related: TRelatedView;
|
||||
};
|
||||
titleWrapping: WordBreak;
|
||||
enableClockUpdates: boolean;
|
||||
enableFileIcons: boolean;
|
||||
loadBodyTags: boolean;
|
||||
currentView: TExplorerView | null;
|
||||
pageSize: number;
|
||||
filterGroupsWidth: string;
|
||||
shouldWrapFilterGroups: boolean;
|
||||
shouldCollapseFilters: boolean;
|
||||
viewOrder: TExplorerView[];
|
||||
configDir: string;
|
||||
pluginVersion: string | null;
|
||||
logLevel: string;
|
||||
}
|
||||
|
||||
type FileInteractionStyle = "title" | "content";
|
||||
|
||||
interface BaseView {
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
interface TTableView extends BaseView {}
|
||||
|
||||
interface TListView extends BaseView {
|
||||
showTags: boolean;
|
||||
}
|
||||
|
||||
interface TGridView extends BaseView {
|
||||
coverImageSources: CoverImageSource[];
|
||||
loadSocialMediaImage: boolean;
|
||||
}
|
||||
|
||||
interface CoverImageSource {
|
||||
type: CoverImageSourceType;
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
type CoverImageSourceType =
|
||||
| "image-property"
|
||||
| "url-property"
|
||||
| "frontmatter"
|
||||
| "body";
|
||||
|
||||
interface TDashboardView extends BaseView {}
|
||||
|
||||
type CollapseStyle = "no-new-lines" | "no-extra-new-lines";
|
||||
|
||||
interface TFeedView extends BaseView {
|
||||
collapseStyle: CollapseStyle;
|
||||
removeH1: boolean;
|
||||
lineClampSmall: number;
|
||||
lineClampMedium: number;
|
||||
lineClampLarge: number;
|
||||
}
|
||||
|
||||
interface TRecommendedView extends BaseView {}
|
||||
|
||||
interface TRelatedView extends BaseView {}
|
||||
|
||||
interface BaseFilter {
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
interface TSearchFilter extends BaseFilter {
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface TFavoritesFilter extends BaseFilter {
|
||||
value: boolean;
|
||||
}
|
||||
|
||||
interface TSortFilter extends BaseFilter {
|
||||
value: SortFilterOption;
|
||||
}
|
||||
|
||||
interface TTimestampFilter extends BaseFilter {
|
||||
value: TimestampFilterOption;
|
||||
}
|
||||
|
||||
interface TCustomFilter extends BaseFilter {
|
||||
selectedGroupId: string;
|
||||
groups: TFilterGroup[];
|
||||
}
|
||||
|
||||
type TimestampFilterOption =
|
||||
| "created-today"
|
||||
| "modified-today"
|
||||
| "created-this-week"
|
||||
| "modified-this-week"
|
||||
| "created-2-weeks"
|
||||
| "modified-2-weeks"
|
||||
| "all";
|
||||
|
||||
type SortFilterOption =
|
||||
| "file-name-asc"
|
||||
| "file-name-desc"
|
||||
| "modified-asc"
|
||||
| "modified-desc"
|
||||
| "random";
|
||||
|
||||
type WordBreak = "normal" | "break-word";
|
||||
|
||||
enum TExplorerView {
|
||||
DASHBOARD = "dashboard",
|
||||
GRID = "grid",
|
||||
LIST = "list",
|
||||
FEED = "feed",
|
||||
TABLE = "table",
|
||||
RECOMMENDED = "recommended",
|
||||
RELATED = "related",
|
||||
}
|
||||
|
||||
type FilterOperator = "and" | "or";
|
||||
|
||||
enum TextFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
STARTS_WITH = "starts-with",
|
||||
ENDS_WITH = "ends-with",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
enum ListFilterCondition {
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
enum NumberFilterCondition {
|
||||
IS_EQUAL = "is-equal",
|
||||
IS_NOT_EQUAL = "is-not-equal",
|
||||
IS_GREATER = "is-greater",
|
||||
IS_LESS = "is-less",
|
||||
IS_GREATER_OR_EQUAL = "is-greater-or-equal",
|
||||
IS_LESS_OR_EQUAL = "is-less-or-equal",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
enum CheckboxFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
enum DateFilterCondition {
|
||||
IS = "is",
|
||||
IS_BEFORE = "is-before",
|
||||
IS_AFTER = "is-after",
|
||||
IS_ON_OR_BEFORE = "is-on-or-before",
|
||||
IS_ON_OR_AFTER = "is-on-or-after",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
enum ContentFilterCondition {
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
IS_EMPTY = "is-empty",
|
||||
IS_NOT_EMPTY = "is-not-empty",
|
||||
}
|
||||
|
||||
enum FolderFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
}
|
||||
|
||||
enum FileNameFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
STARTS_WITH = "starts-with",
|
||||
ENDS_WITH = "ends-with",
|
||||
}
|
||||
|
||||
type FilterCondition =
|
||||
| TextFilterCondition
|
||||
| NumberFilterCondition
|
||||
| DateFilterCondition
|
||||
| CheckboxFilterCondition
|
||||
| ListFilterCondition
|
||||
| ContentFilterCondition
|
||||
| FolderFilterCondition
|
||||
| FileNameFilterCondition;
|
||||
|
||||
//This matches the Obsidian property types
|
||||
enum PropertyType {
|
||||
TEXT = "text",
|
||||
NUMBER = "number",
|
||||
LIST = "list",
|
||||
CHECKBOX = "checkbox",
|
||||
DATE = "date",
|
||||
DATETIME = "datetime",
|
||||
}
|
||||
|
||||
enum FilterRuleType {
|
||||
PROPERTY = "property",
|
||||
FOLDER = "folder",
|
||||
FILE_NAME = "file-name",
|
||||
CONTENT = "content",
|
||||
}
|
||||
|
||||
enum DatePropertyFilterValue {
|
||||
TODAY = "today",
|
||||
TOMORROW = "tomorrow",
|
||||
YESTERDAY = "yesterday",
|
||||
ONE_WEEK_FROM_NOW = "one-week-from-now",
|
||||
ONE_WEEK_AGO = "one-week-ago",
|
||||
ONE_MONTH_FROM_NOW = "one-month-from-now",
|
||||
ONE_MONTH_AGO = "one-month-ago",
|
||||
CUSTOM = "custom",
|
||||
}
|
||||
|
||||
interface BaseFilterRule {
|
||||
id: string;
|
||||
operator: FilterOperator;
|
||||
type: FilterRuleType;
|
||||
condition: FilterCondition;
|
||||
isEnabled: boolean;
|
||||
value: string;
|
||||
matchWhenPropertyDNE: boolean;
|
||||
}
|
||||
|
||||
interface TextPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.TEXT;
|
||||
propertyName: string;
|
||||
condition: TextFilterCondition;
|
||||
}
|
||||
|
||||
interface NumberPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.NUMBER;
|
||||
propertyName: string;
|
||||
condition: NumberFilterCondition;
|
||||
}
|
||||
|
||||
interface ListPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.LIST;
|
||||
propertyName: string;
|
||||
condition: ListFilterCondition;
|
||||
}
|
||||
|
||||
interface CheckboxPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.CHECKBOX;
|
||||
propertyName: string;
|
||||
condition: CheckboxFilterCondition;
|
||||
}
|
||||
|
||||
interface DatePropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.DATE | PropertyType.DATETIME;
|
||||
propertyName: string;
|
||||
condition: DateFilterCondition;
|
||||
valueData: string;
|
||||
}
|
||||
|
||||
interface FolderFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.FOLDER;
|
||||
condition: FolderFilterCondition;
|
||||
includeSubfolders: boolean;
|
||||
}
|
||||
|
||||
interface FileNameFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.FILE_NAME;
|
||||
condition: FileNameFilterCondition;
|
||||
}
|
||||
|
||||
interface ContentFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.CONTENT;
|
||||
condition: ContentFilterCondition;
|
||||
}
|
||||
|
||||
type TFilterRule =
|
||||
| PropertyFilterRule
|
||||
| FolderFilterRule
|
||||
| FileNameFilterRule
|
||||
| ContentFilterRule;
|
||||
|
||||
type PropertyFilterRule =
|
||||
| TextPropertyFilterRule
|
||||
| NumberPropertyFilterRule
|
||||
| ListPropertyFilterRule
|
||||
| CheckboxPropertyFilterRule
|
||||
| DatePropertyFilterRule;
|
||||
|
||||
interface TFilterGroup {
|
||||
id: string;
|
||||
name: string;
|
||||
rules: TFilterRule[];
|
||||
isEnabled: boolean;
|
||||
isSticky: boolean;
|
||||
}
|
||||
|
|
@ -134,5 +134,6 @@
|
|||
"1.39.0": "1.4.13",
|
||||
"1.40.0": "1.4.13",
|
||||
"1.40.1": "1.4.13",
|
||||
"1.40.2": "1.4.13"
|
||||
"1.40.2": "1.4.13",
|
||||
"1.41.0": "1.4.13"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue