Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 36 additions & 17 deletions apps/files/lib/Activity/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,26 @@
*/
namespace OCA\Files\Activity;

use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OCP\Files\FileInfo;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\ITagManager;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOrder;
use OCP\IUserManager;

class Helper {
/** If a user has a lot of favorites the query might get too slow and long */
public const FAVORITE_LIMIT = 50;

public function __construct(
protected ITagManager $tagManager,
protected IRootFolder $rootFolder,
protected IUserManager $userManager,
) {
}

Expand All @@ -32,29 +40,40 @@ public function __construct(
* @throws \RuntimeException when too many or no favorites where found
*/
public function getFavoriteNodes(string $user, bool $foldersOnly = false): array {
$tags = $this->tagManager->load('files', [], false, $user);
$favorites = $tags->getFavorites();

if (empty($favorites)) {
$userObject = $this->userManager->get($user);
if ($userObject === null) {
throw new \RuntimeException('No favorites', 1);
} elseif (isset($favorites[self::FAVORITE_LIMIT])) {
throw new \RuntimeException('Too many favorites', 2);
}

// Can not DI because the user is not known on instantiation
$userFolder = $this->rootFolder->getUserFolder($user);
$favoriteNodes = [];
foreach ($favorites as $favorite) {
$node = $userFolder->getFirstNodeById($favorite);
if ($node) {
if (!$foldersOnly || $node instanceof Folder) {
$favoriteNodes[] = $node;
}
}

$operator = new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'favorite', true);
if ($foldersOnly) {
$operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
$operator,
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', FileInfo::MIMETYPE_FOLDER),
]);
}

$favoriteNodes = $userFolder->search(new SearchQuery(
$operator,
self::FAVORITE_LIMIT + 1,
0,
[
new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime'),
],
$userObject,
));

if (empty($favoriteNodes)) {
throw new \RuntimeException('No favorites', 1);
} elseif (isset($favoriteNodes[self::FAVORITE_LIMIT])) {
throw new \RuntimeException('Too many favorites', 2);
}

if ($foldersOnly) {
/** @var Folder[] $favoriteNodes */
return $favoriteNodes;
}

return $favoriteNodes;
Expand Down
88 changes: 44 additions & 44 deletions apps/files/lib/Dashboard/FavoriteWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
namespace OCA\Files\Dashboard;

use OCA\Files\AppInfo\Application;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OCP\Dashboard\IAPIWidgetV2;
use OCP\Dashboard\IButtonWidget;
use OCP\Dashboard\IIconWidget;
Expand All @@ -19,11 +22,10 @@
use OCP\Dashboard\Model\WidgetItems;
use OCP\Dashboard\Model\WidgetOptions;
use OCP\Files\File;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOrder;
use OCP\IL10N;
use OCP\IPreview;
use OCP\ITagManager;
use OCP\IURLGenerator;
use OCP\IUserManager;

Expand All @@ -32,11 +34,8 @@ class FavoriteWidget implements IIconWidget, IAPIWidgetV2, IButtonWidget, IOptio
public function __construct(
private readonly IL10N $l10n,
private readonly IURLGenerator $urlGenerator,
private readonly IMimeTypeDetector $mimeTypeDetector,
private readonly IUserManager $userManager,
private readonly ITagManager $tagManager,
private readonly IRootFolder $rootFolder,
private readonly IPreview $previewManager,
) {
}

Expand Down Expand Up @@ -71,50 +70,51 @@ public function load(): void {

public function getItems(string $userId, int $limit = 7): array {
$user = $this->userManager->get($userId);

if (!$user) {
return [];
}
$tags = $this->tagManager->load('files', [], false, $userId);
$favorites = $tags->getFavorites();
if (empty($favorites)) {
return [];
}
$favoriteNodes = [];

$userFolder = $this->rootFolder->getUserFolder($userId);
$count = 0;
foreach ($favorites as $favorite) {
$node = $userFolder->getFirstNodeById($favorite);
if ($node) {
$url = $this->urlGenerator->linkToRouteAbsolute(
'files.view.showFile', ['fileid' => $node->getId()]
);
if ($node instanceof File) {
$icon = $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', [
'x' => 256,
'y' => 256,
'fileId' => $node->getId(),
'c' => $node->getEtag(),
'mimeFallback' => true,
]);
} else {
$icon = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'filetypes/folder.svg'));
}
$favoriteNodes[] = new WidgetItem(
$node->getName(),
'',
$url,
$icon,
(string)$node->getCreationTime()
);
$count++;
if ($count >= $limit) {
break;
}
$folderIcon = $this->urlGenerator->getAbsoluteURL(
$this->urlGenerator->imagePath('core', 'filetypes/folder.svg')
);

$favoriteNodes = $userFolder->search(new SearchQuery(
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'favorite', true),
$limit,
0,
[
new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime'),
],
$user,
));

return array_map(function ($node) use ($folderIcon) {
$url = $this->urlGenerator->linkToRouteAbsolute(
'files.view.showFile',
['fileid' => $node->getId()]
);

if ($node instanceof File) {
$icon = $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', [
'x' => 256,
'y' => 256,
'fileId' => $node->getId(),
'c' => $node->getEtag(),
'mimeFallback' => true,
]);
} else {
$icon = $folderIcon;
}
}

return $favoriteNodes;
return new WidgetItem(
$node->getName(),
'',
$url,
$icon,
(string)$node->getCreationTime()
);
}, $favoriteNodes);
}

public function getItemsV2(string $userId, ?string $since = null, int $limit = 7): WidgetItems {
Expand Down
Loading