forked from mystiq/hydrogen-web
refresh vm when left room receives invite
clean up room vm switching in the process
This commit is contained in:
parent
827075bc37
commit
f2d7f5e4da
4 changed files with 70 additions and 74 deletions
|
@ -32,11 +32,10 @@ export class RoomGridViewModel extends ViewModel {
|
|||
|
||||
this._width = options.width;
|
||||
this._height = options.height;
|
||||
this._createRoomOrInviteViewModel = options.createRoomOrInviteViewModel;
|
||||
|
||||
this._createRoomViewModel = options.createRoomViewModel;
|
||||
this._selectedIndex = 0;
|
||||
this._viewModels = [];
|
||||
this._replaceInviteWithRoom = this._replaceInviteWithRoom.bind(this);
|
||||
this._refreshRoomViewModel = this._refreshRoomViewModel.bind(this);
|
||||
this._setupNavigation();
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,7 @@ export class RoomGridViewModel extends ViewModel {
|
|||
// initial focus for a room is set by initializeRoomIdsAndTransferVM
|
||||
}
|
||||
|
||||
_replaceInviteWithRoom(roomId) {
|
||||
_refreshRoomViewModel(roomId) {
|
||||
const index = this._viewModels.findIndex(vm => vm?.id === roomId);
|
||||
if (index === -1) {
|
||||
return;
|
||||
|
@ -72,7 +71,7 @@ export class RoomGridViewModel extends ViewModel {
|
|||
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);
|
||||
const roomVM = this._createRoomViewModel(roomId, this._refreshRoomViewModel);
|
||||
if (roomVM) {
|
||||
this._viewModels[index] = this.track(roomVM);
|
||||
if (this.focusIndex === index) {
|
||||
|
@ -147,7 +146,7 @@ export class RoomGridViewModel extends ViewModel {
|
|||
this._viewModels[i] = this.disposeTracked(vm);
|
||||
}
|
||||
if (newId) {
|
||||
const newVM = this._createRoomOrInviteViewModel(newId, this._replaceInviteWithRoom);
|
||||
const newVM = this._createRoomViewModel(newId, this._refreshRoomViewModel);
|
||||
if (newVM) {
|
||||
this._viewModels[i] = this.track(newVM);
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ export function tests() {
|
|||
"initialize with duplicate set of rooms": assert => {
|
||||
const navigation = createNavigationForRoom(["c", "a", "b", undefined, "a"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -247,7 +246,7 @@ export function tests() {
|
|||
"transfer room view model": assert => {
|
||||
const navigation = createNavigationForRoom(["a"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: () => assert.fail("no vms should be created"),
|
||||
createRoomViewModel: () => assert.fail("no vms should be created"),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -261,7 +260,7 @@ export function tests() {
|
|||
"reject transfer for non-matching room view model": assert => {
|
||||
const navigation = createNavigationForRoom(["a"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -275,7 +274,7 @@ export function tests() {
|
|||
"created & released room view model is not disposed": assert => {
|
||||
const navigation = createNavigationForRoom(["a"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -289,7 +288,7 @@ export function tests() {
|
|||
"transfered & released room view model is not disposed": assert => {
|
||||
const navigation = createNavigationForRoom([undefined, "a"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: () => assert.fail("no vms should be created"),
|
||||
createRoomViewModel: () => assert.fail("no vms should be created"),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -304,7 +303,7 @@ export function tests() {
|
|||
"try release non-existing room view model is": assert => {
|
||||
const navigation = createNavigationForEmptyTile([undefined, "b"], 3);
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -316,7 +315,7 @@ export function tests() {
|
|||
"initial focus is set to empty tile": assert => {
|
||||
const navigation = createNavigationForEmptyTile(["a"], 1);
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
@ -328,7 +327,7 @@ export function tests() {
|
|||
"change room ids after creation": assert => {
|
||||
const navigation = createNavigationForRoom(["a", "b"], "a");
|
||||
const gridVM = new RoomGridViewModel({
|
||||
createRoomOrInviteViewModel: id => new RoomVMMock(id),
|
||||
createRoomViewModel: id => new RoomVMMock(id),
|
||||
navigation,
|
||||
width: 3,
|
||||
height: 2,
|
||||
|
|
|
@ -42,8 +42,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._refreshRoomViewModel = this._refreshRoomViewModel.bind(this);
|
||||
this._createRoomViewModel = this._createRoomViewModel.bind(this);
|
||||
this._setupNavigation();
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ export class SessionViewModel extends ViewModel {
|
|||
this._gridViewModel = this.track(new RoomGridViewModel(this.childOptions({
|
||||
width: 3,
|
||||
height: 2,
|
||||
createRoomOrInviteViewModel: this._createRoomOrInviteViewModel,
|
||||
createRoomViewModel: this._createRoomViewModel,
|
||||
})));
|
||||
if (this._gridViewModel.initializeRoomIdsAndTransferVM(roomIds, this._currentRoomViewModel)) {
|
||||
this._currentRoomViewModel = this.untrack(this._currentRoomViewModel);
|
||||
|
@ -138,7 +138,7 @@ export class SessionViewModel extends ViewModel {
|
|||
if (vm) {
|
||||
this._currentRoomViewModel = this.track(vm);
|
||||
} else {
|
||||
const newVM = this._createRoomViewModel(currentRoomId.value);
|
||||
const newVM = this._createRoomViewModel(currentRoomId.value, this._refreshRoomViewModel);
|
||||
if (newVM) {
|
||||
this._currentRoomViewModel = this.track(newVM);
|
||||
}
|
||||
|
@ -151,72 +151,62 @@ export class SessionViewModel extends ViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
_createRoomViewModel(roomId) {
|
||||
const room = this._sessionContainer.session.rooms.get(roomId);
|
||||
if (!room) {
|
||||
return null;
|
||||
}
|
||||
const roomVM = new RoomViewModel(this.childOptions({
|
||||
room,
|
||||
ownUserId: this._sessionContainer.session.user.id,
|
||||
}));
|
||||
roomVM.load();
|
||||
return roomVM;
|
||||
}
|
||||
|
||||
_createInviteViewModel(roomId, replaceInviteWithRoom) {
|
||||
/**
|
||||
* @param {string} roomId
|
||||
* @param {function} refreshRoomViewModel passed in as an argument, because the grid needs a different impl of this
|
||||
* @return {RoomViewModel | InviteViewModel}
|
||||
*/
|
||||
_createRoomViewModel(roomId, refreshRoomViewModel) {
|
||||
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);
|
||||
if (invite) {
|
||||
console.log("got invite");
|
||||
return new InviteViewModel(this.childOptions({
|
||||
invite,
|
||||
mediaRepository: this._sessionContainer.session.mediaRepository,
|
||||
refreshRoomViewModel,
|
||||
}));
|
||||
} else {
|
||||
// close invite
|
||||
this.navigation.applyPath(removeRoomFromPath(this.navigation.path, roomId));
|
||||
const room = this._sessionContainer.session.rooms.get(roomId);
|
||||
if (room) {
|
||||
console.log("got room");
|
||||
const roomVM = new RoomViewModel(this.childOptions({
|
||||
room,
|
||||
ownUserId: this._sessionContainer.session.user.id,
|
||||
refreshRoomViewModel
|
||||
}));
|
||||
roomVM.load();
|
||||
return roomVM;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_replaceInviteWithRoom(roomId) {
|
||||
/** refresh the room view model after an internal change that needs
|
||||
to change between invite, room or none state */
|
||||
_refreshRoomViewModel(roomId) {
|
||||
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
|
||||
const roomVM = this._createRoomViewModel(roomId);
|
||||
const roomVM = this._createRoomViewModel(roomId, this._refreshRoomViewModel);
|
||||
if (roomVM) {
|
||||
this._currentRoomViewModel = this.track(roomVM);
|
||||
} else {
|
||||
// close room id
|
||||
this.navigation.applyPath(removeRoomFromPath(this.navigation.path, roomId));
|
||||
}
|
||||
this.emitChange("activeMiddleViewModel");
|
||||
}
|
||||
|
||||
_updateRoom(roomId) {
|
||||
if (!roomId) {
|
||||
// closing invite or room view?
|
||||
if (this._currentRoomViewModel) {
|
||||
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
|
||||
this.emitChange("activeMiddleViewModel");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// already open?
|
||||
// opening a room and already open?
|
||||
if (this._currentRoomViewModel?.id === roomId) {
|
||||
console.log("bailing out");
|
||||
return;
|
||||
}
|
||||
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
|
||||
const roomVM = this._createRoomOrInviteViewModel(roomId, this._replaceInviteWithRoom);
|
||||
// close if needed
|
||||
if (this._currentRoomViewModel) {
|
||||
this._currentRoomViewModel = this.disposeTracked(this._currentRoomViewModel);
|
||||
}
|
||||
// and try opening again
|
||||
const roomVM = this._createRoomViewModel(roomId, this._refreshRoomViewModel);
|
||||
if (roomVM) {
|
||||
this._currentRoomViewModel = this.track(roomVM);
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ import {ViewModel} from "../../ViewModel.js";
|
|||
export class InviteViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {invite, mediaRepository, closeCallback} = options;
|
||||
const {invite, mediaRepository, refreshRoomViewModel} = options;
|
||||
this._invite = invite;
|
||||
this._mediaRepository = mediaRepository;
|
||||
this._closeCallback = closeCallback;
|
||||
this._refreshRoomViewModel = refreshRoomViewModel;
|
||||
this._onInviteChange = this._onInviteChange.bind(this);
|
||||
this._error = null;
|
||||
this._closeUrl = this.urlCreator.urlUntilSegment("session");
|
||||
|
@ -99,7 +99,7 @@ export class InviteViewModel extends ViewModel {
|
|||
// we're in a grid view, and opening the room doesn't change
|
||||
// the nav path because the url is the same for an
|
||||
// invite and the room.
|
||||
this._closeCallback(this._invite.accepted);
|
||||
this._refreshRoomViewModel(this.id);
|
||||
} else {
|
||||
this.emitChange();
|
||||
}
|
||||
|
|
|
@ -22,9 +22,10 @@ import {ViewModel} from "../../ViewModel.js";
|
|||
export class RoomViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
const {room, ownUserId} = options;
|
||||
const {room, ownUserId, refreshRoomViewModel} = options;
|
||||
this._room = room;
|
||||
this._ownUserId = ownUserId;
|
||||
this._refreshRoomViewModel = refreshRoomViewModel;
|
||||
this._timelineVM = null;
|
||||
this._onRoomChange = this._onRoomChange.bind(this);
|
||||
this._timelineError = null;
|
||||
|
@ -65,7 +66,7 @@ export class RoomViewModel extends ViewModel {
|
|||
} catch (err) {
|
||||
if (err.name !== "AbortError") {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,13 @@ export class RoomViewModel extends ViewModel {
|
|||
// room doesn't tell us yet which fields changed,
|
||||
// so emit all fields originating from summary
|
||||
_onRoomChange() {
|
||||
this.emitChange("name");
|
||||
// if there is now an invite on this (left) room,
|
||||
// show the invite view by refreshing the view model
|
||||
if (this._room.invite) {
|
||||
this._refreshRoomViewModel(this.id);
|
||||
} else {
|
||||
this.emitChange("name");
|
||||
}
|
||||
}
|
||||
|
||||
get kind() { return "room"; }
|
||||
|
|
Loading…
Reference in a new issue