diff --git a/meshchat.py b/meshchat.py index d6c07bc..30bfce7 100644 --- a/meshchat.py +++ b/meshchat.py @@ -224,12 +224,24 @@ class ReticulumMeshChat: self.message_router.set_outbound_propagation_node(bytes.fromhex(destination_hash)) except: # failed to set propagation node, clear it to ensure we don't use an old one by mistake - self.message_router.outbound_propagation_node = None + self.remove_active_propagation_node() pass # stop using propagation node else: - self.message_router.outbound_propagation_node = None + self.remove_active_propagation_node() + + # stops the in progress propagation node sync + def stop_propagation_node_sync(self): + self.message_router.cancel_propagation_node_requests() + + # stops and removes the active propagation node + def remove_active_propagation_node(self): + # fixme: it's possible for internal transfer state to get stuck if we change propagation node during a sync + # this still happens even if we cancel the propagation node requests + # for now, the user can just manually cancel syncing in the ui if they think it's stuck... + self.stop_propagation_node_sync() + self.message_router.outbound_propagation_node = None # handle receiving a new audio call def on_incoming_audio_call(self, audio_call: AudioCall): @@ -890,6 +902,16 @@ class ReticulumMeshChat: "message": "Sync is starting", }) + # stop syncing propagation node + @routes.get("/api/v1/lxmf/propagation-node/stop-sync") + async def index(request): + + self.stop_propagation_node_sync() + + return web.json_response({ + "message": "Sync is stopping", + }) + # serve propagation nodes @routes.get("/api/v1/lxmf/propagation-nodes") async def index(request): diff --git a/src/frontend/components/App.vue b/src/frontend/components/App.vue index 2176805..04f9616 100644 --- a/src/frontend/components/App.vue +++ b/src/frontend/components/App.vue @@ -398,8 +398,11 @@ export default { }, async syncPropagationNode() { - // do nothing if already syncing + // ask to stop syncing if already syncing if(this.isSyncingPropagationNode){ + if(confirm("Are you sure you want to stop syncing?")){ + await this.stopSyncingPropagationNode(); + } return; } @@ -429,7 +432,7 @@ export default { // show result const status = this.propagationNodeStatus?.state; const messagesReceived = this.propagationNodeStatus?.messages_received ?? 0; - if(status === "complete"){ + if(status === "complete" || status === "idle"){ DialogUtils.alert(`Sync complete. ${messagesReceived} messages received.`); } else { DialogUtils.alert(`Sync error: ${status}`); @@ -437,6 +440,19 @@ export default { }, 500); + }, + async stopSyncingPropagationNode() { + + // stop sync + try { + await axios.get("/api/v1/lxmf/propagation-node/stop-sync"); + } catch(e) { + // do nothing on error + } + + // update propagation status + await this.updatePropagationNodeStatus(); + }, async updatePropagationNodeStatus() { try {