The number beside a conversation is what is addressed to you: mentions in a channel, each unread message in a direct message - the bold name says there is activity, a count of it does not
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
MENTIONS_GROUP_ID,
|
||||
PINNED_GROUP_ID,
|
||||
pinnedGroup,
|
||||
waitingCount,
|
||||
visibleGroups,
|
||||
type RailGroup
|
||||
} from '../lib/groups'
|
||||
@@ -593,12 +594,12 @@ export function BufferList(): JSX.Element {
|
||||
// What is waiting in what is folded away, which is
|
||||
// the thing worth knowing about a closed heading;
|
||||
// how many channels it has is the fallback.
|
||||
const waiting = section.buffers.filter((b) => b.unread > 0 && (!isEffectivelyMuted(b) || b.highlight))
|
||||
const unread = waiting.reduce((n, b) => n + b.unread, 0)
|
||||
const waiting = section.buffers.filter((b) => waitingCount(b) > 0 && (!isEffectivelyMuted(b) || b.highlight))
|
||||
const unread = waiting.reduce((n, b) => n + waitingCount(b), 0)
|
||||
return unread > 0 ? (
|
||||
<span
|
||||
className={classes('unread-badge category-count', waiting.some((b) => b.highlight) && 'highlight')}
|
||||
title={`${unread} unread in ${waiting.length} ${waiting.length === 1 ? 'channel' : 'channels'}`}
|
||||
title={`${unread} ${unread === 1 ? 'mention' : 'mentions'} in ${waiting.length} ${waiting.length === 1 ? 'channel' : 'channels'}`}
|
||||
>
|
||||
{unread > 99 ? '99+' : unread}
|
||||
</span>
|
||||
@@ -1062,9 +1063,9 @@ function BufferRow({
|
||||
arrive is worse than either on its own. */}
|
||||
{live ? (
|
||||
<span className="live-badge">LIVE</span>
|
||||
) : buffer.unread > 0 && (!muted || buffer.highlight) ? (
|
||||
) : waitingCount(buffer) > 0 && (!muted || buffer.highlight) ? (
|
||||
<span className={classes('unread-badge', buffer.highlight && 'highlight')}>
|
||||
{buffer.unread > 99 ? '99+' : buffer.unread}
|
||||
{waitingCount(buffer) > 99 ? '99+' : waitingCount(buffer)}
|
||||
</span>
|
||||
) : (
|
||||
// Left unread on purpose, with nothing new in it. A dot rather than
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom'
|
||||
import { Avatar } from './Avatar'
|
||||
import { Icon } from './Icon'
|
||||
import { useChat, useStore } from '../state/hooks'
|
||||
import { waitingCount } from '../lib/groups'
|
||||
import { rankBuffers, whereText } from '../lib/switcher'
|
||||
import { bufferKindGlyph, classes } from '../lib/util'
|
||||
|
||||
@@ -122,9 +123,9 @@ export function QuickSwitcher(): JSX.Element | null {
|
||||
</span>
|
||||
<span className="switcher-title ellipsis">{hit.title}</span>
|
||||
<span className="switcher-where muted small ellipsis">{hit.where}</span>
|
||||
{b.unread > 0 && (
|
||||
{waitingCount(b) > 0 && (
|
||||
<span className={classes('unread-badge', b.highlight && 'highlight')}>
|
||||
{b.unread > 99 ? '99+' : b.unread}
|
||||
{waitingCount(b) > 99 ? '99+' : waitingCount(b)}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
removeFromFolders,
|
||||
reorder,
|
||||
reorderFolder,
|
||||
waitingCount,
|
||||
type RailFolder,
|
||||
type RailGroup
|
||||
} from './groups'
|
||||
@@ -124,3 +125,15 @@ describe('compareInBand', () => {
|
||||
expect([dm('old', 1), dm('new', 9)].sort(compareInBand).map((c) => c.name)).toEqual(['new', 'old'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('waitingCount', () => {
|
||||
const buffer = (over: Partial<BufferEntry>): BufferEntry =>
|
||||
({ id: 'a|#x', kind: 'channel', unread: 97, mentions: 0, highlight: false, ...over }) as BufferEntry
|
||||
it('is the mentions in a channel, not everything said in it', () => {
|
||||
expect(waitingCount(buffer({}))).toBe(0)
|
||||
expect(waitingCount(buffer({ mentions: 2, highlight: true }))).toBe(2)
|
||||
})
|
||||
it('is each unread message in a direct message, which are all for you', () => {
|
||||
expect(waitingCount(buffer({ kind: 'dm', unread: 4 }))).toBe(4)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -95,6 +95,18 @@ export function isDirectMessage(buffer: BufferEntry): boolean {
|
||||
return buffer.kind === 'dm'
|
||||
}
|
||||
|
||||
/**
|
||||
* The number to show beside a conversation: what is addressed to you.
|
||||
*
|
||||
* Mentions, not everything said - a bold name already says there is activity,
|
||||
* and a count of it is the noise the rail and tray were rid of. A direct
|
||||
* message is the exception that is the same rule: every line in one is
|
||||
* addressed to you, so it is counted by each unread message.
|
||||
*/
|
||||
export function waitingCount(buffer: BufferEntry): number {
|
||||
return isDirectMessage(buffer) ? buffer.unread : buffer.mentions
|
||||
}
|
||||
|
||||
export function pinnedGroup(): RailGroup {
|
||||
return {
|
||||
id: PINNED_GROUP_ID,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { countsTowardRail, isDirectMessage } from './groups'
|
||||
import { countsTowardRail, isDirectMessage, waitingCount } from './groups'
|
||||
import type { BufferEntry } from '../state/store'
|
||||
|
||||
/** What the tray is told is waiting. */
|
||||
@@ -32,7 +32,7 @@ export function trayCount(buffers: BufferEntry[], muted: string[], hidden: strin
|
||||
let latest: BufferEntry | null = null
|
||||
for (const b of buffers) {
|
||||
if (!countsTowardRail(b, muted, hidden, mutedGroups)) continue
|
||||
const waiting = isDirectMessage(b) ? b.unread : b.mentions
|
||||
const waiting = waitingCount(b)
|
||||
if (waiting <= 0) continue
|
||||
if (isDirectMessage(b)) dms += waiting
|
||||
else mentions += waiting
|
||||
|
||||
Reference in New Issue
Block a user