mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
Merge pull request #328 from decaf-dev/dev
* feat: remove image icon placeholder * feat: remove status bar when view is open * refactor: rename to image fit to just cover and contain * feat: remove favorites filter * feat: set pagination indicator as status bar * feat: remove timestamp filter * feat: move search filter up * feat: add toggle to search * feat: make groups front and center * feat: update custom filter button * chore: bump version * fix: remove extra padding on buttons * fix: don't replace existing tab when view opens (#323) * Clean up code (#324) * refactor: remove unused code * feat: clean up old properties * fix: display without leading zero (#325) * feat: add created date to sort (#326) * Update default values (#327) * feat: add default value to properties * feat: rename to File system * refactor: update value * chore: update guardgen * chore: update workflow name * refactor: rename to image cache * docs: update README.md * docs: remove unused images
This commit is contained in:
commit
716615ccba
42 changed files with 753 additions and 834 deletions
2
.github/workflows/check-console-log.yml
vendored
2
.github/workflows/check-console-log.yml
vendored
|
|
@ -1,4 +1,4 @@
|
|||
name: Check Console Log
|
||||
name: Check for console.log statements
|
||||
|
||||
on: pull_request
|
||||
|
||||
|
|
|
|||
141
README.md
141
README.md
|
|
@ -58,14 +58,6 @@ Vault Explorer is a work in progress. Please check the GitHub repository and doc
|
|||
|
||||
<img src="readme/custom-filter-options-2.png" width="500">
|
||||
|
||||
### Favorites
|
||||
|
||||

|
||||
|
||||
### Timestamp filter
|
||||
|
||||

|
||||
|
||||
### Sort filter
|
||||
|
||||

|
||||
|
|
@ -95,75 +87,70 @@ Please do not share your license key with anyone. Shared license keys will be de
|
|||
|
||||
## Features
|
||||
|
||||
| Name | Categories | Documented |
|
||||
| --------------------------------------------------------------------------- | -------------------- | ---------- |
|
||||
| Move focus with left and right arrows | Accessibility | ✅ |
|
||||
| See an image placeholder on the grid card | Cover image | ✅ |
|
||||
| Load a cover image from the image property | Cover | ✅ |
|
||||
| Load images from the url property | Cover image | ✅ |
|
||||
| Load images from the first link in the frontmatter (wiki link or url) | Cover image | ✅ |
|
||||
| Load images from the first link the body (internal embed or external embed) | Cover image | ✅ |
|
||||
| Change the order of cover image sources | Cover image, Setting | ✅ |
|
||||
| Enable/disable cover image sources | Cover image, Setting | ✅ |
|
||||
| Cache social media images | Cover image | ✅ |
|
||||
| Filter files by favorite property | Favorites filter | ✅ |
|
||||
| Favorites support for non-markdown files | Favorites filter | ✅ |
|
||||
| Add to favorites button in context menu | Favorites filter | ✅ |
|
||||
| Remove from favorites button in context menu | Favorites filter | ✅ |
|
||||
| See a favorite icon in the grid card | Favorites filter | ✅ |
|
||||
| Reorder the filter group list | Filter group | ✅ |
|
||||
| Add a filter group | Filter group | ✅ |
|
||||
| Delete a filter group | Filter group | ✅ |
|
||||
| Set a filter group as sticky | Filter group | ✅ |
|
||||
| Unset a filter group as sticky | Filter group | ✅ |
|
||||
| Right click to edit a filter group item | Filter group | |
|
||||
| Add a filter rule | Filter rule | ✅ |
|
||||
| Delete a filter rule | Filter rule | ✅ |
|
||||
| Duplicate a filter rule | Filter rule | ✅ |
|
||||
| Match when property doesn't exist toggle | Filter rule | ✅ |
|
||||
| Filter files by folder | Filter rule | ✅ |
|
||||
| Filter by frontmatter property | Filter rule | ✅ |
|
||||
| Select a condition | Filter rule | ✅ |
|
||||
| Select a logical operator: `and`, `or` | Filter rule | ✅ |
|
||||
| Filter files by folder | Filter rule | ✅ |
|
||||
| Filter files by file content | Filter rule | ✅ |
|
||||
| Filter files by file name | Filter rule | ✅ |
|
||||
| Enable/disable a filter rule | Filter rule | ✅ |
|
||||
| Set the log level | Logging | ✅ |
|
||||
| Filter by search | Search filter | ✅ |
|
||||
| Set page size | Setting | ✅ |
|
||||
| Set property for modification date | Setting | ✅ |
|
||||
| Set property for creation date | Setting | ✅ |
|
||||
| Set a url property | Setting | ✅ |
|
||||
| Set a favorite property | Setting | ✅ |
|
||||
| Set custom text property | Setting | ✅ |
|
||||
| Toggle file icons | Setting | ✅ |
|
||||
| Change the filter groups wrap | Setting | ✅ |
|
||||
| Enable/disable loading the social media image | Setting | ✅ |
|
||||
| Change the collapse style for feed content | Setting | ✅ |
|
||||
| Remove H1 from feed content | Setting | ✅ |
|
||||
| Remove markdown from feed content | Setting | ✅ |
|
||||
| Enable/disable tags on a list item | Setting | ✅ |
|
||||
| Change the plugin configuration folder | Setting, Data | ✅ |
|
||||
| Clear the social media cache | Setting, Data | ✅ |
|
||||
| Change the feed content line clamp for small screens | Setting, Feed view | ✅ |
|
||||
| Change the feed content line clamp for medium screens | Setting, Feed view | ✅ |
|
||||
| Change the feed content line clamp for large screens | Setting, Feed view | ✅ |
|
||||
| Enter a license key | Setting, License | ✅ |
|
||||
| Sort by title: `asc`, `desc` | Sort order | ✅ |
|
||||
| Sort by modification date: `asc`, `desc` | Sort order | ✅ |
|
||||
| Randomly sort files | Sort order | ✅ |
|
||||
| Filter by creation date: `1 day`, `1 week`, `2 weeks` | Timestamp filter | ✅ |
|
||||
| Filter by modification date: `1 day`, `1 week`, `2 weeks` | Timestamp filter | ✅ |
|
||||
| See vault files in a grid view | View | ✅ |
|
||||
| See vault files in a list view | View | ✅ |
|
||||
| See vault files in a feed view | View | ✅ |
|
||||
| Change the view list order | View | |
|
||||
| Limit displayed files with pagination | View | |
|
||||
| Search for a tag when clicked | View | ✅ |
|
||||
| See a file preview when mouse hovers link and ctrl/cmd is pressed | View | |
|
||||
| Search for property when clicked | View | ✅ |
|
||||
| See files icons next to the file name | View | ✅ |
|
||||
| Name | Categories | Documented |
|
||||
| --------------------------------------------------------------------------- | ---------------------- | ---------- |
|
||||
| Move focus with left and right arrows | Accessibility | ✅ |
|
||||
| See an image placeholder on the grid card | Cover image | ✅ |
|
||||
| Load a cover image from the image property | Cover image | ✅ |
|
||||
| Load images from the url property | Cover image | ✅ |
|
||||
| Load images from the first link in the frontmatter (wiki link or url) | Cover image | ✅ |
|
||||
| Load images from the first link the body (internal embed or external embed) | Cover image | ✅ |
|
||||
| Cache social media images | Cover image | ✅ |
|
||||
| Change the order of cover image sources | Cover image, Setting | ✅ |
|
||||
| Enable/disable cover image sources | Cover image, Setting | ✅ |
|
||||
| Enable/disable loading the social media image | Cover image, Setting | ✅ |
|
||||
| Clear the social media cache | Cover image, Setting | ✅ |
|
||||
| Change the collapse style for feed content | Feed view, Setting | ✅ |
|
||||
| Remove H1 from feed content | Feed view, Setting | ✅ |
|
||||
| Remove markdown from feed content | Feed view, Setting | ✅ |
|
||||
| Change the feed content line clamp for small screens | Feed view, Setting | ✅ |
|
||||
| Change the feed content line clamp for medium screens | Feed view, Setting | ✅ |
|
||||
| Change the feed content line clamp for large screens | Feed view, Setting | ✅ |
|
||||
| See files icons next to the file name | File icons | ✅ |
|
||||
| Toggle file icons | File icons, Setting | ✅ |
|
||||
| Reorder the filter group list | Filter group | ✅ |
|
||||
| Add a filter group | Filter group | ✅ |
|
||||
| Delete a filter group | Filter group | ✅ |
|
||||
| Set a filter group as sticky | Filter group | ✅ |
|
||||
| Unset a filter group as sticky | Filter group | ✅ |
|
||||
| Right click to edit a filter group item | Filter group | |
|
||||
| Change the filter groups wrap | Filter groups, Setting | ✅ |
|
||||
| Add a filter rule | Filter rule | ✅ |
|
||||
| Delete a filter rule | Filter rule | ✅ |
|
||||
| Duplicate a filter rule | Filter rule | ✅ |
|
||||
| Match when property doesn't exist toggle | Filter rule | ✅ |
|
||||
| Filter files by folder | Filter rule | ✅ |
|
||||
| Filter by frontmatter property | Filter rule | ✅ |
|
||||
| Select a condition | Filter rule | ✅ |
|
||||
| Select a logical operator: `and`, `or` | Filter rule | ✅ |
|
||||
| Filter files by folder | Filter rule | ✅ |
|
||||
| Filter files by file content | Filter rule | ✅ |
|
||||
| Filter files by file name | Filter rule | ✅ |
|
||||
| Enable/disable a filter rule | Filter rule | ✅ |
|
||||
| Enter a license key | License, Setting | ✅ |
|
||||
| Enable/disable tags on a list item | List view, Setting | ✅ |
|
||||
| Set the log level | Logging | ✅ |
|
||||
| Filter by search | Search filter | ✅ |
|
||||
| Change the plugin configuration folder | Setting | ✅ |
|
||||
| Sort by title: `asc`, `desc` | Sort order | ✅ |
|
||||
| Sort by modification date: `asc`, `desc` | Sort order | ✅ |
|
||||
| Randomly sort files | Sort order | ✅ |
|
||||
| Set property for modification date | Setting | ✅ |
|
||||
| Set property for creation date | Setting | ✅ |
|
||||
| See vault files in a grid view | View | ✅ |
|
||||
| See vault files in a list view | View | ✅ |
|
||||
| See vault files in a feed view | View | ✅ |
|
||||
| See vault files in a table view | View | ✅ |
|
||||
| Change the view list order | View | |
|
||||
| Limit displayed files with pagination | View | |
|
||||
| Search for a tag when clicked | View | ✅ |
|
||||
| See a file preview when mouse hovers link and ctrl/cmd is pressed | View | |
|
||||
| Search for property when clicked | View | ✅ |
|
||||
| Load tags from the body of a markdown notes | View | ✅ |
|
||||
| Set page size | View, Setting | ✅ |
|
||||
| Set a url property | View, Setting | ✅ |
|
||||
| Set custom text property | View, Setting | ✅ |
|
||||
| Enable/disable load tags from a markdown note | View, Setting | ✅ |
|
||||
|
||||
## Network use
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "vault-explorer",
|
||||
"name": "Vault Explorer",
|
||||
"version": "1.41.1",
|
||||
"version": "1.42.0",
|
||||
"minAppVersion": "1.4.13",
|
||||
"description": "Explore your vault in visual format",
|
||||
"author": "DecafDev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-vault-explorer",
|
||||
"version": "1.41.1",
|
||||
"version": "1.42.0",
|
||||
"description": "Explore your vault in visual format",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB |
|
|
@ -7,10 +7,9 @@ export const HOVER_LINK_SOURCE_ID = "vault-explorer-preview";
|
|||
|
||||
export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
||||
properties: {
|
||||
favorite: "",
|
||||
url: "",
|
||||
image: "",
|
||||
coverImageFit: "",
|
||||
url: "url",
|
||||
image: "image",
|
||||
coverImageFit: "image-fit",
|
||||
createdDate: "",
|
||||
modifiedDate: "",
|
||||
custom1: "",
|
||||
|
|
@ -22,14 +21,6 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
|||
isEnabled: true,
|
||||
value: "",
|
||||
},
|
||||
favorites: {
|
||||
isEnabled: true,
|
||||
value: false,
|
||||
},
|
||||
timestamp: {
|
||||
isEnabled: true,
|
||||
value: "all",
|
||||
},
|
||||
sort: {
|
||||
isEnabled: true,
|
||||
value: "file-name-asc",
|
||||
|
|
@ -94,8 +85,6 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
|||
enableClockUpdates: true,
|
||||
enableFileIcons: false,
|
||||
loadBodyTags: true,
|
||||
filterGroupsWidth: "300px",
|
||||
shouldWrapFilterGroups: false,
|
||||
shouldCollapseFilters: false,
|
||||
pageSize: 25,
|
||||
viewOrder: [
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ export enum PluginEvent {
|
|||
VIEW_TOGGLE_SETTING_CHANGE = "view-toggle-setting-change",
|
||||
FILE_ICONS_SETTING_CHANGE = "file-icons-setting-change",
|
||||
LOAD_BODY_TAGS_SETTING_CHANGE = "load-body-tags-setting-change",
|
||||
WRAP_FILTER_GROUPS_SETTING_CHANGE = "wrap-filter-groups-setting-change",
|
||||
LOAD_SOCIAL_MEDIA_IMAGE_SETTING_CHANGE = "load-social-media-image-setting-change",
|
||||
SHOW_TAGS_SETTING_CHANGE = "show-tags-setting-change",
|
||||
}
|
||||
|
|
|
|||
19
src/main.ts
19
src/main.ts
|
|
@ -20,6 +20,7 @@ import { isVersionLessThan } from "./utils";
|
|||
import License from "./svelte/shared/services/license";
|
||||
import { clearSocialMediaImageCache } from "./svelte/app/services/social-media-image-cache";
|
||||
import store from "./svelte/shared/services/store";
|
||||
import "./styles.css";
|
||||
|
||||
export default class VaultExplorerPlugin extends Plugin {
|
||||
settings: VaultExplorerPluginSettings = DEFAULT_SETTINGS;
|
||||
|
|
@ -63,6 +64,22 @@ export default class VaultExplorerPlugin extends Plugin {
|
|||
}
|
||||
|
||||
private registerEvents() {
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("active-leaf-change", () => {
|
||||
const explorerLeaf =
|
||||
this.app.workspace.getActiveViewOfType(VaultExplorerView);
|
||||
const statusBar = document.querySelector(
|
||||
".status-bar"
|
||||
) as HTMLElement | null;
|
||||
if (!statusBar) return;
|
||||
if (explorerLeaf) {
|
||||
statusBar.classList.add("vault-explorer-status-bar");
|
||||
} else {
|
||||
statusBar.classList.remove("vault-explorer-status-bar");
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
//Callback if the file is renamed or moved
|
||||
//This callback is already debounced by Obsidian
|
||||
this.registerEvent(
|
||||
|
|
@ -228,7 +245,7 @@ export default class VaultExplorerPlugin extends Plugin {
|
|||
const leaf = leaves[0];
|
||||
this.app.workspace.revealLeaf(leaf);
|
||||
} else {
|
||||
this.app.workspace.getLeaf().setViewState({
|
||||
this.app.workspace.getLeaf("tab").setViewState({
|
||||
type: VAULT_EXPLORER_VIEW,
|
||||
active: true,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ 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";
|
||||
import Migrate_1_42_0 from "./migrate_1_42_0";
|
||||
|
||||
const migrations: TMigration[] = [
|
||||
{
|
||||
|
|
@ -183,6 +184,11 @@ const migrations: TMigration[] = [
|
|||
to: "1.41.0",
|
||||
migrate: Migrate_1_41_0,
|
||||
},
|
||||
{
|
||||
from: "1.41.1",
|
||||
to: "1.42.0",
|
||||
migrate: Migrate_1_42_0,
|
||||
},
|
||||
];
|
||||
|
||||
export const preformMigrations = (
|
||||
|
|
|
|||
18
src/migrations/migrate_1_42_0.ts
Normal file
18
src/migrations/migrate_1_42_0.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { VaultExplorerPluginSettings } from "src/types";
|
||||
import MigrationInterface from "./migration_interface";
|
||||
import { VaultExplorerPluginSettings_1_41_1 } from "src/types/types-1.41.1";
|
||||
|
||||
export default class Migrate_1_42_0 implements MigrationInterface {
|
||||
migrate(data: Record<string, unknown>) {
|
||||
const typedData = data as unknown as VaultExplorerPluginSettings_1_41_1;
|
||||
const newData: VaultExplorerPluginSettings = {
|
||||
...typedData,
|
||||
};
|
||||
delete (newData as any).filterGroupsWidth;
|
||||
delete (newData as any).shouldWrapFilterGroups;
|
||||
delete (newData as any).filters.favorites;
|
||||
delete (newData as any).filters.timestamp;
|
||||
|
||||
return newData as unknown as Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { App } from "obsidian"
|
||||
import { App } from "obsidian";
|
||||
import { ObsidianProperty, ObsidianPropertyType } from "./types";
|
||||
|
||||
/**
|
||||
|
|
@ -6,17 +6,34 @@ import { ObsidianProperty, ObsidianPropertyType } from "./types";
|
|||
* NOTE: This is an undocumented API function and may break in future versions of Obsidian
|
||||
*/
|
||||
export const getAllObsidianProperties = (app: App) => {
|
||||
const properties = (app as any).metadataTypeManager.getAllProperties() as Record<string, ObsidianProperty>;
|
||||
return Object.values(properties).sort((a: ObsidianProperty, b: ObsidianProperty) => a.name.localeCompare(b.name));
|
||||
const properties = (
|
||||
app as any
|
||||
).metadataTypeManager.getAllProperties() as Record<
|
||||
string,
|
||||
ObsidianProperty
|
||||
>;
|
||||
return Object.values(properties).sort(
|
||||
(a: ObsidianProperty, b: ObsidianProperty) =>
|
||||
a.name.localeCompare(b.name)
|
||||
);
|
||||
};
|
||||
|
||||
export const getObsidianPropertiesByType = (app: App, type: ObsidianPropertyType) => {
|
||||
export const getObsidianPropertiesByType = (
|
||||
app: App,
|
||||
type: ObsidianPropertyType
|
||||
) => {
|
||||
return getAllObsidianProperties(app).filter((p) => p.type === type);
|
||||
}
|
||||
};
|
||||
|
||||
export const getDropdownOptionsForProperties = (properties: ObsidianProperty[]) => {
|
||||
return properties.reduce((acc: Record<string, string>, cur: ObsidianProperty) => {
|
||||
acc[cur.name] = cur.name;
|
||||
return acc;
|
||||
}, { "": "Select a property" });
|
||||
}
|
||||
export const getDropdownOptionsForProperties = (
|
||||
properties: ObsidianProperty[],
|
||||
defaultValue: Record<string, string> = { "": "Select a property" }
|
||||
) => {
|
||||
return properties.reduce(
|
||||
(acc: Record<string, string>, cur: ObsidianProperty) => {
|
||||
acc[cur.name] = cur.name;
|
||||
return acc;
|
||||
},
|
||||
defaultValue
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -108,20 +108,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Wrap filter groups")
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.shouldWrapFilterGroups)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.shouldWrapFilterGroups = value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.WRAP_FILTER_GROUPS_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl).setName("Filters").setHeading();
|
||||
|
||||
new Setting(containerEl).setName("Search filter").addToggle((toggle) =>
|
||||
|
|
@ -136,36 +122,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Favorites filter")
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.filters.favorites.isEnabled)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.filters.favorites.isEnabled =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.FILTER_TOGGLE_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Timestamp filter")
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.filters.timestamp.isEnabled)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.filters.timestamp.isEnabled =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.FILTER_TOGGLE_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl).setName("Sort filter").addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.filters.sort.isEnabled)
|
||||
|
|
@ -490,26 +446,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
|
||||
new Setting(containerEl).setName("Built-in properties").setHeading();
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Favorite property")
|
||||
.setDesc(
|
||||
"Property used to mark a note as a favorite. This must be a checkbox property."
|
||||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOptions(
|
||||
getDropdownOptionsForProperties(checkboxProperties)
|
||||
)
|
||||
.setValue(this.plugin.settings.properties.favorite)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.properties.favorite = value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit(
|
||||
PluginEvent.PROPERTY_SETTING_CHANGE
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Cover image property")
|
||||
.setDesc(
|
||||
|
|
@ -517,7 +453,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOptions(getDropdownOptionsForProperties(textProperties))
|
||||
.addOptions(
|
||||
getDropdownOptionsForProperties(textProperties, {
|
||||
image: "image",
|
||||
})
|
||||
)
|
||||
.setValue(this.plugin.settings.properties.image)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.properties.image = value;
|
||||
|
|
@ -535,7 +475,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOptions(getDropdownOptionsForProperties(textProperties))
|
||||
.addOptions(
|
||||
getDropdownOptionsForProperties(textProperties, {
|
||||
"image-fit": "image-fit",
|
||||
})
|
||||
)
|
||||
.setValue(this.plugin.settings.properties.coverImageFit)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.properties.coverImageFit = value;
|
||||
|
|
@ -553,7 +497,11 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
)
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOptions(getDropdownOptionsForProperties(textProperties))
|
||||
.addOptions(
|
||||
getDropdownOptionsForProperties(textProperties, {
|
||||
url: "url",
|
||||
})
|
||||
)
|
||||
.setValue(this.plugin.settings.properties.url)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.properties.url = value;
|
||||
|
|
@ -569,7 +517,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
text: "Property used to store a creation date. This must be a date or datetime property.",
|
||||
});
|
||||
creationDateDesc.createDiv({
|
||||
text: "If set to 'Select a property', the file's created at date will be used.",
|
||||
text: "If set, the property will be preferred over the file's creation date.",
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
|
|
@ -598,7 +546,7 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
text: "Property used to store a modification date. This must be a date or datetime property.",
|
||||
});
|
||||
modificationDateDesc.createDiv({
|
||||
text: "If set to 'Select a property', the file's modified at date will be used.",
|
||||
text: "If set, the property will be preferred over the file's modification date.",
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
|
|
@ -744,16 +692,14 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Social media image cache")
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setClass("mod-destructive")
|
||||
.setButtonText("Clear cache")
|
||||
.onClick(async () => {
|
||||
await clearSocialMediaImageCache();
|
||||
})
|
||||
);
|
||||
new Setting(containerEl).setName("Image cache").addButton((button) =>
|
||||
button
|
||||
.setClass("mod-destructive")
|
||||
.setButtonText("Clear cache")
|
||||
.onClick(async () => {
|
||||
await clearSocialMediaImageCache();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
|
|
|
|||
3
src/styles.css
Normal file
3
src/styles.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.vault-explorer-status-bar {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Checkbox from "src/svelte/shared/components/checkbox.svelte";
|
||||
|
||||
export let value: boolean;
|
||||
</script>
|
||||
|
||||
<Checkbox id="favorites" label="Favorites" {value} on:change />
|
||||
|
|
@ -35,7 +35,6 @@
|
|||
export let path: string;
|
||||
export let createdMillis: number;
|
||||
export let content: string | null;
|
||||
export let isFavorite: boolean | null;
|
||||
|
||||
let ref: HTMLElement | null = null;
|
||||
let enableFileIcons = false;
|
||||
|
|
@ -146,16 +145,9 @@
|
|||
openInCurrentTab(plugin, path);
|
||||
}
|
||||
|
||||
function handleFavoriteChange(filePath: string, value: boolean) {
|
||||
dispatch("favoritePropertyChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleCardContextMenu(e: Event) {
|
||||
const nativeEvent = e as MouseEvent;
|
||||
openContextMenu(plugin, path, nativeEvent, {
|
||||
isFavorite,
|
||||
onFavoriteChange: handleFavoriteChange,
|
||||
});
|
||||
openContextMenu(plugin, path, nativeEvent, {});
|
||||
}
|
||||
|
||||
function handleCardMouseOver(e: MouseEvent) {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@
|
|||
path={fileRenderData.path}
|
||||
content={fileRenderData.content}
|
||||
createdMillis={fileRenderData.createdMillis}
|
||||
isFavorite={fileRenderData.isFavorite}
|
||||
on:favoritePropertyChange
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -3,115 +3,50 @@
|
|||
import _ from "lodash";
|
||||
import VaultExplorerPlugin from "src/main";
|
||||
import store from "src/svelte/shared/services/store";
|
||||
import { onMount } from "svelte";
|
||||
import Wrap from "src/svelte/shared/components/wrap.svelte";
|
||||
import EventManager from "src/event/event-manager";
|
||||
import { PluginEvent } from "src/event/types";
|
||||
import FilterGroup from "./filter-group.svelte";
|
||||
import Stack from "src/svelte/shared/components/stack.svelte";
|
||||
|
||||
export let groups: TFilterGroup[] = [];
|
||||
|
||||
let containerRef: HTMLDivElement | null = null;
|
||||
let shouldWrapFilterGroups: boolean = false;
|
||||
|
||||
const debounceSaveContainerWidth = _.debounce(saveContainerWidth, 200);
|
||||
|
||||
let plugin: VaultExplorerPlugin;
|
||||
|
||||
store.plugin.subscribe((p) => {
|
||||
plugin = p;
|
||||
shouldWrapFilterGroups = plugin.settings.shouldWrapFilterGroups;
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
function handleWrapFilterGroupsSettingChange() {
|
||||
shouldWrapFilterGroups = plugin.settings.shouldWrapFilterGroups;
|
||||
}
|
||||
|
||||
EventManager.getInstance().on(
|
||||
PluginEvent.WRAP_FILTER_GROUPS_SETTING_CHANGE,
|
||||
handleWrapFilterGroupsSettingChange,
|
||||
);
|
||||
return () => {
|
||||
EventManager.getInstance().off(
|
||||
PluginEvent.WRAP_FILTER_GROUPS_SETTING_CHANGE,
|
||||
handleWrapFilterGroupsSettingChange,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
let resizeObserver: ResizeObserver;
|
||||
|
||||
if (containerRef) {
|
||||
containerRef.style.width = plugin.settings.filterGroupsWidth;
|
||||
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
debounceSaveContainerWidth();
|
||||
});
|
||||
resizeObserver.observe(containerRef);
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver?.disconnect();
|
||||
};
|
||||
});
|
||||
|
||||
async function saveContainerWidth() {
|
||||
if (containerRef) {
|
||||
plugin.settings.filterGroupsWidth = containerRef.style.width;
|
||||
await plugin.saveSettings();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="vault-explorer-filter-group-list">
|
||||
<div
|
||||
class="vault-explorer-filter-group-list__container"
|
||||
bind:this={containerRef}
|
||||
>
|
||||
<Stack spacing="md" width="fit-content">
|
||||
{#if groups.length > 0}
|
||||
<Wrap
|
||||
spacingX="sm"
|
||||
spacingY="sm"
|
||||
wrap={shouldWrapFilterGroups ? "wrap" : "nowrap"}
|
||||
>
|
||||
{#each groups as group (group.id)}
|
||||
<FilterGroup
|
||||
id={group.id}
|
||||
name={group.name}
|
||||
isSelected={group.isEnabled}
|
||||
isSticky={group.isSticky}
|
||||
on:groupClick
|
||||
on:groupDrop
|
||||
on:groupDragOver
|
||||
on:groupDragStart
|
||||
on:groupContextMenu
|
||||
/>
|
||||
{/each}
|
||||
</Wrap>
|
||||
{#each groups as group (group.id)}
|
||||
<FilterGroup
|
||||
id={group.id}
|
||||
name={group.name}
|
||||
isSelected={group.isEnabled}
|
||||
isSticky={group.isSticky}
|
||||
on:groupClick
|
||||
on:groupDrop
|
||||
on:groupDragOver
|
||||
on:groupDragStart
|
||||
on:groupContextMenu
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if groups.length === 0}
|
||||
<span class="vault-explorer-empty-label">No groups</span>
|
||||
<span class="vault-explorer-empty-label">No groups to display</span>
|
||||
{/if}
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.vault-explorer-filter-group-list {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.vault-explorer-filter-group-list__container {
|
||||
padding-bottom: 8px;
|
||||
resize: horizontal;
|
||||
width: min(100%, 700px);
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.vault-explorer-empty-label {
|
||||
color: var(--text-faint);
|
||||
font-size: var(--font-smaller);
|
||||
font-size: var(--font-md);
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -66,18 +66,16 @@
|
|||
|
||||
<style>
|
||||
.vault-explorer-filter-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
height: 75px;
|
||||
white-space: nowrap;
|
||||
font-size: var(--tag-size);
|
||||
font-weight: var(--tag-weight);
|
||||
text-decoration: var(--tag-decoration);
|
||||
padding: var(--tag-padding-y) var(--tag-padding-x);
|
||||
line-height: 1;
|
||||
border-radius: var(--tag-radius);
|
||||
|
||||
padding: 4px 8px;
|
||||
border-radius: var(--radius-m);
|
||||
color: var(--text-faint);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
background-color: var(--background-primary);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.vault-explorer-filter-group:focus-visible {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
export let custom1: string | null;
|
||||
export let custom2: string | null;
|
||||
export let custom3: string | null;
|
||||
export let isFavorite: boolean | null;
|
||||
export let coverImageFit: CoverImageFit;
|
||||
|
||||
let plugin: VaultExplorerPlugin;
|
||||
|
|
@ -134,10 +133,6 @@
|
|||
openInCurrentTab(plugin, path);
|
||||
}
|
||||
|
||||
function handleFavoriteChange(filePath: string, value: boolean) {
|
||||
dispatch("favoritePropertyChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleCoverImageFitChange(filePath: string, value: CoverImageFit) {
|
||||
dispatch("coverImageFitChange", { filePath, value });
|
||||
}
|
||||
|
|
@ -147,9 +142,7 @@
|
|||
|
||||
const showCoverImageOptions = path.endsWith(".md");
|
||||
openContextMenu(plugin, path, nativeEvent, {
|
||||
isFavorite,
|
||||
coverImageFit: showCoverImageOptions ? coverImageFit : undefined,
|
||||
onFavoriteChange: handleFavoriteChange,
|
||||
onCoverImageFitChange: showCoverImageOptions
|
||||
? handleCoverImageFitChange
|
||||
: undefined,
|
||||
|
|
@ -229,14 +222,9 @@
|
|||
{/if}
|
||||
{/each}
|
||||
{#if imageUrl === null}
|
||||
<div class="vault-explorer-grid-card__cover-icon">
|
||||
<Icon
|
||||
iconId={getIconIdForFile(baseName, extension)}
|
||||
size="lg"
|
||||
/>
|
||||
</div>
|
||||
<div class="vault-explorer-grid-card__image"></div>
|
||||
{/if}
|
||||
{#if isFavorite === true}
|
||||
<!-- {#if isFavorite === true}
|
||||
<div class="vault-explorer-grid-card__favorite">
|
||||
<Flex
|
||||
justify="center"
|
||||
|
|
@ -247,7 +235,7 @@
|
|||
<Icon iconId="star" ariaLabel="Favorite" />
|
||||
</Flex>
|
||||
</div>
|
||||
{/if}
|
||||
{/if} -->
|
||||
</div>
|
||||
<div class="vault-explorer-grid-card__body">
|
||||
<div
|
||||
|
|
@ -353,14 +341,7 @@
|
|||
border-top-right-radius: var(--radius-m);
|
||||
}
|
||||
|
||||
.vault-explorer-grid-card__cover-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.vault-explorer-grid-card__favorite {
|
||||
/* .vault-explorer-grid-card__favorite {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
|
|
@ -368,7 +349,7 @@
|
|||
height: 20px;
|
||||
background-color: var(--background-primary);
|
||||
border-radius: 50%;
|
||||
}
|
||||
} */
|
||||
|
||||
.vault-explorer-grid-card__body {
|
||||
padding: 8px 16px;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@
|
|||
custom1={fileRenderData.custom1}
|
||||
custom2={fileRenderData.custom2}
|
||||
custom3={fileRenderData.custom3}
|
||||
isFavorite={fileRenderData.isFavorite}
|
||||
on:favoritePropertyChange
|
||||
on:coverImageFitChange
|
||||
/>
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
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 { createEventDispatcher, onMount } from "svelte";
|
||||
import { onMount } from "svelte";
|
||||
import EventManager from "src/event/event-manager";
|
||||
import { PluginEvent } from "src/event/types";
|
||||
import { openContextMenu } from "../services/context-menu";
|
||||
|
|
@ -18,7 +18,6 @@
|
|||
export let extension: string;
|
||||
export let path: string;
|
||||
export let tags: string[] | null;
|
||||
export let isFavorite: boolean | null;
|
||||
export let showTags: boolean;
|
||||
export let isSmallScreenSize: boolean;
|
||||
|
||||
|
|
@ -26,30 +25,28 @@
|
|||
let ref: HTMLElement | null = null;
|
||||
let plugin: VaultExplorerPlugin;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
store.plugin.subscribe((p) => {
|
||||
plugin = p;
|
||||
enableFileIcons = plugin.settings.enableFileIcons;
|
||||
// showTags = plugin.settings.views.list.showTags;
|
||||
showTags = plugin.settings.views.list.showTags;
|
||||
});
|
||||
|
||||
// onMount(() => {
|
||||
// function handleShowTagsChange() {
|
||||
// showTags = plugin.settings.views.list.showTags;
|
||||
// }
|
||||
onMount(() => {
|
||||
function handleShowTagsChange() {
|
||||
showTags = plugin.settings.views.list.showTags;
|
||||
}
|
||||
|
||||
// EventManager.getInstance().on(
|
||||
// PluginEvent.SHOW_TAGS_SETTING_CHANGE,
|
||||
// handleShowTagsChange,
|
||||
// );
|
||||
// return () => {
|
||||
// EventManager.getInstance().off(
|
||||
// PluginEvent.SHOW_TAGS_SETTING_CHANGE,
|
||||
// handleShowTagsChange,
|
||||
// );
|
||||
// };
|
||||
// });
|
||||
EventManager.getInstance().on(
|
||||
PluginEvent.SHOW_TAGS_SETTING_CHANGE,
|
||||
handleShowTagsChange,
|
||||
);
|
||||
return () => {
|
||||
EventManager.getInstance().off(
|
||||
PluginEvent.SHOW_TAGS_SETTING_CHANGE,
|
||||
handleShowTagsChange,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
function handleFileIconsChange() {
|
||||
|
|
@ -76,16 +73,9 @@
|
|||
openInCurrentTab(plugin, path);
|
||||
}
|
||||
|
||||
function handleFavoriteChange(filePath: string, value: boolean) {
|
||||
dispatch("favoritePropertyChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleItemContextMenu(e: Event) {
|
||||
const nativeEvent = e as MouseEvent;
|
||||
openContextMenu(plugin, path, nativeEvent, {
|
||||
isFavorite,
|
||||
onFavoriteChange: handleFavoriteChange,
|
||||
});
|
||||
openContextMenu(plugin, path, nativeEvent, {});
|
||||
}
|
||||
|
||||
function handleItemMouseOver(e: MouseEvent) {
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
{isSmallScreenSize}
|
||||
path={fileRenderData.path}
|
||||
tags={fileRenderData.tags}
|
||||
isFavorite={fileRenderData.isFavorite}
|
||||
on:favoritePropertyChange
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -53,50 +53,67 @@
|
|||
</script>
|
||||
|
||||
<div class="vault-explorer-pagination-indicator" bind:this={ref}>
|
||||
<Stack
|
||||
align="center"
|
||||
direction={isWrapped ? "row-reverse" : "row"}
|
||||
justify="flex-end"
|
||||
spacing="md"
|
||||
>
|
||||
<Stack spacing="xs">
|
||||
<div class="vault-explorer-pagination-indicator__container">
|
||||
<Stack
|
||||
align="center"
|
||||
direction={isWrapped ? "row-reverse" : "row"}
|
||||
justify="flex-end"
|
||||
spacing="md"
|
||||
>
|
||||
<Flex>
|
||||
<IconButton
|
||||
iconId="chevrons-left"
|
||||
ariaLabel="First page"
|
||||
on:click={() => handlePageChange(1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-left"
|
||||
ariaLabel="Previous page"
|
||||
disabled={currentPage === 1}
|
||||
on:click={() => handlePageChange(currentPage - 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-right"
|
||||
ariaLabel="Next page"
|
||||
disabled={currentPage === totalPages}
|
||||
on:click={() => handlePageChange(currentPage + 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevrons-right"
|
||||
ariaLabel="Last page"
|
||||
on:click={() => handlePageChange(totalPages)}
|
||||
/>
|
||||
</Flex>
|
||||
<Stack spacing="xs">
|
||||
<span>{startIndex + 1}</span>
|
||||
<span>-</span>
|
||||
<span>{endIndex}</span>
|
||||
<Stack spacing="xs">
|
||||
<span>{startIndex + 1}</span>
|
||||
<span>-</span>
|
||||
<span>{endIndex}</span>
|
||||
</Stack>
|
||||
<span>of</span>
|
||||
<span>{totalItems}</span>
|
||||
</Stack>
|
||||
<span>of</span>
|
||||
<span>{totalItems}</span>
|
||||
</Stack>
|
||||
<Flex>
|
||||
<IconButton
|
||||
iconId="chevrons-left"
|
||||
ariaLabel="First page"
|
||||
on:click={() => handlePageChange(1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-left"
|
||||
ariaLabel="Previous page"
|
||||
disabled={currentPage === 1}
|
||||
on:click={() => handlePageChange(currentPage - 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-right"
|
||||
ariaLabel="Next page"
|
||||
disabled={currentPage === totalPages}
|
||||
on:click={() => handlePageChange(currentPage + 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevrons-right"
|
||||
ariaLabel="Last page"
|
||||
on:click={() => handlePageChange(totalPages)}
|
||||
/>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.vault-explorer-pagination-indicator {
|
||||
.vault-explorer-pagination-indicator__container {
|
||||
flex: 1;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
display: flex;
|
||||
border-style: solid;
|
||||
border-width: var(--status-bar-border-width);
|
||||
border-color: var(--status-bar-border-color);
|
||||
background-color: var(--status-bar-background);
|
||||
color: var(--status-bar-text-color);
|
||||
font-size: var(--status-bar-font-size);
|
||||
padding: var(--size-4-1);
|
||||
}
|
||||
|
||||
.vault-explorer-pagination-indicator {
|
||||
display: relative;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,67 @@
|
|||
<script lang="ts">
|
||||
import IconButton from "src/svelte/shared/components/icon-button.svelte";
|
||||
import Stack from "src/svelte/shared/components/stack.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let value: string;
|
||||
|
||||
let inputRef: HTMLInputElement | null;
|
||||
let hidden: boolean = true;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleClearClick() {
|
||||
dispatch("clear", { value: "" });
|
||||
}
|
||||
|
||||
function handleIconClick() {
|
||||
hidden = !hidden;
|
||||
if (!hidden) {
|
||||
requestAnimationFrame(() => {
|
||||
inputRef?.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="vault-explorer-search-filter">
|
||||
<input type="text" placeholder="Search..." {value} on:input />
|
||||
{#if value.length > 0}
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
aria-label="Clear search"
|
||||
class="search-input-clear-button"
|
||||
on:click={() => handleClearClick()}
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleClearClick();
|
||||
}
|
||||
}}
|
||||
<Stack spacing="sm">
|
||||
<div
|
||||
class="vault-explorer-search-filter"
|
||||
style="display: {hidden ? 'none' : 'block'};"
|
||||
>
|
||||
<input
|
||||
bind:this={inputRef}
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
{value}
|
||||
on:input
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{#if value.length > 0}
|
||||
<div
|
||||
tabindex="0"
|
||||
role="button"
|
||||
aria-label="Clear search"
|
||||
class="search-input-clear-button"
|
||||
on:click={() => handleClearClick()}
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleClearClick();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<IconButton
|
||||
iconId="search"
|
||||
ariaLabel="Search"
|
||||
on:click={() => handleIconClick()}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<style>
|
||||
.vault-explorer-search-filter input[type="text"] {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.vault-explorer-search-filter {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,17 @@
|
|||
item.onClick(() => handleValueChange("modified-asc"));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Created time (new to old)");
|
||||
item.setChecked(value === "created-desc");
|
||||
item.onClick(() => handleValueChange("created-desc"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Created time (old to new)");
|
||||
item.setChecked(value === "created-asc");
|
||||
item.onClick(() => handleValueChange("created-asc"));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Random");
|
||||
item.setChecked(value === "random");
|
||||
|
|
|
|||
|
|
@ -42,11 +42,6 @@
|
|||
key: "tags",
|
||||
label: "Tags",
|
||||
},
|
||||
{
|
||||
key: "isFavorite",
|
||||
label: "Favorite",
|
||||
format: (value: unknown) => (value === true ? "Yes" : "No"),
|
||||
},
|
||||
{
|
||||
key: "createdMillis",
|
||||
label: "Created",
|
||||
|
|
@ -85,10 +80,6 @@
|
|||
};
|
||||
});
|
||||
|
||||
function handleFavoriteChange(filePath: string, value: boolean) {
|
||||
dispatch("favoritePropertyChange", { filePath, value });
|
||||
}
|
||||
|
||||
function handleRowClick(path: string) {
|
||||
if (plugin === null) return;
|
||||
|
||||
|
|
@ -108,18 +99,11 @@
|
|||
});
|
||||
}
|
||||
|
||||
function handleRowContextMenu(
|
||||
e: Event,
|
||||
path: string,
|
||||
isFavorite: boolean | null,
|
||||
) {
|
||||
function handleRowContextMenu(e: Event, path: string) {
|
||||
if (plugin === null) return;
|
||||
|
||||
const nativeEvent = e as MouseEvent;
|
||||
openContextMenu(plugin, path, nativeEvent, {
|
||||
isFavorite,
|
||||
onFavoriteChange: handleFavoriteChange,
|
||||
});
|
||||
openContextMenu(plugin, path, nativeEvent, {});
|
||||
}
|
||||
|
||||
function getValue(item: FileRenderData, column: TColumn): unknown {
|
||||
|
|
@ -171,11 +155,7 @@
|
|||
}}
|
||||
on:focus={() => {}}
|
||||
on:contextmenu={(e) =>
|
||||
handleRowContextMenu(
|
||||
e,
|
||||
filteredItem.path,
|
||||
filteredItem.isFavorite,
|
||||
)}
|
||||
handleRowContextMenu(e, filteredItem.path)}
|
||||
on:mouseover={(e) =>
|
||||
handleRowMouseOver(e, filteredItem.path)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Menu } from "obsidian";
|
||||
import IconButton from "src/svelte/shared/components/icon-button.svelte";
|
||||
import { TimestampFilterOption } from "src/types";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let value: TimestampFilterOption;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleValueChange(value: TimestampFilterOption) {
|
||||
dispatch("change", { value });
|
||||
}
|
||||
|
||||
function handleButtonClick(e: CustomEvent) {
|
||||
const nativeEvent = e.detail.nativeEvent as MouseEvent;
|
||||
|
||||
const menu = new Menu();
|
||||
menu.setUseNativeMenu(true);
|
||||
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("All");
|
||||
item.setChecked(value === "all");
|
||||
item.onClick(() => handleValueChange("all"));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Modified today");
|
||||
item.setChecked(value === "modified-today");
|
||||
item.onClick(() => handleValueChange("modified-today"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Created today");
|
||||
item.setChecked(value === "created-today");
|
||||
item.onClick(() => handleValueChange("created-today"));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Modifed this week");
|
||||
item.setChecked(value === "modified-this-week");
|
||||
item.onClick(() => handleValueChange("modified-this-week"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Created this week");
|
||||
item.setChecked(value === "created-this-week");
|
||||
item.onClick(() => handleValueChange("created-this-week"));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Modifed 2 weeks");
|
||||
item.setChecked(value === "modified-2-weeks");
|
||||
item.onClick(() => handleValueChange("modified-2-weeks"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Created 2 weeks");
|
||||
item.setChecked(value === "created-2-weeks");
|
||||
item.onClick(() => handleValueChange("created-2-weeks"));
|
||||
});
|
||||
menu.showAtMouseEvent(nativeEvent);
|
||||
}
|
||||
</script>
|
||||
|
||||
<IconButton
|
||||
ariaLabel="Change timestamp filter"
|
||||
iconId="clock"
|
||||
on:click={handleButtonClick}
|
||||
/>
|
||||
|
|
@ -4,16 +4,13 @@
|
|||
// ============================================
|
||||
import Stack from "../shared/components/stack.svelte";
|
||||
import Flex from "../shared/components/flex.svelte";
|
||||
import FavoritesFilter from "./components/favorites-filter.svelte";
|
||||
import TabList from "../shared/components/tab-list.svelte";
|
||||
import Tab from "../shared/components/tab.svelte";
|
||||
import { Notice, TFile } from "obsidian";
|
||||
import {
|
||||
TCustomFilter,
|
||||
TFavoritesFilter,
|
||||
TSearchFilter,
|
||||
TSortFilter,
|
||||
TTimestampFilter,
|
||||
TExplorerView,
|
||||
CoverImageFit,
|
||||
} from "src/types";
|
||||
|
|
@ -21,9 +18,7 @@
|
|||
import VaultExplorerPlugin from "src/main";
|
||||
import GridView from "./components/grid-view.svelte";
|
||||
import ListView from "./components/list-view.svelte";
|
||||
import { filterByFavorites } from "./services/filters/favorite-filter";
|
||||
import { filterBySearch } from "./services/filters/search-filter";
|
||||
import { filterByTimestamp } from "./services/filters/timestamp-filter";
|
||||
import { filterByGroups } from "./services/filters/custom/filter-by-groups";
|
||||
import { formatFileDataForRender } from "./services/render-data";
|
||||
import _ from "lodash";
|
||||
|
|
@ -38,7 +33,6 @@
|
|||
import { FileRenderData } from "./types";
|
||||
import Logger from "js-logger";
|
||||
import SearchFilter from "./components/search-filter.svelte";
|
||||
import TimestampFilter from "./components/timestamp-filter.svelte";
|
||||
import SortFilter from "./components/sort-filter.svelte";
|
||||
import { DEBOUNCE_INPUT_TIME, SCREEN_SIZE_MD } from "./constants";
|
||||
import FeedView from "./components/feed-view.svelte";
|
||||
|
|
@ -82,14 +76,6 @@
|
|||
isEnabled: true,
|
||||
value: "",
|
||||
};
|
||||
let favoritesFilter: TFavoritesFilter = {
|
||||
isEnabled: false,
|
||||
value: false,
|
||||
};
|
||||
let timestampFilter: TTimestampFilter = {
|
||||
isEnabled: true,
|
||||
value: "all",
|
||||
};
|
||||
let sortFilter: TSortFilter = {
|
||||
isEnabled: true,
|
||||
value: "file-name-asc",
|
||||
|
|
@ -146,9 +132,7 @@
|
|||
shouldCollapseFilters = settings.shouldCollapseFilters;
|
||||
pageSize = settings.pageSize;
|
||||
searchFilter = settings.filters.search;
|
||||
favoritesFilter = settings.filters.favorites;
|
||||
sortFilter = settings.filters.sort;
|
||||
timestampFilter = settings.filters.timestamp;
|
||||
currentView = settings.currentView;
|
||||
customFilter = settings.filters.custom;
|
||||
viewOrder = settings.viewOrder;
|
||||
|
|
@ -171,9 +155,7 @@
|
|||
});
|
||||
|
||||
searchFilter = plugin.settings.filters.search;
|
||||
favoritesFilter = plugin.settings.filters.favorites;
|
||||
sortFilter = plugin.settings.filters.sort;
|
||||
timestampFilter = plugin.settings.filters.timestamp;
|
||||
customFilter = plugin.settings.filters.custom;
|
||||
}
|
||||
|
||||
|
|
@ -579,10 +561,6 @@
|
|||
searchFilter.value = e.target.value;
|
||||
}, DEBOUNCE_INPUT_TIME);
|
||||
|
||||
const debounceFavoriteFilterChange = _.debounce((value) => {
|
||||
favoritesFilter.value = value;
|
||||
}, DEBOUNCE_INPUT_TIME);
|
||||
|
||||
function handleReshuffleClick() {
|
||||
randomFileSortStore.load(plugin.app);
|
||||
}
|
||||
|
|
@ -619,8 +597,6 @@
|
|||
async function saveSettings() {
|
||||
plugin.settings.filters.search = searchFilter;
|
||||
plugin.settings.filters.sort = sortFilter;
|
||||
plugin.settings.filters.timestamp = timestampFilter;
|
||||
plugin.settings.filters.favorites = favoritesFilter;
|
||||
plugin.settings.currentView = currentView;
|
||||
plugin.settings.filters.custom = customFilter;
|
||||
plugin.settings.viewOrder = viewOrder;
|
||||
|
|
@ -672,20 +648,11 @@
|
|||
customFilter.groups = newGroups;
|
||||
}
|
||||
|
||||
function handleListViewTagsToggle() {
|
||||
showListViewTags = !showListViewTags;
|
||||
}
|
||||
|
||||
function handleViewDragOver(e: CustomEvent) {
|
||||
const { nativeEvent } = e.detail;
|
||||
nativeEvent.preventDefault();
|
||||
}
|
||||
|
||||
function handleTimestampFilterChange(e: CustomEvent) {
|
||||
const { value } = e.detail;
|
||||
timestampFilter.value = value;
|
||||
}
|
||||
|
||||
function handleViewDragStart(e: CustomEvent, id: string) {
|
||||
const { nativeEvent } = e.detail;
|
||||
nativeEvent.dataTransfer.setData("text", id);
|
||||
|
|
@ -778,12 +745,6 @@
|
|||
sortFilter.value = value;
|
||||
}
|
||||
|
||||
function handleFavoritesChange(e: CustomEvent) {
|
||||
const nativeEvent = e.detail.nativeEvent;
|
||||
const value = (nativeEvent.target as HTMLInputElement).checked;
|
||||
debounceFavoriteFilterChange(value);
|
||||
}
|
||||
|
||||
function handleCoverImageFitChange(e: CustomEvent) {
|
||||
const { filePath, value } = e.detail as {
|
||||
filePath: string;
|
||||
|
|
@ -793,14 +754,6 @@
|
|||
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({
|
||||
|
|
@ -819,43 +772,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function handleFavoritePropertyChange(e: CustomEvent) {
|
||||
const { filePath, value } = e.detail as {
|
||||
filePath: string;
|
||||
value: boolean;
|
||||
};
|
||||
|
||||
const { properties } = plugin.settings;
|
||||
const { favorite: favoritePropertyName } = properties;
|
||||
|
||||
//If the favorite property is not set, return
|
||||
if (favoritePropertyName === "") {
|
||||
new Notice(
|
||||
"Vault Explorer: Please set a favorite 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: "handleFavoritePropertyChange",
|
||||
message: "file not found. returning...",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.extension === "md") {
|
||||
plugin.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
frontmatter[favoritePropertyName] = value;
|
||||
return frontmatter;
|
||||
});
|
||||
} else {
|
||||
favoritesStore.setFavorite(filePath, value);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCustomFilterClick() {
|
||||
new CustomFilterModal(plugin).open();
|
||||
}
|
||||
|
|
@ -895,7 +811,6 @@
|
|||
) {
|
||||
formatted = filteredCustom.map((loadedFile) => {
|
||||
const { id, file } = loadedFile;
|
||||
const isFavorite = favoritesCache.get(file.path) ?? null;
|
||||
const content = contentCache.get(file.path) ?? null;
|
||||
|
||||
return formatFileDataForRender({
|
||||
|
|
@ -904,7 +819,6 @@
|
|||
fileId: id,
|
||||
file,
|
||||
fileContent: content,
|
||||
fileFavorite: isFavorite,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -917,27 +831,7 @@
|
|||
return true;
|
||||
});
|
||||
|
||||
$: filteredFavorites = filteredSearch.filter((file) => {
|
||||
const { isEnabled, value } = favoritesFilter;
|
||||
if (isEnabled) {
|
||||
return filterByFavorites(file, value);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
$: filteredTimestamp = filteredFavorites.filter((file) => {
|
||||
const { modifiedMillis, createdMillis } = file;
|
||||
return filterByTimestamp({
|
||||
value: timestampFilter.value,
|
||||
createdMillis,
|
||||
modifiedMillis,
|
||||
startOfTodayMillis,
|
||||
startOfThisWeekMillis,
|
||||
startOfLastWeekMillis,
|
||||
});
|
||||
});
|
||||
|
||||
$: renderData = [...filteredTimestamp].sort((a, b) => {
|
||||
$: renderData = [...filteredSearch].sort((a, b) => {
|
||||
const { value } = sortFilter;
|
||||
if (value === "file-name-asc") {
|
||||
return a.displayName
|
||||
|
|
@ -951,6 +845,10 @@
|
|||
return a.modifiedMillis - b.modifiedMillis;
|
||||
} else if (value === "modified-desc") {
|
||||
return b.modifiedMillis - a.modifiedMillis;
|
||||
} else if (value === "created-asc") {
|
||||
return a.createdMillis - b.createdMillis;
|
||||
} else if (value === "created-desc") {
|
||||
return b.createdMillis - a.createdMillis;
|
||||
} else if (value === "random") {
|
||||
const sortKeyA = randomSortCache.get(a.path) ?? 0;
|
||||
const sortKeyB = randomSortCache.get(b.path) ?? 0;
|
||||
|
|
@ -966,8 +864,6 @@
|
|||
//and save the settings again
|
||||
$: searchFilter,
|
||||
sortFilter,
|
||||
timestampFilter,
|
||||
favoritesFilter,
|
||||
currentView,
|
||||
customFilter,
|
||||
viewOrder,
|
||||
|
|
@ -992,64 +888,25 @@
|
|||
<div class="vault-explorer" bind:this={ref}>
|
||||
{#if shouldCollapseFilters === false}
|
||||
<div class="vault-explorer-filters">
|
||||
<Stack spacing="md" direction="column">
|
||||
{#if searchFilter.isEnabled}
|
||||
<SearchFilter
|
||||
value={searchFilter.value}
|
||||
on:input={debounceSearchFilterChange}
|
||||
on:clear={() => (searchFilter.value = "")}
|
||||
/>
|
||||
{/if}
|
||||
<Stack direction="column" spacing="sm">
|
||||
<Flex justify="space-between">
|
||||
<Stack spacing="sm">
|
||||
{#if favoritesFilter.isEnabled}
|
||||
<FavoritesFilter
|
||||
value={favoritesFilter.value}
|
||||
on:change={handleFavoritesChange}
|
||||
/>
|
||||
{/if}
|
||||
<Flex>
|
||||
{#if timestampFilter.isEnabled}
|
||||
<TimestampFilter
|
||||
value={timestampFilter.value}
|
||||
on:change={handleTimestampFilterChange}
|
||||
/>
|
||||
{/if}
|
||||
{#if sortFilter.isEnabled}
|
||||
<SortFilter
|
||||
value={sortFilter.value}
|
||||
on:change={handleSortChange}
|
||||
/>
|
||||
{/if}
|
||||
{#if sortFilter.value == "random"}
|
||||
<IconButton
|
||||
iconId="shuffle"
|
||||
ariaLabel="Reshuffle files"
|
||||
on:click={handleReshuffleClick}
|
||||
/>
|
||||
{/if}
|
||||
<IconButton
|
||||
ariaLabel="Change custom filter"
|
||||
iconId="list-filter"
|
||||
on:click={handleCustomFilterClick}
|
||||
/>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Flex>
|
||||
<Flex justify="space-between">
|
||||
{#if customFilter.isEnabled}
|
||||
<FilterGroupList
|
||||
groups={customFilter.groups}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:groupContextMenu={handleGroupContextMenu}
|
||||
on:groupDrop={handleGroupDrop}
|
||||
on:groupDragOver={handleGroupDragOver}
|
||||
on:groupDragStart={handleGroupDragStart}
|
||||
/>
|
||||
{/if}
|
||||
</Flex>
|
||||
</Stack>
|
||||
<Stack spacing="sm" direction="column">
|
||||
<Flex justify="space-between">
|
||||
{#if customFilter.isEnabled}
|
||||
<FilterGroupList
|
||||
groups={customFilter.groups}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:groupContextMenu={handleGroupContextMenu}
|
||||
on:groupDrop={handleGroupDrop}
|
||||
on:groupDragOver={handleGroupDragOver}
|
||||
on:groupDragStart={handleGroupDragStart}
|
||||
/>
|
||||
{/if}
|
||||
</Flex>
|
||||
<div>
|
||||
<button
|
||||
class="vault-explorer-button"
|
||||
on:click={handleCustomFilterClick}>Configure</button
|
||||
>
|
||||
</div>
|
||||
</Stack>
|
||||
<Spacer size="md" />
|
||||
</div>
|
||||
|
|
@ -1081,24 +938,28 @@
|
|||
/> -->
|
||||
<!-- </Stack> -->
|
||||
</div>
|
||||
<Stack spacing="sm">
|
||||
{#if currentView === "list"}
|
||||
<IconButton
|
||||
iconId="tags"
|
||||
ariaLabel="Toggle tags"
|
||||
on:click={handleListViewTagsToggle}
|
||||
<Flex>
|
||||
{#if searchFilter.isEnabled}
|
||||
<SearchFilter
|
||||
value={searchFilter.value}
|
||||
on:input={debounceSearchFilterChange}
|
||||
on:clear={() => (searchFilter.value = "")}
|
||||
/>
|
||||
<Divider direction="vertical" />
|
||||
{/if}
|
||||
<PaginationIndicator
|
||||
{startIndex}
|
||||
{endIndex}
|
||||
{currentPage}
|
||||
{totalPages}
|
||||
{totalItems}
|
||||
on:change={handlePageChange}
|
||||
/>
|
||||
</Stack>
|
||||
{#if sortFilter.isEnabled}
|
||||
<SortFilter
|
||||
value={sortFilter.value}
|
||||
on:change={handleSortChange}
|
||||
/>
|
||||
{/if}
|
||||
{#if sortFilter.value == "random"}
|
||||
<IconButton
|
||||
iconId="shuffle"
|
||||
ariaLabel="Reshuffle files"
|
||||
on:click={handleReshuffleClick}
|
||||
/>
|
||||
{/if}
|
||||
</Flex>
|
||||
</Wrap>
|
||||
<Spacer size="md" />
|
||||
{#if currentView === "grid"}
|
||||
|
|
@ -1106,7 +967,6 @@
|
|||
data={renderData}
|
||||
{startIndex}
|
||||
{pageLength}
|
||||
on:favoritePropertyChange={handleFavoritePropertyChange}
|
||||
on:coverImageFitChange={handleCoverImageFitChange}
|
||||
/>
|
||||
{:else if currentView === "list"}
|
||||
|
|
@ -1116,23 +976,20 @@
|
|||
showTags={showListViewTags}
|
||||
{startIndex}
|
||||
{pageLength}
|
||||
on:favoritePropertyChange={handleFavoritePropertyChange}
|
||||
/>
|
||||
{:else if currentView === "table"}
|
||||
<TableView
|
||||
data={renderData}
|
||||
{startIndex}
|
||||
{pageLength}
|
||||
on:favoritePropertyChange={handleFavoritePropertyChange}
|
||||
/>
|
||||
<TableView data={renderData} {startIndex} {pageLength} />
|
||||
{:else if currentView === "feed"}
|
||||
<FeedView
|
||||
data={renderData}
|
||||
{startIndex}
|
||||
{pageLength}
|
||||
on:favoritePropertyChange={handleFavoritePropertyChange}
|
||||
/>
|
||||
<FeedView data={renderData} {startIndex} {pageLength} />
|
||||
{/if}
|
||||
<PaginationIndicator
|
||||
{startIndex}
|
||||
{endIndex}
|
||||
{currentPage}
|
||||
{totalPages}
|
||||
{totalItems}
|
||||
on:change={handlePageChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
@ -1144,4 +1001,14 @@
|
|||
.vault-explorer-view-select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.vault-explorer-button {
|
||||
background: none;
|
||||
text-decoration: underline;
|
||||
color: var(--text-faint);
|
||||
font-size: var(--font-small);
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,14 +7,10 @@ export const openContextMenu = (
|
|||
filePath: string,
|
||||
e: MouseEvent,
|
||||
{
|
||||
isFavorite,
|
||||
coverImageFit,
|
||||
onFavoriteChange,
|
||||
onCoverImageFitChange,
|
||||
}: {
|
||||
isFavorite: boolean | null;
|
||||
coverImageFit?: CoverImageFit;
|
||||
onFavoriteChange: (filePath: string, value: boolean) => void;
|
||||
onCoverImageFitChange?: (
|
||||
filePath: string,
|
||||
value: CoverImageFit
|
||||
|
|
@ -35,25 +31,15 @@ export const openContextMenu = (
|
|||
item.setTitle("Open in new window");
|
||||
item.onClick(() => openInNewWindow(plugin, filePath));
|
||||
});
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle(
|
||||
isFavorite ? "Remove from favorites" : "Add to favorites"
|
||||
);
|
||||
item.onClick(() => {
|
||||
const newValue = isFavorite !== null ? !isFavorite : true;
|
||||
onFavoriteChange(filePath, newValue);
|
||||
});
|
||||
});
|
||||
if (coverImageFit !== undefined && onCoverImageFitChange !== undefined) {
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Cover image fit: cover");
|
||||
item.setTitle("Cover");
|
||||
item.setChecked(coverImageFit === "cover");
|
||||
item.onClick(() => onCoverImageFitChange(filePath, "cover"));
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Cover image fit: contain");
|
||||
item.setTitle("Contain");
|
||||
item.setChecked(coverImageFit === "contain");
|
||||
item.onClick(() => onCoverImageFitChange(filePath, "contain"));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
import { FileRenderData } from "../../types";
|
||||
|
||||
export const filterByFavorites = (
|
||||
file: FileRenderData,
|
||||
onlyFavorites: boolean
|
||||
) => {
|
||||
if (onlyFavorites) {
|
||||
return file.isFavorite;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
import { TimestampFilterOption } from "src/types";
|
||||
|
||||
interface FilterByTimestampParams {
|
||||
value: TimestampFilterOption;
|
||||
createdMillis: number;
|
||||
modifiedMillis: number;
|
||||
startOfTodayMillis: number;
|
||||
startOfThisWeekMillis: number;
|
||||
startOfLastWeekMillis: number;
|
||||
}
|
||||
|
||||
export const filterByTimestamp = ({
|
||||
value,
|
||||
createdMillis,
|
||||
modifiedMillis,
|
||||
startOfTodayMillis,
|
||||
startOfThisWeekMillis,
|
||||
startOfLastWeekMillis,
|
||||
}: FilterByTimestampParams) => {
|
||||
if (value === "modified-this-week") {
|
||||
return modifiedMillis > startOfThisWeekMillis;
|
||||
} else if (value === "created-this-week") {
|
||||
return createdMillis > startOfThisWeekMillis;
|
||||
} else if (value === "modified-2-weeks") {
|
||||
return modifiedMillis > startOfLastWeekMillis;
|
||||
} else if (value === "created-2-weeks") {
|
||||
return createdMillis > startOfLastWeekMillis;
|
||||
} else if (value === "modified-today") {
|
||||
return modifiedMillis > startOfTodayMillis;
|
||||
} else if (value === "created-today") {
|
||||
return createdMillis > startOfTodayMillis;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -46,14 +46,12 @@ export const formatFileDataForRender = ({
|
|||
file,
|
||||
fileId,
|
||||
fileContent,
|
||||
fileFavorite,
|
||||
}: {
|
||||
app: App;
|
||||
settings: VaultExplorerPluginSettings;
|
||||
file: TFile;
|
||||
fileId: string;
|
||||
fileContent: string | null;
|
||||
fileFavorite: boolean | null;
|
||||
}): FileRenderData => {
|
||||
const { name, basename, extension, path } = file;
|
||||
|
||||
|
|
@ -67,7 +65,6 @@ export const formatFileDataForRender = ({
|
|||
url: urlProp,
|
||||
image: imageProp,
|
||||
coverImageFit: coverImageFitProp,
|
||||
favorite: favoriteProp,
|
||||
custom1: custom1Prop,
|
||||
custom2: custom2Prop,
|
||||
custom3: custom3Prop,
|
||||
|
|
@ -96,17 +93,6 @@ export const formatFileDataForRender = ({
|
|||
PropertyType.TEXT
|
||||
);
|
||||
|
||||
let isFavorite: boolean | null;
|
||||
if (fileFavorite === null) {
|
||||
isFavorite = loadPropertyValue<boolean>(
|
||||
fileFrontmatter,
|
||||
favoriteProp,
|
||||
PropertyType.CHECKBOX
|
||||
);
|
||||
} else {
|
||||
isFavorite = fileFavorite;
|
||||
}
|
||||
|
||||
let coverImageFit: CoverImageFit | null = loadPropertyValue<string>(
|
||||
fileFrontmatter,
|
||||
coverImageFitProp,
|
||||
|
|
@ -250,7 +236,6 @@ export const formatFileDataForRender = ({
|
|||
content: fileContent,
|
||||
tags,
|
||||
imageUrl,
|
||||
isFavorite,
|
||||
createdMillis,
|
||||
modifiedMillis,
|
||||
custom1,
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ export const clearSocialMediaImageCache = async () => {
|
|||
try {
|
||||
const db = await openDatabase();
|
||||
await db.clear(STORE_NAME);
|
||||
new Notice("Vault Explorer: social media image cache cleared");
|
||||
new Notice("Vault Explorer: Image cache cleared");
|
||||
} catch (err) {
|
||||
new Notice("Failed to clear social media image cache");
|
||||
new Notice("Vault Explorer: Failed to clear image cache");
|
||||
const error = err as Error;
|
||||
Logger.error(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const formatAsBearTimeString = (milliseconds: number) => {
|
|||
return `${diffInHours} hours ago`;
|
||||
}
|
||||
if (diffInDays === 1) {
|
||||
return `Yesterday at ${time.format("hh:mm A")}`;
|
||||
return `Yesterday at ${time.format("h:mm A")}`;
|
||||
}
|
||||
if (time.year() === now.year()) {
|
||||
return time.format("MMMM D");
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ export interface FileRenderData {
|
|||
url: string | null;
|
||||
imageUrl: string | null;
|
||||
tags: string[] | null;
|
||||
isFavorite: boolean | null;
|
||||
createdMillis: number;
|
||||
modifiedMillis: number;
|
||||
custom1: string | null;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
}
|
||||
|
||||
$: className = getClassName(noPadding);
|
||||
$: hasSlotContent = !!$$slots.default;
|
||||
</script>
|
||||
|
||||
<button
|
||||
|
|
@ -34,9 +35,14 @@
|
|||
{disabled}
|
||||
aria-label={ariaLabel}
|
||||
on:click={handleClick}
|
||||
><Icon {iconId} {size} />
|
||||
<div class="vault-explorer-icon-button__text"><slot /></div></button
|
||||
>
|
||||
<Icon {iconId} {size} />
|
||||
{#if hasSlotContent}
|
||||
<div class="vault-explorer-icon-button__text">
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.vault-explorer-icon-button--no-padding {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
(typedObj["properties"] !== null &&
|
||||
typeof typedObj["properties"] === "object" ||
|
||||
typeof typedObj["properties"] === "function") &&
|
||||
typeof typedObj["properties"]["favorite"] === "string" &&
|
||||
typeof typedObj["properties"]["url"] === "string" &&
|
||||
typeof typedObj["properties"]["image"] === "string" &&
|
||||
typeof typedObj["properties"]["coverImageFit"] === "string" &&
|
||||
|
|
@ -30,11 +29,6 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
typeof typedObj["filters"]["search"] === "function") &&
|
||||
typeof typedObj["filters"]["search"]["isEnabled"] === "boolean" &&
|
||||
typeof typedObj["filters"]["search"]["value"] === "string" &&
|
||||
(typedObj["filters"]["favorites"] !== null &&
|
||||
typeof typedObj["filters"]["favorites"] === "object" ||
|
||||
typeof typedObj["filters"]["favorites"] === "function") &&
|
||||
typeof typedObj["filters"]["favorites"]["isEnabled"] === "boolean" &&
|
||||
typeof typedObj["filters"]["favorites"]["value"] === "boolean" &&
|
||||
(typedObj["filters"]["sort"] !== null &&
|
||||
typeof typedObj["filters"]["sort"] === "object" ||
|
||||
typeof typedObj["filters"]["sort"] === "function") &&
|
||||
|
|
@ -43,18 +37,9 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
typedObj["filters"]["sort"]["value"] === "file-name-desc" ||
|
||||
typedObj["filters"]["sort"]["value"] === "modified-asc" ||
|
||||
typedObj["filters"]["sort"]["value"] === "modified-desc" ||
|
||||
typedObj["filters"]["sort"]["value"] === "created-asc" ||
|
||||
typedObj["filters"]["sort"]["value"] === "created-desc" ||
|
||||
typedObj["filters"]["sort"]["value"] === "random") &&
|
||||
(typedObj["filters"]["timestamp"] !== null &&
|
||||
typeof typedObj["filters"]["timestamp"] === "object" ||
|
||||
typeof typedObj["filters"]["timestamp"] === "function") &&
|
||||
typeof typedObj["filters"]["timestamp"]["isEnabled"] === "boolean" &&
|
||||
(typedObj["filters"]["timestamp"]["value"] === "created-today" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "modified-today" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "created-this-week" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "modified-this-week" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "created-2-weeks" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "modified-2-weeks" ||
|
||||
typedObj["filters"]["timestamp"]["value"] === "all") &&
|
||||
(typedObj["filters"]["custom"] !== null &&
|
||||
typeof typedObj["filters"]["custom"] === "object" ||
|
||||
typeof typedObj["filters"]["custom"] === "function") &&
|
||||
|
|
@ -608,9 +593,7 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
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") &&
|
||||
typedObj["views"]["grid"]["coverImageFit"] === "contain") &&
|
||||
typeof typedObj["views"]["grid"]["loadSocialMediaImage"] === "boolean" &&
|
||||
(typedObj["views"]["list"] !== null &&
|
||||
typeof typedObj["views"]["list"] === "object" ||
|
||||
|
|
@ -653,8 +636,6 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore
|
|||
typedObj["currentView"] === TExplorerView.RECOMMENDED ||
|
||||
typedObj["currentView"] === TExplorerView.RELATED) &&
|
||||
typeof typedObj["pageSize"] === "number" &&
|
||||
typeof typedObj["filterGroupsWidth"] === "string" &&
|
||||
typeof typedObj["shouldWrapFilterGroups"] === "boolean" &&
|
||||
typeof typedObj["shouldCollapseFilters"] === "boolean" &&
|
||||
Array.isArray(typedObj["viewOrder"]) &&
|
||||
typedObj["viewOrder"].every((e: any) =>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/** @see {isVaultExplorerPluginSettings} ts-auto-guard:type-guard */
|
||||
export interface VaultExplorerPluginSettings {
|
||||
properties: {
|
||||
favorite: string;
|
||||
url: string;
|
||||
image: string;
|
||||
coverImageFit: string;
|
||||
|
|
@ -13,9 +12,7 @@ export interface VaultExplorerPluginSettings {
|
|||
};
|
||||
filters: {
|
||||
search: TSearchFilter;
|
||||
favorites: TFavoritesFilter;
|
||||
sort: TSortFilter;
|
||||
timestamp: TTimestampFilter;
|
||||
custom: TCustomFilter;
|
||||
};
|
||||
views: {
|
||||
|
|
@ -33,8 +30,6 @@ export interface VaultExplorerPluginSettings {
|
|||
loadBodyTags: boolean;
|
||||
currentView: TExplorerView | null;
|
||||
pageSize: number;
|
||||
filterGroupsWidth: string;
|
||||
shouldWrapFilterGroups: boolean;
|
||||
shouldCollapseFilters: boolean;
|
||||
viewOrder: TExplorerView[];
|
||||
configDir: string;
|
||||
|
|
@ -97,37 +92,22 @@ export interface TSearchFilter extends BaseFilter {
|
|||
value: string;
|
||||
}
|
||||
|
||||
export interface TFavoritesFilter extends BaseFilter {
|
||||
value: boolean;
|
||||
}
|
||||
|
||||
export interface TSortFilter extends BaseFilter {
|
||||
value: SortFilterOption;
|
||||
}
|
||||
|
||||
export interface TTimestampFilter extends BaseFilter {
|
||||
value: TimestampFilterOption;
|
||||
}
|
||||
|
||||
export interface TCustomFilter extends BaseFilter {
|
||||
selectedGroupId: string;
|
||||
groups: TFilterGroup[];
|
||||
}
|
||||
|
||||
export type TimestampFilterOption =
|
||||
| "created-today"
|
||||
| "modified-today"
|
||||
| "created-this-week"
|
||||
| "modified-this-week"
|
||||
| "created-2-weeks"
|
||||
| "modified-2-weeks"
|
||||
| "all";
|
||||
|
||||
export type SortFilterOption =
|
||||
| "file-name-asc"
|
||||
| "file-name-desc"
|
||||
| "modified-asc"
|
||||
| "modified-desc"
|
||||
| "created-asc"
|
||||
| "created-desc"
|
||||
| "random";
|
||||
|
||||
export type WordBreak = "normal" | "break-word";
|
||||
|
|
|
|||
332
src/types/types-1.41.1.ts
Normal file
332
src/types/types-1.41.1.ts
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
export interface VaultExplorerPluginSettings_1_41_1 {
|
||||
properties: {
|
||||
favorite: string;
|
||||
url: string;
|
||||
image: string;
|
||||
coverImageFit: 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[];
|
||||
coverImageFit: CoverImageFit;
|
||||
loadSocialMediaImage: boolean;
|
||||
}
|
||||
|
||||
interface CoverImageSource {
|
||||
type: CoverImageSourceType;
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
type CoverImageFit = "cover" | "contain";
|
||||
|
||||
type CoverImageSourceType =
|
||||
| "image-property"
|
||||
| "url-property"
|
||||
| "frontmatter"
|
||||
| "body";
|
||||
|
||||
interface TDashboardView extends BaseView {}
|
||||
|
||||
type CollapseStyle = "no-new-lines" | "no-extra-new-lines";
|
||||
|
||||
interface TFeedView extends BaseView {
|
||||
collapseStyle: CollapseStyle;
|
||||
removeH1: boolean;
|
||||
lineClampSmall: number;
|
||||
lineClampMedium: number;
|
||||
lineClampLarge: number;
|
||||
}
|
||||
|
||||
interface TRecommendedView extends BaseView {}
|
||||
|
||||
interface TRelatedView extends BaseView {}
|
||||
|
||||
interface BaseFilter {
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
interface TSearchFilter extends BaseFilter {
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface 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;
|
||||
}
|
||||
|
|
@ -9,30 +9,22 @@
|
|||
"modifiedDate": "modification",
|
||||
"createdDate": "creation",
|
||||
"image": "image",
|
||||
"coverImageFit": ""
|
||||
"coverImageFit": "image-fit"
|
||||
},
|
||||
"filters": {
|
||||
"search": {
|
||||
"isEnabled": true,
|
||||
"value": ""
|
||||
},
|
||||
"timestamp": {
|
||||
"isEnabled": true,
|
||||
"value": "all"
|
||||
},
|
||||
"sort": {
|
||||
"isEnabled": true,
|
||||
"value": "file-name-asc"
|
||||
"value": "modified-desc"
|
||||
},
|
||||
"custom": {
|
||||
"isEnabled": true,
|
||||
"selectedGroupId": "",
|
||||
"groups": []
|
||||
},
|
||||
"favorites": {
|
||||
"isEnabled": true,
|
||||
"value": false
|
||||
},
|
||||
"properties": {
|
||||
"groups": []
|
||||
}
|
||||
|
|
@ -94,8 +86,6 @@
|
|||
"enableClockUpdates": true,
|
||||
"enableFileIcons": true,
|
||||
"loadBodyTags": true,
|
||||
"filterGroupsWidth": "69px",
|
||||
"shouldWrapFilterGroups": false,
|
||||
"shouldCollapseFilters": false,
|
||||
"pageSize": 25,
|
||||
"viewOrder": [
|
||||
|
|
@ -105,6 +95,6 @@
|
|||
"feed"
|
||||
],
|
||||
"configDir": ".vaultexplorer",
|
||||
"pluginVersion": "1.41.0",
|
||||
"pluginVersion": "1.42.0",
|
||||
"logLevel": "trace"
|
||||
}
|
||||
|
|
@ -136,5 +136,6 @@
|
|||
"1.40.1": "1.4.13",
|
||||
"1.40.2": "1.4.13",
|
||||
"1.41.0": "1.4.13",
|
||||
"1.41.1": "1.4.13"
|
||||
"1.41.1": "1.4.13",
|
||||
"1.42.0": "1.4.13"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue