diff --git a/app/src/main/java/com/huanchengfly/tieba/post/App.kt b/app/src/main/java/com/huanchengfly/tieba/post/App.kt index 9b67885e..d39765a8 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/App.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/App.kt @@ -284,6 +284,9 @@ class App : Application(), IApp, SketchFactory { lateinit var INSTANCE: App private set + val isInitialized: Boolean + get() = this::INSTANCE.isInitialized + val isSystemNight: Boolean get() = nightMode == Configuration.UI_MODE_NIGHT_YES @@ -669,6 +672,9 @@ class App : Application(), IApp, SketchFactory { } override fun getColorById(context: Context, colorId: Int): Int { +// if (!isInitialized) { +// return context.getColorCompat(colorId) +// } when (colorId) { R.color.default_color_primary -> return getColorByAttr(context, R.attr.colorPrimary) R.color.default_color_accent -> return getColorByAttr(context, R.attr.colorAccent) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/Extensions.kt b/app/src/main/java/com/huanchengfly/tieba/post/Extensions.kt index 80e192e4..50104833 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/Extensions.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/Extensions.kt @@ -26,6 +26,8 @@ import kotlinx.collections.immutable.toImmutableList import java.io.File import kotlin.math.roundToInt +private val Context.scaledDensity: Float + get() = resources.displayMetrics.scaledDensity fun Float.dpToPx(): Int = dpToPxFloat().roundToInt() @@ -33,11 +35,11 @@ fun Float.dpToPx(): Int = fun Float.dpToPxFloat(): Float = this * App.ScreenInfo.DENSITY + 0.5f -fun Float.spToPx(): Int = - (this * App.INSTANCE.resources.displayMetrics.scaledDensity + 0.5f).roundToInt() +fun Float.spToPx(context: Context = App.INSTANCE): Int = + (this * context.scaledDensity + 0.5f).roundToInt() -fun Float.spToPxFloat(): Float = - this * App.INSTANCE.resources.displayMetrics.scaledDensity + 0.5f +fun Float.spToPxFloat(context: Context = App.INSTANCE): Float = + this * context.scaledDensity + 0.5f fun Float.pxToDp(): Int = (this / App.ScreenInfo.DENSITY + 0.5f).roundToInt() @@ -45,8 +47,8 @@ fun Float.pxToDp(): Int = fun Float.pxToDpFloat(): Float = this / App.ScreenInfo.DENSITY + 0.5f -fun Float.pxToSp(): Int = - (this / App.INSTANCE.resources.displayMetrics.scaledDensity + 0.5f).roundToInt() +fun Float.pxToSp(context: Context = App.INSTANCE): Int = + (this / context.scaledDensity + 0.5f).roundToInt() fun Int.dpToPx(): Int = this.toFloat().dpToPx() @@ -54,7 +56,7 @@ fun Int.spToPx(): Int = this.toFloat().spToPx() fun Int.pxToDp(): Int = this.toFloat().pxToDp() -fun Int.pxToSp(): Int = this.toFloat().pxToSp() +fun Int.pxToSp(context: Context = App.INSTANCE): Int = this.toFloat().pxToSp(context) fun Float.pxToSpFloat(): Float = this / App.INSTANCE.resources.displayMetrics.scaledDensity + 0.5f diff --git a/app/src/main/java/com/huanchengfly/tieba/post/arch/BaseComposeActivity.kt b/app/src/main/java/com/huanchengfly/tieba/post/arch/BaseComposeActivity.kt index 22714ffa..15792837 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/arch/BaseComposeActivity.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/arch/BaseComposeActivity.kt @@ -12,6 +12,8 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import com.google.accompanist.systemuicontroller.SystemUiController import com.google.accompanist.systemuicontroller.rememberSystemUiController @@ -114,7 +116,9 @@ abstract class BaseComposeActivity : BaseActivity() { companion object { val LocalWindowSizeClass = - staticCompositionLocalOf { error("not initialized") } + staticCompositionLocalOf { + WindowSizeClass.calculateFromSize(DpSize(0.dp, 0.dp)) + } } } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt index 306568e9..9c9f5858 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/editprofile/view/EditProfileActivity.kt @@ -14,12 +14,32 @@ import androidx.activity.viewModels import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.material.Card +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.Scaffold +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -53,12 +73,31 @@ import com.huanchengfly.tieba.post.ui.page.editprofile.EditProfileEvent import com.huanchengfly.tieba.post.ui.page.editprofile.EditProfileIntent import com.huanchengfly.tieba.post.ui.page.editprofile.EditProfileState import com.huanchengfly.tieba.post.ui.page.editprofile.viewmodel.EditProfileViewModel -import com.huanchengfly.tieba.post.ui.widgets.compose.* +import com.huanchengfly.tieba.post.ui.widgets.compose.ActionItem +import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon +import com.huanchengfly.tieba.post.ui.widgets.compose.CounterTextField +import com.huanchengfly.tieba.post.ui.widgets.compose.Dialog +import com.huanchengfly.tieba.post.ui.widgets.compose.DialogNegativeButton +import com.huanchengfly.tieba.post.ui.widgets.compose.Toolbar import com.huanchengfly.tieba.post.ui.widgets.compose.picker.ListSinglePicker -import com.huanchengfly.tieba.post.utils.* +import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState +import com.huanchengfly.tieba.post.utils.AccountUtil +import com.huanchengfly.tieba.post.utils.ColorUtils +import com.huanchengfly.tieba.post.utils.PermissionUtils +import com.huanchengfly.tieba.post.utils.PickMediasRequest +import com.huanchengfly.tieba.post.utils.StringUtil +import com.huanchengfly.tieba.post.utils.ThemeUtil +import com.huanchengfly.tieba.post.utils.isPhotoPickerAvailable +import com.huanchengfly.tieba.post.utils.registerPickMediasLauncher +import com.huanchengfly.tieba.post.utils.requestPermission import com.yalantis.ucrop.UCrop import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.* +import kotlinx.collections.immutable.persistentListOf +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import java.io.File @AndroidEntryPoint @@ -458,11 +497,11 @@ fun PageEditProfile( } ) { ListSinglePicker( - itemTitles = listOf( + itemTitles = persistentListOf( stringResource(id = R.string.profile_sex_male), stringResource(id = R.string.profile_sex_female) ), - itemValues = listOf(1, 2), + itemValues = persistentListOf(1, 2), selectedPosition = if (sex == 1) 0 else if (sex == 2) 1 else -1, onItemSelected = { _, _, value, _ -> sex = value diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/ForumPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/ForumPage.kt index 5b5487a0..0968089a 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/ForumPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/ForumPage.kt @@ -739,11 +739,11 @@ fun ForumPage( menuState = menuState, menuContent = { ListSinglePicker( - itemTitles = listOf( + itemTitles = persistentListOf( stringResource(id = R.string.title_sort_by_reply), stringResource(id = R.string.title_sort_by_send) ), - itemValues = listOf(0, 1), + itemValues = persistentListOf(0, 1), selectedPosition = currentSortType, onItemSelected = { _, _, value, changed -> if (changed) { diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/FeedCard.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/FeedCard.kt index 9b9f09d2..cfd95607 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/FeedCard.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/FeedCard.kt @@ -98,11 +98,13 @@ private val ImmutableHolder.url: String @Composable private fun DefaultUserHeader( - user: ImmutableHolder, - time: Int, + userProvider: () -> ImmutableHolder, + timeProvider: () -> Int, content: @Composable RowScope.() -> Unit ) { val context = LocalContext.current + val user = remember(userProvider) { userProvider() } + val time = remember(timeProvider) { timeProvider() } UserHeader( avatar = { Avatar( @@ -144,6 +146,7 @@ private fun DefaultUserHeader( @Composable fun Card( + modifier: Modifier = Modifier, header: @Composable ColumnScope.() -> Unit = {}, content: @Composable ColumnScope.() -> Unit = {}, action: @Composable (ColumnScope.() -> Unit)? = null, @@ -156,6 +159,7 @@ fun Card( Column( modifier = cardModifier + .then(modifier) .then(paddingModifier) .padding(horizontal = 16.dp) ) { @@ -509,6 +513,7 @@ fun FeedCard( item: ImmutableHolder, onClick: (ThreadInfo) -> Unit, onAgree: (ThreadInfo) -> Unit, + modifier: Modifier = Modifier, onReplyClick: (ThreadInfo) -> Unit = {}, onClickForum: (SimpleForum) -> Unit = {}, dislikeAction: @Composable () -> Unit = {}, @@ -517,11 +522,9 @@ fun FeedCard( header = { val hasAuthor = remember(item) { item.isNotNull { author } } if (hasAuthor) { - val author = remember(item) { item.getImmutable { author!! } } - val time = remember(item) { item.get { lastTimeInt } } DefaultUserHeader( - user = author, - time = time + userProvider = { item.getImmutable { author!! } }, + timeProvider = { item.get { lastTimeInt } } ) { dislikeAction() } } }, @@ -562,6 +565,7 @@ fun FeedCard( } }, onClick = { onClick(item.get()) }, + modifier = modifier ) } @@ -683,6 +687,7 @@ fun FeedCardPreview() { ) ), onClick = {}, - onAgree = {} + onAgree = {}, + modifier = Modifier.background(ExtendedTheme.colors.card) ) } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Texts.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Texts.kt index 649d36c5..aa07ddb3 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Texts.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/widgets/compose/Texts.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.takeOrElse +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString @@ -207,7 +208,7 @@ fun IconText( ) ) val sizePx = getEmoticonHeightPx(mergedStyle) * 9 / 10 - val sizeSp = sizePx.pxToSp().sp + val sizeSp = sizePx.pxToSp(LocalContext.current).sp val sizeDp = sizePx.pxToDp().dp val iconInlineContent = remember(sizeSp) { diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/StringUtil.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/StringUtil.kt index 0a3a1bd1..5573be65 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/StringUtil.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/StringUtil.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle +import com.huanchengfly.tieba.post.App import com.huanchengfly.tieba.post.R import com.huanchengfly.tieba.post.components.spans.EmoticonSpanV2 import com.huanchengfly.tieba.post.ui.common.theme.utils.ThemeUtils @@ -98,7 +99,7 @@ object StringUtil { nickname: String?, color: Color = Color.Unspecified ): AnnotatedString { - val showBoth = context.appPreferences.showBothUsernameAndNickname + val showBoth = App.isInitialized && context.appPreferences.showBothUsernameAndNickname return buildAnnotatedString { if (showBoth && !nickname.isNullOrBlank() && username != nickname && username.isNotBlank()) { append(nickname) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/ThemeUtil.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/ThemeUtil.kt index c5b78506..373c24b7 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/utils/ThemeUtil.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/ThemeUtil.kt @@ -25,6 +25,7 @@ import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.CustomViewTarget import com.bumptech.glide.request.transition.Transition import com.google.android.material.appbar.AppBarLayout +import com.huanchengfly.tieba.post.App import com.huanchengfly.tieba.post.App.Companion.INSTANCE import com.huanchengfly.tieba.post.App.Companion.translucentBackground import com.huanchengfly.tieba.post.R @@ -44,7 +45,10 @@ import java.util.Locale object ThemeUtil { val themeState: MutableState by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - mutableStateOf(dataStore.getString(KEY_THEME, THEME_DEFAULT)) + mutableStateOf( + if (App.isInitialized) dataStore.getString(KEY_THEME, THEME_DEFAULT) + else THEME_DEFAULT + ) } const val TAG = "ThemeUtil"