Room details: add dialog to member list

This commit is contained in:
10G Meow 2024-03-03 21:08:06 +02:00 committed by N-Pex
parent eec0df7c97
commit cebda1686e
13 changed files with 341 additions and 202 deletions

View file

@ -922,8 +922,9 @@ body {
}
.room-info {
background-color: #e8e8e8;
background-color: #FDFBF9;
height: 100%;
.chat-header {
background-color: transparent;
border: none;
@ -978,6 +979,7 @@ body {
.v-card {
background-color: white;
border-radius: 20px;
box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.05) !important;
}
.member .user-name {
@ -994,6 +996,14 @@ body {
margin-left: 38px;
}
.member.v-list-item {
height: 56px;
&::before {
opacity: 0;
}
}
.show-all {
color: black;
font-size: 14 * $chat-text-size;
@ -1009,6 +1019,22 @@ body {
}
}
.member-action-dialog {
.user-name {
font-size: 18px;
font-weight: 700;
}
.v-list-item__title {
color:#074EE8;
font-size: 16px !important;
font-weight: 700 !important;
}
.v-list-item__subtitle {
color: rgba(0, 0, 0, 0.8);
font-size: 14px !important;
}
}
.with-right-label {
display: flex;
flex-wrap: nowrap;

View file

@ -0,0 +1,5 @@
<template>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.455 1.15172C17.5599 0.837267 17.478 0.490627 17.2437 0.256285C17.0093 0.0219423 16.6627 -0.0598701 16.3483 0.0449199L0.598305 5.29492C0.247955 5.41168 0.00864239 5.7359 0.000224888 6.10512C-0.00811491 6.4744 0.216175 6.80909 0.560907 6.94171L7.78123 9.71878L10.5583 16.9391C10.6909 17.2838 11.0255 17.5081 11.3948 17.4997C11.764 17.4914 12.0883 17.2521 12.205 16.9016L17.455 1.15172Z" fill="#242424"/>
</svg>
</template>

View file

@ -0,0 +1,6 @@
<template>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.25 7.875C4.76677 7.875 4.375 8.26677 4.375 8.75C4.375 9.23323 4.76677 9.625 5.25 9.625H12.25C12.7332 9.625 13.125 9.23323 13.125 8.75C13.125 8.26677 12.7332 7.875 12.25 7.875H5.25Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.75 0C3.91755 0 0 3.91755 0 8.75C0 13.5824 3.91755 17.5 8.75 17.5C13.5824 17.5 17.5 13.5824 17.5 8.75C17.5 3.91755 13.5824 0 8.75 0ZM1.75 8.75C1.75 4.88408 4.88408 1.75 8.75 1.75C12.6159 1.75 15.75 4.88408 15.75 8.75C15.75 12.6159 12.6159 15.75 8.75 15.75C4.88408 15.75 1.75 12.6159 1.75 8.75Z" fill="black"/>
</svg>
</template>

View file

@ -0,0 +1,5 @@
<template>
<svg width="18" height="14" viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.60303 0C8.39234 0 8.18549 0.0563288 8.00393 0.163173C7.82244 0.27002 7.67273 0.423416 7.5704 0.607586L5.39603 4.52146L1.661 2.8615C1.46003 2.77215 1.23813 2.74071 1.02028 2.77072C0.802418 2.80066 0.597196 2.89083 0.427813 3.0311C0.258487 3.17137 0.131608 3.35614 0.0615383 3.56457C-0.00852994 3.77306 -0.0189897 3.99694 0.0313228 4.21104L1.90995 12.2092L1.91022 12.2105C1.947 12.3656 2.01481 12.5117 2.10949 12.64C2.20431 12.7683 2.32401 12.876 2.46147 12.9568C2.59887 13.0376 2.75131 13.0898 2.90944 13.1101C3.06694 13.1304 3.22683 13.1188 3.37968 13.0759C6.7969 12.1327 10.4056 12.1323 13.823 13.0749C13.9758 13.1178 14.1357 13.1294 14.2931 13.1091C14.4512 13.0887 14.6035 13.0366 14.741 12.9558C14.8784 12.8751 14.9981 12.7674 15.0928 12.6392C15.1875 12.511 15.2554 12.3649 15.2922 12.2098L17.1744 4.21182C17.2247 3.99772 17.2143 3.77378 17.1443 3.56528C17.0743 3.35679 16.9475 3.17193 16.7781 3.0316C16.6087 2.89126 16.4035 2.80102 16.1856 2.77108C15.9677 2.74107 15.7457 2.77245 15.5447 2.86179L11.8102 4.52156L9.63586 0.607686C9.53353 0.423534 9.3839 0.270129 9.20234 0.163274C9.02077 0.0564274 8.81364 0 8.60303 0Z" fill="black"/>
</svg>
</template>

View file

@ -0,0 +1,6 @@
<template>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.603 9C15.3923 9 15.1855 9.05633 15.0039 9.16317C14.8224 9.27002 14.6727 9.42342 14.5704 9.60759L12.396 13.5215L8.661 11.8615C8.46003 11.7722 8.23813 11.7407 8.02028 11.7707C7.80242 11.8007 7.5972 11.8908 7.42781 12.0311C7.25849 12.1714 7.13161 12.3561 7.06154 12.5646C6.99147 12.7731 6.98101 12.9969 7.03132 13.211L8.90995 21.2092L8.91022 21.2105C8.947 21.3656 9.01481 21.5117 9.10949 21.64C9.20431 21.7683 9.32401 21.876 9.46147 21.9568C9.59887 22.0376 9.75131 22.0898 9.90944 22.1101C10.0669 22.1304 10.2268 22.1188 10.3797 22.0759C13.7969 21.1327 17.4056 21.1323 20.823 22.0749C20.9758 22.1178 21.1357 22.1294 21.2931 22.1091C21.4512 22.0887 21.6035 22.0366 21.741 21.9558C21.8784 21.8751 21.9981 21.7674 22.0928 21.6392C22.1875 21.511 22.2554 21.3649 22.2922 21.2098L24.1744 13.2118C24.2247 12.9977 24.2143 12.7738 24.1443 12.5653C24.0743 12.3568 23.9475 12.1719 23.7781 12.0316C23.6087 11.8913 23.4035 11.801 23.1856 11.7711C22.9677 11.7411 22.7457 11.7724 22.5447 11.8618L18.8102 13.5216L16.6359 9.60769C16.5335 9.42353 16.3839 9.27013 16.2023 9.16327C16.0208 9.05643 15.8136 9 15.603 9Z" fill="black"/>
<path d="M23.7539 25.6534L23.7541 25.6535C24.0797 25.8133 24.4377 25.7634 24.6963 25.5881C24.9579 25.4108 25.1596 25.0696 25.0855 24.6661C25.0855 24.6661 25.0855 24.6661 25.0855 24.666L24.6677 22.3918L26.4494 20.7718C26.4495 20.7718 26.4495 20.7718 26.4495 20.7718C27.0872 20.192 26.6457 19.2797 25.945 19.1847L25.9446 19.1847L23.4384 18.8463L22.3258 16.7436L22.3258 16.7436C21.9775 16.0856 21.0229 16.0855 20.6744 16.7432C20.6744 16.7433 20.6744 16.7433 20.6744 16.7433C20.6744 16.7434 20.6743 16.7435 20.6742 16.7436L19.5607 18.8451L17.055 19.1847C17.055 19.1847 17.055 19.1847 17.055 19.1847C16.3543 19.2797 15.9128 20.1921 16.5506 20.7718L16.5506 20.7719L18.3328 22.3916L17.9146 24.666L17.9146 24.666C17.8404 25.0696 18.0421 25.4108 18.3038 25.5882C18.5624 25.7634 18.9203 25.8133 19.246 25.6536C19.246 25.6536 19.246 25.6535 19.246 25.6535L21.5011 24.5477L23.7539 25.6534ZM25.4405 19.6619L25.4404 19.6619L25.4405 19.6619ZM17.2564 20.6711L17.2564 20.6711L17.2564 20.6711Z" fill="black" stroke="white" stroke-width="1.5"/>
</svg>
</template>

View file

@ -115,11 +115,9 @@
"ignore": "སྣང་མེད་ཐོངས།",
"join": "ཞུགས།",
"undo": "ཕྱིར་བསྡུ།",
"user_kick_and_ban": "སྤྱོད་མཁན་འདི་ཕྱིར་འབུད་དང་བཀག་སྡོམ་བྱོས།",
"user_make_admin": "འཛིན་སྐྱོང་པ་བཟོས།",
"user_make_moderator": "གཙོ་སྐྱོང་བ་བཟོས།",
"user_revoke_moderator": "གཙོ་སྐྱོང་བའི་དབང་ཚད་མེད་པར་བཟོས།",
"user_kick": "སྤྱོད་མཁན་འདི་སྒོར་ཕུད།"
"user_revoke_moderator": "གཙོ་སྐྱོང་བའི་དབང་ཚད་མེད་པར་བཟོས།"
},
"profile": {
"change_password": "གསང་ཚིག་རྗེས།",

View file

@ -23,7 +23,7 @@
},
"menu": {
"start_private_chat": "Direct Message with this user",
"actions": "actions",
"direct_chat": "Direct chat",
"reply": "Reply",
"edit": "Edit",
"delete": "Delete",
@ -41,9 +41,8 @@
"join": "Join",
"ignore": "Ignore",
"loading": "Loading {appName}",
"user_kick": "Kick this user",
"user_kick_and_ban": "Kick and ban this user",
"user_make_admin": "Make administrator",
"user_kick_and_ban": "Kick out",
"user_make_admin": "Make admin",
"user_make_moderator": "Make moderator",
"user_revoke_moderator": "Revoke moderator"
},
@ -164,7 +163,6 @@
"options": "Options"
},
"device_list": {
"title": "DEVICES",
"blocked": "Blocked",
"verified": "Verified",
"not_verified": "Not verified"

View file

@ -263,8 +263,6 @@
"loading": "Cargando {appName}",
"undo": "Deshacer",
"join": "Unirse",
"user_kick": "Expulsa a este usuario",
"user_kick_and_ban": "Expulsar y banear a este usuario",
"user_make_moderator": "Hacer moderador",
"user_make_admin": "Hacer administrador",
"user_revoke_moderator": "Revocar al moderador",

View file

@ -52,9 +52,7 @@
"join": "Entrar",
"ignore": "Ignore",
"loading": "Carregando {appName}",
"user_kick": "Expulsar este usuário",
"user_make_moderator": "Tornar moderador",
"user_kick_and_ban": "Expulsar e banir este usuário",
"user_make_admin": "Tornar administrador",
"user_revoke_moderator": "Revogar moderador",
"delete_now": "Excluir agora"

View file

@ -179,8 +179,6 @@
"ignore": "忽略",
"join": "加入",
"undo": "撤销",
"user_kick_and_ban": "移出并禁止该用户",
"user_kick": "移出该用户",
"user_make_admin": "设为管理员",
"user_make_moderator": "设为版主",
"user_revoke_moderator": "撤销版主身份"

View file

@ -0,0 +1,203 @@
<template>
<v-dialog
v-model="showDialog"
v-show="room"
class="ma-0 pa-0"
:width="$vuetify.breakpoint.smAndUp ? '688px' : '95%'"
>
<div class="dialog-content text-center member-action-dialog">
<div>
<v-avatar class="avatar" size="56" color="grey">
<img v-if="memberAvatar(activeMember)" :src="memberAvatar(activeMember)" />
<span v-else class="white--text headline">{{
activeMember.name.substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div>
<span class="user-name">
{{
activeMember.userId == $matrix.currentUserId
? $t("room_info.user_you", {
user: activeMember.user ? activeMember.user.displayName : activeMember.name,
})
: $t("room_info.user", {
user: activeMember.user ? activeMember.user.displayName : activeMember.name,
})
}}
</span>
<span v-if="isAdmin(activeMember)" class="user-power">
{{ $t("room_info.user_admin") }}
</span>
<span v-else-if="isModerator(activeMember)" class="user-power">
{{ $t("room_info.user_moderator") }}
</span>
</div>
</div>
<DeviceList :member="activeMember" />
<div class="py-3" v-if="activeMember.userId != $matrix.currentUserId">
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && !$matrix.isDirectRoomWith(room, activeMember.userId)" class="start-private-chat clickable d-block text-none justify-start" @click="startPrivateChat(activeMember.userId)">
<v-icon left>$vuetify.icons.direct_chat</v-icon> {{ $t("menu.direct_chat") }}
</v-btn>
<div v-if="canBanUser(activeMember)">
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && canBanUser(activeMember)" class="start-private-chat clickable d-block text-none justify-start" @click="banUser(activeMember)">
<v-icon left>$vuetify.icons.kick_out</v-icon> {{ $t("menu.user_kick_and_ban") }}
</v-btn>
</div>
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && !isAdmin(activeMember) && canMakeAdmin(activeMember)" class="start-private-chat clickable d-block text-none justify-start" @click="makeAdmin(activeMember)">
<v-icon left>$vuetify.icons.make_admin</v-icon> {{ $t("menu.user_make_admin") }}
</v-btn>
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && !isModerator(activeMember) && !isAdmin(activeMember) && canMakeModerator(activeMember)" class="start-private-chat clickable d-block text-none justify-start" @click="makeModerator(activeMember)">
<v-icon left>$vuetify.icons.make_moderator</v-icon> {{ $t("menu.user_make_moderator") }}
</v-btn>
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && isModerator(activeMember) && canRevokeModerator(activeMember)" class="start-private-chat clickable d-block text-none justify-start" @click="revokeModerator(activeMember)">
<v-icon left>$vuetify.icons.kick_out</v-icon> {{ $t("menu.user_revoke_moderator") }}
</v-btn>
</div>
</div>
</v-dialog>
</template>
<script>
import roomInfoMixin from "./roomInfoMixin";
import DeviceList from "../components/DeviceList";
import util from "../plugins/utils";
export default {
name: "MemberActionDialog",
mixins: [roomInfoMixin],
components: {
DeviceList
},
props: {
show: {
type: Boolean,
default: function () {
return false;
},
},
activeMember: {
type: Object
}
},
data() {
return {
showDialog: false
};
},
watch: {
show: {
handler(newVal, ignoredOldVal) {
this.showDialog = newVal;
}
},
showDialog() {
if (!this.showDialog) {
this.$emit("close");
}
},
},
methods: {
startPrivateChat(userId) {
this.$matrix
.getOrCreatePrivateChat(userId)
.then((room) => {
this.$nextTick(() => {
this.$navigation.push(
{
name: "Chat",
params: {
roomId: util.sanitizeRoomId(
room.getCanonicalAlias() || room.roomId
),
},
},
-1
);
});
})
.catch((err) => {
console.error(err);
})
.finally(() => {
this.showDialog = false;
});
},
canBanUser(member) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && me.powerLevelNorm > member.powerLevelNorm && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("ban", me.powerLevel);
}
return false;
},
/**
* Return true if WE can make the member an admin
* @param member
*/
canMakeAdmin(ignoredmember) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me);
}
return false;
},
/**
* Return true if WE can make the member a moderator
* @param member
*/
canMakeModerator(ignoredmember) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me);
}
return false;
},
/**
* Return true if WE can "unmake" the member a moderator
* @param member
*/
canRevokeModerator(member) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me) && me.powerLevel > member.powerLevel;
}
return false;
},
makeAdmin(member) {
if (this.room) {
this.$matrix.makeAdmin(this.room.roomId, member.userId)
this.showDialog = false;
}
},
makeModerator(member) {
if (this.room) {
this.$matrix.makeModerator(this.room.roomId, member.userId)
this.showDialog = false;
}
},
revokeModerator(member) {
if (this.room) {
this.$matrix.revokeModerator(this.room.roomId, member.userId)
this.showDialog = false;
}
},
banUser(member) {
if (this.room) {
console.log(this.$matrix)
console.log(member.userId)
console.log(this.room.roomId)
this.$matrix.banUser(this.room.roomId, member.userId)
this.showDialog = false;
}
},
},
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

View file

@ -189,6 +189,14 @@
v-model="readOnlyRoom"
></v-switch>
</v-card-text>
<v-card-text class="with-right-label" style="align-items:center" v-if="canViewRetentionPolicy">
<div>
<div class="option-title">{{ $t('room_info.message_retention') }}</div>
<div class="option-text">{{ $t('room_info.message_retention_info') }}</div>
</div>
<div class="text-right">{{ messageRetention }}</div>
<v-btn v-on:click="showMessageRetentionDialog = true" v-if="canChangeRetentionPolicy" icon size="x-small"><v-icon color="black">edit</v-icon></v-btn>
</v-card-text>
</v-card>
<v-card class="members ma-3" flat>
@ -196,69 +204,48 @@
>{{ $t("room_info.members") }}<v-spacer></v-spacer>
<div>{{ members.length }}</div></v-card-title
>
<v-expansion-panels>
<v-expansion-panel v-for="(member, index) in members" :key="member.userId">
<v-expansion-panel-header
class="member"
v-show="showAllMembers || index < SHOW_MEMBER_LIMIT"
>
<div>
<v-avatar class="avatar" size="32" 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-avatar>
<span class="user-name">
{{
member.userId == $matrix.currentUserId
? $t("room_info.user_you", {
user: member.user ? member.user.displayName : member.name,
})
: $t("room_info.user", {
user: member.user ? member.user.displayName : member.name,
})
}}
</span>
<span v-if="isAdmin(member)" class="user-power">
{{ $t("room_info.user_admin") }}
</span>
<span v-else-if="isModerator(member)" class="user-power">
{{ $t("room_info.user_moderator") }}
</span>
</div>
</v-expansion-panel-header>
<v-expansion-panel-content>
<v-tabs>
<v-tab v-if="member.userId != $matrix.currentUserId">{{ $t("menu.actions") }}</v-tab>
<v-tab>{{$t('device_list.title')}}</v-tab>
<!-- TODO: other rooms in common
<v-tab v-if="member.userId != $matrix.currentUserId">{{ $t("menu.common_room") }}</v-tab>
-->
<v-tab-item v-if="member.userId != $matrix.currentUserId">
<div class="py-3">
<v-btn text v-if="member.userId != $matrix.currentUserId && !$matrix.isDirectRoomWith(room, member.userId)" class="start-private-chat clickable d-block text-none" @click="startPrivateChat(member.userId)">{{ $t("menu.start_private_chat") }}</v-btn>
<div v-if="canKickUser(member) || canBanUser(member)">
<div v-if="member.userId != $matrix.currentUserId" class="mt-2">{{ String.fromCharCode(160) }}</div>
<v-btn text v-if="member.userId != $matrix.currentUserId && canKickUser(member)" class="start-private-chat clickable d-block text-none" @click="kickUser(member)">{{ $t("menu.user_kick") }}</v-btn>
<v-btn text v-if="member.userId != $matrix.currentUserId && canBanUser(member)" class="start-private-chat clickable d-block text-none" @click="banUser(member)">{{ $t("menu.user_kick_and_ban") }}</v-btn>
</div>
<div v-if="member.userId != $matrix.currentUserId" class="mt-2">{{ String.fromCharCode(160) }}</div>
<v-btn text v-if="member.userId != $matrix.currentUserId && !isAdmin(member) && canMakeAdmin(member)" class="start-private-chat clickable d-block text-none" @click="makeAdmin(member)">{{ $t("menu.user_make_admin") }}</v-btn>
<v-btn text v-if="member.userId != $matrix.currentUserId && !isModerator(member) && !isAdmin(member) && canMakeModerator(member)" class="start-private-chat clickable d-block text-none" @click="makeModerator(member)">{{ $t("menu.user_make_moderator") }}</v-btn>
<v-btn text v-if="member.userId != $matrix.currentUserId && isModerator(member) && canRevokeModerator(member)" class="start-private-chat clickable d-block text-none" @click="revokeModerator(member)">{{ $t("menu.user_revoke_moderator") }}</v-btn>
</div>
</v-tab-item>
<v-tab-item>
<DeviceList :member="member" />
</v-tab-item>
<!-- <v-tab-item v-if="member.userId != $matrix.currentUserId">
{{ "TODO" }}
</v-tab-item> -->
</v-tabs>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
<v-list>
<v-list-item-group>
<template v-for="(member, index) in members" >
<v-list-item
:key="member.userId"
class="member"
v-show="showAllMembers || index < SHOW_MEMBER_LIMIT"
@click="onListItemClick(member)"
>
<div>
<v-avatar class="avatar" size="32" 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-avatar>
<span class="user-name">
{{
member.userId == $matrix.currentUserId
? $t("room_info.user_you", {
user: member.user ? member.user.displayName : member.name,
})
: $t("room_info.user", {
user: member.user ? member.user.displayName : member.name,
})
}}
</span>
<span v-if="isAdmin(member)" class="user-power">
{{ $t("room_info.user_admin") }}
</span>
<span v-else-if="isModerator(member)" class="user-power">
{{ $t("room_info.user_moderator") }}
</span>
</div>
</v-list-item>
<v-divider
v-if="(showAllMembers || index < SHOW_MEMBER_LIMIT) && index < members.length - 1"
:key="index"
></v-divider>
</template>
</v-list-item-group>
</v-list>
<div class="show-all p-2" @click="showAllMembers = !showAllMembers" v-if="members.length > SHOW_MEMBER_LIMIT">
{{ showAllMembers ? $t("room_info.hide_all") : $t("room_info.show_all") }}
</div>
@ -279,6 +266,13 @@
{{ $t("room_info.version_info", { version: buildVersion }) }}
</div>
<MemberActionDialog
:show="showMemberActionConfirmation"
:activeMember="activeMember || members[0]"
:room="room"
@close="showMemberActionConfirmation = false"
/>
<LeaveRoomDialog
:show="showLeaveConfirmation"
:room="room"
@ -306,11 +300,11 @@
import LeaveRoomDialog from "../components/LeaveRoomDialog";
import PurgeRoomDialog from "../components/PurgeRoomDialog";
import MessageRetentionDialog from "../components/MessageRetentionDialog";
import DeviceList from "../components/DeviceList";
import RoomExport from "../components/RoomExport";
import RoomAvatarPicker from "../components/RoomAvatarPicker";
import CopyLink from "../components/CopyLink.vue"
import RoomTypeSelector from "./RoomTypeSelector.vue";
import MemberActionDialog from "./MemberActionDialog.vue"
import roomInfoMixin from "./roomInfoMixin";
import roomTypeMixin from "./roomTypeMixin";
import util, { STATE_EVENT_ROOM_TYPE } from "../plugins/utils";
@ -322,7 +316,7 @@ export default {
LeaveRoomDialog,
PurgeRoomDialog,
MessageRetentionDialog,
DeviceList,
MemberActionDialog,
RoomExport,
RoomAvatarPicker,
RoomTypeSelector,
@ -333,6 +327,7 @@ export default {
members: [],
user: null,
showAllMembers: false,
showMemberActionConfirmation: false,
showLeaveConfirmation: false,
showPurgeConfirmation: false,
showMessageRetentionDialog: false,
@ -352,7 +347,8 @@ export default {
},
],
SHOW_MEMBER_LIMIT: 5,
exporting: false
exporting: false,
activeMember: null
};
},
mounted() {
@ -446,6 +442,10 @@ export default {
onMessageRetention(retention){
const retentionPeriodsFound = this.retentionPeriods.find(rp => rp.value===retention)
this.messageRetention = retentionPeriodsFound.text
},
onListItemClick(member) {
this.activeMember = member
this.showMemberActionConfirmation = true
},
onEvent(event) {
if (this.room && this.room.roomId == event.getRoomId()) {
@ -490,19 +490,6 @@ export default {
}
},
memberAvatar(member) {
if (member) {
return member.getAvatarUrl(
this.$matrix.matrixClient.getHomeserverUrl(),
40,
40,
"scale",
true
);
}
return null;
},
viewProfile() {
this.$navigation.push({ name: "Profile" }, 1);
},
@ -551,49 +538,11 @@ export default {
this.updatingJoinRule = false;
});
},
startPrivateChat(userId) {
this.$matrix
.getOrCreatePrivateChat(userId)
.then((room) => {
this.$nextTick(() => {
this.$navigation.push(
{
name: "Chat",
params: {
roomId: util.sanitizeRoomId(
room.getCanonicalAlias() || room.roomId
),
},
},
-1
);
});
})
.catch((err) => {
console.error(err);
});
},
exportRoom() {
if (this.room) {
this.exporting = true;
}
},
canKickUser(member) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && me.powerLevel > member.powerLevel && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("kick", me.powerLevel);
}
return false;
},
canBanUser(member) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && me.powerLevelNorm > member.powerLevelNorm && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("ban", me.powerLevel);
}
return false;
},
/**
* Return true if we can change power levels in the room, i.e. make read only room
*/
@ -610,76 +559,6 @@ export default {
}
return false;
},
// TODO - following power level comparisons assume that default power levels are used in the room!
isAdmin(member) {
return member.powerLevelNorm > 50;
},
isModerator(member) {
return member.powerLevelNorm > 0 && member.powerLevelNorm <= 50;
},
/**
* Return true if WE can make the member an admin
* @param member
*/
canMakeAdmin(ignoredmember) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me);
}
return false;
},
/**
* Return true if WE can make the member a moderator
* @param member
*/
canMakeModerator(ignoredmember) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me);
}
return false;
},
/**
* Return true if WE can "unmake" the member a moderator
* @param member
*/
canRevokeModerator(member) {
if (this.room) {
const myUserId = this.$matrix.currentUserId;
const me = this.room.getMember(myUserId);
return me && this.isAdmin(me) && me.powerLevel > member.powerLevel;
}
return false;
},
makeAdmin(member) {
if (this.room) {
this.$matrix.makeAdmin(this.room.roomId, member.userId)
}
},
makeModerator(member) {
if (this.room) {
this.$matrix.makeModerator(this.room.roomId, member.userId)
}
},
revokeModerator(member) {
if (this.room) {
this.$matrix.revokeModerator(this.room.roomId, member.userId)
}
},
kickUser(member) {
if (this.room) {
this.$matrix.kickUser(this.room.roomId, member.userId)
}
},
banUser(member) {
if (this.room) {
this.$matrix.banUser(this.room.roomId, member.userId)
}
},
/**
* Go back to previous page, or if none on the stack, go back to current room view.
*/

View file

@ -159,6 +159,25 @@ export default {
},
},
methods: {
memberAvatar(member) {
if (member) {
return member.getAvatarUrl(
this.$matrix.matrixClient.getHomeserverUrl(),
40,
40,
"scale",
true
);
}
return null;
},
// TODO - following power level comparisons assume that default power levels are used in the room!
isAdmin(member) {
return member.powerLevelNorm > 50;
},
isModerator(member) {
return member.powerLevelNorm > 0 && member.powerLevelNorm <= 50;
},
/**
* Get a string describing current room retention setting.
* Can be "None", "1 week", "1 hour" etc...