61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
import type { Entry, FolderEntry } from '#base_modules/FileManager/types/entries'
|
|
|
|
export default class EntrySearchService {
|
|
public search(entries: Entry[], query: string, signal?: AbortSignal): Entry[] {
|
|
if (signal?.aborted) return []
|
|
|
|
const results: Entry[] = []
|
|
const addedFolders = new Set<string>()
|
|
const q = query.toLowerCase()
|
|
|
|
for (const entry of entries) {
|
|
if (signal?.aborted) return results
|
|
|
|
if (entry.type === 'folder') {
|
|
this.addFolderIfMatches(entry, q, addedFolders, results)
|
|
continue
|
|
}
|
|
|
|
if (entry.path.toLowerCase().includes(q)) {
|
|
results.push(entry)
|
|
}
|
|
|
|
for (const folder of this.getFileParentFolders(entry.path)) {
|
|
this.addFolderIfMatches(folder, q, addedFolders, results)
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
private addFolderIfMatches(
|
|
folder: FolderEntry,
|
|
query: string,
|
|
addedFolders: Set<string>,
|
|
results: Entry[]
|
|
) {
|
|
if (!folder.path.toLowerCase().includes(query) || addedFolders.has(folder.path)) return
|
|
|
|
addedFolders.add(folder.path)
|
|
results.push(folder)
|
|
}
|
|
|
|
private getFileParentFolders(path: string): FolderEntry[] {
|
|
const segments = path.replace(/^\/+/, '').split('/').slice(0, -1)
|
|
const folders: FolderEntry[] = []
|
|
let current = ''
|
|
|
|
for (const segment of segments) {
|
|
current = current ? `${current}/${segment}` : segment
|
|
|
|
folders.push({
|
|
name: segment,
|
|
path: current,
|
|
type: 'folder',
|
|
})
|
|
}
|
|
|
|
return folders
|
|
}
|
|
}
|