Add the "add friends view to room creation
This commit is contained in:
parent
bad4f2bc61
commit
b246a134e2
5 changed files with 204 additions and 39 deletions
|
|
@ -121,6 +121,14 @@
|
||||||
<div v-if="status">{{ status }}</div>
|
<div v-if="status">{{ status }}</div>
|
||||||
</div>
|
</div>
|
||||||
</v-fade-transition>
|
</v-fade-transition>
|
||||||
|
<input
|
||||||
|
ref="avatar"
|
||||||
|
type="file"
|
||||||
|
name="avatar"
|
||||||
|
@change="handlePickedAvatar($event)"
|
||||||
|
accept="image/*"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -239,7 +247,7 @@ export default {
|
||||||
this.$matrix.setCurrentRoomId(roomId);
|
this.$matrix.setCurrentRoomId(roomId);
|
||||||
this.$navigation.push(
|
this.$navigation.push(
|
||||||
{
|
{
|
||||||
name: "Invite"
|
name: "Invite",
|
||||||
},
|
},
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,66 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="create-room">
|
<div class="d-flex flex-column pa-4" style="overflow: hidden">
|
||||||
<div>
|
<div class="flex-grow-0 flex-shrink-0">
|
||||||
<v-container fluid>
|
<div class="room-name">Add Friends</div>
|
||||||
<div class="room-name">Add Friends</div>
|
<v-btn
|
||||||
<!-- <v-btn
|
:loading="loading"
|
||||||
text
|
text
|
||||||
class="header-button-left"
|
class="header-button-right"
|
||||||
v-show="$navigation && $navigation.canPop()"
|
@click.stop="done"
|
||||||
@click.stop="goBack"
|
>
|
||||||
>
|
<span>Done</span>
|
||||||
<v-icon>arrow_back</v-icon>
|
</v-btn>
|
||||||
<span>BACK</span>
|
|
||||||
</v-btn> -->
|
|
||||||
<v-btn text class="header-button-right" @click.stop="done">
|
|
||||||
<span>Done</span>
|
|
||||||
</v-btn>
|
|
||||||
</v-container>
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -27,9 +69,24 @@ import util from "../plugins/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Invite",
|
name: "Invite",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
status: "",
|
||||||
|
loading: false,
|
||||||
|
selectedMembers: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
done() {
|
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(
|
this.$navigation.push(
|
||||||
{
|
{
|
||||||
name: "Chat",
|
name: "Chat",
|
||||||
|
|
@ -38,6 +95,73 @@ export default {
|
||||||
-1
|
-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>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -65,14 +65,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getRoomJoinRule() {
|
getRoomJoinRule() {
|
||||||
if (this.room) {
|
return this.$matrix.getRoomJoinRule(this.room);
|
||||||
const joinRules = this.room.currentState.getStateEvents(
|
|
||||||
"m.room.join_rules",
|
|
||||||
""
|
|
||||||
);
|
|
||||||
return joinRules && joinRules.getContent().join_rule;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePermissions() {
|
updatePermissions() {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ const routes = [
|
||||||
component: Join
|
component: Join
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/invite',
|
path: '/invite/:roomId?',
|
||||||
name: 'Invite',
|
name: 'Invite',
|
||||||
component: () => import('../components/Invite.vue'),
|
component: () => import('../components/Invite.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
|
@ -92,6 +92,11 @@ router.beforeEach((to, from, next) => {
|
||||||
//Invite to public room
|
//Invite to public room
|
||||||
authRequired = false;
|
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
|
// trying to access a restricted page + not logged in
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem('user');
|
localStorage.removeItem('user');
|
||||||
this.$store.commit("setCurrentRoomId", null);
|
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 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) {
|
leaveRoom(roomId) {
|
||||||
return this.matrixClient.leave(roomId, undefined)
|
return this.matrixClient.leave(roomId, undefined)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
@ -398,15 +433,15 @@ export default {
|
||||||
};
|
};
|
||||||
const self = this;
|
const self = this;
|
||||||
return this.matrixClient.setPassword(authDict, newPassword)
|
return this.matrixClient.setPassword(authDict, newPassword)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Forget password and remove the 'is_guest' flag, we are now a "real" user!
|
// Forget password and remove the 'is_guest' flag, we are now a "real" user!
|
||||||
self.currentUser.password = undefined;
|
self.currentUser.password = undefined;
|
||||||
self.currentUser.is_guest = false;
|
self.currentUser.is_guest = false;
|
||||||
localStorage.setItem('user', JSON.stringify(self.currentUser));
|
localStorage.setItem('user', JSON.stringify(self.currentUser));
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue