mirror of
				https://github.com/vector-im/element-web.git
				synced 2025-10-31 00:01:23 +01:00 
			
		
		
		
	Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
		
						commit
						abe6d72125
					
				| @ -144,26 +144,25 @@ function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTi | |||||||
| /** | /** | ||||||
|  * @typedef RoomMembershipAction |  * @typedef RoomMembershipAction | ||||||
|  * @type {Object} |  * @type {Object} | ||||||
|  * @property {string} action 'MatrixActions.RoomMember.membership'. |  * @property {string} action 'MatrixActions.Room.myMembership'. | ||||||
|  * @property {RoomMember} member the member whose membership was updated. |  * @property {Room} room to room for which the self-membership changed. | ||||||
|  |  * @property {string} membership the new membership | ||||||
|  |  * @property {string} oldMembership the previous membership, can be null. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Create a MatrixActions.Room.selfMembership action that represents |  * Create a MatrixActions.Room.myMembership action that represents | ||||||
|  * a MatrixClient `RoomMember.membership` matrix event for the syncing user, |  * a MatrixClient `Room.myMembership` event for the syncing user, | ||||||
|  * emitted when the member's membership is updated. |  * emitted when the syncing user's membership is updated for a room. | ||||||
|  * |  * | ||||||
|  * @param {MatrixClient} matrixClient the matrix client. |  * @param {MatrixClient} matrixClient the matrix client. | ||||||
|  * @param {MatrixEvent} membershipEvent the m.room.member event. |  * @param {Room} room to room for which the self-membership changed. | ||||||
|  * @param {RoomMember} member the member whose membership was updated. |  * @param {string} membership the new membership | ||||||
|  * @param {string} oldMembership the member's previous membership. |  * @param {string} oldMembership the previous membership, can be null. | ||||||
|  * @returns {RoomMembershipAction} an action of type `MatrixActions.RoomMember.membership`. |  * @returns {RoomMembershipAction} an action of type `MatrixActions.Room.myMembership`. | ||||||
|  */ |  */ | ||||||
| function createSelfRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) { | function createSelfMembershipAction(matrixClient, room, membership, oldMembership) { | ||||||
|     if (member.userId === matrixClient.getUserId()) { |     return { action: 'MatrixActions.Room.myMembership', room, membership, oldMembership}; | ||||||
|         return { action: 'MatrixActions.Room.selfMembership', member }; |  | ||||||
|     } |  | ||||||
|     return null; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -205,7 +204,7 @@ export default { | |||||||
|         this._addMatrixClientListener(matrixClient, 'Room', createRoomAction); |         this._addMatrixClientListener(matrixClient, 'Room', createRoomAction); | ||||||
|         this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); |         this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction); | ||||||
|         this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); |         this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction); | ||||||
|         this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createSelfRoomMembershipAction); |         this._addMatrixClientListener(matrixClient, 'Room.myMembership', createSelfMembershipAction); | ||||||
|         this._addMatrixClientListener(matrixClient, 'Event.decrypted', createEventDecryptedAction); |         this._addMatrixClientListener(matrixClient, 'Event.decrypted', createEventDecryptedAction); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -91,13 +91,16 @@ module.exports = React.createClass({ | |||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getInitialState: function() { |     getInitialState: function() { | ||||||
|  |         const llMembers = MatrixClientPeg.get().hasLazyLoadMembersEnabled(); | ||||||
|         return { |         return { | ||||||
|             room: null, |             room: null, | ||||||
|             roomId: null, |             roomId: null, | ||||||
|             roomLoading: true, |             roomLoading: true, | ||||||
|             peekLoading: false, |             peekLoading: false, | ||||||
|             shouldPeek: true, |             shouldPeek: true, | ||||||
| 
 |             // used to trigger a rerender in TimelinePanel once the members are loaded,
 | ||||||
|  |             // so RR are rendered again (now with the members available), ...
 | ||||||
|  |             membersLoaded: !llMembers, | ||||||
|             // The event to be scrolled to initially
 |             // The event to be scrolled to initially
 | ||||||
|             initialEventId: null, |             initialEventId: null, | ||||||
|             // The offset in pixels from the event with which to scroll vertically
 |             // The offset in pixels from the event with which to scroll vertically
 | ||||||
| @ -148,7 +151,7 @@ module.exports = React.createClass({ | |||||||
|         MatrixClientPeg.get().on("Room.name", this.onRoomName); |         MatrixClientPeg.get().on("Room.name", this.onRoomName); | ||||||
|         MatrixClientPeg.get().on("Room.accountData", this.onRoomAccountData); |         MatrixClientPeg.get().on("Room.accountData", this.onRoomAccountData); | ||||||
|         MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember); |         MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember); | ||||||
|         MatrixClientPeg.get().on("RoomMember.membership", this.onRoomMemberMembership); |         MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership); | ||||||
|         MatrixClientPeg.get().on("accountData", this.onAccountData); |         MatrixClientPeg.get().on("accountData", this.onAccountData); | ||||||
| 
 | 
 | ||||||
|         // Start listening for RoomViewStore updates
 |         // Start listening for RoomViewStore updates
 | ||||||
| @ -412,8 +415,8 @@ module.exports = React.createClass({ | |||||||
|             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); |             MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); | ||||||
|             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); |             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); | ||||||
|             MatrixClientPeg.get().removeListener("Room.accountData", this.onRoomAccountData); |             MatrixClientPeg.get().removeListener("Room.accountData", this.onRoomAccountData); | ||||||
|  |             MatrixClientPeg.get().removeListener("Room.myMembership", this.onMyMembership); | ||||||
|             MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); |             MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); | ||||||
|             MatrixClientPeg.get().removeListener("RoomMember.membership", this.onRoomMemberMembership); |  | ||||||
|             MatrixClientPeg.get().removeListener("accountData", this.onAccountData); |             MatrixClientPeg.get().removeListener("accountData", this.onAccountData); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -582,21 +585,25 @@ module.exports = React.createClass({ | |||||||
|         this._warnAboutEncryption(room); |         this._warnAboutEncryption(room); | ||||||
|         this._calculatePeekRules(room); |         this._calculatePeekRules(room); | ||||||
|         this._updatePreviewUrlVisibility(room); |         this._updatePreviewUrlVisibility(room); | ||||||
|         this._loadMembersIfJoined(); |         this._loadMembersIfJoined(room); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     _loadMembersIfJoined: function() { |     _loadMembersIfJoined: async function(room) { | ||||||
|         // lazy load members if enabled
 |         // lazy load members if enabled
 | ||||||
|         if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { |         const cli = MatrixClientPeg.get(); | ||||||
|             const cli = MatrixClientPeg.get(); |         if (cli.hasLazyLoadMembersEnabled()) { | ||||||
|             const room = cli.getRoom(this.state.roomId); |  | ||||||
|             if (room && room.getMyMembership() === 'join') { |             if (room && room.getMyMembership() === 'join') { | ||||||
|                 room.loadMembersIfNeeded().catch((err) => { |                 try { | ||||||
|  |                     await room.loadMembersIfNeeded(); | ||||||
|  |                     if (!this.unmounted) { | ||||||
|  |                         this.setState({membersLoaded: true}); | ||||||
|  |                     } | ||||||
|  |                 } catch (err) { | ||||||
|                     const errorMessage = `Fetching room members for ${room.roomId} failed.` + |                     const errorMessage = `Fetching room members for ${room.roomId} failed.` + | ||||||
|                         " Room members will appear incomplete."; |                         " Room members will appear incomplete."; | ||||||
|                     console.error(errorMessage); |                     console.error(errorMessage); | ||||||
|                     console.error(err); |                     console.error(err); | ||||||
|                 }); |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| @ -710,10 +717,10 @@ module.exports = React.createClass({ | |||||||
|         this._updateRoomMembers(); |         this._updateRoomMembers(); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     onRoomMemberMembership: function(ev, member, oldMembership) { |     onMyMembership: function(room, membership, oldMembership) { | ||||||
|         if (member.userId == MatrixClientPeg.get().credentials.userId) { |         if (room.roomId === this.state.roomId) { | ||||||
|             this._loadMembersIfJoined(); |  | ||||||
|             this.forceUpdate(); |             this.forceUpdate(); | ||||||
|  |             this._loadMembersIfJoined(room); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| @ -1761,6 +1768,7 @@ module.exports = React.createClass({ | |||||||
|                 onReadMarkerUpdated={this._updateTopUnreadMessagesBar} |                 onReadMarkerUpdated={this._updateTopUnreadMessagesBar} | ||||||
|                 showUrlPreview = {this.state.showUrlPreview} |                 showUrlPreview = {this.state.showUrlPreview} | ||||||
|                 className="mx_RoomView_messagePanel" |                 className="mx_RoomView_messagePanel" | ||||||
|  |                 membersLoaded={this.state.membersLoaded} | ||||||
|             />); |             />); | ||||||
| 
 | 
 | ||||||
|         let topUnreadMessagesBar = null; |         let topUnreadMessagesBar = null; | ||||||
|  | |||||||
| @ -34,20 +34,23 @@ module.exports = React.createClass({ | |||||||
|     getInitialState: function() { |     getInitialState: function() { | ||||||
|         const cli = MatrixClientPeg.get(); |         const cli = MatrixClientPeg.get(); | ||||||
|         if (cli.hasLazyLoadMembersEnabled()) { |         if (cli.hasLazyLoadMembersEnabled()) { | ||||||
|             return {loading: true}; |             // show an empty list
 | ||||||
|  |             return this._getMembersState([]); | ||||||
|         } else { |         } else { | ||||||
|             return this._getMembersState(); |             return this._getMembersState(this.roomMembers()); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     componentWillMount: function() { |     componentWillMount: function() { | ||||||
|         this._mounted = false; |         this._mounted = true; | ||||||
|         const cli = MatrixClientPeg.get(); |         const cli = MatrixClientPeg.get(); | ||||||
|         if (!cli.hasLazyLoadMembersEnabled()) { |         if (cli.hasLazyLoadMembersEnabled()) { | ||||||
|  |             this._showMembersAccordingToMembershipWithLL(); | ||||||
|  |             cli.on("Room.myMembership", this.onMyMembership); | ||||||
|  |         } else { | ||||||
|             this._listenForMembersChanges(); |             this._listenForMembersChanges(); | ||||||
|         } |         } | ||||||
|         cli.on("Room", this.onRoom); // invites & joining after peek
 |         cli.on("Room", this.onRoom); // invites & joining after peek
 | ||||||
|         cli.on("RoomMember.membership", this.onRoomMembership); // update when accepting an invite
 |  | ||||||
|         const enablePresenceByHsUrl = SdkConfig.get()["enable_presence_by_hs_url"]; |         const enablePresenceByHsUrl = SdkConfig.get()["enable_presence_by_hs_url"]; | ||||||
|         const hsUrl = MatrixClientPeg.get().baseUrl; |         const hsUrl = MatrixClientPeg.get().baseUrl; | ||||||
|         this._showPresence = true; |         this._showPresence = true; | ||||||
| @ -68,51 +71,50 @@ module.exports = React.createClass({ | |||||||
|         // cli.on("Room.timeline", this.onRoomTimeline);
 |         // cli.on("Room.timeline", this.onRoomTimeline);
 | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     componentDidMount: async function() { |  | ||||||
|         this._mounted = true; |  | ||||||
|         this._loadMembersIfNeeded(true); |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     componentWillUnmount: function() { |     componentWillUnmount: function() { | ||||||
|         this._mounted = false; |         this._mounted = false; | ||||||
|         const cli = MatrixClientPeg.get(); |         const cli = MatrixClientPeg.get(); | ||||||
|         if (cli) { |         if (cli) { | ||||||
|             cli.removeListener("RoomState.members", this.onRoomStateMember); |             cli.removeListener("RoomState.members", this.onRoomStateMember); | ||||||
|             cli.removeListener("RoomMember.name", this.onRoomMemberName); |             cli.removeListener("RoomMember.name", this.onRoomMemberName); | ||||||
|             cli.removeListener("RoomMember.membership", this.onRoomMembership); |             cli.removeListener("Room.myMembership", this.onMyMembership); | ||||||
|             cli.removeListener("RoomState.events", this.onRoomStateEvent); |             cli.removeListener("RoomState.events", this.onRoomStateEvent); | ||||||
|             cli.removeListener("Room", this.onRoom); |             cli.removeListener("Room", this.onRoom); | ||||||
|             cli.removeListener("User.lastPresenceTs", this.onUserLastPresenceTs); |             cli.removeListener("User.lastPresenceTs", this.onUserLastPresenceTs); | ||||||
|             // cli.removeListener("Room.timeline", this.onRoomTimeline);
 |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // cancel any pending calls to the rate_limited_funcs
 |         // cancel any pending calls to the rate_limited_funcs
 | ||||||
|         this._updateList.cancelPendingCall(); |         this._updateList.cancelPendingCall(); | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     _loadMembersIfNeeded: async function(initial) { |     /** | ||||||
|  |      * If lazy loading is enabled, either: | ||||||
|  |      * show a spinner and load the members if the user is joined, | ||||||
|  |      * or show the members available so far if the user is invited | ||||||
|  |      */ | ||||||
|  |     _showMembersAccordingToMembershipWithLL: async function() { | ||||||
|         const cli = MatrixClientPeg.get(); |         const cli = MatrixClientPeg.get(); | ||||||
|         if (cli.hasLazyLoadMembersEnabled()) { |         if (cli.hasLazyLoadMembersEnabled()) { | ||||||
|             const cli = MatrixClientPeg.get(); |             const cli = MatrixClientPeg.get(); | ||||||
|             const room = cli.getRoom(this.props.roomId); |             const room = cli.getRoom(this.props.roomId); | ||||||
|             if (room && room.getMyMembership() === 'join') { |             const membership = room && room.getMyMembership(); | ||||||
|  |             if (membership === "join") { | ||||||
|                 this.setState({loading: true}); |                 this.setState({loading: true}); | ||||||
|                 try { |                 try { | ||||||
|                     await room.loadMembersIfNeeded(); |                     await room.loadMembersIfNeeded(); | ||||||
|                 } catch(ex) {/* already logged in RoomView */} |                 } catch (ex) {/* already logged in RoomView */} | ||||||
|                 if (this._mounted) { |                 if (this._mounted) { | ||||||
|                     this.setState(this._getMembersState()); |                     this.setState(this._getMembersState(this.roomMembers())); | ||||||
|                     this._listenForMembersChanges(); |                     this._listenForMembersChanges(); | ||||||
|                 } |                 } | ||||||
|             } else if(initial) { |             } else if (membership === "invite") { | ||||||
|                 // show the members we've got
 |                 // show the members we've got when invited
 | ||||||
|                 this.setState(this._getMembersState()); |                 this.setState(this._getMembersState(this.roomMembers())); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     _getMembersState: function() { |     _getMembersState: function(members) { | ||||||
|         const members = this.roomMembers(); |  | ||||||
|         // set the state after determining _showPresence to make sure it's
 |         // set the state after determining _showPresence to make sure it's
 | ||||||
|         // taken into account while rerendering
 |         // taken into account while rerendering
 | ||||||
|         return { |         return { | ||||||
| @ -129,34 +131,6 @@ module.exports = React.createClass({ | |||||||
|         }; |         }; | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
|     onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) { |  | ||||||
|         // ignore anything but real-time updates at the end of the room:
 |  | ||||||
|         // updates from pagination will happen when the paginate completes.
 |  | ||||||
|         if (toStartOfTimeline || !data || !data.liveEvent) return; |  | ||||||
| 
 |  | ||||||
|         // treat any activity from a user as implicit presence to update the
 |  | ||||||
|         // ordering of the list whenever someone says something.
 |  | ||||||
|         // Except right now we're not tiebreaking "active now" users in this way
 |  | ||||||
|         // so don't bother for now.
 |  | ||||||
|         if (ev.getSender()) { |  | ||||||
|             // console.log("implicit presence from " + ev.getSender());
 |  | ||||||
| 
 |  | ||||||
|             var tile = this.refs[ev.getSender()]; |  | ||||||
|             if (tile) { |  | ||||||
|                 // work around a race where you might have a room member object
 |  | ||||||
|                 // before the user object exists.  XXX: why does this ever happen?
 |  | ||||||
|                 var all_members = room.currentState.members; |  | ||||||
|                 var userId = ev.getSender(); |  | ||||||
|                 if (all_members[userId].user === null) { |  | ||||||
|                     all_members[userId].user = MatrixClientPeg.get().getUser(userId); |  | ||||||
|                 } |  | ||||||
|                 this._updateList(); // reorder the membership list
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
|     onUserLastPresenceTs(event, user) { |     onUserLastPresenceTs(event, user) { | ||||||
|         // Attach a SINGLE listener for global presence changes then locate the
 |         // Attach a SINGLE listener for global presence changes then locate the
 | ||||||
|         // member tile and re-render it. This is more efficient than every tile
 |         // member tile and re-render it. This is more efficient than every tile
 | ||||||
| @ -175,20 +149,12 @@ module.exports = React.createClass({ | |||||||
|         // We listen for room events because when we accept an invite
 |         // We listen for room events because when we accept an invite
 | ||||||
|         // we need to wait till the room is fully populated with state
 |         // we need to wait till the room is fully populated with state
 | ||||||
|         // before refreshing the member list else we get a stale list.
 |         // before refreshing the member list else we get a stale list.
 | ||||||
| 
 |         this._showMembersAccordingToMembershipWithLL(); | ||||||
|         // also when peeking, we need to await the members being loaded
 |  | ||||||
|         // before showing them.
 |  | ||||||
| 
 |  | ||||||
|         this._loadMembersIfNeeded(); |  | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     onRoomMembership: function(ev, member, oldMembership) { |     onMyMembership: function(room, membership, oldMembership) { | ||||||
|         const cli = MatrixClientPeg.get(); |         if (room.roomId === this.props.roomId && membership === "join") { | ||||||
|         const myId = cli.getUserId(); |             this._showMembersAccordingToMembershipWithLL(); | ||||||
|         if (member.userId === myId && oldMembership !== "join" && member.membership === "join") { |  | ||||||
|             // once we've joined, no need to listen for membership anymore
 |  | ||||||
|             cli.removeListener("RoomMember.membership", this.onRoomMembership); |  | ||||||
|             this._loadMembersIfNeeded(); |  | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -120,7 +120,7 @@ class RoomListStore extends Store { | |||||||
|                 this._generateRoomLists(); |                 this._generateRoomLists(); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|             case 'MatrixActions.Room.selfMembership': { |             case 'MatrixActions.Room.myMembership': { | ||||||
|                 this._generateRoomLists(); |                 this._generateRoomLists(); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|  | |||||||
| @ -74,6 +74,7 @@ describe('RoomList', () => { | |||||||
|         // Mock joined member
 |         // Mock joined member
 | ||||||
|         myMember = new RoomMember(movingRoomId, myUserId); |         myMember = new RoomMember(movingRoomId, myUserId); | ||||||
|         myMember.membership = 'join'; |         myMember.membership = 'join'; | ||||||
|  |         movingRoom.updateMyMembership('join'); | ||||||
|         movingRoom.getMember = (userId) => ({ |         movingRoom.getMember = (userId) => ({ | ||||||
|             [client.credentials.userId]: myMember, |             [client.credentials.userId]: myMember, | ||||||
|         }[userId]); |         }[userId]); | ||||||
| @ -81,6 +82,7 @@ describe('RoomList', () => { | |||||||
|         otherRoom = createRoom({name: 'Other room'}); |         otherRoom = createRoom({name: 'Other room'}); | ||||||
|         myOtherMember = new RoomMember(otherRoom.roomId, myUserId); |         myOtherMember = new RoomMember(otherRoom.roomId, myUserId); | ||||||
|         myOtherMember.membership = 'join'; |         myOtherMember.membership = 'join'; | ||||||
|  |         otherRoom.updateMyMembership('join'); | ||||||
|         otherRoom.getMember = (userId) => ({ |         otherRoom.getMember = (userId) => ({ | ||||||
|             [client.credentials.userId]: myOtherMember, |             [client.credentials.userId]: myOtherMember, | ||||||
|         }[userId]); |         }[userId]); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user