mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-11 03:03:03 +02:00
Fix repeater comms coming back in different channel if a user sends and changes convos rapidly.
This commit is contained in:
@@ -127,7 +127,7 @@ export function App() {
|
|||||||
activeContactIsRepeater,
|
activeContactIsRepeater,
|
||||||
handleTelemetryRequest,
|
handleTelemetryRequest,
|
||||||
handleRepeaterCommand,
|
handleRepeaterCommand,
|
||||||
} = useRepeaterMode(activeConversation, contacts, setMessages);
|
} = useRepeaterMode(activeConversation, contacts, setMessages, activeConversationRef);
|
||||||
|
|
||||||
// WebSocket handlers - memoized to prevent reconnection loops
|
// WebSocket handlers - memoized to prevent reconnection loops
|
||||||
const wsHandlers = useMemo(
|
const wsHandlers = useMemo(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useMemo, useEffect } from 'react';
|
import { useState, useCallback, useMemo, useEffect, type RefObject } from 'react';
|
||||||
import { api } from '../api';
|
import { api } from '../api';
|
||||||
import type {
|
import type {
|
||||||
Contact,
|
Contact,
|
||||||
@@ -118,7 +118,8 @@ export interface UseRepeaterModeResult {
|
|||||||
export function useRepeaterMode(
|
export function useRepeaterMode(
|
||||||
activeConversation: Conversation | null,
|
activeConversation: Conversation | null,
|
||||||
contacts: Contact[],
|
contacts: Contact[],
|
||||||
setMessages: React.Dispatch<React.SetStateAction<Message[]>>
|
setMessages: React.Dispatch<React.SetStateAction<Message[]>>,
|
||||||
|
activeConversationRef: RefObject<Conversation | null>
|
||||||
): UseRepeaterModeResult {
|
): UseRepeaterModeResult {
|
||||||
const [repeaterLoggedIn, setRepeaterLoggedIn] = useState(false);
|
const [repeaterLoggedIn, setRepeaterLoggedIn] = useState(false);
|
||||||
const { handleAirtimeCommand, stopTracking } = useAirtimeTracking(setMessages);
|
const { handleAirtimeCommand, stopTracking } = useAirtimeTracking(setMessages);
|
||||||
@@ -142,26 +143,31 @@ export function useRepeaterMode(
|
|||||||
if (!activeConversation || activeConversation.type !== 'contact') return;
|
if (!activeConversation || activeConversation.type !== 'contact') return;
|
||||||
if (!activeContactIsRepeater) return;
|
if (!activeContactIsRepeater) return;
|
||||||
|
|
||||||
|
const conversationId = activeConversation.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const telemetry = await api.requestTelemetry(activeConversation.id, password);
|
const telemetry = await api.requestTelemetry(conversationId, password);
|
||||||
|
|
||||||
|
// User may have switched conversations during the await
|
||||||
|
if (activeConversationRef.current?.id !== conversationId) return;
|
||||||
|
|
||||||
// Create local messages to display the telemetry (not persisted to database)
|
// Create local messages to display the telemetry (not persisted to database)
|
||||||
const telemetryMessage = createLocalMessage(
|
const telemetryMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
formatTelemetry(telemetry),
|
formatTelemetry(telemetry),
|
||||||
false,
|
false,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
const neighborsMessage = createLocalMessage(
|
const neighborsMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
formatNeighbors(telemetry.neighbors),
|
formatNeighbors(telemetry.neighbors),
|
||||||
false,
|
false,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
const aclMessage = createLocalMessage(
|
const aclMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
formatAcl(telemetry.acl),
|
formatAcl(telemetry.acl),
|
||||||
false,
|
false,
|
||||||
2
|
2
|
||||||
@@ -173,8 +179,9 @@ export function useRepeaterMode(
|
|||||||
// Mark as logged in for CLI command mode
|
// Mark as logged in for CLI command mode
|
||||||
setRepeaterLoggedIn(true);
|
setRepeaterLoggedIn(true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (activeConversationRef.current?.id !== conversationId) return;
|
||||||
const errorMessage = createLocalMessage(
|
const errorMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
`Telemetry request failed: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
`Telemetry request failed: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
||||||
false,
|
false,
|
||||||
0
|
0
|
||||||
@@ -182,7 +189,7 @@ export function useRepeaterMode(
|
|||||||
setMessages((prev) => [...prev, errorMessage]);
|
setMessages((prev) => [...prev, errorMessage]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeConversation, activeContactIsRepeater, setMessages]
|
[activeConversation, activeContactIsRepeater, setMessages, activeConversationRef]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send CLI command to a repeater (after logged in)
|
// Send CLI command to a repeater (after logged in)
|
||||||
@@ -191,20 +198,25 @@ export function useRepeaterMode(
|
|||||||
if (!activeConversation || activeConversation.type !== 'contact') return;
|
if (!activeConversation || activeConversation.type !== 'contact') return;
|
||||||
if (!activeContactIsRepeater || !repeaterLoggedIn) return;
|
if (!activeContactIsRepeater || !repeaterLoggedIn) return;
|
||||||
|
|
||||||
|
const conversationId = activeConversation.id;
|
||||||
|
|
||||||
// Check for special airtime commands first (handled locally)
|
// Check for special airtime commands first (handled locally)
|
||||||
const handled = await handleAirtimeCommand(command, activeConversation.id);
|
const handled = await handleAirtimeCommand(command, conversationId);
|
||||||
if (handled) return;
|
if (handled) return;
|
||||||
|
|
||||||
// Show the command as an outgoing message
|
// Show the command as an outgoing message
|
||||||
const commandMessage = createLocalMessage(activeConversation.id, `> ${command}`, true, 0);
|
const commandMessage = createLocalMessage(conversationId, `> ${command}`, true, 0);
|
||||||
setMessages((prev) => [...prev, commandMessage]);
|
setMessages((prev) => [...prev, commandMessage]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await api.sendRepeaterCommand(activeConversation.id, command);
|
const response = await api.sendRepeaterCommand(conversationId, command);
|
||||||
|
|
||||||
|
// User may have switched conversations during the await
|
||||||
|
if (activeConversationRef.current?.id !== conversationId) return;
|
||||||
|
|
||||||
// Use the actual timestamp from the repeater if available
|
// Use the actual timestamp from the repeater if available
|
||||||
const responseMessage = createLocalMessage(
|
const responseMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
response.response,
|
response.response,
|
||||||
false,
|
false,
|
||||||
1
|
1
|
||||||
@@ -215,8 +227,9 @@ export function useRepeaterMode(
|
|||||||
|
|
||||||
setMessages((prev) => [...prev, responseMessage]);
|
setMessages((prev) => [...prev, responseMessage]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (activeConversationRef.current?.id !== conversationId) return;
|
||||||
const errorMessage = createLocalMessage(
|
const errorMessage = createLocalMessage(
|
||||||
activeConversation.id,
|
conversationId,
|
||||||
`Command failed: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
`Command failed: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
||||||
false,
|
false,
|
||||||
1
|
1
|
||||||
@@ -230,6 +243,7 @@ export function useRepeaterMode(
|
|||||||
repeaterLoggedIn,
|
repeaterLoggedIn,
|
||||||
setMessages,
|
setMessages,
|
||||||
handleAirtimeCommand,
|
handleAirtimeCommand,
|
||||||
|
activeConversationRef,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user