更新代码
This commit is contained in:
@@ -38,7 +38,7 @@ import kotlin.coroutines.suspendCoroutine
|
|||||||
object AppState {
|
object AppState {
|
||||||
var UserId: Int? = null
|
var UserId: Int? = null
|
||||||
var profile: AccountProfileEntity? = null
|
var profile: AccountProfileEntity? = null
|
||||||
var darkMode = false
|
var darkMode by mutableStateOf(false)
|
||||||
var appTheme by mutableStateOf<AppThemeData>(LightThemeColors())
|
var appTheme by mutableStateOf<AppThemeData>(LightThemeColors())
|
||||||
var googleClientId: String? = null
|
var googleClientId: String? = null
|
||||||
var enableGoogleLogin: Boolean = false
|
var enableGoogleLogin: Boolean = false
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.aiosman.ravenow.data.api.GoogleRegisterRequestBody
|
|||||||
import com.aiosman.ravenow.data.api.LoginUserRequestBody
|
import com.aiosman.ravenow.data.api.LoginUserRequestBody
|
||||||
import com.aiosman.ravenow.data.api.RegisterMessageChannelRequestBody
|
import com.aiosman.ravenow.data.api.RegisterMessageChannelRequestBody
|
||||||
import com.aiosman.ravenow.data.api.RegisterRequestBody
|
import com.aiosman.ravenow.data.api.RegisterRequestBody
|
||||||
|
import com.aiosman.ravenow.data.api.RemoveAccountRequestBody
|
||||||
import com.aiosman.ravenow.data.api.ResetPasswordRequestBody
|
import com.aiosman.ravenow.data.api.ResetPasswordRequestBody
|
||||||
import com.aiosman.ravenow.data.api.TrtcSignResponseBody
|
import com.aiosman.ravenow.data.api.TrtcSignResponseBody
|
||||||
import com.aiosman.ravenow.data.api.UnRegisterMessageChannelRequestBody
|
import com.aiosman.ravenow.data.api.UnRegisterMessageChannelRequestBody
|
||||||
@@ -386,6 +387,8 @@ interface AccountService {
|
|||||||
suspend fun getMyTrtcSign(): TrtcSignResponseBody
|
suspend fun getMyTrtcSign(): TrtcSignResponseBody
|
||||||
|
|
||||||
suspend fun getAppConfig(): AppConfig
|
suspend fun getAppConfig(): AppConfig
|
||||||
|
|
||||||
|
suspend fun removeAccount(password: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AccountServiceImpl : AccountService {
|
class AccountServiceImpl : AccountService {
|
||||||
@@ -554,4 +557,16 @@ class AccountServiceImpl : AccountService {
|
|||||||
val body = resp.body() ?: throw ServiceException("Failed to get app config")
|
val body = resp.body() ?: throw ServiceException("Failed to get app config")
|
||||||
return body.data
|
return body.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun removeAccount(password: String) {
|
||||||
|
val resp = ApiClient.api.deleteAccount(
|
||||||
|
RemoveAccountRequestBody(password)
|
||||||
|
)
|
||||||
|
if (!resp.isSuccessful) {
|
||||||
|
parseErrorResponse(resp.errorBody())?.let {
|
||||||
|
throw it.toServiceException()
|
||||||
|
}
|
||||||
|
throw ServiceException("Failed to remove account")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -200,6 +200,10 @@ data class CreateReportRequestBody(
|
|||||||
val base64Images: List<String>,
|
val base64Images: List<String>,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class RemoveAccountRequestBody(
|
||||||
|
@SerializedName("password")
|
||||||
|
val password: String,
|
||||||
|
)
|
||||||
|
|
||||||
interface RaveNowAPI {
|
interface RaveNowAPI {
|
||||||
@POST("register")
|
@POST("register")
|
||||||
@@ -449,5 +453,11 @@ interface RaveNowAPI {
|
|||||||
suspend fun createReport(
|
suspend fun createReport(
|
||||||
@Body body: CreateReportRequestBody
|
@Body body: CreateReportRequestBody
|
||||||
): Response<Unit>
|
): Response<Unit>
|
||||||
|
|
||||||
|
@POST("account/my/delete")
|
||||||
|
suspend fun deleteAccount(
|
||||||
|
@Body body: RemoveAccountRequestBody
|
||||||
|
): Response<Unit>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ import androidx.navigation.navArgument
|
|||||||
import com.aiosman.ravenow.LocalAnimatedContentScope
|
import com.aiosman.ravenow.LocalAnimatedContentScope
|
||||||
import com.aiosman.ravenow.LocalNavController
|
import com.aiosman.ravenow.LocalNavController
|
||||||
import com.aiosman.ravenow.LocalSharedTransitionScope
|
import com.aiosman.ravenow.LocalSharedTransitionScope
|
||||||
|
import com.aiosman.ravenow.ui.about.AboutScreen
|
||||||
import com.aiosman.ravenow.ui.account.AccountEditScreen2
|
import com.aiosman.ravenow.ui.account.AccountEditScreen2
|
||||||
|
import com.aiosman.ravenow.ui.account.AccountSetting
|
||||||
import com.aiosman.ravenow.ui.account.ResetPasswordScreen
|
import com.aiosman.ravenow.ui.account.ResetPasswordScreen
|
||||||
import com.aiosman.ravenow.ui.chat.ChatScreen
|
import com.aiosman.ravenow.ui.chat.ChatScreen
|
||||||
import com.aiosman.ravenow.ui.comment.CommentsScreen
|
import com.aiosman.ravenow.ui.comment.CommentsScreen
|
||||||
@@ -90,6 +92,8 @@ sealed class NavigationRoute(
|
|||||||
data object Chat : NavigationRoute("Chat/{id}")
|
data object Chat : NavigationRoute("Chat/{id}")
|
||||||
data object CommentNoticeScreen : NavigationRoute("CommentNoticeScreen")
|
data object CommentNoticeScreen : NavigationRoute("CommentNoticeScreen")
|
||||||
data object ImageCrop : NavigationRoute("ImageCrop")
|
data object ImageCrop : NavigationRoute("ImageCrop")
|
||||||
|
data object AccountSetting : NavigationRoute("AccountSetting")
|
||||||
|
data object AboutScreen : NavigationRoute("AboutScreen")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -377,6 +381,20 @@ fun NavigationController(
|
|||||||
ImageCropScreen()
|
ImageCropScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
composable(route = NavigationRoute.AccountSetting.route) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalAnimatedContentScope provides this,
|
||||||
|
) {
|
||||||
|
AccountSetting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
composable(route = NavigationRoute.AboutScreen.route) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalAnimatedContentScope provides this,
|
||||||
|
) {
|
||||||
|
AboutScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -425,3 +443,9 @@ fun NavHostController.navigateToChat(id: String) {
|
|||||||
.replace("{id}", id)
|
.replace("{id}", id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun NavHostController.goTo(
|
||||||
|
route: NavigationRoute
|
||||||
|
) {
|
||||||
|
navigate(route.route)
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.aiosman.ravenow.ui.about
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.ravenow.LocalAppTheme
|
||||||
|
import com.aiosman.ravenow.R
|
||||||
|
import com.aiosman.ravenow.ui.comment.NoticeScreenHeader
|
||||||
|
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AboutScreen() {
|
||||||
|
val appColors = LocalAppTheme.current
|
||||||
|
val context = LocalContext.current
|
||||||
|
val versionText = context.packageManager.getPackageInfo(context.packageName, 0).versionName
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(appColors.background),
|
||||||
|
) {
|
||||||
|
StatusBarSpacer()
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
|
||||||
|
) {
|
||||||
|
NoticeScreenHeader(
|
||||||
|
title = stringResource(R.string.about_rave_now),
|
||||||
|
moreIcon = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 24.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(48.dp))
|
||||||
|
// app icon
|
||||||
|
Box {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.mipmap.rider_pro_color_logo_next),
|
||||||
|
contentDescription = "app icon",
|
||||||
|
modifier = Modifier.size(80.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
// app name
|
||||||
|
Text(
|
||||||
|
text = "Rave Now".uppercase(),
|
||||||
|
fontSize = 24.sp,
|
||||||
|
color = appColors.text,
|
||||||
|
fontWeight = FontWeight.ExtraBold
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
// app version
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.version_text, versionText),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = appColors.secondaryText,
|
||||||
|
fontWeight = FontWeight.Normal
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
package com.aiosman.ravenow.ui.account
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
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.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.aiosman.ravenow.AppState
|
||||||
|
import com.aiosman.ravenow.AppStore
|
||||||
|
import com.aiosman.ravenow.LocalAppTheme
|
||||||
|
import com.aiosman.ravenow.LocalNavController
|
||||||
|
import com.aiosman.ravenow.Messaging
|
||||||
|
import com.aiosman.ravenow.R
|
||||||
|
import com.aiosman.ravenow.data.AccountServiceImpl
|
||||||
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
|
import com.aiosman.ravenow.ui.comment.NoticeScreenHeader
|
||||||
|
import com.aiosman.ravenow.ui.composables.ActionButton
|
||||||
|
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||||
|
import com.aiosman.ravenow.ui.index.NavItem
|
||||||
|
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AccountSetting() {
|
||||||
|
val appColors = LocalAppTheme.current
|
||||||
|
val navController = LocalNavController.current
|
||||||
|
var removeAccountModal by remember { mutableStateOf(false) }
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val context = LocalContext.current
|
||||||
|
fun removeAccount(password: String) {
|
||||||
|
scope.launch {
|
||||||
|
removeAccountModal = false
|
||||||
|
try {
|
||||||
|
val accountService = AccountServiceImpl()
|
||||||
|
accountService.removeAccount(password)
|
||||||
|
Messaging.unregisterDevice(context)
|
||||||
|
AppStore.apply {
|
||||||
|
token = null
|
||||||
|
rememberMe = false
|
||||||
|
saveData()
|
||||||
|
}
|
||||||
|
// 删除推送渠道
|
||||||
|
AppState.ReloadAppState(context)
|
||||||
|
navController.navigate(NavigationRoute.Login.route) {
|
||||||
|
popUpTo(NavigationRoute.Login.route) {
|
||||||
|
inclusive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
// show toast
|
||||||
|
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeAccountModal) {
|
||||||
|
ModalBottomSheet(
|
||||||
|
onDismissRequest = {
|
||||||
|
removeAccountModal = false
|
||||||
|
},
|
||||||
|
containerColor = appColors.background,
|
||||||
|
sheetState = rememberModalBottomSheetState(
|
||||||
|
skipPartiallyExpanded = true
|
||||||
|
),
|
||||||
|
dragHandle = {},
|
||||||
|
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
||||||
|
windowInsets = WindowInsets(0)
|
||||||
|
) {
|
||||||
|
RemoveAccountModal(
|
||||||
|
onRemove = {
|
||||||
|
removeAccount(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(appColors.background),
|
||||||
|
) {
|
||||||
|
StatusBarSpacer()
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
|
||||||
|
) {
|
||||||
|
NoticeScreenHeader(
|
||||||
|
title = stringResource(R.string.account_and_security),
|
||||||
|
moreIcon = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(start = 24.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.mipmap.rider_pro_change_password,
|
||||||
|
label = stringResource(R.string.change_password),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// divider
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(1.dp)
|
||||||
|
.background(appColors.divider)
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rider_pro_moment_delete,
|
||||||
|
label = stringResource(R.string.remove_account),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
removeAccountModal = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(1.dp)
|
||||||
|
.background(appColors.divider)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun RemoveAccountModal(
|
||||||
|
onRemove: (String) -> Unit
|
||||||
|
) {
|
||||||
|
val appColors = LocalAppTheme.current
|
||||||
|
var inputPassword by remember { mutableStateOf("") }
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 24.dp, vertical = 16.dp)
|
||||||
|
.background(appColors.background),
|
||||||
|
) {
|
||||||
|
StatusBarSpacer()
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(stringResource(R.string.remove_account), fontWeight = FontWeight.Bold, fontSize = 20.sp)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(bottom = 32.dp, top = 16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.remove_account_desc),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
stringResource(R.string.remove_account_password_hint),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 16.dp, bottom = 4.dp),
|
||||||
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(
|
||||||
|
appColors.inputBackground,
|
||||||
|
shape = RoundedCornerShape(24.dp)
|
||||||
|
)
|
||||||
|
.padding(vertical = 16.dp, horizontal = 16.dp)
|
||||||
|
){
|
||||||
|
|
||||||
|
BasicTextField(
|
||||||
|
value = inputPassword,
|
||||||
|
onValueChange = { inputPassword = it },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
ActionButton(
|
||||||
|
text = stringResource(R.string.remove_account),
|
||||||
|
fullWidth = true,
|
||||||
|
enabled = inputPassword.isNotEmpty(),
|
||||||
|
click = {
|
||||||
|
onRemove(inputPassword)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ object FavouriteListViewModel:ViewModel() {
|
|||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
Pager(
|
Pager(
|
||||||
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
|
config = PagingConfig(pageSize = 20, enablePlaceholders = false),
|
||||||
pagingSourceFactory = {
|
pagingSourceFactory = {
|
||||||
MomentPagingSource(
|
MomentPagingSource(
|
||||||
MomentRemoteDataSource(momentService),
|
MomentRemoteDataSource(momentService),
|
||||||
|
|||||||
@@ -3,34 +3,58 @@ package com.aiosman.ravenow.ui.index
|
|||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.navigationBars
|
import androidx.compose.foundation.layout.navigationBars
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.requiredWidth
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
|
import androidx.compose.material3.DrawerValue
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.ModalNavigationDrawer
|
||||||
import androidx.compose.material3.NavigationBar
|
import androidx.compose.material3.NavigationBar
|
||||||
import androidx.compose.material3.NavigationBarItem
|
import androidx.compose.material3.NavigationBarItem
|
||||||
import androidx.compose.material3.NavigationBarItemColors
|
import androidx.compose.material3.NavigationBarItemColors
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
|
import androidx.compose.material3.SwitchDefaults
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberDrawerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.scale
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.aiosman.ravenow.AppState
|
import com.aiosman.ravenow.AppState
|
||||||
|
import com.aiosman.ravenow.AppStore
|
||||||
import com.aiosman.ravenow.LocalAppTheme
|
import com.aiosman.ravenow.LocalAppTheme
|
||||||
import com.aiosman.ravenow.LocalNavController
|
import com.aiosman.ravenow.LocalNavController
|
||||||
|
import com.aiosman.ravenow.Messaging
|
||||||
|
import com.aiosman.ravenow.R
|
||||||
import com.aiosman.ravenow.ui.NavigationRoute
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
import com.aiosman.ravenow.ui.index.tabs.add.AddPage
|
import com.aiosman.ravenow.ui.index.tabs.add.AddPage
|
||||||
import com.aiosman.ravenow.ui.index.tabs.message.NotificationsScreen
|
import com.aiosman.ravenow.ui.index.tabs.message.NotificationsScreen
|
||||||
@@ -39,6 +63,7 @@ import com.aiosman.ravenow.ui.index.tabs.profile.ProfileWrap
|
|||||||
import com.aiosman.ravenow.ui.index.tabs.search.DiscoverScreen
|
import com.aiosman.ravenow.ui.index.tabs.search.DiscoverScreen
|
||||||
import com.aiosman.ravenow.ui.index.tabs.shorts.ShortVideo
|
import com.aiosman.ravenow.ui.index.tabs.shorts.ShortVideo
|
||||||
import com.aiosman.ravenow.ui.index.tabs.street.StreetPage
|
import com.aiosman.ravenow.ui.index.tabs.street.StreetPage
|
||||||
|
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||||
import com.aiosman.ravenow.ui.post.NewPostViewModel
|
import com.aiosman.ravenow.ui.post.NewPostViewModel
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -62,10 +87,148 @@ fun IndexScreen() {
|
|||||||
val systemUiController = rememberSystemUiController()
|
val systemUiController = rememberSystemUiController()
|
||||||
val pagerState = rememberPagerState(pageCount = { item.size })
|
val pagerState = rememberPagerState(pageCount = { item.size })
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||||
|
val context = LocalContext.current
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
systemUiController.setNavigationBarColor(Color.Transparent)
|
systemUiController.setNavigationBarColor(Color.Transparent)
|
||||||
}
|
}
|
||||||
|
LaunchedEffect(model.openDrawer) {
|
||||||
|
if (model.openDrawer) {
|
||||||
|
drawerState.open()
|
||||||
|
model.openDrawer = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
|
||||||
|
ModalNavigationDrawer(
|
||||||
|
drawerState = drawerState,
|
||||||
|
gesturesEnabled = drawerState.isOpen,
|
||||||
|
drawerContent = {
|
||||||
|
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.requiredWidth(250.dp)
|
||||||
|
.fillMaxHeight()
|
||||||
|
.background(
|
||||||
|
AppColors.background
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(88.dp))
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rave_now_nav_account,
|
||||||
|
label = stringResource(R.string.account_and_security),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
navController.navigate(NavigationRoute.AccountSetting.route)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rider_pro_favourited,
|
||||||
|
label = stringResource(R.string.favourites),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
navController.navigate(NavigationRoute.FavouriteList.route)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rave_now_nav_night,
|
||||||
|
label = stringResource(R.string.dark_mode),
|
||||||
|
rightContent = {
|
||||||
|
Switch(
|
||||||
|
checked = AppState.darkMode,
|
||||||
|
onCheckedChange = {
|
||||||
|
AppState.switchTheme()
|
||||||
|
},
|
||||||
|
|
||||||
|
colors = SwitchDefaults.colors(
|
||||||
|
checkedThumbColor = Color.White,
|
||||||
|
checkedTrackColor = AppColors.main,
|
||||||
|
uncheckedThumbColor = Color.White,
|
||||||
|
uncheckedTrackColor = AppColors.main.copy(alpha = 0.5f),
|
||||||
|
uncheckedBorderColor = Color.Transparent
|
||||||
|
),
|
||||||
|
modifier = Modifier.scale(0.8f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// divider
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 16.dp, bottom = 16.dp, start = 16.dp, end = 16.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(1.dp)
|
||||||
|
.background(AppColors.divider)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rave_now_nav_about,
|
||||||
|
label = stringResource(R.string.about_rave_now),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
navController.navigate(NavigationRoute.AboutScreen.route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// divider
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 16.dp, bottom = 16.dp, start = 16.dp, end = 16.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(1.dp)
|
||||||
|
.background(AppColors.divider)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NavItem(
|
||||||
|
// iconRes = R.drawable.rave_now_nav_switch,
|
||||||
|
// label = "Switch Account"
|
||||||
|
// )
|
||||||
|
// Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
NavItem(
|
||||||
|
iconRes = R.drawable.rave_now_nav_logout,
|
||||||
|
label = stringResource(R.string.logout),
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
Messaging.unregisterDevice(context)
|
||||||
|
AppStore.apply {
|
||||||
|
token = null
|
||||||
|
rememberMe = false
|
||||||
|
saveData()
|
||||||
|
}
|
||||||
|
// 删除推送渠道
|
||||||
|
|
||||||
|
navController.navigate(NavigationRoute.Login.route) {
|
||||||
|
popUpTo(NavigationRoute.Login.route) {
|
||||||
|
inclusive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppState.ReloadAppState(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
NavigationBar(
|
NavigationBar(
|
||||||
@@ -116,7 +279,9 @@ fun IndexScreen() {
|
|||||||
innerPadding
|
innerPadding
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
modifier = Modifier.background(AppColors.background).padding(0.dp),
|
modifier = Modifier
|
||||||
|
.background(AppColors.background)
|
||||||
|
.padding(0.dp),
|
||||||
beyondBoundsPageCount = 5,
|
beyondBoundsPageCount = 5,
|
||||||
userScrollEnabled = false
|
userScrollEnabled = false
|
||||||
) { page ->
|
) { page ->
|
||||||
@@ -129,6 +294,10 @@ fun IndexScreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -229,3 +398,44 @@ fun Notifications() {
|
|||||||
NotificationsScreen()
|
NotificationsScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NavItem(
|
||||||
|
iconRes: Int,
|
||||||
|
label: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
rightContent: @Composable (() -> Unit)? = null
|
||||||
|
) {
|
||||||
|
val appColors = LocalAppTheme.current
|
||||||
|
Row(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 8.dp, start = 16.dp, end = 16.dp, bottom = 8.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = iconRes),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
|
colorFilter = ColorFilter.tint(appColors.text)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 8.dp)
|
||||||
|
.weight(1f),
|
||||||
|
color = appColors.text,
|
||||||
|
)
|
||||||
|
if (rightContent != null) {
|
||||||
|
rightContent()
|
||||||
|
} else {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.rave_now_nav_right),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
|
colorFilter = ColorFilter.tint(appColors.secondaryText)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,8 @@ import androidx.lifecycle.ViewModel
|
|||||||
object IndexViewModel:ViewModel() {
|
object IndexViewModel:ViewModel() {
|
||||||
var tabIndex by mutableStateOf(0)
|
var tabIndex by mutableStateOf(0)
|
||||||
|
|
||||||
|
var openDrawer by mutableStateOf(false)
|
||||||
|
|
||||||
fun ResetModel(){
|
fun ResetModel(){
|
||||||
tabIndex = 0
|
tabIndex = 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
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 androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.aiosman.ravenow.LocalAppTheme
|
import com.aiosman.ravenow.LocalAppTheme
|
||||||
|
import com.aiosman.ravenow.R
|
||||||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.ExploreMomentsList
|
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.ExploreMomentsList
|
||||||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentsList
|
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentsList
|
||||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||||
@@ -42,7 +44,6 @@ import kotlinx.coroutines.launch
|
|||||||
@Composable
|
@Composable
|
||||||
fun MomentsList() {
|
fun MomentsList() {
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
val model = MomentViewModel
|
|
||||||
val navigationBarPaddings =
|
val navigationBarPaddings =
|
||||||
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
|
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
|
||||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||||
@@ -58,7 +59,9 @@ fun MomentsList() {
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth().height(44.dp),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(44.dp),
|
||||||
// center the tabs
|
// center the tabs
|
||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
@@ -74,7 +77,7 @@ fun MomentsList() {
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
|
||||||
) {
|
) {
|
||||||
Text(text = "Worldwide", fontSize = 16.sp, color = AppColors.text,fontWeight = FontWeight.W600)
|
Text(text = stringResource(R.string.index_worldwide), fontSize = 16.sp, color = AppColors.text,fontWeight = FontWeight.W600)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
@@ -97,7 +100,7 @@ fun MomentsList() {
|
|||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Text(text = "Following", fontSize = 16.sp, color = AppColors.text, fontWeight = FontWeight.W600)
|
Text(text = stringResource(R.string.index_following), fontSize = 16.sp, color = AppColors.text, fontWeight = FontWeight.W600)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import com.aiosman.ravenow.ui.composables.pickupAndCompressLauncher
|
|||||||
import com.aiosman.ravenow.ui.composables.toolbar.CollapsingToolbarScaffold
|
import com.aiosman.ravenow.ui.composables.toolbar.CollapsingToolbarScaffold
|
||||||
import com.aiosman.ravenow.ui.composables.toolbar.ScrollStrategy
|
import com.aiosman.ravenow.ui.composables.toolbar.ScrollStrategy
|
||||||
import com.aiosman.ravenow.ui.composables.toolbar.rememberCollapsingToolbarScaffoldState
|
import com.aiosman.ravenow.ui.composables.toolbar.rememberCollapsingToolbarScaffoldState
|
||||||
|
import com.aiosman.ravenow.ui.index.IndexViewModel
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.EmptyMomentPostUnit
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.EmptyMomentPostUnit
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.GalleryItem
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.GalleryItem
|
||||||
import com.aiosman.ravenow.ui.index.tabs.profile.composable.MomentPostUnit
|
import com.aiosman.ravenow.ui.index.tabs.profile.composable.MomentPostUnit
|
||||||
@@ -233,7 +234,9 @@ fun ProfileV3(
|
|||||||
it.noRippleClickable {
|
it.noRippleClickable {
|
||||||
Intent(Intent.ACTION_PICK).apply {
|
Intent(Intent.ACTION_PICK).apply {
|
||||||
type = "image/*"
|
type = "image/*"
|
||||||
pickBannerImageLauncher.launch(this)
|
pickBannerImageLauncher.launch(
|
||||||
|
this
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -278,70 +281,28 @@ fun ProfileV3(
|
|||||||
start = 8.dp,
|
start = 8.dp,
|
||||||
end = 8.dp
|
end = 8.dp
|
||||||
)
|
)
|
||||||
|
.noRippleClickable {
|
||||||
|
IndexViewModel.openDrawer = true
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
.clip(RoundedCornerShape(8.dp))
|
.clip(RoundedCornerShape(8.dp))
|
||||||
.background(AppColors.background.copy(alpha = 0.7f))
|
.background(
|
||||||
|
AppColors.background.copy(
|
||||||
|
alpha = 0.7f
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier.noRippleClickable {
|
|
||||||
expanded = true
|
|
||||||
},
|
|
||||||
tint = AppColors.text
|
tint = AppColors.text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val themeModeString =
|
|
||||||
if (AppState.darkMode) R.string.light_mode else R.string.dark_mode
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = expanded,
|
|
||||||
onDismissRequest = { expanded = false },
|
|
||||||
width = 250,
|
|
||||||
menuItems = listOf(
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.logout),
|
|
||||||
R.mipmap.rider_pro_logout
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
onLogout()
|
|
||||||
navController.navigate(NavigationRoute.Login.route) {
|
|
||||||
popUpTo(NavigationRoute.Index.route) {
|
|
||||||
inclusive = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.change_password),
|
|
||||||
R.mipmap.rider_pro_change_password
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.favourites),
|
|
||||||
R.drawable.rider_pro_favourite
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.FavouriteList.route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(themeModeString),
|
|
||||||
R.drawable.rider_pro_theme_mode_light
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
switchTheme()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +333,9 @@ fun ProfileV3(
|
|||||||
) {
|
) {
|
||||||
if (isSelf) {
|
if (isSelf) {
|
||||||
SelfProfileAction {
|
SelfProfileAction {
|
||||||
navController.navigate(NavigationRoute.AccountEdit.route)
|
navController.navigate(
|
||||||
|
NavigationRoute.AccountEdit.route
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (it.id != AppState.UserId) {
|
if (it.id != AppState.UserId) {
|
||||||
@@ -415,7 +378,10 @@ fun ProfileV3(
|
|||||||
) {
|
) {
|
||||||
StatusBarSpacer()
|
StatusBarSpacer()
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
modifier = Modifier.padding(
|
||||||
|
horizontal = 16.dp,
|
||||||
|
vertical = 8.dp
|
||||||
|
),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
@@ -437,69 +403,22 @@ fun ProfileV3(
|
|||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
if (isSelf) {
|
if (isSelf) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier.noRippleClickable {
|
||||||
|
IndexViewModel.openDrawer = true
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
||||||
contentDescription = "",
|
contentDescription = "",
|
||||||
modifier = Modifier.noRippleClickable {
|
|
||||||
minibarExpanded = true
|
|
||||||
},
|
|
||||||
tint = AppColors.text
|
tint = AppColors.text
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val themeModeString =
|
|
||||||
if (AppState.darkMode) R.string.light_mode else R.string.dark_mode
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = minibarExpanded,
|
|
||||||
onDismissRequest = { minibarExpanded = false },
|
|
||||||
width = 250,
|
|
||||||
menuItems = listOf(
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.logout),
|
|
||||||
R.mipmap.rider_pro_logout
|
|
||||||
) {
|
|
||||||
minibarExpanded = false
|
|
||||||
scope.launch {
|
|
||||||
onLogout()
|
|
||||||
navController.navigate(NavigationRoute.Login.route) {
|
|
||||||
popUpTo(NavigationRoute.Index.route) {
|
|
||||||
inclusive = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.change_password),
|
|
||||||
R.mipmap.rider_pro_change_password
|
|
||||||
) {
|
|
||||||
minibarExpanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.favourites),
|
|
||||||
R.drawable.rider_pro_favourite
|
|
||||||
) {
|
|
||||||
minibarExpanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.FavouriteList.route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(themeModeString),
|
|
||||||
R.drawable.rider_pro_theme_mode_light
|
|
||||||
) {
|
|
||||||
minibarExpanded = false
|
|
||||||
switchTheme()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +466,9 @@ fun ProfileV3(
|
|||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.noRippleClickable {
|
.noRippleClickable {
|
||||||
NewPostViewModel.asNewPost()
|
NewPostViewModel.asNewPost()
|
||||||
navController.navigate(NavigationRoute.NewPost.route)
|
navController.navigate(
|
||||||
|
NavigationRoute.NewPost.route
|
||||||
|
)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
@@ -616,6 +537,11 @@ fun ProfileV3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
PullRefreshIndicator(model.refreshing, refreshState, Modifier.align(Alignment.TopCenter))
|
PullRefreshIndicator(
|
||||||
|
model.refreshing,
|
||||||
|
refreshState,
|
||||||
|
Modifier.align(Alignment.TopCenter)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
app/src/main/res/drawable/rave_now_nav_about.xml
Normal file
9
app/src/main/res/drawable/rave_now_nav_about.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M12,12m-9,0a9,9 0,1 1,18 0a9,9 0,1 1,-18 0" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M11.25,11.25l0.75,0l0,5.25l0.75,0" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#110C13" android:fillType="nonZero" android:pathData="M11.813,7.875m-1.125,0a1.125,1.125 0,1 1,2.25 0a1.125,1.125 0,1 1,-2.25 0" android:strokeColor="#00000000" android:strokeWidth="1"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/rave_now_nav_account.xml
Normal file
9
app/src/main/res/drawable/rave_now_nav_account.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M12,12m-9,0a9,9 0,1 1,18 0a9,9 0,1 1,-18 0" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M12,10m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M6.168,18.849C6.676,17.157 8.234,15.999 10,16L14,16C15.769,15.999 17.328,17.16 17.834,18.855" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
7
app/src/main/res/drawable/rave_now_nav_logout.xml
Normal file
7
app/src/main/res/drawable/rave_now_nav_logout.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M7,6C4.514,8.099 3.604,11.528 4.722,14.583C5.839,17.639 8.746,19.671 12,19.671C15.254,19.671 18.161,17.639 19.278,14.583C20.396,11.528 19.486,8.099 17,6" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M12,4L12,12" android:strokeColor="#000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
13
app/src/main/res/drawable/rave_now_nav_night.xml
Normal file
13
app/src/main/res/drawable/rave_now_nav_night.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M20.253,10.5L20.253,6" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M22.5,8.253L18,8.253" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M15.753,2.25L15.753,5.25" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M17.25,3.753L14.25,3.753" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M20.316,14.306C17.317,15.147 14.099,14.305 11.897,12.103C9.695,9.901 8.853,6.683 9.694,3.684L9.694,3.684C5.682,4.801 3.04,8.625 3.417,12.773C3.793,16.921 7.079,20.207 11.227,20.583C15.375,20.96 19.199,18.318 20.316,14.306L20.316,14.306Z" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
5
app/src/main/res/drawable/rave_now_nav_right.xml
Normal file
5
app/src/main/res/drawable/rave_now_nav_right.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="22dp" android:viewportHeight="22" android:viewportWidth="13" android:width="13dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M6.5,5.55L10.812,9.914C11.133,10.239 11.133,10.761 10.812,11.086L6.5,15.45L6.5,15.45" android:strokeColor="#B1AEB2" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="1.66862918"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
11
app/src/main/res/drawable/rave_now_nav_switch.xml
Normal file
11
app/src/main/res/drawable/rave_now_nav_switch.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.77" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M16.5,13.5l3,3l-3,3" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M4.5,16.503L19.5,16.503" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M7.5,10.5l-3,-3l3,-3" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M19.5,7.503L4.5,7.503" android:strokeColor="#110C13" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
@@ -100,4 +100,12 @@
|
|||||||
<string name="report_fail_desc">举报失败,可以尝试重试</string>
|
<string name="report_fail_desc">举报失败,可以尝试重试</string>
|
||||||
<string name="report_title">举报这篇帖子的原因是?</string>
|
<string name="report_title">举报这篇帖子的原因是?</string>
|
||||||
<string name="close">关闭</string>
|
<string name="close">关闭</string>
|
||||||
|
<string name="about_rave_now">关于Rave Now</string>
|
||||||
|
<string name="account_and_security">账户与安全</string>
|
||||||
|
<string name="remove_account">删除账户</string>
|
||||||
|
<string name="remove_account_desc">注销账号为不可逆的操作,请确认</string>
|
||||||
|
<string name="remove_account_password_hint">输入密码以确认</string>
|
||||||
|
<string name="version_text">版本 %1$s</string>
|
||||||
|
<string name="index_worldwide">发现</string>
|
||||||
|
<string name="index_following">关注</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -99,4 +99,12 @@
|
|||||||
<string name="report_fail_desc">Failed to report, please try again</string>
|
<string name="report_fail_desc">Failed to report, please try again</string>
|
||||||
<string name="report_title">Reason for reporting this post?</string>
|
<string name="report_title">Reason for reporting this post?</string>
|
||||||
<string name="close">Close</string>
|
<string name="close">Close</string>
|
||||||
|
<string name="about_rave_now">About Rave Now</string>
|
||||||
|
<string name="account_and_security">Account and security</string>
|
||||||
|
<string name="remove_account">Remove Account</string>
|
||||||
|
<string name="remove_account_desc">Are you sure you want to remove your account? This action cannot be undone.</string>
|
||||||
|
<string name="remove_account_password_hint">Please enter your password to confirm</string>
|
||||||
|
<string name="version_text">Version %1$s</string>
|
||||||
|
<string name="index_worldwide">Worldwide</string>
|
||||||
|
<string name="index_following">Following</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user