summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaksim Sukharev <antreesy.web@gmail.com>2023-09-27 16:25:50 +0200
committerMaksim Sukharev <antreesy.web@gmail.com>2023-09-29 10:56:52 +0200
commitcc6a7c564e35b8844bdaa94c2c9fcf96bf95b4dd (patch)
tree3ac5e5cb76303bfb0a1857317cba6682fa537bdb
parent450a9270baa5af3e03df15668444c08b2f5dc5b2 (diff)
replace single-used AuthorAvatar component with AvatarWrapper
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
-rw-r--r--src/components/AvatarWrapper/AvatarWrapper.vue54
-rw-r--r--src/components/MessagesList/MessagesGroup/AuthorAvatar.vue117
-rw-r--r--src/components/MessagesList/MessagesGroup/MessagesGroup.spec.js26
-rw-r--r--src/components/MessagesList/MessagesGroup/MessagesGroup.vue23
4 files changed, 72 insertions, 148 deletions
diff --git a/src/components/AvatarWrapper/AvatarWrapper.vue b/src/components/AvatarWrapper/AvatarWrapper.vue
index 6f9957f78..196be555b 100644
--- a/src/components/AvatarWrapper/AvatarWrapper.vue
+++ b/src/components/AvatarWrapper/AvatarWrapper.vue
@@ -2,8 +2,9 @@
- @copyright Copyright (c) 2020 Marco Ambrosini <marcoambrosini@icloud.com>
-
- @author Marco Ambrosini <marcoambrosini@icloud.com>
+ - @author Maksim Sukharev <antreesy.web@gmail.com>
-
- - @license GNU AGPL version 3 or any later version
+ - @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
@@ -20,14 +21,7 @@
-->
<template>
- <div class="avatar-wrapper"
- :class="{
- 'avatar-wrapper--offline': offline,
- 'avatar-wrapper--small': small,
- 'avatar-wrapper--condensed': condensed,
- 'avatar-wrapper--highlighted': highlighted,
- }"
- :style="{'--condensed-overlap': condensedOverlap}">
+ <div class="avatar-wrapper" :class="avatarClass" :style="{'--condensed-overlap': condensedOverlap}">
<div v-if="iconClass"
class="icon"
:class="[`avatar-${size}px`, iconClass]" />
@@ -36,6 +30,11 @@
:class="`avatar-${size}px`">
{{ firstLetterOfGuestName }}
</div>
+ <div v-else-if="isBot"
+ class="bot"
+ :class="`avatar-${size}px`">
+ {{ '>_' }}
+ </div>
<NcAvatar v-else
:key="id"
:user="id"
@@ -54,6 +53,8 @@
<script>
import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
+import { ATTENDEE } from '../../constants.js'
+
export default {
name: 'AvatarWrapper',
@@ -79,6 +80,10 @@ export default {
type: Boolean,
default: false,
},
+ medium: {
+ type: Boolean,
+ default: false,
+ },
condensed: {
type: Boolean,
default: false,
@@ -122,19 +127,37 @@ export default {
},
computed: {
size() {
- return this.small ? 22 : 44
+ return this.small ? 22 : this.medium ? 32 : 44
},
// Determines which icon is displayed
iconClass() {
- if (!this.source || this.source === 'users' || this.isGuest || this.isDeletedUser) {
+ if (!this.source || this.isUser || this.isBot || this.isGuest || this.isDeletedUser) {
return ''
}
if (this.source === 'emails') {
return 'icon-mail'
}
+ if (this.source === 'bots' && this.id === 'changelog') {
+ return 'icon-changelog'
+ }
// source: groups, circles
return 'icon-contacts'
},
+ avatarClass() {
+ return {
+ 'avatar-wrapper--offline': this.offline,
+ 'avatar-wrapper--small': this.small,
+ 'avatar-wrapper--medium': this.medium,
+ 'avatar-wrapper--condensed': this.condensed,
+ 'avatar-wrapper--highlighted': this.highlighted,
+ }
+ },
+ isUser() {
+ return this.source === 'users' || this.source === ATTENDEE.ACTOR_TYPE.BRIDGED
+ },
+ isBot() {
+ return this.source === 'bots' && this.id !== 'changelog'
+ },
isGuest() {
return this.source === 'guests'
},
@@ -161,7 +184,7 @@ export default {
</script>
<style lang="scss" scoped>
-@import '../../assets/avatar.scss';
+@import '../../assets/avatar';
.avatar-wrapper {
height: 44px;
@@ -176,6 +199,13 @@ export default {
@include avatar-mixin(22px);
}
+ &--medium {
+ height: 32px;
+ width: 32px;
+ border-radius: 32px;
+ @include avatar-mixin(32px);
+ }
+
&--condensed {
width: unset;
height: unset;
diff --git a/src/components/MessagesList/MessagesGroup/AuthorAvatar.vue b/src/components/MessagesList/MessagesGroup/AuthorAvatar.vue
deleted file mode 100644
index 26645bb4f..000000000
--- a/src/components/MessagesList/MessagesGroup/AuthorAvatar.vue
+++ /dev/null
@@ -1,117 +0,0 @@
-<!--
- - @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
- -
- - @author Joas Schilling <coding@schilljs.com>
- -
- - @license GNU AGPL version 3 or any later version
- -
- - This program is free software: you can redistribute it and/or modify
- - it under the terms of the GNU Affero General Public License as
- - published by the Free Software Foundation, either version 3 of the
- - License, or (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU Affero General Public License for more details.
- -
- - You should have received a copy of the GNU Affero General Public License
- - along with this program. If not, see <http://www.gnu.org/licenses/>.
--->
-
-<template>
- <NcAvatar v-if="isUser"
- :disable-tooltip="true"
- class="messages__avatar__icon"
- :user="authorId"
- :show-user-status="false"
- :disable-menu="disableMenu"
- :menu-container="menuContainer"
- menu-position="left"
- :display-name="displayName" />
- <div v-else-if="isDeletedUser"
- class="avatar-32px guest">
- X
- </div>
- <div v-else-if="isGuest"
- class="avatar-32px guest">
- {{ firstLetterOfGuestName }}
- </div>
- <div v-else-if="isChangelog"
- class="avatar-32px icon icon-changelog" />
- <div v-else
- class="avatar-32px bot">
- &gt;_
- </div>
-</template>
-
-<script>
-import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
-
-import { ATTENDEE } from '../../../constants.js'
-
-export default {
- name: 'AuthorAvatar',
- components: {
- NcAvatar,
- },
- props: {
- authorType: {
- type: String,
- required: true,
- },
- authorId: {
- type: String,
- required: true,
- },
- displayName: {
- type: String,
- required: true,
- },
- },
-
- computed: {
- isChangelog() {
- return this.authorType === 'bots' && this.authorId === 'changelog'
- },
- isUser() {
- return this.authorType === 'users' || this.authorType === ATTENDEE.ACTOR_TYPE.BRIDGED
- },
- isDeletedUser() {
- return this.authorType === 'deleted_users'
- },
- isGuest() {
- return this.authorType === 'guests'
- },
-
- firstLetterOfGuestName() {
- const customName = this.displayName !== t('spreed', 'Guest') ? this.displayName : '?'
- return customName.charAt(0)
- },
-
- menuContainer() {
- return this.$store.getters.getMainContainerSelector()
- },
-
- disableMenu() {
- // NcAvatarMenu doesn't work on Desktop
- // See: https://github.com/nextcloud/talk-desktop/issues/34
- if (IS_DESKTOP) {
- return true
- }
- // disable the menu if accessing the conversation as guest
- // or the message sender is a bridged user
- return this.$store.getters.getActorType() === 'guests' || this.authorType === ATTENDEE.ACTOR_TYPE.BRIDGED
- },
- },
-}
-</script>
-
-<style lang="scss" scoped>
-@import '../../../assets/avatar';
-
-// size of avatars of chat message authors
-$author-avatar-size: 32px;
-@include avatar-mixin($author-avatar-size);
-
-</style>
diff --git a/src/components/MessagesList/MessagesGroup/MessagesGroup.spec.js b/src/components/MessagesList/MessagesGroup/MessagesGroup.spec.js
index bc00b2f4c..893bbf9e5 100644
--- a/src/components/MessagesList/MessagesGroup/MessagesGroup.spec.js
+++ b/src/components/MessagesList/MessagesGroup/MessagesGroup.spec.js
@@ -82,10 +82,10 @@ describe('MessagesGroup.vue', () => {
},
})
- const avatarEl = wrapper.findComponent({ name: 'AuthorAvatar' })
- expect(avatarEl.attributes('authortype')).toBe(ATTENDEE.ACTOR_TYPE.USERS)
- expect(avatarEl.attributes('authorid')).toBe('actor-1')
- expect(avatarEl.attributes('displayname')).toBe('actor one')
+ const avatarEl = wrapper.findComponent({ name: 'AvatarWrapper' })
+ expect(avatarEl.attributes('source')).toBe(ATTENDEE.ACTOR_TYPE.USERS)
+ expect(avatarEl.attributes('id')).toBe('actor-1')
+ expect(avatarEl.attributes('name')).toBe('actor one')
const authorEl = wrapper.find('.messages__author')
expect(authorEl.text()).toBe('actor one')
@@ -155,7 +155,7 @@ describe('MessagesGroup.vue', () => {
},
})
- const avatarEl = wrapper.findComponent({ name: 'AuthorAvatar' })
+ const avatarEl = wrapper.findComponent({ name: 'AvatarWrapper' })
expect(avatarEl.exists()).toBe(false)
const messagesEl = wrapper.findAllComponents({ name: 'Message' })
@@ -225,10 +225,10 @@ describe('MessagesGroup.vue', () => {
},
})
- const avatarEl = wrapper.findComponent({ name: 'AuthorAvatar' })
- expect(avatarEl.attributes('authortype')).toBe(ATTENDEE.ACTOR_TYPE.GUESTS)
- expect(avatarEl.attributes('authorid')).toBe('actor-1')
- expect(avatarEl.attributes('displayname')).toBe('guest-one-display-name')
+ const avatarEl = wrapper.findComponent({ name: 'AvatarWrapper' })
+ expect(avatarEl.attributes('source')).toBe(ATTENDEE.ACTOR_TYPE.GUESTS)
+ expect(avatarEl.attributes('id')).toBe('actor-1')
+ expect(avatarEl.attributes('name')).toBe('guest-one-display-name')
const authorEl = wrapper.find('.messages__author')
expect(authorEl.text()).toBe('guest-one-display-name')
@@ -280,10 +280,10 @@ describe('MessagesGroup.vue', () => {
},
})
- const avatarEl = wrapper.findComponent({ name: 'AuthorAvatar' })
- expect(avatarEl.attributes('authortype')).toBe(ATTENDEE.ACTOR_TYPE.USERS)
- expect(avatarEl.attributes('authorid')).toBe('actor-1')
- expect(avatarEl.attributes('displayname')).toBe('Deleted user')
+ const avatarEl = wrapper.findComponent({ name: 'AvatarWrapper' })
+ expect(avatarEl.attributes('source')).toBe(ATTENDEE.ACTOR_TYPE.USERS)
+ expect(avatarEl.attributes('id')).toBe('actor-1')
+ expect(avatarEl.attributes('name')).toBe('Deleted user')
const authorEl = wrapper.find('.messages__author')
expect(authorEl.text()).toBe('Deleted user')
diff --git a/src/components/MessagesList/MessagesGroup/MessagesGroup.vue b/src/components/MessagesList/MessagesGroup/MessagesGroup.vue
index 0a1a71ba8..476ff0a25 100644
--- a/src/components/MessagesList/MessagesGroup/MessagesGroup.vue
+++ b/src/components/MessagesList/MessagesGroup/MessagesGroup.vue
@@ -3,7 +3,7 @@
-
- @author Marco Ambrosini <marcoambrosini@icloud.com>
-
- - @license GNU AGPL version 3 or any later version
+ - @license AGPL-3.0-or-later
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
@@ -22,9 +22,12 @@
<template>
<div class="wrapper">
<div class="messages__avatar">
- <AuthorAvatar :author-type="actorType"
- :author-id="actorId"
- :display-name="actorDisplayName" />
+ <AvatarWrapper :id="actorId"
+ :name="actorDisplayName"
+ :source="actorType"
+ :disable-menu="disableMenu"
+ disable-tooltip
+ medium />
</div>
<ul class="messages">
<li class="messages__author" aria-level="4">
@@ -44,7 +47,7 @@
</template>
<script>
-import AuthorAvatar from './AuthorAvatar.vue'
+import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'
import Message from './Message/Message.vue'
import { ATTENDEE } from '../../../constants.js'
@@ -54,7 +57,7 @@ export default {
name: 'MessagesGroup',
components: {
- AuthorAvatar,
+ AvatarWrapper,
Message,
},
inheritAttrs: false,
@@ -128,6 +131,12 @@ export default {
return displayName
},
+
+ disableMenu() {
+ // disable the menu if accessing the conversation as guest
+ // or the message sender is a bridged user
+ return this.$store.getters.getActorType() === 'guests' || this.actorType === ATTENDEE.ACTOR_TYPE.BRIDGED
+ },
},
methods: {
@@ -151,6 +160,7 @@ export default {
display: flex;
margin: auto;
padding: 0;
+
&:focus {
background-color: rgba(47, 47, 47, 0.068);
}
@@ -163,6 +173,7 @@ export default {
flex-direction: column;
width: 100%;
min-width: 0;
+
&__avatar {
position: sticky;
top: 0;