wire up InviteViewModel in Session/RoomGridViewModel

and:
 - switch to room once accepted
 - close invite if rejected
This commit is contained in:
Bruno Windels 2021-04-21 15:47:39 +02:00
parent 0cc95f5083
commit 7e2870acef
3 changed files with 89 additions and 34 deletions

View file

@ -32,10 +32,11 @@ export class RoomGridViewModel extends ViewModel {
this._width = options.width;
this._height = options.height;
this._createRoomViewModel = options.createRoomViewModel;
this._createRoomOrInviteViewModel = options.createRoomOrInviteViewModel;
this._selectedIndex = 0;
this._viewModels = [];
this._replaceInviteWithRoom = this._replaceInviteWithRoom.bind(this);
this._setupNavigation();
}
@ -63,6 +64,24 @@ export class RoomGridViewModel extends ViewModel {
// initial focus for a room is set by initializeRoomIdsAndTransferVM
}
_replaceInviteWithRoom(roomId) {
const index = this._viewModels.findIndex(vm => vm?.id === roomId);
if (index === -1) {
return;
}
this._viewModels[index] = this.disposeTracked(this._viewModels[index]);
// this will create a RoomViewModel because the invite is already
// removed from the collection (see Invite.afterSync)
const roomVM = this._createRoomOrInviteViewModel(roomId, this._replaceInviteWithRoom);
if (roomVM) {
this._viewModels[index] = this.track(roomVM);
if (this.focusIndex === index) {
roomVM.focus();
}
}
this.emitChange();
}
roomViewModelAt(i) {
return this._viewModels[i];
}
@ -128,7 +147,7 @@ export class RoomGridViewModel extends ViewModel {
this._viewModels[i] = this.disposeTracked(vm);
}
if (newId) {
const newVM = this._createRoomViewModel(newId);
const newVM = this._createRoomOrInviteViewModel(newId, this._replaceInviteWithRoom);
if (newVM) {
this._viewModels[i] = this.track(newVM);
}
@ -211,7 +230,7 @@ export function tests() {
"initialize with duplicate set of rooms": assert => {
const navigation = createNavigationForRoom(["c", "a", "b", undefined, "a"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,
@ -228,7 +247,7 @@ export function tests() {
"transfer room view model": assert => {
const navigation = createNavigationForRoom(["a"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: () => assert.fail("no vms should be created"),
createRoomOrInviteViewModel: () => assert.fail("no vms should be created"),
navigation,
width: 3,
height: 2,
@ -242,7 +261,7 @@ export function tests() {
"reject transfer for non-matching room view model": assert => {
const navigation = createNavigationForRoom(["a"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,
@ -256,7 +275,7 @@ export function tests() {
"created & released room view model is not disposed": assert => {
const navigation = createNavigationForRoom(["a"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,
@ -270,7 +289,7 @@ export function tests() {
"transfered & released room view model is not disposed": assert => {
const navigation = createNavigationForRoom([undefined, "a"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: () => assert.fail("no vms should be created"),
createRoomOrInviteViewModel: () => assert.fail("no vms should be created"),
navigation,
width: 3,
height: 2,
@ -285,7 +304,7 @@ export function tests() {
"try release non-existing room view model is": assert => {
const navigation = createNavigationForEmptyTile([undefined, "b"], 3);
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,
@ -297,7 +316,7 @@ export function tests() {
"initial focus is set to empty tile": assert => {
const navigation = createNavigationForEmptyTile(["a"], 1);
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,
@ -309,7 +328,7 @@ export function tests() {
"change room ids after creation": assert => {
const navigation = createNavigationForRoom(["a", "b"], "a");
const gridVM = new RoomGridViewModel({
createRoomViewModel: id => new RoomVMMock(id),
createRoomOrInviteViewModel: id => new RoomVMMock(id),
navigation,
width: 3,
height: 2,

View file

@ -15,8 +15,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {removeRoomFromPath} from "../navigation/index.js";
import {LeftPanelViewModel} from "./leftpanel/LeftPanelViewModel.js";
import {RoomViewModel} from "./room/RoomViewModel.js";
import {InviteViewModel} from "./room/InviteViewModel.js";
import {LightboxViewModel} from "./room/LightboxViewModel.js";
import {SessionStatusViewModel} from "./SessionStatusViewModel.js";
import {RoomGridViewModel} from "./RoomGridViewModel.js";
@ -39,6 +41,8 @@ export class SessionViewModel extends ViewModel {
this._settingsViewModel = null;
this._currentRoomViewModel = null;
this._gridViewModel = null;
this._replaceInviteWithRoom = this._replaceInviteWithRoom.bind(this);
this._createRoomOrInviteViewModel = this._createRoomOrInviteViewModel.bind(this);
this._setupNavigation();
}
@ -84,15 +88,8 @@ export class SessionViewModel extends ViewModel {
this._sessionStatusViewModel.start();
}
get activeSection() {
if (this._currentRoomViewModel) {
return this._currentRoomViewModel.id;
} else if (this._gridViewModel) {
return "roomgrid";
} else if (this._settingsViewModel) {
return "settings";
}
return "placeholder";
get activeMiddleViewModel() {
return this._currentRoomViewModel || this._gridViewModel || this._settingsViewModel;
}
get roomGridViewModel() {
@ -127,7 +124,7 @@ export class SessionViewModel extends ViewModel {
this._gridViewModel = this.track(new RoomGridViewModel(this.childOptions({
width: 3,
height: 2,
createRoomViewModel: roomId => this._createRoomViewModel(roomId),
createRoomOrInviteViewModel: this._createRoomOrInviteViewModel,
})));
if (this._gridViewModel.initializeRoomIdsAndTransferVM(roomIds, this._currentRoomViewModel)) {
this._currentRoomViewModel = this.untrack(this._currentRoomViewModel);
@ -138,6 +135,7 @@ export class SessionViewModel extends ViewModel {
this._gridViewModel.setRoomIds(roomIds);
}
} else if (this._gridViewModel && !roomIds) {
// closing grid, try to show focused room in grid
if (currentRoomId) {
const vm = this._gridViewModel.releaseRoomViewModel(currentRoomId.value);
if (vm) {
@ -152,7 +150,7 @@ export class SessionViewModel extends ViewModel {
this._gridViewModel = this.disposeTracked(this._gridViewModel);
}
if (changed) {
this.emitChange("activeSection");
this.emitChange("activeMiddleViewModel");
}
}
@ -169,11 +167,50 @@ export class SessionViewModel extends ViewModel {
return roomVM;
}
_createInviteViewModel(roomId, replaceInviteWithRoom) {
const invite = this._sessionContainer.session.invites.get(roomId);
if (!invite) {
return null;
}
return new InviteViewModel(this.childOptions({
invite,
mediaRepository: this._sessionContainer.session.mediaRepository,
closeCallback: accepted => this._closeInvite(roomId, accepted, replaceInviteWithRoom),
}));
}
_createRoomOrInviteViewModel(roomId, replaceInviteWithRoom) {
const inviteVM = this._createInviteViewModel(roomId, replaceInviteWithRoom);
if (inviteVM) {
return inviteVM;
}
return this._createRoomViewModel(roomId);
}
_closeInvite(roomId, accepted, replaceInviteWithRoom) {
if (accepted) {
replaceInviteWithRoom(roomId);
} else {
// close invite
this.navigation.applyPath(removeRoomFromPath(this.navigation.path, roomId));
}
}
_replaceInviteWithRoom(roomId) {
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
const roomVM = this._createRoomViewModel(roomId);
if (roomVM) {
this._currentRoomViewModel = this.track(roomVM);
}
this.emitChange("activeMiddleViewModel");
}
_updateRoom(roomId) {
if (!roomId) {
// closing invite or room view?
if (this._currentRoomViewModel) {
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
this.emitChange("currentRoom");
this.emitChange("activeMiddleViewModel");
}
return;
}
@ -182,11 +219,11 @@ export class SessionViewModel extends ViewModel {
return;
}
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
const roomVM = this._createRoomViewModel(roomId);
const roomVM = this._createRoomOrInviteViewModel(roomId, this._replaceInviteWithRoom);
if (roomVM) {
this._currentRoomViewModel = this.track(roomVM);
}
this.emitChange("currentRoom");
this.emitChange("activeMiddleViewModel");
}
_updateSettings(settingsOpen) {
@ -199,7 +236,7 @@ export class SessionViewModel extends ViewModel {
})));
this._settingsViewModel.load();
}
this.emitChange("activeSection");
this.emitChange("activeMiddleViewModel");
}
_updateLightbox(eventId) {

View file

@ -34,16 +34,15 @@ export class SessionView extends TemplateView {
}, [
t.view(new SessionStatusView(vm.sessionStatusViewModel)),
t.view(new LeftPanelView(vm.leftPanelViewModel)),
t.mapView(vm => vm.activeSection, activeSection => {
switch (activeSection) {
case "roomgrid":
return new RoomGridView(vm.roomGridViewModel);
case "placeholder":
return new StaticView(t => t.div({className: "room-placeholder"}, t.h2(vm.i18n`Choose a room on the left side.`)));
case "settings":
return new SettingsView(vm.settingsViewModel);
default: //room id
t.mapView(vm => vm.activeMiddleViewModel, () => {
if (vm.roomGridViewModel) {
return new RoomGridView(vm.roomGridViewModel);
} else if (vm.settingsViewModel) {
return new SettingsView(vm.settingsViewModel);
} else if (vm.currentRoomViewModel) {
return new RoomView(vm.currentRoomViewModel);
} else {
return new StaticView(t => t.div({className: "room-placeholder"}, t.h2(vm.i18n`Choose a room on the left side.`)));
}
}),
t.mapView(vm => vm.lightboxViewModel, lightboxViewModel => lightboxViewModel ? new LightboxView(lightboxViewModel) : null)