forked from Mirrors/elk
feat: account switcher sidebar (#460)
* feat: account switcher sidebar * fix: defer loading sidebar until masto initialised * fix: only show user switcher for 2 or more accounts * chore: use `ofetch` (newer version of `ohymfetch`) * chore: early alpha warning * fix: handle missing user in github preview * refactor: avoid circular auto-import Co-authored-by: Daniel Roe <daniel@roe.dev>
This commit is contained in:
parent
15b59ae9b9
commit
cd85871d01
11 changed files with 78 additions and 25 deletions
|
@ -24,6 +24,12 @@ const featureFlags = useFeatureFlags()
|
|||
>
|
||||
{{ $t('feature_flag.github_cards') }}
|
||||
</CommonDropdownItem>
|
||||
<CommonDropdownItem
|
||||
:checked="featureFlags.experimentalUserSwitcherSidebar"
|
||||
@click="toggleFeatureFlag('experimentalUserSwitcherSidebar')"
|
||||
>
|
||||
{{ $t('feature_flag.user_switcher_sidebar') }}
|
||||
</CommonDropdownItem>
|
||||
</template>
|
||||
</CommonDropdown>
|
||||
</template>
|
||||
|
|
30
components/user/UserPicker.vue
Normal file
30
components/user/UserPicker.vue
Normal file
|
@ -0,0 +1,30 @@
|
|||
<script setup lang="ts">
|
||||
import type { UserLogin } from '~/types'
|
||||
|
||||
const all = useUsers()
|
||||
|
||||
const router = useRouter()
|
||||
const switchUser = (user: UserLogin) => {
|
||||
if (user.account.id === currentUser.value?.account.id)
|
||||
router.push(getAccountRoute(user.account))
|
||||
else
|
||||
loginTo(user)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div flex="~ col" pb8 px4 gap-6 w-20 h-full justify-end>
|
||||
<template v-for="user of all" :key="user.id">
|
||||
<button
|
||||
flex rounded
|
||||
cursor-pointer
|
||||
aria-label="Switch user"
|
||||
:class="user.account.id === currentUser?.account.id ? '' : 'grayscale'"
|
||||
hover:filter-none
|
||||
@click="switchUser(user)"
|
||||
>
|
||||
<AccountAvatar w-12 h-12 :account="user.account" :hover-card="false" />
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
|
@ -4,6 +4,7 @@ export interface FeatureFlags {
|
|||
experimentalVirtualScroll: boolean
|
||||
experimentalAvatarOnAvatar: boolean
|
||||
experimentalGitHubCards: boolean
|
||||
experimentalUserSwitcherSidebar: boolean
|
||||
}
|
||||
export type FeatureFlagsMap = Record<string, FeatureFlags>
|
||||
|
||||
|
@ -12,6 +13,7 @@ export function getDefaultFeatureFlags(): FeatureFlags {
|
|||
experimentalVirtualScroll: false,
|
||||
experimentalAvatarOnAvatar: true,
|
||||
experimentalGitHubCards: true,
|
||||
experimentalUserSwitcherSidebar: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,3 +33,6 @@ export function toggleFeatureFlag(key: keyof FeatureFlags) {
|
|||
else
|
||||
featureFlags[key] = true
|
||||
}
|
||||
|
||||
const userSwitcherSidebar = eagerComputed(() => useFeatureFlags().experimentalUserSwitcherSidebar)
|
||||
export const showUserSwitcherSidebar = computed(() => useUsers().value.length > 1 && userSwitcherSidebar.value)
|
||||
|
|
|
@ -1,14 +1,38 @@
|
|||
<template>
|
||||
<div h-full :class="{ zen: isZenMode }">
|
||||
<main flex w-full mxa lg:max-w-80rem>
|
||||
<div v-if="isMastoInitialised" v-show="showUserSwitcherSidebar" fixed h-full hidden md:block bg-code border-r-1 border-base>
|
||||
<UserPicker />
|
||||
</div>
|
||||
<main flex w-full mxa lg:max-w-80rem :class="isMastoInitialised && showUserSwitcherSidebar ? 'md:pl-20' : ''">
|
||||
<aside class="hidden md:block w-1/4 zen-hide" relative>
|
||||
<div sticky top-0 h-screen flex="~ col">
|
||||
<slot name="left">
|
||||
<NavTitle mx3 mt4 mb2 self-start />
|
||||
<div flex="~ col" overflow-y-auto>
|
||||
<NavSide />
|
||||
<PublishButton v-if="isMastoInitialised && currentUser" m5 />
|
||||
<div flex-auto />
|
||||
<div flex="~ col" overflow-y-auto justify-between h-full>
|
||||
<div flex flex-col>
|
||||
<NavSide />
|
||||
<PublishButton v-if="isMastoInitialised && currentUser" m5 />
|
||||
</div>
|
||||
<div flex flex-col>
|
||||
<UserSignInEntry v-if="isMastoInitialised && !currentUser" />
|
||||
<div v-if="isMastoInitialised && currentUser" py6 px4 w-full flex="~" items-center justify-between>
|
||||
<NuxtLink
|
||||
p2 rounded-full text-start w-full
|
||||
hover:bg-active cursor-pointer transition-100
|
||||
:to="getAccountRoute(currentUser.account)"
|
||||
>
|
||||
<AccountInfo :account="currentUser.account" md:break-words />
|
||||
</NuxtLink>
|
||||
<VDropdown :distance="0" placement="bottom-end">
|
||||
<button btn-action-icon :aria-label="$t('action.switch_account')">
|
||||
<div i-ri:more-2-line />
|
||||
</button>
|
||||
<template #popper="{ hide }">
|
||||
<UserSwitcher @click="hide" />
|
||||
</template>
|
||||
</VDropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
@ -23,28 +47,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<aside class="hidden md:none lg:block w-1/4 zen-hide">
|
||||
<div sticky top-0 h-screen flex="~ col">
|
||||
<div sticky top-0 h-screen flex="~ col" py3>
|
||||
<slot name="right">
|
||||
<SearchWidget v-if="isMastoInitialised" />
|
||||
<UserSignInEntry v-if="isMastoInitialised && !currentUser" />
|
||||
<div v-if="isMastoInitialised && currentUser" py6 px4 w-full flex="~" items-center justify-between>
|
||||
<NuxtLink
|
||||
p2 rounded-full text-start w-full
|
||||
hover:bg-active cursor-pointer transition-100
|
||||
:to="getAccountRoute(currentUser.account)"
|
||||
>
|
||||
<AccountInfo :account="currentUser.account" md:break-words />
|
||||
</NuxtLink>
|
||||
<VDropdown :distance="0" placement="bottom-end">
|
||||
<button btn-action-icon :aria-label="$t('action.switch_account')">
|
||||
<div i-ri:more-2-line />
|
||||
</button>
|
||||
<template #popper="{ hide }">
|
||||
<UserSwitcher @click="hide" />
|
||||
</template>
|
||||
</VDropdown>
|
||||
</div>
|
||||
|
||||
<div flex-auto />
|
||||
<NavFooter />
|
||||
</slot>
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
"feature_flag": {
|
||||
"avatar_on_avatar": "Avatar on Avatar",
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "Virtual Scrolling"
|
||||
},
|
||||
"help": {
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
},
|
||||
"feature_flag": {
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "Virtuelles Scrollen"
|
||||
},
|
||||
"menu": {
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
"feature_flag": {
|
||||
"avatar_on_avatar": "Avatar on Avatar",
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "Virtual Scrolling"
|
||||
},
|
||||
"help": {
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
"feature_flag": {
|
||||
"avatar_on_avatar": "Avatar en Avatar",
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "Virtual Scrolling"
|
||||
},
|
||||
"help": {
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
"feature_flag": {
|
||||
"avatar_on_avatar": "Avatar sur avatar",
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "Défilement virtuel"
|
||||
},
|
||||
"help": {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
},
|
||||
"feature_flag": {
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "仮想スクロール"
|
||||
},
|
||||
"menu": {
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
"feature_flag": {
|
||||
"avatar_on_avatar": "头像堆叠",
|
||||
"github_cards": "GitHub Cards",
|
||||
"user_switcher_sidebar": "User Switcher Sidebar",
|
||||
"virtual_scroll": "虚拟滚动"
|
||||
},
|
||||
"help": {
|
||||
|
|
Loading…
Reference in a new issue