feat: Compose 登录
This commit is contained in:
parent
7eac0d1edc
commit
197d0626a7
|
|
@ -127,7 +127,6 @@ dependencies {
|
||||||
|
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2'
|
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2'
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7'
|
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7'
|
||||||
// implementation 'androidx.compose.material3:material3:1.0.0'
|
|
||||||
|
|
||||||
def media3_version = "1.2.1"
|
def media3_version = "1.2.1"
|
||||||
implementation "androidx.media3:media3-exoplayer:$media3_version"
|
implementation "androidx.media3:media3-exoplayer:$media3_version"
|
||||||
|
|
@ -176,6 +175,7 @@ dependencies {
|
||||||
// Optional - Add full set of material icons
|
// Optional - Add full set of material icons
|
||||||
implementation 'androidx.compose.material:material-icons-extended'
|
implementation 'androidx.compose.material:material-icons-extended'
|
||||||
implementation 'androidx.compose.ui:ui-util'
|
implementation 'androidx.compose.ui:ui-util'
|
||||||
|
// implementation 'androidx.compose.material3:material3:1.0.0'
|
||||||
|
|
||||||
// Android Studio Preview support
|
// Android Studio Preview support
|
||||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,322 @@
|
||||||
|
package com.huanchengfly.tieba.post.ui.page.login
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.webkit.CookieManager
|
||||||
|
import android.webkit.WebView
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material.DropdownMenuItem
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.LinearProgressIndicator
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.SnackbarDuration
|
||||||
|
import androidx.compose.material.SnackbarHostState
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.MoreVert
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.snapshotFlow
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
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 androidx.core.net.toUri
|
||||||
|
import com.huanchengfly.tieba.post.R
|
||||||
|
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorMessage
|
||||||
|
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.webview.MyWebChromeClient
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.webview.MyWebViewClient
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.webview.isInternalHost
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.ClickMenu
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.LoadingState
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.LocalSnackbarHostState
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.Toolbar
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.WebView
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberMenuState
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberSaveableWebViewState
|
||||||
|
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberWebViewNavigator
|
||||||
|
import com.huanchengfly.tieba.post.utils.AccountUtil
|
||||||
|
import com.huanchengfly.tieba.post.utils.AccountUtil.parseCookie
|
||||||
|
import com.huanchengfly.tieba.post.utils.ClientUtils
|
||||||
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.cancellable
|
||||||
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
const val LOGIN_URL =
|
||||||
|
"https://wappass.baidu.com/passport?login&u=https%3A%2F%2Ftieba.baidu.com%2Findex%2Ftbwise%2Fmine"
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
@Destination
|
||||||
|
@Composable
|
||||||
|
fun LoginPage(
|
||||||
|
navigator: DestinationsNavigator,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val webViewState = rememberSaveableWebViewState()
|
||||||
|
val webViewNavigator = rememberWebViewNavigator()
|
||||||
|
var loaded by rememberSaveable {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
var pageTitle by rememberSaveable {
|
||||||
|
mutableStateOf("")
|
||||||
|
}
|
||||||
|
val displayPageTitle by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
pageTitle.ifEmpty {
|
||||||
|
context.getString(R.string.title_default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val currentHost by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
webViewState.lastLoadedUrl?.toUri()?.host.orEmpty().lowercase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val isExternalHost by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
currentHost.isNotEmpty() && !isInternalHost(currentHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposableEffect(Unit) {
|
||||||
|
val job = coroutineScope.launch {
|
||||||
|
snapshotFlow { webViewState.pageTitle }
|
||||||
|
.filterNotNull()
|
||||||
|
.filter { it.isNotEmpty() }
|
||||||
|
.cancellable()
|
||||||
|
.collect {
|
||||||
|
pageTitle = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDispose {
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoad(loaded = loaded) {
|
||||||
|
webViewNavigator.loadUrl(LOGIN_URL)
|
||||||
|
loaded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val isLoading by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
webViewState.loadingState is LoadingState.Loading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val progress by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
webViewState.loadingState.let {
|
||||||
|
if (it is LoadingState.Loading) {
|
||||||
|
it.progress
|
||||||
|
} else {
|
||||||
|
0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val animatedProgress by animateFloatAsState(targetValue = progress, label = "progress")
|
||||||
|
|
||||||
|
MyScaffold(
|
||||||
|
topBar = {
|
||||||
|
Toolbar(
|
||||||
|
title = {
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = displayPageTitle,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
if (isExternalHost) {
|
||||||
|
Text(
|
||||||
|
text = currentHost,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
color = ExtendedTheme.colors.onTopBarSecondary,
|
||||||
|
style = MaterialTheme.typography.caption
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navigationIcon = { BackNavigationIcon(onBackPressed = { navigator.navigateUp() }) },
|
||||||
|
actions = {
|
||||||
|
val menuState = rememberMenuState()
|
||||||
|
ClickMenu(
|
||||||
|
menuContent = {
|
||||||
|
DropdownMenuItem(
|
||||||
|
onClick = {
|
||||||
|
webViewNavigator.reload()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(id = R.string.title_refresh))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
menuState = menuState,
|
||||||
|
triggerShape = CircleShape
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.size(48.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.MoreVert,
|
||||||
|
contentDescription = stringResource(id = R.string.btn_more)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Box {
|
||||||
|
val snackbarHostState = LocalSnackbarHostState.current
|
||||||
|
WebView(
|
||||||
|
state = webViewState,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
|
navigator = webViewNavigator,
|
||||||
|
onCreated = {
|
||||||
|
it.settings.apply {
|
||||||
|
javaScriptEnabled = true
|
||||||
|
domStorageEnabled = true
|
||||||
|
setSupportZoom(true)
|
||||||
|
builtInZoomControls = true
|
||||||
|
displayZoomControls = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
client = remember(navigator) {
|
||||||
|
LoginWebViewClient(
|
||||||
|
navigator,
|
||||||
|
coroutineScope,
|
||||||
|
snackbarHostState
|
||||||
|
)
|
||||||
|
},
|
||||||
|
chromeClient = remember { MyWebChromeClient(context, coroutineScope) }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
LinearProgressIndicator(
|
||||||
|
progress = animatedProgress,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginWebViewClient(
|
||||||
|
nativeNavigator: DestinationsNavigator? = null,
|
||||||
|
val coroutineScope: CoroutineScope,
|
||||||
|
val snackbarHostState: SnackbarHostState,
|
||||||
|
) : MyWebViewClient(nativeNavigator) {
|
||||||
|
private var isLoadingAccount = false
|
||||||
|
|
||||||
|
override fun injectCookies(url: String) {}
|
||||||
|
|
||||||
|
override fun onPageFinished(view: WebView, url: String?) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
if (url == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isLoadingAccount) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val cookieStr = CookieManager.getInstance().getCookie(url) ?: return
|
||||||
|
val cookies = parseCookie(cookieStr).mapKeys { it.key.uppercase() }
|
||||||
|
val bduss = cookies["BDUSS"]
|
||||||
|
val sToken = cookies["STOKEN"]
|
||||||
|
val baiduId = cookies["BAIDUID"]
|
||||||
|
if (url.startsWith("https://tieba.baidu.com/index/tbwise/") || url.startsWith("https://tiebac.baidu.com/index/tbwise/")) {
|
||||||
|
if (bduss == null || sToken == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!baiduId.isNullOrEmpty() && ClientUtils.baiduId.isNullOrEmpty()) {
|
||||||
|
coroutineScope.launch {
|
||||||
|
ClientUtils.saveBaiduId(context, baiduId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
coroutineScope.launch {
|
||||||
|
snackbarHostState.showSnackbar(
|
||||||
|
context.getString(R.string.text_please_wait),
|
||||||
|
duration = SnackbarDuration.Indefinite
|
||||||
|
)
|
||||||
|
}
|
||||||
|
coroutineScope.launch {
|
||||||
|
AccountUtil.fetchAccountFlow(bduss, sToken, cookieStr)
|
||||||
|
.catch {
|
||||||
|
coroutineScope.launch {
|
||||||
|
snackbarHostState.currentSnackbarData?.dismiss()
|
||||||
|
snackbarHostState.showSnackbar(
|
||||||
|
context.getString(
|
||||||
|
R.string.text_login_failed,
|
||||||
|
it.getErrorMessage()
|
||||||
|
), duration = SnackbarDuration.Short
|
||||||
|
)
|
||||||
|
}
|
||||||
|
navigator.loadUrl(LOGIN_URL)
|
||||||
|
isLoadingAccount = false
|
||||||
|
}
|
||||||
|
.flowOn(Dispatchers.Main)
|
||||||
|
.collect { account ->
|
||||||
|
isLoadingAccount = false
|
||||||
|
AccountUtil.newAccount(account.uid, account) {
|
||||||
|
if (it) {
|
||||||
|
AccountUtil.switchAccount(context, account.id)
|
||||||
|
coroutineScope.launch {
|
||||||
|
snackbarHostState.currentSnackbarData?.dismiss()
|
||||||
|
snackbarHostState.showSnackbar(
|
||||||
|
context.getString(R.string.text_login_success),
|
||||||
|
duration = SnackbarDuration.Short
|
||||||
|
)
|
||||||
|
}
|
||||||
|
coroutineScope.launch {
|
||||||
|
delay(1500L)
|
||||||
|
nativeNavigator?.navigateUp()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
coroutineScope.launch {
|
||||||
|
snackbarHostState.currentSnackbarData?.dismiss()
|
||||||
|
snackbarHostState.showSnackbar(
|
||||||
|
context.getString(R.string.text_login_failed_default),
|
||||||
|
duration = SnackbarDuration.Short
|
||||||
|
)
|
||||||
|
}
|
||||||
|
view.loadUrl(LOGIN_URL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,16 +64,15 @@ import com.airbnb.lottie.compose.rememberLottieComposition
|
||||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||||
import com.google.accompanist.placeholder.placeholder
|
import com.google.accompanist.placeholder.placeholder
|
||||||
import com.huanchengfly.tieba.post.R
|
import com.huanchengfly.tieba.post.R
|
||||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
|
||||||
import com.huanchengfly.tieba.post.arch.GlobalEvent
|
import com.huanchengfly.tieba.post.arch.GlobalEvent
|
||||||
import com.huanchengfly.tieba.post.arch.collectPartialAsState
|
import com.huanchengfly.tieba.post.arch.collectPartialAsState
|
||||||
import com.huanchengfly.tieba.post.arch.onGlobalEvent
|
import com.huanchengfly.tieba.post.arch.onGlobalEvent
|
||||||
import com.huanchengfly.tieba.post.arch.pageViewModel
|
import com.huanchengfly.tieba.post.arch.pageViewModel
|
||||||
import com.huanchengfly.tieba.post.goToActivity
|
|
||||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator
|
import com.huanchengfly.tieba.post.ui.common.theme.compose.pullRefreshIndicator
|
||||||
import com.huanchengfly.tieba.post.ui.page.LocalNavigator
|
import com.huanchengfly.tieba.post.ui.page.LocalNavigator
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.destinations.LoginPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.SearchPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.SearchPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.widgets.Chip
|
import com.huanchengfly.tieba.post.ui.widgets.Chip
|
||||||
import com.huanchengfly.tieba.post.ui.widgets.compose.ActionItem
|
import com.huanchengfly.tieba.post.ui.widgets.compose.ActionItem
|
||||||
|
|
@ -638,7 +637,7 @@ fun EmptyScreen(
|
||||||
canOpenExplore: Boolean,
|
canOpenExplore: Boolean,
|
||||||
onOpenExplore: () -> Unit
|
onOpenExplore: () -> Unit
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val navigator = LocalNavigator.current
|
||||||
TipScreen(
|
TipScreen(
|
||||||
title = {
|
title = {
|
||||||
if (!loggedIn) {
|
if (!loggedIn) {
|
||||||
|
|
@ -671,7 +670,7 @@ fun EmptyScreen(
|
||||||
if (!loggedIn) {
|
if (!loggedIn) {
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
context.goToActivity<LoginActivity>()
|
navigator.navigate(LoginPageDestination)
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.LocalContentColor
|
import androidx.compose.material.LocalContentColor
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.AccountCircle
|
import androidx.compose.material.icons.rounded.AccountCircle
|
||||||
|
|
@ -20,11 +21,8 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.google.accompanist.insets.ui.Scaffold
|
|
||||||
import com.huanchengfly.tieba.post.R
|
import com.huanchengfly.tieba.post.R
|
||||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
|
||||||
import com.huanchengfly.tieba.post.dataStore
|
import com.huanchengfly.tieba.post.dataStore
|
||||||
import com.huanchengfly.tieba.post.goToActivity
|
|
||||||
import com.huanchengfly.tieba.post.models.database.Account
|
import com.huanchengfly.tieba.post.models.database.Account
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.PrefsScreen
|
import com.huanchengfly.tieba.post.ui.common.prefs.PrefsScreen
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TextPref
|
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TextPref
|
||||||
|
|
@ -35,6 +33,7 @@ import com.huanchengfly.tieba.post.ui.page.destinations.AccountManagePageDestina
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.BlockSettingsPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.BlockSettingsPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.CustomSettingsPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.CustomSettingsPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.HabitSettingsPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.HabitSettingsPageDestination
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.destinations.LoginPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.MoreSettingsPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.MoreSettingsPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.destinations.OKSignSettingsPageDestination
|
import com.huanchengfly.tieba.post.ui.page.destinations.OKSignSettingsPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar
|
import com.huanchengfly.tieba.post.ui.widgets.compose.Avatar
|
||||||
|
|
@ -63,8 +62,8 @@ fun NowAccountItem(
|
||||||
account: Account?,
|
account: Account?,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
val navigator = LocalNavigator.current
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
val navigator = LocalNavigator.current
|
|
||||||
TextPref(
|
TextPref(
|
||||||
title = stringResource(id = R.string.title_account_manage),
|
title = stringResource(id = R.string.title_account_manage),
|
||||||
summary = stringResource(id = R.string.summary_now_account, account.nameShow ?: account.name),
|
summary = stringResource(id = R.string.summary_now_account, account.nameShow ?: account.name),
|
||||||
|
|
@ -82,12 +81,11 @@ fun NowAccountItem(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val context = LocalContext.current
|
|
||||||
TextPref(
|
TextPref(
|
||||||
title = stringResource(id = R.string.title_account_manage),
|
title = stringResource(id = R.string.title_account_manage),
|
||||||
summary = stringResource(id = R.string.summary_not_logged_in),
|
summary = stringResource(id = R.string.summary_not_logged_in),
|
||||||
enabled = true,
|
enabled = true,
|
||||||
onClick = { context.goToActivity<LoginActivity>() },
|
onClick = { navigator.navigate(LoginPageDestination) },
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
LeadingIcon {
|
LeadingIcon {
|
||||||
AvatarIcon(
|
AvatarIcon(
|
||||||
|
|
@ -110,23 +108,23 @@ fun NowAccountItem(
|
||||||
fun SettingsPage(
|
fun SettingsPage(
|
||||||
navigator: DestinationsNavigator,
|
navigator: DestinationsNavigator,
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
ProvideNavigator(navigator = navigator) {
|
||||||
backgroundColor = Color.Transparent,
|
Scaffold(
|
||||||
topBar = {
|
backgroundColor = Color.Transparent,
|
||||||
TitleCentredToolbar(
|
topBar = {
|
||||||
title = {
|
TitleCentredToolbar(
|
||||||
Text(
|
title = {
|
||||||
text = stringResource(id = R.string.title_settings),
|
Text(
|
||||||
fontWeight = FontWeight.Bold, style = MaterialTheme.typography.h6
|
text = stringResource(id = R.string.title_settings),
|
||||||
)
|
fontWeight = FontWeight.Bold, style = MaterialTheme.typography.h6
|
||||||
},
|
)
|
||||||
navigationIcon = {
|
},
|
||||||
BackNavigationIcon(onBackPressed = { navigator.navigateUp() })
|
navigationIcon = {
|
||||||
}
|
BackNavigationIcon(onBackPressed = { navigator.navigateUp() })
|
||||||
)
|
}
|
||||||
},
|
)
|
||||||
) {
|
},
|
||||||
ProvideNavigator(navigator = navigator) {
|
) {
|
||||||
PrefsScreen(
|
PrefsScreen(
|
||||||
dataStore = LocalContext.current.dataStore,
|
dataStore = LocalContext.current.dataStore,
|
||||||
dividerThickness = 0.dp,
|
dividerThickness = 0.dp,
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,13 @@ import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.huanchengfly.tieba.post.R
|
import com.huanchengfly.tieba.post.R
|
||||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
|
||||||
import com.huanchengfly.tieba.post.dataStore
|
import com.huanchengfly.tieba.post.dataStore
|
||||||
import com.huanchengfly.tieba.post.goToActivity
|
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.PrefsScreen
|
import com.huanchengfly.tieba.post.ui.common.prefs.PrefsScreen
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.DropDownPref
|
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.DropDownPref
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.EditTextPref
|
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.EditTextPref
|
||||||
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TextPref
|
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TextPref
|
||||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.destinations.LoginPageDestination
|
||||||
import com.huanchengfly.tieba.post.ui.page.settings.LeadingIcon
|
import com.huanchengfly.tieba.post.ui.page.settings.LeadingIcon
|
||||||
import com.huanchengfly.tieba.post.ui.widgets.compose.AvatarIcon
|
import com.huanchengfly.tieba.post.ui.widgets.compose.AvatarIcon
|
||||||
import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
|
import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
|
||||||
|
|
@ -130,7 +129,7 @@ fun AccountManagePage(
|
||||||
prefsItem {
|
prefsItem {
|
||||||
TextPref(
|
TextPref(
|
||||||
title = stringResource(id = R.string.title_new_account),
|
title = stringResource(id = R.string.title_new_account),
|
||||||
onClick = { context.goToActivity<LoginActivity>() },
|
onClick = { navigator.navigate(LoginPageDestination) },
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
LeadingIcon {
|
LeadingIcon {
|
||||||
AvatarIcon(
|
AvatarIcon(
|
||||||
|
|
|
||||||
|
|
@ -50,13 +50,13 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||||
import com.huanchengfly.tieba.post.R
|
import com.huanchengfly.tieba.post.R
|
||||||
import com.huanchengfly.tieba.post.activities.LoginActivity
|
|
||||||
import com.huanchengfly.tieba.post.arch.BaseComposeActivity.Companion.LocalWindowSizeClass
|
import com.huanchengfly.tieba.post.arch.BaseComposeActivity.Companion.LocalWindowSizeClass
|
||||||
import com.huanchengfly.tieba.post.arch.GlobalEvent
|
import com.huanchengfly.tieba.post.arch.GlobalEvent
|
||||||
import com.huanchengfly.tieba.post.arch.emitGlobalEvent
|
import com.huanchengfly.tieba.post.arch.emitGlobalEvent
|
||||||
import com.huanchengfly.tieba.post.goToActivity
|
|
||||||
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
|
||||||
import com.huanchengfly.tieba.post.ui.common.windowsizeclass.WindowWidthSizeClass.Companion.Compact
|
import com.huanchengfly.tieba.post.ui.common.windowsizeclass.WindowWidthSizeClass.Companion.Compact
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.LocalNavigator
|
||||||
|
import com.huanchengfly.tieba.post.ui.page.destinations.LoginPageDestination
|
||||||
import com.huanchengfly.tieba.post.utils.AccountUtil
|
import com.huanchengfly.tieba.post.utils.AccountUtil
|
||||||
import com.huanchengfly.tieba.post.utils.AccountUtil.LocalAccount
|
import com.huanchengfly.tieba.post.utils.AccountUtil.LocalAccount
|
||||||
import com.huanchengfly.tieba.post.utils.StringUtil
|
import com.huanchengfly.tieba.post.utils.StringUtil
|
||||||
|
|
@ -73,6 +73,7 @@ fun AccountNavIcon(
|
||||||
spacer: Boolean = true,
|
spacer: Boolean = true,
|
||||||
size: Dp = Sizes.Small
|
size: Dp = Sizes.Small
|
||||||
) {
|
) {
|
||||||
|
val navigator = LocalNavigator.current
|
||||||
val currentAccount = LocalAccount.current
|
val currentAccount = LocalAccount.current
|
||||||
if (spacer) Spacer(modifier = Modifier.width(12.dp))
|
if (spacer) Spacer(modifier = Modifier.width(12.dp))
|
||||||
if (currentAccount == null) {
|
if (currentAccount == null) {
|
||||||
|
|
@ -125,9 +126,11 @@ fun AccountNavIcon(
|
||||||
VerticalDivider(
|
VerticalDivider(
|
||||||
modifier = Modifier.padding(vertical = 8.dp)
|
modifier = Modifier.padding(vertical = 8.dp)
|
||||||
)
|
)
|
||||||
DropdownMenuItem(onClick = {
|
DropdownMenuItem(
|
||||||
context.goToActivity<LoginActivity>()
|
onClick = {
|
||||||
}) {
|
navigator.navigate(LoginPageDestination)
|
||||||
|
}
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Rounded.Add,
|
imageVector = Icons.Rounded.Add,
|
||||||
contentDescription = stringResource(id = R.string.title_new_account),
|
contentDescription = stringResource(id = R.string.title_new_account),
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ object AccountUtil {
|
||||||
fun parseCookie(cookie: String): Map<String, String> {
|
fun parseCookie(cookie: String): Map<String, String> {
|
||||||
return cookie
|
return cookie
|
||||||
.split(";")
|
.split(";")
|
||||||
.map { it.split("=") }
|
.map { it.trim().split("=") }
|
||||||
.filter { it.size > 1 }
|
.filter { it.size > 1 }
|
||||||
.associate { it.first() to it.drop(1).joinToString("=") }
|
.associate { it.first() to it.drop(1).joinToString("=") }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -761,4 +761,7 @@
|
||||||
<string name="menu_add_user_to_white_list">添加到白名单</string>
|
<string name="menu_add_user_to_white_list">添加到白名单</string>
|
||||||
<string name="btn_block">屏蔽选项</string>
|
<string name="btn_block">屏蔽选项</string>
|
||||||
<string name="text_god_verify">%s领域大神</string>
|
<string name="text_god_verify">%s领域大神</string>
|
||||||
|
<string name="text_login_failed">登录失败 %s</string>
|
||||||
|
<string name="text_login_success">登录成功,即将跳转</string>
|
||||||
|
<string name="text_login_failed_default">登录失败</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue