Merge pull request #2118 from matrix-org/bwindels/feature_lazyloading

Lazy loading of room members
This commit is contained in:
Bruno Windels 2018-08-16 18:14:55 +02:00 committed by GitHub
commit cead4096d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 191 additions and 137 deletions

View file

@ -309,9 +309,21 @@ module.exports = React.createClass({
}
});
} else if (room) {
//viewing a previously joined room, try to lazy load members
// Stop peeking because we have joined this room previously
MatrixClientPeg.get().stopPeeking();
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() {
const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId);
if (!me || me.membership !== "join") {
const room = this.state.room;
if (room.getMyMembership() != "join") {
return;
}
// The user may have accepted an invite with is_direct set
if (me.events.member.getPrevContent().membership === "invite" &&
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;
const dmInviter = room.getDMInviter();
if (dmInviter) {
Rooms.setDMRoom(room.roomId, dmInviter);
}
},

View file

@ -844,8 +844,16 @@ module.exports = React.createClass({
SettingsStore.getLabsFeatures().forEach((featureId) => {
// TODO: this ought to be a separate component so that we don't need
// to rebind the onChange each time we render
const onChange = (e) => {
SettingsStore.setFeatureEnabled(featureId, e.target.checked);
const onChange = async (e) => {
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();
};
@ -855,7 +863,7 @@ module.exports = React.createClass({
type="checkbox"
id={featureId}
name={featureId}
defaultChecked={SettingsStore.isFeatureEnabled(featureId)}
checked={SettingsStore.isFeatureEnabled(featureId)}
onChange={onChange}
/>
<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() {
return <div>
<h3>{ _t("Deactivate Account") }</h3>

View file

@ -54,8 +54,8 @@ export default class ChatCreateOrReuseDialog extends React.Component {
for (const roomId of dmRooms) {
const room = client.getRoom(roomId);
if (room) {
const me = room.getMember(client.credentials.userId);
const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === "invite";
const isInvite = room.getMyMembership() === "invite";
const highlight = room.getUnreadNotificationCount('highlight') > 0 || isInvite;
tiles.push(
<RoomTile key={room.roomId} room={room}
transparent={true}
@ -63,7 +63,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
selected={false}
unread={Unread.doesRoomHaveUnreadMessages(room)}
highlight={highlight}
isInvite={me.membership === "invite"}
isInvite={isInvite}
onClick={this.onRoomTileClick}
/>,
);

View file

@ -187,6 +187,9 @@ const Pill = React.createClass({
getContent: () => {
return {avatar_url: resp.avatar_url};
},
getDirectionalContent: function() {
return this.getContent();
},
};
this.setState({member});
}).catch((err) => {

View file

@ -598,7 +598,7 @@ module.exports = withMatrixClient(React.createClass({
onMemberAvatarClick: function() {
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;
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
@ -774,15 +774,15 @@ module.exports = withMatrixClient(React.createClass({
for (const roomId of dmRooms) {
const room = this.props.matrixClient.getRoom(roomId);
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
if (!me.membership || me.membership !== 'join') continue;
// not a DM room if they are not joined
if (myMembership !== 'join') continue;
const them = this.props.member;
// not a DM room if they are not joined
if (!them.membership || them.membership !== 'join') continue;
const highlight = room.getUnreadNotificationCount('highlight') > 0 || me.membership === 'invite';
const highlight = room.getUnreadNotificationCount('highlight') > 0;
tiles.push(
<RoomTile key={room.roomId} room={room}
@ -791,7 +791,7 @@ module.exports = withMatrixClient(React.createClass({
selected={false}
unread={Unread.doesRoomHaveUnreadMessages(room)}
highlight={highlight}
isInvite={me.membership === "invite"}
isInvite={false}
onClick={this.onRoomTileClick}
/>,
);

View file

@ -347,8 +347,8 @@ module.exports = React.createClass({
if (!taggedRoom) {
return;
}
const me = taggedRoom.getMember(MatrixClientPeg.get().credentials.userId);
if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, me, this.props.ConferenceHandler)) {
const myUserId = MatrixClientPeg.get().getUserId();
if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, myUserId, this.props.ConferenceHandler)) {
return;
}

View file

@ -98,15 +98,11 @@ module.exports = React.createClass({
</div>);
}
const myMember = this.props.room ? this.props.room.currentState.members[
MatrixClientPeg.get().credentials.userId
] : null;
const kicked = (
myMember &&
myMember.membership == 'leave' &&
myMember.events.member.getSender() != MatrixClientPeg.get().credentials.userId
);
const banned = myMember && myMember.membership == 'ban';
const myMember = this.props.room ?
this.props.room.getMember(MatrixClientPeg.get().getUserId()) :
null;
const kicked = myMember && myMember.isKicked();
const banned = myMember && myMember && myMember.membership == 'ban';
if (this.props.inviterName) {
let emailMatchBlock;

View file

@ -243,9 +243,7 @@ module.exports = React.createClass({
},
render: function() {
const myUserId = MatrixClientPeg.get().credentials.userId;
const me = this.props.room.currentState.members[myUserId];
const isInvite = this.props.room.getMyMembership() === "invite";
const notificationCount = this.state.notificationCount;
// var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
@ -259,7 +257,7 @@ module.exports = React.createClass({
'mx_RoomTile_unread': this.props.unread,
'mx_RoomTile_unreadNotify': notifBadges,
'mx_RoomTile_highlight': mentionBadges,
'mx_RoomTile_invited': (me && me.membership === 'invite'),
'mx_RoomTile_invited': isInvite,
'mx_RoomTile_menuDisplayed': this.state.menuDisplayed,
'mx_RoomTile_noBadges': !badges,
'mx_RoomTile_transparent': this.props.transparent,