Merge branch 'master' into chat-trim-message

This commit is contained in:
Hannes Heine 2023-07-19 15:02:29 +02:00 committed by GitHub
commit ff9db84cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 37 deletions

View File

@ -9,10 +9,9 @@ function walkRecursive(data, fields, fieldName, callback, _key?) {
if (!Array.isArray(fields)) { if (!Array.isArray(fields)) {
throw new Error('please provide an fields array for the walkRecursive helper') throw new Error('please provide an fields array for the walkRecursive helper')
} }
if (data && typeof data === 'string' && fields.includes(_key)) { const fieldDef = fields.find((f) => f.field === _key)
// well we found what we searched for, lets replace the value with our callback result if (data && typeof data === 'string' && fieldDef) {
const key = _key.split('!') if (!fieldDef.excludes?.includes(fieldName)) data = callback(data, _key)
if (key.length === 1 || key[1] !== fieldName) data = callback(data, key[0])
} else if (data && Array.isArray(data)) { } else if (data && Array.isArray(data)) {
// go into the rabbit hole and dig through that array // go into the rabbit hole and dig through that array
data.forEach((res, index) => { data.forEach((res, index) => {

View File

@ -30,6 +30,7 @@ const standardSanitizeHtmlOptions = {
'strike', 'strike',
'span', 'span',
'blockquote', 'blockquote',
'usertag',
], ],
allowedAttributes: { allowedAttributes: {
a: ['href', 'class', 'target', 'data-*', 'contenteditable'], a: ['href', 'class', 'target', 'data-*', 'contenteditable'],

View File

@ -3,11 +3,11 @@ import { cleanHtml } from '../middleware/helpers/cleanHtml'
// exclamation mark separetes field names, that should not be sanitized // exclamation mark separetes field names, that should not be sanitized
const fields = [ const fields = [
'content', { field: 'content', excludes: ['CreateMessage', 'Message'] },
'contentExcerpt', { field: 'contentExcerpt' },
'reasonDescription', { field: 'reasonDescription' },
'description!embed', { field: 'description', excludes: ['embed'] },
'descriptionExcerpt', { field: 'descriptionExcerpt' },
] ]
export default { export default {

View File

@ -27,4 +27,8 @@
chatMessageBgOthers: $chat-message-bg-others; chatMessageBgOthers: $chat-message-bg-others;
chatNewMessageColor: $chat-new-message-color; chatNewMessageColor: $chat-new-message-color;
chatMessageTimestamp: $chat-message-timestamp;
chatMessageCheckmarkSeen: $chat-message-checkmark-seen;
chatMessageCheckmark: $chat-message-checkmark;
} }

View File

@ -417,3 +417,6 @@ $chat-message-color: $text-color-base;
$chat-message-bg-others: $color-neutral-80; $chat-message-bg-others: $color-neutral-80;
$chat-sidemenu-bg: $color-secondary-active; $chat-sidemenu-bg: $color-secondary-active;
$chat-new-message-color: $color-secondary-active; $chat-new-message-color: $color-secondary-active;
$chat-message-timestamp: $text-color-soft;
$chat-message-checkmark-seen: $text-color-secondary;
$chat-message-checkmark: $text-color-soft;

View File

@ -35,7 +35,7 @@
<div slot="room-header-avatar"> <div slot="room-header-avatar">
<div <div
v-if="selectedRoom && selectedRoom.avatar && selectedRoom.avatar !== 'default-avatar'" v-if="selectedRoom && selectedRoom.avatar"
class="vac-avatar" class="vac-avatar"
:style="{ 'background-image': `url('${selectedRoom.avatar}')` }" :style="{ 'background-image': `url('${selectedRoom.avatar}')` }"
/> />
@ -46,7 +46,7 @@
<div v-for="room in rooms" :slot="'room-list-avatar_' + room.id" :key="room.id"> <div v-for="room in rooms" :slot="'room-list-avatar_' + room.id" :key="room.id">
<div <div
v-if="room.avatar && room.avatar !== 'default-avatar'" v-if="room.avatar"
class="vac-avatar" class="vac-avatar"
:style="{ 'background-image': `url('${room.avatar}')` }" :style="{ 'background-image': `url('${room.avatar}')` }"
/> />
@ -222,9 +222,9 @@ export default {
...mapMutations({ ...mapMutations({
commitUnreadRoomCount: 'chat/UPDATE_ROOM_COUNT', commitUnreadRoomCount: 'chat/UPDATE_ROOM_COUNT',
}), }),
async fetchRooms({ room } = {}) { async fetchRooms({ room, options = {} } = {}) {
this.roomsLoaded = false this.roomsLoaded = options.refetch ? this.roomsLoaded : false
const offset = this.roomPage * this.roomPageSize const offset = (options.refetch ? 0 : this.roomPage) * this.roomPageSize
try { try {
const { const {
data: { Room }, data: { Room },
@ -238,16 +238,25 @@ export default {
fetchPolicy: 'no-cache', fetchPolicy: 'no-cache',
}) })
const newRooms = Room.map((r) => { const rms = []
return { const rmsIds = []
...r, ;[...Room, ...this.rooms].forEach((r) => {
users: r.users.map((u) => { if (!rmsIds.find((v) => v === r.id)) {
return { ...u, username: u.name, avatar: u.avatar?.url } rms.push({
}), ...r,
index: r.lastMessage?.date,
lastMessage: {
...r.lastMessage,
content: r.lastMessage?.content.trim().substring(0, 30),
},
users: r.users.map((u) => {
return { ...u, username: u.name, avatar: u.avatar?.url }
}),
})
rmsIds.push(r.id)
} }
}) })
this.rooms = rms
this.rooms = [...this.rooms, ...newRooms]
if (Room.length < this.roomPageSize) { if (Room.length < this.roomPageSize) {
this.roomsLoaded = true this.roomsLoaded = true
@ -282,8 +291,14 @@ export default {
fetchPolicy: 'no-cache', fetchPolicy: 'no-cache',
}) })
const newMsgIds = Message.filter((m) => m.seen === false).map((m) => m.id) const newMsgIds = Message.filter(
(m) => m.seen === false && m.senderId !== this.currentUser.id,
).map((m) => m.id)
if (newMsgIds.length) { if (newMsgIds.length) {
const roomIndex = this.rooms.findIndex((r) => r.id === room.id)
const changedRoom = { ...this.rooms[roomIndex] }
changedRoom.unreadCount = changedRoom.unreadCount - newMsgIds.length
this.rooms[roomIndex] = changedRoom
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: markMessagesAsSeen(), mutation: markMessagesAsSeen(),
@ -322,24 +337,21 @@ export default {
}, },
async chatMessageAdded({ data }) { async chatMessageAdded({ data }) {
const roomIndex = this.rooms.findIndex((r) => r.id === data.chatMessageAdded.room.id)
const changedRoom = { ...this.rooms[roomIndex] }
changedRoom.lastMessage = data.chatMessageAdded
changedRoom.lastMessage.content = changedRoom.lastMessage.content.trim().substring(0, 30)
changedRoom.lastMessageAt = data.chatMessageAdded.date
changedRoom.unreadCount++
this.rooms[roomIndex] = changedRoom
if (data.chatMessageAdded.room.id === this.selectedRoom?.id) { if (data.chatMessageAdded.room.id === this.selectedRoom?.id) {
this.fetchMessages({ room: this.selectedRoom, options: { refetch: true } }) this.fetchMessages({ room: this.selectedRoom, options: { refetch: true } })
} else { } else {
// TODO this might be optimized selectively (first page vs rest) this.fetchRooms({ options: { refetch: true } })
this.rooms = []
this.roomPage = 0
this.roomsLoaded = false
this.fetchRooms()
} }
}, },
async sendMessage(message) { async sendMessage(message) {
// check for usersTag and change userid to username
message.usersTag.forEach((userTag) => {
const needle = `<usertag>${userTag.id}</usertag>`
const replacement = `<usertag>@${userTag.name.replaceAll(' ', '-').toLowerCase()}</usertag>`
message.content = message.content.replaceAll(needle, replacement)
})
try { try {
await this.$apollo.mutate({ await this.$apollo.mutate({
mutation: createMessageMutation(), mutation: createMessageMutation(),
@ -348,6 +360,11 @@ export default {
content: message.content, content: message.content,
}, },
}) })
const roomIndex = this.rooms.findIndex((r) => r.id === message.roomId)
const changedRoom = { ...this.rooms[roomIndex] }
changedRoom.lastMessage = message
changedRoom.lastMessage.content = changedRoom.lastMessage.content.trim().substring(0, 30)
this.rooms[roomIndex] = changedRoom
} catch (error) { } catch (error) {
this.$toast.error(error.message) this.$toast.error(error.message)
} }

View File

@ -65,7 +65,7 @@ const STYLE = {
backgroundSelected: '#c2dcf2', backgroundSelected: '#c2dcf2',
colorDeleted: '#757e85', colorDeleted: '#757e85',
colorUsername: '#9ca6af', colorUsername: '#9ca6af',
colorTimestamp: '#828c94', colorTimestamp: styleData.chatMessageTimestamp,
backgroundDate: '#e5effa', backgroundDate: '#e5effa',
colorDate: '#505a62', colorDate: '#505a62',
backgroundSystem: '#e5effa', backgroundSystem: '#e5effa',
@ -134,8 +134,8 @@ const STYLE = {
emojiReaction: 'rgba(0, 0, 0, 0.3)', emojiReaction: 'rgba(0, 0, 0, 0.3)',
document: styleData.colorPrimary, document: styleData.colorPrimary,
pencil: '#9e9e9e', pencil: '#9e9e9e',
checkmark: '#9e9e9e', checkmark: styleData.chatMessageCheckmark,
checkmarkSeen: '#0696c7', checkmarkSeen: styleData.chatMessageCheckmarkSeen,
eye: '#fff', eye: '#fff',
dropdownMessage: '#fff', dropdownMessage: '#fff',
dropdownMessageBackground: 'rgba(0, 0, 0, 0.25)', dropdownMessageBackground: 'rgba(0, 0, 0, 0.25)',