forked from Mirrors/gomuks
web/roomlist: add pseudo-space for space orphans
This commit is contained in:
parent
6b01dec307
commit
f4a778ecbb
3 changed files with 43 additions and 12 deletions
|
@ -39,7 +39,7 @@ import {
|
|||
} from "../types"
|
||||
import { InvitedRoomStore } from "./invitedroom.ts"
|
||||
import { RoomStateStore } from "./room.ts"
|
||||
import { RoomListFilter, SpaceEdgeStore } from "./space.ts"
|
||||
import { RoomListFilter, SpaceEdgeStore, SpaceOrphansSpace } from "./space.ts"
|
||||
|
||||
export interface RoomListEntry {
|
||||
room_id: RoomID
|
||||
|
@ -75,6 +75,7 @@ export class StateStore {
|
|||
readonly roomList = new NonNullCachedEventDispatcher<RoomListEntry[]>([])
|
||||
readonly topLevelSpaces = new NonNullCachedEventDispatcher<RoomID[]>([])
|
||||
readonly spaceEdges: Map<RoomID, SpaceEdgeStore> = new Map()
|
||||
readonly spaceOrphans = new SpaceOrphansSpace(this)
|
||||
currentRoomListQuery: string = ""
|
||||
currentRoomListFilter: RoomListFilter | null = null
|
||||
readonly accountData: Map<string, UnknownEventContent> = new Map()
|
||||
|
@ -277,11 +278,18 @@ export class StateStore {
|
|||
if (updatedRoomList) {
|
||||
this.roomList.emit(updatedRoomList)
|
||||
}
|
||||
if (sync.space_edges) {
|
||||
// Ensure all space stores exist first
|
||||
for (const spaceID of Object.keys(sync.space_edges)) {
|
||||
this.getSpaceStore(spaceID, true)
|
||||
}
|
||||
for (const [spaceID, children] of Object.entries(sync.space_edges ?? {})) {
|
||||
this.getSpaceStore(spaceID, true).children = children
|
||||
}
|
||||
}
|
||||
if (sync.top_level_spaces) {
|
||||
this.topLevelSpaces.emit(sync.top_level_spaces)
|
||||
this.spaceOrphans.children = sync.top_level_spaces.map(child_id => ({ child_id }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ export class SpaceEdgeStore implements RoomListFilter {
|
|||
constructor(public id: RoomID, private parent: StateStore) {
|
||||
}
|
||||
|
||||
addParent(parent: SpaceEdgeStore) {
|
||||
#addParent(parent: SpaceEdgeStore) {
|
||||
this.#parentSpaces.add(parent)
|
||||
}
|
||||
|
||||
removeParent(parent: SpaceEdgeStore) {
|
||||
#removeParent(parent: SpaceEdgeStore) {
|
||||
this.#parentSpaces.delete(parent)
|
||||
}
|
||||
|
||||
|
@ -95,28 +95,42 @@ export class SpaceEdgeStore implements RoomListFilter {
|
|||
const spaceStore = this.parent.getSpaceStore(child.child_id)
|
||||
if (spaceStore) {
|
||||
newChildSpaces.add(spaceStore)
|
||||
spaceStore.addParent(this)
|
||||
spaceStore.#addParent(this)
|
||||
} else {
|
||||
newChildRooms.add(child.child_id)
|
||||
}
|
||||
}
|
||||
for (const space of this.#childSpaces) {
|
||||
if (!newChildSpaces.has(space)) {
|
||||
space.removeParent(this)
|
||||
space.#removeParent(this)
|
||||
}
|
||||
}
|
||||
const addedRooms = newChildRooms.difference(this.#childRooms)
|
||||
const removedRooms = this.#childRooms.difference(newChildRooms)
|
||||
const didAddChildren = newChildSpaces.difference(this.#childSpaces).size > 0
|
||||
const recalculateFlattened = removedRooms.size > 0 || didAddChildren
|
||||
this.#children = newChildren
|
||||
this.#childRooms = newChildRooms
|
||||
this.#childSpaces = newChildSpaces
|
||||
if (this.#childSpaces.size > 0) {
|
||||
this.#updateFlattened(removedRooms.size > 0, addedRooms)
|
||||
this.#updateFlattened(recalculateFlattened, addedRooms)
|
||||
} else {
|
||||
this.#flattenedRooms = newChildRooms
|
||||
}
|
||||
if (this.#parentSpaces.size > 0) {
|
||||
this.#notifyParentsOfChange(removedRooms.size > 0, addedRooms, new WeakSet())
|
||||
this.#notifyParentsOfChange(recalculateFlattened, addedRooms, new WeakSet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SpaceOrphansSpace extends SpaceEdgeStore {
|
||||
static id = "fi.mau.gomuks.space_orphans"
|
||||
|
||||
constructor(parent: StateStore) {
|
||||
super(SpaceOrphansSpace.id, parent)
|
||||
}
|
||||
|
||||
include(room: RoomListEntry): boolean {
|
||||
return !super.include(room) && !room.dm_user_id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,12 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
|||
}
|
||||
|
||||
const roomListFilter = client.store.roomListFilterFunc
|
||||
const pseudoSpaces = [
|
||||
null,
|
||||
DirectChatSpace,
|
||||
UnreadsSpace,
|
||||
client.store.spaceOrphans,
|
||||
]
|
||||
return <div className="room-list-wrapper">
|
||||
<div className="room-search-wrapper">
|
||||
<input
|
||||
|
@ -92,9 +98,12 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
|||
</button>
|
||||
</div>
|
||||
<div className="space-bar">
|
||||
<FakeSpace space={null} setSpace={setSpace} isActive={space === null} />
|
||||
<FakeSpace space={DirectChatSpace} setSpace={setSpace} isActive={space?.id === DirectChatSpace.id} />
|
||||
<FakeSpace space={UnreadsSpace} setSpace={setSpace} isActive={space?.id === UnreadsSpace.id} />
|
||||
{pseudoSpaces.map(pseudoSpace => <FakeSpace
|
||||
key={pseudoSpace?.id ?? "null"}
|
||||
space={pseudoSpace}
|
||||
setSpace={setSpace}
|
||||
isActive={space?.id === pseudoSpace?.id}
|
||||
/>)}
|
||||
{spaces.map(roomID => <Space
|
||||
roomID={roomID}
|
||||
client={client}
|
||||
|
|
Loading…
Add table
Reference in a new issue