#74 - Integration with Bookmarks core plugin and support for indirect drag & drop arrangement
- singificants refactoring, compilable, basic functions work
This commit is contained in:
parent
62a91db3de
commit
d32e71f064
|
@ -25,8 +25,7 @@ import {
|
|||
} from "./custom-sort-types";
|
||||
import {isDefined} from "../utils/utils";
|
||||
import {
|
||||
Bookmarks_PluginInstance,
|
||||
determineBookmarkOrder
|
||||
BookmarksPluginInterface
|
||||
} from "../utils/BookmarksCorePluginSignature";
|
||||
|
||||
export interface ProcessingContext {
|
||||
|
@ -34,10 +33,7 @@ export interface ProcessingContext {
|
|||
plugin?: Plugin // to hand over the access to App instance to the sorting engine
|
||||
_mCache?: MetadataCache
|
||||
starredPluginInstance?: Starred_PluginInstance
|
||||
bookmarksPlugin: {
|
||||
instance?: Bookmarks_PluginInstance,
|
||||
groupNameForSorting?: string
|
||||
}
|
||||
bookmarksPluginInstance?: BookmarksPluginInterface,
|
||||
iconFolderPluginInstance?: ObsidianIconFolder_PluginInstance
|
||||
}
|
||||
|
||||
|
@ -364,8 +360,8 @@ export const determineSortingGroup = function (entry: TFile | TFolder, spec: Cus
|
|||
}
|
||||
break
|
||||
case CustomSortGroupType.BookmarkedOnly:
|
||||
if (ctx?.bookmarksPlugin?.instance) {
|
||||
const bookmarkOrder: number | undefined = determineBookmarkOrder(entry.path, ctx.bookmarksPlugin?.instance, ctx.bookmarksPlugin?.groupNameForSorting)
|
||||
if (ctx?.bookmarksPluginInstance) {
|
||||
const bookmarkOrder: number | undefined = ctx?.bookmarksPluginInstance.determineBookmarkOrder(entry.path)
|
||||
if (bookmarkOrder) { // safe ==> orders intentionally start from 1
|
||||
determined = true
|
||||
bookmarkedIdx = bookmarkOrder
|
||||
|
@ -537,7 +533,7 @@ export const determineFolderDatesIfNeeded = (folderItems: Array<FolderItemForSor
|
|||
|
||||
// Order by bookmarks order can be applied independently of grouping by bookmarked status
|
||||
// This function determines the bookmarked order if the sorting criteria (of group or entire folder) requires it
|
||||
export const determineBookmarksOrderIfNeeded = (folderItems: Array<FolderItemForSorting>, sortingSpec: CustomSortSpec, plugin: Bookmarks_PluginInstance, bookmarksGroup?: string) => {
|
||||
export const determineBookmarksOrderIfNeeded = (folderItems: Array<FolderItemForSorting>, sortingSpec: CustomSortSpec, plugin: BookmarksPluginInterface) => {
|
||||
if (!plugin) return
|
||||
|
||||
folderItems.forEach((item) => {
|
||||
|
@ -551,7 +547,7 @@ export const determineBookmarksOrderIfNeeded = (folderItems: Array<FolderItemFor
|
|||
}
|
||||
}
|
||||
if (folderDefaultSortRequiresBookmarksOrder || groupSortRequiresBookmarksOrder) {
|
||||
item.bookmarkedIdx = determineBookmarkOrder(item.path, plugin, bookmarksGroup)
|
||||
item.bookmarkedIdx = plugin.determineBookmarkOrder(item.path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -573,8 +569,8 @@ export const folderSort = function (sortingSpec: CustomSortSpec, ctx: Processing
|
|||
// Finally, for advanced sorting by modified date, for some folders the modified date has to be determined
|
||||
determineFolderDatesIfNeeded(folderItems, sortingSpec)
|
||||
|
||||
if (ctx.bookmarksPlugin?.instance) {
|
||||
determineBookmarksOrderIfNeeded(folderItems, sortingSpec, ctx.bookmarksPlugin.instance, ctx.bookmarksPlugin.groupNameForSorting)
|
||||
if (ctx.bookmarksPluginInstance) {
|
||||
determineBookmarksOrderIfNeeded(folderItems, sortingSpec, ctx.bookmarksPluginInstance)
|
||||
}
|
||||
|
||||
const comparator: SorterFn = getComparator(sortingSpec, fileExplorer.sortOrder)
|
||||
|
@ -605,8 +601,8 @@ export const sortFolderItemsForBookmarking = function (items: Array<TAbstractFil
|
|||
// Finally, for advanced sorting by modified date, for some folders the modified date has to be determined
|
||||
determineFolderDatesIfNeeded(folderItems, sortingSpec)
|
||||
|
||||
if (ctx.bookmarksPlugin?.instance) {
|
||||
determineBookmarksOrderIfNeeded(folderItems, sortingSpec, ctx.bookmarksPlugin.instance, ctx.bookmarksPlugin.groupNameForSorting)
|
||||
if (ctx.bookmarksPluginInstance) {
|
||||
determineBookmarksOrderIfNeeded(folderItems, sortingSpec, ctx.bookmarksPluginInstance)
|
||||
}
|
||||
|
||||
const comparator: SorterFn = getComparator(sortingSpec, uiSortOrder)
|
||||
|
|
63
src/main.ts
63
src/main.ts
|
@ -36,11 +36,7 @@ import {
|
|||
} from "./custom-sort/icons";
|
||||
import {getStarredPlugin} from "./utils/StarredPluginSignature";
|
||||
import {
|
||||
getBookmarksPlugin,
|
||||
bookmarkFolderItem,
|
||||
saveDataAndUpdateBookmarkViews,
|
||||
bookmarkSiblings,
|
||||
updateSortingBookmarksAfterItemRename
|
||||
getBookmarksPlugin
|
||||
} from "./utils/BookmarksCorePluginSignature";
|
||||
import {getIconFolderPlugin} from "./utils/ObsidianIconFolderPluginSignature";
|
||||
import {lastPathComponent} from "./utils/utils";
|
||||
|
@ -98,7 +94,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
}
|
||||
|
||||
readAndParseSortingSpec() {
|
||||
const mCache: MetadataCache = this.app.metadataCache
|
||||
const mCache: MetadataCache = app.metadataCache
|
||||
let failed: boolean = false
|
||||
let anySortingSpecFound: boolean = false
|
||||
let errorMessage: string | null = null
|
||||
|
@ -118,7 +114,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
console.log(this.sortSpecCache)
|
||||
}
|
||||
|
||||
Vault.recurseChildren(this.app.vault.getRoot(), (file: TAbstractFile) => {
|
||||
Vault.recurseChildren(app.vault.getRoot(), (file: TAbstractFile) => {
|
||||
if (failed) return
|
||||
if (file instanceof TFile) {
|
||||
const aFile: TFile = file as TFile
|
||||
|
@ -283,7 +279,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
this.ribbonIconStateInaccurate = true
|
||||
}
|
||||
|
||||
this.addSettingTab(new CustomSortSettingTab(this.app, this));
|
||||
this.addSettingTab(new CustomSortSettingTab(app, this));
|
||||
|
||||
this.registerEventHandlers()
|
||||
|
||||
|
@ -296,7 +292,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
const plugin: CustomSortPlugin = this
|
||||
this.registerEvent(
|
||||
// Keep in mind: this event is triggered once after app starts and then after each modification of _any_ metadata
|
||||
this.app.metadataCache.on("resolved", () => {
|
||||
app.metadataCache.on("resolved", () => {
|
||||
if (!this.settings.suspended) {
|
||||
if (!this.initialAutoOrManualSortingTriggered) {
|
||||
this.readAndParseSortingSpec()
|
||||
|
@ -323,17 +319,17 @@ export default class CustomSortPlugin extends Plugin {
|
|||
);
|
||||
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("file-menu", (menu: Menu, file: TAbstractFile, source: string, leaf?: WorkspaceLeaf) => {
|
||||
app.workspace.on("file-menu", (menu: Menu, file: TAbstractFile, source: string, leaf?: WorkspaceLeaf) => {
|
||||
const bookmarkThisMenuItem = (item: MenuItem) => {
|
||||
// TODO: if already bookmarked in the 'custom sort' group (or its descendants) don't show
|
||||
item.setTitle('Custom sort: bookmark for sorting.');
|
||||
item.setIcon('hashtag');
|
||||
item.onClick(() => {
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.app)
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
console.log(`custom-sort: bookmark this clicked ${source} and the leaf is`)
|
||||
if (bookmarksPlugin) {
|
||||
bookmarkFolderItem(file, bookmarksPlugin, plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
saveDataAndUpdateBookmarkViews(bookmarksPlugin, plugin.app)
|
||||
bookmarksPlugin.bookmarkFolderItem(file)
|
||||
bookmarksPlugin.saveDataAndUpdateBookmarkViews(true)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -342,11 +338,11 @@ export default class CustomSortPlugin extends Plugin {
|
|||
item.setIcon('hashtag');
|
||||
item.onClick(() => {
|
||||
console.log(`custom-sort: bookmark all siblings clicked ${source}`)
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.app)
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
if (bookmarksPlugin) {
|
||||
const orderedChildren: Array<TAbstractFile> = plugin.orderedFolderItemsForBookmarking(file.parent)
|
||||
bookmarkSiblings(orderedChildren, bookmarksPlugin, plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
saveDataAndUpdateBookmarkViews(bookmarksPlugin, plugin.app)
|
||||
bookmarksPlugin.bookmarkSiblings(orderedChildren)
|
||||
bookmarksPlugin.saveDataAndUpdateBookmarkViews(true)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -357,13 +353,21 @@ export default class CustomSortPlugin extends Plugin {
|
|||
)
|
||||
|
||||
this.registerEvent(
|
||||
this.app.vault.on("rename", (file: TAbstractFile, oldPath: string) => {
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.app)
|
||||
app.vault.on("rename", (file: TAbstractFile, oldPath: string) => {
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
if (bookmarksPlugin) {
|
||||
updateSortingBookmarksAfterItemRename(bookmarksPlugin, file, oldPath, plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
bookmarksPlugin.updateSortingBookmarksAfterItemRenamed(file, oldPath)
|
||||
bookmarksPlugin.saveDataAndUpdateBookmarkViews(true)
|
||||
}
|
||||
})
|
||||
)
|
||||
app.vault.on("delete", (file: TAbstractFile) => {
|
||||
const bookmarksPlugin = getBookmarksPlugin(plugin.settings.bookmarksGroupToConsumeAsOrderingReference)
|
||||
if (bookmarksPlugin) {
|
||||
bookmarksPlugin.updateSortingBookmarksAfterItemDeleted(file)
|
||||
bookmarksPlugin.saveDataAndUpdateBookmarkViews(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
registerCommands() {
|
||||
|
@ -385,7 +389,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
}
|
||||
|
||||
initialize() {
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
app.workspace.onLayoutReady(() => {
|
||||
this.fileExplorerFolderPatched = this.patchFileExplorerFolder();
|
||||
})
|
||||
}
|
||||
|
@ -404,13 +408,10 @@ export default class CustomSortPlugin extends Plugin {
|
|||
|
||||
createProcessingContextForSorting(): ProcessingContext {
|
||||
const ctx: ProcessingContext = {
|
||||
_mCache: this.app.metadataCache,
|
||||
starredPluginInstance: getStarredPlugin(this.app),
|
||||
bookmarksPlugin: {
|
||||
instance: this.settings.automaticBookmarksIntegration ? getBookmarksPlugin(this.app) : undefined,
|
||||
groupNameForSorting: this.settings.bookmarksGroupToConsumeAsOrderingReference
|
||||
},
|
||||
iconFolderPluginInstance: getIconFolderPlugin(this.app),
|
||||
_mCache: app.metadataCache,
|
||||
starredPluginInstance: getStarredPlugin(),
|
||||
bookmarksPluginInstance: getBookmarksPlugin(this.settings.bookmarksGroupToConsumeAsOrderingReference),
|
||||
iconFolderPluginInstance: getIconFolderPlugin(),
|
||||
plugin: this
|
||||
}
|
||||
return ctx
|
||||
|
@ -469,7 +470,7 @@ export default class CustomSortPlugin extends Plugin {
|
|||
|
||||
// Credits go to https://github.com/nothingislost/obsidian-bartender
|
||||
getFileExplorer(): FileExplorerView | undefined {
|
||||
let fileExplorer: FileExplorerView | undefined = this.app.workspace.getLeavesOfType("file-explorer")?.first()
|
||||
let fileExplorer: FileExplorerView | undefined = app.workspace.getLeavesOfType("file-explorer")?.first()
|
||||
?.view as unknown as FileExplorerView;
|
||||
return fileExplorer;
|
||||
}
|
||||
|
@ -639,10 +640,4 @@ class CustomSortSettingTab extends PluginSettingTab {
|
|||
|
||||
// TODO: remove console.log (many places added)
|
||||
|
||||
// Invoke 'onItemsChanged' consciously for the bookmarks plugin
|
||||
|
||||
// TODO: on delete - delete from bkmrks
|
||||
|
||||
// TODO: ctx menu 'show in bookmarks' instead of 'bookmrk this'
|
||||
|
||||
// TODO: new items bkmrkd in the top instead of in the bottom. Or maybe at actual location (???)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {App, InstalledPlugin, Plugin, PluginInstance, TAbstractFile, TFolder} from "obsidian";
|
||||
import {InstalledPlugin, PluginInstance, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
import {extractParentFolderPath, lastPathComponent} from "./utils";
|
||||
|
||||
const BookmarksPlugin_getBookmarks_methodName = 'getBookmarks'
|
||||
|
@ -46,25 +46,131 @@ export interface OrderedBookmarkedItem {
|
|||
group: boolean
|
||||
path: BookmarkedItemPath
|
||||
order: number
|
||||
pathOfBookmarkGroupsMatches: boolean
|
||||
}
|
||||
|
||||
interface OrderedBookmarks {
|
||||
[key: BookmarkedItemPath]: OrderedBookmarkedItem
|
||||
}
|
||||
|
||||
export interface Bookmarks_PluginInstance extends PluginInstance {
|
||||
interface Bookmarks_PluginInstance extends PluginInstance {
|
||||
[BookmarksPlugin_getBookmarks_methodName]: () => Array<BookmarkedItem> | undefined
|
||||
[BookmarksPlugin_items_collectionName]: Array<BookmarkedItem>
|
||||
saveData(): void
|
||||
onItemsChanged(saveData: boolean): void
|
||||
}
|
||||
|
||||
export interface BookmarksPluginInterface {
|
||||
determineBookmarkOrder(path: string): number|undefined
|
||||
bookmarkFolderItem(item: TAbstractFile): void
|
||||
saveDataAndUpdateBookmarkViews(updateBookmarkViews: boolean): void
|
||||
bookmarkSiblings(siblings: Array<TAbstractFile>, inTheTop?: boolean): void
|
||||
updateSortingBookmarksAfterItemRenamed(renamedItem: TAbstractFile, oldPath: string): void
|
||||
updateSortingBookmarksAfterItemDeleted(deletedItem: TAbstractFile): void
|
||||
}
|
||||
|
||||
class BookmarksPluginWrapper implements BookmarksPluginInterface {
|
||||
|
||||
plugin: Bookmarks_PluginInstance|undefined
|
||||
groupNameForSorting: string|undefined
|
||||
|
||||
constructor () {
|
||||
}
|
||||
|
||||
// Result:
|
||||
// undefined ==> item not found in bookmarks
|
||||
// > 0 ==> item found in bookmarks at returned position
|
||||
// Intentionally not returning 0 to allow simple syntax of processing the result
|
||||
determineBookmarkOrder = (path: string): number | undefined => {
|
||||
if (!bookmarksCache) {
|
||||
bookmarksCache = getOrderedBookmarks(this.plugin!, this.groupNameForSorting)
|
||||
bookmarksCacheTimestamp = Date.now()
|
||||
}
|
||||
|
||||
const bookmarkedItemPosition: number | undefined = bookmarksCache?.[path]?.order
|
||||
|
||||
return (bookmarkedItemPosition !== undefined && bookmarkedItemPosition >= 0) ? (bookmarkedItemPosition + 1) : undefined
|
||||
}
|
||||
|
||||
bookmarkFolderItem = (item: TAbstractFile) => {
|
||||
this.bookmarkSiblings([item], true)
|
||||
}
|
||||
|
||||
saveDataAndUpdateBookmarkViews = (updateBookmarkViews: boolean = true) => {
|
||||
this.plugin!.onItemsChanged(true)
|
||||
if (updateBookmarkViews) {
|
||||
const bookmarksLeafs = app.workspace.getLeavesOfType('bookmarks')
|
||||
bookmarksLeafs?.forEach((leaf) => {
|
||||
(leaf.view as any)?.update?.()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
bookmarkSiblings = (siblings: Array<TAbstractFile>, inTheTop?: boolean) => {
|
||||
console.log('In this.bookmarksSiblings()')
|
||||
if (siblings.length === 0) return // for sanity
|
||||
|
||||
const bookmarksContainer: BookmarkedParentFolder|undefined = findGroupForItemPathInBookmarks(
|
||||
siblings[0].path,
|
||||
CreateIfMissing,
|
||||
this.plugin!,
|
||||
this.groupNameForSorting
|
||||
)
|
||||
|
||||
if (bookmarksContainer) { // for sanity, the group should be always created if missing
|
||||
siblings.forEach((aSibling) => {
|
||||
const siblingName = lastPathComponent(aSibling.path)
|
||||
if (!bookmarksContainer.items.find((it) =>
|
||||
((it.type === 'folder' || it.type === 'file') && it.path === aSibling.path) ||
|
||||
(it.type === 'group' && it.title === siblingName))) {
|
||||
const newEntry: BookmarkedItem = (aSibling instanceof TFolder) ? createBookmarkGroupEntry(siblingName) : createBookmarkFileEntry(aSibling.path);
|
||||
if (inTheTop) {
|
||||
bookmarksContainer.items.unshift(newEntry)
|
||||
} else {
|
||||
bookmarksContainer.items.push(newEntry)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
updateSortingBookmarksAfterItemRenamed = (renamedItem: TAbstractFile, oldPath: string): void => {
|
||||
updateSortingBookmarksAfterItemRenamed(this.plugin!, renamedItem, oldPath, this.groupNameForSorting)
|
||||
}
|
||||
|
||||
updateSortingBookmarksAfterItemDeleted = (deletedItem: TAbstractFile): void => {
|
||||
updateSortingBookmarksAfterItemDeleted(this.plugin!, deletedItem, this.groupNameForSorting)
|
||||
}
|
||||
}
|
||||
|
||||
export const BookmarksCorePluginId: string = 'bookmarks'
|
||||
|
||||
export const getBookmarksPlugin = (bookmarksGroupName?: string): BookmarksPluginInterface | undefined => {
|
||||
invalidateExpiredBookmarksCache()
|
||||
const installedBookmarksPlugin: InstalledPlugin | undefined = app?.internalPlugins?.getPluginById(BookmarksCorePluginId)
|
||||
console.log(installedBookmarksPlugin)
|
||||
const bookmarks = (installedBookmarksPlugin?.instance as any) ?.['getBookmarks']()
|
||||
console.log(bookmarks)
|
||||
if (installedBookmarksPlugin && installedBookmarksPlugin.enabled && installedBookmarksPlugin.instance) {
|
||||
const bookmarksPluginInstance: Bookmarks_PluginInstance = installedBookmarksPlugin.instance as Bookmarks_PluginInstance
|
||||
// defensive programming, in case Obsidian changes its internal APIs
|
||||
if (typeof bookmarksPluginInstance?.[BookmarksPlugin_getBookmarks_methodName] === 'function') {
|
||||
bookmarksPlugin.plugin = bookmarksPluginInstance
|
||||
bookmarksPlugin.groupNameForSorting = bookmarksGroupName
|
||||
return bookmarksPlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache can outlive the wrapper instances
|
||||
let bookmarksCache: OrderedBookmarks | undefined = undefined
|
||||
let bookmarksCacheTimestamp: number | undefined = undefined
|
||||
|
||||
const bookmarksPlugin: BookmarksPluginWrapper = new BookmarksPluginWrapper()
|
||||
|
||||
const CacheExpirationMilis = 1000 // One second seems to be reasonable
|
||||
|
||||
export const invalidateExpiredBookmarksCache = (force?: boolean): void => {
|
||||
const invalidateExpiredBookmarksCache = (force?: boolean): void => {
|
||||
if (bookmarksCache) {
|
||||
let flush: boolean = true
|
||||
if (!force && !!bookmarksCacheTimestamp) {
|
||||
|
@ -79,23 +185,6 @@ export const invalidateExpiredBookmarksCache = (force?: boolean): void => {
|
|||
}
|
||||
}
|
||||
|
||||
export const BookmarksCorePluginId: string = 'bookmarks'
|
||||
|
||||
export const getBookmarksPlugin = (app?: App): Bookmarks_PluginInstance | undefined => {
|
||||
invalidateExpiredBookmarksCache()
|
||||
const bookmarksPlugin: InstalledPlugin | undefined = app?.internalPlugins?.getPluginById(BookmarksCorePluginId)
|
||||
console.log(bookmarksPlugin)
|
||||
const bookmarks = (bookmarksPlugin?.instance as any) ?.['getBookmarks']()
|
||||
console.log(bookmarks)
|
||||
if (bookmarksPlugin && bookmarksPlugin.enabled && bookmarksPlugin.instance) {
|
||||
const bookmarksPluginInstance: Bookmarks_PluginInstance = bookmarksPlugin.instance as Bookmarks_PluginInstance
|
||||
// defensive programming, in case Obsidian changes its internal APIs
|
||||
if (typeof bookmarksPluginInstance?.[BookmarksPlugin_getBookmarks_methodName] === 'function') {
|
||||
return bookmarksPluginInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TraverseCallback = (item: BookmarkedItem, parentsGroupsPath: string) => boolean | void
|
||||
|
||||
const traverseBookmarksCollection = (items: Array<BookmarkedItem>, callback: TraverseCallback) => {
|
||||
|
@ -132,14 +221,18 @@ const getOrderedBookmarks = (plugin: Bookmarks_PluginInstance, bookmarksGroupNam
|
|||
const pathOfGroup: string = `${parentGroupsPath}${parentGroupsPath?'/':''}${item.title}`
|
||||
const path = isGroup ? pathOfGroup : (item as BookmarkWithPath).path
|
||||
// Consume only the first occurrence of a path in bookmarks, even if many duplicates can exist
|
||||
// TODO: consume the occurrence at correct folders (groups) location resembling the original structure with highest prio
|
||||
// and only if not found, consider any (first) occurrence
|
||||
const alreadyConsumed = orderedBookmarks[path]
|
||||
if (!alreadyConsumed) {
|
||||
const pathOfBookmarkGroupsMatches: boolean = true // TODO: !!! with fresh head determine the condition to check here
|
||||
if (!alreadyConsumed || (pathOfBookmarkGroupsMatches && !alreadyConsumed.pathOfBookmarkGroupsMatches)) {
|
||||
orderedBookmarks[path] = {
|
||||
path: path,
|
||||
order: order++,
|
||||
file: isFile,
|
||||
folder: isFile,
|
||||
group: isGroup
|
||||
group: isGroup,
|
||||
pathOfBookmarkGroupsMatches: pathOfBookmarkGroupsMatches
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,23 +243,6 @@ const getOrderedBookmarks = (plugin: Bookmarks_PluginInstance, bookmarksGroupNam
|
|||
}
|
||||
}
|
||||
|
||||
// Result:
|
||||
// undefined ==> item not found in bookmarks
|
||||
// > 0 ==> item found in bookmarks at returned position
|
||||
// Intentionally not returning 0 to allow simple syntax of processing the result
|
||||
export const determineBookmarkOrder = (path: string, plugin: Bookmarks_PluginInstance, bookmarksGroup?: string): number | undefined => {
|
||||
if (!bookmarksCache) {
|
||||
bookmarksCache = getOrderedBookmarks(plugin, bookmarksGroup)
|
||||
bookmarksCacheTimestamp = Date.now()
|
||||
}
|
||||
|
||||
const bookmarkedItemPosition: number | undefined = bookmarksCache?.[path]?.order
|
||||
|
||||
return (bookmarkedItemPosition !== undefined && bookmarkedItemPosition >= 0) ? (bookmarkedItemPosition + 1) : undefined
|
||||
}
|
||||
|
||||
// EXPERIMENTAL - operates on internal structures of core Bookmarks plugin
|
||||
|
||||
const createBookmarkFileEntry = (path: string): BookmarkedFile => {
|
||||
// Artificial subpath added intentionally to prevent Bookmarks context menu from finding this item in bookmarks
|
||||
// and - in turn - allow bookmarking it by the user for regular (non sorting) purposes
|
||||
|
@ -177,10 +253,6 @@ const createBookmarkGroupEntry = (title: string): BookmarkedGroup => {
|
|||
return { type: "group", ctime: Date.now(), items: [], title: title }
|
||||
}
|
||||
|
||||
export const bookmarkFolderItem = (item: TAbstractFile, plugin: Bookmarks_PluginInstance, bookmarksGroup?: string) => {
|
||||
bookmarkSiblings([item], plugin, bookmarksGroup)
|
||||
}
|
||||
|
||||
interface BookmarkedParentFolder {
|
||||
group?: BookmarkedGroup // undefined when the item is at root level of bookmarks
|
||||
items: Array<BookmarkedItem> // reference to group.items or to root collection of bookmarks
|
||||
|
@ -229,33 +301,9 @@ const findGroupForItemPathInBookmarks = (itemPath: string, createIfMissing: bool
|
|||
const CreateIfMissing = true
|
||||
const DontCreateIfMissing = false
|
||||
|
||||
export const bookmarkSiblings = (siblings: Array<TAbstractFile>, plugin: Bookmarks_PluginInstance, bookmarksGroup?: string) => {
|
||||
if (siblings.length === 0) return // for sanity
|
||||
|
||||
const bookmarksContainer: BookmarkedParentFolder|undefined = findGroupForItemPathInBookmarks(siblings[0].path, CreateIfMissing, plugin, bookmarksGroup)
|
||||
|
||||
if (bookmarksContainer) { // for sanity, the group should be always created if missing
|
||||
siblings.forEach((aSibling) => {
|
||||
const siblingName = lastPathComponent(aSibling.path)
|
||||
if (!bookmarksContainer.items.find((it) =>
|
||||
((it.type === 'folder' || it.type === 'file') && it.path === aSibling.path) ||
|
||||
(it.type === 'group' && it.title === siblingName))) {
|
||||
const newEntry: BookmarkedItem = (aSibling instanceof TFolder) ? createBookmarkGroupEntry(siblingName) : createBookmarkFileEntry(aSibling.path)
|
||||
bookmarksContainer.items.push(newEntry)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const saveDataAndUpdateBookmarkViews = (plugin: Bookmarks_PluginInstance, app: App) => {
|
||||
plugin.onItemsChanged(true)
|
||||
const bookmarksLeafs = app.workspace.getLeavesOfType('bookmarks')
|
||||
bookmarksLeafs?.forEach((leaf) => {
|
||||
(leaf.view as any)?.update?.()
|
||||
})
|
||||
}
|
||||
|
||||
export const updateSortingBookmarksAfterItemRename = (plugin: Bookmarks_PluginInstance, renamedItem: TAbstractFile, oldPath: string, bookmarksGroup?: string) => {
|
||||
const updateSortingBookmarksAfterItemRenamed = (plugin: Bookmarks_PluginInstance, renamedItem: TAbstractFile, oldPath: string, bookmarksGroup?: string) => {
|
||||
|
||||
if (renamedItem.path === oldPath) return; // sanity
|
||||
|
||||
|
@ -302,6 +350,29 @@ export const updateSortingBookmarksAfterItemRename = (plugin: Bookmarks_PluginIn
|
|||
}
|
||||
|
||||
console.log(`Folder renamel from ${oldPath} to ${renamedItem.path}`)
|
||||
|
||||
plugin.onItemsChanged(true)
|
||||
}
|
||||
|
||||
const updateSortingBookmarksAfterItemDeleted = (plugin: Bookmarks_PluginInstance, deletedItem: TAbstractFile, bookmarksGroup?: string) => {
|
||||
|
||||
// Obsidian automatically deletes all bookmark instances of a file, nothing to be done here
|
||||
if (deletedItem instanceof TFile) return;
|
||||
|
||||
let items = plugin[BookmarksPlugin_items_collectionName]
|
||||
const aFolder: boolean = deletedItem instanceof TFolder
|
||||
const aFile: boolean = !aFolder
|
||||
|
||||
const originalContainer: BookmarkedParentFolder|undefined = findGroupForItemPathInBookmarks(deletedItem.path, DontCreateIfMissing, plugin, bookmarksGroup)
|
||||
|
||||
if (!originalContainer) return;
|
||||
|
||||
const item: BookmarkedItem|undefined = originalContainer.items.find((it) => {
|
||||
if (aFolder && it.type === 'group' && it.title === deletedItem.name) return true;
|
||||
if (aFile && it.type === 'file' && it.path === deletedItem.path) return true;
|
||||
})
|
||||
|
||||
if (!item) return;
|
||||
|
||||
originalContainer.items.remove(item)
|
||||
|
||||
console.log(`Folder deletel ${deletedItem.path}`)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {App, CommunityPlugin, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
import {Starred_PluginInstance} from "./StarredPluginSignature";
|
||||
import {CommunityPlugin, TAbstractFile} from "obsidian";
|
||||
|
||||
// For https://github.com/FlorianWoelki/obsidian-icon-folder
|
||||
|
||||
|
@ -19,7 +18,7 @@ export interface ObsidianIconFolder_PluginInstance extends CommunityPlugin {
|
|||
// 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 => {
|
||||
export const getIconFolderPlugin = (): 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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {App, InstalledPlugin, PluginInstance, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
import {InstalledPlugin, PluginInstance, TAbstractFile, TFile, TFolder} from "obsidian";
|
||||
|
||||
export const StarredPlugin_findStarredFile_methodName = 'findStarredFile'
|
||||
|
||||
|
@ -12,7 +12,7 @@ export interface Starred_PluginInstance extends PluginInstance {
|
|||
|
||||
export const StarredCorePluginId: string = 'starred'
|
||||
|
||||
export const getStarredPlugin = (app?: App): Starred_PluginInstance | undefined => {
|
||||
export const getStarredPlugin = (): 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
|
||||
|
|
Loading…
Reference in New Issue