basic view chat routing and component structure
This commit is contained in:
parent
c46793cfaa
commit
410ae72b9e
9 changed files with 693 additions and 12 deletions
32
src/api/chat.js
Normal file
32
src/api/chat.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import request from '@/utils/request'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { baseName } from './utils'
|
||||
|
||||
export async function deleteChatMessage(id, message_id, authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/pleroma/admin/chats/{id}/messages/${message_id}`,
|
||||
method: 'delete',
|
||||
headers: authHeaders(token)
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchChat(id, authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/pleroma/admin/chats/${id}`,
|
||||
method: 'get',
|
||||
headers: authHeaders(token)
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchChatMessages(id, authHost, token) {
|
||||
return await request({
|
||||
baseURL: baseName(authHost),
|
||||
url: `/api/pleroma/admin/chats/${id}/messages`,
|
||||
method: 'get',
|
||||
headers: authHeaders(token)
|
||||
})
|
||||
}
|
||||
|
||||
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
163
src/components/ChatMessage/index.vue
Normal file
163
src/components/ChatMessage/index.vue
Normal file
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<el-card v-if="!message.deleted" class="message-card" @click.native="handleRouteChange()">
|
||||
<div slot="header">
|
||||
<div class="message-header">
|
||||
{{ message.created_at }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
{{ message.content }}
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'ChatMessage',
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
.chat-card {
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
.account {
|
||||
line-height: 26px;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
}
|
||||
.account:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.deactivated {
|
||||
color: gray;
|
||||
line-height: 28px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.image {
|
||||
width: 20%;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.router-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
.show-more-button {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.chat-account {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-avatar-img {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.chat-account-name {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.chat-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.chat-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-checkbox {
|
||||
margin-right: 7px;
|
||||
}
|
||||
.chat-content {
|
||||
font-size: 15px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.chat-created-at {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
}
|
||||
.chat-deleted {
|
||||
font-style: italic;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.chat-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.chat-tags {
|
||||
display: inline;
|
||||
}
|
||||
.chat-without-content {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.el-message {
|
||||
min-width: 80%;
|
||||
}
|
||||
.el-message-box {
|
||||
width: 80%;
|
||||
}
|
||||
.chat-card {
|
||||
.el-card__header {
|
||||
padding: 10px 17px;
|
||||
}
|
||||
.el-tag {
|
||||
margin: 3px 0;
|
||||
}
|
||||
.chat-account-container {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.chat-actions-button {
|
||||
margin: 3px 0 3px;
|
||||
}
|
||||
.chat-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.chat-footer {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.chat-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -67,6 +67,7 @@ export default {
|
|||
reports: 'Reports',
|
||||
invites: 'Invites',
|
||||
statuses: 'Statuses',
|
||||
chats: 'Chats',
|
||||
settings: 'Settings',
|
||||
moderationLog: 'Moderation Log',
|
||||
mediaProxyCache: 'MediaProxy Cache',
|
||||
|
@ -299,6 +300,11 @@ export default {
|
|||
unlisted: 'Unlisted',
|
||||
openStatusInInstance: 'Open status in instance'
|
||||
},
|
||||
chats: {
|
||||
chats: 'Chats',
|
||||
loadMore: 'Load more',
|
||||
chatHistory: 'Chat History'
|
||||
},
|
||||
userProfile: {
|
||||
tags: 'Tags',
|
||||
moderator: 'Moderator',
|
||||
|
|
|
@ -35,6 +35,21 @@ const statuses = {
|
|||
]
|
||||
}
|
||||
|
||||
const chatsDisabled = disabledFeatures.includes('chats')
|
||||
const chats = {
|
||||
path: '/chats',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/chats/index'),
|
||||
name: 'Chats',
|
||||
meta: { title: 'chats', icon: 'form', noCache: true }
|
||||
}
|
||||
],
|
||||
hidden: true
|
||||
}
|
||||
|
||||
const reportsDisabled = disabledFeatures.includes('reports')
|
||||
const reports = {
|
||||
path: '/reports',
|
||||
|
@ -169,6 +184,7 @@ export const asyncRouterMap = [
|
|||
]
|
||||
},
|
||||
...(statusesDisabled ? [] : [statuses]),
|
||||
...(chatsDisabled ? [] : [chats]),
|
||||
...(reportsDisabled ? [] : [reports]),
|
||||
...(invitesDisabled ? [] : [invites]),
|
||||
...(emojiPacksDisabled ? [] : [emojiPacks]),
|
||||
|
@ -211,5 +227,17 @@ export const asyncRouterMap = [
|
|||
],
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/chats/:id',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'ChatsShow',
|
||||
component: () => import('@/views/chats/show')
|
||||
}
|
||||
],
|
||||
hidden: true
|
||||
},
|
||||
{ path: '*', redirect: '/404', hidden: true }
|
||||
]
|
||||
|
|
|
@ -13,6 +13,7 @@ import relays from './modules/relays'
|
|||
import reports from './modules/reports'
|
||||
import settings from './modules/settings'
|
||||
import status from './modules/status'
|
||||
import chat from './modules/chat'
|
||||
import tagsView from './modules/tagsView'
|
||||
import user from './modules/user'
|
||||
import userProfile from './modules/userProfile'
|
||||
|
@ -34,6 +35,7 @@ const store = new Vuex.Store({
|
|||
reports,
|
||||
settings,
|
||||
status,
|
||||
chat,
|
||||
tagsView,
|
||||
user,
|
||||
userProfile,
|
||||
|
|
39
src/store/modules/chat.js
Normal file
39
src/store/modules/chat.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { fetchChat, fetchChatMessages } from '@/api/chat'
|
||||
|
||||
const chat = {
|
||||
state: {
|
||||
fetchedChat: {},
|
||||
fetchedChatMessages: {},
|
||||
loading: false,
|
||||
chatAuthor: {}
|
||||
},
|
||||
mutations: {
|
||||
SET_LOADING: (state, status) => {
|
||||
state.loading = status
|
||||
},
|
||||
SET_CHAT: (state, chat) => {
|
||||
state.fetchedChat = chat
|
||||
},
|
||||
SET_CHAT_MESSAGES: (state, chatMessages) => {
|
||||
state.fetchedChatMessages = chatMessages
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async FetchChat({ commit, dispatch, getters, state }, id) {
|
||||
commit('SET_LOADING', true)
|
||||
const chat = await fetchChat(id, getters.authHost, getters.token)
|
||||
|
||||
commit('SET_CHAT', chat.data)
|
||||
commit('SET_LOADING', false)
|
||||
},
|
||||
async FetchChatMessages({ commit, dispatch, getters, state }, id) {
|
||||
commit('SET_LOADING', true)
|
||||
const chat = await fetchChatMessages(id, getters.authHost, getters.token)
|
||||
|
||||
commit('SET_CHAT_MESSAGES', chat.data)
|
||||
commit('SET_LOADING', false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default chat
|
167
src/views/chats/index.vue
Normal file
167
src/views/chats/index.vue
Normal file
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<div v-if="!loadingPeers" class="chats-container">
|
||||
<div class="chats-header">
|
||||
<h1>
|
||||
{{ $t('chats.chats') }}
|
||||
</h1>
|
||||
<reboot-button/>
|
||||
</div>
|
||||
<div class="chats-header-container"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'Chats',
|
||||
components: {
|
||||
RebootButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
allLoaded() {
|
||||
return this.$store.state.chat.chatsByInstance.allLoaded
|
||||
},
|
||||
buttonLoading() {
|
||||
return this.$store.state.chat.chatsByInstance.buttonLoading
|
||||
},
|
||||
currentInstance() {
|
||||
return this.selectedInstance === this.$store.state.user.authHost
|
||||
},
|
||||
isDesktop() {
|
||||
return this.$store.state.app.device === 'desktop'
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
page() {
|
||||
return this.$store.state.chat.chatsByInstance.page
|
||||
},
|
||||
pageSize() {
|
||||
return this.$store.state.chat.chatsByInstance.pageSize
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('NeedReboot')
|
||||
},
|
||||
destroyed() {
|
||||
this.clearSelection()
|
||||
this.$store.dispatch('ClearState')
|
||||
},
|
||||
methods: {
|
||||
clearSelection() {
|
||||
this.selectedUsers = []
|
||||
},
|
||||
handleLoadMore() {
|
||||
this.$store.dispatch('HandlePageChange', this.page + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
.chats-container {
|
||||
padding: 0 15px;
|
||||
h1 {
|
||||
margin: 10px 0 15px 0;
|
||||
}
|
||||
.chat-container {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
.chats-header-container {
|
||||
.el-button.is-plain:focus, .el-button.is-plain:hover {
|
||||
border-color: #DCDFE6;
|
||||
color: #606266;
|
||||
cursor: default
|
||||
}
|
||||
}
|
||||
.checkbox-container {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.filter-container {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 22px 0 15px 0;
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
width: 145px;
|
||||
}
|
||||
.select-instance {
|
||||
width: 396px;
|
||||
}
|
||||
.chats-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.chats-header-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.chats-pagination {
|
||||
padding: 15px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.checkbox-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.filter-container {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
flex-direction: column;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.select-field {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.select-instance {
|
||||
width: 100%;
|
||||
}
|
||||
.chats-header-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
.el-button-group {
|
||||
width: 100%;
|
||||
}
|
||||
.el-button {
|
||||
padding: 10px 6.5px;
|
||||
width: 50%;
|
||||
}
|
||||
.el-button-group>.el-button:first-child {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.el-button-group>.el-button:not(:first-child):not(:last-child).private-button {
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.el-button-group>.el-button:not(:first-child):not(:last-child).public-button {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top: white;
|
||||
}
|
||||
.el-button-group>.el-button:last-child {
|
||||
border-top-right-radius: 0;
|
||||
border-top: white;
|
||||
}
|
||||
.reboot-button {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
242
src/views/chats/show.vue
Normal file
242
src/views/chats/show.vue
Normal file
|
@ -0,0 +1,242 @@
|
|||
<template>
|
||||
<div v-if="!loading" class="chat-show-container">
|
||||
<header v-if="isDesktop || isTablet" class="user-page-header">
|
||||
<div class="avatar-name-container"/>
|
||||
</header>
|
||||
<div v-if="isMobile" class="chat-page-header-container">
|
||||
<header class="user-page-header">
|
||||
<div class="avatar-name-container"/>
|
||||
<reboot-button/>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="chat-container">
|
||||
<div class="chat-card-header">
|
||||
<h1>
|
||||
{{ $t('chats.chatHistory') }}
|
||||
</h1>
|
||||
<!-- <img v-if="propertyExists(chat.account, 'avatar')" :src="chat.account.avatar" class="chat-avatar-img">
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">{{ chat.account.username }}</span>
|
||||
<span v-else>
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">
|
||||
{{ chat.account.username }}
|
||||
</span>
|
||||
<span v-else class="chat-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
|
||||
</span> -->
|
||||
</div>
|
||||
|
||||
<div class="chat-messages">
|
||||
<div v-for="message in chatMessages" :key="message.id" class="">
|
||||
<chat-message :message="message"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChatMessage from '@/components/ChatMessage'
|
||||
import RebootButton from '@/components/RebootButton'
|
||||
|
||||
export default {
|
||||
name: 'ChatShow',
|
||||
components: { RebootButton, ChatMessage },
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isDesktop() {
|
||||
return this.$store.state.app.device === 'desktop'
|
||||
},
|
||||
isMobile() {
|
||||
return this.$store.state.app.device === 'mobile'
|
||||
},
|
||||
isTablet() {
|
||||
return this.$store.state.app.device === 'tablet'
|
||||
},
|
||||
loading() {
|
||||
return this.$store.state.chat.loading
|
||||
},
|
||||
chat() {
|
||||
return this.$store.state.chat.fetchedChat
|
||||
},
|
||||
chatMessages() {
|
||||
return this.$store.state.chat.fetchedChatMessages
|
||||
}
|
||||
},
|
||||
beforeMount: function() {
|
||||
this.$store.dispatch('NeedReboot')
|
||||
this.$store.dispatch('GetNodeInfo')
|
||||
this.$store.dispatch('FetchChat', this.$route.params.id)
|
||||
this.$store.dispatch('FetchChatMessages', this.$route.params.id)
|
||||
},
|
||||
methods: {
|
||||
propertyExists(account, property) {
|
||||
return account[property]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel='stylesheet/scss' lang='scss'>
|
||||
.avatar-name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.el-icon-top-right {
|
||||
font-size: 2em;
|
||||
line-height: 36px;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
.avatar-name-header {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
.invalid {
|
||||
color: gray;
|
||||
}
|
||||
.no-chats {
|
||||
margin-left: 28px;
|
||||
color: #606266;
|
||||
}
|
||||
.password-reset-token {
|
||||
margin: 0 0 14px 0;
|
||||
}
|
||||
.password-reset-token-dialog {
|
||||
width: 50%
|
||||
}
|
||||
.reboot-button {
|
||||
padding: 10px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.recent-chats-container-show {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.el-timeline-item {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.recent-chats {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.show-private-chats {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.reset-password-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.router-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
.chat-container {
|
||||
margin: 0 15px 0 20px;
|
||||
}
|
||||
.chats {
|
||||
padding: 0 20px 0 0;
|
||||
}
|
||||
.user-page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 22px 15px 22px 20px;
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
h1 {
|
||||
display: inline;
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1824px) {
|
||||
.chat-show-container {
|
||||
max-width: 1824px;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
.avatar-name-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.el-timeline-item__wrapper {
|
||||
padding-left: 18px;
|
||||
}
|
||||
.left-header-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.password-reset-token-dialog {
|
||||
width: 85%
|
||||
}
|
||||
.recent-chats {
|
||||
margin: 20px 10px 15px 10px;
|
||||
}
|
||||
.recent-chats-container-show {
|
||||
width: 100%;
|
||||
margin: 0 0 0 10px;
|
||||
.el-timeline-item {
|
||||
margin-left: 0;
|
||||
}
|
||||
.recent-chats {
|
||||
margin-left: 0;
|
||||
}
|
||||
.show-private-chats {
|
||||
margin: 0 10px 20px 0;
|
||||
}
|
||||
}
|
||||
.chat-card {
|
||||
.el-card__body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
.chat-container {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.chats {
|
||||
padding-right: 10px;
|
||||
margin-left: 0;
|
||||
.el-timeline-item__wrapper {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.user-page-header {
|
||||
padding: 0;
|
||||
margin: 7px 15px 5px 10px;
|
||||
}
|
||||
.chat-page-header-container {
|
||||
width: 100%;
|
||||
.el-dropdown {
|
||||
width: stretch;
|
||||
margin: 0 10px 15px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width:801px) and (min-width: 481px) {
|
||||
.recent-chats-container-show {
|
||||
width: 97%;
|
||||
margin: 0 20px;
|
||||
.el-timeline-item {
|
||||
margin-left: 2px;
|
||||
}
|
||||
.recent-chats {
|
||||
margin: 20px 10px 15px 0;
|
||||
}
|
||||
.show-private-chats {
|
||||
margin: 0 10px 20px 0;
|
||||
}
|
||||
}
|
||||
.show-private-chats {
|
||||
margin: 0 10px 20px 0;
|
||||
}
|
||||
.user-page-header {
|
||||
padding: 0;
|
||||
margin: 7px 15px 20px 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -120,19 +120,21 @@
|
|||
</tr>
|
||||
<tr v-for="chat in chats" :key="chat.id" class="el-table__row chat-item">
|
||||
<td>
|
||||
<div class="chat-card-header">
|
||||
<img v-if="propertyExists(chat.account, 'avatar')" :src="chat.account.avatar" class="chat-avatar-img">
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">{{ chat.account.username }}</span>
|
||||
<span v-else>
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">
|
||||
{{ chat.account.username }}
|
||||
<a v-if="propertyExists(chat, 'id')" :href="`/#/chats/${chat.id}/`">
|
||||
<div class="chat-card-header">
|
||||
<img v-if="propertyExists(chat.account, 'avatar')" :src="chat.account.avatar" class="chat-avatar-img">
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">{{ chat.account.username }}</span>
|
||||
<span v-else>
|
||||
<span v-if="propertyExists(chat.account, 'username')" class="chat-account-name">
|
||||
{{ chat.account.username }}
|
||||
</span>
|
||||
<span v-else class="chat-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
|
||||
</span>
|
||||
<span v-else class="chat-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="chat-card-preview">
|
||||
<span v-if="propertyExists(chat, 'last_message')" class="chat-preview">{{ chat.last_message.content }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-card-preview">
|
||||
<span v-if="propertyExists(chat, 'last_message')" class="chat-preview">{{ chat.last_message.content }}</span>
|
||||
</div>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
Loading…
Reference in a new issue