feat: render app shell with ssr to improve loading experience (#448)
This commit is contained in:
parent
b545efeacc
commit
9395b7031e
35 changed files with 169 additions and 127 deletions
|
@ -22,7 +22,7 @@ defineProps<{
|
|||
</div>
|
||||
<div flex items-center flex-shrink-0 gap-x-2>
|
||||
<slot name="actions" />
|
||||
<NavUser v-if="isMediumScreen" />
|
||||
<NavUser v-if="isHydrated && isMediumScreen" />
|
||||
</div>
|
||||
</div>
|
||||
<slot name="header" />
|
||||
|
|
|
@ -29,28 +29,30 @@ useEventListener('keydown', (e: KeyboardEvent) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<ModalDialog v-model="isSigninDialogOpen" py-4 px-8 max-w-125>
|
||||
<UserSignIn />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isPreviewHelpOpen" max-w-125>
|
||||
<HelpPreview @close="closePreviewHelp()" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isPublishDialogOpen" max-w-180 flex>
|
||||
<!-- This `w-0` style is used to avoid overflow problems in flex layouts,so don't remove it unless you know what you're doing -->
|
||||
<PublishWidget :draft-key="dialogDraftKey" expanded flex-1 w-0 />
|
||||
</ModalDialog>
|
||||
<ModalDialog
|
||||
v-model="isMediaPreviewOpen"
|
||||
pointer-events-none
|
||||
w-full max-w-full h-full max-h-full
|
||||
bg-transparent border-0 shadow-none
|
||||
>
|
||||
<ModalMediaPreview v-if="isMediaPreviewOpen" @close="closeMediaPreview()" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isEditHistoryDialogOpen" max-w-125>
|
||||
<StatusEditPreview :edit="statusEdit" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isCommandPanelOpen" max-w-fit flex>
|
||||
<CommandPanel @close="closeCommandPanel()" />
|
||||
</ModalDialog>
|
||||
<template v-if="isMastoInitialised">
|
||||
<ModalDialog v-model="isSigninDialogOpen" py-4 px-8 max-w-125>
|
||||
<UserSignIn />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isPreviewHelpOpen" max-w-125>
|
||||
<HelpPreview @close="closePreviewHelp()" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isPublishDialogOpen" max-w-180 flex>
|
||||
<!-- This `w-0` style is used to avoid overflow problems in flex layouts,so don't remove it unless you know what you're doing -->
|
||||
<PublishWidget :draft-key="dialogDraftKey" expanded flex-1 w-0 />
|
||||
</ModalDialog>
|
||||
<ModalDialog
|
||||
v-model="isMediaPreviewOpen"
|
||||
pointer-events-none
|
||||
w-full max-w-full h-full max-h-full
|
||||
bg-transparent border-0 shadow-none
|
||||
>
|
||||
<ModalMediaPreview v-if="isMediaPreviewOpen" @close="closeMediaPreview()" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isEditHistoryDialogOpen" max-w-125>
|
||||
<StatusEditPreview :edit="statusEdit" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isCommandPanelOpen" max-w-fit flex>
|
||||
<CommandPanel @close="closeCommandPanel()" />
|
||||
</ModalDialog>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -137,7 +137,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<SafeTeleport to="#teleport-end" @transitionend="trapFocusDialog">
|
||||
<Teleport to="body" @transitionend="trapFocusDialog">
|
||||
<!-- Dialog component -->
|
||||
<Transition name="dialog-visible">
|
||||
<div
|
||||
|
@ -173,7 +173,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</SafeTeleport>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
|
|
|
@ -10,7 +10,7 @@ const moreMenuVisible = ref(false)
|
|||
class="after-content-empty after:(h-[calc(100%+0.5px)] w-0.1px pointer-events-none)"
|
||||
>
|
||||
<!-- These weird styles above are used for scroll locking, don't change it unless you know exactly what you're doing. -->
|
||||
<template v-if="currentUser">
|
||||
<template v-if="isMastoInitialised && currentUser">
|
||||
<NuxtLink to="/home" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
|
||||
<div i-ri:home-5-line />
|
||||
</NuxtLink>
|
||||
|
@ -24,12 +24,12 @@ const moreMenuVisible = ref(false)
|
|||
<NuxtLink group :to="`/${currentServer}/public/local`" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
|
||||
<div i-ri:group-2-line />
|
||||
</NuxtLink>
|
||||
<template v-if="!currentUser">
|
||||
<template v-if="!isMastoInitialised || !currentUser">
|
||||
<NuxtLink :to="`/${currentServer}/public`" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
|
||||
<div i-ri:earth-line />
|
||||
</NuxtLink>
|
||||
</template>
|
||||
<template v-if="currentUser">
|
||||
<template v-if="isMastoInitialised && currentUser">
|
||||
<NuxtLink to="/conversations" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
|
||||
<div i-ri:at-line />
|
||||
</NuxtLink>
|
||||
|
|
|
@ -96,7 +96,7 @@ onBeforeUnmount(() => {
|
|||
</button>
|
||||
</NavSelectLanguage>
|
||||
<!-- Toggle Feature Flags -->
|
||||
<NavSelectFeatureFlags v-if="currentUser">
|
||||
<NavSelectFeatureFlags v-if="isMastoInitialised && currentUser">
|
||||
<button
|
||||
flex flex-row items-center
|
||||
block px-5 py-2 focus-blue w-full
|
||||
|
|
|
@ -30,7 +30,7 @@ const buildTimeAgo = useTimeAgo(buildTime, timeAgoOptions)
|
|||
</button>
|
||||
</CommonTooltip>
|
||||
</NavSelectLanguage>
|
||||
<NavSelectFeatureFlags v-if="currentUser">
|
||||
<NavSelectFeatureFlags v-if="isMastoInitialised && currentUser">
|
||||
<CommonTooltip :content="$t('nav_footer.select_feature_flags')">
|
||||
<button flex :aria-label="$t('nav_footer.select_feature_flags')">
|
||||
<div i-ri:flag-line text-lg />
|
||||
|
@ -44,7 +44,7 @@ const buildTimeAgo = useTimeAgo(buildTime, timeAgoOptions)
|
|||
</button>
|
||||
</div>
|
||||
<div>{{ $t('app_desc_short') }}</div>
|
||||
<div>
|
||||
<div v-if="isMastoInitialised">
|
||||
<i18n-t keypath="nav_footer.built_at">
|
||||
<time :datetime="buildTime" :title="$d(buildTimeDate, 'long')">{{ buildTimeAgo }}</time>
|
||||
</i18n-t>
|
||||
|
|
|
@ -4,7 +4,7 @@ const { notifications } = useNotifications()
|
|||
|
||||
<template>
|
||||
<nav md:px3 md:py4 flex="~ col gap2" text-size-base leading-normal md:text-lg>
|
||||
<template v-if="currentUser">
|
||||
<template v-if="isMastoInitialised && currentUser">
|
||||
<NavSideItem :text="$t('nav_side.home')" to="/home" icon="i-ri:home-5-line" />
|
||||
<NavSideItem :text="$t('nav_side.notifications')" to="/notifications" icon="i-ri:notification-4-line">
|
||||
<template #icon>
|
||||
|
@ -20,12 +20,12 @@ const { notifications } = useNotifications()
|
|||
<NavSideItem :text="$t('nav_side.explore')" :to="`/${currentServer}/explore`" icon="i-ri:hashtag" />
|
||||
<NavSideItem :text="$t('nav_side.local')" :to="`/${currentServer}/public/local`" icon="i-ri:group-2-line " />
|
||||
<NavSideItem :text="$t('nav_side.federated')" :to="`/${currentServer}/public`" icon="i-ri:earth-line" />
|
||||
<template v-if="currentUser">
|
||||
<template v-if="isMastoInitialised && currentUser">
|
||||
<NavSideItem :text="$t('nav_side.conversations')" to="/conversations" icon="i-ri:at-line" />
|
||||
<NavSideItem :text="$t('nav_side.favourites')" to="/favourites" icon="i-ri:heart-3-line" />
|
||||
<NavSideItem :text="$t('nav_side.bookmarks')" to="/bookmarks" icon="i-ri:bookmark-line " />
|
||||
<NavSideItem
|
||||
v-if="isMediumScreen"
|
||||
v-if="isHydrated && isMediumScreen"
|
||||
:text="currentUser.account.displayName"
|
||||
:to="getAccountRoute(currentUser.account)"
|
||||
icon="i-ri:account-circle-line"
|
||||
|
|
|
@ -25,7 +25,7 @@ useCommand({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<NuxtLink :to="to" active-class="text-primary" group focus:outline-none @click="$scrollToTop">
|
||||
<NuxtLink :to="to" :active-class="isMastoInitialised ? 'text-primary' : ''" group focus:outline-none @click="$scrollToTop">
|
||||
<div flex w-fit px5 py2 md:gap2 gap4 items-center transition-100 rounded-full group-hover:bg-active group-focus-visible:ring="2 current">
|
||||
<slot name="icon">
|
||||
<div :class="icon" md:text-size-inherit text-xl />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<VDropdown v-if="currentUser">
|
||||
<VDropdown v-if="isMastoInitialised && currentUser">
|
||||
<div style="-webkit-touch-callout: none;">
|
||||
<AccountAvatar
|
||||
ref="avatar"
|
||||
|
|
|
@ -27,11 +27,11 @@ const description = ref(props.attachment.description ?? '')
|
|||
v-if="removable"
|
||||
aria-label="Remove attachment"
|
||||
hover:bg="gray/40" transition-100 p-1 rounded-5 cursor-pointer
|
||||
:class="[isSmallScreen ? '' : 'op-0 group-hover:op-100hover:']"
|
||||
:class="[isHydrated && isSmallScreen ? '' : 'op-0 group-hover:op-100hover:']"
|
||||
mix-blend-difference
|
||||
@click="$emit('remove')"
|
||||
>
|
||||
<div i-ri:close-line text-3 :class="[isSmallScreen ? 'text-6' : 'text-3']" />
|
||||
<div i-ri:close-line text-3 :class="[isHydrated && isSmallScreen ? 'text-6' : 'text-3']" />
|
||||
</div>
|
||||
</div>
|
||||
<div absolute right-2 bottom-2>
|
||||
|
|
|
@ -167,7 +167,7 @@ defineExpose({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="currentUser" flex="~ col gap-4" py4 px2 sm:px4>
|
||||
<div v-if="isMastoInitialised && currentUser" flex="~ col gap-4" py4 px2 sm:px4>
|
||||
<template v-if="draft.editingStatus">
|
||||
<div flex="~ col gap-1">
|
||||
<div id="state-editing" text-secondary self-center>
|
||||
|
|
|
@ -162,7 +162,7 @@ async function editStatus() {
|
|||
@click="toggleTranslation"
|
||||
/>
|
||||
|
||||
<template v-if="currentUser">
|
||||
<template v-if="isMastoInitialised && currentUser">
|
||||
<template v-if="isAuthor">
|
||||
<CommonDropdownItem
|
||||
:text="status.pinned ? $t('menu.unpin_on_profile') : $t('menu.pin_on_profile')"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div p8 flex="~ col gap4">
|
||||
<p text-sm>
|
||||
<p v-if="isMastoInitialised" text-sm>
|
||||
Viewing <strong>{{ currentServer }}</strong> public data
|
||||
</p>
|
||||
<p text-sm text-secondary>
|
||||
|
|
|
@ -44,7 +44,7 @@ const switchUser = (user: UserLogin) => {
|
|||
@click="openSigninDialog"
|
||||
/>
|
||||
<CommonDropdownItem
|
||||
v-if="currentUser"
|
||||
v-if="isMastoInitialised && currentUser"
|
||||
:text="$t('user.sign_out_account', [getFullHandle(currentUser.account)])"
|
||||
icon="i-ri:logout-box-line"
|
||||
@click="signout"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue