Compare commits

..

1 Commits
main ... design

Author SHA1 Message Date
203e46492e add logo 2025-02-20 16:45:31 +03:00
16 changed files with 96 additions and 125 deletions

Binary file not shown.

View File

@ -33,7 +33,6 @@ import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.datastore.preferences.core.booleanPreferencesKey
import com.example.nto_minipigs.ui.screens.QR.QRResultScreen import com.example.nto_minipigs.ui.screens.QR.QRResultScreen
import com.example.nto_minipigs.ui.screens.QR.QRScreen import com.example.nto_minipigs.ui.screens.QR.QRScreen
import com.example.nto_minipigs.ui.screens.QR.QRViewModel import com.example.nto_minipigs.ui.screens.QR.QRViewModel
@ -55,7 +54,9 @@ class MainActivity : ComponentActivity() {
val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java] val mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
val qrViewModel = ViewModelProvider(this)[QRViewModel::class.java] val qrViewModel = ViewModelProvider(this)[QRViewModel::class.java]
val token = dataStore.getLogin() val token = dataStore.getToken()
Log.d("token", token.toString())
NavHost( NavHost(
navController = navController, navController = navController,
@ -63,7 +64,7 @@ class MainActivity : ComponentActivity() {
) { ) {
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, dataStore = dataStore, navController = navController ) } composable<Main> { MainScreen( viewModel = mainViewModel, dataStore = dataStore, navController = navController ) }
composable<QR> { QRScreen( navController = navController, viewModel = qrViewModel, dataStore = dataStore) } composable<QR> { QRScreen( navController = navController, viewModel = qrViewModel) }
composable<QRResult> { QRResultScreen( navController = navController, viewModel = qrViewModel ) } composable<QRResult> { QRResultScreen( navController = navController, viewModel = qrViewModel ) }
} }
} }
@ -85,46 +86,8 @@ class UserData(private val context: Context) {
settings[tokenKey] = data settings[tokenKey] = data
} }
fun getLogin():String {
return runBlocking { context.dataStore.data.map { preferences ->
preferences[loginKey]
}.first().toString()}
}
suspend fun updateLogin(data:String) =
context.dataStore.edit { settings ->
settings[loginKey] = data
}
fun getPassword():String {
return runBlocking { context.dataStore.data.map { preferences ->
preferences[passwordKey]
}.first().toString()}
}
suspend fun updatePassword(data:String) =
context.dataStore.edit { settings ->
settings[passwordKey] = data
}
fun getAdmin():Boolean {
return runBlocking {
context.dataStore.data.map { preferences ->
preferences[adminKey]
}.first() == true
}
}
suspend fun updateAdmin(data:Boolean) =
context.dataStore.edit { settings ->
settings[adminKey] = data
}
companion object { companion object {
val tokenKey = stringPreferencesKey("Bearer") val tokenKey = stringPreferencesKey("Bearer")
val loginKey = stringPreferencesKey("Login")
val passwordKey = stringPreferencesKey("Password")
val adminKey = booleanPreferencesKey("IsAdmin")
} }
} }

View File

@ -1,7 +1,7 @@
package com.example.nto_minipigs.Retrofit package com.example.nto_minipigs.Retrofit
import com.example.nto_minipigs.Retrofit.Models.Auth import com.example.nto_minipigs.Retrofit.Models.Auth
import com.example.nto_minipigs.Retrofit.Models.AuthResponse import com.example.nto_minipigs.Retrofit.Models.Data
import com.example.nto_minipigs.Retrofit.Models.Door import com.example.nto_minipigs.Retrofit.Models.Door
import com.example.nto_minipigs.Retrofit.Models.DoorResponse import com.example.nto_minipigs.Retrofit.Models.DoorResponse
import com.example.nto_minipigs.Retrofit.Models.User import com.example.nto_minipigs.Retrofit.Models.User
@ -18,12 +18,12 @@ public interface ApiService {
@GET("/api/{LOGIN}/auth") @GET("/api/{LOGIN}/auth")
suspend fun auth(@Path("LOGIN") login: String): ResponseBody suspend fun auth(@Path("LOGIN") login: String): ResponseBody
@GET("/api/info/") @GET("/api/info")
suspend fun info(@Header("Authorization") token: String): Response<User> suspend fun info(@Header("Authorization") token: String): Response<User>
@PATCH("/api/open/") @PATCH("/api/open")
suspend fun open(@Header("Authorization") token: String, @Body data: Long): Response<DoorResponse> suspend fun open(@Body data: Door): Response<DoorResponse>
@POST("/api/login/") @POST("/api/login")
suspend fun login(@Body data: Auth): Response<AuthResponse> suspend fun login(@Body data: Auth): Response<Data>
} }

View File

@ -1,5 +1,5 @@
package com.example.nto_minipigs.Retrofit.Models package com.example.nto_minipigs.Retrofit.Models
data class AuthResponse( data class Data(
val admin: Boolean val token: String
) )

View File

@ -1,5 +1,5 @@
package com.example.nto_minipigs.Retrofit.Models package com.example.nto_minipigs.Retrofit.Models
data class Door( data class Door(
val id: Long val id: String
) )

View File

@ -1,8 +0,0 @@
package com.example.nto_minipigs.Retrofit.Models
data class Entry(
val id: Long,
val employee: Long,
val time: String,
val place: Place,
)

View File

@ -1,7 +0,0 @@
package com.example.nto_minipigs.Retrofit.Models
data class Place(
val id: Long,
val value: Long,
val name: String,
)

View File

@ -7,6 +7,5 @@ data class User(
val password: String, val password: String,
val name: String, val name: String,
val photo: String, val photo: String,
val position: String, val position: String
val entries: ArrayList<Entry>
) )

View File

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

View File

@ -1,10 +1,13 @@
package com.example.nto_minipigs.ui.screens.Login package com.example.nto_minipigs.ui.screens.Login
import androidx.annotation.FontRes import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -20,10 +23,10 @@ import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.nto_minipigs.R
import com.example.nto_minipigs.UserData import com.example.nto_minipigs.UserData
@Composable @Composable
@ -36,12 +39,24 @@ fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataSto
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
){
Image(
painter = painterResource(id = R.drawable.heel),
contentDescription = "",
modifier = Modifier
.size(width = 190.dp, height = 145.dp)
.padding(bottom = 90.dp)
)
}
Text( Text(
text = "MiniPigs", text = "MiniPigs",
style = MaterialTheme.typography.displayMedium, style = MaterialTheme.typography.displayMedium,
fontWeight = FontWeight.ExtraBold,
fontStyle = FontStyle.Italic,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(bottom = 36.dp) modifier = Modifier.padding(bottom = 36.dp)
) )
@ -60,7 +75,7 @@ fun LoginScreen(onNavigateToMain: () -> Unit, viewModel: LoginViewModel, dataSto
value = password, value = password,
onValueChange = { password = it }, onValueChange = { password = it },
label = { Text("Password") }, label = { Text("Password") },
modifier = Modifier.padding(bottom = 16.dp), modifier = Modifier.padding(bottom = 12.dp),
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
) )

View File

@ -17,11 +17,7 @@ class LoginViewModel :ViewModel() {
val auth = Auth(login, password) val auth = Auth(login, password)
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.updateLogin(login)
dataStore.updatePassword(password)
Log.d("yenis", (response.body()?.admin == true).toString())
dataStore.updateAdmin(response.body()?.admin == true)
// dataStore.updateToken("") // dataStore.updateToken("")
func() func()
} }

View File

@ -1,8 +1,8 @@
package com.example.nto_minipigs.ui.screens.Main package com.example.nto_minipigs.ui.screens.Main
import android.util.Log
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background 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.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -15,30 +15,43 @@ 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.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape 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.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Logout 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.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.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard import androidx.compose.material3.OutlinedCard
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
import androidx.compose.material3.rememberDateRangePickerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
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
@ -47,7 +60,7 @@ import coil.compose.rememberAsyncImagePainter
import com.example.nto_minipigs.Login import com.example.nto_minipigs.Login
import com.example.nto_minipigs.QR import com.example.nto_minipigs.QR
import com.example.nto_minipigs.UserData import com.example.nto_minipigs.UserData
import com.example.nto_minipigs.ui.theme.Nto_minipigsTheme import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -56,8 +69,6 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
Nto_minipigsTheme { Nto_minipigsTheme {
val data = viewModel.data.observeAsState() val data = viewModel.data.observeAsState()
val token = dataStore.getToken() val token = dataStore.getToken()
val login = dataStore.getLogin()
val password = dataStore.getPassword()
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
Surface { Surface {
when(val result = data.value){ when(val result = data.value){
@ -74,7 +85,6 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
} }
} }
is NetworkResponse.Success -> { is NetworkResponse.Success -> {
Log.d("yenis", result.data.entries.toString())
Column ( Column (
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
@ -85,13 +95,7 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
.height(200.dp), .height(200.dp),
) { ) {
IconButton( IconButton(
onClick = { coroutineScope.launch { onClick = { coroutineScope.launch { dataStore.updateToken("") }; navController.popBackStack(); navController.navigate(Login) },
dataStore.updateToken("");
dataStore.updateLogin("");
dataStore.updateAdmin(false);
dataStore.updatePassword("") };
navController.popBackStack();
navController.navigate(Login) },
modifier = Modifier modifier = Modifier
.align(Alignment.TopEnd) .align(Alignment.TopEnd)
.size(20.dp) .size(20.dp)
@ -157,23 +161,21 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
.fillMaxSize() .fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainerLow, RoundedCornerShape(topEnd = 24.dp , topStart = 24.dp)) .background(MaterialTheme.colorScheme.surfaceContainerLow, RoundedCornerShape(topEnd = 24.dp , topStart = 24.dp))
) { ) {
LazyColumn( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxSize()
.padding(horizontal = 20.dp) .padding(horizontal = 20.dp)
.padding(top = 8.dp) .padding(top = 8.dp)
.verticalScroll(rememberScrollState())
) { ) {
items( for(i in 1..24) {
items = result.data.entries,
key = { item -> item.id }
) { entry ->
OutlinedCard( OutlinedCard(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 12.dp) .padding(top = 12.dp)
) { ) {
Text( Text(
text = entry.time, text = "4am 141",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Light, fontWeight = FontWeight.Light,
modifier = Modifier modifier = Modifier
@ -181,7 +183,7 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
.padding(top = 12.dp) .padding(top = 12.dp)
) )
Text( Text(
text = entry.place.name, text = "Dildos factory",
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Normal, fontWeight = FontWeight.Normal,
modifier = Modifier modifier = Modifier
@ -192,7 +194,7 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
} }
} }
Button( Button(
onClick = { navController.navigate(QR) }, onClick = {navController.navigate(QR) },
shape = CircleShape, shape = CircleShape,
modifier = Modifier modifier = Modifier
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
@ -211,7 +213,7 @@ fun MainScreen( viewModel: MainViewModel, dataStore: UserData, navController: Na
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.Fetch(login, password) viewModel.Fetch(token)
} }
} }
} }

View File

@ -1,13 +1,14 @@
package com.example.nto_minipigs.ui.screens.Main package com.example.nto_minipigs.ui.screens.Main
import RetrofitClient import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.nto_minipigs.Retrofit.Models.Auth
import com.example.nto_minipigs.Retrofit.Models.User import com.example.nto_minipigs.Retrofit.Models.User
import com.example.nto_minipigs.UserData
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.Credentials
class MainViewModel: ViewModel() { class MainViewModel: ViewModel() {
private val serviceApi = RetrofitClient.apiService private val serviceApi = RetrofitClient.apiService
@ -15,14 +16,13 @@ class MainViewModel: ViewModel() {
private val _data = MutableLiveData<NetworkResponse<User>>() private val _data = MutableLiveData<NetworkResponse<User>>()
val data : LiveData<NetworkResponse<User>> = _data val data : LiveData<NetworkResponse<User>> = _data
fun Fetch(login: String?, password: String?) { fun Fetch(token: String?) {
_data.value = NetworkResponse.Loading _data.value = NetworkResponse.Loading
var basic = Credentials.basic(login.toString(), password.toString())
viewModelScope.launch { viewModelScope.launch {
if(basic != "") { if(token != null) {
try { try {
val response = serviceApi.info(basic) val response = serviceApi.info(token)
if(response.isSuccessful) { if(response.isSuccessful) {
response.body()?.let { response.body()?.let {
_data.value = NetworkResponse.Success(it) _data.value = NetworkResponse.Success(it)

View File

@ -14,20 +14,15 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.datastore.core.DataStore
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.nto_minipigs.QRResult import com.example.nto_minipigs.QRResult
import com.example.nto_minipigs.UserData
@Composable @Composable
fun QRScreen(navController: NavController, viewModel: QRViewModel, dataStore: UserData) { fun QRScreen(navController: NavController, viewModel: QRViewModel) {
var scanFlag by remember { var scanFlag by remember {
mutableStateOf(false) mutableStateOf(false)
} }
val login = dataStore.getLogin()
val password = dataStore.getPassword()
AndroidView( AndroidView(
factory = { context -> factory = { context ->
CompoundBarcodeView(context).apply { CompoundBarcodeView(context).apply {
@ -45,8 +40,7 @@ fun QRScreen(navController: NavController, viewModel: QRViewModel, dataStore: Us
Log.d("penis", barCodeOrQr) Log.d("penis", barCodeOrQr)
scanFlag = true scanFlag = true
this.pause() this.pause()
viewModel.Fetch(barCodeOrQr)
viewModel.Fetch(barCodeOrQr.toLong(), login, password)
navController.navigate(QRResult) navController.navigate(QRResult)
} }
//If you don't put this scanFlag = false, it will never work again. //If you don't put this scanFlag = false, it will never work again.

View File

@ -4,11 +4,11 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.example.nto_minipigs.Retrofit.Models.Auth import com.example.nto_minipigs.Retrofit.Models.Data
import com.example.nto_minipigs.Retrofit.Models.Door import com.example.nto_minipigs.Retrofit.Models.Door
import com.example.nto_minipigs.Retrofit.Models.DoorResponse import com.example.nto_minipigs.Retrofit.Models.DoorResponse
import com.example.nto_minipigs.Retrofit.Models.User
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.Credentials
class QRViewModel: ViewModel() { class QRViewModel: ViewModel() {
private val serviceApi = RetrofitClient.apiService private val serviceApi = RetrofitClient.apiService
@ -16,14 +16,14 @@ class QRViewModel: ViewModel() {
private val _data = MutableLiveData<NetworkResponse<DoorResponse>>() private val _data = MutableLiveData<NetworkResponse<DoorResponse>>()
val data : LiveData<NetworkResponse<DoorResponse>> = _data val data : LiveData<NetworkResponse<DoorResponse>> = _data
fun Fetch(id: Long, login:String, password:String) { fun Fetch(id: String) {
_data.value = NetworkResponse.Loading _data.value = NetworkResponse.Loading
viewModelScope.launch { viewModelScope.launch {
if(id != null) { if(id != null) {
try { try {
var basic = Credentials.basic(login.toString(), password.toString()) val request = Door(id)
val response = serviceApi.open(basic, id) val response = serviceApi.open(request)
if(response.isSuccessful) { if(response.isSuccessful) {
response.body()?.let { response.body()?.let {
_data.value = NetworkResponse.Success(it) _data.value = NetworkResponse.Success(it)

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="102dp"
android:height="64dp"
android:viewportWidth="102"
android:viewportHeight="64">
<path
android:pathData="M0.07,32a50.49,32 0,1 0,100.98 0a50.49,32 0,1 0,-100.98 0z"
android:fillColor="#FFD0D0"/>
<path
android:pathData="M82.56,32C82.56,37.89 77.78,42.67 71.89,42.67C66,42.67 61.22,37.89 61.22,32C61.22,26.11 66,21.33 71.89,21.33C77.78,21.33 82.56,26.11 82.56,32Z"
android:fillColor="#E77171"/>
<path
android:pathData="M29.22,32m-10.67,0a10.67,10.67 0,1 1,21.33 0a10.67,10.67 0,1 1,-21.33 0"
android:fillColor="#E77171"/>
</vector>