|
|
@@ -3,24 +3,50 @@ package com.example.modifier.ui
|
|
|
import android.content.Context
|
|
|
import android.util.Log
|
|
|
import androidx.datastore.core.DataStore
|
|
|
-import androidx.datastore.dataStore
|
|
|
import androidx.datastore.preferences.core.Preferences
|
|
|
-import androidx.datastore.preferences.core.intPreferencesKey
|
|
|
+import androidx.datastore.preferences.core.edit
|
|
|
+import androidx.datastore.preferences.core.stringPreferencesKey
|
|
|
import androidx.datastore.preferences.preferencesDataStore
|
|
|
-import androidx.lifecycle.LiveData
|
|
|
import androidx.lifecycle.MutableLiveData
|
|
|
import androidx.lifecycle.ViewModel
|
|
|
import com.example.modifier.model.ServerConfig
|
|
|
-import com.example.modifier.repository.ServerConfigRepository
|
|
|
+import com.example.modifier.request.LoginRequest
|
|
|
+import com.example.modifier.response.ErrorResponse
|
|
|
+import com.example.modifier.response.LoginResponse
|
|
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
|
+import io.ktor.client.HttpClient
|
|
|
+import io.ktor.client.call.body
|
|
|
+import io.ktor.client.engine.okhttp.OkHttp
|
|
|
+import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
|
|
+import io.ktor.client.plugins.defaultRequest
|
|
|
+import io.ktor.client.request.post
|
|
|
+import io.ktor.client.request.setBody
|
|
|
+import io.ktor.http.ContentType
|
|
|
+import io.ktor.http.HttpStatusCode
|
|
|
+import io.ktor.http.contentType
|
|
|
+import io.ktor.serialization.kotlinx.json.json
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
|
import kotlinx.coroutines.flow.StateFlow
|
|
|
import kotlinx.coroutines.flow.asStateFlow
|
|
|
+import kotlinx.coroutines.flow.map
|
|
|
+import kotlinx.serialization.json.Json
|
|
|
import javax.inject.Inject
|
|
|
|
|
|
+val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "serverConfig")
|
|
|
+
|
|
|
@HiltViewModel
|
|
|
class LoginViewModel @Inject constructor() : ViewModel() {
|
|
|
+ val TAG = "LoginViewModel"
|
|
|
+
|
|
|
+ companion object {
|
|
|
+ val URL = stringPreferencesKey("url")
|
|
|
+ val USERNAME = stringPreferencesKey("username")
|
|
|
+ val PASSWORD = stringPreferencesKey("password")
|
|
|
+ val DEVICE_LABEL = stringPreferencesKey("device_label")
|
|
|
+ val TOKEN = stringPreferencesKey("token")
|
|
|
+ }
|
|
|
+
|
|
|
private val _uiState = MutableStateFlow(LoginUiState())
|
|
|
val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
|
|
|
val serverConfig = MutableLiveData<ServerConfig>()
|
|
|
@@ -29,16 +55,60 @@ class LoginViewModel @Inject constructor() : ViewModel() {
|
|
|
@ApplicationContext
|
|
|
lateinit var appContext: Context
|
|
|
|
|
|
- fun load() {
|
|
|
- serverConfig.postValue(ServerConfig())
|
|
|
+ suspend fun loadConfig() {
|
|
|
+ appContext.dataStore.data.map {
|
|
|
+ ServerConfig(
|
|
|
+ url = it[URL] ?: "",
|
|
|
+ username = it[USERNAME] ?: "",
|
|
|
+ password = it[PASSWORD] ?: "",
|
|
|
+ deviceLabel = it[DEVICE_LABEL] ?: "",
|
|
|
+ token = it[TOKEN] ?: ""
|
|
|
+ )
|
|
|
+ }.collect {
|
|
|
+ serverConfig.postValue(it)
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ suspend fun saveConfig() {
|
|
|
+ appContext.dataStore.edit {
|
|
|
+ it[URL] = serverConfig.value?.url ?: ""
|
|
|
+ it[USERNAME] = serverConfig.value?.username ?: ""
|
|
|
+ it[PASSWORD] = serverConfig.value?.password ?: ""
|
|
|
+ it[DEVICE_LABEL] = serverConfig.value?.deviceLabel ?: ""
|
|
|
+ it[TOKEN] = serverConfig.value?.token ?: ""
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- fun save() {
|
|
|
- if (this::appContext.isInitialized) {
|
|
|
- Log.d("LoginViewModel", "appContext is initialized")
|
|
|
- } else {
|
|
|
- Log.d("LoginViewModel", "appContext is not initialized")
|
|
|
+ suspend fun login() {
|
|
|
+ Log.d(TAG, "login")
|
|
|
+ _uiState.emit(LoginUiState(isLoading = true))
|
|
|
+ val client = HttpClient(OkHttp) {
|
|
|
+ defaultRequest {
|
|
|
+ url(serverConfig.value!!.url!!)
|
|
|
+ }
|
|
|
+ install(ContentNegotiation) {
|
|
|
+ json(Json {
|
|
|
+ prettyPrint = true
|
|
|
+ isLenient = true
|
|
|
+ ignoreUnknownKeys = true
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ val response = client.post("/api/auth/login") {
|
|
|
+ contentType(ContentType.Application.Json)
|
|
|
+ setBody(LoginRequest(serverConfig.value!!.username!!, serverConfig.value!!.password!!))
|
|
|
+ }
|
|
|
+ when (response.status) {
|
|
|
+ HttpStatusCode.OK -> {
|
|
|
+ val loginResponse = response.body<LoginResponse>()
|
|
|
+ Log.i(TAG, "response: $loginResponse")
|
|
|
+ }
|
|
|
+
|
|
|
+ else -> {
|
|
|
+ val errorResponse = response.body<ErrorResponse>()
|
|
|
+ Log.e(TAG, "error: $errorResponse")
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|