Support chat backgrounds

This commit is contained in:
N Pex 2023-10-18 15:05:50 +00:00
parent ea8522d8a3
commit 4e9aecc304
4 changed files with 97 additions and 56 deletions

View file

@ -1,5 +1,5 @@
<template>
<div class="chat-root fill-height d-flex flex-column">
<div class="chat-root fill-height d-flex flex-column" :style="chatContainerStyle">
<ChatHeaderPrivate class="chat-header flex-grow-0 flex-shrink-0"
v-on:header-click="onHeaderClick"
v-on:view-room-details="viewRoomDetails"
@ -62,7 +62,7 @@
<div v-for="(event, index) in filteredEvents" :key="event.getId()" :eventId="event.getId()">
<!-- DAY Marker, shown for every new day in the timeline -->
<div v-if="showDayMarkerBeforeEvent(event) && !!componentForEvent(event, isForExport = false)" class="day-marker" :title="dayForEvent(event)" />
<div v-if="showDayMarkerBeforeEvent(event) && !!componentForEvent(event, isForExport = false)" class="day-marker"><div class="line"></div><div class="text">{{ dayForEvent(event) }}</div><div class="line"></div></div>
<div v-if="!event.isRelation() && !event.isRedaction()" :ref="event.getId()">
<div class="message-wrapper" v-on:touchstart="
@ -82,8 +82,7 @@
/>
<!-- <div v-if="debugging" style="user-select:text">EventID: {{ event.getId() }}</div> -->
<!-- <div v-if="debugging" style="user-select:text">Event: {{ JSON.stringify(event) }}</div> -->
<div v-if="event.getId() == readMarker && index < filteredEvents.length - 1" class="read-marker"
:title="$t('message.unread_messages')" />
<div v-if="event.getId() == readMarker && index < filteredEvents.length - 1" class="read-marker"><div class="line"></div><div class="text">{{ $t('message.unread_messages') }}</div><div class="line"></div></div>
</div>
</div>
</div>
@ -727,7 +726,11 @@ export default {
},
isDirectRoom() {
return this.room.getJoinRule() == "invite" && this.joinedAndInvitedMembers.length == 2;
return this.room && this.room.getJoinRule() == "invite" && this.joinedAndInvitedMembers.length == 2;
},
isPublicRoom() {
return this.room && this.room.getJoinRule() == "public";
},
showCreatedRoomWelcomeHeader() {
@ -736,6 +739,51 @@ export default {
showDirectChatWelcomeHeader() {
return !this.hideDirectChatWelcomeHeader && this.roomCreatedByUsRecently && this.isDirectRoom;
},
chatContainerStyle() {
if (this.$config.chat_backgrounds && this.room && this.roomId) {
const roomType = this.isDirectRoom ? "direct" : this.isPublicRoom ? "public" : "invite";
let backgrounds = this.$config.chat_backgrounds[roomType] || this.$config.chat_backgrounds["all"];
if (backgrounds) {
const numBackgrounds = backgrounds.length;
// If we have several backgrounds set, use the room ID to calculate
// an int hash value, then take mod of that to select a background to use.
// That way, we always get the same one, since room IDs don't change.
// From: https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
const hashCode = function (s) {
var hash = 0,
i, chr;
if (s.length === 0) return hash;
for (i = 0; i < s.length; i++) {
chr = s.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
// Adapted from: https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url
const validUrl = function (s) {
let url;
try {
url = new URL(s, window.location);
} catch (err) {
return false;
}
return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "data:";
}
const index = Math.abs(hashCode(this.roomId)) % numBackgrounds;
const background = backgrounds[index];
if (background && validUrl(background)) {
return "background-image: url(" + background + ");background-repeat: repeat";
}
}
}
return "";
}
},

View file

@ -18,7 +18,7 @@
<div class="chat-content flex-grow-1 flex-shrink-1" ref="chatContainer">
<div v-for="(event, index) in events" :key="event.getId()" :eventId="event.getId()">
<!-- DAY Marker, shown for every new day in the timeline -->
<div v-if="showDayMarkerBeforeEvent(event)" class="day-marker" :title="dateForEvent(event)" />
<div v-if="showDayMarkerBeforeEvent(event)" class="day-marker"><div class="line"></div><div class="text">{{ dayForEvent(event) }}</div><div class="line"></div></div>
<div v-if="!event.isRelation() && !event.isRedacted() && !event.isRedaction()" :ref="event.getId()">
<div class="message-wrapper">