From 7f1a9834989e4d054af9fc2dad9b22011fc86041 Mon Sep 17 00:00:00 2001 From: Melody Ruch <396921921@qq.com> Date: Sat, 15 Aug 2026 23:42:56 +0800 Subject: [PATCH] fix(mqtt): add pause and resume control for message stream --- .../src/components/mqtt/MqttAdminConsole.vue | 16 ++- .../__tests__/MqttAdminConsolePause.spec.ts | 128 ++++++++++++++++++ apps/desktop/src/i18n/locales/en.ts | 2 + apps/desktop/src/i18n/locales/es.ts | 2 + apps/desktop/src/i18n/locales/it.ts | 2 + apps/desktop/src/i18n/locales/ja.ts | 2 + apps/desktop/src/i18n/locales/pt-BR.ts | 2 + apps/desktop/src/i18n/locales/zh-CN.ts | 2 + apps/desktop/src/i18n/locales/zh-TW.ts | 2 + 9 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 apps/desktop/src/components/mqtt/__tests__/MqttAdminConsolePause.spec.ts diff --git a/apps/desktop/src/components/mqtt/MqttAdminConsole.vue b/apps/desktop/src/components/mqtt/MqttAdminConsole.vue index 9fd584ec6a..fff1ecefa5 100644 --- a/apps/desktop/src/components/mqtt/MqttAdminConsole.vue +++ b/apps/desktop/src/components/mqtt/MqttAdminConsole.vue @@ -9,7 +9,7 @@ import TopicTreeNode from "./TopicTreeNode.vue"; import MqttPublishPanel from "./MqttPublishDialog.vue"; import { decodePayload, PAYLOAD_ENCODINGS, PAYLOAD_ENCODING_LABELS, type PayloadEncoding } from "@/lib/mqtt/mqttPayloadCodec"; import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage"; -import { ChevronDown, ChevronUp } from "@lucide/vue"; +import { ChevronDown, ChevronUp, Pause, Play } from "@lucide/vue"; interface Props { connectionId: string; @@ -27,6 +27,7 @@ const selectedTopic = ref(props.initialTopic ?? ""); const loading = ref(true); const error = ref(null); const pollingTimer = ref | null>(null); +const messagesPaused = ref(false); const displayEncoding = ref("plaintext"); const topicSearch = ref(""); const showSubscriptionDialog = ref(false); @@ -218,8 +219,10 @@ async function handleClearMessages() { function startPolling() { stopPolling(); pollingTimer.value = setInterval(async () => { + if (messagesPaused.value) return; try { - messages.value = (await mqttGetMessages(props.connectionId, selectedTopic.value || undefined, 50)) as MqttMessage[]; + const nextMessages = (await mqttGetMessages(props.connectionId, selectedTopic.value || undefined, 50)) as MqttMessage[]; + if (!messagesPaused.value) messages.value = nextMessages; } catch { /* ignore polling errors */ } @@ -233,6 +236,10 @@ function stopPolling() { } } +function toggleMessagesPaused() { + messagesPaused.value = !messagesPaused.value; +} + function formatMessagePayload(msg: MqttMessage): string { if (displayEncoding.value === "plaintext" && msg.payloadText != null) return msg.payloadText; return decodePayload(msg.payloadBase64, displayEncoding.value); @@ -326,6 +333,11 @@ onUnmounted(stopPolling); +