更新重置密码
This commit is contained in:
@@ -6,6 +6,7 @@ import com.aiosman.riderpro.data.api.GoogleRegisterRequestBody
|
||||
import com.aiosman.riderpro.data.api.LoginUserRequestBody
|
||||
import com.aiosman.riderpro.data.api.RegisterMessageChannelRequestBody
|
||||
import com.aiosman.riderpro.data.api.RegisterRequestBody
|
||||
import com.aiosman.riderpro.data.api.ResetPasswordRequestBody
|
||||
import com.aiosman.riderpro.data.api.UpdateNoticeRequestBody
|
||||
import com.aiosman.riderpro.entity.AccountFavouriteEntity
|
||||
import com.aiosman.riderpro.entity.AccountLikeEntity
|
||||
@@ -339,6 +340,9 @@ interface AccountService {
|
||||
suspend fun updateNotice(payload: UpdateNoticeRequestBody)
|
||||
|
||||
suspend fun registerMessageChannel(client: String, identifier: String)
|
||||
|
||||
suspend fun resetPassword(email: String)
|
||||
|
||||
}
|
||||
|
||||
class AccountServiceImpl : AccountService {
|
||||
@@ -455,4 +459,12 @@ class AccountServiceImpl : AccountService {
|
||||
ApiClient.api.registerMessageChannel(RegisterMessageChannelRequestBody(client, identifier))
|
||||
}
|
||||
|
||||
override suspend fun resetPassword(email: String) {
|
||||
ApiClient.api.resetPassword(
|
||||
ResetPasswordRequestBody(
|
||||
username = email
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import android.icu.text.SimpleDateFormat
|
||||
import android.icu.util.TimeZone
|
||||
import com.aiosman.riderpro.AppStore
|
||||
import com.aiosman.riderpro.ConstVars
|
||||
import com.aiosman.riderpro.data.ServiceException
|
||||
import com.auth0.android.jwt.JWT
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.Interceptor
|
||||
|
||||
@@ -92,7 +92,10 @@ data class RegisterMessageChannelRequestBody(
|
||||
@SerializedName("identifier")
|
||||
val identifier: String,
|
||||
)
|
||||
|
||||
data class ResetPasswordRequestBody(
|
||||
@SerializedName("username")
|
||||
val username: String,
|
||||
)
|
||||
interface RiderProAPI {
|
||||
@POST("register")
|
||||
suspend fun register(@Body body: RegisterRequestBody): Response<Unit>
|
||||
@@ -270,4 +273,8 @@ interface RiderProAPI {
|
||||
@Path("id") id: Int
|
||||
): Response<Unit>
|
||||
|
||||
@POST("account/my/password/reset")
|
||||
suspend fun resetPassword(
|
||||
@Body body: ResetPasswordRequestBody
|
||||
): Response<Unit>
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import com.aiosman.riderpro.LocalAnimatedContentScope
|
||||
import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.LocalSharedTransitionScope
|
||||
import com.aiosman.riderpro.ui.account.AccountEditScreen2
|
||||
import com.aiosman.riderpro.ui.account.ResetPasswordScreen
|
||||
import com.aiosman.riderpro.ui.comment.CommentsScreen
|
||||
import com.aiosman.riderpro.ui.favourite.FavouriteNoticeScreen
|
||||
import com.aiosman.riderpro.ui.follower.FollowerListScreen
|
||||
@@ -80,6 +81,7 @@ sealed class NavigationRoute(
|
||||
data object Search : NavigationRoute("Search")
|
||||
data object FollowerList : NavigationRoute("FollowerList/{id}")
|
||||
data object FollowingList : NavigationRoute("FollowingList/{id}")
|
||||
data object ResetPassword : NavigationRoute("ResetPassword")
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +264,13 @@ fun NavigationController(
|
||||
FollowingListScreen(it.arguments?.getInt("id")!!)
|
||||
}
|
||||
}
|
||||
composable(route = NavigationRoute.ResetPassword.route) {
|
||||
CompositionLocalProvider(
|
||||
LocalAnimatedContentScope provides this,
|
||||
) {
|
||||
ResetPasswordScreen()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.aiosman.riderpro.ui.account
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Text
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.R
|
||||
import com.aiosman.riderpro.data.AccountService
|
||||
import com.aiosman.riderpro.data.AccountServiceImpl
|
||||
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
|
||||
import com.aiosman.riderpro.ui.composables.ActionButton
|
||||
import com.aiosman.riderpro.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.riderpro.ui.composables.TextInputField
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ResetPasswordScreen() {
|
||||
var username by remember { mutableStateOf("") }
|
||||
val accountService: AccountService = AccountServiceImpl()
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
var isSendSuccess by remember { mutableStateOf<Boolean?>(null) }
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
val navController = LocalNavController.current
|
||||
|
||||
fun resetPassword() {
|
||||
scope.launch {
|
||||
isLoading = true
|
||||
try {
|
||||
accountService.resetPassword(username)
|
||||
isSendSuccess = true
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
|
||||
isSendSuccess = false
|
||||
} finally {
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
StatusBarSpacer()
|
||||
Box(
|
||||
modifier = Modifier.padding(
|
||||
start = 16.dp,
|
||||
end = 16.dp,
|
||||
top = 16.dp,
|
||||
bottom = 0.dp
|
||||
)
|
||||
) {
|
||||
NoticeScreenHeader(
|
||||
"RECOVER ACCOUNT",
|
||||
moreIcon = false
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(36.dp))
|
||||
|
||||
if (isSendSuccess != null) {
|
||||
if (isSendSuccess!!) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = "Reset password email has been sent to your email address",
|
||||
style = TextStyle(
|
||||
color = Color(0xFF333333),
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = "Failed to send reset password email",
|
||||
style = TextStyle(
|
||||
color = Color(0xFF333333),
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(40.dp))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.noRippleClickable {
|
||||
navController.popBackStack()
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_nav_back),
|
||||
contentDescription = "Back",
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
androidx.compose.material3.Text(
|
||||
stringResource(R.string.back_upper),
|
||||
color = Color.Black,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(120.dp))
|
||||
TextInputField(
|
||||
text = username,
|
||||
onValueChange = { username = it },
|
||||
label = stringResource(R.string.login_email_label),
|
||||
hint = stringResource(R.string.text_hint_email),
|
||||
enabled = !isLoading
|
||||
)
|
||||
Spacer(modifier = Modifier.height(72.dp))
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator()
|
||||
} else {
|
||||
ActionButton(
|
||||
modifier = Modifier
|
||||
.width(345.dp)
|
||||
.height(48.dp),
|
||||
text = "Recover Account",
|
||||
backgroundImage = R.mipmap.rider_pro_signup_red_bg
|
||||
) {
|
||||
resetPassword()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,8 @@ fun TextInputField(
|
||||
password: Boolean = false,
|
||||
label: String? = null,
|
||||
hint: String? = null,
|
||||
error: String? = null
|
||||
error: String? = null,
|
||||
enabled: Boolean = true
|
||||
) {
|
||||
var showPassword by remember { mutableStateOf(!password) }
|
||||
var isFocused by remember { mutableStateOf(false) }
|
||||
@@ -74,6 +75,7 @@ fun TextInputField(
|
||||
),
|
||||
visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
singleLine = true,
|
||||
enabled = enabled
|
||||
)
|
||||
if (password) {
|
||||
Image(
|
||||
|
||||
@@ -197,7 +197,9 @@ fun UserAuthScreen() {
|
||||
fontSize = 12.sp
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(stringResource(R.string.forgot_password), fontSize = 12.sp)
|
||||
Text(stringResource(R.string.forgot_password), fontSize = 12.sp, modifier = Modifier.noRippleClickable {
|
||||
navController.navigate(NavigationRoute.ResetPassword.route)
|
||||
})
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(64.dp))
|
||||
@@ -210,7 +212,6 @@ fun UserAuthScreen() {
|
||||
) {
|
||||
onLogin()
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(48.dp))
|
||||
Text(stringResource(R.string.or_login_with), color = Color(0xFF999999))
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Reference in New Issue
Block a user