Merge branch '422-add-room-member-management-kick-add-moderator-etc' into 'dev'
Add kick,ban,make admin and make moderator operations See merge request keanuapp/keanuapp-weblite!130
This commit is contained in:
commit
f5c75e3232
23 changed files with 281 additions and 27 deletions
|
|
@ -195,7 +195,22 @@
|
|||
})
|
||||
}}
|
||||
</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-if="member.userId != $matrix.currentUserId && !$matrix.isDirectRoomWith(room, member.userId) && expandedMembers.includes(member)" class="start-private-chat clickable" @click="startPrivateChat(member.userId)">{{ $t("menu.start_private_chat") }}</div>
|
||||
<div v-if="canKickUser(member) || canBanUser(member)">
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member)" class="mt-2">{{ String.fromCharCode(160) }}</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member) && canKickUser(member)" class="start-private-chat clickable" @click="kickUser(member)">{{ $t("menu.user_kick") }}</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member) && canBanUser(member)" class="start-private-chat clickable" @click="banUser(member)">{{ $t("menu.user_kick_and_ban") }}</div>
|
||||
</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member)" class="mt-2">{{ String.fromCharCode(160) }}</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member) && !isAdmin(member) && canMakeAdmin(member)" class="start-private-chat clickable" @click="makeAdmin(member)">{{ $t("menu.user_make_admin") }}</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member) && !isModerator(member) && !isAdmin(member) && canMakeModerator(member)" class="start-private-chat clickable" @click="makeModerator(member)">{{ $t("menu.user_make_moderator") }}</div>
|
||||
<div v-if="member.userId != $matrix.currentUserId && expandedMembers.includes(member) && isModerator(member) && canRevokeModerator(member)" class="start-private-chat clickable" @click="revokeModerator(member)">{{ $t("menu.user_revoke_moderator") }}</div>
|
||||
<DeviceList
|
||||
v-if="expandedMembers.includes(member)"
|
||||
:member="member"
|
||||
|
|
@ -528,6 +543,91 @@ export default {
|
|||
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;
|
||||
},
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import MessageOutgoingVideoExport from "./messages/export/MessageOutgoingVideoEx
|
|||
import ContactJoin from "./messages/ContactJoin.vue";
|
||||
import ContactLeave from "./messages/ContactLeave.vue";
|
||||
import ContactInvited from "./messages/ContactInvited.vue";
|
||||
import ContactKicked from "./messages/ContactKicked.vue";
|
||||
import ContactBanned from "./messages/ContactBanned.vue";
|
||||
import ContactChanged from "./messages/ContactChanged.vue";
|
||||
import RoomCreated from "./messages/RoomCreated.vue";
|
||||
import RoomAliased from "./messages/RoomAliased.vue";
|
||||
|
|
@ -66,6 +68,8 @@ export default {
|
|||
ContactJoin,
|
||||
ContactLeave,
|
||||
ContactInvited,
|
||||
ContactKicked,
|
||||
ContactBanned,
|
||||
ContactChanged,
|
||||
RoomCreated,
|
||||
RoomAliased,
|
||||
|
|
@ -123,9 +127,15 @@ export default {
|
|||
return ContactJoin;
|
||||
}
|
||||
} else if (event.getContent().membership == "leave") {
|
||||
if ((event.getPrevContent() || {}).membership == "join" &&
|
||||
event.getStateKey() != event.getSender()) {
|
||||
return ContactKicked;
|
||||
}
|
||||
return ContactLeave;
|
||||
} else if (event.getContent().membership == "invite") {
|
||||
return ContactInvited;
|
||||
} else if (event.getContent().membership == "ban") {
|
||||
return ContactBanned;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
25
src/components/messages/ContactBanned.vue
Normal file
25
src/components/messages/ContactBanned.vue
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<!-- Contact left the chat -->
|
||||
<div class="messageJoin">
|
||||
{{ (event.getStateKey() == this.$matrix.currentUserId) ?
|
||||
$t('message.user_was_banned_you')
|
||||
:
|
||||
event.getSender() == this.$matrix.currentUserId ?
|
||||
$t('message.user_was_banned_by_you',{user: eventStateKeyDisplayName(event)})
|
||||
:
|
||||
$t('message.user_was_banned',{user: eventStateKeyDisplayName(event)})
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messageMixin from "./messageMixin";
|
||||
|
||||
export default {
|
||||
mixins: [messageMixin],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -33,7 +33,7 @@ export default {
|
|||
if (this.displayNameChange) {
|
||||
return this.event.getPrevContent().displayname;
|
||||
}
|
||||
return this.stateEventDisplayName(this.event);
|
||||
return this.eventStateKeyDisplayName(this.event);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- Contact invited to the chat -->
|
||||
<div class="messageJoin">
|
||||
{{ $t('message.user_was_invited', {user: event.getContent().displayname || stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_was_invited', {user: event.getContent().displayname || eventStateKeyDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- Contact joined the chat -->
|
||||
<div class="messageJoin">
|
||||
{{ $t('message.user_joined',{user: stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_joined',{user: eventSenderDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
25
src/components/messages/ContactKicked.vue
Normal file
25
src/components/messages/ContactKicked.vue
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<!-- Contact left the chat -->
|
||||
<div class="messageJoin">
|
||||
{{ (event.getStateKey() == this.$matrix.currentUserId) ?
|
||||
$t('message.user_was_kicked_you')
|
||||
:
|
||||
event.getSender() == this.$matrix.currentUserId ?
|
||||
$t('message.user_was_kicked_by_you',{user: eventStateKeyDisplayName(event)})
|
||||
:
|
||||
$t('message.user_was_kicked',{user: eventStateKeyDisplayName(event)})
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messageMixin from "./messageMixin";
|
||||
|
||||
export default {
|
||||
mixins: [messageMixin],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- Contact left the chat -->
|
||||
<div class="messageJoin">
|
||||
{{ $t('message.user_left',{user: stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_left',{user: eventStateKeyDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<!-- BASE CLASS FOR INCOMING MESSAGE -->
|
||||
<div :class="messageClasses">
|
||||
<div v-if="showSenderAndTime" class="senderAndTime">
|
||||
<div class="sender">{{ messageEventDisplayName(event) }}</div>
|
||||
<div class="sender">{{ eventSenderDisplayName(event) }}</div>
|
||||
<div class="time">
|
||||
{{ formatTime(event.event.origin_server_ts) }}
|
||||
</div>
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
<v-avatar class="avatar" ref="avatar" size="32" color="#ededed" @click.stop="otherAvatarClicked($refs.avatar.$el)">
|
||||
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" />
|
||||
<span v-else class="white--text headline">{{
|
||||
messageEventDisplayName(event).substring(0, 1).toUpperCase()
|
||||
eventSenderDisplayName(event).substring(0, 1).toUpperCase()
|
||||
}}</span>
|
||||
</v-avatar>
|
||||
<!-- SLOT FOR CONTENT -->
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_aliased_room', {user: stateEventDisplayName(event), alias: event.getContent().alias}) }}
|
||||
{{ $t('message.user_aliased_room', {user: eventSenderDisplayName(event), alias: event.getContent().alias}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- ROOM AVATAR CHANGED -->
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_changed_room_avatar',{user: stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_changed_room_avatar',{user: eventSenderDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_created_room', {user: stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_created_room', {user: eventSenderDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
👋
|
||||
{{
|
||||
$t("purge_room.room_deletion_notice", {
|
||||
user: stateEventDisplayName(event),
|
||||
user: eventSenderDisplayName(event),
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_encrypted_room', {user: stateEventDisplayName(event)}) }}
|
||||
{{ $t('message.user_encrypted_room', {user: eventSenderDisplayName(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
{{
|
||||
openToGuests
|
||||
? $t("message.user_changed_guest_access_open", {
|
||||
user: stateEventDisplayName(event),
|
||||
user: eventSenderDisplayName(event),
|
||||
})
|
||||
: $t("message.user_changed_guest_access_closed", {
|
||||
user: stateEventDisplayName(event),
|
||||
user: eventSenderDisplayName(event),
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- ROOM AVATAR CHANGED -->
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_changed_room_history',{user: stateEventDisplayName(event), type: history(event)}) }}
|
||||
{{ $t('message.user_changed_room_history',{user: eventSenderDisplayName(event), type: history(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- ROOM JOIN RULES CHANGED -->
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_changed_join_rules', { user: stateEventDisplayName(event), type: joinRule(event)}) }}
|
||||
{{ $t('message.user_changed_join_rules', { user: eventSenderDisplayName(event), type: joinRule(event)}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- ROOM NAME CHANGED -->
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_changed_room_name', {user: stateEventDisplayName(event), name: event.getContent().name}) }}
|
||||
{{ $t('message.user_changed_room_name', {user: eventSenderDisplayName(event), name: event.getContent().name}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<!-- ROOM TOPIC CHANGED -->
|
||||
<div class="statusEvent">
|
||||
{{ $t('message.user_changed_room_topic', {user: stateEventDisplayName(event), topic: event.getContent().topic}) }}
|
||||
{{ $t('message.user_changed_room_topic', {user: eventSenderDisplayName(event), topic: event.getContent().topic}) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default {
|
|||
const originalEvent = this.timelineSet.findEventById(originalEventId);
|
||||
if (originalEvent) {
|
||||
this.inReplyToEvent = originalEvent;
|
||||
this.inReplyToSender = this.messageEventDisplayName(originalEvent);
|
||||
this.inReplyToSender = this.eventSenderDisplayName(originalEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ export default {
|
|||
/**
|
||||
* Get a display name given an event.
|
||||
*/
|
||||
stateEventDisplayName(event) {
|
||||
eventSenderDisplayName(event) {
|
||||
if (event.getSender() == this.$matrix.currentUserId) {
|
||||
return this.$t('message.you');
|
||||
}
|
||||
|
|
@ -167,11 +167,26 @@ export default {
|
|||
return member.name;
|
||||
}
|
||||
}
|
||||
return event.getContent().displayname || event.event.state_key;
|
||||
return event.getContent().displayname || event.getSender();
|
||||
},
|
||||
|
||||
messageEventDisplayName(event) {
|
||||
return this.stateEventDisplayName(event);
|
||||
/**
|
||||
* In the case where the state_key points out a userId for an operation (e.g. membership events)
|
||||
* return the display name of the affected user.
|
||||
* @param event
|
||||
* @returns
|
||||
*/
|
||||
eventStateKeyDisplayName(event) {
|
||||
if (event.getStateKey() == this.$matrix.currentUserId) {
|
||||
return this.$t('message.you');
|
||||
}
|
||||
if (this.room) {
|
||||
const member = this.room.getMember(event.getStateKey());
|
||||
if (member) {
|
||||
return member.name;
|
||||
}
|
||||
}
|
||||
return event.getStateKey();
|
||||
},
|
||||
|
||||
messageEventAvatar(event) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue