some fixes

This commit is contained in:
Bruno Windels 2022-03-21 16:30:13 +01:00
parent 4be82cd472
commit cad2aa760d
7 changed files with 43 additions and 23 deletions

View file

@ -30,24 +30,36 @@ export class CallViewModel extends ViewModel<Options> {
super(options); super(options);
this.memberViewModels = this.getOption("call").members this.memberViewModels = this.getOption("call").members
.mapValues(member => new CallMemberViewModel(this.childOptions({member}))) .mapValues(member => new CallMemberViewModel(this.childOptions({member})))
.sortValues((a, b) => { .sortValues((a, b) => a.compare(b));
});
} }
get name(): string { get name(): string {
return this.getOption("call").name; return this.getOption("call").name;
} }
get id(): string {
return this.getOption("call").id;
}
get localTracks(): Track[] { get localTracks(): Track[] {
console.log("localTracks", this.getOption("call").localMedia);
return this.getOption("call").localMedia?.tracks ?? []; return this.getOption("call").localMedia?.tracks ?? [];
} }
} }
type MemberOptions = BaseOptions & {member: Member}; type MemberOptions = BaseOptions & {member: Member};
class CallMemberViewModel extends ViewModel<MemberOptions> { export class CallMemberViewModel extends ViewModel<MemberOptions> {
get tracks(): Track[] { get tracks(): Track[] {
return this.getOption("member").remoteTracks; return this.getOption("member").remoteTracks;
} }
compare(other: CallMemberViewModel): number {
const myUserId = this.getOption("member").member.userId;
const otherUserId = other.getOption("member").member.userId;
if(myUserId === otherUserId) {
return 0;
}
return myUserId < otherUserId ? -1 : 1;
}
} }

View file

@ -48,7 +48,7 @@ export class RoomViewModel extends ViewModel {
_setupCallViewModel() { _setupCallViewModel() {
// pick call for this room with lowest key // pick call for this room with lowest key
this._callObservable = new PickMapObservableValue(session.callHandler.calls.filterValues(c => c.roomId === this.roomId)); this._callObservable = new PickMapObservableValue(this.getOption("session").callHandler.calls.filterValues(c => c.roomId === this._room.id));
this._callViewModel = undefined; this._callViewModel = undefined;
this.track(this._callObservable.subscribe(call => { this.track(this._callObservable.subscribe(call => {
this._callViewModel = this.disposeTracked(this._callViewModel); this._callViewModel = this.disposeTracked(this._callViewModel);
@ -347,10 +347,12 @@ export class RoomViewModel extends ViewModel {
} }
async startCall() { async startCall() {
const session = this.getOption("session");
const mediaTracks = await this.platform.mediaDevices.getMediaTracks(true, true); const mediaTracks = await this.platform.mediaDevices.getMediaTracks(true, true);
const localMedia = LocalMedia.fromTracks(mediaTracks); const localMedia = new LocalMedia().withTracks(mediaTracks);
console.log("localMedia", localMedia.tracks);
// this will set the callViewModel above as a call will be added to callHandler.calls // this will set the callViewModel above as a call will be added to callHandler.calls
await this.session.callHandler.createCall(this.roomId, localMedia, "A call " + Math.round(this.platform.random() * 100)); await session.callHandler.createCall(this._room.id, localMedia, "A call " + Math.round(this.platform.random() * 100));
} }
} }

View file

@ -52,6 +52,7 @@ export class CallHandler {
async createCall(roomId: string, localMedia: LocalMedia, name: string): Promise<GroupCall> { async createCall(roomId: string, localMedia: LocalMedia, name: string): Promise<GroupCall> {
const call = new GroupCall(undefined, undefined, roomId, this.groupCallOptions); const call = new GroupCall(undefined, undefined, roomId, this.groupCallOptions);
console.log("created call with id", call.id);
this._calls.set(call.id, call); this._calls.set(call.id, call);
try { try {
await call.create(localMedia, name); await call.create(localMedia, name);

View file

@ -35,7 +35,13 @@ export class LocalMedia {
return new LocalMedia(cameraTrack, screenShareTrack, microphoneTrack as AudioTrack); return new LocalMedia(cameraTrack, screenShareTrack, microphoneTrack as AudioTrack);
} }
get tracks(): Track[] { return []; } get tracks(): Track[] {
const tracks: Track[] = [];
if (this.cameraTrack) { tracks.push(this.cameraTrack); }
if (this.screenShareTrack) { tracks.push(this.screenShareTrack); }
if (this.microphoneTrack) { tracks.push(this.microphoneTrack); }
return tracks;
}
getSDPMetadata(): SDPStreamMetadata { getSDPMetadata(): SDPStreamMetadata {
const metadata = {}; const metadata = {};

View file

@ -93,7 +93,7 @@ export class Room extends BaseRoom {
} }
} }
this._updateCallHandler(roomResponse); this._updateCallHandler(roomResponse, log);
return { return {
roomEncryption, roomEncryption,
@ -448,20 +448,17 @@ export class Room extends BaseRoom {
return this._sendQueue.pendingEvents; return this._sendQueue.pendingEvents;
} }
_updateCallHandler(roomResponse) { _updateCallHandler(roomResponse, log) {
if (this._callHandler) { if (this._callHandler) {
const stateEvents = roomResponse.state?.events; const stateEvents = roomResponse.state?.events;
if (stateEvents) { if (stateEvents) {
for (const e of stateEvents) { this._callHandler.handleRoomState(this, stateEvents, log);
this._callHandler.handleRoomState(this, e);
}
} }
let timelineEvents = roomResponse.timeline?.events; let timelineEvents = roomResponse.timeline?.events;
if (timelineEvents) { if (timelineEvents) {
for (const e of timelineEvents) { const timelineStateEvents = timelineEvents.filter(e => typeof e.state_key === "string");
if (typeof e.state_key === "string") { if (timelineEvents.length !== 0) {
this._callHandler.handleRoomState(this, e); this._callHandler.handleRoomState(this, timelineStateEvents, log);
}
} }
} }
} }

View file

@ -15,29 +15,33 @@ limitations under the License.
*/ */
import {TemplateView, TemplateBuilder} from "../../general/TemplateView"; import {TemplateView, TemplateBuilder} from "../../general/TemplateView";
import {ListView} from "../../general/ListView";
import {Track, TrackType} from "../../../../types/MediaDevices"; import {Track, TrackType} from "../../../../types/MediaDevices";
import type {TrackWrapper} from "../../../dom/MediaDevices"; import type {TrackWrapper} from "../../../dom/MediaDevices";
import type {CallViewModel} from "../../../../../domain/session/room/CallViewModel"; import type {CallViewModel, CallMemberViewModel} from "../../../../../domain/session/room/CallViewModel";
function bindVideoTracks<T>(t: TemplateBuilder<T>, video: HTMLVideoElement, propSelector: (vm: T) => Track[]) { function bindVideoTracks<T>(t: TemplateBuilder<T>, video: HTMLVideoElement, propSelector: (vm: T) => Track[]) {
t.mapSideEffect(propSelector, tracks => { t.mapSideEffect(propSelector, tracks => {
console.log("tracks", tracks);
if (tracks.length) { if (tracks.length) {
video.srcObject = (tracks[0] as TrackWrapper).stream; video.srcObject = (tracks[0] as TrackWrapper).stream;
} }
}); });
return video;
} }
export class CallView extends TemplateView<CallViewModel> { export class CallView extends TemplateView<CallViewModel> {
render(t: TemplateBuilder<CallViewModel>, vm: CallViewModel): HTMLElement { render(t: TemplateBuilder<CallViewModel>, vm: CallViewModel): HTMLElement {
return t.div({class: "CallView"}, [ return t.div({class: "CallView"}, [
t.p(`Call ${vm.name} (${vm.id})`),
t.div({class: "CallView_me"}, bindVideoTracks(t, t.video(), vm => vm.localTracks)), t.div({class: "CallView_me"}, bindVideoTracks(t, t.video(), vm => vm.localTracks)),
t.view(new ListView(vm.memberViewModels, vm => new MemberView(vm))) t.view(new ListView({list: vm.memberViewModels}, vm => new MemberView(vm)))
]); ]);
} }
} }
class MemberView extends TemplateView<CallMemberViewModel> { class MemberView extends TemplateView<CallMemberViewModel> {
render(t, vm) { render(t: TemplateBuilder<CallMemberViewModel>, vm: CallMemberViewModel) {
return bindVideoTracks(t, t.video(), vm => vm.tracks); return bindVideoTracks(t, t.video(), vm => vm.tracks);
} }
} }

View file

@ -53,9 +53,7 @@ export class RoomView extends TemplateView {
]), ]),
t.div({className: "RoomView_body"}, [ t.div({className: "RoomView_body"}, [
t.div({className: "RoomView_error"}, vm => vm.error), t.div({className: "RoomView_error"}, vm => vm.error),
t.mapView(vm => vm.callViewModel, callViewModel => { t.mapView(vm => vm.callViewModel, callViewModel => callViewModel ? new CallView(callViewModel) : null),
return new CallView(callViewModel);
}),
t.mapView(vm => vm.timelineViewModel, timelineViewModel => { t.mapView(vm => vm.timelineViewModel, timelineViewModel => {
return timelineViewModel ? return timelineViewModel ?
new TimelineView(timelineViewModel) : new TimelineView(timelineViewModel) :