A room unmuted on the account stops being drawn as muted: the buffer merge takes the flags the daemon leaves out as cleared; an unmute the server did not take is reported
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
+1
-1
Submodule nobilis updated: 5444b7a4ef...d1bbcaf724
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { ChatStore } from './store'
|
||||
|
||||
/** The store, with a conversation already in its list, and the daemon's update for it applied. */
|
||||
function after(update: Record<string, unknown>, before: Record<string, unknown> = {}): Record<string, unknown> {
|
||||
const store = new ChatStore() as unknown as {
|
||||
state: { buffers: unknown[] }
|
||||
handleBufferListChange: (data: unknown) => void
|
||||
}
|
||||
const base = { id: 'm|!r', accountId: 'm', kind: 'channel', name: '!r', lastActivityTs: 0, unread: 0, highlight: false, mentions: 0 }
|
||||
store.state = { ...store.state, buffers: [{ ...base, ...before }] }
|
||||
// What the daemon sends carries no unread tally: that is this window's own.
|
||||
store.handleBufferListChange({ id: base.id, accountId: base.accountId, kind: base.kind, name: base.name, lastActivityTs: 0, ...update })
|
||||
return store.state.buffers[0] as Record<string, unknown>
|
||||
}
|
||||
|
||||
describe('an update to a conversation the window already has', () => {
|
||||
it('takes a mute off when the daemon leaves it out', () => {
|
||||
// The daemon omits a flag that is off, so absent has to mean cleared: a
|
||||
// room unmuted on the account stayed drawn as muted, with an Unmute that
|
||||
// had nothing left to do.
|
||||
expect(after({}, { serverMuted: true }).serverMuted).toBe(false)
|
||||
expect(after({ serverMuted: true }, {}).serverMuted).toBe(true)
|
||||
})
|
||||
|
||||
it('clears the other flags the same way, and keeps the unread count it holds', () => {
|
||||
const b = after({}, { favourite: true, lowPriority: true, readOnly: 'No permission', forum: true, unread: 4, mentions: 2, highlight: true })
|
||||
expect([b.favourite, b.lowPriority, b.readOnly, b.forum]).toEqual([false, false, undefined, false])
|
||||
expect([b.unread, b.mentions, b.highlight]).toEqual([4, 2, true])
|
||||
})
|
||||
})
|
||||
@@ -3731,8 +3731,28 @@ export class ChatStore {
|
||||
// leaves an optional field out when it is not set, so a plain spread
|
||||
// kept the last value it ever had - a room that reconnected stayed
|
||||
// marked as interrupted, and the banner over it stayed up.
|
||||
//
|
||||
// The same for every flag the daemon leaves out when it is off - muted on
|
||||
// the account, favourite, low priority, read-only, a forum. A merge that
|
||||
// kept the last value it ever had left a room unmuted on the server still
|
||||
// drawn as muted here, with an Unmute that had nothing left to do.
|
||||
this.set({
|
||||
buffers: buffers.map((b) => (b.id === data.id ? { ...b, ...data, link: data.link, syncing: data.syncing, topic: data.topic } : b))
|
||||
buffers: buffers.map((b) =>
|
||||
b.id === data.id
|
||||
? {
|
||||
...b,
|
||||
...data,
|
||||
link: data.link,
|
||||
syncing: data.syncing,
|
||||
topic: data.topic,
|
||||
serverMuted: data.serverMuted ?? false,
|
||||
favourite: data.favourite ?? false,
|
||||
lowPriority: data.lowPriority ?? false,
|
||||
readOnly: data.readOnly,
|
||||
forum: data.forum ?? false
|
||||
}
|
||||
: b
|
||||
)
|
||||
})
|
||||
this.followPeekJoin(data)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user