forked from Mirrors/gomuks
web/roomlist: jump to first unread when clicking space unread counter
Fixes #577
This commit is contained in:
parent
c44ab253f8
commit
c9807df660
4 changed files with 51 additions and 13 deletions
|
@ -27,6 +27,7 @@ export interface FakeSpaceProps {
|
|||
space: Space | null
|
||||
setSpace: (space: RoomListFilter | null) => void
|
||||
isActive: boolean
|
||||
onClickUnread?: (evt: React.MouseEvent<HTMLDivElement> | null, space: Space | null) => void
|
||||
}
|
||||
|
||||
const getFakeSpaceIcon = (space: RoomListFilter | null): JSX.Element | null => {
|
||||
|
@ -44,10 +45,11 @@ const getFakeSpaceIcon = (space: RoomListFilter | null): JSX.Element | null => {
|
|||
}
|
||||
}
|
||||
|
||||
const FakeSpace = ({ space, setSpace, isActive }: FakeSpaceProps) => {
|
||||
const FakeSpace = ({ space, setSpace, isActive, onClickUnread }: FakeSpaceProps) => {
|
||||
const unreads = useEventAsState(space?.counts)
|
||||
const onClickUnreadWrapped = onClickUnread ? () => onClickUnread(null, space) : undefined
|
||||
return <div className={`space-entry ${isActive ? "active" : ""}`} onClick={() => setSpace(space)}>
|
||||
<UnreadCount counts={unreads} space={true} />
|
||||
<UnreadCount counts={unreads} space={true} onClick={onClickUnreadWrapped} />
|
||||
{getFakeSpaceIcon(space)}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import React, { use, useCallback, useRef, useState } from "react"
|
||||
import { RoomListFilter } from "@/api/statestore/space.ts"
|
||||
import { RoomListFilter, Space as SpaceStore, SpaceUnreadCounts } from "@/api/statestore/space.ts"
|
||||
import type { RoomID } from "@/api/types"
|
||||
import { useEventAsState } from "@/util/eventdispatcher.ts"
|
||||
import reverseMap from "@/util/reversemap.ts"
|
||||
|
@ -54,6 +54,38 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
|||
const store = client.store.getSpaceStore(evt.currentTarget.getAttribute("data-target-space")!)
|
||||
setSpace(store)
|
||||
}, [setSpace, client])
|
||||
const onClickSpaceUnread = useCallback((
|
||||
evt: React.MouseEvent<HTMLDivElement> | null, space?: SpaceStore | null,
|
||||
) => {
|
||||
if (evt) {
|
||||
const targetSpace = evt.currentTarget.closest("div.space-entry")?.getAttribute("data-target-space")
|
||||
if (!targetSpace) {
|
||||
return
|
||||
}
|
||||
space = client.store.getSpaceStore(targetSpace)
|
||||
}
|
||||
if (!space) {
|
||||
return
|
||||
}
|
||||
const counts = space.counts.current
|
||||
let wantedField: keyof SpaceUnreadCounts
|
||||
if (counts.unread_highlights > 0) {
|
||||
wantedField = "unread_highlights"
|
||||
} else if (counts.unread_notifications > 0) {
|
||||
wantedField = "unread_notifications"
|
||||
} else if (counts.unread_messages > 0) {
|
||||
wantedField = "unread_messages"
|
||||
} else {
|
||||
return
|
||||
}
|
||||
for (let i = client.store.roomList.current.length - 1; i >= 0; i--) {
|
||||
const entry = client.store.roomList.current[i]
|
||||
if (entry[wantedField] > 0 && space.include(entry)) {
|
||||
mainScreen.setActiveRoom(entry.room_id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}, [mainScreen, client])
|
||||
const clearQuery = () => {
|
||||
client.store.currentRoomListQuery = ""
|
||||
directSetQuery("")
|
||||
|
@ -97,6 +129,7 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
|||
key={pseudoSpace.id}
|
||||
space={pseudoSpace}
|
||||
setSpace={setSpace}
|
||||
onClickUnread={onClickSpaceUnread}
|
||||
isActive={space?.id === pseudoSpace.id}
|
||||
/>)}
|
||||
{spaces.map(roomID => <Space
|
||||
|
@ -105,6 +138,7 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
|||
client={client}
|
||||
onClick={onClickSpace}
|
||||
isActive={space?.id === roomID}
|
||||
onClickUnread={onClickSpaceUnread}
|
||||
/>)}
|
||||
</div>
|
||||
<div className="room-list">
|
||||
|
|
|
@ -25,17 +25,18 @@ export interface SpaceProps {
|
|||
roomID: RoomID
|
||||
client: Client
|
||||
onClick: (evt: React.MouseEvent<HTMLDivElement>) => void
|
||||
onClickUnread: (evt: React.MouseEvent<HTMLDivElement>) => void
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
const Space = ({ roomID, client, onClick, isActive }: SpaceProps) => {
|
||||
const Space = ({ roomID, client, onClick, isActive, onClickUnread }: SpaceProps) => {
|
||||
const unreads = useEventAsState(client.store.spaceEdges.get(roomID)?.counts)
|
||||
const room = useEventAsState(client.store.rooms.get(roomID)?.meta)
|
||||
if (!room) {
|
||||
return
|
||||
}
|
||||
return <div className={`space-entry ${isActive ? "active" : ""}`} onClick={onClick} data-target-space={roomID}>
|
||||
<UnreadCount counts={unreads} space={true} />
|
||||
<UnreadCount counts={unreads} space={true} onClick={onClickUnread} />
|
||||
<img src={getRoomAvatarURL(room)} alt={room.name} title={room.name} className="avatar" />
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -22,9 +22,10 @@ interface UnreadCounts extends SpaceUnreadCounts {
|
|||
interface UnreadCountProps {
|
||||
counts: UnreadCounts | null
|
||||
space?: true
|
||||
onClick?: (evt: React.MouseEvent<HTMLDivElement>) => void
|
||||
}
|
||||
|
||||
const UnreadCount = ({ counts, space }: UnreadCountProps) => {
|
||||
const UnreadCount = ({ counts, space, onClick }: UnreadCountProps) => {
|
||||
if (!counts) {
|
||||
return null
|
||||
}
|
||||
|
@ -46,15 +47,15 @@ const UnreadCount = ({ counts, space }: UnreadCountProps) => {
|
|||
if (countIsBig) {
|
||||
classNames.push("big")
|
||||
}
|
||||
let unreadCountTitle = unreadCount.toString()
|
||||
if (space) {
|
||||
classNames.push("space")
|
||||
unreadCountTitle = [
|
||||
counts.unread_highlights && `${counts.unread_highlights} highlights`,
|
||||
counts.unread_notifications && `${counts.unread_notifications} notifications`,
|
||||
counts.unread_messages && `${counts.unread_messages} messages`,
|
||||
].filter(x => !!x).join("\n")
|
||||
}
|
||||
const unreadCountTitle = [
|
||||
counts.unread_highlights && `${counts.unread_highlights} highlights`,
|
||||
counts.unread_notifications && `${counts.unread_notifications} notifications`,
|
||||
counts.unread_messages && `${counts.unread_messages} messages`,
|
||||
counts.marked_unread && "Marked unread",
|
||||
].filter(x => !!x).join("\n")
|
||||
if (counts.marked_unread) {
|
||||
classNames.push("marked-unread")
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ const UnreadCount = ({ counts, space }: UnreadCountProps) => {
|
|||
classNames.push("highlighted")
|
||||
}
|
||||
return <div className="room-entry-unreads">
|
||||
<div title={unreadCountTitle} className={classNames.join(" ")}>
|
||||
<div title={unreadCountTitle} className={classNames.join(" ")} onClick={onClick}>
|
||||
{unreadCountDisplay}
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue