diff options
author | Christopher Ng <chrng8@gmail.com> | 2023-10-11 17:09:30 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2023-10-16 09:54:41 -0700 |
commit | f2f1e9c8d652af4b6d2e0f33d43956134b77ab08 (patch) | |
tree | b91fd22e890cc0ef48d8f51827bbefffd0752331 /core/src/views/UserMenu.vue | |
parent | 6c5a10fea3194508e79ab73eda2b8c4d70897f97 (diff) | |
download | nextcloud-server-f2f1e9c8d652af4b6d2e0f33d43956134b77ab08.tar.gz nextcloud-server-f2f1e9c8d652af4b6d2e0f33d43956134b77ab08.zip |
enh(a11y): Add avatar description
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'core/src/views/UserMenu.vue')
-rw-r--r-- | core/src/views/UserMenu.vue | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/core/src/views/UserMenu.vue b/core/src/views/UserMenu.vue index 9f0961f835f..464dfc4b399 100644 --- a/core/src/views/UserMenu.vue +++ b/core/src/views/UserMenu.vue @@ -24,12 +24,15 @@ <NcHeaderMenu id="user-menu" class="user-menu" is-nav - :aria-label="t('core', 'Settings menu')"> + :aria-label="t('core', 'Settings menu')" + :description="avatarDescription"> <template #trigger> - <NcAvatar class="user-menu__avatar" + <NcAvatar v-if="!isLoadingUserStatus" + class="user-menu__avatar" :disable-menu="true" :disable-tooltip="true" - :user="userId" /> + :user="userId" + :preloaded-user-status="userStatus" /> </template> <ul> <UserMenuEntry v-for="entry in settingsNavEntries" @@ -40,17 +43,34 @@ </template> <script> -import { emit } from '@nextcloud/event-bus' -import { getCurrentUser } from '@nextcloud/auth' +import axios from '@nextcloud/axios' +import { emit, subscribe } from '@nextcloud/event-bus' import { loadState } from '@nextcloud/initial-state' +import { generateOcsUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' +import { getCapabilities } from '@nextcloud/capabilities' import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' import NcHeaderMenu from '@nextcloud/vue/dist/Components/NcHeaderMenu.js' +import { getAllStatusOptions } from '../../../apps/user_status/src/services/statusOptionsService.js' import UserMenuEntry from '../components/UserMenu/UserMenuEntry.vue' +import logger from '../logger.js' + const settingsNavEntries = loadState('core', 'settingsNavEntries', []) +const translateStatus = (status) => { + const statusMap = Object.fromEntries( + getAllStatusOptions() + .map(({ type, label }) => [type, label]), + ) + if (statusMap[status]) { + return statusMap[status] + } + return status +} + export default { name: 'UserMenu', @@ -63,13 +83,67 @@ export default { data() { return { settingsNavEntries, + displayName: getCurrentUser()?.displayName, userId: getCurrentUser()?.uid, + isLoadingUserStatus: true, + userStatus: { + status: null, + icon: null, + message: null, + }, + } + }, + + computed: { + translatedUserStatus() { + return { + ...this.userStatus, + status: translateStatus(this.userStatus.status), + } + }, + + avatarDescription() { + const description = [ + t('core', 'Avatar of {displayName}', { displayName: this.displayName }), + ...Object.values(this.translatedUserStatus).filter(Boolean), + ].join(' — ') + return description + }, + }, + + async created() { + if (!getCapabilities()?.user_status?.enabled) { + this.isLoadingUserStatus = false + return + } + + const url = generateOcsUrl('/apps/user_status/api/v1/user_status') + try { + const response = await axios.get(url) + const { status, icon, message } = response.data.ocs.data + this.userStatus = { status, icon, message } + } catch (e) { + logger.error('Failed to load user status') } + this.isLoadingUserStatus = false }, mounted() { + subscribe('user_status:status.updated', this.handleUserStatusUpdated) emit('core:user-menu:mounted') }, + + methods: { + handleUserStatusUpdated(state) { + if (this.userId === state.userId) { + this.userStatus = { + status: state.status, + icon: state.icon, + message: state.message, + } + } + }, + }, } </script> |