diff --git a/src/components/CreateRoom.vue b/src/components/CreateRoom.vue index 5ad976e..d1a392d 100644 --- a/src/components/CreateRoom.vue +++ b/src/components/CreateRoom.vue @@ -121,6 +121,14 @@
{{ status }}
+ @@ -239,7 +247,7 @@ export default { this.$matrix.setCurrentRoomId(roomId); this.$navigation.push( { - name: "Invite" + name: "Invite", }, 1 ); diff --git a/src/components/Invite.vue b/src/components/Invite.vue index 3e0c079..1a0dd4a 100644 --- a/src/components/Invite.vue +++ b/src/components/Invite.vue @@ -1,24 +1,66 @@ @@ -27,9 +69,24 @@ import util from "../plugins/utils"; export default { name: "Invite", - + data() { + return { + status: "", + loading: false, + selectedMembers: [], + }; + }, methods: { done() { + if (this.selectedMembers.length > 0) { + this.loading = true; + this.sendInvite(0, this.selectedMembers.slice()); // Copy array! We remove stuff from original! + } else { + this.close(); + } + }, + + close() { this.$navigation.push( { name: "Chat", @@ -38,6 +95,73 @@ export default { -1 ); }, + + sendInvite(index, memberArray) { + if (index == memberArray.length) { + // Done. + this.loading = false; + if (this.selectedMembers.length > 0) { + // Error. + this.status = "Failed to invite one or or more friends!"; + } else { + this.status = ""; + this.close(); + } + return; + } + this.status = `Inviting friend ${index + 1} of ${memberArray.length}`; + const member = memberArray[index]; + + // Is this userId already a member of this room? In that case don't send an invite. + if (this.$matrix.currentRoom) { + const existingMember = this.$matrix.currentRoom.getMember( + member.userId + ); + if (existingMember && existingMember.membership === "join") { + this.unselectMember(member); + this.sendInvite(index + 1, memberArray); + return; + } + } + + this.$matrix.matrixClient + .invite(this.$matrix.currentRoomId, member.userId) + .then(() => { + // Successfully sent! Remove from array so that after all are sent, + // the "selectedMembers" array will only contain those that failed. + this.unselectMember(member); + }) + .catch((err) => { + console.log("Failed to invite:", err); + }) + .finally(() => { + this.sendInvite(index + 1, memberArray); + }); + }, + + unselectMember(member) { + const idx = this.selectedMembers.indexOf(member); + if (idx >= 0) { + this.selectedMembers.splice(idx, 1); + } + }, + + memberName(member) { + return member.user ? member.user.displayName : member.name; + }, + + memberAvatar(member) { + if (member) { + return member.getAvatarUrl( + this.$matrix.matrixClient.getHomeserverUrl(), + 40, + 40, + "scale", + true + ); + } + return null; + }, }, }; diff --git a/src/components/roomInfoMixin.js b/src/components/roomInfoMixin.js index a9e2a69..de8d4cf 100644 --- a/src/components/roomInfoMixin.js +++ b/src/components/roomInfoMixin.js @@ -65,14 +65,7 @@ export default { }, methods: { getRoomJoinRule() { - if (this.room) { - const joinRules = this.room.currentState.getStateEvents( - "m.room.join_rules", - "" - ); - return joinRules && joinRules.getContent().join_rule; - } - return null; + return this.$matrix.getRoomJoinRule(this.room); }, updatePermissions() { diff --git a/src/router/index.js b/src/router/index.js index ccac933..3c74d1c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -63,7 +63,7 @@ const routes = [ component: Join }, { - path: '/invite', + path: '/invite/:roomId?', name: 'Invite', component: () => import('../components/Invite.vue'), meta: { @@ -92,6 +92,11 @@ router.beforeEach((to, from, next) => { //Invite to public room authRequired = false; } + } else if (to.name == 'Invite') { + if (to.params.roomId) { + const roomId = util.sanitizeRoomId(to.params.roomId); + router.app.$matrix.setCurrentRoomId(roomId); + } } // trying to access a restricted page + not logged in diff --git a/src/services/matrix.service.js b/src/services/matrix.service.js index 1831d4d..d2bd115 100644 --- a/src/services/matrix.service.js +++ b/src/services/matrix.service.js @@ -314,7 +314,7 @@ export default { } else { localStorage.removeItem('user'); this.$store.commit("setCurrentRoomId", null); - this.$navigation.push({path: "/login"}, -1); + this.$navigation.push({ path: "/login" }, -1); } }, @@ -360,6 +360,41 @@ export default { return room || null; }, + /** + * Return all users we are in a "invite" only room with! + */ + getAllFriends() { + var ids = {}; + const ret = []; + for (const room of this.rooms) { + if (room._selfMembership == 'join') { // && this.getRoomJoinRule(room) == 'invite') { + for (const member of room.getJoinedMembers()) { + if (member.userId != this.currentUserId && !ids[member.userId]) { + ids[member.userId] = member; + ret.push(member); + } + } + } + } + ret.sort((a, b) => { + const aName = a.user ? a.user.displayName : a.name; + const bName = b.user ? b.user.displayName : b.name; + return aName.localeCompare(bName); + }); + return ret; + }, + + getRoomJoinRule(room) { + if (room) { + const joinRules = room.currentState.getStateEvents( + "m.room.join_rules", + "" + ); + return joinRules && joinRules.getContent().join_rule; + } + return null; + }, + leaveRoom(roomId) { return this.matrixClient.leave(roomId, undefined) .then(() => { @@ -398,15 +433,15 @@ export default { }; const self = this; return this.matrixClient.setPassword(authDict, newPassword) - .then(() => { - // Forget password and remove the 'is_guest' flag, we are now a "real" user! - self.currentUser.password = undefined; - self.currentUser.is_guest = false; - localStorage.setItem('user', JSON.stringify(self.currentUser)); - }) - .then(() => { - return true; - }) + .then(() => { + // Forget password and remove the 'is_guest' flag, we are now a "real" user! + self.currentUser.password = undefined; + self.currentUser.is_guest = false; + localStorage.setItem('user', JSON.stringify(self.currentUser)); + }) + .then(() => { + return true; + }) } return Promise.resolve(false); },