@@ -1203,7 +1218,8 @@
['sent', 'propagated', 'unknown'].includes(chatItem.lxmf_message.state)
"
icon-name="check"
- class="size-3 text-white/90"
+ class="size-3"
+ :class="outboundBubbleSentCheckIconClass(chatItem)"
:title="
chatItem.lxmf_message.state === 'propagated'
? 'Sent to propagation node'
@@ -1239,7 +1255,8 @@
+
+
+
+
+ {{ hopFilterSlider === 0 ? $t("visualiser.all") : hopFilterSlider }}
+
+
+
+
!i.status);
},
+ hopSliderMax() {
+ let m = 0;
+ for (const e of this.pathTable) {
+ if (e.hops != null && e.hops > m) m = e.hops;
+ }
+ return Math.min(256, Math.max(1, m));
+ },
+ hopFilterMax() {
+ if (this.hopFilterSlider === 0) return null;
+ return this.hopFilterSlider;
+ },
},
watch: {
autoReload(val) {
@@ -354,6 +391,18 @@ export default {
// we don't want to trigger a full update from server, just re-run the filtering on existing data
this.processVisualization();
},
+ hopSliderMax() {
+ if (this.hopFilterSlider > this.hopSliderMax) {
+ this.hopFilterSlider = this.hopSliderMax;
+ }
+ },
+ hopFilterSlider() {
+ if (this._hopFilterDebounce) clearTimeout(this._hopFilterDebounce);
+ this._hopFilterDebounce = setTimeout(() => {
+ this._hopFilterDebounce = null;
+ this.processVisualization();
+ }, 80);
+ },
},
beforeUnmount() {
if (this.abortController) {
@@ -368,6 +417,10 @@ export default {
this.stopOrbit();
this.stopBouncingBalls();
clearInterval(this.reloadInterval);
+ if (this._hopFilterDebounce) {
+ clearTimeout(this._hopFilterDebounce);
+ this._hopFilterDebounce = null;
+ }
if (this.network) {
this.network.destroy();
}
@@ -1210,6 +1263,14 @@ export default {
continue;
}
+ if (
+ this.hopFilterMax != null &&
+ disc.hops != null &&
+ disc.hops > this.hopFilterMax
+ ) {
+ continue;
+ }
+
const isConnected = this.discoveredActive.some((a) => {
const aHost = a.target_host || a.remote || a.listen_ip;
const aPort = a.target_port || a.listen_port;
@@ -1284,6 +1345,7 @@ export default {
for (const entry of chunk) {
this.loadedNodesCount++;
if (entry.hops == null) continue;
+ if (this.hopFilterMax != null && entry.hops > this.hopFilterMax) continue;
const announce = this.announces[entry.hash];
if (!announce || !aspectsToShow.includes(announce.aspect)) continue;
diff --git a/meshchatx/src/frontend/components/settings/SettingsPage.vue b/meshchatx/src/frontend/components/settings/SettingsPage.vue
index fa1a748..f5b81be 100644
--- a/meshchatx/src/frontend/components/settings/SettingsPage.vue
+++ b/meshchatx/src/frontend/components/settings/SettingsPage.vue
@@ -98,7 +98,7 @@