Add articles image preview (#67)

* Add articles image preview

* Lowers the pagingItem state
This commit is contained in:
Ashinch 2022-05-13 23:21:21 +08:00 committed by GitHub
parent 6583f3326c
commit c79649bb77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 464 additions and 65 deletions

View File

@ -28,6 +28,15 @@ android {
vectorDrawables {
useSupportLibrary true
}
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
}
}
flavorDimensions "channel"
@ -103,6 +112,8 @@ dependencies {
implementation("io.coil-kt:coil-svg:$coil")
implementation("io.coil-kt:coil-gif:$coil")
implementation "org.conscrypt:conscrypt-android:2.5.2"
// https://square.github.io/okhttp/changelogs/changelog/
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.6"
implementation "com.squareup.retrofit2:retrofit:$retrofit2"

View File

@ -0,0 +1,321 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "98462c2e9c32394054102313366e7262",
"entities": [
{
"tableName": "account",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `type` INTEGER NOT NULL, `updateAt` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateAt",
"columnName": "updateAt",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "feed",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `icon` TEXT, `url` TEXT NOT NULL, `groupId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `isNotification` INTEGER NOT NULL DEFAULT false, `isFullContent` INTEGER NOT NULL DEFAULT false, PRIMARY KEY(`id`), FOREIGN KEY(`groupId`) REFERENCES `group`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "groupId",
"columnName": "groupId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isNotification",
"columnName": "isNotification",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
},
{
"fieldPath": "isFullContent",
"columnName": "isFullContent",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_feed_groupId",
"unique": false,
"columnNames": [
"groupId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_feed_groupId` ON `${TABLE_NAME}` (`groupId`)"
},
{
"name": "index_feed_accountId",
"unique": false,
"columnNames": [
"accountId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_feed_accountId` ON `${TABLE_NAME}` (`accountId`)"
}
],
"foreignKeys": [
{
"table": "group",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"groupId"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "article",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `date` INTEGER NOT NULL, `title` TEXT NOT NULL, `author` TEXT, `rawDescription` TEXT NOT NULL, `shortDescription` TEXT NOT NULL, `fullContent` TEXT, `img` TEXT, `link` TEXT NOT NULL, `feedId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `isUnread` INTEGER NOT NULL DEFAULT true, `isStarred` INTEGER NOT NULL DEFAULT false, `isReadLater` INTEGER NOT NULL DEFAULT false, PRIMARY KEY(`id`), FOREIGN KEY(`feedId`) REFERENCES `feed`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "rawDescription",
"columnName": "rawDescription",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shortDescription",
"columnName": "shortDescription",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "fullContent",
"columnName": "fullContent",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "img",
"columnName": "img",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "link",
"columnName": "link",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "feedId",
"columnName": "feedId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isUnread",
"columnName": "isUnread",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "true"
},
{
"fieldPath": "isStarred",
"columnName": "isStarred",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
},
{
"fieldPath": "isReadLater",
"columnName": "isReadLater",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "false"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_article_feedId",
"unique": false,
"columnNames": [
"feedId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_article_feedId` ON `${TABLE_NAME}` (`feedId`)"
},
{
"name": "index_article_accountId",
"unique": false,
"columnNames": [
"accountId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_article_accountId` ON `${TABLE_NAME}` (`accountId`)"
}
],
"foreignKeys": [
{
"table": "feed",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"feedId"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "group",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `accountId` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "accountId",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_group_accountId",
"unique": false,
"columnNames": [
"accountId"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_group_accountId` ON `${TABLE_NAME}` (`accountId`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '98462c2e9c32394054102313366e7262')"
]
}
}

View File

@ -5,18 +5,18 @@
<uses-permission android:name="android.permission.INTERNET" />
<!-- Disable automatic updates in F-Droid -->
<!-- <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />-->
<!-- Disable automatic updates in F-Droid -->
<!-- <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />-->
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/read_you"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Reader">
android:theme="@style/Theme.Reader"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true"

View File

@ -29,10 +29,18 @@ import me.ash.reader.data.source.AppNetworkDataSource
import me.ash.reader.data.source.OpmlLocalDataSource
import me.ash.reader.data.source.ReaderDatabase
import me.ash.reader.ui.ext.*
import org.conscrypt.Conscrypt
import java.security.Security
import javax.inject.Inject
@HiltAndroidApp
class App : Application(), Configuration.Provider, ImageLoader {
init {
// From: https://gitlab.com/spacecowboy/Feeder
// Install Conscrypt to handle TLSv1.3 pre Android10
Security.insertProviderAt(Conscrypt.newProvider(), 1)
}
@Inject
lateinit var readerDatabase: ReaderDatabase

View File

@ -374,7 +374,7 @@ interface ArticleDao {
@Query(
"""
SELECT a.id, a.date, a.title, a.author, a.rawDescription,
a.shortDescription, a.fullContent, a.link, a.feedId,
a.shortDescription, a.fullContent, a.img, a.link, a.feedId,
a.accountId, a.isUnread, a.isStarred, a.isReadLater
FROM article AS a
LEFT JOIN feed AS b ON b.id = a.feedId
@ -394,7 +394,7 @@ interface ArticleDao {
@Query(
"""
SELECT a.id, a.date, a.title, a.author, a.rawDescription,
a.shortDescription, a.fullContent, a.link, a.feedId,
a.shortDescription, a.fullContent, a.img, a.link, a.feedId,
a.accountId, a.isUnread, a.isStarred, a.isReadLater
FROM article AS a
LEFT JOIN feed AS b ON b.id = a.feedId
@ -416,7 +416,7 @@ interface ArticleDao {
@Query(
"""
SELECT a.id, a.date, a.title, a.author, a.rawDescription,
a.shortDescription, a.fullContent, a.link, a.feedId,
a.shortDescription, a.fullContent, a.img, a.link, a.feedId,
a.accountId, a.isUnread, a.isStarred, a.isReadLater
FROM article AS a
LEFT JOIN feed AS b ON b.id = a.feedId
@ -483,7 +483,7 @@ interface ArticleDao {
@Query(
"""
SELECT a.id, a.date, a.title, a.author, a.rawDescription,
a.shortDescription, a.fullContent, a.link, a.feedId,
a.shortDescription, a.fullContent, a.img, a.link, a.feedId,
a.accountId, a.isUnread, a.isStarred, a.isReadLater
FROM article AS a LEFT JOIN feed AS b
ON a.feedId = b.id
@ -503,25 +503,19 @@ interface ArticleDao {
)
suspend fun queryById(id: String): ArticleWithFeed?
@Insert
suspend fun insert(article: Article): Long
@Insert
suspend fun insertList(articles: List<Article>): List<Long>
@Update
suspend fun update(vararg article: Article)
@Delete
suspend fun delete(vararg article: Article)
@RewriteQueriesToDropUnusedColumns
@Transaction
@Query(
"""
INSERT INTO article
SELECT :id, :date, :title, :author, :rawDescription,
:shortDescription, :fullContent, :link, :feedId,
:shortDescription, :fullContent, :img, :link, :feedId,
:accountId, :isUnread, :isStarred, :isReadLater
WHERE NOT EXISTS(SELECT 1 FROM article WHERE link = :link AND accountId = :accountId)
"""
@ -534,6 +528,7 @@ interface ArticleDao {
rawDescription: String,
shortDescription: String,
fullContent: String? = null,
img: String? = null,
link: String,
feedId: String,
accountId: Int,
@ -552,6 +547,7 @@ interface ArticleDao {
article.rawDescription,
article.shortDescription,
article.fullContent,
article.img,
article.link,
article.feedId,
article.accountId,

View File

@ -32,6 +32,8 @@ data class Article(
@ColumnInfo
var fullContent: String? = null,
@ColumnInfo
var img: String? = null,
@ColumnInfo
val link: String,
@ColumnInfo(index = true)
val feedId: String,

View File

@ -116,13 +116,23 @@ class RssHelper @Inject constructor(
.trim(),
fullContent = content,
link = it.link ?: "",
)
).apply {
img = findImg(rawDescription)
}
)
}
a
}
}
private fun findImg(rawDescription: String): String? {
// From: https://gitlab.com/spacecowboy/Feeder
// Using negative lookahead to skip data: urls, being inline base64
// And capturing original quote to use as ending quote
val regex = """img.*?src=(["'])((?!data).*?)\1""".toRegex(RegexOption.DOT_MATCHES_ALL)
return regex.find(rawDescription)?.groupValues?.get(2)
}
@Throws(Exception::class)
suspend fun queryRssIcon(
feedDao: FeedDao,

View File

@ -2,6 +2,8 @@ package me.ash.reader.data.source
import android.content.Context
import androidx.room.*
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import me.ash.reader.data.dao.AccountDao
import me.ash.reader.data.dao.ArticleDao
import me.ash.reader.data.dao.FeedDao
@ -14,8 +16,7 @@ import java.util.*
@Database(
entities = [Account::class, Feed::class, Article::class, Group::class],
version = 1,
exportSchema = false,
version = 2,
)
@TypeConverters(ReaderDatabase.Converters::class)
abstract class ReaderDatabase : RoomDatabase() {
@ -33,7 +34,7 @@ abstract class ReaderDatabase : RoomDatabase() {
context.applicationContext,
ReaderDatabase::class.java,
"Reader"
).build().also {
).addMigrations(*allMigrations).build().also {
instance = it
}
}
@ -53,3 +54,18 @@ abstract class ReaderDatabase : RoomDatabase() {
}
}
}
val allMigrations = arrayOf(
MIGRATION_1_2,
)
@Suppress("ClassName")
object MIGRATION_1_2 : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"""
ALTER TABLE article ADD COLUMN img TEXT DEFAULT NULL
""".trimIndent()
)
}
}

View File

@ -3,6 +3,9 @@ package me.ash.reader.ui.component
import androidx.annotation.DrawableRes
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
@ -31,6 +34,31 @@ fun AsyncImage(
@DrawableRes error: Int? = R.drawable.ic_broken_image_black_24dp,
) {
val context = LocalContext.current
val color = MaterialTheme.colorScheme.onSurfaceVariant
val placeholderPainterResource = placeholder?.run { painterResource(this) }
val errorPainterResource = error?.run { painterResource(this) }
val placeholderPainter by remember {
mutableStateOf(
placeholderPainterResource?.run {
forwardingPainter(
painter = this,
colorFilter = ColorFilter.tint(color),
alpha = 0.1f,
)
}
)
}
val errorPainter by remember {
mutableStateOf(
errorPainterResource?.run {
forwardingPainter(
painter = this,
colorFilter = ColorFilter.tint(color),
alpha = 0.1f,
)
}
)
}
coil.compose.AsyncImage(
modifier = modifier,
@ -45,20 +73,8 @@ fun AsyncImage(
contentDescription = contentDescription,
contentScale = contentScale,
imageLoader = context.imageLoader,
placeholder = placeholder?.let {
forwardingPainter(
painter = painterResource(it),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurfaceVariant),
alpha = 0.5f,
)
},
error = error?.let {
forwardingPainter(
painter = painterResource(it),
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onError),
alpha = 0.5f
)
},
placeholder = placeholderPainter,
error = errorPainter,
)
}

View File

@ -1,6 +1,9 @@
package me.ash.reader.ui.ext
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.paging.compose.LazyPagingItems
import kotlin.math.abs
fun LazyListState.calculateTopBarAnimateValue(start: Float, end: Float): Float =
@ -12,3 +15,16 @@ fun LazyListState.calculateTopBarAnimateValue(start: Float, end: Float): Float =
if (start < end) (start + increase).coerceIn(start, end)
else (start - increase).coerceIn(end, start)
}
@Composable
fun <T : Any> LazyPagingItems<T>.rememberLazyListState(): LazyListState {
// After recreation, LazyPagingItems first return 0 items, then the cached items.
// This behavior/issue is resetting the LazyListState scroll position.
// Below is a workaround. More info: https://issuetracker.google.com/issues/177245496.
return when (itemCount) {
// Return a different LazyListState instance.
0 -> remember(this) { LazyListState(0, 0) }
// Return rememberLazyListState (normal case).
else -> androidx.compose.foundation.lazy.rememberLazyListState()
}
}

View File

@ -9,7 +9,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.paging.compose.collectAsLazyPagingItems
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@ -38,11 +37,7 @@ fun HomeEntry(
homeViewModel: HomeViewModel = hiltViewModel(),
) {
val context = LocalContext.current
val viewState = homeViewModel.viewState.collectAsStateValue()
val filterState = homeViewModel.filterState.collectAsStateValue()
val pagingItems = viewState.pagingData.collectAsLazyPagingItems()
val navController = rememberAnimatedNavController()
val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) }
@ -116,7 +111,6 @@ fun HomeEntry(
FlowPage(
navController = navController,
homeViewModel = homeViewModel,
pagingItems = pagingItems,
)
}
animatedComposable(route = "${RouteName.READING}/{articleId}") {

View File

@ -3,7 +3,6 @@ package me.ash.reader.ui.page.home
import androidx.lifecycle.ViewModel
import androidx.paging.*
import androidx.work.WorkManager
import com.google.accompanist.pager.ExperimentalPagerApi
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
@ -17,7 +16,6 @@ import me.ash.reader.data.repository.SyncWorker
import me.ash.reader.ui.page.home.flow.FlowItemView
import javax.inject.Inject
@OptIn(ExperimentalPagerApi::class)
@HiltViewModel
class HomeViewModel @Inject constructor(
private val rssRepository: RssRepository,
@ -112,7 +110,6 @@ data class FilterState(
val filter: Filter = Filter.All,
)
@OptIn(ExperimentalPagerApi::class)
data class HomeViewState(
val pagingData: Flow<PagingData<FlowItemView>> = emptyFlow(),
val searchContent: String = "",

View File

@ -15,13 +15,16 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil.size.Scale
import me.ash.reader.R
import me.ash.reader.data.entity.ArticleWithFeed
import me.ash.reader.data.preference.*
import me.ash.reader.ui.component.AsyncImage
import me.ash.reader.ui.ext.formatAsString
@Composable
@ -40,11 +43,12 @@ fun ArticleItem(
Column(
modifier = Modifier
.padding(horizontal = 12.dp)
.clip(RoundedCornerShape(12.dp))
.clip(RoundedCornerShape(20.dp))
.clickable { onClick(articleWithFeed) }
.padding(horizontal = 12.dp, vertical = 12.dp)
.alpha(if (articleWithFeed.article.isStarred || articleWithFeed.article.isUnread) 1f else 0.5f),
) {
// Upper
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
@ -64,6 +68,7 @@ fun ArticleItem(
)
}
// Right
if (articleListDate.value) {
Row(
verticalAlignment = Alignment.CenterVertically,
@ -95,6 +100,8 @@ fun ArticleItem(
}
}
}
// Lower
Row(
modifier = Modifier.fillMaxWidth(),
) {
@ -108,10 +115,12 @@ fun ArticleItem(
) {}
Spacer(modifier = Modifier.width(10.dp))
}
// Article
Column(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.weight(1f),
) {
// Title
Text(
text = articleWithFeed.article.title,
@ -120,6 +129,7 @@ fun ArticleItem(
maxLines = if (articleListDesc.value) 2 else 4,
overflow = TextOverflow.Ellipsis,
)
// Description
if (articleListDesc.value && articleWithFeed.article.shortDescription.isNotBlank()) {
Text(
@ -131,6 +141,19 @@ fun ArticleItem(
)
}
}
// Image
if (articleWithFeed.article.img != null && articleListImage.value) {
AsyncImage(
modifier = Modifier
.padding(start = 10.dp)
.size(80.dp)
.clip(RoundedCornerShape(20.dp)),
data = articleWithFeed.article.img,
scale = Scale.FILL,
contentScale = ContentScale.Crop,
)
}
}
}
}

View File

@ -2,7 +2,6 @@ package me.ash.reader.ui.page.home.flow
import androidx.activity.compose.BackHandler
import androidx.compose.animation.*
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
@ -22,7 +21,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.ash.reader.R
@ -43,7 +42,6 @@ import me.ash.reader.ui.theme.palette.onDark
@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalFoundationApi::class,
com.google.accompanist.pager.ExperimentalPagerApi::class,
androidx.compose.ui.ExperimentalComposeUiApi::class,
)
@ -52,8 +50,9 @@ fun FlowPage(
navController: NavHostController,
flowViewModel: FlowViewModel = hiltViewModel(),
homeViewModel: HomeViewModel,
pagingItems: LazyPagingItems<FlowItemView>,
) {
val homeViewView = homeViewModel.viewState.collectAsStateValue()
val pagingItems = homeViewView.pagingData.collectAsLazyPagingItems()
val keyboardController = LocalSoftwareKeyboardController.current
val topBarTonalElevation = LocalFlowTopBarTonalElevation.current
val articleListTonalElevation = LocalFlowArticleListTonalElevation.current
@ -177,14 +176,6 @@ fun FlowPage(
)
},
content = {
// if (pagingItems.loadState.source.refresh is LoadState.NotLoading && pagingItems.itemCount == 0) {
// LottieAnimation(
// modifier = Modifier
// .alpha(0.7f)
// .padding(80.dp),
// url = "https://assets7.lottiefiles.com/packages/lf20_l4ny0jjm.json",
// )
// }
SwipeRefresh(
onRefresh = {
if (!isSyncing) {

View File

@ -174,10 +174,13 @@ fun FlowPageStyle(
}
SettingItem(
title = stringResource(R.string.article_images),
enable = false,
onClick = {},
onClick = {
(!articleListImage).put(context, scope)
},
) {
Switch(activated = false, enable = false)
Switch(activated = articleListImage.value) {
(!articleListImage).put(context, scope)
}
}
SettingItem(
title = stringResource(R.string.article_desc),
@ -403,6 +406,7 @@ fun FlowPagePreview(
accountId = 0,
date = Date(),
isStarred = true,
img = "https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1yZWxhdGVkfDJ8fHxlbnwwfHx8fA%3D%3D&auto=format&fit=crop&w=800&q=60"
),
feed = Feed(
id = "",

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config xmlns:tools="http://schemas.android.com/tools">
<base-config
cleartextTrafficPermitted="true"
tools:ignore="InsecureBaseConfiguration" />
</network-security-config>