Bug 1699093 - Show prompt for invites to Matrix DM rooms. r=clokep

Differential Revision: https://phabricator.services.mozilla.com/D116888

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Giger 2021-06-16 04:02:16 +00:00
Родитель bfe72fbdb8
Коммит 960f624137
3 изменённых файлов: 131 добавлений и 52 удалений

Просмотреть файл

@ -7,12 +7,9 @@ var EXPORTED_SYMBOLS = ["MatrixProtocol"];
const { clearTimeout, setTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
var {
XPCOMUtils,
EmptyEnumerator,
nsSimpleEnumerator,
l10nHelper,
} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
var { XPCOMUtils, nsSimpleEnumerator, l10nHelper } = ChromeUtils.import(
"resource:///modules/imXPCOMUtils.jsm"
);
var { Services } = ChromeUtils.import("resource:///modules/imServices.jsm");
var {
GenericAccountPrototype,
@ -215,6 +212,10 @@ MatrixBuddy.prototype = {
);
},
get canSendMessage() {
return true;
},
/**
* Initialize the buddy with a user.
*
@ -223,8 +224,7 @@ MatrixBuddy.prototype = {
setUser(user) {
this._user = user;
this._serverAlias = user.displayName;
this._statusType = getStatusFromPresence(user);
this._statusText = user.presenceStatusMsg ?? "";
this.setStatus(getStatusFromPresence(user), user.presenceStatusMsg ?? "");
},
/**
@ -252,6 +252,14 @@ MatrixBuddy.prototype = {
this._account.buddies.delete(this.userName);
GenericAccountBuddyPrototype.remove.call(this);
},
getTooltipInfo() {
return this._account.getBuddyInfo(this.userName);
},
createConversation() {
return this._account.getDirectConversation(this.userName);
},
};
/**
@ -839,31 +847,41 @@ MatrixRoom.prototype = {
initRoomDm(room) {
const dmUserId = room.guessDMUserId();
if (dmUserId === this._account.userId) {
// We are the only member of the room.
this._setInitialized();
// We are the only member of the room that we know of.
// This can sometimes happen when we get a room before all membership
// events got synced in.
return;
}
if (!this.buddy) {
if (this._account.buddies.has(dmUserId)) {
this.buddy = this._account.buddies.get(dmUserId);
if (!this.buddy._user) {
const user = this._account._client.getUser(dmUserId);
this.buddy.setUser(user);
}
return;
}
const user = this._account._client.getUser(dmUserId);
this.buddy = new MatrixBuddy(
this._account,
null,
Services.tags.defaultTag,
user
);
Services.contacts.accountBuddyAdded(this.buddy);
this._account.buddies.set(dmUserId, this.buddy);
this.initBuddy(dmUserId);
}
},
/**
* Initialize the buddy for this conversation.
*
* @param {string} dmUserId - MXID of the user on the other side of this DM.
*/
initBuddy(dmUserId) {
if (this._account.buddies.has(dmUserId)) {
this.buddy = this._account.buddies.get(dmUserId);
if (!this.buddy._user) {
const user = this._account._client.getUser(dmUserId);
this.buddy.setUser(user);
}
return;
}
const user = this._account._client.getUser(dmUserId);
this.buddy = new MatrixBuddy(
this._account,
null,
Services.tags.defaultTag,
user
);
Services.contacts.accountBuddyAdded(this.buddy);
this._account.buddies.set(dmUserId, this.buddy);
},
/**
* Clean up the buddy associated with this DM conversation if it is the last
* conversation associated with it.
@ -1258,23 +1276,7 @@ MatrixAccount.prototype = {
// For now just auto accept the invites by joining the room.
if (me && me.membership == "invite") {
if (me.events.member.getContent().is_direct) {
let roomMembers = room.getJoinedMembers();
// If there is just single user in the room, then set the
// room as a DM Room by adding it to dmMap in our user's accountData.
if (roomMembers.length == 1) {
let interlocutorId = roomMembers[0].userId;
this.setDirectRoom(interlocutorId, room.roomId);
// For the invited rooms, we will not get the summary info from
// the room object created after the joining. So we need to use
// the name from the room object here.
this.getDirectConversation(
interlocutorId,
room.roomId,
room.summary.info.title
);
} else {
this.getGroupConversation(room.roomId, room.summary.info.title);
}
this.invitedToDM(room);
} else {
this.getGroupConversation(room.roomId, room.summary.info.title);
}
@ -1399,6 +1401,37 @@ MatrixAccount.prototype = {
}
},
/**
* A user invited this user to a DM room.
*
* @param {Room} room - Room we're invited to.
*/
invitedToDM(room) {
let userId = room.getDMInviter();
this.addBuddyRequest(
userId,
() => {
this.setDirectRoom(userId, room.roomId);
// For the invited rooms, we will not get the summary info from
// the room object created after the joining. So we need to use
// the name from the room object here.
const conversation = this.getDirectConversation(
userId,
room.roomId,
room.summary.info.title
);
if (room.getInvitedAndJoinedMemberCount() !== 2) {
conversation.waitForRoom().then((conv) => {
conv.checkForUpdate();
});
}
},
() => {
this._client.leave(room.roomId);
}
);
},
/**
* Set the matrix user presence based on the given status info.
*
@ -1810,6 +1843,11 @@ MatrixAccount.prototype = {
})
.then(room => {
conv.initRoom(room);
// The membership events will sometimes be missing to initialize the
// buddy correctly in the normal room init.
if (!conv.buddy) {
conv.initBuddy(userId);
}
})
.catch(error => {
this.ERROR(
@ -1905,15 +1943,19 @@ MatrixAccount.prototype = {
return buddy;
},
requestBuddyInfo(aUserId) {
/**
* Get tooltip info for a user.
*
* @param {string} aUserId - MXID to get tooltip data for.
* @returns {Array<prplITooltipInfo>}
*/
getBuddyInfo(aUserId) {
if (!this.connected) {
return [];
}
let user = this._client.getUser(aUserId);
if (!user) {
Services.obs.notifyObservers(
EmptyEnumerator,
"user-info-received",
aUserId
);
return;
return [];
}
// Convert timespan in milli-seconds into a human-readable form.
@ -1969,8 +2011,12 @@ MatrixAccount.prototype = {
);
}
return tooltipInfo;
},
requestBuddyInfo(aUserId) {
Services.obs.notifyObservers(
new nsSimpleEnumerator(tooltipInfo),
new nsSimpleEnumerator(this.getBuddyInfo(aUserId)),
"user-info-received",
aUserId
);

Просмотреть файл

@ -66,6 +66,9 @@ function getClientRoom(roomId, clientHandler, client) {
isSpaceRoom() {
return false;
},
getLastActiveTimestamp() {
return Date.now();
},
},
makeProxyHandler(clientHandler)
);
@ -105,6 +108,7 @@ function getAccount(clientHandler) {
}
return this._rooms.get(roomId);
},
setAccountData(field, data) {},
},
makeProxyHandler(clientHandler)
);

Просмотреть файл

@ -295,6 +295,35 @@ add_task(async function test_getDMRoomIdsForUserId() {
equal(rooms[0], "!asdf:example.com");
});
add_task(async function test_invitedToDMIn_deny() {
const dmRoomId = "!test:example.com";
let leftRoom = false;
const account = getAccount({
leave(roomId) {
equal(roomId, dmRoomId);
leftRoom = true;
},
});
const room = getClientRoom(
dmRoomId,
{
getDMInviter() {
return "@other:example.com";
},
},
account._client
);
const requestObserver = TestUtils.topicObserved(
"buddy-authorization-request"
);
account.invitedToDM(room);
const [request] = await requestObserver;
request.QueryInterface(Ci.prplIBuddyRequest);
equal(request.userName, "@other:example.com");
request.deny();
ok(leftRoom);
});
function mockMatrixRoom(roomId) {
return {
getMyMembership() {