Merge remote-tracking branch 'origin/develop' into develop
						commit
						520a4ce618
					
				| 
						 | 
					@ -99,6 +99,10 @@ class MatrixClientPeg {
 | 
				
			||||||
        // the react sdk doesn't work without this, so don't allow
 | 
					        // the react sdk doesn't work without this, so don't allow
 | 
				
			||||||
        opts.pendingEventOrdering = "detached";
 | 
					        opts.pendingEventOrdering = "detached";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (SettingsStore.isFeatureEnabled('feature_lazyloading')) {
 | 
				
			||||||
 | 
					            opts.lazyLoadMembers = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            const promise = this.matrixClient.store.startup();
 | 
					            const promise = this.matrixClient.store.startup();
 | 
				
			||||||
            console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
 | 
					            console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
 | 
				
			||||||
| 
						 | 
					@ -115,7 +119,7 @@ class MatrixClientPeg {
 | 
				
			||||||
        MatrixActionCreators.start(this.matrixClient);
 | 
					        MatrixActionCreators.start(this.matrixClient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.log(`MatrixClientPeg: really starting MatrixClient`);
 | 
					        console.log(`MatrixClientPeg: really starting MatrixClient`);
 | 
				
			||||||
        this.get().startClient(opts);
 | 
					        await this.get().startClient(opts);
 | 
				
			||||||
        console.log(`MatrixClientPeg: MatrixClient started`);
 | 
					        console.log(`MatrixClientPeg: MatrixClient started`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,8 +194,7 @@ function _getDirectMessageRooms(addr) {
 | 
				
			||||||
    const rooms = dmRooms.filter((dmRoom) => {
 | 
					    const rooms = dmRooms.filter((dmRoom) => {
 | 
				
			||||||
        const room = MatrixClientPeg.get().getRoom(dmRoom);
 | 
					        const room = MatrixClientPeg.get().getRoom(dmRoom);
 | 
				
			||||||
        if (room) {
 | 
					        if (room) {
 | 
				
			||||||
            const me = room.getMember(MatrixClientPeg.get().credentials.userId);
 | 
					            return room.getMyMembership() === 'join';
 | 
				
			||||||
            return me && me.membership == 'join';
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return rooms;
 | 
					    return rooms;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								src/Rooms.js
								
								
								
								
							
							
						
						
									
										52
									
								
								src/Rooms.js
								
								
								
								
							| 
						 | 
					@ -31,26 +31,26 @@ export function getDisplayAliasForRoom(room) {
 | 
				
			||||||
 * If the room contains only two members including the logged-in user,
 | 
					 * If the room contains only two members including the logged-in user,
 | 
				
			||||||
 * return the other one. Otherwise, return null.
 | 
					 * return the other one. Otherwise, return null.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function getOnlyOtherMember(room, me) {
 | 
					export function getOnlyOtherMember(room, myUserId) {
 | 
				
			||||||
    const joinedMembers = room.getJoinedMembers();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (joinedMembers.length === 2) {
 | 
					    if (room.currentState.getJoinedMemberCount() === 2) {
 | 
				
			||||||
        return joinedMembers.filter(function(m) {
 | 
					        return room.getJoinedMembers().filter(function(m) {
 | 
				
			||||||
            return m.userId !== me.userId;
 | 
					            return m.userId !== myUserId;
 | 
				
			||||||
        })[0];
 | 
					        })[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return null;
 | 
					    return null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function _isConfCallRoom(room, me, conferenceHandler) {
 | 
					function _isConfCallRoom(room, myUserId, conferenceHandler) {
 | 
				
			||||||
    if (!conferenceHandler) return false;
 | 
					    if (!conferenceHandler) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (me.membership != "join") {
 | 
					    const myMembership = room.getMyMembership();
 | 
				
			||||||
 | 
					    if (myMembership != "join") {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const otherMember = getOnlyOtherMember(room, me);
 | 
					    const otherMember = getOnlyOtherMember(room, myUserId);
 | 
				
			||||||
    if (otherMember === null) {
 | 
					    if (otherMember === null) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -68,29 +68,31 @@ const isConfCallRoomCache = {
 | 
				
			||||||
    // $roomId: bool
 | 
					    // $roomId: bool
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function isConfCallRoom(room, me, conferenceHandler) {
 | 
					export function isConfCallRoom(room, myUserId, conferenceHandler) {
 | 
				
			||||||
    if (isConfCallRoomCache[room.roomId] !== undefined) {
 | 
					    if (isConfCallRoomCache[room.roomId] !== undefined) {
 | 
				
			||||||
        return isConfCallRoomCache[room.roomId];
 | 
					        return isConfCallRoomCache[room.roomId];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const result = _isConfCallRoom(room, me, conferenceHandler);
 | 
					    const result = _isConfCallRoom(room, myUserId, conferenceHandler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    isConfCallRoomCache[room.roomId] = result;
 | 
					    isConfCallRoomCache[room.roomId] = result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function looksLikeDirectMessageRoom(room, me) {
 | 
					export function looksLikeDirectMessageRoom(room, myUserId) {
 | 
				
			||||||
    if (me.membership == "join" || me.membership === "ban" ||
 | 
					    const myMembership = room.getMyMembership();
 | 
				
			||||||
        (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) {
 | 
					    const me = room.getMember(myUserId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (myMembership == "join" || myMembership === "ban" || (me && me.isKicked())) {
 | 
				
			||||||
        // Used to split rooms via tags
 | 
					        // Used to split rooms via tags
 | 
				
			||||||
        const tagNames = Object.keys(room.tags);
 | 
					        const tagNames = Object.keys(room.tags);
 | 
				
			||||||
        // Used for 1:1 direct chats
 | 
					        // Used for 1:1 direct chats
 | 
				
			||||||
        const members = room.currentState.getMembers();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't
 | 
					        // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't
 | 
				
			||||||
        // been moved to a different tag section
 | 
					        // been moved to a different tag section
 | 
				
			||||||
        if (members.length === 2 && !tagNames.length) {
 | 
					        const totalMemberCount = room.currentState.getJoinedMemberCount() +
 | 
				
			||||||
 | 
					            room.currentState.getInvitedMemberCount();
 | 
				
			||||||
 | 
					        if (totalMemberCount === 2 && !tagNames.length) {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -100,10 +102,10 @@ export function looksLikeDirectMessageRoom(room, me) {
 | 
				
			||||||
export function guessAndSetDMRoom(room, isDirect) {
 | 
					export function guessAndSetDMRoom(room, isDirect) {
 | 
				
			||||||
    let newTarget;
 | 
					    let newTarget;
 | 
				
			||||||
    if (isDirect) {
 | 
					    if (isDirect) {
 | 
				
			||||||
        const guessedTarget = guessDMRoomTarget(
 | 
					        const guessedUserId = guessDMRoomTargetId(
 | 
				
			||||||
            room, room.getMember(MatrixClientPeg.get().credentials.userId),
 | 
					            room, MatrixClientPeg.get().getUserId()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        newTarget = guessedTarget.userId;
 | 
					        newTarget = guessedUserId;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        newTarget = null;
 | 
					        newTarget = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -159,15 +161,15 @@ export function setDMRoom(roomId, userId) {
 | 
				
			||||||
 * Given a room, estimate which of its members is likely to
 | 
					 * Given a room, estimate which of its members is likely to
 | 
				
			||||||
 * be the target if the room were a DM room and return that user.
 | 
					 * be the target if the room were a DM room and return that user.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function guessDMRoomTarget(room, me) {
 | 
					function guessDMRoomTargetId(room, myUserId) {
 | 
				
			||||||
    let oldestTs;
 | 
					    let oldestTs;
 | 
				
			||||||
    let oldestUser;
 | 
					    let oldestUser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Pick the joined user who's been here longest (and isn't us),
 | 
					    // Pick the joined user who's been here longest (and isn't us),
 | 
				
			||||||
    for (const user of room.getJoinedMembers()) {
 | 
					    for (const user of room.getJoinedMembers()) {
 | 
				
			||||||
        if (user.userId == me.userId) continue;
 | 
					        if (user.userId == myUserId) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (oldestTs === undefined || user.events.member.getTs() < oldestTs) {
 | 
					        if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
 | 
				
			||||||
            oldestUser = user;
 | 
					            oldestUser = user;
 | 
				
			||||||
            oldestTs = user.events.member.getTs();
 | 
					            oldestTs = user.events.member.getTs();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -176,14 +178,14 @@ export function guessDMRoomTarget(room, me) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // if there are no joined members other than us, use the oldest member
 | 
					    // if there are no joined members other than us, use the oldest member
 | 
				
			||||||
    for (const user of room.currentState.getMembers()) {
 | 
					    for (const user of room.currentState.getMembers()) {
 | 
				
			||||||
        if (user.userId == me.userId) continue;
 | 
					        if (user.userId == myUserId) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (oldestTs === undefined || user.events.member.getTs() < oldestTs) {
 | 
					        if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
 | 
				
			||||||
            oldestUser = user;
 | 
					            oldestUser = user;
 | 
				
			||||||
            oldestTs = user.events.member.getTs();
 | 
					            oldestTs = user.events.member.getTs();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (oldestUser === undefined) return me;
 | 
					    if (oldestUser === undefined) return myUserId;
 | 
				
			||||||
    return oldestUser;
 | 
					    return oldestUser;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,7 @@ ConferenceCall.prototype._getConferenceUserRoom = function() {
 | 
				
			||||||
        preset: "private_chat",
 | 
					        preset: "private_chat",
 | 
				
			||||||
        invite: [this.confUserId]
 | 
					        invite: [this.confUserId]
 | 
				
			||||||
    }).then(function(res) {
 | 
					    }).then(function(res) {
 | 
				
			||||||
        return new Room(res.room_id);
 | 
					        return new Room(res.room_id, null, client.getUserId());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -309,9 +309,21 @@ module.exports = React.createClass({
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            } else if (room) {
 | 
					            } else if (room) {
 | 
				
			||||||
 | 
					                //viewing a previously joined room, try to lazy load members
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                // Stop peeking because we have joined this room previously
 | 
					                // Stop peeking because we have joined this room previously
 | 
				
			||||||
                MatrixClientPeg.get().stopPeeking();
 | 
					                MatrixClientPeg.get().stopPeeking();
 | 
				
			||||||
                this.setState({isPeeking: false});
 | 
					                this.setState({isPeeking: false});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // lazy load members if enabled
 | 
				
			||||||
 | 
					                if (SettingsStore.isFeatureEnabled('feature_lazyloading')) {
 | 
				
			||||||
 | 
					                    room.loadMembersIfNeeded().catch((err) => {
 | 
				
			||||||
 | 
					                        const errorMessage = `Fetching room members for ${this.roomId} failed.` +
 | 
				
			||||||
 | 
					                            " Room members will appear incomplete.";
 | 
				
			||||||
 | 
					                        console.error(errorMessage);
 | 
				
			||||||
 | 
					                        console.error(err);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -746,40 +758,13 @@ module.exports = React.createClass({
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _updateDMState() {
 | 
					    _updateDMState() {
 | 
				
			||||||
        const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId);
 | 
					        const room = this.state.room;
 | 
				
			||||||
        if (!me || me.membership !== "join") {
 | 
					        if (room.getMyMembership() != "join") {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        const dmInviter = room.getDMInviter();
 | 
				
			||||||
        // The user may have accepted an invite with is_direct set
 | 
					        if (dmInviter) {
 | 
				
			||||||
        if (me.events.member.getPrevContent().membership === "invite" &&
 | 
					            Rooms.setDMRoom(room.roomId, dmInviter);
 | 
				
			||||||
            me.events.member.getPrevContent().is_direct
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
            // This is a DM with the sender of the invite event (which we assume
 | 
					 | 
				
			||||||
            // preceded the join event)
 | 
					 | 
				
			||||||
            Rooms.setDMRoom(
 | 
					 | 
				
			||||||
                this.state.room.roomId,
 | 
					 | 
				
			||||||
                me.events.member.getUnsigned().prev_sender,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const invitedMembers = this.state.room.getMembersWithMembership("invite");
 | 
					 | 
				
			||||||
        const joinedMembers = this.state.room.getMembersWithMembership("join");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // There must be one invited member and one joined member
 | 
					 | 
				
			||||||
        if (invitedMembers.length !== 1 || joinedMembers.length !== 1) {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // The user may have sent an invite with is_direct sent
 | 
					 | 
				
			||||||
        const other = invitedMembers[0];
 | 
					 | 
				
			||||||
        if (other &&
 | 
					 | 
				
			||||||
            other.membership === "invite" &&
 | 
					 | 
				
			||||||
            other.events.member.getContent().is_direct
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
            Rooms.setDMRoom(this.state.room.roomId, other.userId);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -844,8 +844,16 @@ module.exports = React.createClass({
 | 
				
			||||||
        SettingsStore.getLabsFeatures().forEach((featureId) => {
 | 
					        SettingsStore.getLabsFeatures().forEach((featureId) => {
 | 
				
			||||||
            // TODO: this ought to be a separate component so that we don't need
 | 
					            // TODO: this ought to be a separate component so that we don't need
 | 
				
			||||||
            // to rebind the onChange each time we render
 | 
					            // to rebind the onChange each time we render
 | 
				
			||||||
            const onChange = (e) => {
 | 
					            const onChange = async (e) => {
 | 
				
			||||||
                SettingsStore.setFeatureEnabled(featureId, e.target.checked);
 | 
					                const checked = e.target.checked;
 | 
				
			||||||
 | 
					                if (featureId === "feature_lazyloading") {
 | 
				
			||||||
 | 
					                    const confirmed = await this._onLazyLoadChanging(checked);
 | 
				
			||||||
 | 
					                    if (!confirmed) {
 | 
				
			||||||
 | 
					                        e.preventDefault();
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                await SettingsStore.setFeatureEnabled(featureId, checked);
 | 
				
			||||||
                this.forceUpdate();
 | 
					                this.forceUpdate();
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -855,7 +863,7 @@ module.exports = React.createClass({
 | 
				
			||||||
                        type="checkbox"
 | 
					                        type="checkbox"
 | 
				
			||||||
                        id={featureId}
 | 
					                        id={featureId}
 | 
				
			||||||
                        name={featureId}
 | 
					                        name={featureId}
 | 
				
			||||||
                        defaultChecked={SettingsStore.isFeatureEnabled(featureId)}
 | 
					                        checked={SettingsStore.isFeatureEnabled(featureId)}
 | 
				
			||||||
                        onChange={onChange}
 | 
					                        onChange={onChange}
 | 
				
			||||||
                    />
 | 
					                    />
 | 
				
			||||||
                    <label htmlFor={featureId}>{ SettingsStore.getDisplayName(featureId) }</label>
 | 
					                    <label htmlFor={featureId}>{ SettingsStore.getDisplayName(featureId) }</label>
 | 
				
			||||||
| 
						 | 
					@ -878,6 +886,30 @@ module.exports = React.createClass({
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _onLazyLoadChanging: async function(enabling) {
 | 
				
			||||||
 | 
					        // don't prevent turning LL off when not supported
 | 
				
			||||||
 | 
					        if (enabling) {
 | 
				
			||||||
 | 
					            const supported = await MatrixClientPeg.get().doesServerSupportLazyLoading();
 | 
				
			||||||
 | 
					            if (!supported) {
 | 
				
			||||||
 | 
					                await new Promise((resolve) => {
 | 
				
			||||||
 | 
					                    const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
 | 
				
			||||||
 | 
					                    Modal.createDialog(QuestionDialog, {
 | 
				
			||||||
 | 
					                        title: _t("Lazy loading members not supported"),
 | 
				
			||||||
 | 
					                        description:
 | 
				
			||||||
 | 
					                            <div>
 | 
				
			||||||
 | 
					                         { _t("Lazy loading is not supported by your " +
 | 
				
			||||||
 | 
					                            "current homeserver.") }
 | 
				
			||||||
 | 
					                            </div>,
 | 
				
			||||||
 | 
					                        button: _t("OK"),
 | 
				
			||||||
 | 
					                        onFinished: resolve,
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _renderDeactivateAccount: function() {
 | 
					    _renderDeactivateAccount: function() {
 | 
				
			||||||
        return <div>
 | 
					        return <div>
 | 
				
			||||||
            <h3>{ _t("Deactivate Account") }</h3>
 | 
					            <h3>{ _t("Deactivate Account") }</h3>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,8 @@ export default class ChatCreateOrReuseDialog extends React.Component {
 | 
				
			||||||
        for (const roomId of dmRooms) {
 | 
					        for (const roomId of dmRooms) {
 | 
				
			||||||
            const room = client.getRoom(roomId);
 | 
					            const room = client.getRoom(roomId);
 | 
				
			||||||
            if (room) {
 | 
					            if (room) {
 | 
				
			||||||
                const me = room.getMember(client.credentials.userId);
 | 
					                const isInvite = room.getMyMembership() === "invite";
 | 
				
			||||||
                const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === "invite";
 | 
					                const highlight = room.getUnreadNotificationCount('highlight') > 0 || isInvite;
 | 
				
			||||||
                tiles.push(
 | 
					                tiles.push(
 | 
				
			||||||
                    <RoomTile key={room.roomId} room={room}
 | 
					                    <RoomTile key={room.roomId} room={room}
 | 
				
			||||||
                        transparent={true}
 | 
					                        transparent={true}
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
 | 
				
			||||||
                        selected={false}
 | 
					                        selected={false}
 | 
				
			||||||
                        unread={Unread.doesRoomHaveUnreadMessages(room)}
 | 
					                        unread={Unread.doesRoomHaveUnreadMessages(room)}
 | 
				
			||||||
                        highlight={highlight}
 | 
					                        highlight={highlight}
 | 
				
			||||||
                        isInvite={me.membership === "invite"}
 | 
					                        isInvite={isInvite}
 | 
				
			||||||
                        onClick={this.onRoomTileClick}
 | 
					                        onClick={this.onRoomTileClick}
 | 
				
			||||||
                    />,
 | 
					                    />,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,6 +187,9 @@ const Pill = React.createClass({
 | 
				
			||||||
                getContent: () => {
 | 
					                getContent: () => {
 | 
				
			||||||
                    return {avatar_url: resp.avatar_url};
 | 
					                    return {avatar_url: resp.avatar_url};
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                getDirectionalContent: function() {
 | 
				
			||||||
 | 
					                    return this.getContent();
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            this.setState({member});
 | 
					            this.setState({member});
 | 
				
			||||||
        }).catch((err) => {
 | 
					        }).catch((err) => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -598,7 +598,7 @@ module.exports = withMatrixClient(React.createClass({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onMemberAvatarClick: function() {
 | 
					    onMemberAvatarClick: function() {
 | 
				
			||||||
        const member = this.props.member;
 | 
					        const member = this.props.member;
 | 
				
			||||||
        const avatarUrl = member.user ? member.user.avatarUrl : member.events.member.getContent().avatar_url;
 | 
					        const avatarUrl = member.getMxcAvatarUrl();
 | 
				
			||||||
        if (!avatarUrl) return;
 | 
					        if (!avatarUrl) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
 | 
					        const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
 | 
				
			||||||
| 
						 | 
					@ -774,15 +774,15 @@ module.exports = withMatrixClient(React.createClass({
 | 
				
			||||||
            for (const roomId of dmRooms) {
 | 
					            for (const roomId of dmRooms) {
 | 
				
			||||||
                const room = this.props.matrixClient.getRoom(roomId);
 | 
					                const room = this.props.matrixClient.getRoom(roomId);
 | 
				
			||||||
                if (room) {
 | 
					                if (room) {
 | 
				
			||||||
                    const me = room.getMember(this.props.matrixClient.credentials.userId);
 | 
					                    const myMembership = room.getMyMembership();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // not a DM room if we have are not joined
 | 
					                    // not a DM room if we have are not joined
 | 
				
			||||||
                    if (!me.membership || me.membership !== 'join') continue;
 | 
					                    if (myMembership !== 'join') continue;
 | 
				
			||||||
                    // not a DM room if they are not joined
 | 
					                    
 | 
				
			||||||
                    const them = this.props.member;
 | 
					                    const them = this.props.member;
 | 
				
			||||||
 | 
					                    // not a DM room if they are not joined
 | 
				
			||||||
                    if (!them.membership || them.membership !== 'join') continue;
 | 
					                    if (!them.membership || them.membership !== 'join') continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite';
 | 
					                    const highlight = room.getUnreadNotificationCount('highlight') > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    tiles.push(
 | 
					                    tiles.push(
 | 
				
			||||||
                        <RoomTile key={room.roomId} room={room}
 | 
					                        <RoomTile key={room.roomId} room={room}
 | 
				
			||||||
| 
						 | 
					@ -791,7 +791,7 @@ module.exports = withMatrixClient(React.createClass({
 | 
				
			||||||
                            selected={false}
 | 
					                            selected={false}
 | 
				
			||||||
                            unread={Unread.doesRoomHaveUnreadMessages(room)}
 | 
					                            unread={Unread.doesRoomHaveUnreadMessages(room)}
 | 
				
			||||||
                            highlight={highlight}
 | 
					                            highlight={highlight}
 | 
				
			||||||
                            isInvite={me.membership === "invite"}
 | 
					                            isInvite={false}
 | 
				
			||||||
                            onClick={this.onRoomTileClick}
 | 
					                            onClick={this.onRoomTileClick}
 | 
				
			||||||
                        />,
 | 
					                        />,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -347,8 +347,8 @@ module.exports = React.createClass({
 | 
				
			||||||
                if (!taggedRoom) {
 | 
					                if (!taggedRoom) {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                const me = taggedRoom.getMember(MatrixClientPeg.get().credentials.userId);
 | 
					                const myUserId = MatrixClientPeg.get().getUserId();
 | 
				
			||||||
                if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, me, this.props.ConferenceHandler)) {
 | 
					                if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, myUserId, this.props.ConferenceHandler)) {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,15 +98,11 @@ module.exports = React.createClass({
 | 
				
			||||||
            </div>);
 | 
					            </div>);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const myMember = this.props.room ? this.props.room.currentState.members[
 | 
					        const myMember = this.props.room ?
 | 
				
			||||||
            MatrixClientPeg.get().credentials.userId
 | 
					            this.props.room.getMember(MatrixClientPeg.get().getUserId()) :
 | 
				
			||||||
        ] : null;
 | 
					            null;
 | 
				
			||||||
        const kicked = (
 | 
					        const kicked = myMember && myMember.isKicked();
 | 
				
			||||||
            myMember &&
 | 
					        const banned = myMember && myMember && myMember.membership == 'ban';
 | 
				
			||||||
            myMember.membership == 'leave' &&
 | 
					 | 
				
			||||||
            myMember.events.member.getSender() != MatrixClientPeg.get().credentials.userId
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        const banned = myMember && myMember.membership == 'ban';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.props.inviterName) {
 | 
					        if (this.props.inviterName) {
 | 
				
			||||||
            let emailMatchBlock;
 | 
					            let emailMatchBlock;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,9 +243,7 @@ module.exports = React.createClass({
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render: function() {
 | 
					    render: function() {
 | 
				
			||||||
        const myUserId = MatrixClientPeg.get().credentials.userId;
 | 
					        const isInvite = this.props.room.getMyMembership() === "invite";
 | 
				
			||||||
        const me = this.props.room.currentState.members[myUserId];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const notificationCount = this.state.notificationCount;
 | 
					        const notificationCount = this.state.notificationCount;
 | 
				
			||||||
        // var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
 | 
					        // var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -259,7 +257,7 @@ module.exports = React.createClass({
 | 
				
			||||||
            'mx_RoomTile_unread': this.props.unread,
 | 
					            'mx_RoomTile_unread': this.props.unread,
 | 
				
			||||||
            'mx_RoomTile_unreadNotify': notifBadges,
 | 
					            'mx_RoomTile_unreadNotify': notifBadges,
 | 
				
			||||||
            'mx_RoomTile_highlight': mentionBadges,
 | 
					            'mx_RoomTile_highlight': mentionBadges,
 | 
				
			||||||
            'mx_RoomTile_invited': (me && me.membership === 'invite'),
 | 
					            'mx_RoomTile_invited': isInvite,
 | 
				
			||||||
            'mx_RoomTile_menuDisplayed': this.state.menuDisplayed,
 | 
					            'mx_RoomTile_menuDisplayed': this.state.menuDisplayed,
 | 
				
			||||||
            'mx_RoomTile_noBadges': !badges,
 | 
					            'mx_RoomTile_noBadges': !badges,
 | 
				
			||||||
            'mx_RoomTile_transparent': this.props.transparent,
 | 
					            'mx_RoomTile_transparent': this.props.transparent,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,27 +43,26 @@ export function markAllDevicesKnown(matrixClient, devices) {
 | 
				
			||||||
 * @return {Promise} A promise which resolves to a map userId->deviceId->{@link
 | 
					 * @return {Promise} A promise which resolves to a map userId->deviceId->{@link
 | 
				
			||||||
 * module:crypto~DeviceInfo|DeviceInfo}.
 | 
					 * module:crypto~DeviceInfo|DeviceInfo}.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function getUnknownDevicesForRoom(matrixClient, room) {
 | 
					export async function getUnknownDevicesForRoom(matrixClient, room) {
 | 
				
			||||||
    const roomMembers = room.getEncryptionTargetMembers().map((m) => {
 | 
					    const roomMembers = await room.getEncryptionTargetMembers().map((m) => {
 | 
				
			||||||
        return m.userId;
 | 
					        return m.userId;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return matrixClient.downloadKeys(roomMembers, false).then((devices) => {
 | 
					    const devices = await matrixClient.downloadKeys(roomMembers, false);
 | 
				
			||||||
        const unknownDevices = {};
 | 
					    const unknownDevices = {};
 | 
				
			||||||
        // This is all devices in this room, so find the unknown ones.
 | 
					    // This is all devices in this room, so find the unknown ones.
 | 
				
			||||||
        Object.keys(devices).forEach((userId) => {
 | 
					    Object.keys(devices).forEach((userId) => {
 | 
				
			||||||
            Object.keys(devices[userId]).map((deviceId) => {
 | 
					        Object.keys(devices[userId]).map((deviceId) => {
 | 
				
			||||||
                const device = devices[userId][deviceId];
 | 
					            const device = devices[userId][deviceId];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (device.isUnverified() && !device.isKnown()) {
 | 
					            if (device.isUnverified() && !device.isKnown()) {
 | 
				
			||||||
                    if (unknownDevices[userId] === undefined) {
 | 
					                if (unknownDevices[userId] === undefined) {
 | 
				
			||||||
                        unknownDevices[userId] = {};
 | 
					                    unknownDevices[userId] = {};
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    unknownDevices[userId][deviceId] = device;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            });
 | 
					                unknownDevices[userId][deviceId] = device;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        return unknownDevices;
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    return unknownDevices;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function focusComposer() {
 | 
					function focusComposer() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1231,5 +1231,8 @@
 | 
				
			||||||
    "Import": "Import",
 | 
					    "Import": "Import",
 | 
				
			||||||
    "Failed to set direct chat tag": "Failed to set direct chat tag",
 | 
					    "Failed to set direct chat tag": "Failed to set direct chat tag",
 | 
				
			||||||
    "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
 | 
					    "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
 | 
				
			||||||
    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room"
 | 
					    "Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room",
 | 
				
			||||||
 | 
					    "Increase performance by only loading room members on first view": "Increase performance by only loading room members on first view",
 | 
				
			||||||
 | 
					    "Lazy loading members not supported": "Lazy load members not supported",
 | 
				
			||||||
 | 
					    "Lazy loading is not supported by your current homeserver.": "Lazy loading is not supported by your current homeserver."
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ import {
 | 
				
			||||||
    NotificationBodyEnabledController,
 | 
					    NotificationBodyEnabledController,
 | 
				
			||||||
    NotificationsEnabledController,
 | 
					    NotificationsEnabledController,
 | 
				
			||||||
} from "./controllers/NotificationControllers";
 | 
					} from "./controllers/NotificationControllers";
 | 
				
			||||||
 | 
					import LazyLoadingController from "./controllers/LazyLoadingController";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
 | 
					// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
 | 
				
			||||||
const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config'];
 | 
					const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config'];
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,13 @@ export const SETTINGS = {
 | 
				
			||||||
        supportedLevels: LEVELS_FEATURE,
 | 
					        supportedLevels: LEVELS_FEATURE,
 | 
				
			||||||
        default: false,
 | 
					        default: false,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "feature_lazyloading": {
 | 
				
			||||||
 | 
					        isFeature: true,
 | 
				
			||||||
 | 
					        displayName: _td("Increase performance by only loading room members on first view"),
 | 
				
			||||||
 | 
					        supportedLevels: LEVELS_FEATURE,
 | 
				
			||||||
 | 
					        controller: new LazyLoadingController(),
 | 
				
			||||||
 | 
					        default: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "MessageComposerInput.dontSuggestEmoji": {
 | 
					    "MessageComposerInput.dontSuggestEmoji": {
 | 
				
			||||||
        supportedLevels: LEVELS_ACCOUNT_SETTINGS,
 | 
					        supportedLevels: LEVELS_ACCOUNT_SETTINGS,
 | 
				
			||||||
        displayName: _td('Disable Emoji suggestions while typing'),
 | 
					        displayName: _td('Disable Emoji suggestions while typing'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,7 +248,7 @@ export default class SettingsStore {
 | 
				
			||||||
        if (actualValue !== undefined && actualValue !== null) return actualValue;
 | 
					        if (actualValue !== undefined && actualValue !== null) return actualValue;
 | 
				
			||||||
        return calculatedValue;
 | 
					        return calculatedValue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /* eslint-disable valid-jsdoc */    //https://github.com/eslint/eslint/issues/7307
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Sets the value for a setting. The room ID is optional if the setting is not being
 | 
					     * Sets the value for a setting. The room ID is optional if the setting is not being
 | 
				
			||||||
     * set for a particular room, otherwise it should be supplied. The value may be null
 | 
					     * set for a particular room, otherwise it should be supplied. The value may be null
 | 
				
			||||||
| 
						 | 
					@ -260,7 +260,8 @@ export default class SettingsStore {
 | 
				
			||||||
     * @param {*} value The new value of the setting, may be null.
 | 
					     * @param {*} value The new value of the setting, may be null.
 | 
				
			||||||
     * @return {Promise} Resolves when the setting has been changed.
 | 
					     * @return {Promise} Resolves when the setting has been changed.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static setValue(settingName, roomId, level, value) {
 | 
					    /* eslint-enable valid-jsdoc */
 | 
				
			||||||
 | 
					    static async setValue(settingName, roomId, level, value) {
 | 
				
			||||||
        // Verify that the setting is actually a setting
 | 
					        // Verify that the setting is actually a setting
 | 
				
			||||||
        if (!SETTINGS[settingName]) {
 | 
					        if (!SETTINGS[settingName]) {
 | 
				
			||||||
            throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
 | 
					            throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
 | 
				
			||||||
| 
						 | 
					@ -275,11 +276,12 @@ export default class SettingsStore {
 | 
				
			||||||
            throw new Error("User cannot set " + settingName + " at " + level + " in " + roomId);
 | 
					            throw new Error("User cannot set " + settingName + " at " + level + " in " + roomId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return handler.setValue(settingName, roomId, value).then(() => {
 | 
					        await handler.setValue(settingName, roomId, value);
 | 
				
			||||||
            const controller = SETTINGS[settingName].controller;
 | 
					
 | 
				
			||||||
            if (!controller) return;
 | 
					        const controller = SETTINGS[settingName].controller;
 | 
				
			||||||
 | 
					        if (controller) {
 | 
				
			||||||
            controller.onChange(level, roomId, value);
 | 
					            controller.onChange(level, roomId, value);
 | 
				
			||||||
        });
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2018 New Vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import SettingController from "./SettingController";
 | 
				
			||||||
 | 
					import MatrixClientPeg from "../../MatrixClientPeg";
 | 
				
			||||||
 | 
					import PlatformPeg from "../../PlatformPeg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class LazyLoadingController extends SettingController {
 | 
				
			||||||
 | 
					    async onChange(level, roomId, newValue) {
 | 
				
			||||||
 | 
					        if (!PlatformPeg.get()) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MatrixClientPeg.get().stopClient();
 | 
				
			||||||
 | 
					        await MatrixClientPeg.get().store.deleteAllData();
 | 
				
			||||||
 | 
					        PlatformPeg.get().reload();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -175,13 +175,13 @@ class RoomListStore extends Store {
 | 
				
			||||||
        if (!this._matrixClient) return;
 | 
					        if (!this._matrixClient) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._matrixClient.getRooms().forEach((room, index) => {
 | 
					        this._matrixClient.getRooms().forEach((room, index) => {
 | 
				
			||||||
            const me = room.getMember(this._matrixClient.credentials.userId);
 | 
					            const myUserId = this._matrixClient.getUserId();
 | 
				
			||||||
            if (!me) return;
 | 
					            const membership = room.getMyMembership();
 | 
				
			||||||
 | 
					            const me = room.getMember(myUserId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (me.membership == "invite") {
 | 
					            if (membership == "invite") {
 | 
				
			||||||
                lists["im.vector.fake.invite"].push(room);
 | 
					                lists["im.vector.fake.invite"].push(room);
 | 
				
			||||||
            } else if (me.membership == "join" || me.membership === "ban" ||
 | 
					            } else if (membership == "join" || membership === "ban" || (me && me.isKicked())) {
 | 
				
			||||||
                     (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) {
 | 
					 | 
				
			||||||
                // Used to split rooms via tags
 | 
					                // Used to split rooms via tags
 | 
				
			||||||
                let tagNames = Object.keys(room.tags);
 | 
					                let tagNames = Object.keys(room.tags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,10 +213,10 @@ class RoomListStore extends Store {
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    lists["im.vector.fake.recent"].push(room);
 | 
					                    lists["im.vector.fake.recent"].push(room);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else if (me.membership === "leave") {
 | 
					            } else if (membership === "leave") {
 | 
				
			||||||
                lists["im.vector.fake.archived"].push(room);
 | 
					                lists["im.vector.fake.archived"].push(room);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                console.error("unrecognised membership: " + me.membership + " - this should never happen");
 | 
					                console.error("unrecognised membership: " + membership + " - this should never happen");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,14 +97,7 @@ export default class DMRoomMap {
 | 
				
			||||||
            // no entry? if the room is an invite, look for the is_direct hint.
 | 
					            // no entry? if the room is an invite, look for the is_direct hint.
 | 
				
			||||||
            const room = this.matrixClient.getRoom(roomId);
 | 
					            const room = this.matrixClient.getRoom(roomId);
 | 
				
			||||||
            if (room) {
 | 
					            if (room) {
 | 
				
			||||||
                const me = room.getMember(this.matrixClient.credentials.userId);
 | 
					                return room.getDMInviter();
 | 
				
			||||||
                if (me.membership == 'invite') {
 | 
					 | 
				
			||||||
                    // The 'direct' hihnt is there, so declare that this is a DM room for
 | 
					 | 
				
			||||||
                    // whoever invited us.
 | 
					 | 
				
			||||||
                    if (me.events.member.getContent().is_direct) {
 | 
					 | 
				
			||||||
                        return me.events.member.getSender();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return this.roomToUser[roomId];
 | 
					        return this.roomToUser[roomId];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,8 +77,7 @@ export default class WidgetUtils {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const member = room.getMember(me);
 | 
					        if (room.getMyMembership() !== "join") {
 | 
				
			||||||
        if (!member || member.membership !== "join") {
 | 
					 | 
				
			||||||
            console.warn(`User ${me} is not in room ${roomId}`);
 | 
					            console.warn(`User ${me} is not in room ${roomId}`);
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,21 +14,22 @@ import dis from '../../../../src/dispatcher';
 | 
				
			||||||
import DMRoomMap from '../../../../src/utils/DMRoomMap.js';
 | 
					import DMRoomMap from '../../../../src/utils/DMRoomMap.js';
 | 
				
			||||||
import GroupStore from '../../../../src/stores/GroupStore.js';
 | 
					import GroupStore from '../../../../src/stores/GroupStore.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Room, RoomMember } from 'matrix-js-sdk';
 | 
					import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function generateRoomId() {
 | 
					function generateRoomId() {
 | 
				
			||||||
    return '!' + Math.random().toString().slice(2, 10) + ':domain';
 | 
					    return '!' + Math.random().toString().slice(2, 10) + ':domain';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createRoom(opts) {
 | 
					 | 
				
			||||||
    const room = new Room(generateRoomId());
 | 
					 | 
				
			||||||
    if (opts) {
 | 
					 | 
				
			||||||
        Object.assign(room, opts);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return room;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('RoomList', () => {
 | 
					describe('RoomList', () => {
 | 
				
			||||||
 | 
					    function createRoom(opts) {
 | 
				
			||||||
 | 
					        const room = new Room(generateRoomId(), null, client.getUserId());
 | 
				
			||||||
 | 
					        if (opts) {
 | 
				
			||||||
 | 
					            Object.assign(room, opts);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return room;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let parentDiv = null;
 | 
					    let parentDiv = null;
 | 
				
			||||||
    let sandbox = null;
 | 
					    let sandbox = null;
 | 
				
			||||||
    let client = null;
 | 
					    let client = null;
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,8 @@ describe('RoomList', () => {
 | 
				
			||||||
        sandbox = TestUtils.stubClient(sandbox);
 | 
					        sandbox = TestUtils.stubClient(sandbox);
 | 
				
			||||||
        client = MatrixClientPeg.get();
 | 
					        client = MatrixClientPeg.get();
 | 
				
			||||||
        client.credentials = {userId: myUserId};
 | 
					        client.credentials = {userId: myUserId};
 | 
				
			||||||
 | 
					        //revert this to prototype method as the test-utils monkey-patches this to return a hardcoded value
 | 
				
			||||||
 | 
					        client.getUserId = MatrixClient.prototype.getUserId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        clock = lolex.install();
 | 
					        clock = lolex.install();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue