Fix(WebView): Support check WebView version
This commit is contained in:
@@ -192,6 +192,7 @@ dependencies {
|
||||
implementation(libs.lifecycle.viewmodel.compose)
|
||||
implementation(libs.androidx.core.splashscreen)
|
||||
implementation(libs.hilt.android)
|
||||
implementation(libs.androidx.web.kit)
|
||||
ksp(libs.hilt.android)
|
||||
ksp(libs.hilt.compiler)
|
||||
implementation(libs.coil.kt)
|
||||
|
||||
@@ -8,6 +8,9 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
|
||||
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -16,11 +19,14 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.webkit.WebViewCompat
|
||||
import dagger.hilt.EntryPoint
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -86,6 +92,9 @@ class MainActivity : ComponentActivity() {
|
||||
LaunchedEffect(locale) {
|
||||
LocaleUtils.switchLocale(this@MainActivity, locale)
|
||||
}
|
||||
UseIsFirstLaunch(viewModel) {
|
||||
CheckWebView(it)
|
||||
}
|
||||
}
|
||||
|
||||
val darkTheme = shouldUseDarkTheme(uiState)
|
||||
@@ -154,6 +163,57 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UseIsFirstLaunch(viewModel: MainActivityViewModel, callback: @Composable (ondDismiss: () -> Unit) -> Unit) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
if (!whatIsFirstLaunch(uiState)) {
|
||||
return
|
||||
}
|
||||
|
||||
callback {
|
||||
viewModel.updateIsNotFirstLaunch()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun whatIsFirstLaunch(uiState: MainActivityUiState): Boolean =
|
||||
when (uiState) {
|
||||
MainActivityUiState.Loading -> false
|
||||
is MainActivityUiState.Success ->
|
||||
!uiState.userData.isNotFirstLaunch
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CheckWebView(onDismiss: () -> Unit) {
|
||||
val versionName = WebViewCompat.getCurrentWebViewPackage(LocalContext.current)?.versionName
|
||||
if (versionName == null) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = {Text(text = stringResource(R.string.core_web_view_warning))},
|
||||
text = { Text(text = stringResource(R.string.core_cannot_load_web_view_version)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(text = stringResource(R.string.core_dismiss))
|
||||
}
|
||||
}
|
||||
)
|
||||
return
|
||||
}
|
||||
if (versionName.split(".").first().toInt() < 80) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = {Text(text = stringResource(R.string.core_web_view_warning))},
|
||||
text = { Text(text = stringResource(R.string.core_web_view_version_too_low)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(text = stringResource(R.string.core_dismiss))
|
||||
}
|
||||
}
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun shouldUseDarkTheme(uiState: MainActivityUiState): Boolean =
|
||||
when (uiState) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import top.fatweb.oxygen.toolbox.model.userdata.UserData
|
||||
import top.fatweb.oxygen.toolbox.repository.userdata.UserDataRepository
|
||||
import javax.inject.Inject
|
||||
@@ -14,7 +15,7 @@ import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@HiltViewModel
|
||||
class MainActivityViewModel @Inject constructor(
|
||||
userDataRepository: UserDataRepository
|
||||
private val userDataRepository: UserDataRepository
|
||||
) : ViewModel() {
|
||||
val uiState: StateFlow<MainActivityUiState> = userDataRepository.userData.map {
|
||||
MainActivityUiState.Success(it)
|
||||
@@ -23,6 +24,12 @@ class MainActivityViewModel @Inject constructor(
|
||||
initialValue = MainActivityUiState.Loading,
|
||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5.seconds.inWholeMilliseconds)
|
||||
)
|
||||
|
||||
fun updateIsNotFirstLaunch() {
|
||||
viewModelScope.launch {
|
||||
userDataRepository.updateIsNotFirstLaunch()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface MainActivityUiState {
|
||||
|
||||
@@ -69,7 +69,8 @@ class OxygenPreferencesDataSource @Inject constructor(
|
||||
DarkThemeConfigProto.DARK_THEME_CONFIG_DARK
|
||||
-> DarkThemeConfig.Dark
|
||||
},
|
||||
useDynamicColor = it.useDynamicColor
|
||||
useDynamicColor = it.useDynamicColor,
|
||||
isNotFirstLaunch = it.isNotFirstLaunch
|
||||
)
|
||||
}
|
||||
|
||||
@@ -126,4 +127,12 @@ class OxygenPreferencesDataSource @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateIsNotFirstLaunch() {
|
||||
userPreferences.updateData {
|
||||
it.copy {
|
||||
this.isNotFirstLaunch = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@ data class UserData(
|
||||
val launchPageConfig: LaunchPageConfig,
|
||||
val themeBrandConfig: ThemeBrandConfig,
|
||||
val darkThemeConfig: DarkThemeConfig,
|
||||
val useDynamicColor: Boolean
|
||||
val useDynamicColor: Boolean,
|
||||
val isNotFirstLaunch: Boolean
|
||||
)
|
||||
|
||||
@@ -19,4 +19,6 @@ interface UserDataRepository {
|
||||
suspend fun setDarkThemeConfig(darkThemeConfig: DarkThemeConfig)
|
||||
|
||||
suspend fun setUseDynamicColor(useDynamicColor: Boolean)
|
||||
|
||||
suspend fun updateIsNotFirstLaunch()
|
||||
}
|
||||
|
||||
@@ -35,4 +35,8 @@ internal class LocalUserDataRepository @Inject constructor(
|
||||
override suspend fun setUseDynamicColor(useDynamicColor: Boolean) {
|
||||
oxygenPreferencesDataSource.setUseDynamicColor(useDynamicColor)
|
||||
}
|
||||
|
||||
override suspend fun updateIsNotFirstLaunch() {
|
||||
oxygenPreferencesDataSource.updateIsNotFirstLaunch()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.webkit.WebViewCompat
|
||||
import kotlinx.coroutines.delay
|
||||
import top.fatweb.oxygen.toolbox.R
|
||||
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
|
||||
@@ -126,6 +127,7 @@ internal fun AboutScreen(
|
||||
private fun AboutAppInfo(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val logo = AnimatedImageVector.animatedVectorResource(R.drawable.ic_launcher)
|
||||
var atEnd by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(Unit) {
|
||||
@@ -169,6 +171,15 @@ private fun AboutAppInfo(
|
||||
)
|
||||
})"
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
text = "WebView: ${
|
||||
WebViewCompat.getCurrentWebViewPackage(context)?.versionName ?: stringResource(
|
||||
R.string.core_unknown
|
||||
)
|
||||
}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -271,7 +271,8 @@ private fun SettingDialogPreview() {
|
||||
launchPageConfig = LaunchPageConfig.Tools,
|
||||
themeBrandConfig = ThemeBrandConfig.Default,
|
||||
darkThemeConfig = DarkThemeConfig.FollowSystem,
|
||||
useDynamicColor = true
|
||||
useDynamicColor = true,
|
||||
isNotFirstLaunch = true
|
||||
)
|
||||
),
|
||||
onChangeLanguageConfig = {},
|
||||
|
||||
@@ -14,4 +14,5 @@ message UserPreferences {
|
||||
ThemeBrandConfigProto theme_brand_config = 3;
|
||||
DarkThemeConfigProto dark_theme_config = 4;
|
||||
bool use_dynamic_color = 5;
|
||||
bool is_not_first_launch = 6;
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
<string name="core_unstar">取消收藏</string>
|
||||
<string name="core_cancel">取消</string>
|
||||
<string name="core_undo">撤消</string>
|
||||
<string name="core_dismiss">忽略</string>
|
||||
<string name="core_nothing">空空如也</string>
|
||||
<string name="core_nothing_found">未找到相关内容</string>
|
||||
<string name="core_file_select_one">选择一个文件</string>
|
||||
@@ -33,6 +34,9 @@
|
||||
<string name="core_file_select_one_text">选择一个文本文件</string>
|
||||
<string name="core_file_select_multi_text">选择文本文件</string>
|
||||
<string name="core_can_only_download_http_https">只能下载 HTTP/HTTPS URI:%1$s</string>
|
||||
<string name="core_web_view_warning">⚠️ WebView 警告 ⚠️</string>
|
||||
<string name="core_cannot_load_web_view_version">无法获取 WebView 版本信息,WebView 版本过低可能会导致工具使用异常,请知悉。</string>
|
||||
<string name="core_web_view_version_too_low">当前 WebView 版本过低,可能会导致工具使用异常,请知悉。</string>
|
||||
|
||||
<string name="feature_store_title">商店</string>
|
||||
<string name="feature_store_retry">重试</string>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<string name="core_unstar">Unstar</string>
|
||||
<string name="core_cancel">Cancel</string>
|
||||
<string name="core_undo">Undo</string>
|
||||
<string name="core_dismiss">Dismiss</string>
|
||||
<string name="core_nothing">Nothing</string>
|
||||
<string name="core_nothing_found">Nothing found</string>
|
||||
<string name="core_file_select_one">Select a file</string>
|
||||
@@ -32,6 +33,9 @@
|
||||
<string name="core_file_select_one_text">Select a text file</string>
|
||||
<string name="core_file_select_multi_text">Select text files</string>
|
||||
<string name="core_can_only_download_http_https">Can only download HTTP/HTTPS URIs: %1$s</string>
|
||||
<string name="core_web_view_warning">⚠️ WebView warning ⚠️</string>
|
||||
<string name="core_cannot_load_web_view_version">The WebView version information cannot be obtained. If the WebView version is too low, it may cause abnormal tool usage. Please be informed.</string>
|
||||
<string name="core_web_view_version_too_low">The current WebView version is too low, which may cause abnormal use of the tool. Please be informed.</string>
|
||||
|
||||
<string name="feature_store_title">Store</string>
|
||||
<string name="feature_store_retry">try again</string>
|
||||
|
||||
Reference in New Issue
Block a user