Dialogs and Vuetify styling changes
This commit is contained in:
parent
2ba0d57aa8
commit
a97211afdf
45 changed files with 320 additions and 346 deletions
|
|
@ -22,6 +22,15 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.v-input.no-underline {
|
||||
.v-field__outline {
|
||||
/* Remove text underline */
|
||||
color: transparent !important;
|
||||
min-height: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.home {
|
||||
.v-card {
|
||||
background-color: white;
|
||||
|
|
@ -312,7 +321,20 @@ body {
|
|||
font-family: "Inter", sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 18 * $chat-text-size;
|
||||
.v-input__slot {
|
||||
|
||||
.v-field__overlay {
|
||||
display: none;
|
||||
}
|
||||
.v-field__input {
|
||||
padding: 0;
|
||||
min-height: 32px;
|
||||
mask-image: none;
|
||||
-webkit-mask-image: none;
|
||||
font-family: "Inter", sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 18 * $chat-text-size;
|
||||
}
|
||||
.v-field__outline {
|
||||
/* Remove text underline */
|
||||
color: transparent !important;
|
||||
min-height: 20px;
|
||||
|
|
|
|||
|
|
@ -131,21 +131,28 @@ body { position:absolute; top:0; bottom:0; right:0; left:0; }
|
|||
}
|
||||
}
|
||||
|
||||
.v-dialog {
|
||||
.v-dialog-rounded > * {
|
||||
border-radius: 20px !important;
|
||||
}
|
||||
|
||||
.v-dialog {
|
||||
.dialog-content {
|
||||
border-radius: 20px !important;
|
||||
padding: 20px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.dialog-title {
|
||||
word-break: break-word;
|
||||
text-align: center;
|
||||
padding: 16px 24px 10px 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dialog-text {
|
||||
text-align: left;
|
||||
word-break: break-word;
|
||||
|
||||
a {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
|
|
|
|||
|
|
@ -70,9 +70,8 @@
|
|||
<div class="load-later">
|
||||
<div style="align-self: flex-end;">
|
||||
<v-btn class="clap-button clickable" text elevation="0" v-blur @click.stop="clapButtonClicked()">👏</v-btn>
|
||||
<v-btn :class="{'mic-button': true, 'dimmed': !canRecordAudio}" ref="mic_button" fab small elevation="0" v-blur
|
||||
<v-btn icon="mic" :class="{'mic-button': true, 'dimmed': !canRecordAudio}" ref="mic_button" theme="dark" size="small" elevation="0" v-blur
|
||||
@click.stop="micButtonClicked()">
|
||||
<v-icon color="white">mic</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-icon class="clickable" @click="loadNext" color="white" size="28">expand_more</v-icon>
|
||||
|
|
@ -92,6 +91,7 @@ import emitter from 'tiny-emitter/instance';
|
|||
export default {
|
||||
mixins: [messageMixin],
|
||||
components: { AuthedImage },
|
||||
emits: ['mark-read','loadprevious','loadnext','start-recording','sendclap'],
|
||||
props: {
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
|
|
|
|||
|
|
@ -18,15 +18,13 @@
|
|||
:style="{ top: `${isMove ? y : calcY()}px` }"
|
||||
>
|
||||
<v-btn
|
||||
fab
|
||||
x-small
|
||||
size="small"
|
||||
elevation="0"
|
||||
color="black"
|
||||
@click.stop="onBackgroundClick"
|
||||
class="bottom-sheet-close"
|
||||
v-if="showCloseButton"
|
||||
icon="cancel"
|
||||
>
|
||||
<v-icon color="white" >cancel</v-icon>
|
||||
</v-btn>
|
||||
<div class="bottom-sheet-handle"><div class="bottom-sheet-handle-decoration" /></div>
|
||||
<div ref="sheetContent" class="sheetContent">
|
||||
|
|
@ -220,8 +218,8 @@ export default {
|
|||
|
||||
.bottom-sheet-close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
right: 4px;
|
||||
top: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,9 +117,8 @@
|
|||
<NoHistoryRoomWelcomeHeader v-if="showNoHistoryRoomWelcomeHeader" />
|
||||
|
||||
<!-- "Scroll to end"-button -->
|
||||
<v-btn v-if="!useVoiceMode" :class="{'scroll-to-end': true, 'reversed': reverseOrder}" v-show="showScrollToEnd" fab x-small elevation="0" color="black"
|
||||
<v-btn v-if="!useVoiceMode" icon="arrow_downward" :class="{'scroll-to-end': true, 'reversed': reverseOrder}" v-show="showScrollToEnd" theme="dark" size="x-small" elevation="0" color="black"
|
||||
@click.stop="scrollToEndOfTimeline">
|
||||
<v-icon color="white">arrow_downward</v-icon>
|
||||
</v-btn>
|
||||
|
||||
|
||||
|
|
@ -133,7 +132,7 @@
|
|||
<div class="col">
|
||||
<div class="font-weight-medium">{{ $t("message.replying_to", { user: senderDisplayName }) }}</div>
|
||||
<div v-if="replyToContentType === 'm.text'" class="reply-text" :title="replyToEvent.getContent().body">
|
||||
{{ replyToEvent.getContent().body | latestReply }}
|
||||
{{ latestReply }}
|
||||
</div>
|
||||
<div v-if="replyToContentType === 'm.thread' || replyToContentType === 'io.element.thread'">{{ replyToThreadMessage }}</div>
|
||||
<div v-if="replyToContentType === 'm.image'">{{ $t("message.reply_image") }}</div>
|
||||
|
|
@ -146,11 +145,10 @@
|
|||
class="rounded" />
|
||||
<v-img v-if="replyToContentType === 'm.audio'" src="@/assets/icons/audio_message.svg" />
|
||||
<v-img v-if="replyToContentType === 'm.video'" src="@/assets/icons/video_message.svg" />
|
||||
<v-icon v-if="replyToContentType === 'm.poll'" light>$vuetify.icons.poll</v-icon>
|
||||
<v-icon v-if="replyToContentType === 'm.poll'" theme="light">$vuetify.icons.poll</v-icon>
|
||||
</div>
|
||||
<div class="col col-auto">
|
||||
<v-btn fab x-small elevation="0" color="black" @click.stop="cancelEditReply">
|
||||
<v-icon color="white">cancel</v-icon>
|
||||
<v-btn icon="cancel" size="default" elevation="0" color="black" @click.stop="cancelEditReply">
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -163,7 +161,7 @@
|
|||
<v-row class="input-area-inner align-center" v-show="!showRecorder" v-if="$matrix.userCanSendMessageInCurrentRoom">
|
||||
<v-col class="flex-grow-1 flex-shrink-1 ma-0 pa-0">
|
||||
<v-textarea height="undefined" ref="messageInput" full-width auto-grow rows="1" v-model="currentInput"
|
||||
no-resize class="input-area-text" :placeholder="$t('message.your_message')" hide-details
|
||||
no-resize class="input-area-text input-plain" :placeholder="$t('message.your_message')" hide-details
|
||||
background-color="white" v-on:keydown.enter.prevent="
|
||||
() => {
|
||||
sendCurrentTextMessage();
|
||||
|
|
@ -172,58 +170,52 @@
|
|||
</v-col>
|
||||
|
||||
<v-col class="input-area-button text-center flex-grow-0 flex-shrink-1" v-if="editedEvent">
|
||||
<v-btn fab small elevation="0" color="black" @click.stop="cancelEditReply">
|
||||
<v-icon color="white">cancel</v-icon>
|
||||
<v-btn icon="cancel" elevation="0" color="black" @click.stop="cancelEditReply">
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col v-if="(!currentInput || currentInput.length == 0) && canCreatePoll && !replyToEvent"
|
||||
class="input-area-button text-center flex-grow-0 flex-shrink-1">
|
||||
<v-btn icon large color="black" @click="showCreatePollDialog = true">
|
||||
<v-icon dark>$vuetify.icons.poll</v-icon>
|
||||
<v-btn icon @click="showCreatePollDialog = true">
|
||||
<v-icon size="24">$vuetify.icons.poll</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col class="input-area-button text-center flex-grow-0 flex-shrink-1"
|
||||
v-if="!$config.disableMediaSharing && (!currentInput || currentInput.length == 0 || showRecorder)">
|
||||
<v-btn v-if="canRecordAudio" class="mic-button" ref="mic_button" fab small elevation="0" v-blur
|
||||
<v-btn icon="mic" :color="showRecorder ? 'black' : 'white'" v-if="canRecordAudio" class="mic-button" ref="mic_button" elevation="0" v-blur
|
||||
v-longTap:250="[showRecordingUI, startRecording]">
|
||||
<v-icon :color="showRecorder ? 'white' : 'black'">mic</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-else class="mic-button" ref="mic_button" fab small elevation="0" v-blur
|
||||
<v-btn icon="mic" :color="showRecorder ? 'black' : 'white'" v-else class="mic-button" ref="mic_button" elevation="0" v-blur
|
||||
@click.stop="showNoRecordingAvailableDialog = true">
|
||||
<v-icon :color="showRecorder ? 'white' : 'black'">mic</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col class="input-area-button text-center flex-grow-0 flex-shrink-1" v-else-if="currentInput && currentInput.length > 0">
|
||||
<v-btn fab small elevation="0" color="black" @click.stop="sendCurrentTextMessage"
|
||||
<v-btn :icon="editedEvent ? 'save' : 'arrow_upward'" size="default" elevation="0" color="black" @click.stop="sendCurrentTextMessage"
|
||||
:disabled="sendButtonDisabled">
|
||||
<v-icon color="white">{{ editedEvent ? "save" : "arrow_upward" }}</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col class="input-area-button text-center flex-grow-0 flex-shrink-1 input-more-icon">
|
||||
<v-btn fab small elevation="0" v-blur @click.stop="
|
||||
<v-btn size="small" elevation="0" v-blur @click.stop="
|
||||
isEmojiQuickReaction = false;
|
||||
showMoreMessageOperations($event)
|
||||
">
|
||||
<v-icon>$vuetify.icons.addReaction</v-icon>
|
||||
" icon="$vuetify.icons.addReaction">
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col v-if="$config.shortCodeStickers" class="input-area-button text-center flex-grow-0 flex-shrink-1">
|
||||
<v-btn id="btn-attach" icon large color="black" @click="showStickerPicker"
|
||||
<v-btn id="btn-stickers" icon="face" @click="showStickerPicker"
|
||||
:disabled="attachButtonDisabled">
|
||||
<v-icon large>face</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
|
||||
<v-col v-if="!$config.disableMediaSharing" class="input-area-button text-center flex-grow-0 flex-shrink-1">
|
||||
<label icon flat ref="attachmentLabel">
|
||||
<v-btn icon large color="black" @click="showAttachmentPicker"
|
||||
<v-btn icon @click="showAttachmentPicker"
|
||||
:disabled="attachButtonDisabled">
|
||||
<v-icon x-large>add_circle_outline</v-icon>
|
||||
<v-icon size="36">add_circle_outline</v-icon>
|
||||
</v-btn>
|
||||
</label>
|
||||
</v-col>
|
||||
|
|
@ -296,7 +288,7 @@
|
|||
</template>
|
||||
<v-divider></v-divider>
|
||||
<v-textarea v-if="showAttachmentCaptionInput" v-model="attachmentCaption" ref="attachmentCaption" color="black" background-color="transparent"
|
||||
solo full-width auto-grow rows="1" no-resize hide-details :placeholder="$t('file_mode.add_a_message')"></v-textarea>
|
||||
variant="solo" full-width auto-grow rows="1" no-resize hide-details :placeholder="$t('file_mode.add_a_message')"></v-textarea>
|
||||
<v-card-actions>
|
||||
<v-spacer>
|
||||
<div v-if="currentSendError">{{ currentSendError }}</div>
|
||||
|
|
@ -347,14 +339,13 @@
|
|||
<CreatePollDialog :show="showCreatePollDialog" @close="showCreatePollDialog = false" />
|
||||
|
||||
<UserProfileDialog
|
||||
:show="showProfileDialog"
|
||||
v-model="showProfileDialog"
|
||||
:activeMember="compActiveMember"
|
||||
:room="room"
|
||||
@close="showProfileDialog = false"
|
||||
/>
|
||||
|
||||
<!-- PURGE ROOM POPUP -->
|
||||
<PurgeRoomDialog :show="showPurgeConfirmation" :room="room" @close="showPurgeConfirmation = false" />
|
||||
<PurgeRoomDialog v-model="showPurgeConfirmation" :room="room" />
|
||||
|
||||
<RoomExport :room="room" v-if="downloadingChat" v-on:close="downloadingChat = false" />
|
||||
|
||||
|
|
@ -552,16 +543,6 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
filters: {
|
||||
latestReply(contents) {
|
||||
const contentArr = contents.split("\n").reverse();
|
||||
if (contentArr[0] === "") {
|
||||
contentArr.shift();
|
||||
}
|
||||
return (contentArr && contentArr.length > 0) ? contentArr[0].replace(/^> (<.*> )?/g, "") : "";
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
emitter.on('audio-playback-ended', this.audioPlaybackEnded);
|
||||
const container = this.chatContainer;
|
||||
|
|
@ -589,6 +570,14 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
latestReply() {
|
||||
const contents = this.replyToEvent ? this.replyToEvent.getContent().body : "";
|
||||
const contentArr = contents.split("\n").reverse();
|
||||
if (contentArr[0] === "") {
|
||||
contentArr.shift();
|
||||
}
|
||||
return (contentArr && contentArr.length > 0) ? contentArr[0].replace(/^> (<.*> )?/g, "") : "";
|
||||
},
|
||||
heartEmoji() {
|
||||
return this.$refs.emojiPicker.mapEmojis["Symbols"].find(({ aliases }) => aliases.includes('heart')).data;
|
||||
},
|
||||
|
|
@ -800,20 +789,20 @@ export default {
|
|||
roomWelcomeHeader() {
|
||||
if (!this.hideRoomWelcomeHeader && this.roomCreatedByUsRecently) {
|
||||
if (this.roomDisplayType == ROOM_TYPE_CHANNEL) {
|
||||
return WelcomeHeaderChannel;
|
||||
return markRaw(WelcomeHeaderChannel);
|
||||
}
|
||||
if (this.isDirectRoom) {
|
||||
return WelcomeHeaderDirectChat;
|
||||
return markRaw(WelcomeHeaderDirectChat);
|
||||
}
|
||||
return WelcomeHeaderRoom;
|
||||
return markRaw(WelcomeHeaderRoom);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
messageOperationsComponent() {
|
||||
if (this.room.displayType == ROOM_TYPE_CHANNEL) {
|
||||
return MessageOperationsChannel;
|
||||
return markRaw(MessageOperationsChannel);
|
||||
}
|
||||
return MessageOperations;
|
||||
return markRaw(MessageOperations);
|
||||
},
|
||||
chatContainerStyle() {
|
||||
if (this.$config.chat_backgrounds && this.room && this.roomId) {
|
||||
|
|
|
|||
|
|
@ -38,17 +38,15 @@
|
|||
</v-avatar>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
|
||||
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red"
|
||||
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" icon="$vuetify.icons.ic_moderator-delete" class="mx-2 box-shadow-none" theme="light" size="small" color="red"
|
||||
@click.stop="$emit('purge')">
|
||||
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn id="btn-leave-room" class="mx-2 box-shadow-none" fab dark small color="red" @click.stop="leaveRoom" v-else>
|
||||
<v-icon color="white">$vuetify.icons.ic_member-leave</v-icon>
|
||||
<v-btn id="btn-leave-room" v-else icon="$vuetify.icons.ic_member-leave" class="mx-2 box-shadow-none" theme="light" size="small" color="red" @click.stop="leaveRoom">
|
||||
</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1 clickable close-button more-menu-button">
|
||||
<div :class="{ 'popup-open': showMoreMenu }">
|
||||
<v-btn class="mx-2 box-shadow-none" fab dark small color="transparent" @click.stop="onShowMoreMenu">
|
||||
<v-btn class="mx-2 box-shadow-none" icon theme="dark" size="small" color="transparent" @click.stop="onShowMoreMenu">
|
||||
<v-icon size="15">$vuetify.icons.ic_more</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
|
@ -56,7 +54,7 @@
|
|||
</v-row>
|
||||
|
||||
<!-- "REALLY LEAVE?" dialog -->
|
||||
<LeaveRoomDialog :show="showLeaveConfirmation" :room="room" @close="showLeaveConfirmation = false" />
|
||||
<LeaveRoomDialog v-model="showLeaveConfirmation" :room="room" />
|
||||
|
||||
<!-- PROFILE INFO POPUP -->
|
||||
<ProfileInfoPopup :show="showProfileInfo" @close="showProfileInfo = false" />
|
||||
|
|
@ -79,6 +77,7 @@ import roomInfoMixin from "./roomInfoMixin";
|
|||
export default {
|
||||
name: "ChatHeader",
|
||||
mixins: [profileInfoMixin, roomInfoMixin],
|
||||
emits: ['download','view-room-details','header-click'],
|
||||
components: {
|
||||
LeaveRoomDialog,
|
||||
ProfileInfoPopup,
|
||||
|
|
|
|||
|
|
@ -43,22 +43,20 @@
|
|||
</v-col>
|
||||
|
||||
<v-col cols="auto" class="text-end ma-0 pa-0 ms-1">
|
||||
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" class="mx-2 box-shadow-none" fab dark small color="red"
|
||||
<v-btn id="btn-purge-room" v-if="userCanPurgeRoom" icon="$vuetify.icons.ic_moderator-delete" class="mx-2 box-shadow-none" theme="light" size="small" color="red"
|
||||
@click.stop="$emit('purge')">
|
||||
<v-icon light>$vuetify.icons.ic_moderator-delete</v-icon>
|
||||
</v-btn>
|
||||
<template v-else>
|
||||
<v-btn v-if="$matrix.joinedRooms.length == 1" id="btn-leave-room" class="box-shadow-none leave-button" color="red" @click.stop="leaveRoom">
|
||||
<v-icon color="white">$vuetify.icons.ic_member-leave</v-icon>{{ $t('room.leave') }}
|
||||
<v-btn v-if="$matrix.joinedRooms.length == 1" id="btn-leave-room" class="box-shadow-none leave-button" theme="dark" color="red" @click.stop="leaveRoom">
|
||||
<v-icon color="white"></v-icon>{{ $t('room.leave') }}
|
||||
</v-btn>
|
||||
<v-btn id="btn-leave-room" class="mx-2 box-shadow-none" fab dark small color="red" @click.stop="leaveRoom" v-else>
|
||||
<v-icon color="white">$vuetify.icons.ic_member-leave</v-icon>
|
||||
<v-btn v-else id="btn-leave-room" icon="$vuetify.icons.ic_member-leave" class="mx-2 box-shadow-none" theme="dark" size="small" color="red" @click.stop="leaveRoom">
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-col>
|
||||
<v-col v-if="$matrix.joinedRooms.length > 1" cols="auto" class="text-end ma-0 pa-0 ms-1 clickable close-button more-menu-button">
|
||||
<div :class="{ 'popup-open': showMoreMenu }">
|
||||
<v-btn class="mx-2 box-shadow-none" fab dark small color="transparent" @click.stop="onShowMoreMenu">
|
||||
<v-btn class="mx-2 box-shadow-none" icon theme="dark" size="small" color="transparent" @click.stop="onShowMoreMenu">
|
||||
<v-icon size="15">$vuetify.icons.ic_more</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
|
@ -66,7 +64,7 @@
|
|||
</v-row>
|
||||
|
||||
<!-- "REALLY LEAVE?" dialog -->
|
||||
<LeaveRoomDialog :show="showLeaveConfirmation" :room="room" @close="showLeaveConfirmation = false" />
|
||||
<LeaveRoomDialog v-model="showLeaveConfirmation" :room="room" />
|
||||
|
||||
<!-- PROFILE INFO POPUP -->
|
||||
<ProfileInfoPopup :show="showProfileInfo" @close="showProfileInfo = false" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
v-show="room"
|
||||
scrollable
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '940px' : '95%'"
|
||||
|
|
@ -101,34 +100,18 @@
|
|||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
import util from "../plugins/utils";
|
||||
import InputControl from "./InputControl.vue";
|
||||
import RoomDialogBase from "./RoomDialogBase.vue";
|
||||
|
||||
export default {
|
||||
name: "CreatePollDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function() {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
extends: RoomDialogBase,
|
||||
data() {
|
||||
return this.defaultData();
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit("close");
|
||||
} else {
|
||||
methods: {
|
||||
onOpenDialog() {
|
||||
// Reset values
|
||||
let defaults = this.defaultData();
|
||||
this.isValid = defaults.isValid;
|
||||
|
|
@ -142,13 +125,9 @@ export default {
|
|||
if (this.$refs.pollcreateform) {
|
||||
this.$refs.pollcreateform.resetValidation();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
defaultData() {
|
||||
return {
|
||||
showDialog: false,
|
||||
isValid: true,
|
||||
isCreating: false,
|
||||
status: String.fromCharCode(160),
|
||||
|
|
|
|||
|
|
@ -76,11 +76,11 @@
|
|||
<v-row class="align-center">
|
||||
<v-col class="py-0">
|
||||
<div class="text-start font-weight-bold">{{ $t("join.choose_name") }}</div>
|
||||
<v-select ref="avatar" :items="availableAvatars" cache-items outlined dense @change="selectAvatar"
|
||||
<v-select ref="avatar" :items="availableAvatars" variant="outlined" dense @change="selectAvatar"
|
||||
:value="selectedProfile">
|
||||
<template v-slot:selection>
|
||||
<v-text-field background-color="transparent" solo flat hide-details
|
||||
@click.native.stop="(event) => event.target.focus()" @focus="$event.target.select()"
|
||||
<v-text-field background-color="transparent" variant="solo" flat hide-details
|
||||
@click.stop="(event) => event.target.focus()" @focus="$event.target.select()"
|
||||
v-model="selectedProfile.name"></v-text-field>
|
||||
</template>
|
||||
<template v-slot:item="data">
|
||||
|
|
@ -124,8 +124,10 @@
|
|||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<MessageRetentionDialog :initialValue="limitHistoryMilliseconds" :show="selectRetentionDialog"
|
||||
v-on:close="selectRetentionDialog = false" v-on:message-retention-update="onUpdateHistoryLimit" />
|
||||
<MessageRetentionDialog
|
||||
v-model="selectRetentionDialog"
|
||||
:initialValue="limitHistoryMilliseconds"
|
||||
v-on:message-retention-update="onUpdateHistoryLimit" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
:key="device.deviceId"
|
||||
:value="device.deviceId"
|
||||
>
|
||||
<template v-slot:default="{ active }">
|
||||
<template v-slot:default="{ isActive }">
|
||||
<v-list-item-title>{{ displayName(device) }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{
|
||||
verificationStatus(device)
|
||||
}}</v-list-item-subtitle>
|
||||
<v-list-item-action v-if="active">
|
||||
<v-list-item-action v-if="isActive">
|
||||
<v-btn icon>
|
||||
<v-icon
|
||||
:color="
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
? 'red'
|
||||
: device.isVerified()
|
||||
? 'green'
|
||||
: 'grey lighten-1'
|
||||
: 'grey-lighten-1'
|
||||
"
|
||||
>verified_user</v-icon
|
||||
>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<div color="rgba(255,255,255,0.1)" class="text-center">
|
||||
<v-form v-model="isValid" ref="form">
|
||||
<v-text-field v-model="user.user_id" :label="$t('getlink.username')" color="black" background-color="white"
|
||||
solo :rules="[(v) => !!v || $t('login.username_required')]" :error="userErrorMessage != null"
|
||||
variant="solo" :rules="[(v) => !!v || $t('login.username_required')]" :error="userErrorMessage != null"
|
||||
:error-messages="userErrorMessage" required v-on:keyup.enter="onUsernameEnter"
|
||||
v-on:keydown="hasError = false"></v-text-field>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export default {
|
|||
prop: "modelValue",
|
||||
event: "update:modelValue",
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<v-col sm="8" align="center">
|
||||
<div class="text-start font-weight-light">{{ $t("login.email") }}</div>
|
||||
<v-text-field v-model="email" color="black" :rules="emailRules" type="email" maxlength="200"
|
||||
background-color="white" v-on:keyup.enter="onEmailEntered(email)" autofocus solo></v-text-field>
|
||||
background-color="white" v-on:keyup.enter="onEmailEntered(email)" autofocus variant="solo"></v-text-field>
|
||||
<v-btn :disabled="!emailIsValid" color="black" depressed class="filled-button"
|
||||
@click.stop="onEmailEntered(email)">
|
||||
{{ $t("login.send_verification") }}
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
<v-col sm="8" align="center">
|
||||
<div class="text-start font-weight-light">{{ $t("login.registration_token") }}</div>
|
||||
<v-text-field v-model="token" color="black" :rules="tokenRules" type="text" maxlength="64"
|
||||
background-color="white" v-on:keyup.enter="onTokenEntered(token)" autofocus solo></v-text-field>
|
||||
background-color="white" v-on:keyup.enter="onTokenEntered(token)" autofocus variant="solo"></v-text-field>
|
||||
<v-btn :disabled="!tokenIsValid" color="black" depressed class="filled-button"
|
||||
@click.stop="onTokenEntered(token)">
|
||||
{{ $t("login.send_token") }}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<div class="flex-grow-0 flex-shrink-0 chip-group-wrapper">
|
||||
<div class="h4">{{$t('invite.send_invites_to')}}</div>
|
||||
<div>{{ status }}</div>
|
||||
<v-chip-group active-class="primary--text" column>
|
||||
<v-chip-group selected-class="primary--text" column>
|
||||
<v-chip
|
||||
v-for="member in selectedMembers"
|
||||
:key="member.userId"
|
||||
|
|
@ -43,14 +43,14 @@
|
|||
}}</span>
|
||||
</v-avatar>
|
||||
</template>
|
||||
<template v-slot:default="{ active }">
|
||||
<template v-slot:default="{ isActive }">
|
||||
<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-action>
|
||||
<v-btn icon v-if="active">
|
||||
<v-icon color="grey lighten-1">check</v-icon>
|
||||
<v-btn icon v-if="isActive">
|
||||
<v-icon color="grey-lighten-1">check</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
|
||||
<v-row v-if="canEditProfile">
|
||||
<v-col cols="10" sm="7" class="py-0">
|
||||
<v-select ref="avatar" :items="availableAvatars" cache-items outlined dense @change="selectAvatar"
|
||||
<v-select ref="avatar" :items="availableAvatars" variant="outlined" dense @change="selectAvatar"
|
||||
:value="selectedProfile" single-line autofocus>
|
||||
<template v-slot:selection>
|
||||
<v-text-field background-color="transparent" solo flat hide-details
|
||||
@click.native.stop="(event) => event.target.focus()" @focus="$event.target.select()"
|
||||
<v-text-field background-color="transparent" variant="solo" flat hide-details
|
||||
@click.stop="(event) => event.target.focus()" @focus="$event.target.select()"
|
||||
v-model="selectedProfile.name"></v-text-field>
|
||||
</template>
|
||||
<template v-slot:item="data">
|
||||
|
|
@ -70,11 +70,11 @@
|
|||
|
||||
<interactive-auth ref="interactiveAuth" />
|
||||
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" large
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" size="large"
|
||||
@click.stop="handleJoin" :loading="loading" v-if="!currentUser">{{
|
||||
roomId && roomId.startsWith("@") ? $t("join.enter_room_user") : $t("join.enter_room")
|
||||
}}</v-btn>
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" large
|
||||
<v-btn id="btn-join" class="btn-dark" :disabled="!acceptUA || (room && room.selfMembership == 'ban')" size="large"
|
||||
block @click.stop="handleJoin" :loading="loading" v-else>{{
|
||||
roomId && roomId.startsWith("@") ? $t("join.join_user") : $t("join.join")
|
||||
}}</v-btn>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
v-show="room"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '688px' : '95%'"
|
||||
>
|
||||
|
|
@ -69,41 +68,21 @@
|
|||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import RoomDialogBase from "./RoomDialogBase.vue";
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
|
||||
export default {
|
||||
name: "LeaveRoomDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
extends: RoomDialogBase,
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
lastRoom: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit("close");
|
||||
} else {
|
||||
this.lastRoom = this.onlyJoinedToThisRoom();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onOpenDialog() {
|
||||
this.lastRoom = this.onlyJoinedToThisRoom();
|
||||
},
|
||||
onlyJoinedToThisRoom() {
|
||||
const joinedRooms = this.$matrix.joinedRooms;
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
:label="$t('login.username')"
|
||||
color="black"
|
||||
background-color="white"
|
||||
solo
|
||||
variant="solo"
|
||||
:rules="[(v) => !!v || $t('login.username_required')]"
|
||||
:error="userErrorMessage != null"
|
||||
:error-messages="userErrorMessage"
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
:label="$t('login.password')"
|
||||
color="black"
|
||||
background-color="#f5f5f5"
|
||||
filled
|
||||
variant="filled"
|
||||
type="password"
|
||||
:rules="[(v) => !!v || $t('login.password_required')]"
|
||||
:error="passErrorMessage != null"
|
||||
|
|
|
|||
|
|
@ -16,14 +16,12 @@
|
|||
>
|
||||
<slot></slot>
|
||||
<v-btn
|
||||
fab
|
||||
x-small
|
||||
icon="cancel"
|
||||
size="small"
|
||||
elevation="0"
|
||||
color="black"
|
||||
@click.stop="backgroundClick"
|
||||
class="bottom-sheet-close"
|
||||
>
|
||||
<v-icon color="white" >cancel</v-icon>
|
||||
</v-btn>
|
||||
</SwipeableBottomSheet>
|
||||
</div>
|
||||
|
|
@ -91,8 +89,8 @@ export default {
|
|||
.message-operations-bottom-sheet {
|
||||
.bottom-sheet-close {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
right: 4px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.transition-bg {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<v-dialog v-model="showDialog" v-show="room" class="ma-0 pa-0" :width="$vuetify.display.smAndUp ? '688px' : '95%'">
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '688px' : '95%'">
|
||||
<div class="dialog-content text-center">
|
||||
<template>
|
||||
<h2>{{ $t("room_info.message_retention") }}</h2>
|
||||
|
|
@ -27,18 +30,12 @@
|
|||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
import RoomDialogBase from "./RoomDialogBase.vue";
|
||||
|
||||
export default {
|
||||
name: "MessageRetentionDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
extends: RoomDialogBase,
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
initialValue: {
|
||||
type: Number,
|
||||
default: function () {
|
||||
|
|
@ -48,32 +45,20 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
isValid: true,
|
||||
retention: 0,
|
||||
retentionMinValue: 60,
|
||||
retentionMaxValue: 60 * 60 * 24 * 500
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog(val, oldVal) {
|
||||
if (!val && oldVal) {
|
||||
this.$emit("close");
|
||||
} else if (val && !oldVal) {
|
||||
// Showing, reset
|
||||
this.setInitialValue();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setInitialValue();
|
||||
},
|
||||
methods: {
|
||||
onOpenDialog() {
|
||||
// Showing, reset
|
||||
this.setInitialValue();
|
||||
},
|
||||
setInitialValue() {
|
||||
this.isValid = true;
|
||||
if (this.room) {
|
||||
|
|
|
|||
|
|
@ -113,9 +113,9 @@
|
|||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '940px' : '80%'"
|
||||
>
|
||||
<v-card :disabled="settingPassword">
|
||||
<v-card-title>{{ $matrix.currentUser.is_guest ? $t("profile.set_password") : $t("profile.change_password") }}</v-card-title>
|
||||
<v-card-text>
|
||||
<v-card :disabled="settingPassword" class="dialog-content">
|
||||
<h2 class="dialog-title">{{ $matrix.currentUser.is_guest ? $t("profile.set_password") : $t("profile.change_password") }}</h2>
|
||||
<div class="dialog-text">
|
||||
<v-text-field
|
||||
v-if="!$matrix.currentUser.is_guest"
|
||||
v-model="password"
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
<div class="text-red" v-if="passwordErrorMessage">
|
||||
{{ passwordErrorMessage }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
</div>
|
||||
<v-divider></v-divider>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
|
|
@ -174,7 +174,7 @@
|
|||
</v-dialog>
|
||||
|
||||
<!-- edit display name dialog -->
|
||||
<v-dialog
|
||||
<RoundedDialog
|
||||
v-model="showEditDisplaynameDialog"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '940px' : '80%'"
|
||||
|
|
@ -207,7 +207,7 @@
|
|||
>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</RoundedDialog>
|
||||
|
||||
<SelectLanguageDialog
|
||||
v-model="showSelectLanguageDialog"
|
||||
|
|
@ -265,6 +265,7 @@ import AuthedImage from "./AuthedImage.vue";
|
|||
import CopyLink from "./CopyLink.vue"
|
||||
import { requestNotificationPermission, windowNotificationPermission } from "../plugins/notificationAndServiceWorker.js"
|
||||
import { mapState } from 'vuex'
|
||||
import RoundedDialog from "./RoundedDialog.vue";
|
||||
|
||||
export default {
|
||||
name: "Profile",
|
||||
|
|
@ -274,7 +275,8 @@ export default {
|
|||
SelectLanguageDialog,
|
||||
LogoutRoomDialog,
|
||||
CopyLink,
|
||||
AuthedImage
|
||||
AuthedImage,
|
||||
RoundedDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<v-dialog
|
||||
persistent
|
||||
v-model="showDialog"
|
||||
v-show="room" class="ma-0 pa-0"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '688px' : '95%'"
|
||||
>
|
||||
<div v-if="timeout == -1" class="dialog-content text-center">
|
||||
|
|
@ -96,47 +96,25 @@
|
|||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
import { STATE_EVENT_ROOM_DELETION_NOTICE } from "../plugins/utils";
|
||||
import RoomDialogBase from "./RoomDialogBase.vue";
|
||||
|
||||
export default {
|
||||
name: "LeaveRoomDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
name: "PurgeRoomDialog",
|
||||
extends: RoomDialogBase,
|
||||
data() {
|
||||
return {
|
||||
timeout: -1,
|
||||
timeoutTimer: null,
|
||||
showDialog: false,
|
||||
isPurging: false,
|
||||
status: null,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog(val, oldVal) {
|
||||
if (!val && oldVal) {
|
||||
this.undo();
|
||||
this.$emit("close");
|
||||
} else if (val && !oldVal) {
|
||||
// Showing, reset
|
||||
this.status = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onOpenDialog() {
|
||||
// Showing, reset
|
||||
this.status = null;
|
||||
},
|
||||
undo() {
|
||||
if (this.timeoutTimer) {
|
||||
clearInterval(this.timeoutTimer);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-model="showDialog"
|
||||
v-show="room"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '688px' : '95%'"
|
||||
>
|
||||
|
|
@ -39,37 +38,16 @@
|
|||
</v-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
import RoomDialogBase from "./RoomDialogBase.vue";
|
||||
|
||||
export default {
|
||||
name: "ReportRoomDialog",
|
||||
mixins: [roomInfoMixin],
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
extends: RoomDialogBase,
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
reason: ""
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
},
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit("close");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onReport() {
|
||||
|
|
|
|||
43
src/components/RoomDialogBase.vue
Normal file
43
src/components/RoomDialogBase.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<template><div></div></template>
|
||||
<script>
|
||||
import roomInfoMixin from "./roomInfoMixin";
|
||||
|
||||
export default {
|
||||
name: "RoomDialogBase",
|
||||
mixins: [roomInfoMixin],
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
data() {
|
||||
return {
|
||||
showDialog: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
room() {
|
||||
this.showDialog = this.shouldShow();
|
||||
},
|
||||
modelValue() {
|
||||
this.showDialog = this.shouldShow();
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit('update:modelValue', false)
|
||||
} else {
|
||||
this.onOpenDialog();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
shouldShow() {
|
||||
return this.modelValue && this.room ? true : false;
|
||||
},
|
||||
onOpenDialog() {
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -101,6 +101,7 @@ import "../services/filesaver.cjs";
|
|||
export default {
|
||||
name: "RoomExport",
|
||||
mixins: [chatMixin],
|
||||
emits: ["close"],
|
||||
components: {
|
||||
ChatHeader,
|
||||
MessageIncomingText,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
maxlength="50"
|
||||
@blur="updateRoomName()"
|
||||
@keyup.enter="updateRoomName()"
|
||||
solo
|
||||
variant="solo"
|
||||
></v-text-field>
|
||||
</div>
|
||||
<div :class="{'topic':true,'cursor-default':!userCanPurgeRoom}">
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
autofocus
|
||||
@blur="updateRoomTopic()"
|
||||
@keyup.enter="updateRoomTopic()"
|
||||
solo
|
||||
variant="solo"
|
||||
>
|
||||
</v-text-field>
|
||||
</div>
|
||||
|
|
@ -108,36 +108,26 @@
|
|||
{{ item.text }}
|
||||
</template>
|
||||
<template v-slot:item="{ item, attrs, on }">
|
||||
<v-list-item v-on="on" v-bind="attrs" #default="{ active }">
|
||||
<v-list-item v-on="on" v-bind="attrs">
|
||||
<template v-slot:prepend>
|
||||
<v-avatar color="grey">
|
||||
<v-icon color="black">{{ item.icon }}</v-icon>
|
||||
</v-avatar>
|
||||
</template>
|
||||
<v-list-item-title v-text="item.text"></v-list-item-title>
|
||||
<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>
|
||||
<v-list-item-title>{{ item.text }}</v-list-item-title>
|
||||
<template v-slot:append="{ isActive }">
|
||||
<v-list-item-action>
|
||||
<v-btn icon v-if="isActive">
|
||||
<v-icon color="grey-lighten-1">check</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-select>
|
||||
|
||||
<!-- <div v-if="anyoneCanJoin">
|
||||
<div>Anyone with a link can join.</div>
|
||||
<v-text-field
|
||||
:value="publicRoomLink"
|
||||
readonly
|
||||
append-icon="content_copy"
|
||||
filled
|
||||
type="text"
|
||||
@click:append="copyRoomLink"
|
||||
></v-text-field>
|
||||
</div> -->
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<v-card class="account ma-3" flat>
|
||||
<v-card-title class="h2">{{ $t("room_info.message_retention") }}</v-card-title>
|
||||
<v-card-text v-if="canViewRetentionPolicy">
|
||||
|
|
@ -168,7 +158,7 @@
|
|||
</v-card-text>
|
||||
|
||||
</v-card>
|
||||
|
||||
|
||||
<v-card class="account ma-3" flat v-if="canChangeReadOnly()">
|
||||
<v-card-title class="h2">{{ $t("room_info.moderation") }}</v-card-title>
|
||||
<v-card-text class="" v-if="canChangeReadOnly()">
|
||||
|
|
@ -179,7 +169,7 @@
|
|||
<div class="option-text">{{ $t('room_info.read_only_room_info') }}</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<v-card class="account ma-3" flat>
|
||||
<v-card-title class="h2">{{ $t("room_info.report") }}</v-card-title>
|
||||
<v-card-text class="">
|
||||
|
|
@ -188,21 +178,21 @@
|
|||
<v-btn
|
||||
color="black"
|
||||
depressed
|
||||
small
|
||||
size="small"
|
||||
class="outlined-button"
|
||||
@click.stop="report"
|
||||
>{{ $t("room_info.report") }}</v-btn>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<v-card class="members ma-3" flat>
|
||||
<v-card-title class="h2"
|
||||
>{{ $t("room_info.members") }}<v-spacer></v-spacer>
|
||||
<div>{{ members.length }}</div></v-card-title
|
||||
>
|
||||
<v-list>
|
||||
<template v-for="(member, index) in members" :key="member.userId">
|
||||
<template v-for="(member, index) in members" :key="member.userId">
|
||||
<v-list-item
|
||||
class="member"
|
||||
v-show="showAllMembers || index < SHOW_MEMBER_LIMIT"
|
||||
|
|
@ -266,35 +256,30 @@
|
|||
</div>
|
||||
|
||||
<UserProfileDialog
|
||||
:show="showMemberActionConfirmation"
|
||||
v-model="showMemberActionConfirmation"
|
||||
:activeMember="activeMember || members[0]"
|
||||
:room="room"
|
||||
@close="showMemberActionConfirmation = false"
|
||||
/>
|
||||
|
||||
<LeaveRoomDialog
|
||||
:show="showLeaveConfirmation"
|
||||
v-model="showLeaveConfirmation"
|
||||
:room="room"
|
||||
@close="showLeaveConfirmation = false"
|
||||
/>
|
||||
|
||||
<PurgeRoomDialog
|
||||
:show="showPurgeConfirmation"
|
||||
v-model="showPurgeConfirmation"
|
||||
:room="room"
|
||||
@close="showPurgeConfirmation = false"
|
||||
/>
|
||||
|
||||
<MessageRetentionDialog
|
||||
:show="showMessageRetentionDialog"
|
||||
v-model="showMessageRetentionDialog"
|
||||
:room="room"
|
||||
@close="showMessageRetentionDialog = false"
|
||||
v-on:message-retention-update="onMessageRetention"
|
||||
/>
|
||||
|
||||
<ReportRoomDialog
|
||||
:show="showReportDialog"
|
||||
v-model="showReportDialog"
|
||||
:room="room"
|
||||
@close="showReportDialog = false"
|
||||
/>
|
||||
|
||||
<RoomExport :room="room" v-if="exporting" v-on:close="exporting = false" />
|
||||
|
|
|
|||
|
|
@ -26,13 +26,15 @@
|
|||
|
||||
<v-list-item-title class="room-list-name">{{ room.name }}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ room.topic }}</v-list-item-subtitle>
|
||||
<v-list-item-action>
|
||||
<v-btn id="btn-accept" class="filled-button" depressed color="black" @click.stop="acceptInvitation(room)">{{
|
||||
$t("menu.join") }}</v-btn>
|
||||
<v-btn v-if="!room.isServiceNoticeRoom" id="btn-reject" class="filled-button" color="black"
|
||||
@click.stop="rejectInvitation(room)" text>{{
|
||||
$t("menu.ignore") }}</v-btn>
|
||||
</v-list-item-action>
|
||||
<template v-slot:append>
|
||||
<v-list-item-action>
|
||||
<v-btn id="btn-accept" class="filled-button" depressed color="black" @click.stop="acceptInvitation(room)">{{
|
||||
$t("menu.join") }}</v-btn>
|
||||
<v-btn v-if="!room.isServiceNoticeRoom" id="btn-reject" class="filled-button" color="black"
|
||||
@click.stop="rejectInvitation(room)" text>{{
|
||||
$t("menu.ignore") }}</v-btn>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item v-for="room in joinedRooms" :key="room.roomId" :value="room.roomId"
|
||||
|
|
@ -51,10 +53,12 @@
|
|||
<v-list-item-subtitle class="room-list-new-messages" v-if="notificationCount(room) > 0">
|
||||
{{ $t("room.room_list_new_messages", { count: notificationCount(room) }) }}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-action>
|
||||
<v-icon size="16" v-if="room.roomId == $matrix.currentRoomId">$vuetify.icons.ic_circle_filled</v-icon>
|
||||
<v-icon size="16" v-else>$vuetify.icons.ic_circle</v-icon>
|
||||
</v-list-item-action>
|
||||
<template v-slot:append>
|
||||
<v-list-item-action>
|
||||
<v-icon size="16" v-if="room.roomId == $matrix.currentRoomId">$vuetify.icons.ic_circle_filled</v-icon>
|
||||
<v-icon size="16" v-else>$vuetify.icons.ic_circle</v-icon>
|
||||
</v-list-item-action>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-select outlined dense :items="availableRoomTypes"
|
||||
<v-select variant="outlined" dense :items="availableRoomTypes"
|
||||
:value="modelValue"
|
||||
@change="$emit('update:modelValue', $event)"
|
||||
:reduce="(obj) => obj.value">
|
||||
|
|
|
|||
14
src/components/RoundedDialog.vue
Normal file
14
src/components/RoundedDialog.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<v-dialog v-bind="{ ...$props, ...$attrs }" content-class="v-dialog-rounded">
|
||||
<slot></slot>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
<RoundedDialog
|
||||
class="ma-0 pa-0"
|
||||
v-bind="{ ...$props, ...$attrs }"
|
||||
:width="$vuetify.display.smAndUp ? '940px' : '90%'"
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<v-select
|
||||
v-model="$i18n.locale"
|
||||
:items="languages"
|
||||
menu-props="auto"
|
||||
:menu-props="{ auto: true }"
|
||||
:label="$t('profile.select_language')"
|
||||
v-on:change="$store.commit('setLanguage', $i18n.locale)"
|
||||
hide-details
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
<v-card-actions>
|
||||
<v-btn
|
||||
id="btn-done"
|
||||
color="black"
|
||||
depressed
|
||||
block
|
||||
class="btn-dark"
|
||||
|
|
@ -37,14 +36,16 @@
|
|||
>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</RoundedDialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LanguageMixin from "./languageMixin";
|
||||
import RoundedDialog from "./RoundedDialog.vue";
|
||||
|
||||
export default {
|
||||
mixins: [LanguageMixin],
|
||||
components: { RoundedDialog }
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,17 +5,14 @@
|
|||
centered
|
||||
class="tabs"
|
||||
show-arrows
|
||||
slider-color="primary"
|
||||
>
|
||||
<v-tabs-slider></v-tabs-slider>
|
||||
|
||||
<v-tab v-for="pack in packs" :key="pack">
|
||||
<v-tab v-for="(pack,ipack) in packs" :key="'pack-' + ipack" :value="'pack-' + ipack">
|
||||
{{ pack }}
|
||||
<v-icon>mdi-phone</v-icon>
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
<v-tabs-items v-model="currentStickerPack" class="tab-items">
|
||||
<v-tab-item v-for="pack in packs" :key="pack">
|
||||
<v-tabs-window v-model="currentStickerPack">
|
||||
<v-window-item v-for="(pack,ipack) in packs" :key="'pack-content-' + ipack" :value="'pack-' + ipack">
|
||||
<v-card flat>
|
||||
<v-container fluid>
|
||||
<v-row>
|
||||
|
|
@ -25,8 +22,8 @@
|
|||
</v-row>
|
||||
</v-container>
|
||||
</v-card>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-window-item>
|
||||
</v-tabs-window>
|
||||
</BottomSheet>
|
||||
</template>
|
||||
|
||||
|
|
@ -40,17 +37,14 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
currentStickerPack: 'tab-0',
|
||||
currentStickerPack: 'pack-0',
|
||||
packs: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
packs() {
|
||||
return stickers.getPacks();
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
open() {
|
||||
this.packs = stickers.getPacks();
|
||||
this.$refs.sheet.open();
|
||||
},
|
||||
stickersInPack(pack) {
|
||||
|
|
@ -69,6 +63,10 @@ export default {
|
|||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.sheetContent {
|
||||
top: 40px !important;
|
||||
padding: 0 20px 20px 20px !important;
|
||||
}
|
||||
.sticker-picker {
|
||||
z-index: 10;
|
||||
|
||||
|
|
@ -76,6 +74,7 @@ export default {
|
|||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: 1;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
<template>
|
||||
<v-dialog
|
||||
v-if="activeMember"
|
||||
v-model="showDialog"
|
||||
v-show="room"
|
||||
class="ma-0 pa-0"
|
||||
:width="$vuetify.display.smAndUp ? '688px' : '95%'"
|
||||
v-if="showDialog"
|
||||
>
|
||||
<div class="dialog-content text-center member-action-dialog">
|
||||
<div class="pt-4">
|
||||
|
|
@ -39,7 +38,7 @@
|
|||
</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-btn text size="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="canBanUserComp">
|
||||
|
|
@ -47,13 +46,13 @@
|
|||
<v-icon left>$vuetify.icons.kickout</v-icon> {{ $t("menu.user_kick_and_ban") }}
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-btn text x-large block v-if="activeMember.userId != $matrix.currentUserId && !isAdminComp && canMakeAdminComp" class="start-private-chat clickable d-block text-none justify-start" @click="makeAdmin(activeMember)">
|
||||
<v-btn text size="x-large" block v-if="activeMember.userId != $matrix.currentUserId && !isAdminComp && canMakeAdminComp" 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 && !isModeratorComp && !isAdminComp && canMakeModeratorComp" class="start-private-chat clickable d-block text-none justify-start" @click="makeModerator(activeMember)">
|
||||
<v-btn text size="x-large" block v-if="activeMember.userId != $matrix.currentUserId && !isModeratorComp && !isAdminComp && canMakeModeratorComp" 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 && isModeratorComp && canRevokeModeratorComp" class="start-private-chat clickable d-block text-none justify-start" @click="revokeModerator(activeMember)">
|
||||
<v-btn text size="x-large" block v-if="activeMember.userId != $matrix.currentUserId && isModeratorComp && canRevokeModeratorComp" class="start-private-chat clickable d-block text-none justify-start" @click="revokeModerator(activeMember)">
|
||||
<v-icon left>$vuetify.icons.revoke</v-icon> {{ $t("menu.user_revoke_moderator") }}
|
||||
</v-btn>
|
||||
</div>
|
||||
|
|
@ -73,8 +72,9 @@ export default {
|
|||
DeviceList,
|
||||
AuthedImage
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
props: {
|
||||
show: {
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return false;
|
||||
|
|
@ -141,14 +141,20 @@ export default {
|
|||
}
|
||||
},
|
||||
watch: {
|
||||
activeMember() {
|
||||
this.showDialog = this.show && this.activeMember && this.room;
|
||||
},
|
||||
room() {
|
||||
this.showDialog = this.show && this.activeMember && this.room;
|
||||
},
|
||||
show: {
|
||||
handler(newVal, ignoredOldVal) {
|
||||
this.showDialog = newVal;
|
||||
this.showDialog = newVal && this.activeMember && this.room;
|
||||
}
|
||||
},
|
||||
showDialog() {
|
||||
if (!this.showDialog) {
|
||||
this.$emit("close");
|
||||
this.$emit('update:modelValue', false);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
class="ma-2 white-space-pre"
|
||||
:color="dark ? 'black' : '#ededed'"
|
||||
:text-color="dark ? 'white' : 'black'"
|
||||
:outlined="!dark"
|
||||
:variant="!dark ? 'ouelined' : 'tonal'"
|
||||
>{{ $t("profile_info_popup.you_are") }}
|
||||
<span v-if="$matrix.currentUser.is_guest">
|
||||
<i18n-t keypath="profile_info_popup.identity_temporary" tag="span">
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default {
|
|||
"background-color": "white",
|
||||
disabled: this.creatingRoom,
|
||||
//autofocus: true,
|
||||
solo: true,
|
||||
variant: "solo",
|
||||
required: true,
|
||||
};
|
||||
},
|
||||
|
|
@ -50,8 +50,9 @@ export default {
|
|||
rules: this.roomTopicRules,
|
||||
maxLength: "500",
|
||||
disabled: this.creatingRoom,
|
||||
filled: true,
|
||||
rounded: true,
|
||||
variant: "filled",
|
||||
class: "no-underline",
|
||||
//rounded: true,
|
||||
"hide-details": true,
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="file-drop-input-container">
|
||||
<v-textarea ref="input" full-width solo flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
<v-textarea ref="input" full-width variant="solo" flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
rows="1" :placeholder="$t('file_mode.add_a_message')" hide-details background-color="transparent"
|
||||
v-on:keydown.enter.prevent="() => {
|
||||
sendCurrentTextMessage();
|
||||
|
|
@ -82,14 +82,14 @@
|
|||
<div class="file-drop-files-sent">{{ $t((this.messageInput && this.messageInput.length > 0) ?
|
||||
"file_mode.files_sent_with_note" : "file_mode.files_sent", attachmentsSent.length) }}</div>
|
||||
<div class="file-drop-section">
|
||||
<v-textarea disabled full-width solo flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
<v-textarea disabled full-width variant="solo" flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
rows="1" hide-details background-color="transparent" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom section -->
|
||||
<div v-if="status == mainStatuses.SENDING" class="file-drop-sending-input-container">
|
||||
<v-textarea disabled full-width solo flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
<v-textarea disabled full-width variant="solo" flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
rows="1" :placeholder="$t('file_mode.add_a_message')" hide-details background-color="transparent" />
|
||||
<v-btn>{{ $t("file_mode.sending") }}<v-progress-circular indeterminate size="18" width="2"
|
||||
color="#4642F1"></v-progress-circular></v-btn>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default {
|
|||
const context = this
|
||||
for (const locale of Object.keys(this.$i18n.messages)) {
|
||||
this.languages.push({
|
||||
title: this.$i18n.messages[locale].language_display_name || locale,
|
||||
text: this.$i18n.messages[locale].language_display_name || locale,
|
||||
value: locale,
|
||||
display: context.displayLanguage.includes(locale)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<message-incoming v-bind="{ ...$props, ...$attrs }">
|
||||
<div class="bubble poll-bubble">
|
||||
<div class="poll-icon">
|
||||
<v-icon dark>$vuetify.icons.poll</v-icon>
|
||||
<v-icon theme="dark">$vuetify.icons.poll</v-icon>
|
||||
</div>
|
||||
|
||||
<div class="poll-question">{{ pollQuestion }}</div>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
<template>
|
||||
<div :class="{'message-operations':true,'incoming':incoming,'outgoing':!incoming}">
|
||||
<template v-for="(item,index) in getEmojis">
|
||||
<v-btn v-if="userCanSendReactionAndAnswerPoll && index < maxRecents" :key="item.data" id="btn-quick-reaction" icon @click.stop="addQuickReaction(item.data)" class="ma-0 pa-0" dense>
|
||||
<template v-for="(item,index) in getEmojis" :key="item.data">
|
||||
<v-btn v-if="userCanSendReactionAndAnswerPoll && index < maxRecents" id="btn-quick-reaction" icon @click.stop="addQuickReaction(item.data)" class="ma-0 pa-0" dense>
|
||||
<span class="recent-emoji">{{ item.data }}</span>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-btn v-if="userCanSendReactionAndAnswerPoll" id="btn-more" icon @click.stop="more" class="ma-0 pa-0">
|
||||
<v-icon small> $vuetify.icons.addReaction </v-icon>
|
||||
<v-icon size="small"> $vuetify.icons.addReaction </v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-if="userCanSendMessage" id="btn-reply" icon @click.stop="addReply" class="ma-0 pa-0">
|
||||
<v-icon>reply</v-icon>
|
||||
</v-btn>
|
||||
<v-btn id="btn-edit" icon @click.stop="edit" class="ma-0 pa-0" v-if="isEditable">
|
||||
<v-icon small>edit</v-icon>
|
||||
<v-icon size="small">edit</v-icon>
|
||||
</v-btn>
|
||||
<v-btn id="btn-redact" icon @click.stop="redact" class="ma-0 pa-0" v-if="isRedactable">
|
||||
<v-icon small>delete</v-icon>
|
||||
<v-icon size="small">delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn id="btn-download" icon @click.stop="download" class="ma-0 pa-0" v-if="isDownloadable">
|
||||
<v-icon small>get_app</v-icon>
|
||||
<v-icon size="small">get_app</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<span v-else class="text-white headline">{{ userAvatarLetter }}</span>
|
||||
</v-avatar>
|
||||
<QuickReactionsChannel v-if="room.displayType == ROOM_TYPE_CHANNEL" :event="eventForReactions" :timelineSet="timelineSet" v-bind="$attrs"/>
|
||||
<QuickReactions v-else :event="eventForReactions" :timelineSet="timelineSet" v-bin="$attrs"/>
|
||||
<QuickReactions v-else :event="eventForReactions" :timelineSet="timelineSet" v-bind="$attrs"/>
|
||||
<SeenBy v-if="room.displayType != ROOM_TYPE_CHANNEL" :room="room" :event="event"/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<message-outgoing v-bind="{ ...$props, ...$attrs }">
|
||||
<div class="bubble poll-bubble">
|
||||
<div class="poll-icon">
|
||||
<v-icon light>$vuetify.icons.poll</v-icon>
|
||||
<v-icon theme="light">$vuetify.icons.poll</v-icon>
|
||||
</div>
|
||||
|
||||
<div class="poll-question">{{ pollQuestion }}</div>
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-chip
|
||||
class="pa-2 ma-1 ml-0"
|
||||
outlined
|
||||
small
|
||||
variant="outlined"
|
||||
size="small"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="onClickEmoji(name)"
|
||||
|
|
@ -24,8 +24,8 @@
|
|||
<v-chip
|
||||
v-else
|
||||
class="pa-2 ma-1 ml-0"
|
||||
outlined
|
||||
small
|
||||
variant="outlined"
|
||||
size="small"
|
||||
>
|
||||
{{ name }} {{ value.length }}
|
||||
</v-chip>
|
||||
|
|
@ -34,22 +34,22 @@
|
|||
v-if="totalReaction > REACTION_LIMIT"
|
||||
@click="showAllReaction = !showAllReaction"
|
||||
class="pa-2 ma-1 ml-0"
|
||||
outlined
|
||||
small
|
||||
variant="outlined"
|
||||
size="small"
|
||||
>
|
||||
{{ otherReactionText }}
|
||||
</v-chip>
|
||||
<v-tooltip top v-if="!!totalReaction">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-chip
|
||||
outlined
|
||||
small
|
||||
variant="outlined"
|
||||
size="small"
|
||||
class="pa-2 ma-1 ml-0"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="more"
|
||||
>
|
||||
<v-icon small> $vuetify.icons.addReaction </v-icon>
|
||||
<v-icon size="small"> $vuetify.icons.addReaction </v-icon>
|
||||
</v-chip>
|
||||
</template>
|
||||
<span>{{ $t("global.add_reaction") }}</span>
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@
|
|||
ref="seenByListBottomSheet"
|
||||
>
|
||||
<v-list>
|
||||
<v-subheader class="text-uppercase"> {{ $t("message.seen_by") }}</v-subheader>
|
||||
<v-list-subheader class="text-uppercase"> {{ $t("message.seen_by") }}</v-list-subheader>
|
||||
<v-list-item v-for="(member, index) in seenBy" :key="index" class="text-left">
|
||||
<v-list-item-icon>
|
||||
<template v-slot:prepend>
|
||||
<v-avatar size="40" color="grey">
|
||||
<AuthedImage v-if="memberAvatar(member.roomMember)" :src="memberAvatar(member.roomMember)" />
|
||||
<span v-else class="text-white headline">{{
|
||||
member.roomMember.name.substring(0, 1).toUpperCase()
|
||||
}}</span>
|
||||
</v-avatar>
|
||||
</v-list-item-icon>
|
||||
</template>
|
||||
<v-list-item-title>{{member.roomMember.name}}</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ seenByTimeStamp(member.readTimestamp) }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
|
|
|
|||
|
|
@ -2,19 +2,19 @@
|
|||
<div :class="{ 'message-operations': true, 'incoming': incoming, 'outgoing': !incoming }">
|
||||
<v-list dense>
|
||||
<v-list-item key="edit" v-if="isEditable" @click.stop="edit">
|
||||
<v-list-item-icon><v-icon>$vuetify.icons.ic_edit</v-icon></v-list-item-icon>
|
||||
<template v-slot:prepend><v-icon>$vuetify.icons.ic_edit</v-icon></template>
|
||||
<v-list-item-title>{{ $t("menu.edit") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item key="pin" v-if="userCanPin && !event.isPinned" @click.stop="pin">
|
||||
<v-list-item-icon><v-icon>$vuetify.icons.ic_pin</v-icon></v-list-item-icon>
|
||||
<template v-slot:prepend><v-icon>$vuetify.icons.ic_pin</v-icon></template>
|
||||
<v-list-item-title>{{ $t("menu.pin") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item key="unpin" v-if="userCanPin && event.isPinned" @click.stop="unpin">
|
||||
<v-list-item-icon><v-icon>$vuetify.icons.ic_pin</v-icon></v-list-item-icon>
|
||||
<template v-slot:prepend><v-icon>$vuetify.icons.ic_pin</v-icon></template>
|
||||
<v-list-item-title>{{ $t("menu.unpin") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item key="redact" v-if="isRedactable" @click.stop="redact">
|
||||
<v-list-item-icon><v-icon color="#222222">delete_outline</v-icon></v-list-item-icon>
|
||||
<template v-slot:prepend><v-icon color="#222222">delete_outline</v-icon></template>
|
||||
<v-list-item-title>{{ $t("menu.delete") }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@
|
|||
</v-btn>
|
||||
</div>
|
||||
|
||||
<MessageRetentionDialog :show="showMessageRetentionDialog" :room="room" @close="showMessageRetentionDialog = false"
|
||||
<MessageRetentionDialog
|
||||
v-model="showMessageRetentionDialog"
|
||||
:room="room"
|
||||
v-on:message-retention-update="onMessageRetention" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ const custom = {
|
|||
component: (props) => {
|
||||
const {
|
||||
icon,
|
||||
tag,
|
||||
...rest
|
||||
} = props;
|
||||
const stringIcon = icon;
|
||||
if (icons[stringIcon]) {
|
||||
return h(props.tag, rest, [h(icons[stringIcon].component)]);
|
||||
return h(tag, rest, [h(icons[stringIcon].component, { style: "width:100%;height:100%" })]);
|
||||
}
|
||||
return md.component(props);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import CreateFileDrop from '../components/CreateFileDrop.vue'
|
|||
import User from '../models/user'
|
||||
import util from '../plugins/utils'
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
|
|
@ -30,7 +31,7 @@ const routes = [
|
|||
{
|
||||
path: '/info',
|
||||
name: 'RoomInfo',
|
||||
component: () => import('../components/RoomInfo.vue'),
|
||||
component: defineAsyncComponent(() => import('../components/RoomInfo.vue')),
|
||||
props: true,
|
||||
meta: {
|
||||
title: 'Info',
|
||||
|
|
@ -94,7 +95,7 @@ const routes = [
|
|||
{
|
||||
path: '/invite/:roomId?',
|
||||
name: 'Invite',
|
||||
component: () => import('../components/Invite.vue'),
|
||||
component: defineAsyncComponent(() => import('../components/Invite.vue')),
|
||||
meta: {
|
||||
title: 'Add Friends'
|
||||
}
|
||||
|
|
@ -102,7 +103,7 @@ const routes = [
|
|||
{
|
||||
path: '/goodbye',
|
||||
name: 'Goodbye',
|
||||
component: () => import('../components/QuoteView.vue'),
|
||||
component: defineAsyncComponent(() => import('../components/QuoteView.vue')),
|
||||
props: true
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue