Add basic feed list in FeedScreen

This commit is contained in:
Shinokuni 2023-07-27 17:37:36 +02:00
parent d76200e292
commit 5c7f86b170
8 changed files with 122 additions and 26 deletions

View File

@ -97,4 +97,6 @@ dependencies {
androidTestImplementation "io.insert-koin:koin-test:$rootProject.ext.koin_version"
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.9.0'
implementation "com.github.skydoves:landscapist-coil:2.2.2"
}

View File

@ -1,6 +1,6 @@
package com.readrops.app.compose
import com.readrops.app.compose.feeds.FeedsViewModel
import com.readrops.app.compose.feeds.FeedViewModel
import com.readrops.app.compose.repositories.BaseRepository
import com.readrops.app.compose.repositories.LocalRSSRepository
import com.readrops.app.compose.timelime.TimelineViewModel
@ -13,7 +13,7 @@ val composeAppModule = module {
viewModel { TimelineViewModel(get(), get()) }
viewModel { FeedsViewModel(get()) }
viewModel { FeedViewModel(get(), get()) }
// repositories

View File

@ -14,7 +14,7 @@ import androidx.compose.ui.res.painterResource
import cafe.adriel.voyager.navigator.CurrentScreen
import cafe.adriel.voyager.navigator.Navigator
import com.readrops.app.compose.account.AccountScreen
import com.readrops.app.compose.feeds.FeedsScreen
import com.readrops.app.compose.feeds.FeedScreen
import com.readrops.app.compose.more.MoreScreen
import com.readrops.app.compose.timelime.TimelineScreen
@ -44,7 +44,7 @@ class MainActivity : ComponentActivity() {
NavigationBarItem(
selected = false,
onClick = { navigator.push(FeedsScreen()) },
onClick = { navigator.push(FeedScreen()) },
icon = {
Icon(
painter = painterResource(R.drawable.ic_rss_feed_grey),

View File

@ -0,0 +1,36 @@
package com.readrops.app.compose.feeds
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import coil.request.ImageRequest
import com.readrops.db.entities.Feed
import com.skydoves.landscapist.coil.CoilImage
@Composable
fun FeedItem(feed: Feed) {
val context = LocalContext.current
Column(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
CoilImage(imageRequest = {
ImageRequest.Builder(context)
.data(feed.url)
.build()
})
Text(
text = feed.name!!,
style = MaterialTheme.typography.headlineSmall
)
}
}

View File

@ -3,11 +3,14 @@ package com.readrops.app.compose.feeds
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -18,13 +21,15 @@ import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.androidx.AndroidScreen
import org.koin.androidx.compose.getViewModel
class FeedsScreen : AndroidScreen() {
class FeedScreen : AndroidScreen() {
@Composable
override fun Content() {
val viewModel = getViewModel<FeedsViewModel>()
val viewModel = getViewModel<FeedViewModel>()
var showDialog by remember { mutableStateOf(false) }
val state by viewModel.feedsState.collectAsState()
if (showDialog) {
AddFeedDialog(
onDismiss = { showDialog = false },
@ -38,10 +43,36 @@ class FeedsScreen : AndroidScreen() {
Box(
modifier = Modifier.fillMaxSize()
) {
when (state) {
is FeedsState.LoadedState -> {
val feeds = (state as FeedsState.LoadedState).feeds
if (feeds.isNotEmpty()) {
LazyColumn {
items(
items = feeds
) { feed ->
FeedItem(
feed = feed,
)
}
}
}
}
is FeedsState.ErrorState -> {
}
else -> {
}
}
FloatingActionButton(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(16.dp),
.align(Alignment.BottomEnd)
.padding(16.dp),
onClick = { showDialog = true }
) {
Icon(

View File

@ -0,0 +1,41 @@
package com.readrops.app.compose.feeds
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.readrops.app.compose.repositories.BaseRepository
import com.readrops.db.Database
import com.readrops.db.entities.Feed
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.launch
class FeedViewModel(
private val database: Database,
private val repository: BaseRepository,
) : ViewModel() {
private val _feedsState = MutableStateFlow<FeedsState>(FeedsState.InitialState)
val feedsState = _feedsState.asStateFlow()
init {
viewModelScope.launch(context = Dispatchers.IO) {
database.newFeedDao().selectFeeds()
.catch { _feedsState.value = FeedsState.ErrorState(Exception(it)) }
.collect { _feedsState.value = FeedsState.LoadedState(it) }
}
}
fun insertFeed(url: String) {
viewModelScope.launch(context = Dispatchers.IO) {
repository.insertNewFeeds(listOf(url))
}
}
}
sealed class FeedsState {
object InitialState : FeedsState()
data class ErrorState(val exception: Exception) : FeedsState()
data class LoadedState(val feeds: List<Feed>) : FeedsState()
}

View File

@ -1,18 +0,0 @@
package com.readrops.app.compose.feeds
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.readrops.app.compose.repositories.BaseRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class FeedsViewModel(
private val repository: BaseRepository,
) : ViewModel() {
fun insertFeed(url: String) {
viewModelScope.launch(context = Dispatchers.IO) {
repository.insertNewFeeds(listOf(url))
}
}
}

View File

@ -3,10 +3,14 @@ package com.readrops.db.dao.newdao
import androidx.room.Dao
import androidx.room.Query
import com.readrops.db.entities.Feed
import kotlinx.coroutines.flow.Flow
@Dao
abstract class NewFeedDao : NewBaseDao<Feed> {
@Query("Select * From Feed")
abstract fun selectFeeds(): Flow<List<Feed>>
@Query("Select * from Feed Where account_id = :accountId order by name ASC")
abstract suspend fun selectFeeds(accountId: Int): List<Feed>