Add TimelineItem large layout base
This commit is contained in:
parent
8a04fad0d7
commit
b15eb9fa91
@ -103,5 +103,6 @@ dependencies {
|
||||
|
||||
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.9.0'
|
||||
|
||||
implementation "com.github.skydoves:landscapist-coil:2.2.2"
|
||||
implementation "io.coil-kt:coil:2.4.0"
|
||||
implementation "io.coil-kt:coil-compose:2.4.0"
|
||||
}
|
@ -9,9 +9,7 @@ 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) {
|
||||
@ -22,11 +20,11 @@ fun FeedItem(feed: Feed) {
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
) {
|
||||
CoilImage(imageRequest = {
|
||||
/*CoilImage(imageRequest = {
|
||||
ImageRequest.Builder(context)
|
||||
.data(feed.url)
|
||||
.build()
|
||||
})
|
||||
})*/
|
||||
|
||||
Text(
|
||||
text = feed.name!!,
|
||||
|
@ -1,73 +1,152 @@
|
||||
package com.readrops.app.compose.timelime
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Add
|
||||
import androidx.compose.material.icons.outlined.FavoriteBorder
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
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.api.utils.DateUtils
|
||||
import com.readrops.app.compose.R
|
||||
import com.readrops.app.compose.utils.theme.ShortSpacer
|
||||
import com.readrops.app.compose.utils.theme.VeryShortSpacer
|
||||
import com.readrops.app.compose.utils.theme.spacing
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun TimelineItem(
|
||||
itemWithFeed: ItemWithFeed,
|
||||
onClick: () -> Unit,
|
||||
onFavorite: () -> Unit,
|
||||
onReadLater: () -> Unit,
|
||||
onShare: () -> Unit
|
||||
) {
|
||||
Card(
|
||||
// elevation = 4.card,
|
||||
modifier = Modifier.background(Color.White)
|
||||
.padding(8.dp)
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
PaddingValues(
|
||||
horizontal = MaterialTheme.spacing.shortSpacing,
|
||||
vertical = MaterialTheme.spacing.veryShortSpacing
|
||||
)
|
||||
)
|
||||
.clickable { onClick() }
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MaterialTheme.spacing.shortSpacing,
|
||||
end = MaterialTheme.spacing.shortSpacing,
|
||||
top = MaterialTheme.spacing.shortSpacing,
|
||||
)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
/* Icon(
|
||||
painter = painterResource(id = com.readrops.app.R.drawable.ic_rss_feed_grey),
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_rss_feed_grey),
|
||||
contentDescription = null,
|
||||
// modifier = Modifier.size((MaterialTheme.typography.subtitle2.fontSize.value * 1.5).dp)
|
||||
)*/
|
||||
|
||||
// Spacer(Modifier.padding(4.dp))
|
||||
|
||||
Text(
|
||||
text = "feed name",
|
||||
//style = MaterialTheme.typography.
|
||||
modifier = Modifier.size(MaterialTheme.typography.labelLarge.fontSize.value.dp)
|
||||
)
|
||||
|
||||
VeryShortSpacer()
|
||||
|
||||
Column {
|
||||
Text(
|
||||
text = itemWithFeed.feedName,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
VeryShortSpacer()
|
||||
|
||||
if (itemWithFeed.folder != null) {
|
||||
Text(
|
||||
text = itemWithFeed.folder!!.name!!,
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "Item date",
|
||||
// style = MaterialTheme.typography.subtitle2
|
||||
text = DateUtils.formattedDateByLocal(itemWithFeed.item.pubDate!!),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.size(8.dp))
|
||||
ShortSpacer()
|
||||
|
||||
Text(
|
||||
text = "title example",
|
||||
//style = MaterialTheme.typography.h5,
|
||||
text = itemWithFeed.item.title!!,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.shortSpacing)
|
||||
)
|
||||
|
||||
Spacer(Modifier.size(8.dp))
|
||||
ShortSpacer()
|
||||
|
||||
/* Image(
|
||||
painter = painterResource(id = com.readrops.app.R.drawable.header_background),
|
||||
contentDescription = null
|
||||
)*/
|
||||
if (itemWithFeed.item.imageLink != null) {
|
||||
AsyncImage(
|
||||
model = itemWithFeed.item.imageLink,
|
||||
contentDescription = itemWithFeed.item.title!!,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.aspectRatio(3f / 2f)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(MaterialTheme.spacing.shortSpacing)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.FavoriteBorder,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.clickable { onFavorite() }
|
||||
)
|
||||
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Add, // placeholder icon
|
||||
contentDescription = null,
|
||||
modifier = Modifier.clickable { onReadLater() }
|
||||
)
|
||||
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Share,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.clickable { onShare() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -65,16 +65,21 @@ object TimelineTab : Tab {
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
) {
|
||||
when (state) {
|
||||
is TimelineState.LoadedState -> {
|
||||
val items = (state as TimelineState.LoadedState).items
|
||||
is TimelineState.Loaded -> {
|
||||
val items = (state as TimelineState.Loaded).items
|
||||
|
||||
if (items.isNotEmpty()) {
|
||||
LazyColumn {
|
||||
items(
|
||||
items = items
|
||||
) {
|
||||
items = items,
|
||||
key = { it.item.id },
|
||||
) { itemWithFeed ->
|
||||
TimelineItem(
|
||||
onClick = { navigator.push(ItemScreen()) }
|
||||
itemWithFeed = itemWithFeed,
|
||||
onClick = { navigator.push(ItemScreen()) },
|
||||
onFavorite = {},
|
||||
onReadLater = {},
|
||||
onShare = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package com.readrops.app.compose.timelime
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.readrops.app.compose.base.TabViewModel
|
||||
import com.readrops.db.Database
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import com.readrops.db.queries.ItemsQueryBuilder
|
||||
import com.readrops.db.queries.QueryFilters
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@ -14,7 +16,7 @@ class TimelineViewModel(
|
||||
private val database: Database,
|
||||
) : TabViewModel(database) {
|
||||
|
||||
private val _timelineState = MutableStateFlow<TimelineState>(TimelineState.InitialState)
|
||||
private val _timelineState = MutableStateFlow<TimelineState>(TimelineState.Loading)
|
||||
val timelineState = _timelineState.asStateFlow()
|
||||
|
||||
private var _isRefreshing = MutableStateFlow(false)
|
||||
@ -22,10 +24,12 @@ class TimelineViewModel(
|
||||
|
||||
init {
|
||||
viewModelScope.launch(context = Dispatchers.IO) {
|
||||
database.newItemDao().selectAll()
|
||||
.catch { _timelineState.value = TimelineState.ErrorState(Exception(it)) }
|
||||
val query = ItemsQueryBuilder.buildItemsQuery(QueryFilters(accountId = 1))
|
||||
|
||||
database.newItemDao().selectAll(query)
|
||||
.catch { _timelineState.value = TimelineState.Error(Exception(it)) }
|
||||
.collect {
|
||||
_timelineState.value = TimelineState.LoadedState(it)
|
||||
_timelineState.value = TimelineState.Loaded(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,13 +46,13 @@ class TimelineViewModel(
|
||||
}
|
||||
|
||||
override fun invalidate() {
|
||||
refreshTimeline()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TimelineState {
|
||||
object InitialState : TimelineState()
|
||||
data class ErrorState(val exception: Exception) : TimelineState()
|
||||
data class LoadedState(val items: List<Item>) : TimelineState()
|
||||
object Loading : TimelineState()
|
||||
data class Error(val exception: Exception) : TimelineState()
|
||||
data class Loaded(val items: List<ItemWithFeed>) : TimelineState()
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,20 @@
|
||||
package com.readrops.db.dao.newdao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import androidx.room.RawQuery
|
||||
import androidx.sqlite.db.SupportSQLiteQuery
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.entities.ItemState
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class NewItemDao : NewBaseDao<Item> {
|
||||
|
||||
@Query("Select * From Item")
|
||||
abstract fun selectAll(): Flow<List<Item>>
|
||||
@RawQuery(observedEntities = [Item::class, Feed::class, Folder::class, ItemState::class])
|
||||
abstract fun selectAll(query: SupportSQLiteQuery): Flow<List<ItemWithFeed>>
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user