From 3e35991578d7abac5387f36e2fecfabce88a3f57 Mon Sep 17 00:00:00 2001 From: daichi-matsumoto Date: Mon, 11 Dec 2023 13:48:41 +0900 Subject: [PATCH 1/4] some pager instance cached in repository scope --- .../core/repository/FanboxRepository.kt | 24 +++++++++++++++---- .../feature/post/detail/PostDetailScreen.kt | 15 +++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/core/repository/src/main/java/caios/android/fanbox/core/repository/FanboxRepository.kt b/core/repository/src/main/java/caios/android/fanbox/core/repository/FanboxRepository.kt index 6c59aa38..04bda0f6 100644 --- a/core/repository/src/main/java/caios/android/fanbox/core/repository/FanboxRepository.kt +++ b/core/repository/src/main/java/caios/android/fanbox/core/repository/FanboxRepository.kt @@ -13,6 +13,7 @@ import android.webkit.MimeTypeMap import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.PagingData +import androidx.paging.cachedIn import caios.android.fanbox.core.datastore.PreferenceBookmarkedPosts import caios.android.fanbox.core.datastore.PreferenceFanboxCookie import caios.android.fanbox.core.model.FanboxTag @@ -72,6 +73,7 @@ import io.ktor.utils.io.jvm.javaio.copyTo import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -170,6 +172,8 @@ class FanboxRepositoryImpl( private val ioDispatcher: CoroutineDispatcher, ) : FanboxRepository { + private val scope = CoroutineScope(SupervisorJob() + ioDispatcher) + private val creatorCache = mutableMapOf() private val postCache = mutableMapOf() private var homePostsPager: Flow>? = null @@ -322,7 +326,10 @@ class FanboxRepositoryImpl( pagingSourceFactory = { HomePostsPagingSource(this, isHideRestricted) }, - ).flow.also { homePostsPager = it } + ) + .flow + .cachedIn(scope) + .also { homePostsPager = it } } override fun getHomePostsPagerCache(loadSize: Int, isHideRestricted: Boolean): Flow> { @@ -336,7 +343,10 @@ class FanboxRepositoryImpl( pagingSourceFactory = { HomePostsPagingSource(this, isHideRestricted) }, - ).flow.also { supportedPostsPager = it } + ) + .flow + .cachedIn(scope) + .also { supportedPostsPager = it } } override fun getSupportedPostsPagerCache(loadSize: Int, isHideRestricted: Boolean): Flow> { @@ -350,7 +360,10 @@ class FanboxRepositoryImpl( pagingSourceFactory = { CreatorPostsPagingSource(creatorId, this) }, - ).flow.also { creatorPostsPager = it } + ) + .flow + .cachedIn(scope) + .also { creatorPostsPager = it } } override fun getCreatorPostsPagerCache(): Flow>? { @@ -364,7 +377,10 @@ class FanboxRepositoryImpl( pagingSourceFactory = { SearchPostsPagingSource(this, creatorId, query) }, - ).flow.also { searchPostsPager = it } + ) + .flow + .cachedIn(scope) + .also { searchPostsPager = it } } override fun getPostsFromQueryPagerCache(): Flow>? { diff --git a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt index 63a0ad1b..effd1d2d 100644 --- a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt +++ b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt @@ -62,10 +62,13 @@ import caios.android.fanbox.core.ui.component.RestrictCardItem import caios.android.fanbox.core.ui.component.TagItems import caios.android.fanbox.core.ui.extensition.FadePlaceHolder import caios.android.fanbox.core.ui.extensition.fanboxHeader +import caios.android.fanbox.core.ui.extensition.isNullOrEmpty import caios.android.fanbox.core.ui.extensition.marquee import caios.android.fanbox.core.ui.theme.bold import caios.android.fanbox.core.ui.theme.center +import caios.android.fanbox.core.ui.view.ErrorView import caios.android.fanbox.core.ui.view.SimpleAlertContents +import caios.android.fanbox.feature.post.R import caios.android.fanbox.feature.post.detail.items.PostDetailArticleHeader import caios.android.fanbox.feature.post.detail.items.PostDetailCommentLikeButton import caios.android.fanbox.feature.post.detail.items.PostDetailCommentSection @@ -103,10 +106,10 @@ internal fun PostDetailRoute( } } - if (paging != null) { + if (!paging.isNullOrEmpty()) { LazyPagingItemsLoadContents( modifier = modifier, - lazyPagingItems = paging, + lazyPagingItems = paging!!, ) { val initIndex = remember { paging.itemSnapshotList.indexOfFirst { it?.id == postId } } val pagerState = rememberPagerState(if (initIndex != -1) initIndex else 0) { paging.itemCount } @@ -130,7 +133,7 @@ internal fun PostDetailRoute( } } } - } else { + } else if (paging != null) { PostDetailView( modifier = modifier, postId = postId, @@ -142,6 +145,12 @@ internal fun PostDetailRoute( navigateToCommentDeleteDialog = navigateToCommentDeleteDialog, terminate = terminate, ) + } else { + ErrorView( + modifier = Modifier.fillMaxSize(), + errorState = ScreenState.Error(R.string.error_network), + retryAction = { terminate.invoke() }, + ) } } From ce0a7b16e40b7f6dc97f85c672ad0fb4de7e640e Mon Sep 17 00:00:00 2001 From: daichi-matsumoto Date: Mon, 11 Dec 2023 13:54:25 +0900 Subject: [PATCH 2/4] fix order about version history --- .../caios/android/fanbox/core/datastore/PreferenceVersion.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PreferenceVersion.kt b/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PreferenceVersion.kt index 5ef729d3..d06ac68b 100644 --- a/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PreferenceVersion.kt +++ b/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PreferenceVersion.kt @@ -29,6 +29,7 @@ class PreferenceVersion @Inject constructor( message = if (Locale.getDefault() == Locale.JAPAN) it.logJp else it.logEn, ) } + .sortedByDescending { it.date } .also { data = it } From 6672f9897f3d34e92d80779a9fa1da7d070e22af Mon Sep 17 00:00:00 2001 From: daichi-matsumoto Date: Mon, 11 Dec 2023 14:07:28 +0900 Subject: [PATCH 3/4] fix default color --- .../fanbox/core/datastore/PixiViewPreferencesDataStore.kt | 4 ++-- core/datastore/src/main/proto/items/theme_color_config.proto | 2 +- .../java/caios/android/fanbox/core/model/ThemeColorConfig.kt | 2 +- .../src/main/java/caios/android/fanbox/core/model/UserData.kt | 2 +- .../src/main/java/caios/android/fanbox/core/ui/theme/Theme.kt | 2 +- .../feature/setting/theme/items/SettingThemeColorSection.kt | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PixiViewPreferencesDataStore.kt b/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PixiViewPreferencesDataStore.kt index 3ce790ca..c9808f05 100644 --- a/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PixiViewPreferencesDataStore.kt +++ b/core/datastore/src/main/java/caios/android/fanbox/core/datastore/PixiViewPreferencesDataStore.kt @@ -24,6 +24,7 @@ class PixiViewPreferencesDataStore( else -> ThemeConfig.System }, themeColorConfig = when (it.themeColorConfig) { + ThemeColorConfigProto.THEME_COLOR_CONFIG_RED -> ThemeColorConfig.Red ThemeColorConfigProto.THEME_COLOR_CONFIG_BLUE -> ThemeColorConfig.Blue ThemeColorConfigProto.THEME_COLOR_CONFIG_BROWN -> ThemeColorConfig.Brown ThemeColorConfigProto.THEME_COLOR_CONFIG_GREEN -> ThemeColorConfig.Green @@ -99,8 +100,7 @@ class PixiViewPreferencesDataStore( ThemeColorConfig.Green -> ThemeColorConfigProto.THEME_COLOR_CONFIG_GREEN ThemeColorConfig.Pink -> ThemeColorConfigProto.THEME_COLOR_CONFIG_PINK ThemeColorConfig.Purple -> ThemeColorConfigProto.THEME_COLOR_CONFIG_PURPLE - ThemeColorConfig.Default -> ThemeColorConfigProto.THEME_COLOR_CONFIG_DEFAULT - else -> ThemeColorConfigProto.THEME_COLOR_CONFIG_BLUE + ThemeColorConfig.Red -> ThemeColorConfigProto.THEME_COLOR_CONFIG_RED } } } diff --git a/core/datastore/src/main/proto/items/theme_color_config.proto b/core/datastore/src/main/proto/items/theme_color_config.proto index 6da10d60..0cc88574 100644 --- a/core/datastore/src/main/proto/items/theme_color_config.proto +++ b/core/datastore/src/main/proto/items/theme_color_config.proto @@ -5,7 +5,7 @@ option java_multiple_files = true; enum ThemeColorConfigProto { THEME_COLOR_CONFIG_UNSPECIFIED = 0; - THEME_COLOR_CONFIG_DEFAULT = 1; + THEME_COLOR_CONFIG_RED = 1; THEME_COLOR_CONFIG_BLUE = 2; THEME_COLOR_CONFIG_BROWN = 3; THEME_COLOR_CONFIG_GREEN = 4; diff --git a/core/model/src/main/java/caios/android/fanbox/core/model/ThemeColorConfig.kt b/core/model/src/main/java/caios/android/fanbox/core/model/ThemeColorConfig.kt index fd40bf3f..2d4fe50f 100644 --- a/core/model/src/main/java/caios/android/fanbox/core/model/ThemeColorConfig.kt +++ b/core/model/src/main/java/caios/android/fanbox/core/model/ThemeColorConfig.kt @@ -4,5 +4,5 @@ import androidx.compose.runtime.Stable @Stable enum class ThemeColorConfig { - Default, Blue, Brown, Green, Pink, Purple + Red, Blue, Brown, Green, Pink, Purple } diff --git a/core/model/src/main/java/caios/android/fanbox/core/model/UserData.kt b/core/model/src/main/java/caios/android/fanbox/core/model/UserData.kt index a99776fe..815b4b8c 100644 --- a/core/model/src/main/java/caios/android/fanbox/core/model/UserData.kt +++ b/core/model/src/main/java/caios/android/fanbox/core/model/UserData.kt @@ -29,7 +29,7 @@ data class UserData( return UserData( pixiViewId = "", themeConfig = ThemeConfig.System, - themeColorConfig = ThemeColorConfig.Default, + themeColorConfig = ThemeColorConfig.Red, isAgreedPrivacyPolicy = false, isAgreedTermsOfService = false, isAppLock = false, diff --git a/core/ui/src/main/java/caios/android/fanbox/core/ui/theme/Theme.kt b/core/ui/src/main/java/caios/android/fanbox/core/ui/theme/Theme.kt index 03d6a356..c48936eb 100644 --- a/core/ui/src/main/java/caios/android/fanbox/core/ui/theme/Theme.kt +++ b/core/ui/src/main/java/caios/android/fanbox/core/ui/theme/Theme.kt @@ -89,7 +89,7 @@ val DarkDefaultColorScheme = darkColorScheme( fun PixiViewTheme( fanboxCookie: String = "", fanboxMetadata: FanboxMetaData = FanboxMetaData.dummy(), - themeColorConfig: ThemeColorConfig = ThemeColorConfig.Default, + themeColorConfig: ThemeColorConfig = ThemeColorConfig.Red, shouldUseDarkTheme: Boolean = isSystemInDarkTheme(), enableDynamicTheme: Boolean = false, content: @Composable () -> Unit, diff --git a/feature/setting/src/main/java/caios/android/fanbox/feature/setting/theme/items/SettingThemeColorSection.kt b/feature/setting/src/main/java/caios/android/fanbox/feature/setting/theme/items/SettingThemeColorSection.kt index 3a2c6b17..cd049360 100644 --- a/feature/setting/src/main/java/caios/android/fanbox/feature/setting/theme/items/SettingThemeColorSection.kt +++ b/feature/setting/src/main/java/caios/android/fanbox/feature/setting/theme/items/SettingThemeColorSection.kt @@ -70,12 +70,12 @@ internal fun SettingThemeColorSection( key = { it.name }, ) { val color = when (it) { + ThemeColorConfig.Red -> if (isDarkMode) DarkDefaultColorScheme else LightDefaultColorScheme ThemeColorConfig.Blue -> if (isDarkMode) DarkBlueColorScheme else LightBlueColorScheme ThemeColorConfig.Brown -> if (isDarkMode) DarkBrownColorScheme else LightBrownColorScheme ThemeColorConfig.Green -> if (isDarkMode) DarkGreenColorScheme else LightGreenColorScheme ThemeColorConfig.Purple -> if (isDarkMode) DarkPurpleColorScheme else LightPurpleColorScheme ThemeColorConfig.Pink -> if (isDarkMode) DarkPinkColorScheme else LightPinckColorScheme - else -> if (isDarkMode) DarkDefaultColorScheme else LightDefaultColorScheme } SettingThemeColorItem( From 8a0ed3f2562f09c0f0f28c9d6c5008088fee7e49 Mon Sep 17 00:00:00 2001 From: daichi-matsumoto Date: Mon, 11 Dec 2023 15:10:37 +0900 Subject: [PATCH 4/4] add comment like method to PostDetailScreen --- .../feature/post/detail/PostDetailScreen.kt | 43 ++++++--------- .../items/PostDetailCommentLikeSection.kt | 55 ++++++++++++++++--- .../welcome/login/activity/LoginScreen.kt | 3 + 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt index effd1d2d..d6329bf0 100644 --- a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt +++ b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/PostDetailScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize @@ -19,10 +18,7 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.InsertDriveFile -import androidx.compose.material.icons.filled.Bookmark -import androidx.compose.material.icons.outlined.BookmarkBorder import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.surfaceColorAtElevation @@ -31,6 +27,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -250,6 +247,7 @@ private fun PostDetailScreen( modifier: Modifier = Modifier, ) { var isShowMenu by remember { mutableStateOf(false) } + var isPostLiked by rememberSaveable(postDetail.isLiked) { mutableStateOf(postDetail.isLiked) } var isBookmarked by remember(postDetail.isBookmarked) { mutableStateOf(postDetail.isBookmarked) } val isShowCoordinateHeader = when (val content = postDetail.body) { @@ -316,32 +314,23 @@ private fun PostDetailScreen( } item { - Row( + PostDetailCommentLikeButton( modifier = Modifier .padding(horizontal = 16.dp) .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(16.dp), - ) { - PostDetailCommentLikeButton( - modifier = Modifier.weight(1f), - likeCount = postDetail.likeCount, - commentCount = postDetail.commentCount, - ) - - IconButton( - onClick = { - isBookmarked = !isBookmarked - onClickPostBookmark.invoke(postDetail.asPost(), isBookmarked) - }, - ) { - Icon( - imageVector = if (isBookmarked) Icons.Default.Bookmark else Icons.Outlined.BookmarkBorder, - tint = if (isBookmarked) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface, - contentDescription = null, - ) - } - } + isLiked = isPostLiked, + isBookmarked = isBookmarked, + likeCount = postDetail.likeCount, + commentCount = postDetail.commentCount, + onClickLike = { + isPostLiked = true + onClickPostLike.invoke(postDetail.id) + }, + onClickBookmark = { + isBookmarked = it + onClickPostBookmark.invoke(postDetail.asPost(), isBookmarked) + }, + ) } if (postDetail.isRestricted) { diff --git a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/items/PostDetailCommentLikeSection.kt b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/items/PostDetailCommentLikeSection.kt index d6f09c7a..ad09e25e 100644 --- a/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/items/PostDetailCommentLikeSection.kt +++ b/feature/post/src/main/java/caios/android/fanbox/feature/post/detail/items/PostDetailCommentLikeSection.kt @@ -1,36 +1,52 @@ package caios.android.fanbox.feature.post.detail.items +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Comment +import androidx.compose.material.icons.filled.Bookmark import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.outlined.BookmarkBorder import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton 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.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @Composable internal fun PostDetailCommentLikeButton( commentCount: Int, likeCount: Int, + isBookmarked: Boolean, + isLiked: Boolean, + onClickLike: () -> Unit, + onClickBookmark: (Boolean) -> Unit, modifier: Modifier = Modifier, ) { + val likeColor = if (isLiked) Color(0xffe0405e) else MaterialTheme.colorScheme.onSurfaceVariant + val bookmarkColor = if (isBookmarked) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant + Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), ) { Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), ) { Icon( - modifier = Modifier.size(18.dp), + modifier = Modifier.size(20.dp), imageVector = Icons.AutoMirrored.Filled.Comment, tint = MaterialTheme.colorScheme.onSurfaceVariant, contentDescription = null, @@ -38,26 +54,47 @@ internal fun PostDetailCommentLikeButton( Text( text = commentCount.toString(), - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) } Row( + modifier = Modifier + .clip(CircleShape) + .clickable { + if (!isLiked) { + onClickLike.invoke() + } + onClickBookmark.invoke(true) + } + .padding(4.dp), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(6.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), ) { Icon( - modifier = Modifier.size(18.dp), + modifier = Modifier.size(20.dp), imageVector = Icons.Default.Favorite, - tint = MaterialTheme.colorScheme.onSurfaceVariant, + tint = likeColor, contentDescription = null, ) Text( text = likeCount.toString(), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.bodySmall, + color = likeColor, + ) + } + + Spacer(modifier = Modifier.weight(1f)) + + IconButton( + onClick = { onClickBookmark.invoke(!isBookmarked) }, + ) { + Icon( + imageVector = if (isBookmarked) Icons.Default.Bookmark else Icons.Outlined.BookmarkBorder, + tint = bookmarkColor, + contentDescription = null, ) } } diff --git a/feature/welcome/src/main/java/caios/android/fanbox/feature/welcome/login/activity/LoginScreen.kt b/feature/welcome/src/main/java/caios/android/fanbox/feature/welcome/login/activity/LoginScreen.kt index 84828e32..10350646 100644 --- a/feature/welcome/src/main/java/caios/android/fanbox/feature/welcome/login/activity/LoginScreen.kt +++ b/feature/welcome/src/main/java/caios/android/fanbox/feature/welcome/login/activity/LoginScreen.kt @@ -61,7 +61,10 @@ internal fun LoginScreen( cookieManager.acceptCookie() cookieManager.acceptThirdPartyCookies(it) + it.settings.loadWithOverviewMode = true + it.settings.domStorageEnabled = true it.settings.javaScriptEnabled = true + it.settings.javaScriptCanOpenWindowsAutomatically = true }, client = object : AccompanistWebViewClient() { override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {