Add the "add friends view to room creation

This commit is contained in:
N-Pex 2021-04-02 09:28:51 +02:00
parent bad4f2bc61
commit b246a134e2
5 changed files with 204 additions and 39 deletions

View file

@ -121,6 +121,14 @@
<div v-if="status">{{ status }}</div>
</div>
</v-fade-transition>
<input
ref="avatar"
type="file"
name="avatar"
@change="handlePickedAvatar($event)"
accept="image/*"
style="display: none"
/>
</div>
</template>
@ -239,7 +247,7 @@ export default {
this.$matrix.setCurrentRoomId(roomId);
this.$navigation.push(
{
name: "Invite"
name: "Invite",
},
1
);

View file

@ -1,24 +1,66 @@
<template>
<div class="create-room">
<div>
<v-container fluid>
<div class="room-name">Add Friends</div>
<!-- <v-btn
text
class="header-button-left"
v-show="$navigation && $navigation.canPop()"
@click.stop="goBack"
>
<v-icon>arrow_back</v-icon>
<span>BACK</span>
</v-btn> -->
<v-btn text class="header-button-right" @click.stop="done">
<span>Done</span>
</v-btn>
</v-container>
<div class="d-flex flex-column pa-4" style="overflow: hidden">
<div class="flex-grow-0 flex-shrink-0">
<div class="room-name">Add Friends</div>
<v-btn
:loading="loading"
text
class="header-button-right"
@click.stop="done"
>
<span>Done</span>
</v-btn>
</div>
<div>Not yet implemented</div>
<div
class="flex-grow-0 flex-shrink-0"
style="min-height: 100px; max-height: 30vh"
>
<div class="h4">Send invites to</div>
<div>{{ status }}</div>
<v-chip-group active-class="primary--text" column>
<v-chip
v-for="member in selectedMembers"
:key="member.userId"
close
@click:close="unselectMember(member)"
>
{{ memberName(member) }}
</v-chip>
</v-chip-group>
</div>
<div class="flex-grow-1 flex-shrink-1">
<v-list class="member ma-2" style="overflow-y: auto">
<v-list-item-group multiple v-model="selectedMembers">
<v-list-item
v-for="member in $matrix.getAllFriends()"
:key="member.userId"
:value="member"
>
<template v-slot:default="{ active }">
<v-list-item-avatar color="grey">
<img v-if="memberAvatar(member)" :src="memberAvatar(member)" />
<span v-else class="white--text headline">{{
member.name.substring(0, 1).toUpperCase()
}}</span>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{ memberName(member) }}</v-list-item-title>
<v-list-item-subtitle
v-text="member.userId"
></v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn icon v-if="active">
<v-icon color="grey lighten-1">check</v-icon>
</v-btn>
</v-list-item-action>
</template>
</v-list-item>
</v-list-item-group>
</v-list>
</div>
</div>
</template>
@ -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;
},
},
};
</script>

View file

@ -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() {

View file

@ -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

View file

@ -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);
},