2019-11-04 09:21:05 +00:00
|
|
|
|
<template>
|
|
|
|
|
<div
|
|
|
|
|
v-if="isOpen"
|
|
|
|
|
id="mentions-popup-container"
|
|
|
|
|
@click="containerClick"
|
2020-04-20 10:40:45 +00:00
|
|
|
|
@contextmenu="containerClick"
|
2019-11-04 09:21:05 +00:00
|
|
|
|
>
|
|
|
|
|
<div class="mentions-popup">
|
|
|
|
|
<div class="mentions-popup-title">
|
|
|
|
|
Recent mentions
|
2020-07-19 14:29:52 +00:00
|
|
|
|
<button
|
|
|
|
|
v-if="resolvedMessages.length"
|
2021-10-12 22:56:39 +00:00
|
|
|
|
class="btn dismiss-all-mentions"
|
|
|
|
|
@click="dismissAllMentions()"
|
2020-07-19 14:29:52 +00:00
|
|
|
|
>
|
2021-10-12 22:56:39 +00:00
|
|
|
|
Dismiss all
|
2020-07-19 14:29:52 +00:00
|
|
|
|
</button>
|
2019-11-04 09:21:05 +00:00
|
|
|
|
</div>
|
|
|
|
|
<template v-if="resolvedMessages.length === 0">
|
2020-04-13 07:59:18 +00:00
|
|
|
|
<p v-if="isLoading">Loading…</p>
|
2020-07-19 14:29:52 +00:00
|
|
|
|
<p v-else>You have no recent mentions.</p>
|
2019-11-04 09:21:05 +00:00
|
|
|
|
</template>
|
2022-06-19 00:25:21 +00:00
|
|
|
|
<template v-for="message in resolvedMessages" v-else :key="message.msgId">
|
|
|
|
|
<div :class="['msg', message.type]">
|
2020-04-20 10:40:45 +00:00
|
|
|
|
<div class="mentions-info">
|
|
|
|
|
<div>
|
|
|
|
|
<span class="from">
|
2022-06-19 00:25:21 +00:00
|
|
|
|
<Username :user="(message.from as any)" />
|
2020-04-20 10:40:45 +00:00
|
|
|
|
<template v-if="message.channel">
|
|
|
|
|
in {{ message.channel.channel.name }} on
|
|
|
|
|
{{ message.channel.network.name }}
|
|
|
|
|
</template>
|
2022-06-19 00:25:21 +00:00
|
|
|
|
<template v-else> in unknown channel </template> </span
|
|
|
|
|
>{{ ` ` }}
|
2020-04-20 10:40:45 +00:00
|
|
|
|
<span :title="message.localetime" class="time">
|
2022-06-19 00:25:21 +00:00
|
|
|
|
{{ messageTime(message.time.toString()) }}
|
2020-04-20 10:40:45 +00:00
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2021-10-12 22:56:39 +00:00
|
|
|
|
<span
|
|
|
|
|
class="close-tooltip tooltipped tooltipped-w"
|
|
|
|
|
aria-label="Dismiss this mention"
|
|
|
|
|
>
|
2020-04-20 10:40:45 +00:00
|
|
|
|
<button
|
2021-10-12 22:56:39 +00:00
|
|
|
|
class="msg-dismiss"
|
|
|
|
|
aria-label="Dismiss this mention"
|
|
|
|
|
@click="dismissMention(message)"
|
2020-04-20 10:40:45 +00:00
|
|
|
|
></button>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2019-11-04 09:21:05 +00:00
|
|
|
|
<div class="content" dir="auto">
|
2022-06-19 00:25:21 +00:00
|
|
|
|
<ParsedMessage :message="(message as any)" />
|
2019-11-04 09:21:05 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style>
|
2020-04-13 09:31:56 +00:00
|
|
|
|
#mentions-popup-container {
|
|
|
|
|
z-index: 8;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-04 09:21:05 +00:00
|
|
|
|
.mentions-popup {
|
|
|
|
|
background-color: var(--window-bg-color);
|
|
|
|
|
position: absolute;
|
|
|
|
|
width: 400px;
|
|
|
|
|
right: 80px;
|
|
|
|
|
top: 55px;
|
|
|
|
|
max-height: 400px;
|
2020-07-19 14:29:52 +00:00
|
|
|
|
overflow-y: auto;
|
2019-11-04 09:21:05 +00:00
|
|
|
|
z-index: 2;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mentions-popup > .mentions-popup-title {
|
2020-07-19 14:29:52 +00:00
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
2019-11-04 09:21:05 +00:00
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 10:40:45 +00:00
|
|
|
|
.mentions-popup .mentions-info {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-04 09:21:05 +00:00
|
|
|
|
.mentions-popup .msg {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
user-select: text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mentions-popup .msg:last-child {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mentions-popup .msg .content {
|
|
|
|
|
background-color: var(--highlight-bg-color);
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
padding: 6px;
|
|
|
|
|
margin-top: 2px;
|
2020-07-27 14:27:06 +00:00
|
|
|
|
word-wrap: break-word;
|
|
|
|
|
word-break: break-word; /* Webkit-specific */
|
2019-11-04 09:21:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-12 22:56:39 +00:00
|
|
|
|
.mentions-popup .msg-dismiss::before {
|
2019-11-04 09:21:05 +00:00
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: normal;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
line-height: 16px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
content: "×";
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-12 22:56:39 +00:00
|
|
|
|
.mentions-popup .msg-dismiss:hover {
|
2020-04-20 10:40:45 +00:00
|
|
|
|
color: var(--link-color);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-12 22:56:39 +00:00
|
|
|
|
.mentions-popup .dismiss-all-mentions {
|
2020-07-19 14:29:52 +00:00
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 4px 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (min-height: 500px) {
|
|
|
|
|
.mentions-popup {
|
|
|
|
|
max-height: 60vh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-04 09:21:05 +00:00
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.mentions-popup {
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
border: 0;
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-height: none;
|
|
|
|
|
right: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
top: 45px; /* header height */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
|
<script lang="ts">
|
2019-11-04 09:21:05 +00:00
|
|
|
|
import Username from "./Username.vue";
|
|
|
|
|
import ParsedMessage from "./ParsedMessage.vue";
|
|
|
|
|
import socket from "../js/socket";
|
2020-03-16 17:58:40 +00:00
|
|
|
|
import eventbus from "../js/eventbus";
|
2020-04-20 10:40:45 +00:00
|
|
|
|
import localetime from "../js/helpers/localetime";
|
2019-11-04 09:21:05 +00:00
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
|
import relativeTime from "dayjs/plugin/relativeTime";
|
2022-06-19 00:25:21 +00:00
|
|
|
|
import {computed, watch, defineComponent, ref, onMounted, onUnmounted} from "vue";
|
|
|
|
|
import {useStore} from "../js/store";
|
|
|
|
|
import {ClientMention} from "../js/types";
|
2019-11-04 09:21:05 +00:00
|
|
|
|
|
|
|
|
|
dayjs.extend(relativeTime);
|
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
|
export default defineComponent({
|
2019-11-04 09:21:05 +00:00
|
|
|
|
name: "Mentions",
|
|
|
|
|
components: {
|
|
|
|
|
Username,
|
|
|
|
|
ParsedMessage,
|
|
|
|
|
},
|
2022-06-19 00:25:21 +00:00
|
|
|
|
setup() {
|
|
|
|
|
const store = useStore();
|
|
|
|
|
const isOpen = ref(false);
|
|
|
|
|
const isLoading = ref(false);
|
|
|
|
|
const resolvedMessages = computed(() => {
|
|
|
|
|
const messages = store.state.mentions.slice().reverse();
|
2019-11-04 09:21:05 +00:00
|
|
|
|
|
|
|
|
|
for (const message of messages) {
|
2020-04-20 10:40:45 +00:00
|
|
|
|
message.localetime = localetime(message.time);
|
2022-06-19 00:25:21 +00:00
|
|
|
|
message.channel = store.getters.findChannel(message.chanId);
|
2019-11-04 09:21:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
|
return messages.filter((message) => !message.channel?.channel.muted);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
() => store.state.mentions,
|
|
|
|
|
() => {
|
|
|
|
|
isLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const messageTime = (time: string) => {
|
2019-11-04 09:21:05 +00:00
|
|
|
|
return dayjs(time).fromNow();
|
2022-06-19 00:25:21 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const dismissMention = (message: ClientMention) => {
|
|
|
|
|
store.state.mentions.splice(
|
|
|
|
|
store.state.mentions.findIndex((m) => m.msgId === message.msgId),
|
2019-11-04 09:21:05 +00:00
|
|
|
|
1
|
|
|
|
|
);
|
|
|
|
|
|
2021-10-12 22:56:39 +00:00
|
|
|
|
socket.emit("mentions:dismiss", message.msgId);
|
2022-06-19 00:25:21 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const dismissAllMentions = () => {
|
|
|
|
|
store.state.mentions = [];
|
2021-10-12 22:56:39 +00:00
|
|
|
|
socket.emit("mentions:dismiss_all");
|
2022-06-19 00:25:21 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const containerClick = (event: Event) => {
|
2019-11-04 09:21:05 +00:00
|
|
|
|
if (event.currentTarget === event.target) {
|
2022-06-19 00:25:21 +00:00
|
|
|
|
isOpen.value = false;
|
2019-11-04 09:21:05 +00:00
|
|
|
|
}
|
2022-06-19 00:25:21 +00:00
|
|
|
|
};
|
2019-11-04 09:21:05 +00:00
|
|
|
|
|
2022-06-19 00:25:21 +00:00
|
|
|
|
const togglePopup = () => {
|
|
|
|
|
isOpen.value = !isOpen.value;
|
|
|
|
|
|
|
|
|
|
if (isOpen.value) {
|
|
|
|
|
isLoading.value = true;
|
2019-11-04 09:21:05 +00:00
|
|
|
|
socket.emit("mentions:get");
|
|
|
|
|
}
|
2022-06-19 00:25:21 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const closePopup = () => {
|
|
|
|
|
isOpen.value = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
eventbus.on("mentions:toggle", togglePopup);
|
|
|
|
|
eventbus.on("escapekey", closePopup);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
eventbus.off("mentions:toggle", togglePopup);
|
|
|
|
|
eventbus.off("escapekey", closePopup);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isOpen,
|
|
|
|
|
isLoading,
|
|
|
|
|
resolvedMessages,
|
|
|
|
|
messageTime,
|
|
|
|
|
dismissMention,
|
|
|
|
|
dismissAllMentions,
|
|
|
|
|
containerClick,
|
|
|
|
|
};
|
2019-11-04 09:21:05 +00:00
|
|
|
|
},
|
2022-06-19 00:25:21 +00:00
|
|
|
|
});
|
2019-11-04 09:21:05 +00:00
|
|
|
|
</script>
|