diff options
Diffstat (limited to 'core/src/components/AccountMenu')
-rw-r--r-- | core/src/components/AccountMenu/AccountMenuEntry.vue | 117 | ||||
-rw-r--r-- | core/src/components/AccountMenu/AccountMenuProfileEntry.vue | 100 |
2 files changed, 217 insertions, 0 deletions
diff --git a/core/src/components/AccountMenu/AccountMenuEntry.vue b/core/src/components/AccountMenu/AccountMenuEntry.vue new file mode 100644 index 00000000000..d983226d273 --- /dev/null +++ b/core/src/components/AccountMenu/AccountMenuEntry.vue @@ -0,0 +1,117 @@ +<!-- + - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + - SPDX-License-Identifier: AGPL-3.0-or-later +--> + +<template> + <NcListItem :id="href ? undefined : id" + :anchor-id="id" + :active="active" + class="account-menu-entry" + compact + :href="href" + :name="name" + target="_self" + @click="onClick"> + <template #icon> + <NcLoadingIcon v-if="loading" :size="20" class="account-menu-entry__loading" /> + <slot v-else-if="$scopedSlots.icon" name="icon" /> + <img v-else + class="account-menu-entry__icon" + :class="{ 'account-menu-entry__icon--active': active }" + :src="iconSource" + alt=""> + </template> + </NcListItem> +</template> + +<script lang="ts"> +import { loadState } from '@nextcloud/initial-state' +import { defineComponent } from 'vue' + +import NcListItem from '@nextcloud/vue/components/NcListItem' +import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon' + +const versionHash = loadState('core', 'versionHash', '') + +export default defineComponent({ + name: 'AccountMenuEntry', + + components: { + NcListItem, + NcLoadingIcon, + }, + + props: { + id: { + type: String, + required: true, + }, + name: { + type: String, + required: true, + }, + href: { + type: String, + required: true, + }, + active: { + type: Boolean, + default: false, + }, + icon: { + type: String, + default: '', + }, + }, + + data() { + return { + loading: false, + } + }, + + computed: { + iconSource() { + return `${this.icon}?v=${versionHash}` + }, + }, + + methods: { + onClick(e: MouseEvent) { + this.$emit('click', e) + + // Allow to not show the loading indicator + // in case the click event was already handled + if (!e.defaultPrevented) { + this.loading = true + } + }, + }, +}) +</script> + +<style lang="scss" scoped> +.account-menu-entry { + &__icon { + height: 16px; + width: 16px; + margin: calc((var(--default-clickable-area) - 16px) / 2); // 16px icon size + filter: var(--background-invert-if-dark); + + &--active { + filter: var(--primary-invert-if-dark); + } + } + + &__loading { + height: 20px; + width: 20px; + margin: calc((var(--default-clickable-area) - 20px) / 2); // 20px icon size + } + + :deep(.list-item-content__main) { + width: fit-content; + } +} +</style> diff --git a/core/src/components/AccountMenu/AccountMenuProfileEntry.vue b/core/src/components/AccountMenu/AccountMenuProfileEntry.vue new file mode 100644 index 00000000000..8b895b8ca31 --- /dev/null +++ b/core/src/components/AccountMenu/AccountMenuProfileEntry.vue @@ -0,0 +1,100 @@ +<!-- + - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + - SPDX-License-Identifier: AGPL-3.0-or-later +--> + +<template> + <NcListItem :id="profileEnabled ? undefined : id" + :anchor-id="id" + :active="active" + compact + :href="profileEnabled ? href : undefined" + :name="displayName" + target="_self"> + <template v-if="profileEnabled" #subname> + {{ name }} + </template> + <template v-if="loading" #indicator> + <NcLoadingIcon /> + </template> + </NcListItem> +</template> + +<script lang="ts"> +import { loadState } from '@nextcloud/initial-state' +import { getCurrentUser } from '@nextcloud/auth' +import { subscribe, unsubscribe } from '@nextcloud/event-bus' +import { defineComponent } from 'vue' + +import NcListItem from '@nextcloud/vue/components/NcListItem' +import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon' + +const { profileEnabled } = loadState('user_status', 'profileEnabled', { profileEnabled: false }) + +export default defineComponent({ + name: 'AccountMenuProfileEntry', + + components: { + NcListItem, + NcLoadingIcon, + }, + + props: { + id: { + type: String, + required: true, + }, + name: { + type: String, + required: true, + }, + href: { + type: String, + required: true, + }, + active: { + type: Boolean, + required: true, + }, + }, + + setup() { + return { + profileEnabled, + displayName: getCurrentUser()!.displayName, + } + }, + + data() { + return { + loading: false, + } + }, + + mounted() { + subscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate) + subscribe('settings:display-name:updated', this.handleDisplayNameUpdate) + }, + + beforeDestroy() { + unsubscribe('settings:profile-enabled:updated', this.handleProfileEnabledUpdate) + unsubscribe('settings:display-name:updated', this.handleDisplayNameUpdate) + }, + + methods: { + handleClick() { + if (this.profileEnabled) { + this.loading = true + } + }, + + handleProfileEnabledUpdate(profileEnabled: boolean) { + this.profileEnabled = profileEnabled + }, + + handleDisplayNameUpdate(displayName: string) { + this.displayName = displayName + }, + }, +}) +</script> |