From c1680bdf0c4ea64cb29c4d63c4a8027abba07e5a Mon Sep 17 00:00:00 2001 From: Juan Castro Date: Thu, 13 Aug 2026 17:15:46 -0400 Subject: [PATCH] fix(gui): page through every shared item instead of the first 50 --- src/gui/src/UI/Dashboard/TabFiles.js | 5 +- src/gui/src/helpers/list_all_shared.js | 46 +++++++++++++++++++ src/gui/src/helpers/refresh_item_container.js | 5 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/gui/src/helpers/list_all_shared.js diff --git a/src/gui/src/UI/Dashboard/TabFiles.js b/src/gui/src/UI/Dashboard/TabFiles.js index 9819c7895..461cfdcb6 100644 --- a/src/gui/src/UI/Dashboard/TabFiles.js +++ b/src/gui/src/UI/Dashboard/TabFiles.js @@ -36,6 +36,7 @@ import { dedupedName } from './dedupedName.js'; import { isEntryVisible, isHiddenName, showHiddenFiles } from './hiddenFiles.js'; import { icons } from '../../helpers/actionIcons.js'; +import list_all_shared from '../../helpers/list_all_shared.js'; const { html_encode, SelectionArea } = window; @@ -2141,11 +2142,13 @@ const TabFiles = { let directoryContents; try { directoryContents = isSharedView - ? (await window.puter.fs.listShared()).items.map((share) => ({ + ? (await list_all_shared()).map((share) => ({ uid: share.entryUid, name: share.path.split('/').pop(), path: share.path, is_dir: share.isDir, + modified: share.modified, + size: share.size, shared_with_me: true, share_mode: share.mode, shared_by: share.issuer, diff --git a/src/gui/src/helpers/list_all_shared.js b/src/gui/src/helpers/list_all_shared.js new file mode 100644 index 000000000..b9954cff7 --- /dev/null +++ b/src/gui/src/helpers/list_all_shared.js @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// Largest page the backend will serve (ShareStore.MAX_HOLDER_PAGE_SIZE). +const PAGE_SIZE = 200; + +/** + * Every share the current user holds, across all pages. A page can be short + * once unreachable items are filtered out, so it pages on `cursor` rather than + * on the item count. + * + * @returns {Promise>} + */ +const list_all_shared = async () => { + const shares = []; + let cursor; + + do { + const page = await window.puter.fs.listShared({ + limit: PAGE_SIZE, + ...(cursor ? { cursor } : {}), + }); + shares.push(...(page.items ?? [])); + cursor = page.cursor; + } while ( cursor ); + + return shares; +}; + +export default list_all_shared; diff --git a/src/gui/src/helpers/refresh_item_container.js b/src/gui/src/helpers/refresh_item_container.js index 4b694820f..206f7920c 100644 --- a/src/gui/src/helpers/refresh_item_container.js +++ b/src/gui/src/helpers/refresh_item_container.js @@ -20,6 +20,7 @@ import path from '../lib/path.js'; import UIItem from '../UI/UIItem.js'; import item_icon from './item_icon.js'; +import list_all_shared from './list_all_shared.js'; const refresh_item_container = function (el_item_container, options) { // start a transaction @@ -127,11 +128,13 @@ const refresh_item_container = function (el_item_container, options) { // get items with subdomains/workers included to avoid per-item stat calls const entries_promise = is_shared_view - ? puter.fs.listShared().then((page) => page.items.map((share) => ({ + ? list_all_shared().then((shares) => shares.map((share) => ({ uid: share.entryUid, name: path.basename(share.path), path: share.path, is_dir: share.isDir, + modified: share.modified, + size: share.size, // Carried so the context menu can offer "remove from shared" // rather than a delete the backend would refuse. shared_with_me: true,