diff --git a/apps/files/lib/Service/UserConfig.php b/apps/files/lib/Service/UserConfig.php
index dcf30b7796db6..f2ad1db02d7d4 100644
--- a/apps/files/lib/Service/UserConfig.php
+++ b/apps/files/lib/Service/UserConfig.php
@@ -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 @@ private function getAllowedConfigValues(string $key): array {
* 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 @@ public function setConfig(string $key, $value): void {
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 @@ public function getConfigs(): array {
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 [];
+ }
}
diff --git a/apps/files/src/components/FilesAppSettings/FilesAppSettingsRecent.vue b/apps/files/src/components/FilesAppSettings/FilesAppSettingsRecent.vue
new file mode 100644
index 0000000000000..71a127443bbc8
--- /dev/null
+++ b/apps/files/src/components/FilesAppSettings/FilesAppSettingsRecent.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/files/src/services/Recent.ts b/apps/files/src/services/Recent.ts
index 314426101b66d..484bf7cf230a7 100644
--- a/apps/files/src/services/Recent.ts
+++ b/apps/files/src/services/Recent.ts
@@ -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
const contents = contentsResponse.data.results
diff --git a/apps/files/src/store/userconfig.ts b/apps/files/src/store/userconfig.ts
index 00fd45e67ac7b..e3675a510544a 100644
--- a/apps/files/src/store/userconfig.ts
+++ b/apps/files/src/store/userconfig.ts
@@ -23,6 +23,7 @@ const initialUserConfig = loadState('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,
diff --git a/apps/files/src/types.ts b/apps/files/src/types.ts
index f87c0c4b8e7c9..a1d830dbf9e7b 100644
--- a/apps/files/src/types.ts
+++ b/apps/files/src/types.ts
@@ -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
diff --git a/apps/files/src/views/FilesAppSettings.vue b/apps/files/src/views/FilesAppSettings.vue
index 7772b3d89c220..0e1967bf58a69 100644
--- a/apps/files/src/views/FilesAppSettings.vue
+++ b/apps/files/src/views/FilesAppSettings.vue
@@ -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() {
+
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index 284ba7f6ef039..7bec32d0d2331 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -153,9 +153,7 @@ public function searchInCaches(ISearchQuery $searchQuery, array $caches): array
$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));