dataStore completely fixed, MAIN screen implemented

This commit is contained in:
pedro 2025-02-20 10:49:25 +03:00
parent 8c7c61f299
commit 39a60043d2
10 changed files with 248 additions and 36 deletions

View File

@ -0,0 +1,47 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
</profile>
</component>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -60,6 +60,7 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4) androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.androidx.material.icons.extended)
val retrofitVersion = "2.11.0" val retrofitVersion = "2.11.0"
@ -68,4 +69,5 @@ dependencies {
implementation("androidx.datastore:datastore-preferences:1.1.2") implementation("androidx.datastore:datastore-preferences:1.1.2")
implementation("androidx.datastore:datastore:1.1.2") implementation("androidx.datastore:datastore:1.1.2")
implementation("androidx.compose.runtime:runtime-livedata:1.7.8") implementation("androidx.compose.runtime:runtime-livedata:1.7.8")
implementation("io.coil-kt:coil-compose:2.0.0-rc01")
} }

View File

@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
@ -26,9 +27,12 @@ import com.example.nto_minipigs.ui.screens.Main.MainScreen
import com.example.nto_minipigs.ui.screens.Main.MainViewModel import com.example.nto_minipigs.ui.screens.Main.MainViewModel
import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ -46,19 +50,17 @@ class MainActivity : ComponentActivity() {
val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] val loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java]
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java] val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
val token by dataStore.token.collectAsState("") val token = dataStore.getToken()
Log.d("token", token.toString()) Log.d("token", token.toString())
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = if(token == null) Login else Main startDestination = if(token == "") Login else Main
// startDestination = Login
) { ) {
composable<Login> { LoginScreen( onNavigateToMain = { navController.popBackStack(); navController.navigate(route = Main) }, viewModel = loginViewModel, dataStore = dataStore ) } composable<Login> { LoginScreen( onNavigateToMain = { navController.popBackStack(); navController.navigate(route = Main) }, viewModel = loginViewModel, dataStore = dataStore ) }
composable<Main> { MainScreen( viewModel = mainViewModel, token = token.toString() ) } composable<Main> { MainScreen( viewModel = mainViewModel, dataStore = dataStore, navController = navController ) }
}
LaunchedEffect(Unit) {
dataStore.loadToken()
} }
} }
} }
@ -68,14 +70,10 @@ class MainActivity : ComponentActivity() {
class UserData(private val context: Context) { class UserData(private val context: Context) {
val Context.dataStore by preferencesDataStore("user_data") val Context.dataStore by preferencesDataStore("user_data")
val token = MutableStateFlow(context.dataStore.data.map { preferences -> fun getToken():String {
preferences[tokenKey] return runBlocking { context.dataStore.data.map { preferences ->
})
public fun loadToken() {
runBlocking { token.value = context.dataStore.data.map { preferences ->
preferences[tokenKey] preferences[tokenKey]
}} }.first().toString()}
} }
suspend fun updateToken(data:String) = suspend fun updateToken(data:String) =

View File

@ -3,5 +3,5 @@ package com.example.nto_minipigs.core
object Constants { object Constants {
const val SHARED_PREFS = "shared_prefs" const val SHARED_PREFS = "shared_prefs"
const val EMAIL_KEY = "email_key" const val EMAIL_KEY = "email_key"
const val SERVER_ADDRESS = "http://10.6.66.120:5000" const val SERVER_ADDRESS = "http:///192.168.99.212:5000"
} }

View File

@ -34,7 +34,7 @@ fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataSto
) { ) {
Text( Text(
text = "MiniPigs", text = "MiniPigs",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.displayMedium,
modifier = Modifier.padding(bottom = 36.dp) modifier = Modifier.padding(bottom = 36.dp)
) )

View File

@ -18,6 +18,7 @@ class LoginViewModel :ViewModel() {
val response = serviceApi.login(auth) val response = serviceApi.login(auth)
if(response.isSuccessful) { if(response.isSuccessful) {
dataStore.updateToken(response.body()?.token.toString()) dataStore.updateToken(response.body()?.token.toString())
// dataStore.updateToken("")
func() func()
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -1,13 +1,39 @@
package com.example.nto_minipigs.ui.screens.Main package com.example.nto_minipigs.ui.screens.Main
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
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.aspectRatio
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.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Logout
import androidx.compose.material.icons.filled.BookmarkRemove
import androidx.compose.material.icons.outlined.Logout
import androidx.compose.material.icons.outlined.QrCode
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.Card
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -21,39 +47,167 @@ import androidx.compose.ui.Modifier
import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import coil.compose.rememberAsyncImagePainter
import com.example.nto_minipigs.Login
import com.example.nto_minipigs.UserData import com.example.nto_minipigs.UserData
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
@Composable @Composable
fun MainScreen( viewModel: MainViewModel, token: String?) { fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: NavController) {
Nto_minipigsTheme { Nto_minipigsTheme {
val data = viewModel.data.observeAsState() val data = viewModel.data.observeAsState()
val token = dataStore.getToken()
val coroutineScope = rememberCoroutineScope()
Surface { Surface {
Column( when(val result = data.value){
modifier = Modifier.fillMaxSize(), is NetworkResponse.Error -> {
verticalArrangement = Arrangement.Center, Text(text = result.message)
horizontalAlignment = Alignment.CenterHorizontally, }
) { NetworkResponse.Loading -> {
when(val result = data.value){ Column(
is NetworkResponse.Error -> { modifier = Modifier.fillMaxSize(),
Text(text = result.message) verticalArrangement = Arrangement.Center,
} horizontalAlignment = Alignment.CenterHorizontally,
NetworkResponse.Loading -> { ) {
CircularProgressIndicator() CircularProgressIndicator()
} }
is NetworkResponse.Success -> {
Text(text = result.data.toString())
}
null -> {}
} }
is NetworkResponse.Success -> {
Column (
modifier = Modifier.fillMaxSize()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(top = 40.dp)
.height(200.dp),
) {
IconButton(
onClick = { coroutineScope.launch { dataStore.updateToken("") }; navController.popBackStack(); navController.navigate(Login) },
modifier = Modifier
.align(Alignment.TopEnd)
.size(20.dp)
.aspectRatio(1f)
.offset(x = -30.dp, y = 40.dp)
) {
Icon(
Icons.AutoMirrored.Outlined.Logout,
contentDescription = null,
tint = MaterialTheme.colorScheme.error,
modifier = Modifier
.fillMaxSize()
.shadow(7.dp)
) }
Button(
onClick = { viewModel.Fetch(token) }, Row(
shape = RoundedCornerShape(12.dp), modifier = Modifier.fillMaxSize(),
) { verticalAlignment = Alignment.CenterVertically
Text(text = "Sign In", style = MaterialTheme.typography.bodyLarge) ) {
Column (
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(start = 30.dp)
.size(120.dp)
.aspectRatio(1f)
.background(MaterialTheme.colorScheme.primaryContainer, CircleShape)
) {
Image(
painter = rememberAsyncImagePainter(result.data.photo),
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = Modifier.size(105.dp).clip(CircleShape)
)
}
Column(
modifier = Modifier
.padding(horizontal = 25.dp)
) {
Text(
text = result.data.lastVisit,
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Light
)
Text(
text = result.data.name,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Medium
)
Text(
text = result.data.position,
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Normal
)
}
}
}
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainerLow, RoundedCornerShape(topEnd = 24.dp , topStart = 24.dp))
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 20.dp)
.padding(top = 8.dp)
.verticalScroll(rememberScrollState())
) {
for(i in 1..24) {
OutlinedCard(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp)
) {
Text(
text = "4am 141",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Light,
modifier = Modifier
.padding(start = 16.dp)
.padding(top = 12.dp)
)
Text(
text = "Dildos factory",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Normal,
modifier = Modifier
.padding(start = 16.dp)
.padding(bottom = 12.dp)
)
}
}
}
Button(
onClick = { },
shape = CircleShape,
modifier = Modifier
.align(Alignment.BottomEnd)
.size(80.dp)
.aspectRatio(1f)
.offset(x = -30.dp, y = -80.dp)
.shadow(7.dp)
) {
Icon(Icons.Outlined.QrCode, contentDescription = null, Modifier.size(60.dp))
}
}
}
} }
null -> {}
} }
} }

View File

@ -17,7 +17,6 @@ class MainViewModel: ViewModel() {
val data : LiveData<NetworkResponse<User>> = _data val data : LiveData<NetworkResponse<User>> = _data
fun Fetch(token: String?) { fun Fetch(token: String?) {
Log.d("penis", token.toString())
_data.value = NetworkResponse.Loading _data.value = NetworkResponse.Loading
viewModelScope.launch { viewModelScope.launch {
@ -37,6 +36,10 @@ class MainViewModel: ViewModel() {
} }
} }
} }
fun Logout() {
}
} }
sealed class NetworkResponse<out T> { sealed class NetworkResponse<out T> {

View File

@ -24,6 +24,7 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended"}
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }