diff --git a/src/gui/src/UI/Dashboard/TabFiles.js b/src/gui/src/UI/Dashboard/TabFiles.js index 8ece94c58..a358266a1 100644 --- a/src/gui/src/UI/Dashboard/TabFiles.js +++ b/src/gui/src/UI/Dashboard/TabFiles.js @@ -169,17 +169,21 @@ const TabFiles = { } catch { /* keep raw name */ } $row.attr('data-name', displayName); $row.attr('data-path', file.path || ''); - $row.attr('data-size', file.size || 0); - $row.attr('data-modified', file.modified || 0); $row.attr('data-type', file.type || ''); $row.find('.item-name').text(displayName); $row.find('.item-name-editor').val(displayName); // Refresh the visible Size/Modified cells too, not just the // hidden data attributes, so a remote overwrite is reflected. - if ( $row.attr('data-is_dir') !== '1' ) { - $row.find('.item-size').text(_this.formatFileSize(file.size)); + // Only when the payload actually carries the field — a minimal + // update event must not zero out a correct value on screen. + if ( typeof file.size !== 'undefined' ) { + $row.attr('data-size', file.size || 0); + if ( $row.attr('data-is_dir') !== '1' ) { + $row.find('.item-size').text(_this.formatFileSize(file.size)); + } } if ( file.modified ) { + $row.attr('data-modified', file.modified); $row.find('.item-modified').text(window.timeago.format(file.modified * 1000)); } if ( @@ -189,6 +193,9 @@ const TabFiles = { ) { $row.find('.item-icon img').attr('src', file.thumbnail); } + // The footer's item-count/total-size line is computed from the + // rows' data-size attributes — keep it in step with the cell. + _this.updateFooterStats(); }; // Dashboard-compatible item creator for use by helpers.js and socket handlers. @@ -1876,6 +1883,9 @@ const TabFiles = { text-align: center; padding: 0 16px; ">This folder couldn't be opened.`); + // The list was emptied above; without this the footer keeps the + // previous directory's item count over a pane with zero rows. + this.updateFooterStats(); this.hideSpinner(); this.renderingDirectory = false; return; diff --git a/src/gui/src/UI/Dashboard/TabHome.js b/src/gui/src/UI/Dashboard/TabHome.js index a9717ab71..49fad800e 100644 --- a/src/gui/src/UI/Dashboard/TabHome.js +++ b/src/gui/src/UI/Dashboard/TabHome.js @@ -238,8 +238,14 @@ const TabHome = { // Pull fresh whoami, then broadcast. The dispatched event is handled // by the `refresh` listener below, so we don't call refresh() here — // doing both is what caused every focus to fire duplicate reloads. + // The broadcast is the only thing that triggers the refresh, so cap + // the wait: a whoami that never settles (hung connection) must not + // leave the cards stale for the rest of the session. try { - await window.refresh_user_data?.(puter.authToken); + await Promise.race([ + window.refresh_user_data?.(puter.authToken), + new Promise(resolve => setTimeout(resolve, 8000)), + ]); } catch {} try { window.dispatchEvent(