keanu-weblite/src/components/messages/SeenBy.vue

140 lines
4 KiB
Vue
Raw Normal View History

2023-04-28 11:01:22 +02:00
<template>
2023-06-25 17:12:29 +03:00
<div>
<div class="seen-by-container">
2025-05-28 09:49:12 +02:00
<v-tooltip location="top" open-delay="500" v-if="seenBy.length > 0">
2025-05-12 18:23:31 +02:00
<template v-slot:activator="{ props }">
<div v-bind="props" class="clickable">
2023-06-25 17:12:29 +03:00
<div class="more" v-if="seenBy.length > 0">{{ moreItems }}</div>
<transition-group name="list" tag="div" v-if="seenBy.length > 0">
<v-avatar v-for="(member, index) in seenBy" :key="member.roomMember.userId" class="seen-by-user" size="16" color="grey"
v-show="index < SHOW_LIMIT" @click="open">
2025-03-31 16:33:54 +02:00
<AuthedImage v-if="memberAvatar(member.roomMember)" :src="memberAvatar(member.roomMember)" />
2025-05-06 10:53:34 +02:00
<span v-else class="text-white headline">{{
2023-06-25 17:12:29 +03:00
member.roomMember.name.substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
</transition-group>
</div>
</template>
2025-05-06 11:28:47 +02:00
<span>{{ $t("message.seen_by_count", seenBy.length) }}</span>
2023-06-25 17:12:29 +03:00
</v-tooltip>
</div>
2025-10-19 14:05:29 +03:00
<BottomSheet ref="seenByListBottomSheet">
2023-06-25 17:12:29 +03:00
<v-list>
2025-05-08 11:52:39 +02:00
<v-list-subheader class="text-uppercase"> {{ $t("message.seen_by") }}</v-list-subheader>
2025-05-06 09:27:53 +02:00
<v-list-item v-for="(member, index) in seenBy" :key="index" class="text-left">
2025-05-08 11:52:39 +02:00
<template v-slot:prepend>
2023-06-25 17:12:29 +03:00
<v-avatar size="40" color="grey">
2025-03-31 16:33:54 +02:00
<AuthedImage v-if="memberAvatar(member.roomMember)" :src="memberAvatar(member.roomMember)" />
2025-05-06 10:53:34 +02:00
<span v-else class="text-white headline">{{
2023-06-25 17:12:29 +03:00
member.roomMember.name.substring(0, 1).toUpperCase()
2023-04-28 11:01:22 +02:00
}}</span>
</v-avatar>
2025-05-08 11:52:39 +02:00
</template>
2025-05-06 09:27:53 +02:00
<v-list-item-title>{{member.roomMember.name}}</v-list-item-title>
<v-list-item-subtitle>{{ seenByTimeStamp(member.readTimestamp) }}</v-list-item-subtitle>
2023-06-25 17:12:29 +03:00
</v-list-item>
</v-list>
</BottomSheet>
2023-04-28 11:01:22 +02:00
</div>
</template>
<script>
2025-03-31 16:33:54 +02:00
import BottomSheet from "../BottomSheet.vue";
import AuthedImage from "../AuthedImage.vue";
2023-06-25 17:12:29 +03:00
import utils from "../../plugins/utils.js";
2023-04-28 11:01:22 +02:00
export default {
2023-06-25 17:12:29 +03:00
components: {
2025-03-31 16:33:54 +02:00
BottomSheet,
AuthedImage
2023-06-25 17:12:29 +03:00
},
2023-04-28 11:01:22 +02:00
props: {
room: {
type: Object,
default: function () {
return null;
},
},
event: {
type: Object,
default: function () {
return null;
}
},
},
data() {
return {
seenBy: [],
SHOW_LIMIT: 5,
2023-06-25 17:12:29 +03:00
utils
2023-04-28 11:01:22 +02:00
}
},
mounted() {
this.update();
if (this.room) {
this.room.on("Room.receipt", this.onReceipt);
}
},
beforeUnmount() {
2023-04-28 11:01:22 +02:00
if (this.room) {
this.room.off("Room.receipt", this.onReceipt);
}
},
computed: {
moreItems() {
if (this.seenBy.length > this.SHOW_LIMIT) {
return `+${this.seenBy.length - this.SHOW_LIMIT}`;
}
return "";
}
},
methods: {
2023-06-25 17:12:29 +03:00
seenByTimeStamp(timestamp) {
let dayDiff = utils.dayDiffToday(timestamp);
if (dayDiff < 3) {
2025-05-06 11:28:47 +02:00
return this.$t("message.time_ago", dayDiff) + ' '+utils.formatTime(timestamp);
2023-06-25 17:12:29 +03:00
} else {
return utils.formatTime(timestamp);
}
},
open() {
this.$refs.seenByListBottomSheet.open();
},
2023-04-28 11:01:22 +02:00
onReceipt(ignoredevent) {
this.update();
},
memberAvatar(member) {
if (member) {
return member.getAvatarUrl(
this.$matrix.matrixClient.getHomeserverUrl(),
16,
16,
"scale",
2025-03-31 16:33:54 +02:00
true,
false,
this.$matrix.useAuthedMedia
2023-04-28 11:01:22 +02:00
);
}
return null;
},
update() {
this.seenBy = ((this.room && this.event) ? this.room.getReceiptsForEvent(this.event) : [])
.filter(receipt => receipt.type == 'm.read' && receipt.userId !== this.$matrix.currentUserId)
2023-06-25 17:12:29 +03:00
.map(receipt => {
return { readTimestamp: receipt.data.ts, roomMember: this.room.getMember(receipt.userId) }
}
);
2023-04-28 11:01:22 +02:00
},
},
watch: {
event() {
this.update();
}
}
};
</script>
<style lang="scss">
@use "@/assets/css/chat.scss" as *;
2023-04-28 11:01:22 +02:00
</style>