feat: use explorer page as search for mobile only (#1301)

zio/stable
Michel EDIGHOFFER 2023-02-03 11:40:54 +01:00 committed by GitHub
parent a2fb458696
commit 4b1b18768d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 41 deletions

View File

@ -4,6 +4,8 @@ defineProps<{
backOnSmallScreen?: boolean backOnSmallScreen?: boolean
/** Show the back button on both small and big screens */ /** Show the back button on both small and big screens */
back?: boolean back?: boolean
/** Do not applying overflow hidden to let use floatable components in title */
noOverflowHidden?: boolean
}>() }>()
const route = useRoute() const route = useRoute()
@ -19,7 +21,7 @@ const wideLayout = computed(() => route.meta.wideLayout ?? false)
class="native:lg:w-[calc(100vw-5rem)] native:xl:w-[calc(135%+(100vw-1200px)/2)]" class="native:lg:w-[calc(100vw-5rem)] native:xl:w-[calc(135%+(100vw-1200px)/2)]"
> >
<div flex justify-between px5 py2 :class="{ 'xl:hidden': $route.name !== 'tag' }" data-tauri-drag-region class="native:xl:flex"> <div flex justify-between px5 py2 :class="{ 'xl:hidden': $route.name !== 'tag' }" data-tauri-drag-region class="native:xl:flex">
<div flex gap-3 items-center overflow-hidden py2 class="native-mac:pl-14 native-mac:sm:pl-0"> <div flex gap-3 items-center :overflow-hidden="!noOverflowHidden ? '' : false" py2 w-full class="native-mac:pl-14 native-mac:sm:pl-0">
<NuxtLink <NuxtLink
v-if="backOnSmallScreen || back" flex="~ gap1" items-center btn-text p-0 xl:hidden v-if="backOnSmallScreen || back" flex="~ gap1" items-center btn-text p-0 xl:hidden
:aria-label="$t('nav.back')" :aria-label="$t('nav.back')"
@ -27,10 +29,10 @@ const wideLayout = computed(() => route.meta.wideLayout ?? false)
> >
<div i-ri:arrow-left-line class="rtl-flip" /> <div i-ri:arrow-left-line class="rtl-flip" />
</NuxtLink> </NuxtLink>
<div truncate> <div :truncate="!noOverflowHidden ? '' : false" w-full>
<slot name="title" /> <slot name="title" />
</div> </div>
<div h-7 w-1px /> <div sm:hidden h-7 w-1px />
</div> </div>
<div flex items-center flex-shrink-0 gap-x-2> <div flex items-center flex-shrink-0 gap-x-2>
<slot name="actions" /> <slot name="actions" />

View File

@ -14,7 +14,7 @@ const moreMenuVisible = ref(false)
<NuxtLink to="/home" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop"> <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 /> <div i-ri:home-5-line />
</NuxtLink> </NuxtLink>
<NuxtLink to="/search" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop"> <NuxtLink :to="isHydrated ? `/${currentServer}/explore` : '/explore'" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
<div i-ri:search-line /> <div i-ri:search-line />
</NuxtLink> </NuxtLink>
<NuxtLink to="/notifications" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop"> <NuxtLink to="/notifications" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
@ -28,9 +28,6 @@ const moreMenuVisible = ref(false)
<NuxtLink :to="`/${currentServer}/explore`" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop"> <NuxtLink :to="`/${currentServer}/explore`" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
<div i-ri:hashtag /> <div i-ri:hashtag />
</NuxtLink> </NuxtLink>
<NuxtLink to="/search" :active-class="moreMenuVisible ? '' : 'text-primary'" flex flex-row items-center place-content-center h-full flex-1 @click="$scrollToTop">
<div i-ri:search-line />
</NuxtLink>
<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"> <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 /> <div i-ri:group-2-line />
</NuxtLink> </NuxtLink>

View File

@ -6,12 +6,12 @@ const { notifications } = useNotifications()
</script> </script>
<template> <template>
<nav sm:px3 flex="~ col gap2" shrink text-size-base leading-normal md:text-lg> <nav sm:px3 flex="~ col gap2" shrink text-size-base leading-normal md:text-lg h-full>
<div shrink hidden sm:block mt-4 /> <div shrink hidden sm:block mt-4 />
<SearchWidget lg:ms-1 lg:me-5 hidden xl:block /> <SearchWidget lg:ms-1 lg:me-5 hidden xl:block />
<NavSideItem :text="$t('nav.search')" to="/search" icon="i-ri:search-line" xl:hidden :command="command" /> <NavSideItem :text="$t('nav.search')" :to="isHydrated ? `/${currentServer}/explore` : '/explore'" icon="i-ri:search-line" hidden sm:block xl:hidden :command="command" />
<div shrink hidden sm:block mt-4 /> <div shrink hidden sm:block mt-2 />
<NavSideItem :text="$t('nav.home')" to="/home" icon="i-ri:home-5-line" user-only :command="command" /> <NavSideItem :text="$t('nav.home')" to="/home" icon="i-ri:home-5-line" user-only :command="command" />
<NavSideItem :text="$t('nav.notifications')" to="/notifications" icon="i-ri:notification-4-line" user-only :command="command"> <NavSideItem :text="$t('nav.notifications')" to="/notifications" icon="i-ri:notification-4-line" user-only :command="command">
<template #icon> <template #icon>
@ -29,7 +29,7 @@ const { notifications } = useNotifications()
<NavSideItem :text="$t('action.compose')" to="/compose" icon="i-ri:quill-pen-line" user-only :command="command" /> <NavSideItem :text="$t('action.compose')" to="/compose" icon="i-ri:quill-pen-line" user-only :command="command" />
<div shrink hidden sm:block mt-4 /> <div shrink hidden sm:block mt-4 />
<NavSideItem :text="$t('nav.explore')" :to="isHydrated ? `/${currentServer}/explore` : '/explore'" icon="i-ri:hashtag" :command="command" /> <NavSideItem :text="$t('nav.explore')" :to="isHydrated ? `/${currentServer}/explore` : '/explore'" icon="i-ri:hashtag" :command="command" xs:hidden sm:hidden xl:block />
<NavSideItem :text="$t('nav.local')" :to="isHydrated ? `/${currentServer}/public/local` : '/public/local'" icon="i-ri:group-2-line " :command="command" /> <NavSideItem :text="$t('nav.local')" :to="isHydrated ? `/${currentServer}/public/local` : '/public/local'" icon="i-ri:group-2-line " :command="command" />
<NavSideItem :text="$t('nav.federated')" :to="isHydrated ? `/${currentServer}/public` : '/public'" icon="i-ri:earth-line" :command="command" /> <NavSideItem :text="$t('nav.federated')" :to="isHydrated ? `/${currentServer}/public` : '/public'" icon="i-ri:earth-line" :command="command" />
<NavSideItem :text="$t('nav.lists')" :to="`/${currentServer}/lists`" icon="i-ri:list-check" user-only :command="command" /> <NavSideItem :text="$t('nav.lists')" :to="`/${currentServer}/lists`" icon="i-ri:list-check" user-only :command="command" />

View File

@ -20,7 +20,7 @@ router.afterEach(() => {
<template> <template>
<div flex justify-between> <div flex justify-between>
<NuxtLink <NuxtLink
flex items-end gap-4 flex items-end gap-3
py2 px-5 py2 px-5
text-2xl text-2xl
select-none select-none

View File

@ -5,9 +5,14 @@ const index = ref(0)
const { t } = useI18n() const { t } = useI18n()
const el = ref<HTMLElement>() const el = ref<HTMLElement>()
const input = ref<HTMLInputElement>()
const router = useRouter() const router = useRouter()
const { focused } = useFocusWithin(el) const { focused } = useFocusWithin(el)
defineExpose({
input,
})
const results = computed(() => { const results = computed(() => {
if (query.value.length === 0) if (query.value.length === 0)
return [] return []
@ -68,6 +73,7 @@ const activate = () => {
bg-transparent bg-transparent
outline="focus:none" outline="focus:none"
pe-4 pe-4
ml-1
:placeholder="isHydrated ? t('nav.search') : ''" :placeholder="isHydrated ? t('nav.search') : ''"
pb="1px" pb="1px"
placeholder-text-secondary placeholder-text-secondary
@ -77,7 +83,7 @@ const activate = () => {
> >
</div> </div>
<!-- Results --> <!-- Results -->
<div left-0 top-12 absolute w-full z10 group-focus-within="pointer-events-auto visible" invisible pointer-events-none> <div left-0 top-11 absolute w-full z10 group-focus-within="pointer-events-auto visible" invisible pointer-events-none>
<div w-full bg-base border="~ base" rounded-3 max-h-100 overflow-auto py2> <div w-full bg-base border="~ base" rounded-3 max-h-100 overflow-auto py2>
<span v-if="query.trim().length === 0" block text-center text-sm text-secondary> <span v-if="query.trim().length === 0" block text-center text-sm text-secondary>
{{ t('search.search_desc') }} {{ t('search.search_desc') }}

View File

@ -3,3 +3,4 @@ import { breakpointsTailwind } from '@vueuse/core'
export const breakpoints = useBreakpoints(breakpointsTailwind) export const breakpoints = useBreakpoints(breakpointsTailwind)
export const isMediumOrLargeScreen = breakpoints.between('sm', 'xl') export const isMediumOrLargeScreen = breakpoints.between('sm', 'xl')
export const isExtraLargeScreen = breakpoints.smallerOrEqual('xl')

View File

@ -17,14 +17,14 @@ const isGrayscale = usePreferences('grayscaleMode')
<template> <template>
<div h-full :data-mode="isHydrated && isGrayscale ? 'grayscale' : ''"> <div h-full :data-mode="isHydrated && isGrayscale ? 'grayscale' : ''">
<main flex w-full mxa lg:max-w-80rem class="native:grid native:sm:grid-cols-[auto_1fr] native:lg:grid-cols-[auto_minmax(600px,2fr)_1fr]"> <main flex w-full mxa lg:max-w-80rem class="native:grid native:sm:grid-cols-[auto_1fr] native:lg:grid-cols-[auto_minmax(600px,2fr)_1fr]">
<aside class="hidden native:w-auto sm:flex w-1/8 md:w-1/6 lg:w-1/5 xl:w-1/4 justify-end xl:me-4 zen-hide" relative> <aside class="native:w-auto w-1/8 md:w-1/6 lg:w-1/5 xl:w-1/4" hidden sm:flex justify-end xl:me-4 zen-hide relative>
<div sticky top-0 w-20 xl:w-100 h-screen flex="~ col" lt-xl-items-center> <div sticky top-0 w-20 xl:w-100 h-screen flex="~ col" lt-xl-items-center>
<slot name="left"> <slot name="left">
<div flex="~ col" overflow-y-auto justify-between h-full max-w-full pt-5 native:pt-7 overflow-x-hidden> <div flex="~ col" overflow-y-auto justify-between h-full max-w-full pt-5 native:pt-7 overflow-x-hidden>
<NavTitle /> <NavTitle />
<NavSide command /> <NavSide command />
<div flex-auto /> <div flex-auto />
<div v-if="isHydrated" flex flex-col> <div v-if="isHydrated" flex flex-col sticky bottom-0 bg-base>
<div hidden xl:block> <div hidden xl:block>
<UserSignInEntry v-if="!currentUser" /> <UserSignInEntry v-if="!currentUser" />
</div> </div>
@ -59,7 +59,7 @@ const isGrayscale = usePreferences('grayscaleMode')
<NavBottom v-if="isHydrated" sm:hidden /> <NavBottom v-if="isHydrated" sm:hidden />
</div> </div>
</div> </div>
<aside v-if="isHydrated && !wideLayout" class="hidden sm:none lg:block w-1/4 zen-hide"> <aside v-if="isHydrated && !wideLayout" class="hidden w-1/4 sm:none lg:block zen-hide">
<div sticky top-0 h-screen flex="~ col" gap-2 py3 ms-2> <div sticky top-0 h-screen flex="~ col" gap-2 py3 ms-2>
<slot name="right"> <slot name="right">
<div flex-auto /> <div flex-auto />

View File

@ -3,6 +3,17 @@ import type { CommonRouteTabOption } from '~/components/common/CommonRouteTabs.v
const { t } = useI18n() const { t } = useI18n()
const search = $ref<{ input?: HTMLInputElement }>()
const route = useRoute()
watchEffect(() => {
if (isMediumOrLargeScreen && route.name === 'explore' && search?.input)
search?.input?.focus()
})
onActivated(() =>
search?.input?.focus(),
)
onDeactivated(() => search?.input?.blur())
const tabs = $computed<CommonRouteTabOption[]>(() => [ const tabs = $computed<CommonRouteTabOption[]>(() => [
{ {
to: isHydrated.value ? `/${currentServer.value}/explore` : '/explore', to: isHydrated.value ? `/${currentServer.value}/explore` : '/explore',
@ -26,13 +37,16 @@ const tabs = $computed<CommonRouteTabOption[]>(() => [
</script> </script>
<template> <template>
<MainContent> <MainContent :no-overflow-hidden="isExtraLargeScreen" :back-on-small-screen="isExtraLargeScreen">
<template #title> <template v-if="!isExtraLargeScreen" #title>
<span timeline-title-style flex items-center gap-2 cursor-pointer @click="$scrollToTop"> <span timeline-title-style flex items-center gap-2 cursor-pointer @click="$scrollToTop">
<div i-ri:hashtag /> <div i-ri:hashtag />
<span>{{ t('nav.explore') }}</span> <span>{{ t('nav.explore') }}</span>
</span> </span>
</template> </template>
<template v-else #title>
<SearchWidget v-if="isHydrated" ref="search" class="m-1" />
</template>
<template #header> <template #header>
<CommonRouteTabs replace :options="tabs" /> <CommonRouteTabs replace :options="tabs" />

View File

@ -1,23 +0,0 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
useHeadFixed({
title: () => t('nav.search'),
})
</script>
<template>
<MainContent>
<template #title>
<NuxtLink to="/search" timeline-title-style flex items-center gap-2 @click="$scrollToTop">
<div i-ri:search-line class="rtl-flip" />
<span>{{ $t('nav.search') }}</span>
</NuxtLink>
</template>
<div px2 mt3>
<SearchWidget v-if="isHydrated" />
</div>
</MainContent>
</template>