feat(recent-files): add recent_files_limit config on files settings

Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
This commit is contained in:
Cristian Scheid 2026-03-06 16:28:03 -03:00
parent d677a3a5e2
commit 62f3ea390e
7 changed files with 69 additions and 7 deletions

View file

@ -79,6 +79,13 @@ class UserConfig {
'default' => true,
'allowed' => [true, false],
],
[
// Maximum number of files to display in the recent section
'key' => 'recent_files_limit',
'default' => 100,
'min' => 1,
'max' => 100,
],
];
protected ?IUser $user = null;
@ -118,7 +125,7 @@ class UserConfig {
* Get the default config value for a given key
*
* @param string $key a valid config key
* @return string|bool
* @return string|bool|int
*/
private function getDefaultConfigValue(string $key) {
foreach (self::ALLOWED_CONFIGS as $config) {
@ -146,7 +153,13 @@ class UserConfig {
throw new \InvalidArgumentException('Unknown config key');
}
if (!in_array($value, $this->getAllowedConfigValues($key))) {
$config = $this->getConfigDefinition($key);
if (isset($config['min'], $config['max'])) {
if ((int)$value < $config['min'] || (int)$value > $config['max']) {
throw new \InvalidArgumentException('Invalid config value');
}
} elseif (!in_array($value, $this->getAllowedConfigValues($key))) {
throw new \InvalidArgumentException('Invalid config value');
}
@ -179,4 +192,19 @@ class UserConfig {
return array_combine($this->getAllowedConfigKeys(), $userConfigs);
}
/**
* Get the config definition for a given key
*
* @param string $key
* @return array
*/
private function getConfigDefinition(string $key): array {
foreach (self::ALLOWED_CONFIGS as $config) {
if ($config['key'] === $key) {
return $config;
}
}
return [];
}
}

View file

@ -0,0 +1,32 @@
<!--
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<script lang="ts" setup>
import { t } from '@nextcloud/l10n'
import { NcInputField } from '@nextcloud/vue'
import debounce from 'debounce'
import NcAppSettingsSection from '@nextcloud/vue/components/NcAppSettingsSection'
import NcFormBox from '@nextcloud/vue/components/NcFormBox'
import { useUserConfigStore } from '../../store/userconfig.ts'
const store = useUserConfigStore()
const debouncedUpdate = debounce((value: number) => {
store.update('recent_files_limit', value)
}, 500)
</script>
<template>
<NcAppSettingsSection id="recent" :name="t('files', 'Recent view')">
<NcFormBox>
<NcInputField
v-model="store.userConfig.recent_files_limit"
type="number"
:min="1"
:max="100"
:label="t('files', 'Maximum number of files shown in the Recent view')"
@update:model-value="debouncedUpdate(Number($event))" />
</NcFormBox>
</NcAppSettingsSection>
</template>

View file

@ -41,7 +41,7 @@ export async function getContents(path = '/', options: { signal: AbortSignal }):
const contentsResponse = await client.search('/', {
signal: options.signal,
details: true,
data: getRecentSearch(lastTwoWeeksTimestamp),
data: getRecentSearch(lastTwoWeeksTimestamp, store.userConfig.recent_files_limit),
}) as ResponseDataDetailed<SearchResult>
const contents = contentsResponse.data.results

View file

@ -23,6 +23,7 @@ const initialUserConfig = loadState<UserConfig>('files', 'config', {
show_mime_column: true,
sort_favorites_first: true,
sort_folders_first: true,
recent_files_limit: 100,
show_dialog_deletion: false,
show_dialog_file_extension: true,

View file

@ -51,7 +51,7 @@ export interface PathOptions {
// User config store
export interface UserConfig {
[key: string]: boolean | string | undefined
[key: string]: boolean | string | number | undefined
crop_image_previews: boolean
default_view: 'files' | 'personal'
@ -59,6 +59,7 @@ export interface UserConfig {
grid_view: boolean
sort_favorites_first: boolean
sort_folders_first: boolean
recent_files_limit: number
show_files_extensions: boolean
show_hidden: boolean

View file

@ -11,6 +11,7 @@ import NcAppSettingsDialog from '@nextcloud/vue/components/NcAppSettingsDialog'
import FilesAppSettingsAppearance from '../components/FilesAppSettings/FilesAppSettingsAppearance.vue'
import FilesAppSettingsGeneral from '../components/FilesAppSettings/FilesAppSettingsGeneral.vue'
import FilesAppSettingsLegacyApi from '../components/FilesAppSettings/FilesAppSettingsLegacyApi.vue'
import FilesAppSettingsRecent from '../components/FilesAppSettings/FilesAppSettingsRecent.vue'
import FilesAppSettingsShortcuts from '../components/FilesAppSettings/FilesAppSettingsShortcuts.vue'
import FilesAppSettingsWarnings from '../components/FilesAppSettings/FilesAppSettingsWarnings.vue'
import FilesAppSettingsWebDav from '../components/FilesAppSettings/FilesAppSettingsWebDav.vue'
@ -57,6 +58,7 @@ async function showKeyboardShortcuts() {
<FilesAppSettingsLegacyApi />
<FilesAppSettingsWarnings />
<FilesAppSettingsWebDav />
<FilesAppSettingsRecent />
<FilesAppSettingsShortcuts />
</NcAppSettingsDialog>
</template>

View file

@ -153,9 +153,7 @@ class QuerySearchHelper {
$requestedFields = $this->searchBuilder->extractRequestedFields($searchQuery->getSearchOperation());
$joinExtendedCache = in_array('creation_time', $requestedFields) || in_array('upload_time', $requestedFields);
$query = $builder->selectFileCache('file', $joinExtendedCache);
$query = $builder->selectFileCache('file', true);
if (in_array('systemtag', $requestedFields)) {
$this->equipQueryForSystemTags($query, $this->requireUser($searchQuery));