feat(front): username initials as fallback for profile image and usermenu icon

This commit is contained in:
ArneBo 2025-01-17 18:53:43 +01:00
parent 37710a9ccb
commit 440527c078
4 changed files with 27 additions and 13 deletions

View File

@ -31,7 +31,6 @@ const defaultAvatarStyle = computed(() => ({ backgroundColor: `#${actorColor.val
<style lang="scss"> <style lang="scss">
.ui.circular.avatar { .ui.circular.avatar {
float: left; float: left;
margin-right: 8px;
text-align: center; text-align: center;
border-radius: 50%; border-radius: 50%;
@ -39,4 +38,4 @@ const defaultAvatarStyle = computed(() => ({ backgroundColor: `#${actorColor.val
align-content: center; align-content: center;
} }
} }
</style> </style>

View File

@ -5,7 +5,7 @@
width: 3em; width: 3em;
} }
.ui.circular.avatar { .ui.tiny.avatar {
width: 28px; width: 28px;
height: 28px; height: 28px;
font-size: 1em !important; font-size: 1em !important;

View File

@ -3,6 +3,7 @@ import { useI18n } from 'vue-i18n'
import { computed, ref} from 'vue' import { computed, ref} from 'vue'
import { useStore } from '~/store' import { useStore } from '~/store'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { hashCode, intToRGB } from '~/utils/color'
import useThemeList from '~/composables/useThemeList' import useThemeList from '~/composables/useThemeList'
import useTheme from '~/composables/useTheme' import useTheme from '~/composables/useTheme'
@ -23,6 +24,9 @@ const { theme } = useTheme()
const isOpen = ref(false) const isOpen = ref(false)
const actorColor = computed(() => intToRGB(hashCode(store.state.auth.profile.full_username)))
const defaultAvatarStyle = computed(() => ({ backgroundColor: `#${actorColor.value}` }))
const labels = computed(() => ({ const labels = computed(() => ({
profile: t('components.common.UserMenu.link.profile'), profile: t('components.common.UserMenu.link.profile'),
settings: t('components.common.UserMenu.link.settings'), settings: t('components.common.UserMenu.link.settings'),
@ -57,6 +61,13 @@ const labels = computed(() => ({
:src="store.getters['instance/absoluteUrl'](store.state.auth.profile?.avatar.urls.medium_square_crop)" :src="store.getters['instance/absoluteUrl'](store.state.auth.profile?.avatar.urls.medium_square_crop)"
class="avatar" class="avatar"
> >
<span
v-else-if="store.state.auth.authenticated"
:style="defaultAvatarStyle"
class="ui avatar circular label"
>
{{ store.state.auth.profile?.full_username?.[0] || "" }}
</span>
<i v-else class="bi bi-gear-fill" /> <i v-else class="bi bi-gear-fill" />
</Button> </Button>
<template #items> <template #items>

View File

@ -5,6 +5,8 @@ import { onBeforeRouteUpdate } from 'vue-router'
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useStore } from '~/store' import { useStore } from '~/store'
import { hashCode, intToRGB } from '~/utils/color'
import UserFollowButton from '~/components/federation/UserFollowButton.vue' import UserFollowButton from '~/components/federation/UserFollowButton.vue'
import axios from 'axios' import axios from 'axios'
@ -39,6 +41,9 @@ const store = useStore()
// We are working either with an Actor or null // We are working either with an Actor or null
const object = ref<Actor | null>(null) const object = ref<Actor | null>(null)
const actorColor = computed(() => intToRGB(hashCode(object.full_username)))
const defaultAvatarStyle = computed(() => ({ backgroundColor: `#${actorColor.value}` }))
const displayName = computed(() => object.value?.name ?? object.value?.preferred_username) const displayName = computed(() => object.value?.name ?? object.value?.preferred_username)
const fullUsername = computed(() => props.domain const fullUsername = computed(() => props.domain
? `${props.username}@${props.domain}` ? `${props.username}@${props.domain}`
@ -83,19 +88,19 @@ watch(props, fetchData, { immediate: true })
> >
<Layout flex> <Layout flex>
<!-- Profile Picture --> <!-- Profile Picture -->
<i
v-if="!object?.icon"
class="avatar icon"
>
<!-- TODO: Get User Initials -->
TU
</i>
<img <img
v-else v-if="object?.icon"
v-lazy="store.getters['instance/absoluteUrl'](object.icon.urls.medium_square_crop)" v-lazy="store.getters['instance/absoluteUrl'](object.icon.urls.medium_square_crop)"
alt="" alt=""
class="avatar" class="avatar"
/> />
<span
v-else
:style="defaultAvatarStyle"
class="ui avatar circular label"
>
{{ store.state.auth.profile?.full_username?.[0] || "" }}
</span>
<!-- <div class="ui five wide column"> <!-- <div class="ui five wide column">
<button <button
ref="dropdown" ref="dropdown"
@ -264,11 +269,10 @@ watch(props, fetchData, { immediate: true })
border-radius: 50%; border-radius: 50%;
} }
i.avatar { span.avatar {
font-size: 100px; font-size: 100px;
font-style: normal; font-style: normal;
font-weight: 800; font-weight: 800;
padding: 26px 0px 0px 26px;
background-color: var(--fw-gray-500); background-color: var(--fw-gray-500);
border-radius: 50%; border-radius: 50%;
width: 176px; width: 176px;