#60 - Simplified integration with obsidian-icon-folder plugin
- the plugin integration and matching part completed - unit tests
This commit is contained in:
parent
18faf70b5e
commit
01af14b174
|
@ -8,7 +8,8 @@ export enum CustomSortGroupType {
|
|||
ExactSuffix,
|
||||
ExactHeadAndTail, // Like W...n or Un...ed, which is shorter variant of typing the entire title
|
||||
HasMetadataField, // Notes (or folder's notes) containing a specific metadata field
|
||||
StarredOnly
|
||||
StarredOnly,
|
||||
IconFolderPlugin
|
||||
}
|
||||
|
||||
export enum CustomSortOrder {
|
||||
|
@ -59,6 +60,7 @@ export interface CustomSortGroup {
|
|||
matchFilenameWithExt?: boolean
|
||||
foldersOnly?: boolean
|
||||
withMetadataFieldName?: string // for 'with-metadata:' grouping
|
||||
folderIconName?: string // for integration with obsidian-folder-icon community plugin
|
||||
priority?: number
|
||||
combineWithIdx?: number
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ import {
|
|||
import {CustomSortGroupType, CustomSortOrder, CustomSortSpec, RegExpSpec} from './custom-sort-types';
|
||||
import {CompoundDashNumberNormalizerFn, CompoundDotRomanNumberNormalizerFn} from "./sorting-spec-processor";
|
||||
import {findStarredFile_pathParam, Starred_PluginInstance} from "../utils/StarredPluginSignature";
|
||||
import {
|
||||
ObsidianIconFolder_PluginInstance,
|
||||
ObsidianIconFolderPlugin_Data
|
||||
} from "../utils/ObsidianIconFolderPluginSignature";
|
||||
|
||||
const mockTFile = (basename: string, ext: string, size?: number, ctime?: number, mtime?: number): TFile => {
|
||||
return {
|
||||
|
@ -1067,6 +1071,458 @@ describe('determineSortingGroup', () => {
|
|||
expect(starredPluginInstance.findStarredFile).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
})
|
||||
describe('CustomSortGroupType.IconFolderPlugin', () => {
|
||||
it('should not match file w/o icon', () => {
|
||||
// given
|
||||
const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333);
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {settings: {}} // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(file, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 1, // The lastIdx+1, group not determined
|
||||
isFolder: false,
|
||||
sortString: "References.md",
|
||||
ctimeNewest: MOCK_TIMESTAMP + 222,
|
||||
ctimeOldest: MOCK_TIMESTAMP + 222,
|
||||
mtime: MOCK_TIMESTAMP + 333,
|
||||
path: 'Some parent folder/References.md'
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should not match file with icon of different name', () => {
|
||||
// given
|
||||
const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333);
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'IncorrectIconName'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'Some parent folder/References.md': 'CorrectIconName'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(file, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 1, // The lastIdx+1, group not determined
|
||||
isFolder: false,
|
||||
sortString: "References.md",
|
||||
ctimeNewest: MOCK_TIMESTAMP + 222,
|
||||
ctimeOldest: MOCK_TIMESTAMP + 222,
|
||||
mtime: MOCK_TIMESTAMP + 333,
|
||||
path: 'Some parent folder/References.md'
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match file with any icon', () => {
|
||||
// given
|
||||
const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333);
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'Some parent folder/References.md': 'Irrelevant icon name, only presence matters'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(file, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: false,
|
||||
sortString: "References.md",
|
||||
ctimeNewest: MOCK_TIMESTAMP + 222,
|
||||
ctimeOldest: MOCK_TIMESTAMP + 222,
|
||||
mtime: MOCK_TIMESTAMP + 333,
|
||||
path: 'Some parent folder/References.md'
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match file with icon of expected name', () => {
|
||||
// given
|
||||
const file: TFile = mockTFile('References', 'md', 111, MOCK_TIMESTAMP + 222, MOCK_TIMESTAMP + 333);
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'CorrectIconName'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'Some parent folder/References.md': 'CorrectIconName'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(file, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: false,
|
||||
sortString: "References.md",
|
||||
ctimeNewest: MOCK_TIMESTAMP + 222,
|
||||
ctimeOldest: MOCK_TIMESTAMP + 222,
|
||||
mtime: MOCK_TIMESTAMP + 333,
|
||||
path: 'Some parent folder/References.md'
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should not match folder w/o icon', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolder('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {settings: {}} // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 1, // The lastIdx+1, group not determined
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: [],
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match folder with any icon (icon specified by string alone)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': 'Irrelevant icon name, only presence matters'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match folder with any icon (icon specified together with inheritance)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': {
|
||||
iconName: 'ConfiguredIcon',
|
||||
inheritanceIcon: 'ConfiguredInheritanceIcon'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match folder with specified icon (icon specified by string alone)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'ConfiguredIcon-by-string'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': 'ConfiguredIcon-by-string'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should match folder with specified icon (icon specified together with inheritance)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'ConfiguredIcon'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': {
|
||||
iconName: 'ConfiguredIcon',
|
||||
inheritanceIcon: 'ConfiguredInheritanceIcon'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 0,
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should not match folder with different icon (icon specified by string alone)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'ConfiguredIcon-by-string'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': 'AnotherConfiguredIcon-by-string'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 1, // lastIdx+1 - no match
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('should not match folder with different icon (icon specified together with inheritance)', () => {
|
||||
// given
|
||||
const folder: TFolder = mockTFolderWithChildren('TestEmptyFolder');
|
||||
const sortSpec: CustomSortSpec = {
|
||||
targetFoldersPaths: ['/'],
|
||||
groups: [{
|
||||
type: CustomSortGroupType.IconFolderPlugin,
|
||||
folderIconName: 'ConfiguredIcon'
|
||||
}]
|
||||
}
|
||||
const obsidianIconFolderPluginInstance: Partial<ObsidianIconFolder_PluginInstance> = {
|
||||
getData: jest.fn( function(): ObsidianIconFolderPlugin_Data {
|
||||
return {
|
||||
settings: {}, // The obsidian-folder-icon plugin keeps the settings there indeed ;-)
|
||||
'TestEmptyFolder': {
|
||||
iconName: 'OtherConfiguredIcon',
|
||||
inheritanceIcon: 'ConfiguredInheritanceIcon'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// when
|
||||
const result = determineSortingGroup(folder, sortSpec, {
|
||||
iconFolderPluginInstance: obsidianIconFolderPluginInstance as ObsidianIconFolder_PluginInstance
|
||||
})
|
||||
|
||||
// then
|
||||
expect(result).toEqual({
|
||||
groupIdx: 1, // lastIdx+1 - no match
|
||||
isFolder: true,
|
||||
sortString: "TestEmptyFolder",
|
||||
ctimeNewest: 0,
|
||||
ctimeOldest: 0,
|
||||
mtime: 0,
|
||||
path: 'TestEmptyFolder',
|
||||
folder: {
|
||||
children: expect.any(Array),
|
||||
isRoot: expect.any(Function),
|
||||
name: "TestEmptyFolder",
|
||||
parent: {},
|
||||
path: "TestEmptyFolder",
|
||||
vault: {}
|
||||
}
|
||||
});
|
||||
expect(obsidianIconFolderPluginInstance.getData).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
describe('when sort by metadata is involved', () => {
|
||||
it('should correctly read direct metadata from File item (order by metadata set on group) alph', () => {
|
||||
// given
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
App,
|
||||
CommunityPlugin,
|
||||
FrontMatterCache,
|
||||
InstalledPlugin,
|
||||
requireApiVersion,
|
||||
|
@ -8,9 +9,19 @@ import {
|
|||
TFolder
|
||||
} from 'obsidian';
|
||||
import {
|
||||
determineStarredStatusOf,
|
||||
getStarredPlugin,
|
||||
Starred_PluginInstance,
|
||||
StarredPlugin_findStarredFile_methodName
|
||||
} from '../utils/StarredPluginSignature'
|
||||
} from '../utils/StarredPluginSignature';
|
||||
import {
|
||||
determineIconOf,
|
||||
getIconFolderPlugin,
|
||||
FolderIconObject,
|
||||
ObsidianIconFolder_PluginInstance,
|
||||
ObsidianIconFolderPlugin_Data,
|
||||
ObsidianIconFolderPlugin_getData_methodName
|
||||
} from '../utils/ObsidianIconFolderPluginSignature'
|
||||
import {
|
||||
CustomSortGroup,
|
||||
CustomSortGroupType,
|
||||
|
@ -154,6 +165,7 @@ export const matchGroupRegex = (theRegex: RegExpSpec, nameForMatching: string):
|
|||
|
||||
export interface Context {
|
||||
starredPluginInstance?: Starred_PluginInstance
|
||||
iconFolderPluginInstance?: ObsidianIconFolder_PluginInstance
|
||||
}
|
||||
|
||||
export const determineSortingGroup = function (entry: TFile | TFolder, spec: CustomSortSpec, ctx?: Context): FolderItemForSorting {
|
||||
|
@ -253,17 +265,24 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
|||
break
|
||||
case CustomSortGroupType.StarredOnly:
|
||||
if (ctx?.starredPluginInstance) {
|
||||
let starred: boolean
|
||||
if (aFile) {
|
||||
starred = !!ctx.starredPluginInstance[StarredPlugin_findStarredFile_methodName]({path: entry.path})
|
||||
} else { // aFolder
|
||||
starred = determineStarredStatusOfFolder(entry as TFolder, ctx.starredPluginInstance)
|
||||
}
|
||||
let starred: boolean = determineStarredStatusOf(entry, aFile, ctx.starredPluginInstance)
|
||||
if (starred) {
|
||||
determined = true
|
||||
}
|
||||
}
|
||||
break
|
||||
case CustomSortGroupType.IconFolderPlugin:
|
||||
if(ctx?.iconFolderPluginInstance) {
|
||||
let iconName: string | undefined = determineIconOf(entry, ctx.iconFolderPluginInstance)
|
||||
if (iconName) {
|
||||
if (group.folderIconName) {
|
||||
determined = iconName === group.folderIconName
|
||||
} else {
|
||||
determined = true
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case CustomSortGroupType.MatchAll:
|
||||
determined = true;
|
||||
break
|
||||
|
@ -389,25 +408,6 @@ export const determineDatesForFolder = (folder: TFolder, now: number): [Modified
|
|||
return [mtimeOfFolder, ctimeNewestOfFolder, ctimeOldestOfFolder]
|
||||
}
|
||||
|
||||
export const StarredCorePluginId: string = 'starred'
|
||||
|
||||
export const getStarredPlugin = (app?: App): Starred_PluginInstance | undefined => {
|
||||
const starredPlugin: InstalledPlugin | undefined = app?.internalPlugins?.getPluginById(StarredCorePluginId)
|
||||
if (starredPlugin && starredPlugin.enabled && starredPlugin.instance) {
|
||||
const starredPluginInstance: Starred_PluginInstance = starredPlugin.instance as Starred_PluginInstance
|
||||
// defensive programming, in case Obsidian changes its internal APIs
|
||||
if (typeof starredPluginInstance?.[StarredPlugin_findStarredFile_methodName] === 'function') {
|
||||
return starredPluginInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const determineStarredStatusOfFolder = (folder: TFolder, starredPluginInstance: Starred_PluginInstance): boolean => {
|
||||
return folder.children.some((folderItem) => {
|
||||
return !isFolder(folderItem) && starredPluginInstance[StarredPlugin_findStarredFile_methodName]({path: folderItem.path})
|
||||
})
|
||||
}
|
||||
|
||||
export const determineFolderDatesIfNeeded = (folderItems: Array<FolderItemForSorting>, sortingSpec: CustomSortSpec) => {
|
||||
const Now: number = Date.now()
|
||||
folderItems.forEach((item) => {
|
||||
|
@ -427,6 +427,7 @@ export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]
|
|||
let fileExplorer = this.fileExplorer
|
||||
sortingSpec._mCache = sortingSpec.plugin?.app.metadataCache
|
||||
const starredPluginInstance: Starred_PluginInstance | undefined = getStarredPlugin(sortingSpec?.plugin?.app)
|
||||
const iconFolderPluginInstance: ObsidianIconFolder_PluginInstance | undefined = getIconFolderPlugin(sortingSpec?.plugin?.app)
|
||||
|
||||
const folderItems: Array<FolderItemForSorting> = (sortingSpec.itemsToHide ?
|
||||
this.file.children.filter((entry: TFile | TFolder) => {
|
||||
|
@ -436,7 +437,8 @@ export const folderSort = function (sortingSpec: CustomSortSpec, order: string[]
|
|||
this.file.children)
|
||||
.map((entry: TFile | TFolder) => {
|
||||
const itemForSorting: FolderItemForSorting = determineSortingGroup(entry, sortingSpec, {
|
||||
starredPluginInstance: starredPluginInstance
|
||||
starredPluginInstance: starredPluginInstance,
|
||||
iconFolderPluginInstance: iconFolderPluginInstance
|
||||
})
|
||||
return itemForSorting
|
||||
})
|
||||
|
|
|
@ -12,7 +12,24 @@ declare module 'obsidian' {
|
|||
id: string;
|
||||
}
|
||||
|
||||
export type CommunityPluginId = string
|
||||
|
||||
// undocumented internal interface - for experimental features
|
||||
export interface CommunityPlugin {
|
||||
manifest: {
|
||||
id: CommunityPluginId
|
||||
}
|
||||
_loaded: boolean
|
||||
}
|
||||
|
||||
// undocumented internal interface - for experimental features
|
||||
export interface CommunityPlugins {
|
||||
enabledPlugins: Set<CommunityPluginId>
|
||||
plugins: {[key: CommunityPluginId]: CommunityPlugin}
|
||||
}
|
||||
|
||||
export interface App {
|
||||
plugins: CommunityPlugins;
|
||||
internalPlugins: InternalPlugins; // undocumented internal API - for experimental features
|
||||
viewRegistry: ViewRegistry;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import {App, CommunityPlugin, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
import {Starred_PluginInstance} from "./StarredPluginSignature";
|
||||
|
||||
// For https://github.com/FlorianWoelki/obsidian-icon-folder
|
||||
|
||||
export const ObsidianIconFolderPlugin_getData_methodName = 'getData'
|
||||
|
||||
export interface FolderIconObject {
|
||||
iconName: string | null;
|
||||
inheritanceIcon: string;
|
||||
}
|
||||
|
||||
export type ObsidianIconFolderPlugin_Data = Record<string, boolean | string | FolderIconObject | any>
|
||||
|
||||
export interface ObsidianIconFolder_PluginInstance extends CommunityPlugin {
|
||||
[ObsidianIconFolderPlugin_getData_methodName]: () => ObsidianIconFolderPlugin_Data
|
||||
}
|
||||
|
||||
// https://github.com/FlorianWoelki/obsidian-icon-folder/blob/fd9c7df1486744450cec3d7ee9cee2b34d008e56/manifest.json#L2
|
||||
export const ObsidianIconFolderPluginId: string = 'obsidian-icon-folder'
|
||||
|
||||
export const getIconFolderPlugin = (app?: App): ObsidianIconFolder_PluginInstance | undefined => {
|
||||
const iconFolderPlugin: CommunityPlugin | undefined = app?.plugins?.plugins?.[ObsidianIconFolderPluginId]
|
||||
if (iconFolderPlugin && iconFolderPlugin._loaded && app?.plugins?.enabledPlugins?.has(ObsidianIconFolderPluginId)) {
|
||||
const iconFolderPluginInstance: ObsidianIconFolder_PluginInstance = iconFolderPlugin as ObsidianIconFolder_PluginInstance
|
||||
// defensive programming, in case the community plugin changes its internal APIs
|
||||
if (typeof iconFolderPluginInstance?.[ObsidianIconFolderPlugin_getData_methodName] === 'function') {
|
||||
return iconFolderPluginInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intentionally partial and simplified, only detect icons configured directly,
|
||||
// ignoring any icon inheritance or regexp-based applied icons
|
||||
export const determineIconOf = (entry: TAbstractFile, iconFolderPluginInstance: ObsidianIconFolder_PluginInstance): string | undefined => {
|
||||
const iconsData: ObsidianIconFolderPlugin_Data | undefined = iconFolderPluginInstance[ObsidianIconFolderPlugin_getData_methodName]()
|
||||
const entryForPath: any = iconsData?.[entry.path]
|
||||
// Icons configured directly
|
||||
if (typeof entryForPath === 'string') {
|
||||
return entryForPath
|
||||
} else if (typeof (entryForPath as FolderIconObject)?.iconName === 'string') {
|
||||
return (entryForPath as FolderIconObject)?.iconName ?? undefined
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import {PluginInstance, TFile} from "obsidian";
|
||||
import {App, InstalledPlugin, PluginInstance, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
|
||||
export const StarredPlugin_findStarredFile_methodName = 'findStarredFile'
|
||||
|
||||
|
@ -9,3 +9,35 @@ export interface findStarredFile_pathParam {
|
|||
export interface Starred_PluginInstance extends PluginInstance {
|
||||
[StarredPlugin_findStarredFile_methodName]: (filePath: findStarredFile_pathParam) => TFile | null
|
||||
}
|
||||
|
||||
export const StarredCorePluginId: string = 'starred'
|
||||
|
||||
export const getStarredPlugin = (app?: App): Starred_PluginInstance | undefined => {
|
||||
const starredPlugin: InstalledPlugin | undefined = app?.internalPlugins?.getPluginById(StarredCorePluginId)
|
||||
if (starredPlugin && starredPlugin.enabled && starredPlugin.instance) {
|
||||
const starredPluginInstance: Starred_PluginInstance = starredPlugin.instance as Starred_PluginInstance
|
||||
// defensive programming, in case Obsidian changes its internal APIs
|
||||
if (typeof starredPluginInstance?.[StarredPlugin_findStarredFile_methodName] === 'function') {
|
||||
return starredPluginInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isFolder = (entry: TAbstractFile) => {
|
||||
// The plain obvious 'entry instanceof TFolder' doesn't work inside Jest unit tests, hence a workaround below
|
||||
return !!((entry as any).isRoot);
|
||||
}
|
||||
|
||||
export const determineStarredStatusOfFolder = (folder: TFolder, starredPluginInstance: Starred_PluginInstance): boolean => {
|
||||
return folder.children.some((folderItem) => {
|
||||
return !isFolder(folderItem) && starredPluginInstance[StarredPlugin_findStarredFile_methodName]({path: folderItem.path})
|
||||
})
|
||||
}
|
||||
|
||||
export const determineStarredStatusOf = (entry: TFile | TFolder, aFile: boolean, starredPluginInstance: Starred_PluginInstance) => {
|
||||
if (aFile) {
|
||||
return !!starredPluginInstance[StarredPlugin_findStarredFile_methodName]({path: entry.path})
|
||||
} else { // aFolder
|
||||
return determineStarredStatusOfFolder(entry as TFolder, starredPluginInstance)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue