nextcloud/core/src/components/ContactsMenu/ContactMenuEntry.vue
Ferdinand Thiessen 91f3b6b4ee
chore: adjust code to new codestyle
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-02 13:19:42 +02:00

196 lines
4.4 KiB
Vue

<!--
- SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<li class="contact">
<NcAvatar
class="contact__avatar"
:user="contact.isUser ? contact.uid : undefined"
:is-no-user="!contact.isUser"
:disable-menu="true"
:display-name="contact.avatarLabel"
:preloaded-user-status="preloadedUserStatus" />
<a
class="contact__body"
:href="contact.profileUrl || contact.topAction?.hyperlink">
<div class="contact__body__full-name">{{ contact.fullName }}</div>
<div v-if="contact.lastMessage" class="contact__body__last-message">{{ contact.lastMessage }}</div>
<div v-if="contact.statusMessage" class="contact__body__status-message">{{ contact.statusMessage }}</div>
<div v-else class="contact__body__email-address">{{ contact.emailAddresses[0] }}</div>
</a>
<NcActions
v-if="actions.length"
:inline="contact.topAction ? 1 : 0">
<template v-for="(action, idx) in actions">
<NcActionLink
v-if="action.hyperlink !== '#'"
:key="`${idx}-link`"
:href="action.hyperlink"
class="other-actions">
<template #icon>
<img aria-hidden="true" class="contact__action__icon" :src="action.icon">
</template>
{{ action.title }}
</NcActionLink>
<NcActionText v-else :key="`${idx}-text`" class="other-actions">
<template #icon>
<img aria-hidden="true" class="contact__action__icon" :src="action.icon">
</template>
{{ action.title }}
</NcActionText>
</template>
<NcActionButton
v-for="action in jsActions"
:key="action.id"
:close-after-click="true"
class="other-actions"
@click="action.callback(contact)">
<template #icon>
<NcIconSvgWrapper :svg="action.iconSvg(contact)" />
</template>
{{ action.displayName(contact) }}
</NcActionButton>
</NcActions>
</li>
</template>
<script>
import { getEnabledContactsMenuActions } from '@nextcloud/vue/functions/contactsMenu'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcActionLink from '@nextcloud/vue/components/NcActionLink'
import NcActions from '@nextcloud/vue/components/NcActions'
import NcActionText from '@nextcloud/vue/components/NcActionText'
import NcAvatar from '@nextcloud/vue/components/NcAvatar'
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
export default {
name: 'ContactMenuEntry',
components: {
NcActionLink,
NcActionText,
NcActionButton,
NcActions,
NcAvatar,
NcIconSvgWrapper,
},
props: {
contact: {
required: true,
type: Object,
},
},
computed: {
actions() {
if (this.contact.topAction) {
return [this.contact.topAction, ...this.contact.actions]
}
return this.contact.actions
},
jsActions() {
return getEnabledContactsMenuActions(this.contact)
},
preloadedUserStatus() {
if (this.contact.status) {
return {
status: this.contact.status,
message: this.contact.statusMessage,
icon: this.contact.statusIcon,
}
}
return undefined
},
},
}
</script>
<style scoped lang="scss">
.contact {
display: flex;
position: relative;
align-items: center;
padding: 3px;
padding-inline-start: 10px;
&__action {
&__icon {
width: 20px;
height: 20px;
padding: calc((var(--default-clickable-area) - 20px) / 2);
filter: var(--background-invert-if-dark);
}
}
&__avatar {
display: inherit;
}
&__body {
flex-grow: 1;
padding-inline-start: 10px;
margin-inline-start: 10px;
min-width: 0;
div {
position: relative;
width: 100%;
overflow-x: hidden;
text-overflow: ellipsis;
margin: -1px 0;
}
div:first-of-type {
margin-top: 0;
}
div:last-of-type {
margin-bottom: 0;
}
&__last-message, &__status-message, &__email-address {
color: var(--color-text-maxcontrast);
}
&:focus-visible {
box-shadow: 0 0 0 4px var(--color-main-background) !important;
outline: 2px solid var(--color-main-text) !important;
}
}
.other-actions {
width: 16px;
height: 16px;
cursor: pointer;
img {
filter: var(--background-invert-if-dark);
}
}
button.other-actions {
width: 44px;
&:focus {
border-color: transparent;
box-shadow: 0 0 0 2px var(--color-main-text);
}
&:focus-visible {
border-radius: var(--border-radius-pill);
}
}
/* actions menu */
.menu {
top: 47px;
margin-inline-end: 13px;
}
.popovermenu::after {
inset-inline-end: 2px;
}
}
</style>