Display folders and feeds in Drawer
This commit is contained in:
parent
cffc102b20
commit
db2b089533
@ -4,6 +4,7 @@ import com.readrops.app.compose.account.AccountViewModel
|
|||||||
import com.readrops.app.compose.account.selection.AccountSelectionViewModel
|
import com.readrops.app.compose.account.selection.AccountSelectionViewModel
|
||||||
import com.readrops.app.compose.feeds.FeedViewModel
|
import com.readrops.app.compose.feeds.FeedViewModel
|
||||||
import com.readrops.app.compose.repositories.BaseRepository
|
import com.readrops.app.compose.repositories.BaseRepository
|
||||||
|
import com.readrops.app.compose.repositories.GetFoldersWithFeeds
|
||||||
import com.readrops.app.compose.repositories.LocalRSSRepository
|
import com.readrops.app.compose.repositories.LocalRSSRepository
|
||||||
import com.readrops.app.compose.timelime.TimelineViewModel
|
import com.readrops.app.compose.timelime.TimelineViewModel
|
||||||
import com.readrops.db.entities.account.Account
|
import com.readrops.db.entities.account.Account
|
||||||
@ -12,7 +13,7 @@ import org.koin.dsl.module
|
|||||||
|
|
||||||
val composeAppModule = module {
|
val composeAppModule = module {
|
||||||
|
|
||||||
viewModel { TimelineViewModel(get()) }
|
viewModel { TimelineViewModel(get(), get()) }
|
||||||
|
|
||||||
viewModel { FeedViewModel(get()) }
|
viewModel { FeedViewModel(get()) }
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ val composeAppModule = module {
|
|||||||
|
|
||||||
viewModel { AccountViewModel(get()) }
|
viewModel { AccountViewModel(get()) }
|
||||||
|
|
||||||
|
single { GetFoldersWithFeeds(get()) }
|
||||||
|
|
||||||
// repositories
|
// repositories
|
||||||
|
|
||||||
factory<BaseRepository> { (account: Account) ->
|
factory<BaseRepository> { (account: Account) ->
|
||||||
|
@ -39,6 +39,7 @@ import com.google.accompanist.swiperefresh.SwipeRefresh
|
|||||||
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
|
||||||
import com.readrops.app.compose.R
|
import com.readrops.app.compose.R
|
||||||
import com.readrops.app.compose.item.ItemScreen
|
import com.readrops.app.compose.item.ItemScreen
|
||||||
|
import com.readrops.app.compose.timelime.drawer.TimelineDrawer
|
||||||
import com.readrops.app.compose.util.theme.spacing
|
import com.readrops.app.compose.util.theme.spacing
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.androidx.compose.getViewModel
|
import org.koin.androidx.compose.getViewModel
|
||||||
@ -78,6 +79,7 @@ object TimelineTab : Tab {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val closeDrawer = { scope.launch { drawerState.close() } }
|
||||||
ModalNavigationDrawer(
|
ModalNavigationDrawer(
|
||||||
drawerState = drawerState,
|
drawerState = drawerState,
|
||||||
drawerContent = {
|
drawerContent = {
|
||||||
@ -85,9 +87,15 @@ object TimelineTab : Tab {
|
|||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
onClickDefaultItem = {
|
onClickDefaultItem = {
|
||||||
viewModel.updateDrawerDefaultItem(it)
|
viewModel.updateDrawerDefaultItem(it)
|
||||||
scope.launch {
|
closeDrawer()
|
||||||
drawerState.close()
|
},
|
||||||
}
|
onFolderClick = {
|
||||||
|
viewModel.updateDrawerFolderSelection(it)
|
||||||
|
closeDrawer()
|
||||||
|
},
|
||||||
|
onFeedClick = {
|
||||||
|
viewModel.updateDrawerFeedSelection(it)
|
||||||
|
closeDrawer()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package com.readrops.app.compose.timelime
|
|||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.readrops.app.compose.base.TabViewModel
|
import com.readrops.app.compose.base.TabViewModel
|
||||||
|
import com.readrops.app.compose.repositories.GetFoldersWithFeeds
|
||||||
|
import com.readrops.app.compose.timelime.drawer.DrawerDefaultItemsSelection
|
||||||
import com.readrops.db.Database
|
import com.readrops.db.Database
|
||||||
import com.readrops.db.entities.Feed
|
import com.readrops.db.entities.Feed
|
||||||
import com.readrops.db.entities.Folder
|
import com.readrops.db.entities.Folder
|
||||||
@ -11,6 +13,8 @@ import com.readrops.db.queries.ItemsQueryBuilder
|
|||||||
import com.readrops.db.queries.QueryFilters
|
import com.readrops.db.queries.QueryFilters
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
@ -21,6 +25,7 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
class TimelineViewModel(
|
class TimelineViewModel(
|
||||||
private val database: Database,
|
private val database: Database,
|
||||||
|
private val getFoldersWithFeeds: GetFoldersWithFeeds,
|
||||||
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
|
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||||
) : TabViewModel(database) {
|
) : TabViewModel(database) {
|
||||||
|
|
||||||
@ -38,11 +43,23 @@ class TimelineViewModel(
|
|||||||
accountEvent.consumeAsFlow().collectLatest { account ->
|
accountEvent.consumeAsFlow().collectLatest { account ->
|
||||||
val query = ItemsQueryBuilder.buildItemsQuery(QueryFilters(accountId = account.id))
|
val query = ItemsQueryBuilder.buildItemsQuery(QueryFilters(accountId = account.id))
|
||||||
|
|
||||||
database.newItemDao().selectAll(query)
|
val items = async {
|
||||||
.catch { _timelineState.value = TimelineState.Error(Exception(it)) }
|
database.newItemDao().selectAll(query)
|
||||||
.collect {
|
.catch { _timelineState.value = TimelineState.Error(Exception(it)) }
|
||||||
_timelineState.value = TimelineState.Loaded(it)
|
.collect {
|
||||||
|
_timelineState.value = TimelineState.Loaded(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val drawer = async {
|
||||||
|
_drawerState.update {
|
||||||
|
it.copy(
|
||||||
|
foldersAndFeeds = getFoldersWithFeeds.get(account.id)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
awaitAll(items, drawer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +76,21 @@ class TimelineViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun updateDrawerDefaultItem(selection: DrawerDefaultItemsSelection) {
|
fun updateDrawerDefaultItem(selection: DrawerDefaultItemsSelection) {
|
||||||
_drawerState.update { it.copy(selection = selection) }
|
_drawerState.update {
|
||||||
|
it.copy(
|
||||||
|
selection = selection,
|
||||||
|
selectedFolderId = 0,
|
||||||
|
selectedFeedId = 0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDrawerFolderSelection(folderId: Int) {
|
||||||
|
_drawerState.update { it.copy(selectedFolderId = folderId, selectedFeedId = 0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDrawerFeedSelection(feedId: Int) {
|
||||||
|
_drawerState.update { it.copy(selectedFeedId = feedId, selectedFolderId = 0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +107,8 @@ sealed class TimelineState {
|
|||||||
@Immutable
|
@Immutable
|
||||||
data class DrawerState(
|
data class DrawerState(
|
||||||
val selection: DrawerDefaultItemsSelection = DrawerDefaultItemsSelection.ARTICLES,
|
val selection: DrawerDefaultItemsSelection = DrawerDefaultItemsSelection.ARTICLES,
|
||||||
val folderSelection: Int = 0,
|
val selectedFolderId: Int = 0,
|
||||||
val feedSelection: Int = 0,
|
val selectedFeedId: Int = 0,
|
||||||
val foldersAndFeeds: Map<Folder?, List<Feed>> = emptyMap()
|
val foldersAndFeeds: Map<Folder?, List<Feed>> = emptyMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.readrops.app.compose.timelime.drawer
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.NavigationDrawerItemDefaults
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.readrops.app.compose.util.theme.DrawerSpacing
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DrawerFeedItem(
|
||||||
|
label: @Composable () -> Unit,
|
||||||
|
icon: @Composable () -> Unit,
|
||||||
|
badge: @Composable () -> Unit,
|
||||||
|
selected: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
val colors = NavigationDrawerItemDefaults.colors()
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
selected = selected,
|
||||||
|
onClick = onClick,
|
||||||
|
color = colors.containerColor(selected = selected).value,
|
||||||
|
shape = CircleShape,
|
||||||
|
modifier = modifier
|
||||||
|
.height(36.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(start = 16.dp, end = 24.dp)
|
||||||
|
) {
|
||||||
|
val iconColor = colors.iconColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)
|
||||||
|
|
||||||
|
DrawerSpacing()
|
||||||
|
|
||||||
|
Box(Modifier.weight(1f)) {
|
||||||
|
val labelColor = colors.textColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides labelColor, content = label)
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawerSpacing()
|
||||||
|
|
||||||
|
val badgeColor = colors.badgeColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides badgeColor, content = badge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
package com.readrops.app.compose.timelime.drawer
|
||||||
|
|
||||||
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.animation.core.LinearOutSlowInEasing
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.NavigationDrawerItemDefaults
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.rotate
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.readrops.app.compose.R
|
||||||
|
import com.readrops.app.compose.util.theme.DrawerSpacing
|
||||||
|
import com.readrops.db.entities.Feed
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DrawerFolderItem(
|
||||||
|
label: @Composable () -> Unit,
|
||||||
|
icon: @Composable () -> Unit,
|
||||||
|
badge: @Composable () -> Unit,
|
||||||
|
selected: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
feeds: List<Feed>,
|
||||||
|
selectedFeed: Int,
|
||||||
|
onFeedClick: (Int) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
val colors = NavigationDrawerItemDefaults.colors()
|
||||||
|
|
||||||
|
var isExpanded by remember { mutableStateOf(false) }
|
||||||
|
val rotationState by animateFloatAsState(
|
||||||
|
targetValue = if (isExpanded) 180f else 0f,
|
||||||
|
label = "drawer item arrow rotation"
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.animateContentSize(
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = 300,
|
||||||
|
easing = LinearOutSlowInEasing,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
selected = selected,
|
||||||
|
onClick = onClick,
|
||||||
|
color = colors.containerColor(selected = selected).value,
|
||||||
|
shape = CircleShape,
|
||||||
|
modifier = modifier
|
||||||
|
.height(56.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.animateContentSize(
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = 300,
|
||||||
|
easing = LinearOutSlowInEasing,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(start = 16.dp, end = 24.dp)
|
||||||
|
) {
|
||||||
|
val iconColor = colors.iconColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)
|
||||||
|
|
||||||
|
DrawerSpacing()
|
||||||
|
|
||||||
|
Box(Modifier.weight(1f)) {
|
||||||
|
val labelColor = colors.textColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides labelColor, content = label)
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawerSpacing()
|
||||||
|
|
||||||
|
val badgeColor = colors.badgeColor(selected).value
|
||||||
|
CompositionLocalProvider(LocalContentColor provides badgeColor, content = badge)
|
||||||
|
|
||||||
|
DrawerSpacing()
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.ArrowDropDown,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { isExpanded = isExpanded.not() }
|
||||||
|
.rotate(rotationState),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExpanded && feeds.isNotEmpty()) {
|
||||||
|
for (feed in feeds) {
|
||||||
|
DrawerFeedItem(
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = feed.name!!,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
AsyncImage(
|
||||||
|
model = feed.iconUrl,
|
||||||
|
contentDescription = feed.name,
|
||||||
|
placeholder = painterResource(id = R.drawable.ic_folder_grey),
|
||||||
|
modifier = Modifier.size(24.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
badge = { Text(feed.unreadCount.toString()) },
|
||||||
|
selected = feed.id == selectedFeed,
|
||||||
|
onClick = { onFeedClick(feed.id) },
|
||||||
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
package com.readrops.app.compose.timelime
|
package com.readrops.app.compose.timelime.drawer
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Star
|
import androidx.compose.material.icons.filled.Star
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
@ -17,8 +21,11 @@ import androidx.compose.runtime.collectAsState
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import coil.compose.AsyncImage
|
||||||
import com.readrops.app.compose.R
|
import com.readrops.app.compose.R
|
||||||
|
import com.readrops.app.compose.timelime.TimelineViewModel
|
||||||
import com.readrops.app.compose.util.theme.spacing
|
import com.readrops.app.compose.util.theme.spacing
|
||||||
|
|
||||||
enum class DrawerDefaultItemsSelection {
|
enum class DrawerDefaultItemsSelection {
|
||||||
@ -32,10 +39,17 @@ enum class DrawerDefaultItemsSelection {
|
|||||||
fun TimelineDrawer(
|
fun TimelineDrawer(
|
||||||
viewModel: TimelineViewModel,
|
viewModel: TimelineViewModel,
|
||||||
onClickDefaultItem: (DrawerDefaultItemsSelection) -> Unit,
|
onClickDefaultItem: (DrawerDefaultItemsSelection) -> Unit,
|
||||||
|
onFolderClick: (Int) -> Unit,
|
||||||
|
onFeedClick: (Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
val state by viewModel.drawerState.collectAsState()
|
val state by viewModel.drawerState.collectAsState()
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
|
||||||
ModalDrawerSheet {
|
ModalDrawerSheet(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.verticalScroll(scrollState)
|
||||||
|
) {
|
||||||
Spacer(modifier = Modifier.size(MaterialTheme.spacing.drawerSpacing))
|
Spacer(modifier = Modifier.size(MaterialTheme.spacing.drawerSpacing))
|
||||||
|
|
||||||
DrawerDefaultItems(
|
DrawerDefaultItems(
|
||||||
@ -44,6 +58,65 @@ fun TimelineDrawer(
|
|||||||
)
|
)
|
||||||
|
|
||||||
DrawerDivider()
|
DrawerDivider()
|
||||||
|
|
||||||
|
Column {
|
||||||
|
for (folderEntry in state.foldersAndFeeds) {
|
||||||
|
val folder = folderEntry.key
|
||||||
|
|
||||||
|
if (folder != null) {
|
||||||
|
DrawerFolderItem(
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = folder.name!!,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
painterResource(id = R.drawable.ic_folder_grey),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
badge = {
|
||||||
|
Text(folderEntry.value.sumOf { it.unreadCount }.toString())
|
||||||
|
},
|
||||||
|
selected = state.selectedFolderId == folder.id,
|
||||||
|
onClick = { onFolderClick(folder.id) },
|
||||||
|
feeds = folderEntry.value,
|
||||||
|
selectedFeed = state.selectedFeedId,
|
||||||
|
onFeedClick = { onFeedClick(it) },
|
||||||
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val feeds = folderEntry.value
|
||||||
|
|
||||||
|
for (feed in feeds) {
|
||||||
|
DrawerFeedItem(
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = feed.name!!,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
AsyncImage(
|
||||||
|
model = feed.iconUrl,
|
||||||
|
contentDescription = feed.name,
|
||||||
|
placeholder = painterResource(id = R.drawable.ic_folder_grey),
|
||||||
|
modifier = Modifier.size(24.dp)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
badge = { Text(feed.unreadCount.toString()) },
|
||||||
|
selected = feed.id == state.selectedFeedId,
|
||||||
|
onClick = { onFeedClick(feed.id) },
|
||||||
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,3 +40,6 @@ fun LargeSpacer() = Spacer(Modifier.size(MaterialTheme.spacing.largeSpacing))
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VeryLargeSpacer() = Spacer(Modifier.size(MaterialTheme.spacing.veryLargeSpacing))
|
fun VeryLargeSpacer() = Spacer(Modifier.size(MaterialTheme.spacing.veryLargeSpacing))
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DrawerSpacing() = Spacer(Modifier.size(MaterialTheme.spacing.drawerSpacing))
|
Loading…
x
Reference in New Issue
Block a user