forked from mystiq/hydrogen-web
some fixes
This commit is contained in:
parent
4be82cd472
commit
cad2aa760d
7 changed files with 43 additions and 23 deletions
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 = {};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) :
|
||||||
|
|
Loading…
Reference in a new issue