mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Websocket for contact deletion, radio contact deletion flag fix, resent message now appends sender name
This commit is contained in:
@@ -215,6 +215,19 @@ class ContactRepository:
|
||||
)
|
||||
await db.conn.commit()
|
||||
|
||||
@staticmethod
|
||||
async def clear_on_radio_except(keep_keys: list[str]) -> None:
|
||||
"""Set on_radio=False for all contacts NOT in keep_keys."""
|
||||
if not keep_keys:
|
||||
await db.conn.execute("UPDATE contacts SET on_radio = 0 WHERE on_radio = 1")
|
||||
else:
|
||||
placeholders = ",".join("?" * len(keep_keys))
|
||||
await db.conn.execute(
|
||||
f"UPDATE contacts SET on_radio = 0 WHERE on_radio = 1 AND public_key NOT IN ({placeholders})",
|
||||
keep_keys,
|
||||
)
|
||||
await db.conn.commit()
|
||||
|
||||
@staticmethod
|
||||
async def delete(public_key: str) -> None:
|
||||
normalized = public_key.lower()
|
||||
|
||||
@@ -127,4 +127,9 @@ async def delete_channel(key: str) -> dict:
|
||||
"""
|
||||
logger.info("Deleting channel %s from database", key)
|
||||
await ChannelRepository.delete(key)
|
||||
|
||||
from app.websocket import broadcast_event
|
||||
|
||||
broadcast_event("channel_deleted", {"key": key})
|
||||
|
||||
return {"status": "ok"}
|
||||
|
||||
@@ -271,16 +271,21 @@ async def sync_contacts_from_radio() -> dict:
|
||||
contacts = result.payload
|
||||
count = 0
|
||||
|
||||
synced_keys: list[str] = []
|
||||
for public_key, contact_data in contacts.items():
|
||||
lower_key = public_key.lower()
|
||||
await ContactRepository.upsert(
|
||||
Contact.from_radio_dict(lower_key, contact_data, on_radio=True)
|
||||
)
|
||||
synced_keys.append(lower_key)
|
||||
claimed = await MessageRepository.claim_prefix_messages(lower_key)
|
||||
if claimed > 0:
|
||||
logger.info("Claimed %d prefix DM message(s) for contact %s", claimed, public_key[:12])
|
||||
count += 1
|
||||
|
||||
# Clear on_radio for contacts not found on the radio
|
||||
await ContactRepository.clear_on_radio_except(synced_keys)
|
||||
|
||||
logger.info("Synced %d contacts from radio", count)
|
||||
return {"synced": count}
|
||||
|
||||
@@ -368,6 +373,10 @@ async def delete_contact(public_key: str) -> dict:
|
||||
await ContactRepository.delete(contact.public_key)
|
||||
logger.info("Deleted contact %s", contact.public_key[:12])
|
||||
|
||||
from app.websocket import broadcast_event
|
||||
|
||||
broadcast_event("contact_deleted", {"public_key": contact.public_key})
|
||||
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
|
||||
@@ -399,6 +399,7 @@ async def resend_channel_message(
|
||||
sender_timestamp=now,
|
||||
received_at=now,
|
||||
outgoing=True,
|
||||
sender_name=radio_name or None,
|
||||
)
|
||||
if new_msg_id is None:
|
||||
# Timestamp-second collision (same text+channel within the same second).
|
||||
|
||||
@@ -287,6 +287,14 @@ export function App() {
|
||||
onContact: (contact: Contact) => {
|
||||
setContacts((prev) => mergeContactIntoList(prev, contact));
|
||||
},
|
||||
onContactDeleted: (publicKey: string) => {
|
||||
setContacts((prev) => prev.filter((c) => c.public_key !== publicKey));
|
||||
messageCache.remove(publicKey);
|
||||
},
|
||||
onChannelDeleted: (key: string) => {
|
||||
setChannels((prev) => prev.filter((c) => c.key !== key));
|
||||
messageCache.remove(key);
|
||||
},
|
||||
onRawPacket: (packet: RawPacket) => {
|
||||
setRawPackets((prev) => appendRawPacketUnique(prev, packet, MAX_RAW_PACKETS));
|
||||
},
|
||||
@@ -306,6 +314,7 @@ export function App() {
|
||||
setConfig,
|
||||
activeConversationRef,
|
||||
setContacts,
|
||||
setChannels,
|
||||
triggerReconcile,
|
||||
refreshUnreads,
|
||||
fetchAllContacts,
|
||||
|
||||
@@ -20,6 +20,8 @@ interface UseWebSocketOptions {
|
||||
onHealth?: (health: HealthStatus) => void;
|
||||
onMessage?: (message: Message) => void;
|
||||
onContact?: (contact: Contact) => void;
|
||||
onContactDeleted?: (publicKey: string) => void;
|
||||
onChannelDeleted?: (key: string) => void;
|
||||
onRawPacket?: (packet: RawPacket) => void;
|
||||
onMessageAcked?: (messageId: number, ackCount: number, paths?: MessagePath[]) => void;
|
||||
onError?: (error: ErrorEvent) => void;
|
||||
@@ -103,6 +105,12 @@ export function useWebSocket(options: UseWebSocketOptions) {
|
||||
case 'contact':
|
||||
handlers.onContact?.(msg.data as Contact);
|
||||
break;
|
||||
case 'contact_deleted':
|
||||
handlers.onContactDeleted?.((msg.data as { public_key: string }).public_key);
|
||||
break;
|
||||
case 'channel_deleted':
|
||||
handlers.onChannelDeleted?.((msg.data as { key: string }).key);
|
||||
break;
|
||||
case 'raw_packet':
|
||||
handlers.onRawPacket?.(msg.data as RawPacket);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user