1616
1717package com.example.reply.ui
1818
19- import androidx.compose.animation.AnimatedVisibility
20- import androidx.compose.foundation.background
21- import androidx.compose.foundation.layout.Arrangement
22- import androidx.compose.foundation.layout.Column
23- import androidx.compose.foundation.layout.Row
24- import androidx.compose.foundation.layout.fillMaxHeight
2519import androidx.compose.foundation.layout.fillMaxSize
26- import androidx.compose.foundation.layout.fillMaxWidth
27- import androidx.compose.foundation.layout.padding
28- import androidx.compose.foundation.layout.wrapContentWidth
29- import androidx.compose.material.icons.Icons
30- import androidx.compose.material.icons.filled.Article
31- import androidx.compose.material.icons.filled.Chat
32- import androidx.compose.material.icons.filled.Inbox
33- import androidx.compose.material.icons.filled.Menu
34- import androidx.compose.material.icons.filled.MenuOpen
35- import androidx.compose.material.icons.outlined.Chat
36- import androidx.compose.material.icons.outlined.People
37- import androidx.compose.material.icons.outlined.Videocam
38- import androidx.compose.material3.DrawerValue
39- import androidx.compose.material3.ExperimentalMaterial3Api
4020import androidx.compose.material3.Icon
41- import androidx.compose.material3.IconButton
42- import androidx.compose.material3.MaterialTheme
43- import androidx.compose.material3.ModalDrawerSheet
44- import androidx.compose.material3.ModalNavigationDrawer
45- import androidx.compose.material3.NavigationBar
46- import androidx.compose.material3.NavigationBarItem
47- import androidx.compose.material3.NavigationDrawerItem
48- import androidx.compose.material3.NavigationDrawerItemDefaults
49- import androidx.compose.material3.NavigationRail
50- import androidx.compose.material3.NavigationRailItem
51- import androidx.compose.material3.PermanentDrawerSheet
52- import androidx.compose.material3.PermanentNavigationDrawer
5321import androidx.compose.material3.Text
54- import androidx.compose.material3.rememberDrawerState
22+ import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
5523import androidx.compose.runtime.Composable
56- import androidx.compose.runtime.rememberCoroutineScope
57- import androidx.compose.ui.Alignment
24+ import androidx.compose.runtime.getValue
25+ import androidx.compose.runtime.mutableStateOf
26+ import androidx.compose.runtime.remember
27+ import androidx.compose.runtime.setValue
5828import androidx.compose.ui.Modifier
59- import androidx.compose.ui.graphics.Color
6029import androidx.compose.ui.res.stringResource
61- import androidx.compose.ui.tooling.preview.Preview
62- import androidx.compose.ui.unit.dp
6330import androidx.window.core.layout.WindowWidthSizeClass
64- import com.example.reply.R
6531import com.example.reply.ui.utils.DevicePosture
6632import com.example.reply.ui.utils.ReplyContentType
67- import com.example.reply.ui.utils.ReplyNavigationType
68- import kotlinx.coroutines.launch
6933
70- @OptIn(ExperimentalMaterial3Api ::class )
7134@Composable
7235fun ReplyApp (
7336 windowSize : WindowWidthSizeClass ,
@@ -81,243 +44,69 @@ fun ReplyApp(
8144 * In the state of folding device If it's half fold in BookPosture we want to avoid content
8245 * at the crease/hinge
8346 */
84- val navigationType: ReplyNavigationType
8547 val contentType: ReplyContentType
8648
8749 when (windowSize) {
8850 WindowWidthSizeClass .COMPACT -> {
89- navigationType = ReplyNavigationType .BOTTOM_NAVIGATION
9051 contentType = ReplyContentType .LIST_ONLY
9152 }
9253 WindowWidthSizeClass .MEDIUM -> {
93- navigationType = ReplyNavigationType .NAVIGATION_RAIL
9454 contentType = if (foldingDevicePosture != DevicePosture .NormalPosture ) {
9555 ReplyContentType .LIST_AND_DETAIL
9656 } else {
9757 ReplyContentType .LIST_ONLY
9858 }
9959 }
10060 WindowWidthSizeClass .EXPANDED -> {
101- navigationType = if (foldingDevicePosture is DevicePosture .BookPosture ) {
102- ReplyNavigationType .NAVIGATION_RAIL
103- } else {
104- ReplyNavigationType .PERMANENT_NAVIGATION_DRAWER
105- }
10661 contentType = ReplyContentType .LIST_AND_DETAIL
10762 }
10863 else -> {
109- navigationType = ReplyNavigationType .BOTTOM_NAVIGATION
11064 contentType = ReplyContentType .LIST_ONLY
11165 }
11266 }
11367
114- ReplyNavigationWrapperUI (navigationType, contentType, replyHomeUIState)
68+ ReplyNavigationWrapperUI (contentType, replyHomeUIState)
11569}
11670
117- @OptIn(ExperimentalMaterial3Api ::class )
11871@Composable
11972private fun ReplyNavigationWrapperUI (
120- navigationType : ReplyNavigationType ,
12173 contentType : ReplyContentType ,
12274 replyHomeUIState : ReplyHomeUIState
12375) {
124- val drawerState = rememberDrawerState(initialValue = DrawerValue .Closed )
125- val scope = rememberCoroutineScope()
126- val selectedDestination = ReplyDestinations .INBOX
127-
128- if (navigationType == ReplyNavigationType .PERMANENT_NAVIGATION_DRAWER ) {
129- PermanentNavigationDrawer (
130- drawerContent = {
131- PermanentDrawerSheet {
132- NavigationDrawerContent (selectedDestination)
133- }
134- }
135- ) {
136- ReplyAppContent (navigationType, contentType, replyHomeUIState)
137- }
138- } else {
139- ModalNavigationDrawer (
140- drawerContent = {
141- ModalDrawerSheet {
142- NavigationDrawerContent (
143- selectedDestination,
144- onDrawerClicked = {
145- scope.launch {
146- drawerState.close()
147- }
148- }
149- )
150- }
151- },
152- drawerState = drawerState
153- ) {
154- ReplyAppContent (
155- navigationType, contentType, replyHomeUIState,
156- onDrawerClicked = {
157- scope.launch {
158- drawerState.open()
159- }
160- }
161- )
162- }
76+ var selectedDestination: ReplyDestination by remember {
77+ mutableStateOf(ReplyDestination .Inbox )
16378 }
164- }
165-
166- @Composable
167- fun ReplyAppContent (
168- navigationType : ReplyNavigationType ,
169- contentType : ReplyContentType ,
170- replyHomeUIState : ReplyHomeUIState ,
171- onDrawerClicked : () -> Unit = {}
172- ) {
173- Row (modifier = Modifier .fillMaxSize()) {
174- AnimatedVisibility (visible = navigationType == ReplyNavigationType .NAVIGATION_RAIL ) {
175- ReplyNavigationRail (
176- onDrawerClicked = onDrawerClicked
177- )
178- }
179- Column (modifier = Modifier
180- .fillMaxSize()
181- .background(MaterialTheme .colorScheme.inverseOnSurface)
182- ) {
183- if (contentType == ReplyContentType .LIST_AND_DETAIL ) {
184- ReplyListAndDetailContent (
185- replyHomeUIState = replyHomeUIState,
186- modifier = Modifier .weight(1f ),
79+ NavigationSuiteScaffold (
80+ navigationSuiteItems = {
81+ ReplyDestination .entries.forEach {
82+ item(
83+ label = { Text (stringResource(it.labelRes)) },
84+ icon = { Icon (it.icon, stringResource(it.labelRes)) },
85+ selected = it == selectedDestination,
86+ onClick = { /* TODO update selection*/ },
18787 )
188- } else {
189- ReplyListOnlyContent (replyHomeUIState = replyHomeUIState, modifier = Modifier .weight(1f ))
190- }
191-
192- AnimatedVisibility (visible = navigationType == ReplyNavigationType .BOTTOM_NAVIGATION ) {
193- ReplyBottomNavigationBar ()
19488 }
19589 }
90+ ) {
91+ ReplyAppContent (contentType, replyHomeUIState)
19692 }
19793}
19894
199- @Composable
200- @Preview
201- fun ReplyNavigationRail (
202- onDrawerClicked : () -> Unit = {},
203- ) {
204- NavigationRail (modifier = Modifier .fillMaxHeight()) {
205- NavigationRailItem (
206- selected = false ,
207- onClick = onDrawerClicked,
208- icon = { Icon (imageVector = Icons .Default .Menu , contentDescription = stringResource(id = R .string.navigation_drawer)) }
209- )
210- NavigationRailItem (
211- selected = true ,
212- onClick = { /* TODO*/ },
213- icon = { Icon (imageVector = Icons .Default .Inbox , contentDescription = stringResource(id = R .string.tab_inbox)) }
214- )
215- NavigationRailItem (
216- selected = false ,
217- onClick = {/* TODO*/ },
218- icon = { Icon (imageVector = Icons .Default .Article , stringResource(id = R .string.tab_article)) }
219- )
220- NavigationRailItem (
221- selected = false ,
222- onClick = { /* TODO*/ },
223- icon = { Icon (imageVector = Icons .Outlined .Chat , stringResource(id = R .string.tab_dm)) }
224- )
225- NavigationRailItem (
226- selected = false ,
227- onClick = { /* TODO*/ },
228- icon = { Icon (imageVector = Icons .Outlined .People , stringResource(id = R .string.tab_groups)) }
229- )
230- }
231- }
232-
233- @Composable
234- @Preview
235- fun ReplyBottomNavigationBar () {
236- NavigationBar (modifier = Modifier .fillMaxWidth()) {
237- NavigationBarItem (
238- selected = true ,
239- onClick = { /* TODO*/ },
240- icon = { Icon (imageVector = Icons .Default .Inbox , contentDescription = stringResource(id = R .string.tab_inbox)) }
241- )
242- NavigationBarItem (
243- selected = false ,
244- onClick = { /* TODO*/ },
245- icon = { Icon (imageVector = Icons .Default .Article , contentDescription = stringResource(id = R .string.tab_inbox)) }
246- )
247- NavigationBarItem (
248- selected = false ,
249- onClick = { /* TODO*/ },
250- icon = { Icon (imageVector = Icons .Outlined .Chat , contentDescription = stringResource(id = R .string.tab_inbox)) }
251- )
252- NavigationBarItem (
253- selected = false ,
254- onClick = { /* TODO*/ },
255- icon = { Icon (imageVector = Icons .Outlined .Videocam , contentDescription = stringResource(id = R .string.tab_inbox)) }
256- )
257- }
258- }
25995
260- @OptIn(ExperimentalMaterial3Api ::class )
26196@Composable
262- fun NavigationDrawerContent (
263- selectedDestination : String ,
264- modifier : Modifier = Modifier ,
265- onDrawerClicked : () -> Unit = {}
97+ fun ReplyAppContent (
98+ contentType : ReplyContentType ,
99+ replyHomeUIState : ReplyHomeUIState ,
266100) {
267- Column (
268- modifier
269- .wrapContentWidth()
270- .fillMaxHeight()
271- .background(MaterialTheme .colorScheme.inverseOnSurface)
272- .padding(24 .dp)
273- ) {
274- Row (
275- modifier = modifier
276- .fillMaxWidth()
277- .padding(16 .dp),
278- horizontalArrangement = Arrangement .SpaceBetween ,
279- verticalAlignment = Alignment .CenterVertically
280- ) {
281- Text (
282- text = stringResource(id = R .string.app_name).uppercase(),
283- style = MaterialTheme .typography.titleMedium,
284- color = MaterialTheme .colorScheme.primary
285- )
286- IconButton (onClick = onDrawerClicked) {
287- Icon (
288- imageVector = Icons .Default .MenuOpen ,
289- contentDescription = stringResource(id = R .string.navigation_drawer)
290- )
291- }
292- }
293-
294- NavigationDrawerItem (
295- selected = selectedDestination == ReplyDestinations .INBOX ,
296- label = { Text (text = stringResource(id = R .string.tab_inbox), modifier = Modifier .padding(horizontal = 16 .dp)) },
297- icon = { Icon (imageVector = Icons .Default .Inbox , contentDescription = stringResource(id = R .string.tab_inbox)) },
298- colors = NavigationDrawerItemDefaults .colors(unselectedContainerColor = Color .Transparent ),
299- onClick = { /* TODO*/ }
300- )
301- NavigationDrawerItem (
302- selected = selectedDestination == ReplyDestinations .ARTICLES ,
303- label = { Text (text = stringResource(id = R .string.tab_article), modifier = Modifier .padding(horizontal = 16 .dp)) },
304- icon = { Icon (imageVector = Icons .Default .Article , contentDescription = stringResource(id = R .string.tab_article)) },
305- colors = NavigationDrawerItemDefaults .colors(unselectedContainerColor = Color .Transparent ),
306- onClick = { /* TODO*/ }
101+ if (contentType == ReplyContentType .LIST_AND_DETAIL ) {
102+ ReplyListAndDetailContent (
103+ replyHomeUIState = replyHomeUIState,
104+ modifier = Modifier .fillMaxSize(),
307105 )
308- NavigationDrawerItem (
309- selected = selectedDestination == ReplyDestinations .DM ,
310- label = { Text (text = stringResource(id = R .string.tab_dm), modifier = Modifier .padding(horizontal = 16 .dp)) },
311- icon = { Icon (imageVector = Icons .Default .Chat , contentDescription = stringResource(id = R .string.tab_dm)) },
312- colors = NavigationDrawerItemDefaults .colors(unselectedContainerColor = Color .Transparent ),
313- onClick = { /* TODO*/ }
314- )
315- NavigationDrawerItem (
316- selected = selectedDestination == ReplyDestinations .GROUPS ,
317- label = { Text (text = stringResource(id = R .string.tab_groups), modifier = Modifier .padding(horizontal = 16 .dp)) },
318- icon = { Icon (imageVector = Icons .Default .Article , contentDescription = stringResource(id = R .string.tab_groups)) },
319- colors = NavigationDrawerItemDefaults .colors(unselectedContainerColor = Color .Transparent ),
320- onClick = { /* TODO*/ }
106+ } else {
107+ ReplyListOnlyContent (
108+ replyHomeUIState = replyHomeUIState,
109+ modifier = Modifier .fillMaxSize(),
321110 )
322111 }
323112}
0 commit comments