Fix the synchronization bug when importing OPML files after version 0.8.0 (#92)

This commit is contained in:
Ashinch 2022-06-01 17:29:01 +08:00 committed by GitHub
parent 999fc40a7c
commit 1be4779df2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 59 deletions

View File

@ -494,6 +494,20 @@ interface ArticleDao {
) )
suspend fun queryLatestByFeedId(accountId: Int, feedId: String): Article? suspend fun queryLatestByFeedId(accountId: Int, feedId: String): Article?
@Query(
"""
SELECT * from article
WHERE link = :link
AND feedId = :feedId
AND accountId = :accountId
"""
)
suspend fun queryArticleByLink(
link: String,
feedId: String,
accountId: Int,
): Article?
@Transaction @Transaction
@Query( @Query(
""" """
@ -509,56 +523,17 @@ interface ArticleDao {
@Update @Update
suspend fun update(vararg article: Article) suspend fun update(vararg article: Article)
@RewriteQueriesToDropUnusedColumns
@Transaction @Transaction
@Query( suspend fun insertListIfNotExist(articles: List<Article>): List<Article> {
""" return articles.mapNotNull {
INSERT INTO article if (queryArticleByLink(
SELECT :id, :date, :title, :author, :rawDescription, link = it.link,
:shortDescription, :fullContent, :link, :feedId, feedId = it.feedId,
:accountId, :isUnread, :isStarred, :isReadLater, :img accountId = it.accountId
WHERE NOT EXISTS(SELECT 1 FROM article WHERE link = :link AND accountId = :accountId) ) == null
""" ) it else null
) }.also {
suspend fun insertIfNotExist( insertList(it)
id: String,
date: Date,
title: String,
author: String? = null,
rawDescription: String,
shortDescription: String,
fullContent: String? = null,
img: String? = null,
link: String,
feedId: String,
accountId: Int,
isUnread: Boolean = true,
isStarred: Boolean = false,
isReadLater: Boolean = false,
): Long
@Transaction
suspend fun insertIfNotExist(article: Article): Long {
return insertIfNotExist(
article.id,
article.date,
article.title,
article.author,
article.rawDescription,
article.shortDescription,
article.fullContent,
article.img,
article.link,
article.feedId,
article.accountId,
article.isUnread,
article.isStarred,
article.isReadLater,
)
} }
@Transaction
suspend fun insertIfNotExist(articles: List<Article>): List<Article> {
return articles.mapNotNull { if (insertIfNotExist(it) > 0) it else null }
} }
} }

View File

@ -83,11 +83,11 @@ class LocalRssRepository @Inject constructor(
notificationHelper.notify( notificationHelper.notify(
FeedWithArticle( FeedWithArticle(
it.feedWithArticle.feed, it.feedWithArticle.feed,
articleDao.insertIfNotExist(it.feedWithArticle.articles) articleDao.insertListIfNotExist(it.feedWithArticle.articles)
) )
) )
} else { } else {
articleDao.insertIfNotExist(it.feedWithArticle.articles) articleDao.insertListIfNotExist(it.feedWithArticle.articles)
} }
} }
Log.i("RlOG", "onCompletion: ${System.currentTimeMillis() - preTime}") Log.i("RlOG", "onCompletion: ${System.currentTimeMillis() - preTime}")

View File

@ -33,7 +33,7 @@ fun FeedItem(
feed: Feed, feed: Feed,
alpha: Float = 1f, alpha: Float = 1f,
badgeAlpha: Float = 1f, badgeAlpha: Float = 1f,
isEnded: Boolean = false, isEnded: () -> Boolean,
isExpanded: () -> Boolean, isExpanded: () -> Boolean,
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(), feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
onClick: () -> Unit = {}, onClick: () -> Unit = {},
@ -48,7 +48,7 @@ fun FeedItem(
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
.background( .background(
color = MaterialTheme.colorScheme.secondary.copy(alpha = alpha), color = MaterialTheme.colorScheme.secondary.copy(alpha = alpha),
shape = if (isEnded) ShapeBottom32 else RectangleShape, shape = if (isEnded()) ShapeBottom32 else RectangleShape,
) )
.combinedClickable( .combinedClickable(
onClick = { onClick = {
@ -60,7 +60,7 @@ fun FeedItem(
} }
) )
.padding(horizontal = 14.dp) .padding(horizontal = 14.dp)
.padding(top = 14.dp, bottom = if (isEnded) 22.dp else 14.dp), .padding(top = 14.dp, bottom = if (isEnded()) 22.dp else 14.dp),
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier

View File

@ -218,6 +218,7 @@ fun FeedsPage(
group = groupWithFeed.group, group = groupWithFeed.group,
alpha = groupAlpha, alpha = groupAlpha,
indicatorAlpha = groupIndicatorAlpha, indicatorAlpha = groupIndicatorAlpha,
isEnded = { index == feedsUiState.groupWithFeedList.lastIndex },
onExpanded = { onExpanded = {
groupsVisible[groupWithFeed.group.id] = groupsVisible[groupWithFeed.group.id] =
!(groupsVisible[groupWithFeed.group.id] ?: false) !(groupsVisible[groupWithFeed.group.id] ?: false)
@ -238,7 +239,7 @@ fun FeedsPage(
feed = groupWithFeed.feed, feed = groupWithFeed.feed,
alpha = groupAlpha, alpha = groupAlpha,
badgeAlpha = feedBadgeAlpha, badgeAlpha = feedBadgeAlpha,
isEnded = index != feedsUiState.groupWithFeedList.lastIndex && feedsUiState.groupWithFeedList[index + 1] is GroupFeedsView.Group, isEnded = { index == feedsUiState.groupWithFeedList.lastIndex || feedsUiState.groupWithFeedList[index + 1] is GroupFeedsView.Group },
isExpanded = { groupsVisible[groupWithFeed.feed.groupId] ?: false }, isExpanded = { groupsVisible[groupWithFeed.feed.groupId] ?: false },
) { ) {
filterChange( filterChange(

View File

@ -35,6 +35,7 @@ fun GroupItem(
group: Group, group: Group,
alpha: Float = 1f, alpha: Float = 1f,
indicatorAlpha: Float = 1f, indicatorAlpha: Float = 1f,
isEnded: () -> Boolean,
isExpanded: () -> Boolean, isExpanded: () -> Boolean,
groupOptionViewModel: GroupOptionViewModel = hiltViewModel(), groupOptionViewModel: GroupOptionViewModel = hiltViewModel(),
onExpanded: () -> Unit = {}, onExpanded: () -> Unit = {},
@ -48,7 +49,7 @@ fun GroupItem(
.animateContentSize() .animateContentSize()
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
.clip(if (isExpanded()) ShapeTop32 else Shape32) .clip(if (isExpanded() && !isEnded()) ShapeTop32 else Shape32)
.background( .background(
MaterialTheme.colorScheme.secondary.copy(alpha = alpha) MaterialTheme.colorScheme.secondary.copy(alpha = alpha)
) )

View File

@ -45,7 +45,7 @@ fun SubscribeDialog(
val groupsState = subscribeUiState.groups.collectAsState(initial = emptyList()) val groupsState = subscribeUiState.groups.collectAsState(initial = emptyList())
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
it?.let { uri -> it?.let { uri ->
context.contentResolver.openInputStream(uri)?.use { inputStream -> context.contentResolver.openInputStream(uri)?.let { inputStream ->
subscribeViewModel.importFromInputStream(inputStream) subscribeViewModel.importFromInputStream(inputStream)
} }
} }

View File

@ -94,6 +94,7 @@ fun FeedsPagePreview(
) )
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
GroupItem( GroupItem(
isEnded = { false },
isExpanded = { groupListExpand.value }, isExpanded = { groupListExpand.value },
group = generateGroupPreview(), group = generateGroupPreview(),
alpha = groupAlpha, alpha = groupAlpha,
@ -103,7 +104,7 @@ fun FeedsPagePreview(
feed = generateFeedPreview(), feed = generateFeedPreview(),
alpha = groupAlpha, alpha = groupAlpha,
badgeAlpha = feedBadgeAlpha, badgeAlpha = feedBadgeAlpha,
isEnded = true, isEnded = { true },
isExpanded = { true }, isExpanded = { true },
) )
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))