mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' into 3086-avoid-red-color-for-non-essential-things--new
This commit is contained in:
commit
d13f6f0728
@ -9,10 +9,9 @@ function walkRecursive(data, fields, fieldName, callback, _key?) {
|
||||
if (!Array.isArray(fields)) {
|
||||
throw new Error('please provide an fields array for the walkRecursive helper')
|
||||
}
|
||||
if (data && typeof data === 'string' && fields.includes(_key)) {
|
||||
// well we found what we searched for, lets replace the value with our callback result
|
||||
const key = _key.split('!')
|
||||
if (key.length === 1 || key[1] !== fieldName) data = callback(data, key[0])
|
||||
const fieldDef = fields.find((f) => f.field === _key)
|
||||
if (data && typeof data === 'string' && fieldDef) {
|
||||
if (!fieldDef.excludes?.includes(fieldName)) data = callback(data, _key)
|
||||
} else if (data && Array.isArray(data)) {
|
||||
// go into the rabbit hole and dig through that array
|
||||
data.forEach((res, index) => {
|
||||
|
||||
@ -30,6 +30,7 @@ const standardSanitizeHtmlOptions = {
|
||||
'strike',
|
||||
'span',
|
||||
'blockquote',
|
||||
'usertag',
|
||||
],
|
||||
allowedAttributes: {
|
||||
a: ['href', 'class', 'target', 'data-*', 'contenteditable'],
|
||||
|
||||
@ -3,11 +3,11 @@ import { cleanHtml } from '../middleware/helpers/cleanHtml'
|
||||
|
||||
// exclamation mark separetes field names, that should not be sanitized
|
||||
const fields = [
|
||||
'content',
|
||||
'contentExcerpt',
|
||||
'reasonDescription',
|
||||
'description!embed',
|
||||
'descriptionExcerpt',
|
||||
{ field: 'content', excludes: ['CreateMessage', 'Message'] },
|
||||
{ field: 'contentExcerpt' },
|
||||
{ field: 'reasonDescription' },
|
||||
{ field: 'description', excludes: ['embed'] },
|
||||
{ field: 'descriptionExcerpt' },
|
||||
]
|
||||
|
||||
export default {
|
||||
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
createdAt: toString(datetime()),
|
||||
id: apoc.create.uuid(),
|
||||
indexId: CASE WHEN maxIndex IS NOT NULL THEN maxIndex + 1 ELSE 0 END,
|
||||
content: $content,
|
||||
content: LEFT($content,2000),
|
||||
saved: true,
|
||||
distributed: false,
|
||||
seen: false
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<vue-advanced-chat
|
||||
:theme="theme"
|
||||
:current-user-id="currentUser.id"
|
||||
:room-id="!singleRoom ? roomId : null"
|
||||
:room-id="computedRoomId"
|
||||
:template-actions="JSON.stringify(templatesText)"
|
||||
:menu-actions="JSON.stringify(menuActions)"
|
||||
:text-messages="JSON.stringify(textMessages)"
|
||||
@ -27,15 +27,33 @@
|
||||
show-reaction-emojis="false"
|
||||
@show-demo-options="showDemoOptions = $event"
|
||||
>
|
||||
<div slot="menu-icon" @click.prevent.stop="$emit('close-single-room', true)">
|
||||
<div v-if="singleRoom">
|
||||
<ds-icon name="close"></ds-icon>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedRoom && selectedRoom.roomId"
|
||||
slot="room-options"
|
||||
class="chat-room-options"
|
||||
>
|
||||
<ds-flex v-if="singleRoom">
|
||||
<ds-flex-item centered class="single-chat-bubble">
|
||||
<nuxt-link :to="{ name: 'chat' }">
|
||||
<base-icon name="chat-bubble" />
|
||||
</nuxt-link>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item centered>
|
||||
<div
|
||||
class="vac-svg-button vac-room-options"
|
||||
@click="$emit('close-single-room', true)"
|
||||
>
|
||||
<slot name="menu-icon">
|
||||
<ds-icon name="close" />
|
||||
</slot>
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</div>
|
||||
|
||||
<div slot="room-header-avatar">
|
||||
<div
|
||||
v-if="selectedRoom && selectedRoom.avatar && selectedRoom.avatar !== 'default-avatar'"
|
||||
v-if="selectedRoom && selectedRoom.avatar"
|
||||
class="vac-avatar"
|
||||
:style="{ 'background-image': `url('${selectedRoom.avatar}')` }"
|
||||
/>
|
||||
@ -46,7 +64,7 @@
|
||||
|
||||
<div v-for="room in rooms" :slot="'room-list-avatar_' + room.id" :key="room.id">
|
||||
<div
|
||||
v-if="room.avatar && room.avatar !== 'default-avatar'"
|
||||
v-if="room.avatar"
|
||||
class="vac-avatar"
|
||||
:style="{ 'background-image': `url('${room.avatar}')` }"
|
||||
/>
|
||||
@ -89,11 +107,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
menuActions: [
|
||||
// NOTE: if menuActions is empty, the related slot is not shown
|
||||
{
|
||||
name: 'dummyItem',
|
||||
title: 'Just a dummy item',
|
||||
},
|
||||
/*
|
||||
{
|
||||
name: 'inviteUser',
|
||||
@ -197,10 +210,24 @@ export default {
|
||||
computed: {
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
getStoreRoomId: 'chat/roomID',
|
||||
}),
|
||||
computedChatStyle() {
|
||||
return chatStyle.STYLE.light
|
||||
},
|
||||
computedRoomId() {
|
||||
let roomId = null
|
||||
|
||||
if (!this.singleRoom) {
|
||||
roomId = this.roomId
|
||||
|
||||
if (this.getStoreRoomId.roomId) {
|
||||
roomId = this.getStoreRoomId.roomId
|
||||
}
|
||||
}
|
||||
|
||||
return roomId
|
||||
},
|
||||
textMessages() {
|
||||
return {
|
||||
ROOMS_EMPTY: this.$t('chat.roomsEmpty'),
|
||||
@ -221,10 +248,11 @@ export default {
|
||||
methods: {
|
||||
...mapMutations({
|
||||
commitUnreadRoomCount: 'chat/UPDATE_ROOM_COUNT',
|
||||
commitRoomIdFromSingleRoom: 'chat/UPDATE_ROOM_ID',
|
||||
}),
|
||||
async fetchRooms({ room } = {}) {
|
||||
this.roomsLoaded = false
|
||||
const offset = this.roomPage * this.roomPageSize
|
||||
async fetchRooms({ room, options = {} } = {}) {
|
||||
this.roomsLoaded = options.refetch ? this.roomsLoaded : false
|
||||
const offset = (options.refetch ? 0 : this.roomPage) * this.roomPageSize
|
||||
try {
|
||||
const {
|
||||
data: { Room },
|
||||
@ -238,21 +266,37 @@ export default {
|
||||
fetchPolicy: 'no-cache',
|
||||
})
|
||||
|
||||
const newRooms = Room.map((r) => {
|
||||
return {
|
||||
...r,
|
||||
users: r.users.map((u) => {
|
||||
return { ...u, username: u.name, avatar: u.avatar?.url }
|
||||
}),
|
||||
const rms = []
|
||||
const rmsIds = []
|
||||
;[...Room, ...this.rooms].forEach((r) => {
|
||||
if (!rmsIds.find((v) => v === r.id)) {
|
||||
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 = [...this.rooms, ...newRooms]
|
||||
this.rooms = rms
|
||||
|
||||
if (Room.length < this.roomPageSize) {
|
||||
this.roomsLoaded = true
|
||||
}
|
||||
this.roomPage += 1
|
||||
|
||||
if (this.singleRoom && this.rooms.length > 0) {
|
||||
this.commitRoomIdFromSingleRoom(this.rooms[0].roomId)
|
||||
} else if (this.getStoreRoomId.roomId) {
|
||||
// reset store room id
|
||||
this.commitRoomIdFromSingleRoom(null)
|
||||
}
|
||||
} catch (error) {
|
||||
this.rooms = []
|
||||
this.$toast.error(error.message)
|
||||
@ -282,8 +326,14 @@ export default {
|
||||
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) {
|
||||
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
|
||||
.mutate({
|
||||
mutation: markMessagesAsSeen(),
|
||||
@ -322,32 +372,36 @@ export default {
|
||||
},
|
||||
|
||||
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) {
|
||||
this.fetchMessages({ room: this.selectedRoom, options: { refetch: true } })
|
||||
} else {
|
||||
// TODO this might be optimized selectively (first page vs rest)
|
||||
this.rooms = []
|
||||
this.roomPage = 0
|
||||
this.roomsLoaded = false
|
||||
this.fetchRooms()
|
||||
this.fetchRooms({ options: { refetch: true } })
|
||||
}
|
||||
},
|
||||
|
||||
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 {
|
||||
await this.$apollo.mutate({
|
||||
const {
|
||||
data: { CreateMessage: createdMessage },
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: createMessageMutation(),
|
||||
variables: {
|
||||
roomId: message.roomId,
|
||||
content: message.content,
|
||||
},
|
||||
})
|
||||
const roomIndex = this.rooms.findIndex((r) => r.id === message.roomId)
|
||||
const changedRoom = { ...this.rooms[roomIndex] }
|
||||
changedRoom.lastMessage = createdMessage
|
||||
changedRoom.lastMessage.content = changedRoom.lastMessage.content.trim().substring(0, 30)
|
||||
this.rooms[roomIndex] = changedRoom
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message)
|
||||
}
|
||||
@ -389,4 +443,8 @@ body {
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.ds-flex-item.single-chat-bubble {
|
||||
margin-right: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -58,14 +58,14 @@ export default {
|
||||
routes.push({
|
||||
label: this.$t('group.contentMenu.visitGroupPage'),
|
||||
icon: 'home',
|
||||
name: 'group-id-slug',
|
||||
path: `/groups/${this.group.id}`,
|
||||
params: { id: this.group.id, slug: this.group.slug },
|
||||
})
|
||||
}
|
||||
if (this.group.myRole === 'owner') {
|
||||
routes.push({
|
||||
label: this.$t('admin.settings.name'),
|
||||
path: `/group/edit/${this.group.id}`,
|
||||
path: `/groups/edit/${this.group.id}`,
|
||||
icon: 'edit',
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<nuxt-link
|
||||
class="group-teaser"
|
||||
:to="{ name: 'group-id-slug', params: { id: group.id, slug: group.slug } }"
|
||||
:to="{ name: 'groups-id-slug', params: { id: group.id, slug: group.slug } }"
|
||||
>
|
||||
<base-card
|
||||
:class="{
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<p class="description">{{ $t(`notifications.reason.${notification.reason}`) }}</p>
|
||||
<nuxt-link
|
||||
class="link"
|
||||
:to="{ name: isGroup ? 'group-id-slug' : 'post-id-slug', params, ...hashParam }"
|
||||
:to="{ name: isGroup ? 'groups-id-slug' : 'post-id-slug', params, ...hashParam }"
|
||||
@click.native="$emit('read')"
|
||||
>
|
||||
<base-card wideContent>
|
||||
|
||||
@ -65,7 +65,7 @@
|
||||
class="notification-mention-post"
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
:to="{
|
||||
name: isGroup(notification.from) ? 'group-id-slug' : 'post-id-slug',
|
||||
name: isGroup(notification.from) ? 'groups-id-slug' : 'post-id-slug',
|
||||
params: params(notification.from),
|
||||
hash: hashParam(notification.from),
|
||||
}"
|
||||
|
||||
@ -96,7 +96,7 @@ export default {
|
||||
groupLink() {
|
||||
const { id, slug } = this.group
|
||||
if (!(id && slug)) return ''
|
||||
return { name: 'group-id-slug', params: { slug, id } }
|
||||
return { name: 'groups-id-slug', params: { slug, id } }
|
||||
},
|
||||
groupSlug() {
|
||||
const { slug } = this.group || {}
|
||||
|
||||
@ -148,7 +148,7 @@ export default {
|
||||
case 'User':
|
||||
return 'profile-id-slug'
|
||||
case 'Group':
|
||||
return 'group-id-slug'
|
||||
return 'groups-id-slug'
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
||||
@ -4,8 +4,23 @@ export const createMessageMutation = () => {
|
||||
return gql`
|
||||
mutation ($roomId: ID!, $content: String!) {
|
||||
CreateMessage(roomId: $roomId, content: $content) {
|
||||
#_id
|
||||
id
|
||||
indexId
|
||||
content
|
||||
senderId
|
||||
author {
|
||||
id
|
||||
}
|
||||
username
|
||||
avatar
|
||||
date
|
||||
room {
|
||||
id
|
||||
}
|
||||
saved
|
||||
distributed
|
||||
seen
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -26,6 +41,9 @@ export const messageQuery = () => {
|
||||
username
|
||||
avatar
|
||||
date
|
||||
room {
|
||||
id
|
||||
}
|
||||
saved
|
||||
distributed
|
||||
seen
|
||||
|
||||
@ -24,7 +24,7 @@ const options = {
|
||||
}
|
||||
`,
|
||||
message: 'error-pages.group-not-found',
|
||||
path: 'group',
|
||||
path: 'groups',
|
||||
}
|
||||
const persistentLinks = PersistentLinks(options)
|
||||
|
||||
@ -59,7 +59,7 @@ export default {
|
||||
})
|
||||
this.$toast.success(this.$t('group.groupCreated'))
|
||||
this.$router.history.push({
|
||||
name: 'group-id-slug',
|
||||
name: 'groups-id-slug',
|
||||
params: { id: responseId, slug: responseSlug },
|
||||
})
|
||||
} catch (error) {
|
||||
@ -33,11 +33,11 @@ export default {
|
||||
return [
|
||||
{
|
||||
name: this.$t('group.general'),
|
||||
path: `/group/edit/${this.group.id}`,
|
||||
path: `/groups/edit/${this.group.id}`,
|
||||
},
|
||||
{
|
||||
name: this.$t('group.members'),
|
||||
path: `/group/edit/${this.group.id}/members`,
|
||||
path: `/groups/edit/${this.group.id}/members`,
|
||||
},
|
||||
]
|
||||
},
|
||||
@ -60,7 +60,7 @@ export default {
|
||||
})
|
||||
this.$toast.success(this.$t('group.updatedGroup'))
|
||||
this.$router.history.push({
|
||||
name: 'group-id-slug',
|
||||
name: 'groups-id-slug',
|
||||
params: { id: responseId, slug: responseSlug },
|
||||
})
|
||||
} catch (error) {
|
||||
@ -1,5 +1,5 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import groups from './groups.vue'
|
||||
import groups from './index.vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<ds-space>
|
||||
<!-- create group -->
|
||||
<ds-space centered>
|
||||
<nuxt-link :to="{ name: 'group-create' }">
|
||||
<nuxt-link :to="{ name: 'groups-create' }">
|
||||
<base-button
|
||||
class="group-add-button"
|
||||
icon="plus"
|
||||
@ -14,6 +14,9 @@ export const mutations = {
|
||||
UPDATE_ROOM_COUNT(state, count) {
|
||||
state.unreadRoomCount = count
|
||||
},
|
||||
UPDATE_ROOM_ID(state, roomid) {
|
||||
state.roomId = roomid || null
|
||||
},
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user