mirror of
https://github.com/pe1hvh/meshcore-gui.git
synced 2026-08-07 09:22:50 +02:00
HotFixPerformance
This commit is contained in:
@@ -25,7 +25,7 @@ from typing import Any, Dict, List
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
VERSION: str = "1.13.2"
|
||||
VERSION: str = "1.13.3"
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
@@ -293,7 +293,7 @@ CHANNEL_CACHE_ENABLED: bool = False
|
||||
|
||||
# Fixed device name applied when the BOT checkbox is enabled.
|
||||
# The original device name is saved and restored when BOT is disabled.
|
||||
BOT_DEVICE_NAME: str = "NL-OV-ZWL-STDSHGN-WKC Bot"
|
||||
BOT_DEVICE_NAME: str = "ZwolsBotje"
|
||||
|
||||
# Default device name used as fallback when restoring from BOT mode
|
||||
# and no original name was saved (e.g. after a restart).
|
||||
|
||||
+146
-62
@@ -677,34 +677,17 @@ class DashboardPage:
|
||||
container.set_visibility(pid == panel_id)
|
||||
self._active_panel = panel_id
|
||||
|
||||
# Apply channel filter to messages panel
|
||||
if panel_id == 'messages' and self._messages:
|
||||
self._messages.set_active_channel(channel)
|
||||
# Force immediate rebuild so the panel is populated the
|
||||
# moment it becomes visible, instead of waiting for the
|
||||
# next 500 ms timer tick (which caused the "empty on first
|
||||
# click, populated on second click" symptom).
|
||||
data = self._shared.get_snapshot()
|
||||
self._messages.update(
|
||||
data,
|
||||
self._messages.channel_filters,
|
||||
self._messages.last_channels,
|
||||
room_pubkeys=(
|
||||
self._room_server.get_room_pubkeys()
|
||||
if self._room_server else None
|
||||
),
|
||||
)
|
||||
|
||||
# Apply channel filter to archive panel
|
||||
if panel_id == 'archive' and self._archive_page:
|
||||
self._archive_page.set_channel_filter(channel)
|
||||
|
||||
# Force map recenter when opening map panel (Leaflet may be hidden on load)
|
||||
if panel_id == 'map' and self._map:
|
||||
data = self._shared.get_snapshot()
|
||||
data['force_center'] = True
|
||||
self._map.update(data)
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
self._refresh_active_panel_now(force_map_center=(panel_id == 'map'))
|
||||
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
# Update active menu highlight (standalone buttons only)
|
||||
for pid, btn in self._menu_buttons.items():
|
||||
if pid == panel_id:
|
||||
@@ -712,10 +695,89 @@ class DashboardPage:
|
||||
else:
|
||||
btn.classes(remove='domca-menu-active')
|
||||
|
||||
# Refresh only the selected panel immediately so the user does not
|
||||
# need to wait for the next 500 ms dashboard tick.
|
||||
self._refresh_active_panel_now()
|
||||
|
||||
# Close drawer after selection
|
||||
if self._drawer:
|
||||
self._drawer.hide()
|
||||
|
||||
<<<<<<< HEAD
|
||||
def _refresh_active_panel_now(self) -> None:
|
||||
"""Refresh exactly the active panel once, outside the timer tick."""
|
||||
data = self._shared.get_snapshot()
|
||||
|
||||
if self._active_panel == 'device' and self._device:
|
||||
self._device.update(data)
|
||||
elif self._active_panel == 'map' and self._map:
|
||||
data = dict(data)
|
||||
data['force_center'] = True
|
||||
self._map.update(data)
|
||||
elif self._active_panel == 'actions' and self._actions:
|
||||
self._actions.update(data)
|
||||
elif self._active_panel == 'contacts' and self._contacts:
|
||||
self._contacts.update(data)
|
||||
elif self._active_panel == 'messages' and self._messages:
|
||||
if data.get('channels'):
|
||||
self._messages.update_filters(data)
|
||||
self._messages.update_channel_options(data['channels'])
|
||||
self._update_submenus(data)
|
||||
=======
|
||||
def _refresh_active_panel_now(self, force_map_center: bool = False) -> None:
|
||||
"""Refresh only the currently visible panel.
|
||||
|
||||
This is used directly after a panel switch so the user does not
|
||||
need to wait for the next 500 ms dashboard tick.
|
||||
"""
|
||||
data = self._shared.get_snapshot()
|
||||
|
||||
if data.get('channels'):
|
||||
self._messages.update_filters(data)
|
||||
self._messages.update_channel_options(data['channels'])
|
||||
self._update_submenus(data)
|
||||
|
||||
if self._active_panel == 'device':
|
||||
self._device.update(data)
|
||||
elif self._active_panel == 'map':
|
||||
if force_map_center:
|
||||
data['force_center'] = True
|
||||
self._map.update(data)
|
||||
elif self._active_panel == 'actions':
|
||||
self._actions.update(data)
|
||||
elif self._active_panel == 'contacts':
|
||||
self._contacts.update(data)
|
||||
elif self._active_panel == 'messages':
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
self._messages.update(
|
||||
data,
|
||||
self._messages.channel_filters,
|
||||
self._messages.last_channels,
|
||||
<<<<<<< HEAD
|
||||
room_pubkeys=self._room_server.get_room_pubkeys() if self._room_server else None,
|
||||
)
|
||||
elif self._active_panel == 'rooms' and self._room_server:
|
||||
if data.get('channels'):
|
||||
self._messages.update_filters(data)
|
||||
self._messages.update_channel_options(data['channels'])
|
||||
self._update_submenus(data)
|
||||
self._room_server.update(data)
|
||||
elif self._active_panel == 'rxlog' and self._rxlog:
|
||||
self._rxlog.update(data)
|
||||
elif self._active_panel == 'archive' and self._archive_page:
|
||||
self._archive_page.refresh()
|
||||
=======
|
||||
room_pubkeys=(
|
||||
self._room_server.get_room_pubkeys()
|
||||
if self._room_server else None
|
||||
),
|
||||
)
|
||||
elif self._active_panel == 'rooms':
|
||||
self._room_server.update(data)
|
||||
elif self._active_panel == 'rxlog':
|
||||
self._rxlog.update(data)
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Room Server callback (from ContactsPanel)
|
||||
# ------------------------------------------------------------------
|
||||
@@ -753,56 +815,78 @@ class DashboardPage:
|
||||
# Always update status
|
||||
self._status_label.text = data['status']
|
||||
|
||||
# Device info
|
||||
if data['device_updated'] or is_first:
|
||||
self._device.update(data)
|
||||
|
||||
# Map: always send a snapshot while the panel is active.
|
||||
# The JS runtime coalesces pending payloads — only the newest
|
||||
# is ever applied — so calling update() on every tick is cheap.
|
||||
# This ensures the Leaflet runtime always gets at least one
|
||||
# valid snapshot after it finishes loading, regardless of
|
||||
# whether device_updated or is_first happened to be True
|
||||
# on the tick that fired before MeshCoreLeafletBoot was defined.
|
||||
if self._active_panel == 'map':
|
||||
self._map.update(data)
|
||||
|
||||
# Channel-dependent UI: always ensure consistency when
|
||||
# channels exist. Because a single DashboardPage instance
|
||||
# is shared across browser sessions (render() is called on
|
||||
# each new connection), the old session's timer can steal
|
||||
# the is_first flag before the new timer fires. Running
|
||||
# these unconditionally is safe because each method has an
|
||||
# internal fingerprint/equality check that prevents
|
||||
# unnecessary DOM updates.
|
||||
<<<<<<< HEAD
|
||||
# Channel-dependent navigation/filter state remains global, but
|
||||
# expensive panel refreshes must only run for the active panel.
|
||||
=======
|
||||
# Channel-dependent drawer/submenu state may stay global.
|
||||
# The helpers below already contain equality checks, so this
|
||||
# remains cheap while keeping navigation consistent.
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
if data['channels']:
|
||||
self._messages.update_filters(data)
|
||||
self._messages.update_channel_options(data['channels'])
|
||||
self._update_submenus(data)
|
||||
|
||||
# BOT checkbox state (only on actual change or first render
|
||||
# to avoid overwriting user interaction mid-toggle)
|
||||
if data['channels_updated'] or is_first:
|
||||
self._actions.update(data)
|
||||
if self._active_panel == 'device':
|
||||
if data['device_updated'] or is_first:
|
||||
self._device.update(data)
|
||||
<<<<<<< HEAD
|
||||
elif self._active_panel == 'map':
|
||||
self._map.update(data)
|
||||
elif self._active_panel == 'actions':
|
||||
if data['channels_updated'] or is_first:
|
||||
self._actions.update(data)
|
||||
elif self._active_panel == 'contacts':
|
||||
if data['contacts_updated'] or is_first:
|
||||
self._contacts.update(data)
|
||||
=======
|
||||
|
||||
# Contacts
|
||||
if data['contacts_updated'] or is_first:
|
||||
self._contacts.update(data)
|
||||
elif self._active_panel == 'map':
|
||||
# Keep sending snapshots while the map panel is active.
|
||||
# The browser runtime coalesces pending payloads, so only
|
||||
# the newest snapshot is applied.
|
||||
self._map.update(data)
|
||||
|
||||
# Messages (always — for live filter changes)
|
||||
self._messages.update(
|
||||
data,
|
||||
self._messages.channel_filters,
|
||||
self._messages.last_channels,
|
||||
room_pubkeys=self._room_server.get_room_pubkeys() if self._room_server else None,
|
||||
)
|
||||
elif self._active_panel == 'actions':
|
||||
if data['channels_updated'] or is_first:
|
||||
self._actions.update(data)
|
||||
|
||||
# Room Server panels (always — for live messages + contact changes)
|
||||
self._room_server.update(data)
|
||||
elif self._active_panel == 'contacts':
|
||||
if data['contacts_updated'] or is_first:
|
||||
self._contacts.update(data)
|
||||
|
||||
# RX Log
|
||||
if data['rxlog_updated']:
|
||||
self._rxlog.update(data)
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
elif self._active_panel == 'messages':
|
||||
self._messages.update(
|
||||
data,
|
||||
self._messages.channel_filters,
|
||||
self._messages.last_channels,
|
||||
<<<<<<< HEAD
|
||||
room_pubkeys=self._room_server.get_room_pubkeys() if self._room_server else None,
|
||||
)
|
||||
elif self._active_panel == 'rooms':
|
||||
self._room_server.update(data)
|
||||
elif self._active_panel == 'rxlog':
|
||||
if data['rxlog_updated'] or is_first:
|
||||
self._rxlog.update(data)
|
||||
elif self._active_panel == 'archive' and self._archive_page:
|
||||
if data.get('messages_updated') or data.get('channels_updated') or is_first:
|
||||
self._archive_page.refresh()
|
||||
=======
|
||||
room_pubkeys=(
|
||||
self._room_server.get_room_pubkeys()
|
||||
if self._room_server else None
|
||||
),
|
||||
)
|
||||
|
||||
elif self._active_panel == 'rooms':
|
||||
self._room_server.update(data)
|
||||
|
||||
elif self._active_panel == 'rxlog':
|
||||
if data['rxlog_updated'] or is_first:
|
||||
self._rxlog.update(data)
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
|
||||
# Signal worker that GUI is ready for data
|
||||
if is_first and data['channels'] and data['contacts']:
|
||||
|
||||
@@ -48,7 +48,6 @@ class MapPanel:
|
||||
ui.element('div').props(f'id={self._container_id}').classes(
|
||||
'meshcore-leaflet-host w-full h-72'
|
||||
)
|
||||
self._dispatch_to_browser(snapshot={'__command__': 'ensure_map'})
|
||||
self._apply_theme_only()
|
||||
|
||||
def set_ui_dark_mode(self, value: bool | None) -> None:
|
||||
|
||||
@@ -634,6 +634,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
const hasSnapshotWork = Boolean(current.snapshot);
|
||||
const hasLiveMap = maps.has(containerId);
|
||||
|
||||
if (!hasSnapshotWork && !hasLiveMap) {
|
||||
=======
|
||||
if (!current.snapshot && current.theme && !maps.has(containerId)) {
|
||||
pending.set(containerId, current);
|
||||
>>>>>>> b76eacf1119026c49c25d2811a6d713da8f8e01b
|
||||
return;
|
||||
}
|
||||
|
||||
pending.set(containerId, current);
|
||||
scheduleProcess(containerId, 0);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user