feat(ui): new user menu in sidebar

This commit is contained in:
ArneBo 2024-12-15 14:56:01 +01:00 committed by upsiflu
parent 32cf6c2e3d
commit 7f293d4143
2 changed files with 120 additions and 86 deletions

View File

@ -5,7 +5,6 @@ import { useI18n } from 'vue-i18n'
import { useStore } from '~/store' import { useStore } from '~/store'
import Input from '~/components/ui/Input.vue' import Input from '~/components/ui/Input.vue'
import Pill from '~/components/ui/Pill.vue'
import Link from '~/components/ui/Link.vue' import Link from '~/components/ui/Link.vue'
import ActorAvatar from '~/components/common/ActorAvatar.vue' import ActorAvatar from '~/components/common/ActorAvatar.vue'
import UserMenu from './UserMenu.vue' import UserMenu from './UserMenu.vue'

View File

@ -1,20 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { SUPPORTED_LOCALES, setI18nLanguage } from '~/init/locale' import { SUPPORTED_LOCALES, setI18nLanguage } from '~/init/locale'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { computed } 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 useThemeList from '~/composables/useThemeList' import useThemeList from '~/composables/useThemeList'
import useTheme from '~/composables/useTheme' import useTheme from '~/composables/useTheme'
import OptionsButton from '~/components/ui/button/Options.vue' import Button from '~/components/ui/Button.vue'
import Popover from '~/components/ui/Popover.vue' import Popover from '~/components/ui/Popover.vue'
import PopoverCheckbox from '~/components/ui/popover/PopoverCheckbox.vue' import PopoverCheckbox from '~/components/ui/popover/PopoverCheckbox.vue'
import PopoverItem from '~/components/ui/popover/PopoverItem.vue' import PopoverItem from '~/components/ui/popover/PopoverItem.vue'
import PopoverRadio from '~/components/ui/popover/PopoverRadio.vue' import PopoverRadio from '~/components/ui/popover/PopoverRadio.vue'
import PopoverRadioItem from '~/components/ui/popover/PopoverRadioItem.vue' import PopoverRadioItem from '~/components/ui/popover/PopoverRadioItem.vue'
import PopoverSubmenu from '~/components/ui/popover/PopoverSubmenu.vue' import PopoverSubmenu from '~/components/ui/popover/PopoverSubmenu.vue'
import Link from '~/components/ui/Link.vue'
interface Events { interface Events {
(e: 'show:shortcuts-modal'): void (e: 'show:shortcuts-modal'): void
@ -30,6 +31,8 @@ const { t, locale } = useI18n()
const themes = useThemeList() const themes = useThemeList()
const { theme } = useTheme() const { theme } = useTheme()
const openUserMenu = ref(false)
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'),
@ -50,28 +53,48 @@ const labels = computed(() => ({
</script> </script>
<template> <template>
<Popover> <Popover v-model:open="openUserMenu">
<template #default="{ toggleOpen }"> <Button
<OptionsButton @click="toggleOpen"> @click="openUserMenu = !openUserMenu"
class="icon-only">
<img <img
v-if="store.state.auth.authenticated && store.state.auth.profile?.avatar?.urls.medium_square_crop" v-if="store.state.auth.authenticated && store.state.auth.profile?.avatar?.urls.medium_square_crop"
alt="" alt=""
: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)"
> >
<ActorAvatar <i v-else class="bi bi-gear-fill" />
v-else-if="store.state.auth.authenticated" </Button>
:actor="{preferred_username: store.state.auth.username, full_username: store.state.auth.username,}"
/>
<i
v-else
class="cog icon"
/>
</OptionsButton>
</template>
<template #items> <template #items>
<PopoverItem v-if="store.state.ui.notifications.inbox + additionalNotifications > 0">
<Link :to="{name: 'notifications'}">
<i class="bi bi-inbox-fill" />
<div :class="['ui', 'accent', 'mini', 'bottom floating', 'circular', 'label']"
>
{{ store.state.ui.notifications.inbox + additionalNotifications }}
</div>
{{ labels.notifications }}
</Link>
</PopoverItem>
<PopoverItem v-if="store.state.auth.authenticated && store.state.auth.profile?.avatar?.urls.medium_square_crop">
<Link
:to="{name: 'profile.overview', params: { username: store.state.auth.username },}"
icon="bi-person-fill"
>
{{ labels.profile }}
</Link>
</PopoverItem>
<PopoverItem v-if="store.state.auth.authenticated && store.state.auth.profile?.avatar?.urls.medium_square_crop">
<Link
:to="{ path: '/settings' }"
icon="bi-gear-fill"
>
{{ labels.settings }}
</Link>
</PopoverItem>
<hr v-if="store.state.auth.authenticated"/>
<PopoverSubmenu> <PopoverSubmenu>
<i class="bi bi-music-note-list" /> <i class="bi bi-translate" />
Change language {{ labels.language }}
<template #items> <template #items>
<PopoverItem v-for="(language, key) in SUPPORTED_LOCALES" <PopoverItem v-for="(language, key) in SUPPORTED_LOCALES"
:key="key" :key="key"
@ -80,76 +103,88 @@ const labels = computed(() => ({
</PopoverItem> </PopoverItem>
</template> </template>
</PopoverSubmenu> </PopoverSubmenu>
<hr />
<PopoverItem>
<i class="bi bi-heart" />
Add to favorites
</PopoverItem>
<PopoverSubmenu> <PopoverSubmenu>
<i class="bi bi-collection" /> <i class="bi bi-palette-fill" />
Organize and share {{ labels.theme }}
<template #items> <template #items>
<PopoverCheckbox v-model="bc"> <PopoverItem v-for="th in themes"
Bandcamp :key="th.key"
<template #after> @click="theme= th.key" >
<Popover> <i :class="th.icon" />
<template #default="{ toggleOpen }"> {{ th.name }}
<Pill
@click.stop="toggleOpen"
:blue="bcPrivacy === 'pod'"
:red="bcPrivacy === 'public'"
>
{{ bcPrivacy }}
</Pill>
</template>
<template #items>
<PopoverRadio v-model="bcPrivacy" :choices="privacyChoices" />
</template>
</Popover>
</template>
</PopoverCheckbox>
<PopoverCheckbox v-model="cc">
Creative Commons
<template #after>
<Popover v-model:open="isOpen">
<template #default="{ toggleOpen }">
<Pill
@click="toggleOpen"
:blue="ccPrivacy === 'pod'"
:red="ccPrivacy === 'public'"
>
{{ ccPrivacy }}
</Pill>
</template>
<template #items>
<PopoverRadio v-model="ccPrivacy" :choices="privacyChoices" />
</template>
</Popover>
</template>
</PopoverCheckbox>
<hr />
<PopoverItem>
<i class="bi bi-plus-lg" />
New library
</PopoverItem> </PopoverItem>
<hr />
<PopoverCheckbox v-model="share">
Share by link
<template #after>
<Button @click.stop color="secondary" round icon="bi-link" />
<Button @click.stop color="secondary" round icon="bi-code" />
</template> </template>
</PopoverCheckbox> </PopoverSubmenu>
<hr />
<PopoverSubmenu>
<i class="bi bi-question-square-fill" />
{{ labels.support }}
<template #items>
<PopoverItem>
<Link
to="https://forum.funkwhale.audio"
>
<i class="bi-gear-fill" />
{{ labels.forum }}
</Link>
</PopoverItem>
<PopoverItem>
<Link
to="https://matrix.to/#/#funkwhale-support:matrix.org"
>
<i class="bi bi-chat-left-fill" />
{{ labels.chat }}
</Link>
</PopoverItem>
<PopoverItem>
<Link
to="https://dev.funkwhale.audio/funkwhale/funkwhale/issues"
>
<i class="bi-gitlab" />
{{ labels.git }}
</Link>
</PopoverItem>
</template> </template>
</PopoverSubmenu> </PopoverSubmenu>
<PopoverItem> <PopoverItem>
<i class="bi bi-cloud-download" /> <Link
Download to="https://docs.funkwhale.audio"
class="item"
target="_blank"
>
<i class="bi bi-book" />
{{ labels.docs }}
</Link>
</PopoverItem> </PopoverItem>
<hr /> <PopoverItem
<PopoverItem> @click.prevent="emit('show:shortcuts-modal')"
<i class="bi bi-exclamation" /> >
Report <i class="bi bi-keyboard" />
{{ labels.shortcuts }}
</PopoverItem>
<hr v-if="store.state.auth.authenticated"/>
<PopoverItem v-if="store.state.auth.authenticated && route.path != '/logout'"
>
<Link :to="{ name: 'logout' }">
<i class="bi bi-box-arrow-right" />
{{ labels.logout }}
</Link>
</PopoverItem>
<PopoverItem v-if="!store.state.auth.authenticated">
<Link
:to="{ name: 'login' }"
>
<i class="bi-box-arrow-in-right" />
{{ labels.login }}
</Link>
</PopoverItem>
<PopoverItem v-if="!store.state.auth.authenticated && store.state.instance.settings.users.registration_enabled.value">
<Link
:to="{ name: 'signup' }"
>
<i class="bi bi-person-square" />
{{ labels.signup }}
</Link>
</PopoverItem> </PopoverItem>
</template> </template>
</Popover> </Popover>