fix: Dashboard Files footer sync and Home refresh resilience

- The shared row updater now refreshes the footer's item-count/total
  line, which is computed from the data-size attributes it just wrote;
  a remote overwrite no longer leaves the row and footer disagreeing.
- Size/Modified are only written when the update payload carries them,
  so a minimal event can't zero out correct values on screen.
- A failed readdir now resets the footer instead of keeping the
  previous directory's counts over an empty pane.
- Home's focus-refresh caps its wait on refresh_user_data, so a whoami
  that never settles can't leave the plan/usage cards stale forever.
This commit is contained in:
jelveh
2026-07-18 16:57:53 -07:00
parent 01f6076bcb
commit cf6e77300c
2 changed files with 21 additions and 5 deletions
+14 -4
View File
@@ -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.</div>`);
// 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;
+7 -1
View File
@@ -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(