diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index f47a278..3822fdf 100644 --- a/src/assets/css/chat.scss +++ b/src/assets/css/chat.scss @@ -740,8 +740,7 @@ body { } } -.message-operations-strut, -.avatar-operations-strut { +.message-operations-strut { position: relative; height: 0px; z-index: 10; @@ -757,16 +756,6 @@ body { white-space: nowrap; } -.avatar-operations { - position: absolute; - width: fit-content; - background-color: white; - height: 40px; - border-radius: 20px; - padding: 0px 20px; - box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.15); -} - .send-options { z-index: 11; // Above mic button } diff --git a/src/components/Chat.vue b/src/components/Chat.vue index 3ea47df..074a15c 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -46,14 +46,6 @@ /> -
- -
- @@ -324,6 +316,12 @@ + @@ -332,7 +330,6 @@ import Vue from "vue"; import { TimelineWindow, EventTimeline } from "matrix-js-sdk"; import util, { ROOM_TYPE_VOICE_MODE, ROOM_TYPE_FILE_MODE } from "../plugins/utils"; import MessageOperations from "./messages/MessageOperations.vue"; -import AvatarOperations from "./messages/AvatarOperations.vue"; import ChatHeader from "./ChatHeader"; import ChatHeaderPrivate from "./ChatHeaderPrivate.vue"; import VoiceRecorder from "./VoiceRecorder"; @@ -342,6 +339,7 @@ import DirectChatWelcomeHeader from "./DirectChatWelcomeHeader"; import NoHistoryRoomWelcomeHeader from "./NoHistoryRoomWelcomeHeader.vue"; import MessageOperationsBottomSheet from "./MessageOperationsBottomSheet"; import StickerPickerBottomSheet from "./StickerPickerBottomSheet"; +import UserProfileDialog from "./UserProfileDialog.vue" import BottomSheet from "./BottomSheet.vue"; import ImageResize from "image-resize"; import CreatePollDialog from "./CreatePollDialog.vue"; @@ -399,10 +397,10 @@ export default { MessageOperationsBottomSheet, StickerPickerBottomSheet, BottomSheet, - AvatarOperations, CreatePollDialog, AudioLayout, - FileDropLayout + FileDropLayout, + UserProfileDialog }, data() { @@ -432,8 +430,6 @@ export default { showNoRecordingAvailableDialog: false, showContextMenu: false, showContextMenuAnchor: null, - showAvatarMenu: false, - showAvatarMenuAnchor: null, initialLoadDone: false, loading: false, // Set this to true during long operations to show a "spinner" overlay showRecorder: false, @@ -489,7 +485,8 @@ export default { /** * A timer to handle message retention/auto deletion */ - retentionTimer: null + retentionTimer: null, + showProfileDialog: false }; }, @@ -521,7 +518,7 @@ export default { if (this.retentionTimer) { clearInterval(this.retentionTimer); this.retentionTimer = null; - } + } }, destroyed() { @@ -530,6 +527,10 @@ export default { }, computed: { + compActiveMember() { + const currentUserId= this.selectedEvent?.sender.userId || this.$matrix.currentUserId + return this.joinedAndInvitedMembers.find(({userId}) => userId === currentUserId) + }, nonImageFiles() { return this.isCurrentFileInputsAnArray && this.currentFileInputs.filter(file => !file?.type.includes("image/")) }, @@ -615,30 +616,6 @@ export default { showMessageOperations() { return this.selectedEvent && this.showContextMenu; }, - avatarOpStyle() { - // Calculate where to show the context menu. - // - const ref = this.selectedEvent && this.$refs[this.selectedEvent.getId()]; - var top = 0; - var left = "unset"; - var right = "unset"; - if (ref && ref[0]) { - if (this.showAvatarMenuAnchor) { - var rectAnchor = this.showAvatarMenuAnchor.getBoundingClientRect(); - var rectChat = this.$refs.avatarOperationsStrut.getBoundingClientRect(); - top = rectAnchor.top - rectChat.top; - if (this.$vuetify.rtl) { - right = (rectAnchor.right - rectChat.right)+ "px"; - } else { - left = (rectAnchor.left - rectChat.left) + "px"; - } - // if (left + 250 > rectChat.right) { - // left = rectChat.right - 250; // Pretty ugly, but we want to make sure it does not escape the screen, and we don't have the exakt width of it (yet)! - // } - } - } - return "top:" + top + "px;left:" + left + ";right:" + right; - }, canRecordAudio() { return util.browserCanRecordAudio(); }, @@ -910,7 +887,7 @@ export default { if (this.retentionTimer) { clearInterval(this.retentionTimer); this.retentionTimer = null; - } + } }, removeTimedOutEvents(events) { @@ -921,7 +898,7 @@ export default { } return events.filter((e) => { if (maxLifetime > 0 && !e.isState()) { // Keep all state events - return e.getLocalAge() < maxLifetime; + return e.getLocalAge() < maxLifetime; } return true; }); @@ -1700,50 +1677,20 @@ export default { showAvatarMenuForEvent(e) { const event = e.event; this.selectedEvent = event; - this.showAvatarMenu = true; - this.showAvatarMenuAnchor = e.anchor; + + this.showProfileDialog = true }, viewProfile() { this.$navigation.push({ name: "Profile" }, 1); }, - startPrivateChat(e) { - this.loading = true; - this.$matrix - .getOrCreatePrivateChat(e.event.getSender()) - .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.loading = false; - }); - }, - closeContextMenusIfOpen(e) { if (this.showContextMenu) { this.showContextMenu = false; this.showContextMenuAnchor = null; e.preventDefault(); } - if (this.showAvatarMenu) { - this.showAvatarMenu = false; - this.showAvatarMenuAnchor = null; - e.preventDefault(); - } }, /** Stop Read Receipt timer */ diff --git a/src/components/ChatHeader.vue b/src/components/ChatHeader.vue index c9b4f8d..e075d06 100644 --- a/src/components/ChatHeader.vue +++ b/src/components/ChatHeader.vue @@ -120,26 +120,6 @@ export default { room() { return this.$matrix.currentRoom; }, - memberAvatar() { - let roomMember; - if (this.room) { - this.room.getMembers().forEach(member => { - if (this.room.name === member.name) { - roomMember = member; - } - }); - if (roomMember) { - return roomMember.getAvatarUrl( - this.$matrix.matrixClient.getHomeserverUrl(), - 40, - 40, - "scale", - true - ); - } - } - return null; - }, notifications() { return this.$matrix.joinedRooms.some(r => (r.roomId !== this.$matrix.currentRoomId && r.getCanonicalAlias() !== this.$matrix.currentRoomId) && r.getUnreadNotificationCount("total") > 0) || this.$matrix.invites.length > 0; diff --git a/src/components/RoomExport.vue b/src/components/RoomExport.vue index 6f7b872..865954c 100644 --- a/src/components/RoomExport.vue +++ b/src/components/RoomExport.vue @@ -84,7 +84,6 @@ import RoomEncrypted from "./messages/RoomEncrypted.vue"; import RoomDeletionNotice from "./messages/RoomDeletionNotice.vue"; import DebugEvent from "./messages/DebugEvent.vue"; import MessageOperations from "./messages/MessageOperations.vue"; -import AvatarOperations from "./messages/AvatarOperations.vue"; import ChatHeader from "./ChatHeader.vue"; import VoiceRecorder from "./VoiceRecorder.vue"; import RoomInfoBottomSheet from "./RoomInfoBottomSheet.vue"; @@ -141,7 +140,6 @@ export default { MessageOperationsBottomSheet, StickerPickerBottomSheet, BottomSheet, - AvatarOperations, CreatePollDialog, }, props: { @@ -264,7 +262,7 @@ export default { if (parentEvent) { Vue.set(parentEvent, "isMxThread", true); Vue.set(event, "parentThread", parentEvent); - } + } }); this.events.filter(event => (event.replyEventId && !event.replyEvent)).forEach(event => { const parentEvent = this.timelineSet.findEventById(event.replyEventId) || this.room.findEventById(event.replyEventId); diff --git a/src/components/RoomInfo.vue b/src/components/RoomInfo.vue index 236b753..ea19a15 100644 --- a/src/components/RoomInfo.vue +++ b/src/components/RoomInfo.vue @@ -266,7 +266,7 @@ {{ $t("room_info.version_info", { version: buildVersion }) }} -
- - {{ - activeMember.name.substring(0, 1).toUpperCase() - }} + + {{ firstLetterUserName }}
{{ - activeMember.userId == $matrix.currentUserId + isCurrentUser ? $t("room_info.user_you", { - user: activeMemberName(activeMember) + user: activeMemberNameComp }) : $t("room_info.user", { - user: activeMemberName(activeMember) + user: activeMemberNameComp }) }} - + {{ $t("room_info.user_admin") }} - + {{ $t("room_info.user_moderator") }}
@@ -43,18 +42,18 @@ $vuetify.icons.direct_chat {{ $t("menu.direct_chat") }} -
- +
+ $vuetify.icons.kickout {{ $t("menu.user_kick_and_ban") }}
- + $vuetify.icons.make_admin {{ $t("menu.user_make_admin") }} - + $vuetify.icons.make_moderator {{ $t("menu.user_make_moderator") }} - + $vuetify.icons.revoke {{ $t("menu.user_revoke_moderator") }}
@@ -67,7 +66,7 @@ import DeviceList from "../components/DeviceList"; import util from "../plugins/utils"; export default { - name: "MemberActionDialog", + name: "UserProfileDialog", mixins: [roomInfoMixin], components: { DeviceList @@ -80,7 +79,10 @@ export default { }, }, activeMember: { - type: Object + type: Object, + default: function () { + return null; + } } }, data() { @@ -89,6 +91,36 @@ export default { }; }, computed: { + canRevokeModeratorComp () { + return this.canRevokeModerator(this.activeMember) + }, + isModeratorComp() { + return this.isModerator(this.activeMember) + }, + canMakeModeratorComp() { + return this.canMakeModerator(this.activeMember) + }, + canMakeAdminComp() { + return this.canMakeAdmin(this.activeMember) + }, + canBanUserComp() { + return this.canBanUser(this.activeMember) + }, + isAdminComp() { + return this.isAdmin(this.activeMember) + }, + activeMemberNameComp() { + return this.activeMember.user ? this.activeMember.user.displayName : this.activeMember.name + }, + isCurrentUser() { + return this.activeMember.userId == this.$matrix.currentUserId + }, + firstLetterUserName() { + return this.activeMember.name.substring(0, 1).toUpperCase() + }, + memberAvatarComp() { + return this.memberAvatar(this.activeMember) + }, joinedMembersByRoomId() { const joinedRooms = this.$matrix.joinedRooms.filter(room => !this.$matrix.isDirectRoom(room)) || []; return joinedRooms.map(room => ({ @@ -120,9 +152,6 @@ export default { }, methods: { - activeMemberName(activeMember) { - return activeMember.user ? activeMember.user.displayName : activeMember.name - }, startPrivateChat(userId) { this.$matrix .getOrCreatePrivateChat(userId) diff --git a/src/components/chatMixin.js b/src/components/chatMixin.js index ce4b85b..95e3e7f 100644 --- a/src/components/chatMixin.js +++ b/src/components/chatMixin.js @@ -38,7 +38,6 @@ import RoomTopicChanged from "./messages/RoomTopicChanged.vue"; import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue"; import RoomHistoryVisibility from "./messages/RoomHistoryVisibility.vue"; import MessageOperations from "./messages/MessageOperations.vue"; -import AvatarOperations from "./messages/AvatarOperations.vue"; import ChatHeader from "./ChatHeader"; import VoiceRecorder from "./VoiceRecorder"; import RoomInfoBottomSheet from "./RoomInfoBottomSheet"; @@ -100,7 +99,6 @@ export default { MessageOperationsBottomSheet, StickerPickerBottomSheet, BottomSheet, - AvatarOperations, CreatePollDialog, }, methods: { diff --git a/src/components/messages/AvatarOperations.vue b/src/components/messages/AvatarOperations.vue deleted file mode 100644 index 509ce2d..0000000 --- a/src/components/messages/AvatarOperations.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - \ No newline at end of file