forked from mystiq/hydrogen-web
update call member info with room member info
This commit is contained in:
parent
a52740ed1b
commit
90b6a5ccb6
4 changed files with 53 additions and 18 deletions
|
@ -117,7 +117,10 @@ class OwnMemberViewModel extends ViewModel<OwnMemberOptions> implements IStreamV
|
|||
}
|
||||
}
|
||||
|
||||
type MemberOptions = BaseOptions & {member: Member, mediaRepository: MediaRepository};
|
||||
type MemberOptions = BaseOptions & {
|
||||
member: Member,
|
||||
mediaRepository: MediaRepository
|
||||
};
|
||||
|
||||
export class CallMemberViewModel extends ViewModel<MemberOptions> implements IStreamViewModel {
|
||||
get stream(): Stream | undefined {
|
||||
|
|
|
@ -22,6 +22,7 @@ import {EventType, CallIntent} from "./callEventTypes";
|
|||
import {GroupCall} from "./group/GroupCall";
|
||||
import {makeId} from "../common";
|
||||
import {CALL_LOG_TYPE} from "./common";
|
||||
import {EVENT_TYPE as MEMBER_EVENT_TYPE, RoomMember} from "../room/members/RoomMember";
|
||||
|
||||
import type {LocalMedia} from "./LocalMedia";
|
||||
import type {Room} from "../room/Room";
|
||||
|
@ -36,6 +37,7 @@ import type {Transaction} from "../storage/idb/Transaction";
|
|||
import type {CallEntry} from "../storage/idb/stores/CallStore";
|
||||
import type {Clock} from "../../platform/web/dom/Clock";
|
||||
import type {RoomStateHandler} from "../room/state/types";
|
||||
import type {MemberSync} from "../room/timeline/persistence/MemberWriter";
|
||||
|
||||
export type Options = Omit<GroupCallOptions, "emitUpdate" | "createTimeout"> & {
|
||||
clock: Clock
|
||||
|
@ -77,7 +79,7 @@ export class CallHandler implements RoomStateHandler {
|
|||
const names = this.options.storage.storeNames;
|
||||
const txn = await this.options.storage.readTxn([
|
||||
names.calls,
|
||||
names.roomState
|
||||
names.roomState,
|
||||
]);
|
||||
return txn;
|
||||
}
|
||||
|
@ -97,15 +99,17 @@ export class CallHandler implements RoomStateHandler {
|
|||
}));
|
||||
const roomIds = Array.from(new Set(callEntries.map(e => e.roomId)));
|
||||
await Promise.all(roomIds.map(async roomId => {
|
||||
// const ownCallsMemberEvent = await txn.roomState.get(roomId, EventType.GroupCallMember, this.options.ownUserId);
|
||||
// if (ownCallsMemberEvent) {
|
||||
// this.handleCallMemberEvent(ownCallsMemberEvent.event, log);
|
||||
// }
|
||||
// TODO: don't load all members until we need them
|
||||
const callsMemberEvents = await txn.roomState.getAllForType(roomId, EventType.GroupCallMember);
|
||||
for (const entry of callsMemberEvents) {
|
||||
this.handleCallMemberEvent(entry.event, roomId, log);
|
||||
}
|
||||
// TODO: we should be loading the other members as well at some point
|
||||
await Promise.all(callsMemberEvents.map(async entry => {
|
||||
const roomMemberState = await txn.roomState.get(roomId, MEMBER_EVENT_TYPE, entry.event.sender);
|
||||
if (roomMemberState) {
|
||||
const roomMember = RoomMember.fromMemberEvent(roomMemberState.event);
|
||||
if (roomMember) {
|
||||
this.handleCallMemberEvent(entry.event, roomMember, roomId, log);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}));
|
||||
log.set("newSize", this._calls.size);
|
||||
});
|
||||
|
@ -144,12 +148,15 @@ export class CallHandler implements RoomStateHandler {
|
|||
// TODO: check and poll turn server credentials here
|
||||
|
||||
/** @internal */
|
||||
handleRoomState(room: Room, event: StateEvent, txn: Transaction, log: ILogItem) {
|
||||
async handleRoomState(room: Room, event: StateEvent, memberSync: MemberSync, txn: Transaction, log: ILogItem) {
|
||||
if (event.type === EventType.GroupCall) {
|
||||
this.handleCallEvent(event, room.id, txn, log);
|
||||
}
|
||||
if (event.type === EventType.GroupCallMember) {
|
||||
this.handleCallMemberEvent(event, room.id, log);
|
||||
const member: RoomMember | undefined = await memberSync.lookupMemberAtEvent(event.sender, event, txn);
|
||||
if (member) { // should always have a member?
|
||||
this.handleCallMemberEvent(event, member, room.id, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +164,11 @@ export class CallHandler implements RoomStateHandler {
|
|||
updateRoomMembers(room: Room, memberChanges: Map<string, MemberChange>) {
|
||||
// TODO: also have map for roomId to calls, so we can easily update members
|
||||
// we will also need this to get the call for a room
|
||||
for (const call of this._calls.values()) {
|
||||
if (call.roomId === room.id) {
|
||||
call.updateRoomMembers(memberChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
@ -193,7 +205,7 @@ export class CallHandler implements RoomStateHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private handleCallMemberEvent(event: StateEvent, roomId: string, log: ILogItem) {
|
||||
private handleCallMemberEvent(event: StateEvent, member: RoomMember, roomId: string, log: ILogItem) {
|
||||
const userId = event.state_key;
|
||||
const roomMemberKey = getRoomMemberKey(roomId, userId)
|
||||
const calls = event.content["m.calls"] ?? [];
|
||||
|
@ -201,7 +213,7 @@ export class CallHandler implements RoomStateHandler {
|
|||
const callId = call["m.call_id"];
|
||||
const groupCall = this._calls.get(callId);
|
||||
// TODO: also check the member when receiving the m.call event
|
||||
groupCall?.updateMembership(userId, call, log);
|
||||
groupCall?.updateMembership(userId, member, call, log);
|
||||
};
|
||||
const newCallIdsMemberOf = new Set<string>(calls.map(call => call["m.call_id"]));
|
||||
let previousCallIdsMemberOf = this.roomMemberToCallIds.get(roomMemberKey);
|
||||
|
|
|
@ -18,7 +18,7 @@ import {ObservableMap} from "../../../observable/map/ObservableMap";
|
|||
import {Member} from "./Member";
|
||||
import {LocalMedia} from "../LocalMedia";
|
||||
import {MuteSettings, CALL_LOG_TYPE} from "../common";
|
||||
import {RoomMember} from "../../room/members/RoomMember";
|
||||
import {MemberChange, RoomMember} from "../../room/members/RoomMember";
|
||||
import {EventEmitter} from "../../../utils/EventEmitter";
|
||||
import {EventType, CallIntent} from "../callEventTypes";
|
||||
|
||||
|
@ -258,7 +258,20 @@ export class GroupCall extends EventEmitter<{change: never}> {
|
|||
}
|
||||
|
||||
/** @internal */
|
||||
updateMembership(userId: string, callMembership: CallMembership, syncLog: ILogItem) {
|
||||
updateRoomMembers(memberChanges: Map<string, MemberChange>) {
|
||||
for (const change of memberChanges.values()) {
|
||||
const {member} = change;
|
||||
for (const callMember of this._members.values()) {
|
||||
// find all call members for a room member (can be multiple, for every device)
|
||||
if (callMember.userId === member.userId) {
|
||||
callMember.updateRoomMember(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
updateMembership(userId: string, roomMember: RoomMember, callMembership: CallMembership, syncLog: ILogItem) {
|
||||
syncLog.wrap({l: "update call membership", t: CALL_LOG_TYPE, id: this.id, userId}, log => {
|
||||
const devices = callMembership["m.devices"];
|
||||
const previousDeviceIds = this.getDeviceIdsForUserId(userId);
|
||||
|
@ -290,7 +303,7 @@ export class GroupCall extends EventEmitter<{change: never}> {
|
|||
}
|
||||
log.set("add", true);
|
||||
member = new Member(
|
||||
RoomMember.fromUserId(this.roomId, userId, "join"),
|
||||
roomMember,
|
||||
device, this._memberOptions,
|
||||
);
|
||||
this._members.add(memberKey, member);
|
||||
|
|
|
@ -68,7 +68,7 @@ export class Member {
|
|||
private connection?: MemberConnection;
|
||||
|
||||
constructor(
|
||||
public readonly member: RoomMember,
|
||||
public member: RoomMember,
|
||||
private callDeviceMembership: CallDeviceMembership,
|
||||
private readonly options: Options,
|
||||
) {}
|
||||
|
@ -180,6 +180,13 @@ export class Member {
|
|||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
updateRoomMember(roomMember: RoomMember) {
|
||||
this.member = roomMember;
|
||||
// TODO: this emits an update during the writeSync phase, which we usually try to avoid
|
||||
this.options.emitUpdate(this);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
emitUpdateFromPeerCall = (peerCall: PeerCall, params: any, log: ILogItem): void => {
|
||||
const connection = this.connection!;
|
||||
|
|
Loading…
Reference in a new issue