Skip to content

Commit f705486

Browse files
Merge pull request #59216 from nextcloud/backport/58761/stable33
[stable33] feat(recent-files): add recent_files_limit config on files settings
2 parents 1564846 + e9ca2dc commit f705486

20 files changed

Lines changed: 89 additions & 10 deletions

File tree

apps/dav/lib/Capabilities.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public function __construct(
1818
}
1919

2020
/**
21-
* @return array{dav: array{chunking: string, public_shares_chunking: bool, search_supports_creation_time: bool, search_supports_upload_time: bool, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
21+
* @return array{dav: array{chunking: string, public_shares_chunking: bool, search_supports_creation_time: bool, search_supports_upload_time: bool, search_supports_last_activity: bool, bulkupload?: string, absence-supported?: bool, absence-replacement?: bool}}
2222
*/
2323
public function getCapabilities() {
2424
$capabilities = [
@@ -27,6 +27,7 @@ public function getCapabilities() {
2727
'public_shares_chunking' => true,
2828
'search_supports_creation_time' => true,
2929
'search_supports_upload_time' => true,
30+
'search_supports_last_activity' => true,
3031
]
3132
];
3233
if ($this->config->getSystemValueBool('bulkupload.enabled', true)) {

apps/dav/lib/Connector/Sabre/FilesPlugin.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class FilesPlugin extends ServerPlugin {
6767
public const METADATA_ETAG_PROPERTYNAME = '{http://nextcloud.org/ns}metadata_etag';
6868
public const UPLOAD_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}upload_time';
6969
public const CREATION_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}creation_time';
70+
public const LAST_ACTIVITY_PROPERTYNAME = '{http://nextcloud.org/ns}last_activity';
7071
public const SHARE_NOTE = '{http://nextcloud.org/ns}note';
7172
public const SHARE_HIDE_DOWNLOAD_PROPERTYNAME = '{http://nextcloud.org/ns}hide-download';
7273
public const SUBFOLDER_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-folder-count';
@@ -446,6 +447,10 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
446447
return $node->getFileInfo()->getCreationTime();
447448
});
448449

450+
$propFind->handle(self::LAST_ACTIVITY_PROPERTYNAME, function () use ($node) {
451+
return $node->getFileInfo()->getLastActivity();
452+
});
453+
449454
foreach ($node->getFileInfo()->getMetadata() as $metadataKey => $metadataValue) {
450455
$propFind->handle(self::FILE_METADATA_PREFIX . $metadataKey, $metadataValue);
451456
}

apps/dav/lib/Files/FileSearchBackend.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public function getPropertyDefinitionsForScope(string $href, ?string $path): arr
8888
new SearchPropertyDefinition('{DAV:}getlastmodified', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
8989
new SearchPropertyDefinition('{DAV:}creationdate', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
9090
new SearchPropertyDefinition('{http://nextcloud.org/ns}upload_time', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
91+
new SearchPropertyDefinition('{http://nextcloud.org/ns}last_activity', true, false, true, SearchPropertyDefinition::DATATYPE_DATETIME),
9192
new SearchPropertyDefinition(FilesPlugin::SIZE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
9293
new SearchPropertyDefinition(TagsPlugin::FAVORITE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_BOOLEAN),
9394
new SearchPropertyDefinition(FilesPlugin::INTERNAL_FILEID_PROPERTYNAME, true, true, false, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
@@ -304,6 +305,8 @@ private function getSearchResultProperty(SearchResult $result, SearchPropertyDef
304305
return $node->getNode()->getCreationTime();
305306
case '{http://nextcloud.org/ns}upload_time':
306307
return $node->getNode()->getUploadTime();
308+
case '{http://nextcloud.org/ns}last_activity':
309+
return $node->getNode()->getLastActivity();
307310
case FilesPlugin::SIZE_PROPERTYNAME:
308311
return $node->getSize();
309312
case FilesPlugin::INTERNAL_FILEID_PROPERTYNAME:
@@ -332,6 +335,8 @@ private function transformQuery(Query $query, ?SearchBinaryOperator $scopeOperat
332335
$direction = $order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING;
333336
if (str_starts_with($order->property->name, FilesPlugin::FILE_METADATA_PREFIX)) {
334337
return new SearchOrder($direction, substr($order->property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX)), IMetadataQuery::EXTRA);
338+
} elseif ($order->property->name === FilesPlugin::LAST_ACTIVITY_PROPERTYNAME) {
339+
return new SearchOrder($direction, 'last_activity');
335340
} else {
336341
return new SearchOrder($direction, $this->mapPropertyNameToColumn($order->property));
337342
}

apps/dav/openapi.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"chunking",
3333
"public_shares_chunking",
3434
"search_supports_creation_time",
35-
"search_supports_upload_time"
35+
"search_supports_upload_time",
36+
"search_supports_last_activity"
3637
],
3738
"properties": {
3839
"chunking": {
@@ -47,6 +48,9 @@
4748
"search_supports_upload_time": {
4849
"type": "boolean"
4950
},
51+
"search_supports_last_activity": {
52+
"type": "boolean"
53+
},
5054
"bulkupload": {
5155
"type": "string"
5256
},

apps/dav/tests/unit/CapabilitiesTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function testGetCapabilities(): void {
3333
'public_shares_chunking' => true,
3434
'search_supports_creation_time' => true,
3535
'search_supports_upload_time' => true,
36+
'search_supports_last_activity' => true,
3637
],
3738
];
3839
$this->assertSame($expected, $capabilities->getCapabilities());
@@ -55,6 +56,7 @@ public function testGetCapabilitiesWithBulkUpload(): void {
5556
'public_shares_chunking' => true,
5657
'search_supports_creation_time' => true,
5758
'search_supports_upload_time' => true,
59+
'search_supports_last_activity' => true,
5860
'bulkupload' => '1.0',
5961
],
6062
];
@@ -78,6 +80,7 @@ public function testGetCapabilitiesWithAbsence(): void {
7880
'public_shares_chunking' => true,
7981
'search_supports_creation_time' => true,
8082
'search_supports_upload_time' => true,
83+
'search_supports_last_activity' => true,
8184
'absence-supported' => true,
8285
'absence-replacement' => true,
8386
],

apps/files/lib/ConfigLexicon.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
class ConfigLexicon implements ILexicon {
2424
public const OVERWRITES_HOME_FOLDERS = 'overwrites_home_folders';
25+
public const RECENT_LIMIT = 'recent_limit';
2526

2627
public function getStrictness(): Strictness {
2728
return Strictness::IGNORE;
@@ -37,6 +38,13 @@ public function getAppConfigs(): array {
3738
lazy: false,
3839
note: 'It will be populated with app IDs of mount providers that overwrite home folders. Currently, only files_external and groupfolders.',
3940
),
41+
new Entry(
42+
self::RECENT_LIMIT,
43+
ValueType::INT,
44+
defaultRaw: 100,
45+
definition: 'Maximum number of files to display on recent files view',
46+
lazy: false,
47+
),
4048
];
4149
}
4250

apps/files/lib/Controller/ViewController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use OC\Files\FilenameValidator;
1111
use OC\Files\Filesystem;
1212
use OCA\Files\AppInfo\Application;
13+
use OCA\Files\ConfigLexicon;
1314
use OCA\Files\Event\LoadAdditionalScriptsEvent;
1415
use OCA\Files\Event\LoadSearchPlugins;
1516
use OCA\Files\Event\LoadSidebar;
@@ -25,6 +26,7 @@
2526
use OCP\AppFramework\Http\RedirectResponse;
2627
use OCP\AppFramework\Http\Response;
2728
use OCP\AppFramework\Http\TemplateResponse;
29+
use OCP\AppFramework\Services\IAppConfig;
2830
use OCP\AppFramework\Services\IInitialState;
2931
use OCP\Authentication\TwoFactorAuth\IRegistry;
3032
use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent as ResourcesLoadAdditionalScriptsEvent;
@@ -62,6 +64,7 @@ public function __construct(
6264
private ViewConfig $viewConfig,
6365
private FilenameValidator $filenameValidator,
6466
private IRegistry $twoFactorRegistry,
67+
private IAppConfig $appConfig,
6568
) {
6669
parent::__construct($appName, $request);
6770
}
@@ -174,6 +177,7 @@ public function index($dir = '', $view = '', $fileid = null) {
174177
$this->initialState->provideInitialState('storageStats', $storageInfo);
175178
$this->initialState->provideInitialState('config', $this->userConfig->getConfigs());
176179
$this->initialState->provideInitialState('viewConfigs', $this->viewConfig->getConfigs());
180+
$this->initialState->provideInitialState('recent_limit', $this->appConfig->getAppValueInt(ConfigLexicon::RECENT_LIMIT, 100));
177181

178182
// File sorting user config
179183
$filesSortingConfig = json_decode($this->config->getUserValue($userId, 'files', 'files_sorting_configs', '{}'), true);

apps/files/src/services/Recent.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import type { ResponseDataDetailed, SearchResult } from 'webdav'
88
import { getCurrentUser } from '@nextcloud/auth'
99
import { Folder, Permission } from '@nextcloud/files'
1010
import { getRecentSearch, getRemoteURL, getRootPath, resultToNode } from '@nextcloud/files/dav'
11+
import { loadState } from '@nextcloud/initial-state'
1112
import logger from '../logger.ts'
1213
import { getPinia } from '../store/index.ts'
1314
import { useUserConfigStore } from '../store/userconfig.ts'
1415
import { client } from './WebdavClient.ts'
1516

1617
const lastTwoWeeksTimestamp = Math.round((Date.now() / 1000) - (60 * 60 * 24 * 14))
18+
const recentLimit = loadState<number>('files', 'recent_limit', 100)
1719

1820
/**
1921
* Get recently changed nodes
@@ -41,7 +43,7 @@ export async function getContents(path = '/', options: { signal: AbortSignal }):
4143
const contentsResponse = await client.search('/', {
4244
signal: options.signal,
4345
details: true,
44-
data: getRecentSearch(lastTwoWeeksTimestamp),
46+
data: getRecentSearch(lastTwoWeeksTimestamp, recentLimit),
4547
}) as ResponseDataDetailed<SearchResult>
4648

4749
const contents = contentsResponse.data.results

apps/files/tests/Controller/ViewControllerTest.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCP\AppFramework\Http\ContentSecurityPolicy;
1919
use OCP\AppFramework\Http\RedirectResponse;
2020
use OCP\AppFramework\Http\TemplateResponse;
21+
use OCP\AppFramework\Services\IAppConfig;
2122
use OCP\AppFramework\Services\IInitialState;
2223
use OCP\Authentication\TwoFactorAuth\IRegistry;
2324
use OCP\Diagnostics\IEventLogger;
@@ -48,6 +49,7 @@
4849
class ViewControllerTest extends TestCase {
4950
private ContainerInterface&MockObject $container;
5051
private IAppManager&MockObject $appManager;
52+
private IAppConfig&MockObject $appConfig;
5153
private ICacheFactory&MockObject $cacheFactory;
5254
private IConfig&MockObject $config;
5355
private IEventDispatcher $eventDispatcher;
@@ -71,6 +73,7 @@ class ViewControllerTest extends TestCase {
7173
protected function setUp(): void {
7274
parent::setUp();
7375
$this->appManager = $this->createMock(IAppManager::class);
76+
$this->appConfig = $this->createMock(IAppConfig::class);
7477
$this->config = $this->createMock(IConfig::class);
7578
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
7679
$this->initialState = $this->createMock(IInitialState::class);
@@ -142,6 +145,7 @@ protected function setUp(): void {
142145
$this->viewConfig,
143146
$filenameValidator,
144147
$this->twoFactorRegistry,
148+
$this->appConfig,
145149
])
146150
->onlyMethods([
147151
'getStorageInfo',
@@ -298,11 +302,11 @@ public function testTwoFactorAuthEnabled(): void {
298302
'backup_codes' => true,
299303
]);
300304

301-
$invokedCountProvideInitialState = $this->exactly(9);
305+
$invokedCountProvideInitialState = $this->exactly(10);
302306
$this->initialState->expects($invokedCountProvideInitialState)
303307
->method('provideInitialState')
304308
->willReturnCallback(function ($key, $data) use ($invokedCountProvideInitialState): void {
305-
if ($invokedCountProvideInitialState->numberOfInvocations() === 9) {
309+
if ($invokedCountProvideInitialState->numberOfInvocations() === 10) {
306310
$this->assertEquals('isTwoFactorEnabled', $key);
307311
$this->assertTrue($data);
308312
}

apps/files_trashbin/lib/Trash/TrashItem.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ public function getUploadTime(): int {
154154
return $this->fileInfo->getUploadTime();
155155
}
156156

157+
public function getLastActivity(): int {
158+
return $this->fileInfo->getLastActivity();
159+
}
160+
157161
public function getParentId(): int {
158162
return $this->fileInfo->getParentId();
159163
}

0 commit comments

Comments
 (0)