From ba54e63a488ce5b2da2a7f959f6833466fae7b72 Mon Sep 17 00:00:00 2001 From: SebastianMC <23032356+SebastianMC@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:53:43 +0100 Subject: [PATCH] #132 - new orders: `advanced recursive modified` and `advanced recursive created` --- src/custom-sort/custom-sort-types.ts | 4 + src/custom-sort/custom-sort.ts | 88 ++++++++++++------- .../sorting-spec-processor.spec.ts | 32 ++++++- src/custom-sort/sorting-spec-processor.ts | 2 + 4 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/custom-sort/custom-sort-types.ts b/src/custom-sort/custom-sort-types.ts index 5dea555..678b432 100644 --- a/src/custom-sort/custom-sort-types.ts +++ b/src/custom-sort/custom-sort-types.ts @@ -22,12 +22,16 @@ export enum CustomSortOrder { trueAlphabeticalReverseWithFileExt, byModifiedTime, // New to old byModifiedTimeAdvanced, + byModifiedTimeAdvancedRecursive, byModifiedTimeReverse, // Old to new byModifiedTimeReverseAdvanced, + byModifiedTimeReverseAdvancedRecursive, byCreatedTime, // New to old byCreatedTimeAdvanced, + byCreatedTimeAdvancedRecursive, byCreatedTimeReverse, byCreatedTimeReverseAdvanced, + byCreatedTimeReverseAdvancedRecursive, byMetadataFieldAlphabetical, byMetadataFieldTrueAlphabetical, byMetadataFieldAlphabeticalReverse, diff --git a/src/custom-sort/custom-sort.ts b/src/custom-sort/custom-sort.ts index 97d81ae..945621b 100644 --- a/src/custom-sort/custom-sort.ts +++ b/src/custom-sort/custom-sort.ts @@ -5,7 +5,8 @@ import { requireApiVersion, TAbstractFile, TFile, - TFolder + TFolder, + Vault } from 'obsidian'; import { determineStarredStatusOf, @@ -190,12 +191,16 @@ const Sorters: { [key in CustomSortOrder]: SorterFn } = { [CustomSortOrder.trueAlphabeticalReverseWithFileExt]: (a: FIFS, b: FIFS) => CollatorTrueAlphabeticalCompare(b.sortStringWithExt, a.sortStringWithExt), [CustomSortOrder.byModifiedTime]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.mtime - b.mtime), [CustomSortOrder.byModifiedTimeAdvanced]: sorterByFolderMDate(), + [CustomSortOrder.byModifiedTimeAdvancedRecursive]: sorterByFolderMDate(), [CustomSortOrder.byModifiedTimeReverse]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.mtime - a.mtime), [CustomSortOrder.byModifiedTimeReverseAdvanced]: sorterByFolderMDate(true), + [CustomSortOrder.byModifiedTimeReverseAdvancedRecursive]: sorterByFolderMDate(true), [CustomSortOrder.byCreatedTime]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (a.ctime - b.ctime), [CustomSortOrder.byCreatedTimeAdvanced]: sorterByFolderCDate(), + [CustomSortOrder.byCreatedTimeAdvancedRecursive]: sorterByFolderCDate(), [CustomSortOrder.byCreatedTimeReverse]: (a: FIFS, b: FIFS) => (a.isFolder && b.isFolder) ? CollatorCompare(a.sortString, b.sortString) : (b.ctime - a.ctime), [CustomSortOrder.byCreatedTimeReverseAdvanced]: sorterByFolderCDate(true), + [CustomSortOrder.byCreatedTimeReverseAdvancedRecursive]: sorterByFolderCDate(true), [CustomSortOrder.byMetadataFieldAlphabetical]: sorterByMetadataField(StraightOrder, !TrueAlphabetical, SortingLevelId.forPrimary), [CustomSortOrder.byMetadataFieldTrueAlphabetical]: sorterByMetadataField(StraightOrder, TrueAlphabetical, SortingLevelId.forPrimary), [CustomSortOrder.byMetadataFieldAlphabeticalReverse]: sorterByMetadataField(ReverseOrder, !TrueAlphabetical, SortingLevelId.forPrimary), @@ -577,17 +582,27 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus } } +const SortOrderRequiringRecursiveFolderDate = new Set([ + CustomSortOrder.byModifiedTimeAdvancedRecursive, + CustomSortOrder.byModifiedTimeReverseAdvancedRecursive, + CustomSortOrder.byCreatedTimeAdvancedRecursive, + CustomSortOrder.byCreatedTimeReverseAdvancedRecursive +]) + +export const sortOrderNeedsFolderDeepDates = (...orders: Array): boolean => { + return orders.some((o) => o && SortOrderRequiringRecursiveFolderDate.has(o)) +} + const SortOrderRequiringFolderDate = new Set([ + ...SortOrderRequiringRecursiveFolderDate, CustomSortOrder.byModifiedTimeAdvanced, CustomSortOrder.byModifiedTimeReverseAdvanced, CustomSortOrder.byCreatedTimeAdvanced, CustomSortOrder.byCreatedTimeReverseAdvanced ]) -export const sortOrderNeedsFolderDates = (order: CustomSortOrder | undefined, secondary?: CustomSortOrder): boolean => { - // The CustomSortOrder.standardObsidian used as default because it doesn't require date on folders - return SortOrderRequiringFolderDate.has(order ?? CustomSortOrder.standardObsidian) - || SortOrderRequiringFolderDate.has(secondary ?? CustomSortOrder.standardObsidian) +export const sortOrderNeedsFolderDates = (...orders: Array): boolean => { + return orders.some((o) => o && SortOrderRequiringFolderDate.has(o)) } const SortOrderRequiringBookmarksOrder = new Set([ @@ -595,50 +610,54 @@ const SortOrderRequiringBookmarksOrder = new Set([ CustomSortOrder.byBookmarkOrderReverse ]) -export const sortOrderNeedsBookmarksOrder = (order: CustomSortOrder | undefined, secondary?: CustomSortOrder): boolean => { - // The CustomSortOrder.standardObsidian used as default because it doesn't require bookmarks order - return SortOrderRequiringBookmarksOrder.has(order ?? CustomSortOrder.standardObsidian) - || SortOrderRequiringBookmarksOrder.has(secondary ?? CustomSortOrder.standardObsidian) +export const sortOrderNeedsBookmarksOrder = (...orders: Array): boolean => { + return orders.some((o) => o && SortOrderRequiringBookmarksOrder.has(o)) } // Syntax sugar for readability export type ModifiedTime = number export type CreatedTime = number -export const determineDatesForFolder = (folder: TFolder, now: number): [ModifiedTime, CreatedTime] => { +export const determineDatesForFolder = (folder: TFolder, recursive?: boolean): [ModifiedTime, CreatedTime] => { let mtimeOfFolder: ModifiedTime = DEFAULT_FOLDER_MTIME let ctimeOfFolder: CreatedTime = DEFAULT_FOLDER_CTIME - folder.children.forEach((item) => { - if (!isFolder(item)) { - const file: TFile = item as TFile - if (file.stat.mtime > mtimeOfFolder) { - mtimeOfFolder = file.stat.mtime - } - if (file.stat.ctime < ctimeOfFolder || ctimeOfFolder === DEFAULT_FOLDER_CTIME) { - ctimeOfFolder = file.stat.ctime - } + const checkFile = (abFile: TAbstractFile) => { + if (isFolder(abFile)) return + + const file: TFile = abFile as TFile + if (file.stat.mtime > mtimeOfFolder) { + mtimeOfFolder = file.stat.mtime } - }) + if (file.stat.ctime < ctimeOfFolder || ctimeOfFolder === DEFAULT_FOLDER_CTIME) { + ctimeOfFolder = file.stat.ctime + } + } + + if (recursive) { + Vault.recurseChildren(folder, checkFile) + } else { + folder.children.forEach((item) => checkFile(item)) + } return [mtimeOfFolder, ctimeOfFolder] } export const determineFolderDatesIfNeeded = (folderItems: Array, sortingSpec: CustomSortSpec) => { - const Now: number = Date.now() + const foldersDatesNeeded = sortOrderNeedsFolderDates(sortingSpec.defaultOrder, sortingSpec.defaultSecondaryOrder) + const foldersDeepDatesNeeded = sortOrderNeedsFolderDeepDates(sortingSpec.defaultOrder, sortingSpec.defaultSecondaryOrder) + + const groupOrders = sortingSpec.groups?.map((group) => ({ + foldersDatesNeeded: sortOrderNeedsFolderDates(group.order, group.secondaryOrder), + foldersDeepDatesNeeded: sortOrderNeedsFolderDeepDates(group.order, group.secondaryOrder) + })) + folderItems.forEach((item) => { if (item.folder) { - const folderDefaultSortRequiresFolderDate: boolean = !!(sortingSpec.defaultOrder && sortOrderNeedsFolderDates(sortingSpec.defaultOrder, sortingSpec.defaultSecondaryOrder)) - let groupSortRequiresFolderDate: boolean = false - if (!folderDefaultSortRequiresFolderDate) { - const groupIdx: number | undefined = item.groupIdx - if (groupIdx !== undefined) { - const groupOrder: CustomSortOrder | undefined = sortingSpec.groups[groupIdx].order - const groupSecondaryOrder: CustomSortOrder | undefined = sortingSpec.groups[groupIdx].secondaryOrder - groupSortRequiresFolderDate = !!groupOrder && sortOrderNeedsFolderDates(groupOrder, groupSecondaryOrder) - } - } - if (folderDefaultSortRequiresFolderDate || groupSortRequiresFolderDate) { - [item.mtime, item.ctime] = determineDatesForFolder(item.folder, Now) + if (foldersDatesNeeded || (item.groupIdx !== undefined && groupOrders[item.groupIdx].foldersDatesNeeded)) { + [item.mtime, item.ctime] = determineDatesForFolder( + item.folder, + foldersDeepDatesNeeded || (item.groupIdx !== undefined && groupOrders[item.groupIdx].foldersDeepDatesNeeded) + ) } } }) @@ -649,8 +668,9 @@ export const determineFolderDatesIfNeeded = (folderItems: Array, sortingSpec: CustomSortSpec, plugin: BookmarksPluginInterface) => { if (!plugin) return + const folderDefaultSortRequiresBookmarksOrder: boolean = !!(sortingSpec.defaultOrder && sortOrderNeedsBookmarksOrder(sortingSpec.defaultOrder, sortingSpec.defaultSecondaryOrder)) + folderItems.forEach((item) => { - const folderDefaultSortRequiresBookmarksOrder: boolean = !!(sortingSpec.defaultOrder && sortOrderNeedsBookmarksOrder(sortingSpec.defaultOrder, sortingSpec.defaultSecondaryOrder)) let groupSortRequiresBookmarksOrder: boolean = false if (!folderDefaultSortRequiresBookmarksOrder) { const groupIdx: number | undefined = item.groupIdx diff --git a/src/custom-sort/sorting-spec-processor.spec.ts b/src/custom-sort/sorting-spec-processor.spec.ts index 5533c0f..2d7913e 100644 --- a/src/custom-sort/sorting-spec-processor.spec.ts +++ b/src/custom-sort/sorting-spec-processor.spec.ts @@ -2325,6 +2325,14 @@ target-folder: AA < advanced created /:files Archive... > advanced created +/folders Deep1... + < advanced recursive created +/:files Deep2... + > advanced recursive created +/folders Deep3... + < advanced recursive modified +/:files Deep4... + > advanced recursive modified ` const expectedSortSpecForAdvancedFolderDateSortingMethods: { [key: string]: CustomSortSpec } = { @@ -2373,12 +2381,32 @@ const expectedSortSpecForAdvancedFolderDateSortingMethods: { [key: string]: Cust exactPrefix: 'Archive', foldersOnly: true, order: CustomSortOrder.byCreatedTimeAdvanced, - type: 3 + type: CustomSortGroupType.ExactPrefix }, { exactPrefix: 'Archive', filesOnly: true, order: CustomSortOrder.byCreatedTimeReverseAdvanced, - type: 3 + type: CustomSortGroupType.ExactPrefix + }, { + exactPrefix: 'Deep1', + foldersOnly: true, + order: CustomSortOrder.byCreatedTimeAdvancedRecursive, + type: CustomSortGroupType.ExactPrefix + }, { + exactPrefix: 'Deep2', + filesOnly: true, + order: CustomSortOrder.byCreatedTimeReverseAdvancedRecursive, + type: CustomSortGroupType.ExactPrefix + }, { + exactPrefix: 'Deep3', + foldersOnly: true, + order: CustomSortOrder.byModifiedTimeAdvancedRecursive, + type: CustomSortGroupType.ExactPrefix + }, { + exactPrefix: 'Deep4', + filesOnly: true, + order: CustomSortOrder.byModifiedTimeReverseAdvancedRecursive, + type: CustomSortGroupType.ExactPrefix }], outsidersFilesGroupIdx: 1, outsidersFoldersGroupIdx: 0, diff --git a/src/custom-sort/sorting-spec-processor.ts b/src/custom-sort/sorting-spec-processor.ts index f1e1b2f..ebf6d08 100644 --- a/src/custom-sort/sorting-spec-processor.ts +++ b/src/custom-sort/sorting-spec-processor.ts @@ -124,6 +124,8 @@ const OrderLiterals: { [key: string]: CustomSortOrderAscDescPair } = { 'modified': {asc: CustomSortOrder.byModifiedTime, desc: CustomSortOrder.byModifiedTimeReverse}, 'advanced modified': {asc: CustomSortOrder.byModifiedTimeAdvanced, desc: CustomSortOrder.byModifiedTimeReverseAdvanced}, 'advanced created': {asc: CustomSortOrder.byCreatedTimeAdvanced, desc: CustomSortOrder.byCreatedTimeReverseAdvanced}, + 'advanced recursive modified': {asc: CustomSortOrder.byModifiedTimeAdvancedRecursive, desc: CustomSortOrder.byModifiedTimeReverseAdvancedRecursive}, + 'advanced recursive created': {asc: CustomSortOrder.byCreatedTimeAdvancedRecursive, desc: CustomSortOrder.byCreatedTimeReverseAdvancedRecursive}, 'standard': {asc: CustomSortOrder.standardObsidian, desc: CustomSortOrder.standardObsidian}, 'ui selected': {asc: CustomSortOrder.standardObsidian, desc: CustomSortOrder.standardObsidian}, 'by-bookmarks-order': {asc: CustomSortOrder.byBookmarkOrder, desc: CustomSortOrder.byBookmarkOrderReverse},