2018-07-08 17:22:01 +00:00
|
|
|
<template>
|
|
|
|
<div
|
|
|
|
class="messages"
|
|
|
|
role="log"
|
|
|
|
aria-live="polite"
|
|
|
|
aria-relevant="additions"
|
2018-07-09 18:37:52 +00:00
|
|
|
@copy="onCopy"
|
2018-07-08 17:22:01 +00:00
|
|
|
>
|
2018-07-11 09:27:44 +00:00
|
|
|
<template v-for="(message, id) in condensedMessages">
|
2018-07-08 17:22:01 +00:00
|
|
|
<div
|
2018-07-11 09:27:44 +00:00
|
|
|
v-if="shouldDisplayDateMarker(message, id)"
|
2018-07-08 17:22:01 +00:00
|
|
|
:key="message.id + '-date'"
|
|
|
|
:data-time="message.time"
|
|
|
|
:aria-label="message.time | localedate"
|
|
|
|
class="date-marker-container tooltipped tooltipped-s"
|
|
|
|
>
|
|
|
|
<div class="date-marker">
|
|
|
|
<span
|
|
|
|
:data-label="message.time | friendlydate"
|
|
|
|
class="date-marker-text"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div
|
2018-07-11 09:27:44 +00:00
|
|
|
v-if="shouldDisplayUnreadMarker(id)"
|
2018-07-08 17:22:01 +00:00
|
|
|
:key="message.id + '-unread'"
|
|
|
|
class="unread-marker"
|
|
|
|
>
|
|
|
|
<span class="unread-marker-text"/>
|
|
|
|
</div>
|
2018-07-09 12:14:44 +00:00
|
|
|
|
2018-07-09 13:21:14 +00:00
|
|
|
<MessageCondensed
|
|
|
|
v-if="message.type === 'condensed'"
|
|
|
|
:key="message.id"
|
|
|
|
:messages="message.messages"/>
|
2018-07-08 17:22:01 +00:00
|
|
|
<Message
|
2018-07-09 12:14:44 +00:00
|
|
|
v-else
|
2018-07-08 17:22:01 +00:00
|
|
|
:message="message"
|
2018-07-12 08:26:12 +00:00
|
|
|
:key="message.id"
|
|
|
|
@linkPreviewToggle="onLinkPreviewToggle"/>
|
2018-07-08 17:22:01 +00:00
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2018-07-09 12:14:44 +00:00
|
|
|
const constants = require("../js/constants");
|
2018-07-09 18:37:52 +00:00
|
|
|
const clipboard = require("../js/clipboard");
|
2018-07-11 20:45:01 +00:00
|
|
|
import socket from "../js/socket";
|
2018-07-08 17:22:01 +00:00
|
|
|
import Message from "./Message.vue";
|
2018-07-09 12:14:44 +00:00
|
|
|
import MessageCondensed from "./MessageCondensed.vue";
|
2018-07-08 17:22:01 +00:00
|
|
|
|
|
|
|
export default {
|
|
|
|
name: "MessageList",
|
|
|
|
components: {
|
|
|
|
Message,
|
2018-07-09 12:14:44 +00:00
|
|
|
MessageCondensed,
|
2018-07-08 17:22:01 +00:00
|
|
|
},
|
|
|
|
props: {
|
|
|
|
channel: Object,
|
|
|
|
},
|
2018-07-09 12:14:44 +00:00
|
|
|
computed: {
|
2018-07-11 09:27:44 +00:00
|
|
|
condensedMessages() {
|
2018-07-09 12:14:44 +00:00
|
|
|
if (this.channel.type !== "channel") {
|
|
|
|
return this.channel.messages;
|
|
|
|
}
|
|
|
|
|
|
|
|
const condensed = [];
|
|
|
|
let lastCondensedContainer = null;
|
|
|
|
|
|
|
|
for (const message of this.channel.messages) {
|
|
|
|
// If this message is not condensable, or its an action affecting our user,
|
|
|
|
// then just append the message to container and be done with it
|
|
|
|
if (message.self || message.highlight || !constants.condensedTypes.includes(message.type)) {
|
|
|
|
lastCondensedContainer = null;
|
|
|
|
|
|
|
|
condensed.push(message);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lastCondensedContainer === null) {
|
|
|
|
lastCondensedContainer = {
|
2018-07-09 13:21:14 +00:00
|
|
|
id: message.id, // Use id of first message in the condensed container
|
2018-07-11 09:27:44 +00:00
|
|
|
time: message.time,
|
2018-07-09 12:14:44 +00:00
|
|
|
type: "condensed",
|
|
|
|
messages: [],
|
|
|
|
};
|
|
|
|
|
|
|
|
condensed.push(lastCondensedContainer);
|
|
|
|
}
|
|
|
|
|
|
|
|
lastCondensedContainer.messages.push(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
return condensed;
|
|
|
|
},
|
|
|
|
},
|
2018-07-08 17:22:01 +00:00
|
|
|
methods: {
|
2018-07-11 09:27:44 +00:00
|
|
|
shouldDisplayDateMarker(message, id) {
|
|
|
|
const previousMessage = this.condensedMessages[id - 1];
|
2018-07-08 17:22:01 +00:00
|
|
|
|
2018-07-11 09:27:44 +00:00
|
|
|
if (!previousMessage) {
|
2018-07-08 17:22:01 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-11 09:27:44 +00:00
|
|
|
return (new Date(previousMessage.time)).getDay() !== (new Date(message.time)).getDay();
|
2018-07-08 17:22:01 +00:00
|
|
|
},
|
2018-07-11 09:27:44 +00:00
|
|
|
shouldDisplayUnreadMarker(id) {
|
|
|
|
const previousMessage = this.condensedMessages[id - 1];
|
|
|
|
|
|
|
|
if (!previousMessage) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.channel.firstUnread === previousMessage.id;
|
2018-07-08 17:22:01 +00:00
|
|
|
},
|
2018-07-09 18:37:52 +00:00
|
|
|
onCopy() {
|
|
|
|
clipboard(this.$el);
|
|
|
|
},
|
2018-07-11 20:45:01 +00:00
|
|
|
onLinkPreviewToggle(preview, message) {
|
|
|
|
// Tell the server we're toggling so it remembers at page reload
|
|
|
|
// TODO Avoid sending many single events when using `/collapse` or `/expand`
|
|
|
|
// See https://github.com/thelounge/thelounge/issues/1377
|
|
|
|
socket.emit("msg:preview:toggle", {
|
|
|
|
target: this.channel.id,
|
|
|
|
msgId: message.id,
|
|
|
|
link: preview.link,
|
|
|
|
shown: preview.shown,
|
|
|
|
});
|
|
|
|
},
|
2018-07-08 17:22:01 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|