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

View file

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

View file

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