diff --git a/appcompose/build.gradle b/appcompose/build.gradle index 2fb960d3..9f1b1783 100644 --- a/appcompose/build.gradle +++ b/appcompose/build.gradle @@ -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" } \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/ComposeAppModule.kt b/appcompose/src/main/java/com/readrops/app/compose/ComposeAppModule.kt index 685890c3..e8db3def 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/ComposeAppModule.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/ComposeAppModule.kt @@ -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 diff --git a/appcompose/src/main/java/com/readrops/app/compose/MainActivity.kt b/appcompose/src/main/java/com/readrops/app/compose/MainActivity.kt index 1ed1d3c5..6edcac87 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/MainActivity.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/MainActivity.kt @@ -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), diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedItem.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedItem.kt new file mode 100644 index 00000000..d4ecfe5f --- /dev/null +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedItem.kt @@ -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 + ) + } +} diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsScreen.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedScreen.kt similarity index 58% rename from appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsScreen.kt rename to appcompose/src/main/java/com/readrops/app/compose/feeds/FeedScreen.kt index 48a7ba2d..ca8f2548 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsScreen.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedScreen.kt @@ -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() + val viewModel = getViewModel() 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( diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt new file mode 100644 index 00000000..14b26400 --- /dev/null +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt @@ -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.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) : FeedsState() +} \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsViewModel.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsViewModel.kt deleted file mode 100644 index 6f626a68..00000000 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedsViewModel.kt +++ /dev/null @@ -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)) - } - } -} \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt index b5d11f56..471fefca 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt @@ -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 { + @Query("Select * From Feed") + abstract fun selectFeeds(): Flow> + @Query("Select * from Feed Where account_id = :accountId order by name ASC") abstract suspend fun selectFeeds(accountId: Int): List