Share item-added updates across GUI shells
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s

Extracted desktop `item.added` container update logic into a shared `apply_item_added_to_containers` helper and wired it into both `UIDesktop` and `UIDashboard`. The helper handles overwrite updates, new item insertion, icon refresh, and resorting for matching item containers. This fixes dashboard-hosted explorer/file dialogs not reflecting uploads until navigation.
This commit is contained in:
jelveh
2026-07-24 23:01:10 -07:00
parent 4245ac04ac
commit 3b1ba72ddd
3 changed files with 88 additions and 42 deletions
+6
View File
@@ -25,6 +25,7 @@ import UIAlert from '../UIAlert.js';
import UIWindowSaveAccount from '../UIWindowSaveAccount.js';
import UIWindowLogin from '../UIWindowLogin.js';
import UIWindowFeedback from '../UIWindowFeedback.js';
import apply_item_added_to_containers from '../../helpers/apply_item_added_to_containers.js';
/**
* Creates and displays the Dashboard window.
*
@@ -364,6 +365,11 @@ async function UIDashboard (options) {
if ( window.UIDashboardFileItem ) {
window.UIDashboardFileItem(item);
}
// The Files tab above is the dashboard's own listing; file dialogs and
// explorer windows opened over the dashboard are plain UIWindow item
// containers and need the same update the desktop gives them.
await apply_item_added_to_containers(item);
});
// Apply initial route from URL - activate the correct tab
+2 -42
View File
@@ -41,6 +41,7 @@ import UINotification from './UINotification.js';
import UIWindowWelcome from './UIWindowWelcome.js';
import launch_app from '../helpers/launch_app.js';
import item_icon from '../helpers/item_icon.js';
import apply_item_added_to_containers from '../helpers/apply_item_added_to_containers.js';
import UIWindowSearch from './UIWindowSearch.js';
async function UIDesktop (options) {
@@ -627,48 +628,7 @@ async function UIDesktop (options) {
return;
}
// Update replaced items with matching uids
if ( item.overwritten_uid ) {
$(`.item[data-uid='${item.overwritten_uid}']`).attr({
'data-immutable': item.immutable,
'data-path': item.path,
'data-name': item.name,
'data-size': item.size,
'data-modified': item.modified,
'data-type': item.type,
});
// set new icon
const new_icon = (item.is_dir ? window.icons['folder.svg'] : (await item_icon(item)).image);
$(`.item[data-uid="${item.overwritten_uid}"]`).find('.item-icon > img').attr('src', new_icon);
//sort each window
$(`.item-container[data-path='${html_encode(item.dirpath)}' i]`).each(function () {
window.sort_items(this, $(this).attr('data-sort_by'), $(this).attr('data-sort_order'));
});
}
else {
UIItem({
appendTo: $(`.item-container[data-path='${html_encode(item.dirpath)}' i]`),
uid: item.uid,
immutable: item.immutable || item.writable === false,
associated_app_name: item.associated_app?.name,
path: item.path,
icon: await item_icon(item),
name: item.name,
size: item.size,
type: item.type,
modified: item.modified,
is_dir: item.is_dir,
is_shortcut: item.is_shortcut,
shortcut_to: item.shortcut_to,
shortcut_to_path: item.shortcut_to_path,
});
//sort each window
$(`.item-container[data-path='${html_encode(item.dirpath)}' i]`).each(function () {
window.sort_items(this, $(this).attr('data-sort_by'), $(this).attr('data-sort_order'));
});
}
await apply_item_added_to_containers(item);
});
// Hidden file dialog
@@ -0,0 +1,80 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*/
import UIItem from '../UI/UIItem.js';
import item_icon from './item_icon.js';
/**
* Reflect an `item.added` socket event in every open UIWindow item container
* showing the item's directory — explorer windows and file dialogs.
*
* Shared by both shells: the desktop and the dashboard each own their
* chrome-specific listing (desktop icons / the dashboard's Files tab) but both
* can host UIWindow item containers, and those need the same treatment. When
* only the desktop did this, uploading through a file dialog's "Upload" button
* on the dashboard left the dialog looking empty until it was navigated.
*
* A dialog's `accept` filter needs no handling here — UIItem reads
* data-allowed_file_types off the container it is appended to.
*
* @param {object} item fsentry from the `item.added` event
*/
const apply_item_added_to_containers = async function (item) {
const $containers = $(`.item-container[data-path='${html_encode(item.dirpath)}' i]`);
if ( $containers.length === 0 ) {
return;
}
// An overwrite reuses the existing element rather than adding a second one.
if ( item.overwritten_uid ) {
$(`.item[data-uid='${item.overwritten_uid}']`).attr({
'data-immutable': item.immutable,
'data-path': item.path,
'data-name': item.name,
'data-size': item.size,
'data-modified': item.modified,
'data-type': item.type,
});
const new_icon = (item.is_dir ? window.icons['folder.svg'] : (await item_icon(item)).image);
$(`.item[data-uid="${item.overwritten_uid}"]`).find('.item-icon > img').attr('src', new_icon);
} else {
UIItem({
appendTo: $containers,
uid: item.uid,
immutable: item.immutable || item.writable === false,
associated_app_name: item.associated_app?.name,
path: item.path,
icon: await item_icon(item),
name: item.name,
size: item.size,
type: item.type,
modified: item.modified,
is_dir: item.is_dir,
is_shortcut: item.is_shortcut,
shortcut_to: item.shortcut_to,
shortcut_to_path: item.shortcut_to_path,
});
}
$containers.each(function () {
window.sort_items(this, $(this).attr('data-sort_by'), $(this).attr('data-sort_order'));
});
};
export default apply_item_added_to_containers;