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"
|
} from "../types"
|
||||||
import { InvitedRoomStore } from "./invitedroom.ts"
|
import { InvitedRoomStore } from "./invitedroom.ts"
|
||||||
import { RoomStateStore } from "./room.ts"
|
import { RoomStateStore } from "./room.ts"
|
||||||
import { RoomListFilter, SpaceEdgeStore } from "./space.ts"
|
import { RoomListFilter, SpaceEdgeStore, SpaceOrphansSpace } from "./space.ts"
|
||||||
|
|
||||||
export interface RoomListEntry {
|
export interface RoomListEntry {
|
||||||
room_id: RoomID
|
room_id: RoomID
|
||||||
|
@ -75,6 +75,7 @@ export class StateStore {
|
||||||
readonly roomList = new NonNullCachedEventDispatcher<RoomListEntry[]>([])
|
readonly roomList = new NonNullCachedEventDispatcher<RoomListEntry[]>([])
|
||||||
readonly topLevelSpaces = new NonNullCachedEventDispatcher<RoomID[]>([])
|
readonly topLevelSpaces = new NonNullCachedEventDispatcher<RoomID[]>([])
|
||||||
readonly spaceEdges: Map<RoomID, SpaceEdgeStore> = new Map()
|
readonly spaceEdges: Map<RoomID, SpaceEdgeStore> = new Map()
|
||||||
|
readonly spaceOrphans = new SpaceOrphansSpace(this)
|
||||||
currentRoomListQuery: string = ""
|
currentRoomListQuery: string = ""
|
||||||
currentRoomListFilter: RoomListFilter | null = null
|
currentRoomListFilter: RoomListFilter | null = null
|
||||||
readonly accountData: Map<string, UnknownEventContent> = new Map()
|
readonly accountData: Map<string, UnknownEventContent> = new Map()
|
||||||
|
@ -277,11 +278,18 @@ export class StateStore {
|
||||||
if (updatedRoomList) {
|
if (updatedRoomList) {
|
||||||
this.roomList.emit(updatedRoomList)
|
this.roomList.emit(updatedRoomList)
|
||||||
}
|
}
|
||||||
for (const [spaceID, children] of Object.entries(sync.space_edges ?? {})) {
|
if (sync.space_edges) {
|
||||||
this.getSpaceStore(spaceID, true).children = children
|
// 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) {
|
if (sync.top_level_spaces) {
|
||||||
this.topLevelSpaces.emit(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) {
|
constructor(public id: RoomID, private parent: StateStore) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addParent(parent: SpaceEdgeStore) {
|
#addParent(parent: SpaceEdgeStore) {
|
||||||
this.#parentSpaces.add(parent)
|
this.#parentSpaces.add(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeParent(parent: SpaceEdgeStore) {
|
#removeParent(parent: SpaceEdgeStore) {
|
||||||
this.#parentSpaces.delete(parent)
|
this.#parentSpaces.delete(parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,28 +95,42 @@ export class SpaceEdgeStore implements RoomListFilter {
|
||||||
const spaceStore = this.parent.getSpaceStore(child.child_id)
|
const spaceStore = this.parent.getSpaceStore(child.child_id)
|
||||||
if (spaceStore) {
|
if (spaceStore) {
|
||||||
newChildSpaces.add(spaceStore)
|
newChildSpaces.add(spaceStore)
|
||||||
spaceStore.addParent(this)
|
spaceStore.#addParent(this)
|
||||||
} else {
|
} else {
|
||||||
newChildRooms.add(child.child_id)
|
newChildRooms.add(child.child_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const space of this.#childSpaces) {
|
for (const space of this.#childSpaces) {
|
||||||
if (!newChildSpaces.has(space)) {
|
if (!newChildSpaces.has(space)) {
|
||||||
space.removeParent(this)
|
space.#removeParent(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const addedRooms = newChildRooms.difference(this.#childRooms)
|
const addedRooms = newChildRooms.difference(this.#childRooms)
|
||||||
const removedRooms = this.#childRooms.difference(newChildRooms)
|
const removedRooms = this.#childRooms.difference(newChildRooms)
|
||||||
|
const didAddChildren = newChildSpaces.difference(this.#childSpaces).size > 0
|
||||||
|
const recalculateFlattened = removedRooms.size > 0 || didAddChildren
|
||||||
this.#children = newChildren
|
this.#children = newChildren
|
||||||
this.#childRooms = newChildRooms
|
this.#childRooms = newChildRooms
|
||||||
this.#childSpaces = newChildSpaces
|
this.#childSpaces = newChildSpaces
|
||||||
if (this.#childSpaces.size > 0) {
|
if (this.#childSpaces.size > 0) {
|
||||||
this.#updateFlattened(removedRooms.size > 0, addedRooms)
|
this.#updateFlattened(recalculateFlattened, addedRooms)
|
||||||
} else {
|
} else {
|
||||||
this.#flattenedRooms = newChildRooms
|
this.#flattenedRooms = newChildRooms
|
||||||
}
|
}
|
||||||
if (this.#parentSpaces.size > 0) {
|
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 roomListFilter = client.store.roomListFilterFunc
|
||||||
|
const pseudoSpaces = [
|
||||||
|
null,
|
||||||
|
DirectChatSpace,
|
||||||
|
UnreadsSpace,
|
||||||
|
client.store.spaceOrphans,
|
||||||
|
]
|
||||||
return <div className="room-list-wrapper">
|
return <div className="room-list-wrapper">
|
||||||
<div className="room-search-wrapper">
|
<div className="room-search-wrapper">
|
||||||
<input
|
<input
|
||||||
|
@ -92,9 +98,12 @@ const RoomList = ({ activeRoomID }: RoomListProps) => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-bar">
|
<div className="space-bar">
|
||||||
<FakeSpace space={null} setSpace={setSpace} isActive={space === null} />
|
{pseudoSpaces.map(pseudoSpace => <FakeSpace
|
||||||
<FakeSpace space={DirectChatSpace} setSpace={setSpace} isActive={space?.id === DirectChatSpace.id} />
|
key={pseudoSpace?.id ?? "null"}
|
||||||
<FakeSpace space={UnreadsSpace} setSpace={setSpace} isActive={space?.id === UnreadsSpace.id} />
|
space={pseudoSpace}
|
||||||
|
setSpace={setSpace}
|
||||||
|
isActive={space?.id === pseudoSpace?.id}
|
||||||
|
/>)}
|
||||||
{spaces.map(roomID => <Space
|
{spaces.map(roomID => <Space
|
||||||
roomID={roomID}
|
roomID={roomID}
|
||||||
client={client}
|
client={client}
|
||||||
|
|
Loading…
Add table
Reference in a new issue