create hero member events state to prevent frequent async loads
This commit is contained in:
parent
7243e8f10a
commit
ccc29ae166
27 changed files with 180 additions and 137 deletions
|
|
@ -84,9 +84,9 @@ export function RoomMentionAutocomplete({
|
|||
const mDirects = useAtomValue(mDirectAtom);
|
||||
const rooms = useAtomValue(allRoomsAtom);
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(rooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const allRooms = useMemo(
|
||||
() => Array.from(rooms).sort(factoryRoomIdByAtoZ(getRoomName)),
|
||||
|
|
|
|||
|
|
@ -379,8 +379,8 @@ export function EmojiBoard({
|
|||
addToRecentEmoji = true,
|
||||
}: EmojiBoardProps) {
|
||||
const ct = useClient();
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(imagePackRooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
|
||||
const emojiTab = tab === EmojiBoardTab.Emoji;
|
||||
const usage = emojiTab ? ImageUsage.Emoticon : ImageUsage.Sticker;
|
||||
|
|
|
|||
|
|
@ -230,7 +230,6 @@ type MutualRoomsData = {
|
|||
directs: string[];
|
||||
};
|
||||
|
||||
const EMPTY_LIST: string[] = [];
|
||||
export function MutualRoomsChip({ userId }: { userId: string }) {
|
||||
const ct = useClient();
|
||||
const mutualRoomsState = useMutualRooms(userId);
|
||||
|
|
@ -240,11 +239,9 @@ export function MutualRoomsChip({ userId }: { userId: string }) {
|
|||
const directs = useDirectRooms();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(
|
||||
mutualRoomsState.status === AsyncStatus.Success ? mutualRoomsState.data : EMPTY_LIST
|
||||
);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const [cords, setCords] = useState<RectCords>();
|
||||
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ export function AddExistingModal({ parentId, space, requestClose }: AddExistingM
|
|||
const roomIdToParents = useAtomValue(roomToParentsAtom);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(ct.rooms.join.read);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const [selected, setSelected] = useState<string[]>([]);
|
||||
|
||||
|
|
|
|||
|
|
@ -148,9 +148,9 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) {
|
|||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||
const screenSize = useScreenSizeContext();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(spaceId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const avatarMxc = getRoomAvatar(spaceId);
|
||||
const avatarUrl = avatarMxc
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ export function LobbyHero() {
|
|||
const useAuthentication = useMediaAuthentication();
|
||||
const spaceId = useSpace();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(spaceId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
const topic = useRoomTopic(spaceId);
|
||||
|
||||
const avatarMxc = getRoomAvatar(spaceId);
|
||||
|
|
|
|||
|
|
@ -191,9 +191,10 @@ type SpaceProfileProps = {
|
|||
function SpaceProfile({ roomId, suggested, closed, categoryId, handleClose }: SpaceProfileProps) {
|
||||
const ct = useClient();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const name = getRoomName(roomId) ?? 'Unknown';
|
||||
const avatar = getRoomAvatar(roomId);
|
||||
|
|
|
|||
|
|
@ -191,11 +191,10 @@ export function MessageSearch({
|
|||
}, [lastVItemIndex, lastGroupIndex, fetchNextPage, isFetchingNextPage, hasNextPage]);
|
||||
|
||||
const roomToTimeline = useObservableValue(ct.roomToTimeline);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(
|
||||
searchPathSearchParams.global === 'true' ? allRooms : rooms
|
||||
);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
return (
|
||||
<Box direction="Column" gap="700">
|
||||
|
|
|
|||
|
|
@ -77,9 +77,10 @@ export function RoomSettings({ initialPage, requestClose }: RoomSettingsProps) {
|
|||
const ct = useClient();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const roomAvatar = getRoomAvatar(roomId);
|
||||
const roomName = getRoomName(roomId);
|
||||
|
||||
|
|
|
|||
|
|
@ -112,9 +112,10 @@ export function RoomTimeline({ eventId, roomInputRef, editor, timeline }: RoomTi
|
|||
|
||||
const powerLevels = usePowerLevelsContext();
|
||||
const creators = useRoomCreators(roomId);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const membersAPI = useRoomMembersAPI();
|
||||
const creatorsTag = useRoomCreatorsTag();
|
||||
|
|
|
|||
|
|
@ -271,9 +271,10 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
|||
const roomToJoinRule = useObservableValue(ct.roomToJoinRule);
|
||||
|
||||
const pinnedEvents = useRoomPinnedEvents(roomId);
|
||||
const [getRoomHeroes, roomToHeroMemberResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMemberResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMemberResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const avatarMxc = getRoomAvatar(roomId);
|
||||
const name = getRoomName(roomId) ?? 'Unknown';
|
||||
|
|
|
|||
|
|
@ -181,8 +181,9 @@ export const RoomPinMenu = forwardRef<HTMLDivElement, RoomPinMenuProps>(({ reque
|
|||
const redactedSet = useObservableValueOptionally(timeline?.relations.redacted);
|
||||
const edits = useObservableValueOptionally(timeline?.relations.edits.eventToRelations);
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
|
||||
const membersAPI = useRoomMembersAPI();
|
||||
const { linkifyOpts, htmlReactParserOptions } = useMessageParserOptions(
|
||||
roomId,
|
||||
|
|
|
|||
|
|
@ -108,8 +108,9 @@ export function TimelineView({ threadTimeline, threadInputRef }: TimelineViewPro
|
|||
|
||||
const powerLevels = usePowerLevelsContext();
|
||||
const creators = useRoomCreators(roomId);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
|
||||
const membersAPI = useRoomMembersAPI();
|
||||
const creatorsTag = useRoomCreatorsTag();
|
||||
|
|
|
|||
|
|
@ -153,9 +153,9 @@ export function Search({ requestClose }: SearchProps) {
|
|||
const topActiveRooms = useTopActiveRooms(searchRoomType, rooms, directs, spaces);
|
||||
const targetRooms = useSearchTargetRooms(searchRoomType, rooms, directs, spaces);
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(directs);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const getTargetStr: SearchItemStrGetter<string> = useCallback(
|
||||
(roomId: string) => {
|
||||
|
|
|
|||
|
|
@ -58,12 +58,8 @@ function GlobalPackSelector({
|
|||
}) {
|
||||
const ct = useClient();
|
||||
|
||||
const imagePackRooms = useMemo(
|
||||
() => packs.map((pack) => pack.address?.roomId).filter((rId) => typeof rId === 'string'),
|
||||
[packs]
|
||||
);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(imagePackRooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
|
||||
const roomToPacks = useMemo(() => {
|
||||
const rToP = new Map<string, ImagePack[]>();
|
||||
|
|
|
|||
|
|
@ -77,9 +77,10 @@ export function SpaceSettings({ initialPage, requestClose }: SpaceSettingsProps)
|
|||
const roomId = useRoom();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const roomAvatar = getRoomAvatar(roomId);
|
||||
const roomName = getRoomName(roomId);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useClient } from '../useClient';
|
||||
import { useObservableValue } from '../useObservableValue';
|
||||
import { GetRoomHeroesCallback, RoomToHeroMembers } from './useRoomHeros';
|
||||
import { GetRoomHeroesCallback } from './useRoomHeros';
|
||||
import { roomMemberContentAvatarUrl } from '../../utils/room';
|
||||
import { roomToHeroMembersAtom } from '../../state/room/roomToHeroMembers';
|
||||
|
||||
export type GetRoomAvatarCallback = (roomId: string) => string | undefined;
|
||||
|
||||
export const useGetRoomAvatar = (
|
||||
getRoomHeroes: GetRoomHeroesCallback,
|
||||
roomToHeroMembers: RoomToHeroMembers | undefined
|
||||
): GetRoomAvatarCallback => {
|
||||
export const useGetRoomAvatar = (getRoomHeroes: GetRoomHeroesCallback): GetRoomAvatarCallback => {
|
||||
const ct = useClient();
|
||||
const roomToAvatar = useObservableValue(ct.roomToAvatar);
|
||||
const roomToHeroMembers = useAtomValue(roomToHeroMembersAtom);
|
||||
|
||||
const getRoomAvatar: GetRoomAvatarCallback = useCallback(
|
||||
(roomId: string) => {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useClient } from '../useClient';
|
||||
import { useObservableValue } from '../useObservableValue';
|
||||
import { GetRoomHeroesCallback, RoomToHeroMembers } from './useRoomHeros';
|
||||
import { GetRoomHeroesCallback } from './useRoomHeros';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { roomMemberContentDisplayname } from '../../utils/room';
|
||||
import { roomToHeroMembersAtom } from '../../state/room/roomToHeroMembers';
|
||||
|
||||
export type GetRoomNameCallback = (roomId: string) => string | undefined;
|
||||
|
||||
export const useGetRoomName = (
|
||||
getRoomHeroes: GetRoomHeroesCallback,
|
||||
roomToHeroMembers: RoomToHeroMembers | undefined
|
||||
): GetRoomNameCallback => {
|
||||
export const useGetRoomName = (getRoomHeroes: GetRoomHeroesCallback): GetRoomNameCallback => {
|
||||
const ct = useClient();
|
||||
const roomToName = useObservableValue(ct.roomToName);
|
||||
const roomToAlias = useObservableValue(ct.roomToAlias);
|
||||
const roomToHeroMembers = useAtomValue(roomToHeroMembersAtom);
|
||||
|
||||
const getRoomName: GetRoomNameCallback = useCallback(
|
||||
(roomId: string) => {
|
||||
|
|
@ -25,7 +25,7 @@ export const useGetRoomName = (
|
|||
|
||||
const members = roomToHeroMembers?.get(roomId);
|
||||
|
||||
const heroesName: string[] = getRoomHeroes(roomId).map((userId) => {
|
||||
const heroNames: string[] = getRoomHeroes(roomId).map((userId) => {
|
||||
const member = members?.get(userId);
|
||||
if (!member) return getMxIdLocalPart(userId) ?? userId;
|
||||
const { content } = member;
|
||||
|
|
@ -34,9 +34,19 @@ export const useGetRoomName = (
|
|||
return username;
|
||||
});
|
||||
|
||||
if (heroesName) return heroesName.join(', ');
|
||||
if (heroNames.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
if (heroNames.length === 1) {
|
||||
return heroNames[0];
|
||||
}
|
||||
|
||||
if (heroNames.length === 2) {
|
||||
return `${heroNames[0]} & ${heroNames[1]}`;
|
||||
}
|
||||
|
||||
return `${heroNames.slice(0, -1).join(', ')} & ${heroNames.at(-1)}`;
|
||||
},
|
||||
[roomToName, roomToAlias, getRoomHeroes, roomToHeroMembers]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,10 @@
|
|||
import { useCallback, useMemo } from 'react';
|
||||
import { PendingObservableResult } from 'neurone/lib/utils/observable';
|
||||
import { StateEventWithoutRoomId } from 'neurone/lib/api/types';
|
||||
import { useCallback } from 'react';
|
||||
import { useClient } from '../useClient';
|
||||
import {
|
||||
useComputedPendingObservableResult,
|
||||
useObservableValue,
|
||||
useObservableValuePromise,
|
||||
} from '../useObservableValue';
|
||||
import { getJoinRoomMemberId } from '../../../client/storage/collections';
|
||||
|
||||
export type UserIdToRoomMember = Map<string, StateEventWithoutRoomId>;
|
||||
export type RoomToHeroMembers = Map<string, UserIdToRoomMember>;
|
||||
import { useObservableValue } from '../useObservableValue';
|
||||
|
||||
export type GetRoomHeroesCallback = (roomId: string) => string[];
|
||||
|
||||
export const useRoomHeroes = (
|
||||
roomOrRooms: string | string[]
|
||||
): [GetRoomHeroesCallback, PendingObservableResult<RoomToHeroMembers>] => {
|
||||
export const useRoomHeroes = (): GetRoomHeroesCallback => {
|
||||
const ct = useClient();
|
||||
const roomToSummary = useObservableValue(ct.roomToSummary);
|
||||
const directRoomToUser = useObservableValue(ct.directRoomToUser);
|
||||
|
|
@ -31,34 +19,5 @@ export const useRoomHeroes = (
|
|||
},
|
||||
[roomToSummary, directRoomToUser]
|
||||
);
|
||||
|
||||
const membersResult = useObservableValuePromise(
|
||||
useMemo(() => {
|
||||
const ids = Array.isArray(roomOrRooms)
|
||||
? roomOrRooms.flatMap((roomId) =>
|
||||
getHeroes(roomId).map((userId) => getJoinRoomMemberId(roomId, userId))
|
||||
)
|
||||
: getHeroes(roomOrRooms).map((userId) => getJoinRoomMemberId(roomOrRooms, userId));
|
||||
|
||||
return ct.storage.joinRoomMember.observableRead.getMultiple(ids);
|
||||
}, [roomOrRooms, getHeroes, ct])
|
||||
);
|
||||
|
||||
const roomToHeroesResult: PendingObservableResult<RoomToHeroMembers> =
|
||||
useComputedPendingObservableResult(
|
||||
membersResult,
|
||||
useCallback((members) => {
|
||||
const roomToHeroes = new Map<string, UserIdToRoomMember>();
|
||||
members.forEach((member) => {
|
||||
if (!member) return;
|
||||
const { roomId, userId, event } = member;
|
||||
const userToEvent: UserIdToRoomMember = roomToHeroes.get(roomId) ?? new Map();
|
||||
userToEvent.set(userId, event);
|
||||
roomToHeroes.set(roomId, userToEvent);
|
||||
});
|
||||
return roomToHeroes;
|
||||
}, [])
|
||||
);
|
||||
|
||||
return [getHeroes, roomToHeroesResult];
|
||||
return getHeroes;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ export type LocalRoomSummary = {
|
|||
};
|
||||
export const useLocalRoomSummary = (roomId: string): LocalRoomSummary => {
|
||||
const ct = useClient();
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(roomId);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
const roomTopic = useRoomTopic(roomId);
|
||||
const roomToAlias = useObservableValue(ct.roomToAlias);
|
||||
const roomToJoinRule = useObservableValue(ct.roomToJoinRule);
|
||||
|
|
|
|||
|
|
@ -183,9 +183,10 @@ export function Direct() {
|
|||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const directs = useDirectRooms();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(directs);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const roomToJoinRule = useObservableValue(ct.roomToJoinRule);
|
||||
const roomToNotifications = useRoomsNotifications(directs, roomToNotificationsAtom);
|
||||
const unreadRooms = useRoomsUnread(directs, unreadRoomsAtom);
|
||||
|
|
|
|||
|
|
@ -207,9 +207,10 @@ export function Home() {
|
|||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const rooms = useHomeRooms();
|
||||
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(rooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const roomToJoinRule = useObservableValue(ct.roomToJoinRule);
|
||||
const roomToNotifications = useRoomsNotifications(rooms, roomToNotificationsAtom);
|
||||
const unreadRooms = useRoomsUnread(rooms, unreadRoomsAtom);
|
||||
|
|
|
|||
|
|
@ -596,15 +596,11 @@ export function Notifications() {
|
|||
}
|
||||
}, [timelineState, notificationTimeline, lastVItemIndex, loadTimeline]);
|
||||
|
||||
const notificationRooms = useMemo(
|
||||
() => Array.from(new Set(notificationTimeline.groups.map((g) => g.roomId))),
|
||||
[notificationTimeline]
|
||||
);
|
||||
|
||||
const roomToTimeline = useObservableValue(ct.roomToTimeline);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(notificationRooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ import {
|
|||
parseSidebar,
|
||||
sidebarItemWithout,
|
||||
useSidebarItems,
|
||||
useSidebarRooms,
|
||||
} from '../../../hooks/useSidebarItems';
|
||||
import { AccountDataType } from '../../../../types/matrix/accountData';
|
||||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
|
|
@ -667,11 +666,9 @@ export function SpaceTabs({ scrollRef }: SpaceTabsProps) {
|
|||
const [openedFolder, setOpenedFolder] = useAtom(useOpenedSidebarFolderAtom());
|
||||
const [draggingItem, setDraggingItem] = useState<SidebarDraggable>();
|
||||
|
||||
const sidebarRooms = useSidebarRooms(originalSidebarItems);
|
||||
const [getRoomHeroes, roomToHeroResult] = useRoomHeroes(sidebarRooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroResult.value);
|
||||
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroResult.value);
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
useEffect(() => {
|
||||
localEchoSidebarItem(originalSidebarItems);
|
||||
|
|
|
|||
|
|
@ -401,9 +401,11 @@ export function Space() {
|
|||
const hierarchy = useSpaceJoinedHierarchy(spaceId);
|
||||
|
||||
const rooms = useMemo(() => hierarchy.map((item) => item.roomId), [hierarchy]);
|
||||
const [getRoomHeroes, roomToHeroMembersResult] = useRoomHeroes(rooms);
|
||||
const getRoomName = useGetRoomName(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes, roomToHeroMembersResult.value);
|
||||
|
||||
const getRoomHeroes = useRoomHeroes();
|
||||
const getRoomName = useGetRoomName(getRoomHeroes);
|
||||
const getRoomAvatar = useGetRoomAvatar(getRoomHeroes);
|
||||
|
||||
const roomToJoinRule = useObservableValue(ct.roomToJoinRule);
|
||||
const roomToNotifications = useRoomsNotifications(rooms, roomToNotificationsAtom);
|
||||
const unreadRooms = useRoomsUnread(rooms, unreadRoomsAtom);
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ import {
|
|||
} from '../room/roomToNotifications';
|
||||
import { ClientContext } from '../../../client/context';
|
||||
import { unreadRoomsAtom, useBindUnreadRoomsAtom } from '../room/roomToUnread';
|
||||
import { roomToHeroMembersAtom, useBindRoomToHeroMembers } from '../room/roomToHeroMembers';
|
||||
|
||||
export const useBindAtoms = (ct: ClientContext) => {
|
||||
useBindMDirectAtom(ct, mDirectAtom);
|
||||
useBindAllRoomsAtom(ct, allRoomsAtom);
|
||||
useBindRoomToParentsAtom(ct, roomToParentsAtom);
|
||||
useBindRoomToNotificationsAtom(ct, roomToNotificationsAtom);
|
||||
useBindRoomToHeroMembers(ct, roomToHeroMembersAtom);
|
||||
useBindUnreadRoomsAtom(ct, unreadRoomsAtom);
|
||||
|
||||
useBindRoomIdToTypingMembersAtom(ct, roomIdToTypingMembersAtom);
|
||||
|
|
|
|||
75
src/app/state/room/roomToHeroMembers.ts
Normal file
75
src/app/state/room/roomToHeroMembers.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { useCallback, useEffect } from 'react';
|
||||
import { StateEventWithoutRoomId } from 'neurone/lib/api/types';
|
||||
import { atom, useSetAtom } from 'jotai';
|
||||
import { ClientContext } from '../../../client/context';
|
||||
import { useObservableValue } from '../../hooks/useObservableValue';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
import { getJoinRoomMemberId } from '../../../client/storage/collections';
|
||||
|
||||
export type UserIdToRoomMember = Map<string, StateEventWithoutRoomId>;
|
||||
export type RoomToHeroMembers = Map<string, UserIdToRoomMember>;
|
||||
|
||||
export const roomToHeroMembersAtom = atom<RoomToHeroMembers>(new Map());
|
||||
|
||||
export const useBindRoomToHeroMembers = (
|
||||
ct: ClientContext,
|
||||
heroMembersAtom: typeof roomToHeroMembersAtom
|
||||
) => {
|
||||
const setHeroMembersAtom = useSetAtom(heroMembersAtom);
|
||||
|
||||
const rooms = useObservableValue(ct.rooms.join);
|
||||
const roomToSummary = useObservableValue(ct.roomToSummary);
|
||||
const directRoomToUser = useObservableValue(ct.directRoomToUser);
|
||||
|
||||
const [heroMembersState, loadHeroMembers] = useAsyncCallback(
|
||||
useCallback(async () => {
|
||||
const getHeroes = (roomId: string): string[] => {
|
||||
const heroes = roomToSummary.get(roomId)?.['m.heroes'];
|
||||
if (heroes && heroes.length > 0) return heroes;
|
||||
|
||||
const dmUserId = directRoomToUser.get(roomId);
|
||||
return dmUserId ? [dmUserId] : [];
|
||||
};
|
||||
|
||||
const ids = rooms.flatMap((roomId) =>
|
||||
getHeroes(roomId).map((userId) => getJoinRoomMemberId(roomId, userId))
|
||||
);
|
||||
|
||||
return ct.storage.joinRoomMember.observableRead.getMultiple(ids);
|
||||
}, [ct, rooms, roomToSummary, directRoomToUser])
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
loadHeroMembers();
|
||||
}, [loadHeroMembers]);
|
||||
|
||||
const heroMembers =
|
||||
heroMembersState.status === AsyncStatus.Success ? heroMembersState.data : undefined;
|
||||
|
||||
// dispose
|
||||
useEffect(() => () => heroMembers?.dispose(), [heroMembers]);
|
||||
|
||||
useEffect(() => {
|
||||
const processHeroMembers = () => {
|
||||
const roomToHeroes = new Map<string, UserIdToRoomMember>();
|
||||
|
||||
heroMembers?.read.forEach((member) => {
|
||||
if (!member) return;
|
||||
const { roomId, userId, event } = member;
|
||||
const userToEvent: UserIdToRoomMember = roomToHeroes.get(roomId) ?? new Map();
|
||||
userToEvent.set(userId, event);
|
||||
roomToHeroes.set(roomId, userToEvent);
|
||||
});
|
||||
|
||||
setHeroMembersAtom(roomToHeroes);
|
||||
};
|
||||
|
||||
if (heroMembers) {
|
||||
processHeroMembers();
|
||||
}
|
||||
const unsubscribe = heroMembers?.subscribe(processHeroMembers);
|
||||
return () => {
|
||||
unsubscribe?.();
|
||||
};
|
||||
}, [heroMembers, setHeroMembersAtom]);
|
||||
};
|
||||
Loading…
Reference in a new issue