This commit is contained in:
Никита Онянов 2025-05-15 01:31:54 +03:00
parent c37cb039ae
commit 9ef0b10646
17 changed files with 172 additions and 34 deletions

View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="deploymentTargetSelector"> <component name="deploymentTargetSelector">
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="App">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
</SelectionState> </SelectionState>
</selectionStates> </selectionStates>

View File

@ -52,10 +52,21 @@ android {
} }
dependencies { dependencies {
//implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
//implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("androidx.datastore:datastore-core:1.1.3")
implementation("androidx.datastore:datastore:1.1.3")
implementation("androidx.datastore:datastore-preferences:1.1.3")
implementation("androidx.navigation:navigation-compose:2.8.9") implementation("androidx.navigation:navigation-compose:2.8.9")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("com.squareup.retrofit2:converter-kotlinx-serialization:2.11.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.ktx)

View File

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.AppWithWin" android:theme="@style/Theme.AppWithWin"

View File

@ -9,6 +9,9 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.example.appwithwin.ui.theme.MatuleTheme import com.example.appwithwin.ui.theme.MatuleTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import com.example.appwithwin.data.local.DataStore
import com.example.appwithwin.data.remote.network.RetrofitClient
import com.example.appwithwin.data.repository.AuthRepository
import com.example.appwithwin.ui.screen.welcome.welcome1 import com.example.appwithwin.ui.screen.welcome.welcome1
import com.example.appwithwin.ui.screen.welcome.welcome2 import com.example.appwithwin.ui.screen.welcome.welcome2
import com.example.appwithwin.ui.screen.welcome.welcome3 import com.example.appwithwin.ui.screen.welcome.welcome3
@ -21,16 +24,18 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
val dataStore = DataStore(applicationContext)
val repository = AuthRepository(dataStore, RetrofitClient.auth)
setContent { setContent {
MatuleTheme { MatuleTheme {
AppNavigation() AppNavigation(repository)
} }
} }
} }
} }
@Composable @Composable
fun AppNavigation() { fun AppNavigation(repository: AuthRepository) {
val navController = rememberNavController() val navController = rememberNavController()
NavHost( NavHost(
navController = navController, navController = navController,
@ -38,28 +43,28 @@ fun AppNavigation() {
) { ) {
composable(Screen.welcome1.route) { composable(Screen.welcome1.route) {
welcome1( welcome1(
onClick = { on1Click = {
navController.navigate(Screen.welcome2.route) navController.navigate(Screen.welcome2.route)
} }
) )
} }
composable(Screen.welcome2.route) { composable(Screen.welcome2.route) {
welcome2( welcome2(
onClick = { on2Click = {
navController.navigate(Screen.welcome3.route) navController.navigate(Screen.welcome3.route)
} }
) )
} }
composable(Screen.welcome3.route) { composable(Screen.welcome3.route) {
welcome3( welcome3(
onClick = { on3Click = {
navController.navigate(Screen.welcome4.route) navController.navigate(Screen.welcome4.route)
} }
) )
} }
composable(Screen.welcome4.route) { composable(Screen.welcome4.route) {
welcome4( welcome4(
onClick = { on4Click = {
navController.navigate(Screen.SignIn.route) navController.navigate(Screen.SignIn.route)
} }
) )
@ -75,8 +80,9 @@ fun AppNavigation() {
composable(Screen.Register.route) { composable(Screen.Register.route) {
RegisterAccount( RegisterAccount(
onBackClick = { onBackClick = {
navController.popBackStack() navController.navigate(Screen.SignIn.route)
} },
repository
) )
} }
} }
@ -88,5 +94,5 @@ sealed class Screen(val route: String) {
object welcome1 : Screen("welcome1") object welcome1 : Screen("welcome1")
object welcome2 : Screen("welcome2") object welcome2 : Screen("welcome2")
object welcome3 : Screen("welcome3") object welcome3 : Screen("welcome3")
object welcome4 : Screen("welcome2") object welcome4 : Screen("welcome4")
} }

View File

@ -0,0 +1,17 @@
package com.example.registernew.data
data class AuthState(
val isLoading: Boolean = false,
val isAuthenticated: Boolean = false,
val user: User? = null,
val error: String? = null,
val isCodeSent: Boolean = false,
val isCodeVerified: Boolean = false,
val isPasswordReset: Boolean = false,
val isPasswordChanged: Boolean = false,
val isAlternativeResetFlow: Boolean = false,
val isAlternativeCodeSent: Boolean = false,
val isAlternativeCodeVerified: Boolean = false,
val isAlternativePasswordReset: Boolean = false,
val showPasswordChangeScreen: Boolean = false
)

View File

@ -0,0 +1,7 @@
package com.example.registernew.data
data class User(
val email: String,
val password: String,
val isVerified: Boolean = false
)

View File

@ -0,0 +1,24 @@
package com.example.appwithwin.data.local
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class DataStore(private val context: Context) {
val TOKEN_KEY = stringPreferencesKey("token_key")
val tokenFlow: Flow<String> = context.dataStore.data.map { pref ->
pref[TOKEN_KEY] ?: ""
}
suspend fun setToken(token: String){
context.dataStore.edit { pref ->
pref[TOKEN_KEY] = token
}
}
}

View File

@ -0,0 +1,17 @@
package com.example.appwithwin.data.remote.network
import com.example.appwithwin.data.remote.network.auth.AuthRemoteSource
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
object RetrofitClient {
private const val URL = "http://192.168.1.35:8080"
private val retrofit = Retrofit.Builder().baseUrl(URL)
.addConverterFactory(Json.asConverterFactory("application/json; charset=UTF8".toMediaType()))
.build()
val auth by lazy {
retrofit.create(AuthRemoteSource::class.java)
}
}

View File

@ -0,0 +1,9 @@
package com.example.appwithwin.data.remote.network.auth
import retrofit2.http.Body
import retrofit2.http.POST
interface AuthRemoteSource {
@POST("/registration")
suspend fun registartion(@Body registrationRequest: RegistrationRequest):RegistrationResponse
}

View File

@ -0,0 +1,9 @@
package com.example.appwithwin.data.remote.network.auth
import kotlinx.serialization.Serializable
@Serializable
data class RegistrationRequest(
val userName: String,
val password: String,
val email: String
)

View File

@ -0,0 +1,9 @@
package com.example.appwithwin.data.remote.network.auth
import kotlinx.serialization.Serializable
@Serializable
data class RegistrationResponse(
val first: String,
val second: String
)

View File

@ -0,0 +1,12 @@
package com.example.appwithwin.data.repository
import com.example.appwithwin.data.local.DataStore
import com.example.appwithwin.data.remote.network.auth.AuthRemoteSource
import com.example.appwithwin.data.remote.network.auth.RegistrationRequest
class AuthRepository (val dataStore: DataStore,val authRemoteSource: AuthRemoteSource){
suspend fun registration(registrationRequest: RegistrationRequest){
val result = authRemoteSource.registartion(registrationRequest)
dataStore.setToken(result.second)
}
}

View File

@ -16,6 +16,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
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.res.painterResource import androidx.compose.ui.res.painterResource
@ -23,10 +24,14 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.appwithwin.R import com.example.appwithwin.R
import com.example.appwithwin.data.remote.network.RetrofitClient
import com.example.appwithwin.data.remote.network.auth.RegistrationRequest
import com.example.appwithwin.data.repository.AuthRepository
import com.example.appwithwin.ui.theme.MatuleTheme import com.example.appwithwin.ui.theme.MatuleTheme
import kotlinx.coroutines.launch
@Composable @Composable
fun RegisterAccount(onBackClick: () -> Unit) { fun RegisterAccount(onBackClick: () -> Unit, repository: AuthRepository) {
Scaffold( Scaffold(
topBar = { topBar = {
Row( Row(
@ -66,12 +71,12 @@ fun RegisterAccount(onBackClick: () -> Unit) {
} }
} }
) { paddingValues -> ) { paddingValues ->
RegisterInContent(paddingValues) RegisterInContent(paddingValues, repository)
} }
} }
@Composable @Composable
fun RegisterInContent(paddingValues: PaddingValues) { fun RegisterInContent(paddingValues: PaddingValues, repository: AuthRepository) {
Column( Column(
modifier = Modifier.padding(paddingValues = paddingValues) modifier = Modifier.padding(paddingValues = paddingValues)
) { ) {
@ -79,19 +84,21 @@ fun RegisterInContent(paddingValues: PaddingValues) {
title = stringResource(R.string.register), title = stringResource(R.string.register),
subTitle = stringResource(R.string.sign_in_subtitle) subTitle = stringResource(R.string.sign_in_subtitle)
) )
val userName = remember { mutableStateOf("") }
val email = remember { mutableStateOf("") } val email = remember { mutableStateOf("") }
val password = remember { mutableStateOf("") } val password = remember { mutableStateOf("") }
val confirmPassword = remember { mutableStateOf("") } //val confirmPassword = remember { mutableStateOf("") }
val isAgreementChecked = remember { mutableStateOf(false) } //val isAgreementChecked = remember { mutableStateOf(false) }
val coroutione = rememberCoroutineScope()
Spacer(modifier = Modifier.height(35.dp)) Spacer(modifier = Modifier.height(35.dp))
AuthTextFiled( AuthTextFiled(
labelText = stringResource(R.string.your_name), labelText = stringResource(R.string.your_name),
placeHolderText = stringResource(R.string.template_name), placeHolderText = stringResource(R.string.template_name),
value = email.value, value = userName.value,
onValueChange = { onValueChange = {
email.value = it userName.value = it
} }
) )
@ -109,8 +116,8 @@ fun RegisterInContent(paddingValues: PaddingValues) {
AuthTextFiled( AuthTextFiled(
labelText = stringResource(R.string.password), labelText = stringResource(R.string.password),
placeHolderText = stringResource(R.string.template_password), placeHolderText = stringResource(R.string.template_password),
value = confirmPassword.value, value = password.value,
onValueChange = { confirmPassword.value = it }, onValueChange = { password.value = it },
isPassword = true isPassword = true
) )
@ -121,7 +128,16 @@ fun RegisterInContent(paddingValues: PaddingValues) {
CommonButton( CommonButton(
modifier = Modifier.padding(top = 50.dp), modifier = Modifier.padding(top = 50.dp),
buttonLabel = stringResource(R.string.Register), buttonLabel = stringResource(R.string.Register),
onClick = { }, onClick = {
coroutione.launch {
val registrationRequest = RegistrationRequest(
email = email.value,
password = password.value,
userName = userName.value
)
repository.registration(registrationRequest)
}
},
) )
} }
} }

View File

@ -21,16 +21,16 @@ import kotlinx.coroutines.delay
@Composable @Composable
fun welcome1( fun welcome1(
onClick: () -> Unit on1Click: () -> Unit
) { ) {
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
delay(2000) delay(2000)
onClick() on1Click()
} }
Scaffold { paddingValues -> win1(paddingValues,onClick) } Scaffold { paddingValues -> win1(paddingValues) }
} }
@Composable @Composable
fun win1(paddingValues: PaddingValues, onClick: () -> Unit, ) { fun win1(paddingValues: PaddingValues ) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()

View File

@ -29,15 +29,15 @@ import com.example.appwithwin.R
@Composable @Composable
fun welcome2( fun welcome2(
onClick: () -> Unit on2Click: () -> Unit
) { ) {
Scaffold{ Scaffold{
paddingValues -> win2(paddingValues,onClick) paddingValues -> win2(paddingValues,on2Click)
} }
} }
@Composable @Composable
fun win2(paddingValues: PaddingValues, onStart1Click: () -> Unit, ){ fun win2(paddingValues: PaddingValues, onClick: () -> Unit, ){
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -78,7 +78,7 @@ fun win2(paddingValues: PaddingValues, onStart1Click: () -> Unit, ){
) )
} }
Button( Button(
onClick = onStart1Click, onClick = onClick,
modifier = Modifier modifier = Modifier
.padding(top = 50.dp) .padding(top = 50.dp)
.background(Color.White, RoundedCornerShape(8.dp)) .background(Color.White, RoundedCornerShape(8.dp))

View File

@ -30,9 +30,9 @@ import com.example.appwithwin.R
@Composable @Composable
fun welcome3( fun welcome3(
onClick: () -> Unit on3Click: () -> Unit
) { ) {
Scaffold{ paddingValues -> win3(paddingValues,onClick) } Scaffold{ paddingValues -> win3(paddingValues,on3Click) }
} }
@Composable @Composable

View File

@ -29,9 +29,9 @@ import com.example.appwithwin.R
@Composable @Composable
fun welcome4( fun welcome4(
onClick: () -> Unit on4Click: () -> Unit
) { ) {
Scaffold{ paddingValues -> win4(paddingValues,onClick) } Scaffold{ paddingValues -> win4(paddingValues,on4Click) }
} }
@Composable @Composable