fix: key messages by networkId:room to prevent collision across networks
Two networks sharing a room name (e.g. "general") were clobbering each
other's message lists. Now keyed by `${networkId}:${room}` throughout
the web store, MessagePane, and Sidebar DM detection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,8 +16,9 @@ export function MessagePane() {
|
|||||||
const { messages, historyCutoff, activeRoom, activeNetworkId, localPeer, connectedPeers, knownPeers, send } = useWaste()
|
const { messages, historyCutoff, activeRoom, activeNetworkId, localPeer, connectedPeers, knownPeers, send } = useWaste()
|
||||||
const [draft, setDraft] = useState('')
|
const [draft, setDraft] = useState('')
|
||||||
const bottomRef = useRef<HTMLDivElement>(null)
|
const bottomRef = useRef<HTMLDivElement>(null)
|
||||||
const roomMessages = messages[activeRoom] ?? []
|
const msgKey = activeNetworkId ? `${activeNetworkId}:${activeRoom}` : activeRoom
|
||||||
const cutoff = historyCutoff[activeRoom] ?? 0
|
const roomMessages = messages[msgKey] ?? []
|
||||||
|
const cutoff = historyCutoff[msgKey] ?? 0
|
||||||
|
|
||||||
// Find the index of the first live message (ts > cutoff).
|
// Find the index of the first live message (ts > cutoff).
|
||||||
// The divider appears just before this index, or at the top if all are history.
|
// The divider appears just before this index, or at the top if all are history.
|
||||||
|
|||||||
@@ -42,9 +42,15 @@ export function Sidebar() {
|
|||||||
|
|
||||||
const netCustomRooms = activeNetworkId ? (customRooms[activeNetworkId] ?? []) : []
|
const netCustomRooms = activeNetworkId ? (customRooms[activeNetworkId] ?? []) : []
|
||||||
const rooms = ['general', ...netCustomRooms]
|
const rooms = ['general', ...netCustomRooms]
|
||||||
Object.keys(messages).forEach(r => {
|
if (activeNetworkId) {
|
||||||
if (r.startsWith('dm:') && !rooms.includes(r)) rooms.push(r)
|
const prefix = `${activeNetworkId}:dm:`
|
||||||
})
|
Object.keys(messages).forEach(k => {
|
||||||
|
if (k.startsWith(prefix)) {
|
||||||
|
const r = k.slice(activeNetworkId.length + 1)
|
||||||
|
if (!rooms.includes(r)) rooms.push(r)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function submitNewRoom(e: React.FormEvent) {
|
function submitNewRoom(e: React.FormEvent) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|||||||
@@ -283,14 +283,14 @@ export const useWaste = create<WasteState>((set, get) => ({
|
|||||||
case 'message_received': {
|
case 'message_received': {
|
||||||
if (msg.message) {
|
if (msg.message) {
|
||||||
const m = msg.message
|
const m = msg.message
|
||||||
const room = m.room
|
const key = `${msg.network_id}:${m.room}`
|
||||||
const fromId = String(m.from)
|
const fromId = String(m.from)
|
||||||
set(s => {
|
set(s => {
|
||||||
const existing = s.messages[room] ?? []
|
const existing = s.messages[key] ?? []
|
||||||
if (m.mid && existing.some(e => e.mid === m.mid)) return s
|
if (m.mid && existing.some(e => e.mid === m.mid)) return s
|
||||||
const prev = s.peerStatus[fromId] ?? {}
|
const prev = s.peerStatus[fromId] ?? {}
|
||||||
return {
|
return {
|
||||||
messages: { ...s.messages, [room]: [...existing, m] },
|
messages: { ...s.messages, [key]: [...existing, m] },
|
||||||
peerStatus: { ...s.peerStatus, [fromId]: { ...prev, lastSeen: m.ts } },
|
peerStatus: { ...s.peerStatus, [fromId]: { ...prev, lastSeen: m.ts } },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -378,16 +378,17 @@ export const useWaste = create<WasteState>((set, get) => ({
|
|||||||
const room = msg.room
|
const room = msg.room
|
||||||
const incoming = (msg.messages ?? []) as ChatMessage[]
|
const incoming = (msg.messages ?? []) as ChatMessage[]
|
||||||
if (!room || incoming.length === 0) break
|
if (!room || incoming.length === 0) break
|
||||||
|
const key = `${msg.network_id}:${room}`
|
||||||
set(s => {
|
set(s => {
|
||||||
const existing = s.messages[room] ?? []
|
const existing = s.messages[key] ?? []
|
||||||
const existingMids = new Set(existing.map(m => m.mid).filter(Boolean))
|
const existingMids = new Set(existing.map(m => m.mid).filter(Boolean))
|
||||||
const fresh = incoming.filter(m => !m.mid || !existingMids.has(m.mid))
|
const fresh = incoming.filter(m => !m.mid || !existingMids.has(m.mid))
|
||||||
if (fresh.length === 0) return s
|
if (fresh.length === 0) return s
|
||||||
const merged = [...fresh, ...existing].sort((a, b) => a.ts - b.ts)
|
const merged = [...fresh, ...existing].sort((a, b) => a.ts - b.ts)
|
||||||
const cutoff = fresh[fresh.length - 1]?.ts ?? 0
|
const cutoff = fresh[fresh.length - 1]?.ts ?? 0
|
||||||
return {
|
return {
|
||||||
messages: { ...s.messages, [room]: merged },
|
messages: { ...s.messages, [key]: merged },
|
||||||
historyCutoff: { ...s.historyCutoff, [room]: cutoff },
|
historyCutoff: { ...s.historyCutoff, [key]: cutoff },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user