Skip to content

Commit

Permalink
Merge pull request #11771 from nextcloud/fix/noid/mark-federated-users
Browse files Browse the repository at this point in the history
feat(Participants): mark federated users in MessagesList and ParticipantList
  • Loading branch information
Antreesy authored Mar 12, 2024
2 parents 03ae3d3 + 135cb20 commit 9c5a927
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 58 deletions.
31 changes: 27 additions & 4 deletions src/components/AvatarWrapper/AvatarWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<div v-else-if="isBot" class="avatar bot">
{{ '>_' }}
</div>
<img v-else-if="isRemoteUser && token"
<img v-else-if="isFederatedUser && token"
:key="avatarUrl"
:src="avatarUrl"
:width="size"
Expand All @@ -47,10 +47,20 @@
:show-user-status-compact="showUserStatusCompact"
:preloaded-user-status="preloadedUserStatus"
:size="size" />
<!-- Override user status for federated users -->
<span v-if="showUserStatus && isFederatedUser"
class="avatar-wrapper__user-status"
role="img"
aria-hidden="false"
:aria-label="t('spreed', 'Federated user')">
<WebIcon :size="14" />
</span>
</div>
</template>

<script>
import WebIcon from 'vue-material-design-icons/Web.vue'

import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'

import { ATTENDEE, AVATAR } from '../../constants.js'
Expand All @@ -63,6 +73,7 @@ export default {

components: {
NcAvatar,
WebIcon,
},

props: {
Expand Down Expand Up @@ -130,10 +141,10 @@ export default {
computed: {
// Determines which icon is displayed
iconClass() {
if (!this.source || this.isUser || (this.isRemoteUser && this.token) || this.isBot || this.isGuest || this.isDeletedUser) {
if (!this.source || this.isUser || (this.isFederatedUser && this.token) || this.isBot || this.isGuest || this.isDeletedUser) {
return ''
}
if (this.isRemoteUser) {
if (this.isFederatedUser) {
return 'icon-user'
}
if (this.source === ATTENDEE.ACTOR_TYPE.EMAILS) {
Expand Down Expand Up @@ -164,7 +175,7 @@ export default {
isUser() {
return this.source === ATTENDEE.ACTOR_TYPE.USERS || this.source === ATTENDEE.ACTOR_TYPE.BRIDGED
},
isRemoteUser() {
isFederatedUser() {
return this.source === ATTENDEE.ACTOR_TYPE.FEDERATED_USERS
},
isBot() {
Expand Down Expand Up @@ -195,6 +206,7 @@ export default {

<style lang="scss" scoped>
.avatar-wrapper {
position: relative;
height: var(--avatar-size);
width: var(--avatar-size);
border-radius: var(--avatar-size);
Expand Down Expand Up @@ -256,6 +268,17 @@ export default {
&--highlighted {
outline: 2px solid var(--color-primary-element);
}

&__user-status {
position: absolute;
right: -4px;
bottom: -4px;
height: 18px;
width: 18px;
border: 2px solid var(--color-main-background);
background-color: var(--color-main-background);
border-radius: 50%;
}
}

</style>
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,22 @@
{{ reactionsOverview[reaction].length }}
</NcButton>
</div>
<div class="scrollable">
<NcListItemIcon v-for="item in reactionsOverview[reactionFilter]"
<ul class="reactions-list__scrollable">
<li v-for="item in reactionsOverview[reactionFilter]"
:key="item.actorId + item.actorType"
:name="item.actorDisplayName">
<span class="reactions-emojis">
class="reactions-item">
<AvatarWrapper :id="item.actorId"
:token="token"
:name="item.actorDisplayName"
:source="item.actorType"
:size="AVATAR.SIZE.SMALL"
disable-menu />
<span class="reactions-item__name">{{ item.actorDisplayName }}</span>
<span class="reactions-item__emojis">
{{ item.reaction?.join('') ?? reactionFilter }}
</span>
</NcListItemIcon>
</div>
</li>
</ul>
</template>
<NcLoadingIcon v-else :size="64" />
</div>
Expand All @@ -60,21 +67,22 @@
import HeartOutlineIcon from 'vue-material-design-icons/HeartOutline.vue'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcListItemIcon from '@nextcloud/vue/dist/Components/NcListItemIcon.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'

import { ATTENDEE } from '../../../../../constants.js'
import AvatarWrapper from '../../../../AvatarWrapper/AvatarWrapper.vue'

import { ATTENDEE, AVATAR } from '../../../../../constants.js'
import { useGuestNameStore } from '../../../../../stores/guestName.js'

export default {

name: 'ReactionsList',

components: {
AvatarWrapper,
NcModal,
NcLoadingIcon,
NcListItemIcon,
NcButton,
HeartOutlineIcon,
},
Expand All @@ -100,6 +108,7 @@ export default {

setup() {
return {
AVATAR,
guestNameStore: useGuestNameStore(),
}
},
Expand Down Expand Up @@ -198,19 +207,34 @@ export default {
gap: 4px;
}

.scrollable {
.reactions-list__scrollable {
overflow-y: auto;
overflow-x: hidden;
height: calc(450px - 123px); // 123px is the height of the header 105px and the footer 18px
}

.reactions-emojis {
max-width: 180px;
direction: rtl;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
position: relative;
.reactions-item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 6px 0;

&__name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

&__emojis {
margin-left: auto;
max-width: 180px;
direction: rtl;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
position: relative;
}
}
</style>
27 changes: 23 additions & 4 deletions src/components/MessagesList/MessagesGroup/MessagesGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@
</div>
<ul class="messages">
<li class="messages__author" aria-level="4">
{{ actorDisplayName }}
<div v-if="lastEditTimestamp">
{{ getLastEditor }}
</div>
<span class="messages__author-name">{{ actorDisplayName }}</span>
<span v-if="isFederatedUser" class="messages__author-server">{{ getRemoteServer }}</span>
<span v-if="lastEditTimestamp" class="messages__author-edit">{{ getLastEditor }}</span>
</li>
<Message v-for="(message, index) of messages"
:key="message.id"
Expand Down Expand Up @@ -131,6 +130,14 @@ export default {
return displayName
},

isFederatedUser() {
return this.actorType === ATTENDEE.ACTOR_TYPE.FEDERATED_USERS
},

getRemoteServer() {
return this.isFederatedUser ? '(' + this.actorId.split('@').pop() + ')' : ''
},

getLastEditor() {
if (!this.lastEditTimestamp) {
return ''
Expand Down Expand Up @@ -202,8 +209,20 @@ export default {
&__author {
display: flex;
gap: 4px;
max-width: 600px;
padding: 4px 0 0 8px;
color: var(--color-text-maxcontrast);

&-name {
flex-shrink: 0;
}

&-edit,
&-server {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'

import ContactSelectionBubble from '../ContactSelectionBubble.vue'
import DialpadPanel from '../DialpadPanel.vue'
import ParticipantSearchResults from '../RightSidebar/Participants/ParticipantsSearchResults/ParticipantsSearchResults.vue'
import ParticipantSearchResults from '../RightSidebar/Participants/ParticipantsSearchResults.vue'
import SelectPhoneNumber from '../SelectPhoneNumber.vue'
import TransitionWrapper from '../TransitionWrapper.vue'

Expand Down
3 changes: 2 additions & 1 deletion src/components/NewMessage/NewMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,8 @@ export default {
}

// Caching the user id data for each possible mention
possibleMention.id = possibleMention.mentionId
// mentionId should be the default match since 'federation-v1'
possibleMention.id = possibleMention.mentionId ?? possibleMention.id
this.userData[possibleMention.id] = possibleMention
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'

import BreakoutRoomItem from './BreakoutRoomItem.vue'
import BreakoutRoomsActions from './BreakoutRoomsActions.vue'
import Participant from '../Participants/ParticipantsList/Participant/Participant.vue'
import Participant from '../Participants/Participant.vue'

import { CONVERSATION, PARTICIPANT } from '../../../constants.js'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionText from '@nextcloud/vue/dist/Components/NcActionText.js'

import Participant from './Participant.vue'
import AvatarWrapper from '../../../../AvatarWrapper/AvatarWrapper.vue'
import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'

import { ATTENDEE, PARTICIPANT } from '../../../../../constants.js'
import storeConfig from '../../../../../store/storeConfig.js'
import { findNcActionButton } from '../../../../../test-helpers.js'
import { ATTENDEE, PARTICIPANT } from '../../../constants.js'
import storeConfig from '../../../store/storeConfig.js'
import { findNcActionButton } from '../../../test-helpers.js'

describe('Participant.vue', () => {
let conversation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,23 +363,23 @@ import NcActionText from '@nextcloud/vue/dist/Components/NcActionText.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'

import ParticipantPermissionsEditor from './ParticipantPermissionsEditor/ParticipantPermissionsEditor.vue'
import AvatarWrapper from '../../../../AvatarWrapper/AvatarWrapper.vue'
import DialpadPanel from '../../../../DialpadPanel.vue'
import ParticipantPermissionsEditor from './ParticipantPermissionsEditor.vue'
import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'
import DialpadPanel from '../../DialpadPanel.vue'

import { useIsInCall } from '../../../../../composables/useIsInCall.js'
import { CONVERSATION, PARTICIPANT, ATTENDEE, WEBINAR } from '../../../../../constants.js'
import { useIsInCall } from '../../../composables/useIsInCall.js'
import { CONVERSATION, PARTICIPANT, ATTENDEE, WEBINAR } from '../../../constants.js'
import {
callSIPDialOut,
callSIPHangupPhone,
callSIPHoldPhone,
callSIPMutePhone,
callSIPUnmutePhone,
callSIPSendDTMF,
} from '../../../../../services/callsService.js'
import { formattedTime } from '../../../../../utils/formattedTime.ts'
import { readableNumber } from '../../../../../utils/readableNumber.js'
import { getStatusMessage } from '../../../../../utils/userStatus.js'
} from '../../../services/callsService.js'
import { formattedTime } from '../../../utils/formattedTime.ts'
import { readableNumber } from '../../../utils/readableNumber.js'
import { getStatusMessage } from '../../../utils/userStatus.js'

export default {
name: 'Participant',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { cloneDeep } from 'lodash'
import Vuex from 'vuex'

import ParticipantPermissionsEditor from './ParticipantPermissionsEditor.vue'
import PermissionsEditor from '../../../../../PermissionsEditor/PermissionsEditor.vue'
import PermissionsEditor from '../../PermissionsEditor/PermissionsEditor.vue'

import { PARTICIPANT, ATTENDEE } from '../../../../../../constants.js'
import storeConfig from '../../../../../../store/storeConfig.js'
import { PARTICIPANT, ATTENDEE } from '../../../constants.js'
import storeConfig from '../../../store/storeConfig.js'

describe('ParticipantPermissionsEditor.vue', () => {
let conversation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
<script>
import { showError, showSuccess } from '@nextcloud/dialogs'

import PermissionEditor from '../../../../../PermissionsEditor/PermissionsEditor.vue'
import PermissionEditor from '../../PermissionsEditor/PermissionsEditor.vue'

import { PARTICIPANT } from '../../../../../../constants.js'
import { PARTICIPANT } from '../../../constants.js'

export default {
name: 'ParticipantPermissionsEditor',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@

<script>

import Participant from './Participant/Participant.vue'
import LoadingPlaceholder from '../../../LoadingPlaceholder.vue'
import Participant from './Participant.vue'
import LoadingPlaceholder from '../../LoadingPlaceholder.vue'

export default {
name: 'ParticipantsList',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
<script>
import { RecycleScroller } from 'vue-virtual-scroller'

import Participant from './Participant/Participant.vue'
import LoadingPlaceholder from '../../../LoadingPlaceholder.vue'
import Participant from './Participant.vue'
import LoadingPlaceholder from '../../LoadingPlaceholder.vue'

import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ import NcAppNavigationCaption from '@nextcloud/vue/dist/Components/NcAppNavigati
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'

import Hint from '../../../Hint.vue'
import ParticipantsList from '../ParticipantsList/ParticipantsList.vue'
import ParticipantsList from './ParticipantsList.vue'
import Hint from '../../Hint.vue'

import { ATTENDEE } from '../../../../constants.js'
import { useIntegrationsStore } from '../../../../stores/integrations.js'
import { ATTENDEE } from '../../../constants.js'
import { useIntegrationsStore } from '../../../stores/integrations.js'

const isCirclesEnabled = loadState('spreed', 'circles_enabled')

Expand Down
6 changes: 3 additions & 3 deletions src/components/RightSidebar/Participants/ParticipantsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ import { subscribe, unsubscribe } from '@nextcloud/event-bus'

import NcAppNavigationCaption from '@nextcloud/vue/dist/Components/NcAppNavigationCaption.js'

import ParticipantsList from './ParticipantsList/ParticipantsList.vue'
import ParticipantsListVirtual from './ParticipantsList/ParticipantsListVirtual.vue'
import ParticipantsSearchResults from './ParticipantsSearchResults/ParticipantsSearchResults.vue'
import ParticipantsList from './ParticipantsList.vue'
import ParticipantsListVirtual from './ParticipantsListVirtual.vue'
import ParticipantsSearchResults from './ParticipantsSearchResults.vue'
import DialpadPanel from '../../DialpadPanel.vue'
import Hint from '../../Hint.vue'
import SearchBox from '../../LeftSidebar/SearchBox/SearchBox.vue'
Expand Down

0 comments on commit 9c5a927

Please sign in to comment.