Add initial drawer with default items

This commit is contained in:
Shinokuni 2023-08-18 22:45:04 +02:00
parent 282e3dd9f8
commit 005858b8cd
4 changed files with 210 additions and 87 deletions

View File

@ -0,0 +1,99 @@
package com.readrops.app.compose.timelime
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.NavigationDrawerItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.readrops.app.compose.R
import com.readrops.app.compose.util.theme.spacing
@Composable
fun TimelineDrawer(
viewModel: TimelineViewModel,
) {
ModalDrawerSheet {
Spacer(modifier = Modifier.size(MaterialTheme.spacing.drawerSpacing))
DrawerDefaultItems()
DrawerDivider()
}
}
@Composable
fun DrawerDefaultItems() {
NavigationDrawerItem(
label = { Text("Articles") },
icon = {
Icon(
painter = painterResource(id = R.drawable.ic_timeline),
contentDescription = null
)
},
selected = true,
onClick = { },
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text("New articles") },
icon = {
Icon(
painter = painterResource(id = R.drawable.ic_new),
contentDescription = null
)
},
selected = false,
onClick = { },
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text("Favorites") },
icon = {
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null
)
},
selected = false,
onClick = { },
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text("To read later") },
icon = {
Icon(
painter = painterResource(id = R.drawable.ic_read_later),
contentDescription = null
)
},
selected = false,
onClick = { },
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
@Composable
fun DrawerDivider() {
Divider(
thickness = 2.dp,
modifier = Modifier.padding(
vertical = MaterialTheme.spacing.drawerSpacing,
horizontal = 28.dp // M3 guidelines
)
)
}

View File

@ -12,17 +12,21 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@ -35,6 +39,7 @@ import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import com.readrops.app.compose.R
import com.readrops.app.compose.item.ItemScreen
import com.readrops.app.compose.util.theme.spacing
import kotlinx.coroutines.launch
import org.koin.androidx.compose.getViewModel
@ -56,102 +61,115 @@ object TimelineTab : Tab {
val state by viewModel.timelineState.collectAsState()
val isRefreshing by viewModel.isRefreshing.collectAsState()
val scrollState = rememberLazyListState()
val swipeToRefreshState = rememberSwipeRefreshState(isRefreshing)
val navigator = LocalNavigator.currentOrThrow
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "Timeline") },
navigationIcon = {
IconButton(onClick = { }) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = null
)
}
},
actions = {
IconButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_filter_list),
contentDescription = null
)
}
val scrollState = rememberLazyListState()
val swipeToRefreshState = rememberSwipeRefreshState(isRefreshing)
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
IconButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_sync),
contentDescription = null
)
}
}
)
},
floatingActionButton = {
FloatingActionButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_done_all),
contentDescription = null
)
}
},
) { paddingValues ->
SwipeRefresh(
state = swipeToRefreshState,
onRefresh = {
viewModel.refreshTimeline()
},
modifier = Modifier.padding(paddingValues)
) {
when (state) {
is TimelineState.Loading -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxSize()
) {
CircularProgressIndicator()
}
}
is TimelineState.Error -> {
}
is TimelineState.Loaded -> {
val items = (state as TimelineState.Loaded).items
if (items.isNotEmpty()) {
LazyColumn(
state = scrollState,
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.shortSpacing)
) {
items(
items = items,
key = { it.item.id },
contentType = { "item_with_feed" }
) { itemWithFeed ->
TimelineItem(
itemWithFeed = itemWithFeed,
onClick = { navigator.push(ItemScreen()) },
onFavorite = {},
onReadLater = {},
onShare = {},
)
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
TimelineDrawer(viewModel = viewModel)
}
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "Articles") },
navigationIcon = {
IconButton(
onClick = {
scope.launch {
drawerState.open()
}
}
) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = null
)
}
},
actions = {
IconButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_filter_list),
contentDescription = null
)
}
IconButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_sync),
contentDescription = null
)
}
}
)
},
floatingActionButton = {
FloatingActionButton(onClick = { }) {
Icon(
painter = painterResource(id = R.drawable.ic_done_all),
contentDescription = null
)
}
},
) { paddingValues ->
SwipeRefresh(
state = swipeToRefreshState,
onRefresh = {
viewModel.refreshTimeline()
},
modifier = Modifier.padding(paddingValues)
) {
when (state) {
is TimelineState.Loading -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxSize()
) {
CircularProgressIndicator()
}
}
is TimelineState.Error -> {
}
is TimelineState.Loaded -> {
val items = (state as TimelineState.Loaded).items
if (items.isNotEmpty()) {
LazyColumn(
state = scrollState,
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.shortSpacing)
) {
items(
items = items,
key = { it.item.id },
contentType = { "item_with_feed" }
) { itemWithFeed ->
TimelineItem(
itemWithFeed = itemWithFeed,
onClick = { navigator.push(ItemScreen()) },
onFavorite = {},
onReadLater = {},
onShare = {},
)
}
}
} else {
NoItemPlaceholder()
}
} else {
NoItemPlaceholder()
}
}
}
}
}
}
}

View File

@ -15,7 +15,8 @@ data class Spacing(
val shortSpacing: Dp = 8.dp,
val mediumSpacing: Dp = 16.dp,
val largeSpacing: Dp = 24.dp,
val veryLargeSpacing: Dp = 48.dp
val veryLargeSpacing: Dp = 48.dp,
val drawerSpacing: Dp = 12.dp
)
val LocalSpacing = compositionLocalOf { Spacing() }

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,4H4C2.89,4 2.01,4.89 2.01,6L2,18c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V6C22,4.89 21.11,4 20,4zM8.5,15H7.3l-2.55,-3.5V15H3.5V9h1.25l2.5,3.5V9H8.5V15zM13.5,10.26H11v1.12h2.5v1.26H11v1.11h2.5V15h-4V9h4V10.26zM20.5,14c0,0.55 -0.45,1 -1,1h-4c-0.55,0 -1,-0.45 -1,-1V9h1.25v4.51h1.13V9.99h1.25v3.51h1.12V9h1.25V14z"/>
</vector>