Skip to content

Commit a0fd2f3

Browse files
committed
feat: migrate to react-modal-sheet for mobile
1 parent d37e2b2 commit a0fd2f3

17 files changed

Lines changed: 162 additions & 396 deletions

File tree

packages/webapp/components/TipTap/pad-title-section/MobilePadTitle.tsx

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ import SignInPanel from '@components/pages/panels/SignInPanel'
1414
import ToolbarButton from '@components/TipTap/toolbar/ToolbarButton'
1515
import { BiCheck, BiUndo, BiRedo } from 'react-icons/bi'
1616
import { useNotificationCount } from '@hooks/useNotificationCount'
17-
import { ModalBottomToTop } from '@components/ui/ModalBottomToTop'
1817
import NotificationModal from '@components/notificationPanel/mobile/NotificationModal'
19-
18+
import { Sheet } from 'react-modal-sheet'
2019
interface UserProfileButtonProps {
2120
user: any
2221
onProfileClick: () => void
2322
}
2423

24+
interface UndoRedoButtonsProps {
25+
editor: any
26+
className?: string
27+
}
28+
2529
interface NotificationButtonProps {
2630
unreadCount: number
27-
modalRef: React.RefObject<any>
31+
setIsNotificationSheetOpen: (isOpen: boolean) => void
2832
}
2933

3034
const EditableToggle = ({ isEditable }: { isEditable: boolean }) => {
@@ -73,12 +77,15 @@ const UserProfileButton = ({ user, onProfileClick }: UserProfileButtonProps) =>
7377
)
7478
}
7579

76-
const NotificationButton = ({ unreadCount, modalRef }: NotificationButtonProps) => {
80+
const NotificationButton = ({
81+
unreadCount,
82+
setIsNotificationSheetOpen
83+
}: NotificationButtonProps) => {
7784
return (
7885
<Button
7986
className="btn-ghost tooltip tooltip-bottom relative p-2"
8087
data-tip="Notifications"
81-
onClick={() => modalRef.current?.check()}>
88+
onClick={() => setIsNotificationSheetOpen(true)}>
8289
<MdInsertComment size={26} className="text-docsy" />
8390
{unreadCount > 0 && (
8491
<div className="absolute top-[2px] right-[2px] flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-xs text-white">
@@ -89,11 +96,6 @@ const NotificationButton = ({ unreadCount, modalRef }: NotificationButtonProps)
8996
)
9097
}
9198

92-
interface UndoRedoButtonsProps {
93-
editor: any
94-
className?: string
95-
}
96-
9799
const UndoRedoButtons = ({ editor, className }: UndoRedoButtonsProps) => {
98100
return (
99101
<div className={`flex items-center ${className}`}>
@@ -119,6 +121,8 @@ const MobilePadTitle = () => {
119121
} = useStore((state) => state.settings)
120122
const [isProfileModalOpen, setProfileModalOpen] = useState(false)
121123
const notificationModalRef = useRef<any>(null!)
124+
const [isNotificationSheetOpen, setIsNotificationSheetOpen] = useState(false)
125+
const [isFilterModalOpen, setIsFilterModalOpen] = useState(false)
122126

123127
return (
124128
<>
@@ -139,7 +143,10 @@ const MobilePadTitle = () => {
139143

140144
<div className="flex w-[20%] items-center justify-end gap-2">
141145
<ReadOnlyIndicator />
142-
<NotificationButton unreadCount={unreadCount} modalRef={notificationModalRef} />
146+
<NotificationButton
147+
unreadCount={unreadCount}
148+
setIsNotificationSheetOpen={setIsNotificationSheetOpen}
149+
/>
143150
<UserProfileButton user={user} onProfileClick={() => setProfileModalOpen(true)} />
144151
</div>
145152
</div>
@@ -149,17 +156,19 @@ const MobilePadTitle = () => {
149156
</div>
150157
</div>
151158

152-
<ModalBottomToTop
153-
modalId="notificationModal"
154-
contentClassName="h-[60%] overflow-hidden"
155-
ref={notificationModalRef}
156-
defaultHeight={800}>
157-
<div
158-
style={{ height: 'calc(100% - 24px)' }}
159-
className="flex flex-col justify-start overflow-hidden">
160-
<NotificationModal />
161-
</div>
162-
</ModalBottomToTop>
159+
<Sheet
160+
id="notification_sheet"
161+
modalEffectRootId="notification_sheet"
162+
isOpen={isNotificationSheetOpen}
163+
onClose={() => setIsNotificationSheetOpen(false)}>
164+
<Sheet.Container>
165+
<Sheet.Header />
166+
<Sheet.Content>
167+
<NotificationModal />
168+
</Sheet.Content>
169+
</Sheet.Container>
170+
<Sheet.Backdrop />
171+
</Sheet>
163172

164173
<Modal
165174
asAChild={false}

packages/webapp/components/notificationPanel/desktop/NotificationPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const NotificationPanel = () => {
1919
setNotificationActiveTab
2020
} = useStore((state) => state)
2121

22-
useNotificationSummary({ mobile: false })
22+
useNotificationSummary()
2323
useNotificationTabData()
2424

2525
const activeTabNotifList = useMemo(() => {

packages/webapp/components/notificationPanel/hooks/useNotificationSummary.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ import { useApi } from '@hooks/useApi'
33
import { getNotificationsSummary } from '@api'
44
import { useAuthStore, useStore } from '@stores'
55
import { TNotificationSummary } from '@types'
6-
import { useDropdown } from '@components/ui/Dropdown'
7-
import { useModalBottomToTopOptional } from '@components/ui'
86

9-
export const useNotificationSummary = ({ mobile = false }: { mobile: boolean }) => {
7+
export const useNotificationSummary = () => {
108
const { workspaceId } = useStore((state) => state.settings)
119
const user = useAuthStore((state) => state.profile)
1210
const {
@@ -17,9 +15,6 @@ export const useNotificationSummary = ({ mobile = false }: { mobile: boolean })
1715
setNotificationTab,
1816
setNotificationPage
1917
} = useStore((state) => state)
20-
const modalContext = mobile ? useModalBottomToTopOptional() : null
21-
const dropdownContext = mobile ? null : useDropdown()
22-
const isOpen = modalContext?.isOpen || dropdownContext?.isOpen || false
2318

2419
const { request: summaryRequest } = useApi(getNotificationsSummary, null, false)
2520

@@ -55,5 +50,5 @@ export const useNotificationSummary = ({ mobile = false }: { mobile: boolean })
5550
}
5651

5752
fetchNotificationSummary()
58-
}, [user, workspaceId, isOpen])
53+
}, [user, workspaceId])
5954
}

packages/webapp/components/notificationPanel/mobile/NotificationModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useNotificationTabData } from '../hooks/useNotificationTabData'
1212
const NotificationModal = () => {
1313
const { loadingNotification, notifications, notificationActiveTab } = useStore((state) => state)
1414

15-
useNotificationSummary({ mobile: true })
15+
useNotificationSummary()
1616
useNotificationTabData()
1717

1818
const activeTabNotifList = useMemo(() => {

packages/webapp/components/pages/document/components/FilterModal.tsx

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,36 @@
11
import React, { useState, useEffect, useRef, RefObject } from 'react'
22
import { useRouter } from 'next/router'
33
import { IoClose } from 'react-icons/io5'
4+
const FilterModalHeader = ({
5+
setIsFilterModalOpen
6+
}: {
7+
setIsFilterModalOpen: (isOpen: boolean) => void
8+
}) => {
9+
return (
10+
<>
11+
<div className="flex w-full items-center justify-center">
12+
<span className="drag-indicator h-1 w-14 rounded-full bg-gray-300"></span>
13+
</div>
14+
<div className="mb-3 flex w-full bg-white py-2 text-black">
15+
<p className="w-2/3 text-lg font-semibold">Filters</p>
16+
<div className="flex w-1/3 flex-row items-center justify-end justify-items-end">
17+
<label
18+
htmlFor="filterModalBottom"
19+
className="btn btn-square btn-ghost btn-sm ml-2 text-black"
20+
onClick={() => setIsFilterModalOpen(false)}>
21+
<IoClose size={20} />
22+
</label>
23+
</div>
24+
</div>
25+
</>
26+
)
27+
}
428

5-
const FilterModal = () => {
29+
const FilterModal = ({
30+
setIsFilterModalOpen
31+
}: {
32+
setIsFilterModalOpen: (isOpen: boolean) => void
33+
}) => {
634
const filterSearchRef = useRef<HTMLInputElement>(null)
735
const [totalHeading, setTotalHeading] = useState(0)
836
const [totalSearch, setTotalSearch] = useState(0)
@@ -51,15 +79,8 @@ const FilterModal = () => {
5179
}
5280

5381
return (
54-
<div className="h-full max-h-96 w-full rounded-t-2xl bg-white p-4">
55-
<div className="mb-3 flex w-full bg-white py-2 text-blue-600">
56-
<p className="w-2/3">Filters</p>
57-
<div className="flex w-1/3 flex-row items-center justify-end justify-items-end">
58-
<label htmlFor="filterModalBottom" className="btn btn-circle btn-xs ml-2">
59-
<IoClose size={20} />
60-
</label>
61-
</div>
62-
</div>
82+
<div className="h-full max-h-96 w-full rounded-t-lg bg-white p-4">
83+
<FilterModalHeader setIsFilterModalOpen={setIsFilterModalOpen} />
6384
<div className="join w-full">
6485
<input
6586
id="filterModalBottom"
@@ -71,7 +92,7 @@ const FilterModal = () => {
7192
onKeyUp={searchThroughHeading}
7293
ref={filterSearchRef}
7394
/>
74-
<p className="join-item flex w-3/12 items-center justify-center rounded-r bg-base-300 text-sm">
95+
<p className="join-item bg-base-300 flex w-3/12 items-center justify-center rounded-r text-sm">
7596
<span className="text-center">
7697
found <br /> {totalSearch} of {totalHeading}
7798
</span>

packages/webapp/components/pages/document/components/TocModal.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,12 @@ import { MdFilterAlt, MdHistory } from 'react-icons/md'
88
import TableOfContents from '@components/TipTap/tableOfContents/mobile/TocMobile'
99
import { useModal } from '@components/ui/ModalDrawer'
1010

11-
const TocModal = ({ filterModalRef }: any) => {
11+
const TocModal = ({ setIsFilterModalOpen }: any) => {
1212
const { close: closeModal } = useModal() || {}
1313
const {
1414
editor: { loading, applyingFilters, providerSyncing, instance: editor }
1515
} = useStore((state) => state.settings)
1616

17-
const handleFilterClick = useCallback(() => {
18-
filterModalRef.current?.check()
19-
}, [])
20-
2117
if (loading || !editor || applyingFilters || providerSyncing) {
2218
return null
2319
}
@@ -46,7 +42,7 @@ const TocModal = ({ filterModalRef }: any) => {
4642
<label
4743
htmlFor="mobile_history_panel"
4844
onClick={() => {
49-
handleFilterClick()
45+
setIsFilterModalOpen(true)
5046
closeModal?.()
5147
}}
5248
className="btn btn-sm join-item">

packages/webapp/components/pages/document/components/chat/ChatContainerMobile.tsx

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import { useChatStore } from '@stores'
22
import ToolbarMobile from '@components/chat/components/ToolbarMobile'
33
import { ChannelProvider } from '@components/chat/context/ChannelProvider'
44
import { ChatRoom } from '@components/chat/ChatRoom'
5-
import { ModalBottomToTop } from '@components/ui/ModalBottomToTop'
6-
import { useEffect, useRef } from 'react'
5+
import { Sheet } from 'react-modal-sheet'
76

87
const initSettings = {
98
displayChannelBar: false,
@@ -22,42 +21,27 @@ const initSettings = {
2221

2322
const ChatContainerMobile = () => {
2423
const chatRoom = useChatStore((state) => state.chatRoom)
25-
const modalRef = useRef(null)
26-
const destroyChatRoom = useChatStore((state) => state.destroyChatRoom)
27-
28-
useEffect(() => {
29-
if (!modalRef.current) return
30-
31-
if (chatRoom?.headingId) {
32-
;(modalRef.current as any).check()
33-
} else {
34-
;(modalRef.current as any).uncheck()
35-
}
36-
}, [chatRoom?.headingId, modalRef.current])
37-
38-
const modalStateChange = (state: boolean) => {
39-
if (!state) destroyChatRoom()
40-
}
24+
const toggleChatRoom = useChatStore((state) => state.toggleChatRoom)
4125

4226
if (!chatRoom?.headingId) return null
4327

4428
return (
45-
<ModalBottomToTop
46-
showBackdrop={false}
47-
ref={modalRef}
48-
onModalStateChange={modalStateChange}
49-
modalId="chatBottomPannel"
50-
contentClassName="h-[60%] overflow-hidden"
51-
defaultHeight={560}>
52-
<div
53-
style={{ height: 'calc(100% - 24px)' }}
54-
className="flex flex-col justify-start overflow-hidden">
55-
<ToolbarMobile />
56-
<ChannelProvider initChannelId={chatRoom.headingId} initSettings={initSettings}>
57-
<ChatRoom className="flex h-auto flex-auto flex-col overflow-auto"></ChatRoom>
58-
</ChannelProvider>
59-
</div>
60-
</ModalBottomToTop>
29+
<Sheet
30+
isOpen={chatRoom.open}
31+
onClose={() => toggleChatRoom()}
32+
id="chat_sheet"
33+
modalEffectRootId="chat_sheet">
34+
<Sheet.Container>
35+
<Sheet.Header />
36+
<Sheet.Content>
37+
<ToolbarMobile />
38+
<ChannelProvider initChannelId={chatRoom.headingId} initSettings={initSettings}>
39+
<ChatRoom className="flex h-auto flex-auto flex-col overflow-auto"></ChatRoom>
40+
</ChannelProvider>
41+
</Sheet.Content>
42+
</Sheet.Container>
43+
<Sheet.Backdrop />
44+
</Sheet>
6145
)
6246
}
6347

packages/webapp/components/pages/document/layouts/MobileLayout.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from 'react'
1+
import React, { useRef, useState } from 'react'
22
import MobilePadTitle from '@components/TipTap/pad-title-section/MobilePadTitle'
33
import FilterModal from '../components/FilterModal'
44
import MobileEditor from '../components/MobileEditor'
@@ -9,12 +9,12 @@ import BigPencilBtn from '@components/pages/document/components/BigPencilBtn'
99
import { ModalDrawer } from '@components/ui/ModalDrawer'
1010
import { useHashRouter } from '@hooks/useHashRouter'
1111
import MobileHistory from '@components/pages/history/mobile/MobileHistory'
12-
import { ModalBottomToTop } from '@components/ui/ModalBottomToTop'
12+
import { Sheet } from 'react-modal-sheet'
1313

14-
const MobileLeftSidePanel = ({ filterModalRef }: any) => {
14+
const MobileLeftSidePanel = ({ filterModalRef, setIsFilterModalOpen }: any) => {
1515
return (
1616
<ModalDrawer modalId="mobile_left_side_panel" width={80}>
17-
<TocModal filterModalRef={filterModalRef} />
17+
<TocModal filterModalRef={filterModalRef} setIsFilterModalOpen={setIsFilterModalOpen} />
1818
</ModalDrawer>
1919
)
2020
}
@@ -26,6 +26,8 @@ const MobileLayout = () => {
2626
}
2727
} = useStore((state) => state)
2828

29+
const [isFilterModalOpen, setIsFilterModalOpen] = useState(false)
30+
2931
const filterModalRef = useRef<HTMLDivElement>(null)
3032
const deviceClass = isMobile ? 'm_mobile' : 'm_desktop'
3133

@@ -36,13 +38,27 @@ const MobileLayout = () => {
3638
return (
3739
<div className={`tiptap relative flex h-full w-full flex-col ${deviceClass}`}>
3840
<MobilePadTitle />
39-
<MobileLeftSidePanel filterModalRef={filterModalRef} />
41+
<MobileLeftSidePanel
42+
filterModalRef={filterModalRef}
43+
setIsFilterModalOpen={setIsFilterModalOpen}
44+
/>
4045
<MobileEditor />
4146
<BigPencilBtn />
4247
<ChatContainerMobile />
43-
<ModalBottomToTop modalId="filterModal" ref={filterModalRef} defaultHeight={300}>
44-
<FilterModal />
45-
</ModalBottomToTop>
48+
49+
<Sheet
50+
isOpen={isFilterModalOpen}
51+
onClose={() => setIsFilterModalOpen(false)}
52+
snapPoints={[0.5, 0]}
53+
modalEffectRootId="filter_sheet"
54+
id="filter_sheet">
55+
<Sheet.Container>
56+
<Sheet.Content>
57+
<FilterModal setIsFilterModalOpen={setIsFilterModalOpen} />
58+
</Sheet.Content>
59+
</Sheet.Container>
60+
<Sheet.Backdrop />
61+
</Sheet>
4662
</div>
4763
)
4864
}

0 commit comments

Comments
 (0)