Skip to content

Commit adfc741

Browse files
author
Sravan S
authored
chore: Update router sample with Mobile + Desktop (#634)
fixes: https://sendbird.atlassian.net/browse/QM-2172
1 parent fa99875 commit adfc741

20 files changed

+739
-480
lines changed

samples/router/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# sendbird uikit react router sample
2+
3+
This is a complex sample involving the use of [react-router](https://reactrouter.com/) with Sendbird UIKit for React
4+
5+
This is just one of the many ways to use Sendbird UIKit for React with react-router
6+
in a responsive way.
7+
8+
We split layout into mobile and desktop layouts.
9+
Mobile layout only shows a component at a time.
10+
Desktop layout shows ChannelList and Channel at the same time.
11+
ChannelSettings and MessageSearch are conditionally rendered.
12+
13+
Similar concepts can be applied to implement ThreadedMessageList.
14+
CreateChannel can also be conditionally rendered on a URL,
15+
for this, you have to render custom header on channel list.
16+
And create a new route for CreateChannel. Where, you can render
17+
the create channel modal(for desktop) or seperate page(for mobile).
18+
You can make use of `@sendbird/uikit-react/CreateChannel` component for this.
19+
20+
## How to run
21+
22+
Clone only this sub directory
23+
Donot download the entire UIKit for React repository
24+
25+
Set desired appId in `src/App.tsx`
26+
27+
Make sure you have nodejs@18 installed
28+
29+
```bash
30+
npm install
31+
npm run dev
32+
```
33+

samples/router/package-lock.json

Lines changed: 442 additions & 424 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

samples/router/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13-
"@sendbird/uikit-react": "^3.4.8",
13+
"@sendbird/chat": "^4.9.2",
14+
"@sendbird/uikit-react": "^3.5.1",
1415
"react": "^18.2.0",
1516
"react-dom": "^18.2.0",
16-
"react-router-dom": "^6.11.2"
17+
"react-router-dom": "^6.13.0"
1718
},
1819
"devDependencies": {
1920
"@types/react": "^18.0.37",

samples/router/src/App.css

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.sendbird-chat-desktop {
2+
height: 100vh;
3+
display: grid;
4+
grid-template-columns: 320px 1fr;
5+
}
6+
7+
.sendbird-chat-desktop__channel-list {
8+
grid-column: 1;
9+
}
10+
11+
.sendbird-chat-desktop__channel {
12+
grid-column: 2;
13+
display: grid;
14+
grid-template-columns: 1fr;
15+
}
16+
17+
.sendbird-chat-desktop__channel-settings,
18+
.sendbird-chat-desktop__channel-message-search {
19+
grid-column: 2;
20+
width: 320px;
21+
}
22+
23+
.sendbird-chat-desktop__channel-list,
24+
.sendbird-chat-desktop__channel,
25+
.sendbird-chat-desktop__channel-settings,
26+
.sendbird-chat-desktop__channel-message-search {
27+
height: 100%;
28+
}

samples/router/src/App.tsx

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,21 @@
1-
import '@sendbird/uikit-react/dist/index.css'
1+
import './App.css'
22

33
import SendbirdProvider from '@sendbird/uikit-react/SendbirdProvider'
4-
import {
5-
createBrowserRouter,
6-
RouterProvider,
7-
} from 'react-router-dom'
8-
9-
import { ErrorPage } from './routes/Error'
10-
import { ChannelList } from './routes/ChannelList'
11-
import { Channel } from './routes/Channel'
12-
import { ChannelSettings } from './routes/ChannelSettings'
13-
import { MessageSearch } from './routes/MessageSearch'
14-
15-
const router = createBrowserRouter([
16-
{
17-
path: '/',
18-
element: <ChannelList />,
19-
errorElement: <ErrorPage />,
20-
},
21-
{
22-
path: 'channel/:channelUrl',
23-
element: <Channel />,
24-
},
25-
{
26-
path: 'channel/:channelUrl/settings',
27-
element: <ChannelSettings />,
28-
},
29-
{
30-
path: 'channel/:channelUrl/search',
31-
element: <MessageSearch />,
32-
},
33-
])
4+
import { RouterProvider } from 'react-router-dom'
5+
import { router as mobileRouter } from './MobileLayout/Router'
6+
import { router as desktopRouter } from './DesktopLayout/Router'
347

358
function App() {
9+
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
3610
return (
3711
<div className="sendbird-app">
3812
<SendbirdProvider
39-
appId={import.meta.env.VITE_SB_APP_ID}
40-
userId='sendbird'
41-
nickname='sendbird'
13+
appId="YOUR_APP_ID"
14+
userId='YOUR_USER_ID'
15+
nickname='YOUR_NICKNAME'
16+
breakpoint={isMobile}
4217
>
43-
<RouterProvider router={router} />
18+
<RouterProvider router={isMobile ? mobileRouter : desktopRouter} />
4419
</SendbirdProvider>
4520
</div>
4621
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import SbChannel from '@sendbird/uikit-react/Channel'
2+
3+
import {
4+
Outlet,
5+
useNavigate,
6+
useParams,
7+
useSearchParams,
8+
} from 'react-router-dom'
9+
10+
export default function Channel() {
11+
const { channelUrl } = useParams()
12+
const [searchParams] = useSearchParams()
13+
const messageId = searchParams.get('messageId')
14+
const createdAt = searchParams.get('createdAt')
15+
const numCreatedAt = Number(createdAt)
16+
const navigate = useNavigate()
17+
return (
18+
<div className='sendbird-chat-desktop__channel'>
19+
<SbChannel
20+
channelUrl={channelUrl as string}
21+
onBackClick={() => {
22+
navigate('/')
23+
}}
24+
onSearchClick={() => {
25+
navigate(`/channels/${channelUrl}/search`)
26+
}}
27+
{ ...(messageId && typeof numCreatedAt === 'number') && {
28+
startingPoint: numCreatedAt,
29+
highlightedMessageId: messageId,
30+
animatedMessageId: messageId,
31+
}}
32+
showSearchIcon
33+
onChatHeaderActionClick={() => {
34+
navigate(`/channels/${channelUrl}/settings`)
35+
}}
36+
/>
37+
<Outlet />
38+
</div>
39+
)
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import SbChannel from '@sendbird/uikit-react/Channel'
2+
import SbChannelList from '@sendbird/uikit-react/ChannelList'
3+
import {
4+
Outlet,
5+
useNavigate,
6+
useParams,
7+
} from 'react-router-dom'
8+
9+
import { useNavigateOnBan } from '../hooks/useNavigateOnBan'
10+
11+
export default function ChannelList() {
12+
const navigate = useNavigate()
13+
const { channelUrl } = useParams()
14+
15+
useNavigateOnBan()
16+
17+
return (
18+
<div className='sendbird-chat-desktop'>
19+
<div className='sendbird-chat-desktop__channel-list'>
20+
<SbChannelList
21+
disableAutoSelect
22+
onChannelSelect={(channel) => {
23+
navigate(`/channels/${channel.url}`)
24+
}}
25+
/>
26+
</div>
27+
{
28+
// An empty channel!
29+
// You might want to implement a custom placeholder instead
30+
!channelUrl && (
31+
<SbChannel
32+
channelUrl=''
33+
/>
34+
)
35+
}
36+
<Outlet />
37+
</div>
38+
)
39+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import SbChannelSettings from "@sendbird/uikit-react/ChannelSettings"
2+
import { useNavigate, useParams } from "react-router-dom"
3+
4+
export default function ChannelSettings() {
5+
const { channelUrl } = useParams()
6+
const navigate = useNavigate()
7+
return (
8+
<div className='sendbird-chat-desktop__channel-settings'>
9+
<SbChannelSettings
10+
channelUrl={channelUrl as string}
11+
onCloseClick={() => {
12+
navigate(`/channels/${channelUrl}`)
13+
}}
14+
onLeaveChannel={() => {
15+
navigate('/')
16+
}}
17+
/>
18+
</div>
19+
)
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import SbMessageSearch from "@sendbird/uikit-react/MessageSearch"
2+
import { useNavigate, useParams } from "react-router-dom"
3+
4+
export default function MessageSearch() {
5+
const { channelUrl } = useParams()
6+
const navigate = useNavigate()
7+
return (
8+
<div className='sendbird-chat-desktop__channel-message-search'>
9+
<SbMessageSearch
10+
channelUrl={channelUrl as string}
11+
onCloseClick={() => {
12+
navigate(`/channels/${channelUrl}`)
13+
}}
14+
onResultClick={(message) => {
15+
navigate(`/channels/${channelUrl}?messageId=${message?.messageId}&createdAt=${message?.createdAt}`)
16+
}}
17+
/>
18+
</div>
19+
)
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Route, createBrowserRouter, createRoutesFromElements } from 'react-router-dom'
2+
3+
import Channel from './Channel'
4+
import ChannelSettings from './ChannelSettings'
5+
import MessageSearch from './MessageSearch'
6+
import ChannelList from './ChannelList'
7+
8+
export const router = createBrowserRouter(
9+
createRoutesFromElements(
10+
<Route path="/" element={<ChannelList />}>
11+
<Route path="channels/:channelUrl" element={<Channel />}>
12+
<Route path='settings' element={<ChannelSettings />} />
13+
<Route path='search' element={<MessageSearch />} />
14+
</Route>
15+
</Route>
16+
)
17+
)

0 commit comments

Comments
 (0)