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,