Support pinning thread messages (media)
This commit is contained in:
parent
d3ffc3d15b
commit
5e1223fc01
10 changed files with 152 additions and 27 deletions
|
|
@ -17,7 +17,7 @@
|
|||
<span ref="messageInOutRef" class="content">
|
||||
<slot></slot>
|
||||
</span>
|
||||
<div class="pin-icon" v-if="event.isPinned"><v-icon>$vuetify.icons.ic_pin_filled</v-icon></div>
|
||||
<div class="pin-icon" v-if="isPinned"><v-icon>$vuetify.icons.ic_pin_filled</v-icon></div>
|
||||
<div class="op-button" ref="opbutton" v-if="!event.isRedacted() && room.displayType != ROOM_TYPE_CHANNEL">
|
||||
<v-btn id="btn-more" icon @click.stop="showContextMenu($refs.opbutton)">
|
||||
<v-icon>more_vert</v-icon>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
</div>
|
||||
|
||||
<div class="message">
|
||||
<v-container v-if="!event.isRedacted()" fluid class="imageCollection">
|
||||
<SwipeableThumbnailsView :items="items" v-if="!event.isRedacted() && room.displayType == ROOM_TYPE_CHANNEL" />
|
||||
<v-container v-else-if="!event.isRedacted()" fluid class="imageCollection">
|
||||
<v-row wrap>
|
||||
<v-col v-for="({ size, item }) in layoutedItems()" :key="item.event.getId()" :cols="size">
|
||||
<ThumbnailView :item="item" :previewOnly="true" v-on:itemclick="onItemClick($event)" />
|
||||
|
|
@ -38,16 +39,18 @@
|
|||
<script>
|
||||
import MessageIncoming from "./MessageIncoming.vue";
|
||||
import messageMixin from "./messageMixin";
|
||||
import util from "../../plugins/utils";
|
||||
import util, { ROOM_TYPE_CHANNEL } from "../../plugins/utils";
|
||||
import GalleryItemsView from '../file_mode/GalleryItemsView.vue';
|
||||
import ThumbnailView from '../file_mode/ThumbnailView.vue';
|
||||
import SwipeableThumbnailsView from "./channel/SwipeableThumbnailsView.vue";
|
||||
|
||||
export default {
|
||||
extends: MessageIncoming,
|
||||
components: { MessageIncoming, GalleryItemsView, ThumbnailView },
|
||||
components: { MessageIncoming, GalleryItemsView, ThumbnailView, SwipeableThumbnailsView },
|
||||
mixins: [messageMixin],
|
||||
data() {
|
||||
return {
|
||||
ROOM_TYPE_CHANNEL: ROOM_TYPE_CHANNEL,
|
||||
items: [],
|
||||
showItem: null,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="pin-icon" v-if="event.isPinned"><v-icon>$vuetify.icons.ic_pin_filled</v-icon></div>
|
||||
<div class="pin-icon" v-if="isPinned"><v-icon>$vuetify.icons.ic_pin_filled</v-icon></div>
|
||||
|
||||
<!-- SLOT FOR CONTENT -->
|
||||
<span ref="messageInOutRef" class="content">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
|
||||
<div class="message">
|
||||
<v-container v-if="!event.isRedacted()" fluid class="imageCollection">
|
||||
<SwipeableThumbnailsView :items="items" v-if="!event.isRedacted() && room.displayType == ROOM_TYPE_CHANNEL" />
|
||||
<v-container v-else-if="!event.isRedacted()" fluid class="imageCollection">
|
||||
<v-row wrap>
|
||||
<v-col v-for="({ size, item }) in layoutedItems()" :key="item.event.getId()" :cols="size">
|
||||
<ThumbnailView :item="item" :previewOnly="true" v-on:itemclick="onItemClick($event)" />
|
||||
|
|
@ -39,16 +40,18 @@
|
|||
<script>
|
||||
import MessageOutgoing from "./MessageOutgoing.vue";
|
||||
import messageMixin from "./messageMixin";
|
||||
import util from "../../plugins/utils";
|
||||
import util, { ROOM_TYPE_CHANNEL } from "../../plugins/utils";
|
||||
import GalleryItemsView from '../file_mode/GalleryItemsView.vue';
|
||||
import ThumbnailView from '../file_mode/ThumbnailView.vue';
|
||||
import SwipeableThumbnailsView from "./channel/SwipeableThumbnailsView.vue";
|
||||
|
||||
export default {
|
||||
extends: MessageOutgoing,
|
||||
components: { MessageOutgoing, GalleryItemsView, ThumbnailView },
|
||||
components: { MessageOutgoing, GalleryItemsView, ThumbnailView, SwipeableThumbnailsView },
|
||||
mixins: [messageMixin],
|
||||
data() {
|
||||
return {
|
||||
ROOM_TYPE_CHANNEL: ROOM_TYPE_CHANNEL,
|
||||
items: [],
|
||||
showItem: null,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@
|
|||
<v-list-item-title>{{ $t("menu.unpin") }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</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>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t("menu.delete") }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
41
src/components/messages/channel/SwipeableThumbnailsView.vue
Normal file
41
src/components/messages/channel/SwipeableThumbnailsView.vue
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div class="swipeable-thumbnails-view">
|
||||
<v-responsive :aspect-ratio="16 / 9" class="ma-0 pa-0">
|
||||
<v-carousel height="100%" hide-delimiters show-arrows-on-hover v-model="currentIndex">
|
||||
<v-carousel-item v-for="(item,index) in items" :key="item.event.getId()">
|
||||
<ThumbnailView :item="items[index]" :previewOnly="true" />
|
||||
</v-carousel-item>
|
||||
</v-carousel>
|
||||
</v-responsive>
|
||||
<div class="indicator-container">
|
||||
<div v-for="(item,index) in items" :key="index" :class="{'indicator': true, 'current': index == currentIndex}" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messageMixin from "../../messages/messageMixin";
|
||||
import ThumbnailView from '../../file_mode/ThumbnailView.vue';
|
||||
|
||||
export default {
|
||||
mixins: [messageMixin],
|
||||
components: { ThumbnailView },
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -109,7 +109,7 @@ export default {
|
|||
* Don't show sender and time if the next event is within 2 minutes and also from us (= back to back messages)
|
||||
*/
|
||||
showSenderAndTime() {
|
||||
if (!this.event.isPinned && this.nextEvent && this.nextEvent.getSender() == this.event.getSender()) {
|
||||
if (!this.isPinned && this.nextEvent && this.nextEvent.getSender() == this.event.getSender()) {
|
||||
const ts1 = this.nextEvent.event.origin_server_ts;
|
||||
const ts2 = this.event.event.origin_server_ts;
|
||||
return ts1 - ts2 < 2 * 60 * 1000; // less than 2 minutes
|
||||
|
|
@ -180,15 +180,19 @@ export default {
|
|||
return this.event.getContent().body;
|
||||
},
|
||||
|
||||
isPinned() {
|
||||
return this.event.parentThread ? this.event.parentThread.isPinned : this.event.isPinned;
|
||||
},
|
||||
|
||||
/**
|
||||
* Classes to set for the message. Currently only for "messageIn"
|
||||
*/
|
||||
|
||||
messageClasses() {
|
||||
if (this.incoming) {
|
||||
return { messageIn: true, "from-admin": this.senderIsAdminOrModerator(this.event), "pinned": this.event.isPinned };
|
||||
return { messageIn: true, "from-admin": this.senderIsAdminOrModerator(this.event), "pinned": this.isPinned };
|
||||
} else {
|
||||
return { messageOut: true, "pinned": this.event.isPinned };
|
||||
return { messageOut: true, "pinned": this.isPinned };
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue