aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src/filters/FilenameFilter.ts
blob: f86269ccd99574f8db1ed7a2c3040109512a2531 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*!
 * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

import type { IFileListFilterChip, INode } from '@nextcloud/files'

import { subscribe } from '@nextcloud/event-bus'
import { FileListFilter, registerFileListFilter } from '@nextcloud/files'
import { getPinia } from '../store/index.ts'
import { useSearchStore } from '../store/search.ts'

/**
 * Register the filename filter
 */
export function registerFilenameFilter() {
	registerFileListFilter(new FilenameFilter())
}

/**
 * Simple file list filter controlled by the Navigation search box
 */
class FilenameFilter extends FileListFilter {

	private searchQuery = ''

	constructor() {
		super('files:filename', 5)
		subscribe('files:search:updated', ({ query, scope }) => {
			if (scope === 'filter') {
				this.updateQuery(query)
			}
		})
	}

	public filter(nodes: INode[]): INode[] {
		const queryParts = this.searchQuery.toLocaleLowerCase().split(' ').filter(Boolean)
		return nodes.filter((node) => {
			const displayname = node.displayname.toLocaleLowerCase()
			return queryParts.every((part) => displayname.includes(part))
		})
	}

	public reset(): void {
		this.updateQuery('')
	}

	public updateQuery(query: string) {
		query = (query || '').trim()

		// Only if the query is different we update the filter to prevent re-computing all nodes
		if (query !== this.searchQuery) {
			this.searchQuery = query
			this.filterUpdated()

			const chips: IFileListFilterChip[] = []
			if (query !== '') {
				chips.push({
					text: query,
					onclick: () => {
						this.updateQuery('')
					},
				})
			} else {
				// make sure to also reset the search store when pressing the "X" on the filter chip
				const store = useSearchStore(getPinia())
				if (store.scope === 'filter') {
					store.query = ''
				}
			}
			this.updateChips(chips)
		}
	}

}