Skip to content

Commit 83771f2

Browse files
committed
feat: optimize popover in mobile
Signed-off-by: Innei <[email protected]>
1 parent 44f7797 commit 83771f2

File tree

18 files changed

+120
-52
lines changed

18 files changed

+120
-52
lines changed

src/app/(app)/notes/[id]/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { Presence } from '~/components/modules/activity'
77
import {
88
NoteActionAside,
99
NoteBottomBarAction,
10+
NoteBottomTopic,
1011
NoteFooterNavigationBarForMobile,
1112
NoteMetaBar,
1213
NoteMetaReadingCount,
13-
NoteTopic,
1414
} from '~/components/modules/note'
1515
import {
1616
NoteBanner,
@@ -96,7 +96,7 @@ export default async function Page(props: {
9696
<ClientOnly>
9797
<div className="mt-8" data-hide-print />
9898
<NoteBottomBarAction />
99-
<NoteTopic />
99+
<NoteBottomTopic />
100100
<XLogInfoForNote />
101101
<NoteFooterNavigationBarForMobile />
102102
</ClientOnly>

src/app/(app)/notes/[id]/pageExtra.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,15 @@ export const NoteHeaderDate = () => {
8888
}`
8989

9090
return (
91-
<FloatPopover as="span" type="tooltip" TriggerComponent={NoteDateMeta}>
91+
<FloatPopover
92+
sheet={{
93+
triggerAsChild: false,
94+
}}
95+
as="span"
96+
mobileAsSheet
97+
type="tooltip"
98+
TriggerComponent={NoteDateMeta}
99+
>
92100
{tips}
93101
</FloatPopover>
94102
)

src/app/(dashboard)/dashboard/notes/list/page.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const cardSlot: CardProps<NoteModel>['slots'] = {
8787
<RelativeTime date={data.created} />
8888
{data.modified && (
8989
<FloatPopover
90+
mobileAsSheet
9091
wrapperClassName="text-xs"
9192
as="span"
9293
type="tooltip"
@@ -97,7 +98,8 @@ const cardSlot: CardProps<NoteModel>['slots'] = {
9798
)}
9899
{data.topic && (
99100
<FloatPopover
100-
TriggerComponent={() => (
101+
mobileAsSheet
102+
triggerElement={
101103
<div className="flex items-center gap-1">
102104
<img
103105
src={data.topic?.icon}
@@ -106,7 +108,7 @@ const cardSlot: CardProps<NoteModel>['slots'] = {
106108
/>
107109
<div>{data.topic && data.topic.name}</div>
108110
</div>
109-
)}
111+
}
110112
>
111113
<div className="flex flex-col gap-1">
112114
<div>专栏:{data.topic.name}</div>

src/app/(dashboard)/dashboard/posts/list/page.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ const cardSlot: CardProps<PostModel>['slots'] = {
9494
<RelativeTime date={data.created} />
9595
{data.modified && (
9696
<FloatPopover
97+
mobileAsSheet
9798
wrapperClassName="text-xs"
9899
as="span"
99100
type="tooltip"
@@ -103,6 +104,7 @@ const cardSlot: CardProps<PostModel>['slots'] = {
103104
</FloatPopover>
104105
)}
105106
<FloatPopover
107+
mobileAsSheet
106108
triggerElement={
107109
<div className="flex items-center gap-2">
108110
<FeHash className="translate-y-[0.5px]" />

src/components/layout/footer/FooterInfo.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ const PoweredBy: Component = ({ className }) => {
117117
<span className="mx-1">&</span>
118118
<FloatPopover
119119
isDisabled={!process.env.COMMIT_HASH}
120+
mobileAsSheet
120121
type="tooltip"
121122
triggerElement={
122123
<StyledLink href="https://github.com/innei/Shiro" target="_blank">

src/components/layout/footer/GatewayInfo.tsx

+22-23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { routeBuilder, Routes } from '~/lib/route-builder'
1818
const Help = () => {
1919
return (
2020
<FloatPopover
21+
mobileAsSheet
2122
as="span"
2223
triggerElement={
2324
<i className="icon-[mingcute--question-line] cursor-help" />
@@ -58,30 +59,27 @@ const ConnectedIndicator = () => {
5859
trackerMessage="socket_status"
5960
action={TrackerAction.Impression}
6061
/>
61-
{connected ? (
62-
<>
63-
<span
64-
className="absolute size-5"
65-
style={{
66-
background: `radial-gradient(45.91% 45.91% at 49.81% 54.09%, #00FC47 7.13%, rgba(174, 244, 194, 0.46) 65.83%, rgba(252, 252, 252, 0.00) 100%)`,
67-
}}
68-
/>
62+
<ConnectionStatus isConnected={connected} />
63+
</div>
64+
)
65+
}
6966

70-
<span className="ml-6">已连接</span>
71-
</>
72-
) : (
73-
<>
74-
<span
75-
className="absolute size-5"
76-
style={{
77-
background: `radial-gradient(45.91% 45.91% at 49.81% 54.09%, #FC0000 7.13%, rgba(244, 174, 174, 0.46) 65.83%, rgba(252, 252, 252, 0.00) 100%)`,
78-
}}
79-
/>
67+
function ConnectionStatus({ isConnected }: { isConnected: boolean }) {
68+
const color = isConnected ? '#00FC47' : '#FC0000'
69+
const secondaryColor = isConnected
70+
? 'rgba(174, 244, 194, 0.46)'
71+
: 'rgba(244, 174, 174, 0.46)'
72+
const text = isConnected ? '已连接' : '未连接'
8073

81-
<span className="ml-6">未连接</span>
82-
</>
83-
)}
84-
</div>
74+
const backgroundStyle = {
75+
background: `radial-gradient(45.91% 45.91% at 49.81% 54.09%, ${color} 7.13%, ${secondaryColor} 65.83%, rgba(252, 252, 252, 0.00) 100%)`,
76+
}
77+
78+
return (
79+
<>
80+
<span className="absolute size-5" style={backgroundStyle} />
81+
<span className="ml-6">{text}</span>
82+
</>
8583
)
8684
}
8785

@@ -94,6 +92,7 @@ export const GatewayInfo = () => {
9492
<div className="inline-flex items-center gap-2">
9593
<FloatPopover
9694
asChild
95+
mobileAsSheet
9796
placement="top"
9897
trigger="both"
9998
offset={10}
@@ -170,7 +169,7 @@ const RoomsInfo = () => {
170169
if (data.length === 0)
171170
return <div className="text-gray-500">还没有小伙伴在阅览文章哦~</div>
172171
return (
173-
<div className="max-w-[80vw] lg:max-w-[400px]">
172+
<div className="lg:max-w-[400px]">
174173
<div className="mb-2 text-sm font-medium">下面的内容正在被看爆:</div>
175174
<ul className="flex flex-col justify-between gap-2">
176175
{data.map((room) => (

src/components/modules/comment/CommentBox/UniversalTextArea.tsx

+18-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { useCallback, useEffect, useRef } from 'react'
44
import { useIsomorphicLayoutEffect } from 'foxact/use-isomorphic-layout-effect'
55
import dynamic from 'next/dynamic'
66

7+
import { useIsMobile } from '~/atoms/hooks'
78
import { FloatPopover } from '~/components/ui/float-popover'
89
import { TextArea } from '~/components/ui/input'
910
import { useRefValue } from '~/hooks/common/use-ref-value'
10-
import { preventDefault } from '~/lib/dom'
1111

1212
import { getRandomPlaceholder } from './constants'
1313
import {
@@ -73,6 +73,7 @@ export const UniversalTextArea: Component = ({ className }) => {
7373
}, [])
7474

7575
const [sendComment] = useSendComment()
76+
const isMobile = useIsMobile()
7677
return (
7778
<TextArea
7879
bordered={false}
@@ -87,22 +88,32 @@ export const UniversalTextArea: Component = ({ className }) => {
8788
}}
8889
>
8990
<CommentBoxSlotPortal>
90-
<FloatPopover trigger="click" TriggerComponent={EmojiButton} headless>
91-
<EmojiPicker onEmojiSelect={handleInsertEmoji} />
92-
</FloatPopover>
91+
<>
92+
{!isMobile && (
93+
<FloatPopover
94+
mobileAsSheet
95+
trigger="click"
96+
TriggerComponent={EmojiButton}
97+
headless
98+
>
99+
<EmojiPicker onEmojiSelect={handleInsertEmoji} />
100+
</FloatPopover>
101+
)}
102+
</>
93103
</CommentBoxSlotPortal>
94104
</TextArea>
95105
)
96106
}
97107

98108
const EmojiButton = () => {
99109
return (
100-
<button
110+
<div
101111
className="ml-0 inline-flex size-5 translate-y-1 text-base center md:ml-4"
102-
onClick={preventDefault}
112+
role="button"
113+
tabIndex={0}
103114
>
104115
<i className="icon-[mingcute--emoji-2-line]" />
105116
<span className="sr-only">表情</span>
106-
</button>
117+
</div>
107118
)
108119
}

src/components/modules/dashboard/home/Shiju.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const ShiJu = () => {
2020

2121
if (!origin) return null
2222
return (
23-
<FloatPopover triggerElement={<span>{data?.shiju}</span>}>
23+
<FloatPopover mobileAsSheet triggerElement={<span>{data?.shiju}</span>}>
2424
<div className="max-w-[800px] text-center">
2525
<h3 className="sticky top-0 py-2 text-2xl font-medium">
2626
{origin.title}

src/components/modules/dashboard/ip/IpInfoPopover.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const IpInfoPopover: Component<IpInfoPopoverProps> = (props) => {
4545

4646
return (
4747
<FloatPopover
48+
mobileAsSheet
4849
type="tooltip"
4950
wrapperClassName="truncate"
5051
onOpen={() => {

src/components/modules/note/NoteTopic.tsx src/components/modules/note/NoteBottomTopic.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import Link from 'next/link'
44
import type { FC } from 'react'
55

6+
import { useIsMobile } from '~/atoms/hooks'
67
import { Avatar } from '~/components/ui/avatar'
78
import { Divider } from '~/components/ui/divider'
89
import { FloatPopover } from '~/components/ui/float-popover'
@@ -21,9 +22,9 @@ const textToBigCharOrWord = (name: string | undefined) => {
2122
return bigChar
2223
}
2324

24-
export const NoteTopic: FC = () => {
25+
export const NoteBottomTopic: FC = () => {
2526
const topic = useCurrentNoteDataSelector((state) => state?.data.topic)
26-
27+
const isMobile = useIsMobile()
2728
if (!topic) return null
2829
const { icon, name, introduce } = topic
2930

@@ -47,14 +48,19 @@ export const NoteTopic: FC = () => {
4748
<span className="text-md mb-2 font-medium">
4849
<FloatPopover
4950
strategy="absolute"
51+
mobileAsSheet
5052
triggerElement={
51-
<Link
52-
href={routeBuilder(Routes.NoteTopic, {
53-
slug: topic.slug,
54-
})}
55-
>
53+
isMobile ? (
5654
<span>{name}</span>
57-
</Link>
55+
) : (
56+
<Link
57+
href={routeBuilder(Routes.NoteTopic, {
58+
slug: topic.slug,
59+
})}
60+
>
61+
<span>{name}</span>
62+
</Link>
63+
)
5864
}
5965
>
6066
<NoteTopicDetail topic={topic} />

src/components/modules/note/NoteTopicDetail.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Link from 'next/link'
55
import type { TopicModel } from '@mx-space/api-client'
66
import type { FC } from 'react'
77

8+
import { useIsMobile } from '~/atoms/hooks'
89
import { MdiClockOutline } from '~/components/icons/clock'
910
import { MdiFountainPenTip } from '~/components/icons/pen'
1011
import { Divider, DividerVertical } from '~/components/ui/divider'
@@ -30,6 +31,7 @@ export const NoteTopicDetail: FC<{ topic: TopicModel }> = (props) => {
3031
}),
3132
})
3233

34+
const isMobile = useIsMobile()
3335
const isClient = useIsClient()
3436
if (!isClient) {
3537
return null
@@ -45,6 +47,9 @@ export const NoteTopicDetail: FC<{ topic: TopicModel }> = (props) => {
4547
<h1 className="!m-0 inline-block pb-2 text-lg font-medium">
4648
{topic.name}
4749
</h1>
50+
{isMobile && (
51+
<i className="icon-[mingcute--arrow-right-up-line] ml-2 translate-y-[2px] opacity-70" />
52+
)}
4853
</Link>
4954

5055
<div className="line-clamp-2 break-all text-neutral-content">

src/components/modules/note/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export * from './NoteMainContainer'
77
export * from './NoteMetaBar'
88
export * from './NotePasswordForm'
99
export * from './NoteTimeline'
10-
export * from './NoteTopic'
10+
export * from './NoteBottomTopic'
1111
export * from './NoteTopicDetail'
1212
export * from './NoteTopicInfo'
1313
export * from './NoteTopicMarkdownRender'

src/components/modules/post/PostMetaBar.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const PostMetaBar: Component<{
4242
)}
4343
{!!meta.modified && (
4444
<FloatPopover
45+
mobileAsSheet
4546
wrapperClassName="text-xs"
4647
as="span"
4748
type="tooltip"

src/components/modules/shared/MetaBar.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const CurrentReadingCountingMetaBarItem: FC<{
1919
{leftElement}
2020
<FloatPopover
2121
asChild
22+
mobileAsSheet
2223
type="tooltip"
2324
triggerElement={
2425
<span>

src/components/modules/shared/SearchFAB.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ const SearchPanelImpl = () => {
295295
}}
296296
>
297297
<FloatPopover
298+
mobileAsSheet
298299
type="tooltip"
299300
triggerElement={
300301
<i className="icon-[mingcute--download-2-line]" />

src/components/ui/float-popover/FloatPopover.tsx

+29-1
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,41 @@ import React, {
2020
import { AnimatePresence, m } from 'framer-motion'
2121
import type { UseFloatingOptions } from '@floating-ui/react-dom'
2222
import type { FC, PropsWithChildren, ReactElement } from 'react'
23+
import type { PresentSheetProps } from '../sheet'
2324

25+
import { useIsMobile } from '~/atoms/hooks'
2426
import { microReboundPreset } from '~/constants/spring'
2527
import useClickAway from '~/hooks/common/use-click-away'
2628
import { useEventCallback } from '~/hooks/common/use-event-callback'
2729
import { clsxm } from '~/lib/helper'
2830

2931
import { RootPortal } from '../portal'
32+
import { PresentSheet } from '../sheet'
33+
34+
export const FloatPopover = function <T extends {}>(
35+
props: FloatPopoverProps<T> & {
36+
mobileAsSheet?: boolean
37+
sheet?: Partial<Omit<PresentSheetProps, 'content'>>
38+
},
39+
) {
40+
const isMobile = useIsMobile()
41+
if (isMobile && props.mobileAsSheet) {
42+
const { triggerElement, TriggerComponent, triggerComponentProps } = props
43+
44+
const Child = triggerElement
45+
? triggerElement
46+
: TriggerComponent
47+
? createElement(TriggerComponent as any, triggerComponentProps)
48+
: null
49+
50+
return (
51+
<PresentSheet content={props.children} {...props.sheet}>
52+
{Child}
53+
</PresentSheet>
54+
)
55+
}
56+
return <RealFloatPopover {...props} />
57+
}
3058

3159
type FloatPopoverProps<T> = PropsWithChildren<{
3260
triggerElement?: string | ReactElement
@@ -71,7 +99,7 @@ const PopoverActionContext = createContext<{
7199

72100
export const usePopoverAction = () => useContext(PopoverActionContext)
73101

74-
export const FloatPopover = function FloatPopover<T extends {}>(
102+
const RealFloatPopover = function FloatPopover<T extends {}>(
75103
props: FloatPopoverProps<T>,
76104
) {
77105
const {

0 commit comments

Comments
 (0)