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