report errors from ErrorBoundary on GroupCall and Member in UI

UI is still very crude fwiw
This commit is contained in:
Bruno Windels 2023-01-09 14:04:13 +01:00
parent 1e4180a71f
commit fef7af3b31
4 changed files with 49 additions and 5 deletions

View File

@ -39,7 +39,11 @@ export class CallViewModel extends ViewModel<Options> {
constructor(options: Options) { constructor(options: Options) {
super(options); super(options);
const ownMemberViewModelMap = new ObservableValueMap("self", new EventObservableValue(this.call, "change")) const callObservable = new EventObservableValue(this.call, "change");
this.track(callObservable.subscribe(() => {
this.emitChange();
}));
const ownMemberViewModelMap = new ObservableValueMap("self", callObservable)
.mapValues((call, emitChange) => new OwnMemberViewModel(this.childOptions({call, emitChange})), () => {}); .mapValues((call, emitChange) => new OwnMemberViewModel(this.childOptions({call, emitChange})), () => {});
this.memberViewModels = this.call.members this.memberViewModels = this.call.members
.filterValues(member => member.isConnected) .filterValues(member => member.isConnected)
@ -79,6 +83,10 @@ export class CallViewModel extends ViewModel<Options> {
return this.call.id; return this.call.id;
} }
get error(): string | undefined {
return this.call.error?.message;
}
private get call(): GroupCall { private get call(): GroupCall {
return this.getOption("call"); return this.getOption("call");
} }
@ -135,6 +143,10 @@ class OwnMemberViewModel extends ViewModel<Options> implements IStreamViewModel
})); }));
} }
get error(): string | undefined {
return undefined;
}
get stream(): Stream | undefined { get stream(): Stream | undefined {
return this.call.localPreviewMedia?.userMedia; return this.call.localPreviewMedia?.userMedia;
} }
@ -195,6 +207,10 @@ export class CallMemberViewModel extends ViewModel<MemberOptions> implements ISt
return this.member.remoteMedia?.userMedia; return this.member.remoteMedia?.userMedia;
} }
get error(): string | undefined {
return this.member.error?.message;
}
private get member(): Member { private get member(): Member {
return this.getOption("member"); return this.getOption("member");
} }
@ -242,4 +258,5 @@ export interface IStreamViewModel extends AvatarSource, ViewModel {
get stream(): Stream | undefined; get stream(): Stream | undefined;
get isCameraMuted(): boolean; get isCameraMuted(): boolean;
get isMicrophoneMuted(): boolean; get isMicrophoneMuted(): boolean;
get error(): string | undefined;
} }

View File

@ -74,9 +74,14 @@ export class CallTile extends SimpleTile {
async join() { async join() {
if (this.canJoin) { if (this.canJoin) {
try {
const stream = await this.platform.mediaDevices.getMediaTracks(false, true); const stream = await this.platform.mediaDevices.getMediaTracks(false, true);
const localMedia = new LocalMedia().withUserMedia(stream); const localMedia = new LocalMedia().withUserMedia(stream);
await this._call.join(localMedia); await this._call.join(localMedia);
} catch (err) {
this._error = err;
this.emitChange("error");
}
} }
} }

View File

@ -24,6 +24,14 @@ limitations under the License.
grid-row: 1; grid-row: 1;
} }
.CallView_error {
color: red;
font-weight: bold;
align-self: start;
justify-self: center;
margin: 16px;
}
.CallView_members { .CallView_members {
display: grid; display: grid;
gap: 12px; gap: 12px;
@ -59,6 +67,14 @@ limitations under the License.
justify-self: center; justify-self: center;
} }
.StreamView_error {
color: red;
font-weight: bold;
align-self: start;
justify-self: center;
margin: 16px;
}
.StreamView_muteStatus { .StreamView_muteStatus {
align-self: start; align-self: start;
justify-self: end; justify-self: end;

View File

@ -43,7 +43,10 @@ export class CallView extends TemplateView<CallViewModel> {
"CallView_unmutedCamera": vm => !vm.isCameraMuted, "CallView_unmutedCamera": vm => !vm.isCameraMuted,
}, onClick: disableTargetCallback(() => vm.toggleCamera())}), }, onClick: disableTargetCallback(() => vm.toggleCamera())}),
t.button({className: "CallView_hangup", onClick: disableTargetCallback(() => vm.hangup())}), t.button({className: "CallView_hangup", onClick: disableTargetCallback(() => vm.hangup())}),
]) ]),
t.if(vm => !!vm.error, t => {
return t.div({className: "CallView_error"}, vm => vm.error);
})
]); ]);
} }
@ -112,6 +115,9 @@ class StreamView extends TemplateView<IStreamViewModel> {
microphoneMuted: vm => vm.isMicrophoneMuted && !vm.isCameraMuted, microphoneMuted: vm => vm.isMicrophoneMuted && !vm.isCameraMuted,
cameraMuted: vm => vm.isCameraMuted, cameraMuted: vm => vm.isCameraMuted,
} }
}),
t.if(vm => !!vm.error, t => {
return t.div({className: "StreamView_error"}, vm => vm.error);
}) })
]); ]);
} }