feat: moving to ktor and kotlin
This commit is contained in:
		
							parent
							
								
									5adcbadb5d
								
							
						
					
					
						commit
						4b95caf144
					
				| @ -37,6 +37,14 @@ android { | |||||||
| dependencies { | dependencies { | ||||||
|     defaultLibrary() |     defaultLibrary() | ||||||
| 
 | 
 | ||||||
|  |     val ktorClientCore = "3.0.3" | ||||||
|  | 
 | ||||||
|  |     implementation("io.ktor:ktor-client-cio:${ktorClientCore}") | ||||||
|  |     implementation("io.ktor:ktor-client-content-negotiation:${ktorClientCore}") | ||||||
|  |     implementation("io.ktor:ktor-client-core:${ktorClientCore}") | ||||||
|  |     implementation("io.ktor:ktor-client-logging:${ktorClientCore}") | ||||||
|  |     implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorClientCore}") | ||||||
|  | 
 | ||||||
|     implementation(Dependencies.AndroidX.activity) |     implementation(Dependencies.AndroidX.activity) | ||||||
|     implementation(Dependencies.AndroidX.fragment) |     implementation(Dependencies.AndroidX.fragment) | ||||||
|     implementation(Dependencies.AndroidX.constraintLayout) |     implementation(Dependencies.AndroidX.constraintLayout) | ||||||
| @ -49,7 +57,7 @@ dependencies { | |||||||
| 
 | 
 | ||||||
|     implementation("com.squareup.picasso:picasso:2.8") |     implementation("com.squareup.picasso:picasso:2.8") | ||||||
|     implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") |     implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1") | ||||||
|     implementation("androidx.datastore:datastore-preferences:1.1.1") |     implementation("androidx.datastore:datastore-preferences:1.1.2") | ||||||
|     implementation("com.google.mlkit:barcode-scanning:17.3.0") |     implementation("com.google.mlkit:barcode-scanning:17.3.0") | ||||||
| 
 | 
 | ||||||
|     val cameraX = "1.3.4" |     val cameraX = "1.3.4" | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| package ru.myitschool.work.core | package ru.myitschool.work.core | ||||||
| // БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ | // БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ | ||||||
| object Constants { | object Constants { | ||||||
|     const val SERVER_ADDRESS = "http://192.168.1.6:8080" |     const val SERVER_ADDRESS = "http://192.168.1.103:8080" | ||||||
| } | } | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | package ru.myitschool.work.data | ||||||
|  | 
 | ||||||
|  | import ru.myitschool.work.data.local.CredentialsLocalDataSource | ||||||
|  | import ru.myitschool.work.domain.entities.QrEntity | ||||||
|  | import ru.myitschool.work.domain.qr.QrRepository | ||||||
|  | 
 | ||||||
|  | class QrRepositoryImpl( | ||||||
|  |     private val networkDataSource: QrNetworkDataSource, | ||||||
|  |     private val credentialsLocalDataSource: CredentialsLocalDataSource | ||||||
|  | ) : QrRepository { | ||||||
|  | 
 | ||||||
|  |     override suspend fun pushQr(qrEntity: QrEntity): Result<Unit> { | ||||||
|  |         return networkDataSource.pushQr(qrEntity, credentialsLocalDataSource.authData!!) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,46 @@ | |||||||
|  | package ru.myitschool.work.data | ||||||
|  | 
 | ||||||
|  | import ru.myitschool.work.data.local.CredentialsLocalDataSource | ||||||
|  | import ru.myitschool.work.data.local.UserLocalDataSource | ||||||
|  | import ru.myitschool.work.domain.entities.UserEntity | ||||||
|  | import ru.myitschool.work.domain.login.LoginRepository | ||||||
|  | import ru.myitschool.work.data.network.UserNetworkDataSource | ||||||
|  | import ru.myitschool.work.domain.user.UserRepository | ||||||
|  | 
 | ||||||
|  | class UserRepositoryImpl( | ||||||
|  |     private val credentialsLocalDataSource: CredentialsLocalDataSource, | ||||||
|  |     private val userLocalDatSource: UserLocalDataSource, | ||||||
|  |     private val networkDataSource: UserNetworkDataSource | ||||||
|  | ) : LoginRepository, UserRepository { | ||||||
|  | 
 | ||||||
|  |     override suspend fun login(login: String, password: String): Result<Unit> { | ||||||
|  | 
 | ||||||
|  |         return runCatching { | ||||||
|  |             networkDataSource.login(credentialsLocalDataSource.setAuthData(login, password)) | ||||||
|  |                 .onSuccess { dto -> | ||||||
|  |                     userLocalDatSource.cacheData( | ||||||
|  |                         UserEntity( | ||||||
|  |                             id = dto.id ?: error("Null user id"), | ||||||
|  |                             name = dto.name ?: error("Null user name"), | ||||||
|  |                             lastVisit = dto.lastVisit ?: error("Null user lastVisit"), | ||||||
|  |                             photoUrl = dto.photoUrl ?: error("Null user photoUrl"), | ||||||
|  |                             position = dto.position ?: error("Null user position") | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun logout() { | ||||||
|  |         credentialsLocalDataSource.clear() | ||||||
|  |         userLocalDatSource.clear() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun isUserExist(login: String): Result<Boolean> { | ||||||
|  |         return networkDataSource.isUserExist(login) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override suspend fun getCurrentUser(): UserEntity { | ||||||
|  |         return userLocalDatSource.getUser()!! | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,80 +0,0 @@ | |||||||
| package ru.myitschool.work.data; |  | ||||||
| 
 |  | ||||||
| import androidx.annotation.NonNull; |  | ||||||
| 
 |  | ||||||
| import java.util.function.Consumer; |  | ||||||
| 
 |  | ||||||
| import ru.myitschool.work.data.dto.QrDto; |  | ||||||
| import ru.myitschool.work.data.network.RetrofitFactory; |  | ||||||
| import ru.myitschool.work.data.source.Credentials; |  | ||||||
| import ru.myitschool.work.data.source.UserApi; |  | ||||||
| import ru.myitschool.work.domain.entities.QrEntity; |  | ||||||
| import ru.myitschool.work.domain.entities.Status; |  | ||||||
| import ru.myitschool.work.domain.entities.UserEntity; |  | ||||||
| import ru.myitschool.work.domain.login.LoginRepository; |  | ||||||
| import ru.myitschool.work.domain.qr.QrRepository; |  | ||||||
| import ru.myitschool.work.domain.user.UserRepository; |  | ||||||
| import ru.myitschool.work.utils.CallToConsumer; |  | ||||||
| 
 |  | ||||||
| public class UserRepositoryImplementation implements UserRepository, LoginRepository, QrRepository { |  | ||||||
| 
 |  | ||||||
|     private static UserRepositoryImplementation INSTANCE; |  | ||||||
|     private final UserApi userApi = RetrofitFactory.getInstance().getUserApi(); |  | ||||||
|     private final Credentials credentials = Credentials.getInstance(); |  | ||||||
| 
 |  | ||||||
|     private UserRepositoryImplementation() {} |  | ||||||
| 
 |  | ||||||
|     public static synchronized UserRepositoryImplementation getInstance() { |  | ||||||
|         if (INSTANCE == null) { |  | ||||||
|             INSTANCE = new UserRepositoryImplementation(); |  | ||||||
|         } |  | ||||||
|         return INSTANCE; |  | ||||||
|     } |  | ||||||
|     @Override |  | ||||||
|     public void getUserByLogin(@NonNull String login, @NonNull Consumer<Status<UserEntity>> callback) { |  | ||||||
| 
 |  | ||||||
|         userApi.getByLogin(login).enqueue(new CallToConsumer<>( |  | ||||||
|                 callback, |  | ||||||
|                 userDto -> { |  | ||||||
|                     if (userDto != null) { |  | ||||||
|                         final String resultLogin = userDto.login; |  | ||||||
|                         final String id = userDto.id; |  | ||||||
|                         final String name = userDto.name; |  | ||||||
|                         if (resultLogin != null && id != null && name != null) { |  | ||||||
|                             return new UserEntity( |  | ||||||
|                                     id, |  | ||||||
|                                     resultLogin, |  | ||||||
|                                     name, |  | ||||||
|                                     userDto.lastVisit, |  | ||||||
|                                     userDto.photoUrl, |  | ||||||
|                                     userDto.position |  | ||||||
|                             ); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     return null; |  | ||||||
|                 } |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void isUserExist(@NonNull String login, Consumer<Status<Void>> callback) { |  | ||||||
|         userApi.isExist(login).enqueue(new CallToConsumer<>( |  | ||||||
|                 callback, |  | ||||||
|                 dto -> null |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void logoutUser() { |  | ||||||
|         credentials.setAuthData(null); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void pushQr(@NonNull QrEntity qrEntity, @NonNull Consumer<Status<Void>> callback) { |  | ||||||
|         userApi.openDoor(qrEntity.getLogin(), |  | ||||||
|                 new QrDto(qrEntity.getQr())).enqueue(new CallToConsumer<>( |  | ||||||
|                         callback, |  | ||||||
|                         dto -> null |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,15 +1,11 @@ | |||||||
| package ru.myitschool.work.data.dto; | package ru.myitschool.work.data.dto | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.Nullable; | import kotlinx.serialization.SerialName | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
| 
 | 
 | ||||||
| import com.google.gson.annotations.SerializedName; |  | ||||||
| 
 | 
 | ||||||
| public class QrDto { | @Serializable | ||||||
|     @Nullable | data class QrDto( | ||||||
|     @SerializedName("value") |     @SerialName("value") | ||||||
|     public String code; |     val code: String | ||||||
| 
 | ) | ||||||
|     public QrDto(@Nullable String code) { |  | ||||||
|         this.code = code; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -5,6 +5,9 @@ import androidx.annotation.Nullable; | |||||||
| 
 | 
 | ||||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||||
| 
 | 
 | ||||||
|  | import kotlinx.serialization.Serializable; | ||||||
|  | 
 | ||||||
|  | @Serializable | ||||||
| public class UserDto { | public class UserDto { | ||||||
| 
 | 
 | ||||||
|     @Nullable |     @Nullable | ||||||
|  | |||||||
| @ -0,0 +1,35 @@ | |||||||
|  | package ru.myitschool.work.data.local; | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.NonNull; | ||||||
|  | import androidx.annotation.Nullable; | ||||||
|  | 
 | ||||||
|  | public class CredentialsLocalDataSource { | ||||||
|  | 
 | ||||||
|  |     private static CredentialsLocalDataSource INSTANCE; | ||||||
|  | 
 | ||||||
|  |     private CredentialsLocalDataSource() {} | ||||||
|  | 
 | ||||||
|  |     public static synchronized CredentialsLocalDataSource getInstance() { | ||||||
|  |         if (INSTANCE == null) { | ||||||
|  |             INSTANCE = new CredentialsLocalDataSource(); | ||||||
|  |         } | ||||||
|  |         return INSTANCE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Nullable | ||||||
|  |     private String authData = null; | ||||||
|  | 
 | ||||||
|  |     public String setAuthData(@NonNull String login, @NonNull String password) { | ||||||
|  |         this.authData = okhttp3.Credentials.basic(login, password); | ||||||
|  |         return this.authData; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void clear() { | ||||||
|  |         this.authData = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Nullable | ||||||
|  |     public String getAuthData() { | ||||||
|  |         return authData; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | package ru.myitschool.work.data.local | ||||||
|  | 
 | ||||||
|  | import ru.myitschool.work.domain.entities.UserEntity | ||||||
|  | 
 | ||||||
|  | object UserLocalDataSource { | ||||||
|  | 
 | ||||||
|  |     private var currentUser: UserEntity? = null | ||||||
|  | 
 | ||||||
|  |     fun cacheData(user: UserEntity) { | ||||||
|  |         currentUser = user | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun getUser(): UserEntity? { | ||||||
|  |         return currentUser | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun clear() { | ||||||
|  |         currentUser = null | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package ru.myitschool.work.data.network | ||||||
|  | 
 | ||||||
|  | import android.util.Log | ||||||
|  | import io.ktor.client.HttpClient | ||||||
|  | import io.ktor.client.engine.cio.CIO | ||||||
|  | import io.ktor.client.plugins.contentnegotiation.ContentNegotiation | ||||||
|  | import io.ktor.client.plugins.defaultRequest | ||||||
|  | import io.ktor.client.plugins.logging.LogLevel | ||||||
|  | import io.ktor.client.plugins.logging.Logger | ||||||
|  | import io.ktor.client.plugins.logging.Logging | ||||||
|  | import io.ktor.http.ContentType | ||||||
|  | import io.ktor.http.contentType | ||||||
|  | import io.ktor.serialization.kotlinx.json.json | ||||||
|  | import kotlinx.serialization.json.Json | ||||||
|  | 
 | ||||||
|  | object KtorClient { | ||||||
|  |     val client | ||||||
|  |         get() = HttpClient(CIO) { | ||||||
|  |             install(ContentNegotiation) { | ||||||
|  |                 json(Json { | ||||||
|  |                     isLenient = true | ||||||
|  |                     ignoreUnknownKeys = true | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|  |             install(Logging) { | ||||||
|  |                 logger = object : Logger { | ||||||
|  |                     override fun log(message: String) { | ||||||
|  |                         Log.d("KTOR_CLIENT", message) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 level = LogLevel.ALL | ||||||
|  |             } | ||||||
|  |             defaultRequest { | ||||||
|  |                 contentType(ContentType.Application.Json) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package ru.myitschool.work.data | ||||||
|  | 
 | ||||||
|  | import io.ktor.client.request.headers | ||||||
|  | import io.ktor.client.request.patch | ||||||
|  | import io.ktor.client.request.setBody | ||||||
|  | import io.ktor.http.ContentType | ||||||
|  | import io.ktor.http.HttpHeaders | ||||||
|  | import io.ktor.http.HttpStatusCode | ||||||
|  | import io.ktor.http.contentType | ||||||
|  | import kotlinx.coroutines.Dispatchers | ||||||
|  | import kotlinx.coroutines.withContext | ||||||
|  | import ru.myitschool.work.core.Constants | ||||||
|  | import ru.myitschool.work.data.dto.QrDto | ||||||
|  | import ru.myitschool.work.data.network.KtorClient | ||||||
|  | import ru.myitschool.work.domain.entities.QrEntity | ||||||
|  | 
 | ||||||
|  | object QrNetworkDataSource { | ||||||
|  | 
 | ||||||
|  |     suspend fun pushQr(qrEntity: QrEntity, token: String): Result<Unit>  = withContext(Dispatchers.IO) { | ||||||
|  | 
 | ||||||
|  |         runCatching { | ||||||
|  | 
 | ||||||
|  |             val response = KtorClient.client.patch("${Constants.SERVER_ADDRESS}/api/push_qr") { | ||||||
|  |                 headers { | ||||||
|  |                     append(HttpHeaders.Authorization, token) | ||||||
|  |                 } | ||||||
|  |                 contentType(ContentType.Application.Json) | ||||||
|  |                 setBody( | ||||||
|  |                     QrDto(code = qrEntity.code) | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |             if (response.status != HttpStatusCode.OK) | ||||||
|  |                 error("Status ${response.status}") | ||||||
|  |             Unit | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,28 +0,0 @@ | |||||||
| package ru.myitschool.work.data.network; |  | ||||||
| 
 |  | ||||||
| import static ru.myitschool.work.core.Constants.SERVER_ADDRESS; |  | ||||||
| 
 |  | ||||||
| import retrofit2.Retrofit; |  | ||||||
| import retrofit2.converter.gson.GsonConverterFactory; |  | ||||||
| import ru.myitschool.work.data.source.UserApi; |  | ||||||
| 
 |  | ||||||
| public class RetrofitFactory { |  | ||||||
| 
 |  | ||||||
|     private static RetrofitFactory INSTANCE; |  | ||||||
| 
 |  | ||||||
|     public static synchronized RetrofitFactory getInstance() { |  | ||||||
|         if (INSTANCE == null) { |  | ||||||
|             INSTANCE = new RetrofitFactory(); |  | ||||||
|         } |  | ||||||
|         return INSTANCE; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private final Retrofit retrofit = new Retrofit.Builder() |  | ||||||
|             .baseUrl(SERVER_ADDRESS) |  | ||||||
|             .addConverterFactory(GsonConverterFactory.create()) |  | ||||||
|             .build(); |  | ||||||
| 
 |  | ||||||
|     public UserApi getUserApi() { |  | ||||||
|         return retrofit.create(UserApi.class); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package ru.myitschool.work.data.network | ||||||
|  | 
 | ||||||
|  | import io.ktor.client.call.body | ||||||
|  | import io.ktor.client.request.get | ||||||
|  | import io.ktor.client.request.headers | ||||||
|  | import io.ktor.http.HttpHeaders | ||||||
|  | import io.ktor.http.HttpStatusCode | ||||||
|  | import kotlinx.coroutines.Dispatchers | ||||||
|  | import kotlinx.coroutines.withContext | ||||||
|  | import ru.myitschool.work.core.Constants | ||||||
|  | import ru.myitschool.work.data.dto.UserDto | ||||||
|  | 
 | ||||||
|  | object UserNetworkDataSource { | ||||||
|  | 
 | ||||||
|  |     suspend fun isUserExist(login: String): Result<Boolean> = withContext(Dispatchers.IO) { | ||||||
|  |         runCatching { | ||||||
|  |             val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/username/$login") | ||||||
|  |             result.status == HttpStatusCode.OK | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     suspend fun login(token: String): Result<UserDto> = | ||||||
|  |         withContext(Dispatchers.IO) { | ||||||
|  |             runCatching { | ||||||
|  |                 val result = KtorClient.client.get("${Constants.SERVER_ADDRESS}/api/users/login") { | ||||||
|  |                     headers { | ||||||
|  |                         append(HttpHeaders.Authorization, token) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 if (result.status != HttpStatusCode.OK) | ||||||
|  |                     error("Status ${result.status}") | ||||||
|  |                 result.body() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     suspend fun getUserByLogin() {} | ||||||
|  | } | ||||||
| @ -1,29 +0,0 @@ | |||||||
| package ru.myitschool.work.data.source; |  | ||||||
| 
 |  | ||||||
| import androidx.annotation.Nullable; |  | ||||||
| 
 |  | ||||||
| public class Credentials { |  | ||||||
| 
 |  | ||||||
|     private static Credentials INSTANCE; |  | ||||||
| 
 |  | ||||||
|     private Credentials() {} |  | ||||||
| 
 |  | ||||||
|     public static synchronized Credentials getInstance() { |  | ||||||
|         if (INSTANCE == null) { |  | ||||||
|             INSTANCE = new Credentials(); |  | ||||||
|         } |  | ||||||
|         return INSTANCE; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Nullable |  | ||||||
|     private String authData = null; |  | ||||||
| 
 |  | ||||||
|     public void setAuthData(@Nullable String authData) { |  | ||||||
|         this.authData = authData; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Nullable |  | ||||||
|     public String getAuthData() { |  | ||||||
|         return authData; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| package ru.myitschool.work.data.source; |  | ||||||
| 
 |  | ||||||
| import retrofit2.Call; |  | ||||||
| import retrofit2.http.Body; |  | ||||||
| import retrofit2.http.GET; |  | ||||||
| import retrofit2.http.PATCH; |  | ||||||
| import retrofit2.http.Path; |  | ||||||
| import ru.myitschool.work.data.dto.QrDto; |  | ||||||
| import ru.myitschool.work.data.dto.UserDto; |  | ||||||
| 
 |  | ||||||
| public interface UserApi { |  | ||||||
| 
 |  | ||||||
|     @GET("api/{login}/info") |  | ||||||
|     Call<UserDto> getByLogin(@Path("login") String login); |  | ||||||
|     @GET("api/{login}/auth") |  | ||||||
|     Call<Void> isExist(@Path("login") String login); |  | ||||||
|     @PATCH("api/{login}/open/") |  | ||||||
|     Call<Void> openDoor(@Path("login") String login, @Body QrDto qrDto); |  | ||||||
| } |  | ||||||
| @ -1,27 +1,5 @@ | |||||||
| package ru.myitschool.work.domain.entities; | package ru.myitschool.work.domain.entities | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | data class QrEntity( | ||||||
| 
 |     val code: String | ||||||
| public class QrEntity { | ) | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     private final String login; |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     public String getQr() { |  | ||||||
|         return qr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     private final String qr; |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     public String getLogin() { |  | ||||||
|         return login; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public QrEntity(@NonNull String login, @NonNull String qr) { |  | ||||||
|         this.login = login; |  | ||||||
|         this.qr = qr; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,65 +1,9 @@ | |||||||
| package ru.myitschool.work.domain.entities; | package ru.myitschool.work.domain.entities | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | data class UserEntity( | ||||||
| 
 |     val id: String, | ||||||
| import javax.annotation.Nullable; |     val name: String, | ||||||
| 
 |     val lastVisit: String, | ||||||
| public class UserEntity { |     val photoUrl: String, | ||||||
| 
 |     val position: String, | ||||||
|     @NonNull | ) | ||||||
|     private final String id; |  | ||||||
|     @NonNull |  | ||||||
|     private final String name; |  | ||||||
|     @NonNull |  | ||||||
|     private final String login; |  | ||||||
|     @Nullable |  | ||||||
|     private final String last_visit; |  | ||||||
|     @Nullable |  | ||||||
|     private final String photoUrl; |  | ||||||
|     @Nullable |  | ||||||
|     private final String position; |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     public String getId() { |  | ||||||
|         return id; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Nullable |  | ||||||
|     public String getLast_visit() { |  | ||||||
|         return last_visit; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     public String getName() { |  | ||||||
|         return name; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Nullable |  | ||||||
|     public String getPhotoUrl() { |  | ||||||
|         return photoUrl; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Nullable |  | ||||||
|     public String getPosition() { |  | ||||||
|         return position; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     public String getLogin() { |  | ||||||
|         return login; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public UserEntity( |  | ||||||
|             @NonNull String id, @NonNull String login, |  | ||||||
|             @NonNull String name, |  | ||||||
|             @Nullable String last_visit, |  | ||||||
|             @Nullable String photoUrl, |  | ||||||
|             @Nullable String position) { |  | ||||||
|         this.id = id; |  | ||||||
|         this.login = login; |  | ||||||
|         this.name = name; |  | ||||||
|         this.last_visit = last_visit; |  | ||||||
|         this.photoUrl = photoUrl; |  | ||||||
|         this.position = position; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,29 +1,11 @@ | |||||||
| package ru.myitschool.work.domain.login; | package ru.myitschool.work.domain.login | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import android.util.Log | ||||||
|  | import kotlin.math.log | ||||||
| 
 | 
 | ||||||
| import java.util.function.Consumer; | class IsUserExistUseCase( | ||||||
|  |     private val repository: LoginRepository | ||||||
|  | ) { | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.domain.entities.Status; |     suspend operator fun invoke(login: String) = repository.isUserExist(login) | ||||||
| 
 |  | ||||||
| public class IsUserExistUseCase { |  | ||||||
| 
 |  | ||||||
|     private final LoginRepository repository; |  | ||||||
| 
 |  | ||||||
|     public IsUserExistUseCase(LoginRepository repository) { |  | ||||||
|         this.repository = repository; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void execute(@NonNull String login, Consumer<Status<Boolean>> callback) { |  | ||||||
|         repository.isUserExist(login, status -> { |  | ||||||
|             boolean isAvailable = status.getStatusCode() == 200 || status.getStatusCode() == 401; |  | ||||||
|             callback.accept( |  | ||||||
|                     new Status<>( |  | ||||||
|                             status.getStatusCode(), |  | ||||||
|                             isAvailable ? status.getStatusCode() == 200 : null, |  | ||||||
|                             status.getErrors() |  | ||||||
|                     ) |  | ||||||
|             ); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| @ -1,13 +1,8 @@ | |||||||
| package ru.myitschool.work.domain.login; | package ru.myitschool.work.domain.login | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | interface LoginRepository { | ||||||
| 
 | 
 | ||||||
| import java.util.function.Consumer; |     suspend fun login(login: String, password: String) : Result<Unit> | ||||||
| 
 |     suspend fun logout() | ||||||
| import ru.myitschool.work.domain.entities.Status; |     suspend fun isUserExist(login: String): Result<Boolean> | ||||||
| 
 |  | ||||||
| public interface LoginRepository { |  | ||||||
| 
 |  | ||||||
|     void isUserExist(@NonNull String login, Consumer<Status<Void>> callback); |  | ||||||
|     void logoutUser(); |  | ||||||
| } | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package ru.myitschool.work.domain.login | ||||||
|  | 
 | ||||||
|  | class LoginUseCase( | ||||||
|  |     private val repository: LoginRepository | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     operator fun invoke(login: String, password: String) = | ||||||
|  |         repository.loginUser(login, password) | ||||||
|  | } | ||||||
| @ -1,28 +1,10 @@ | |||||||
| package ru.myitschool.work.domain.qr; | package ru.myitschool.work.domain.qr | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import ru.myitschool.work.domain.entities.QrEntity | ||||||
| 
 | 
 | ||||||
| import java.util.function.Consumer; | class PushQrUseCase( | ||||||
|  |     private val repository: QrRepository | ||||||
|  | ) { | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.domain.entities.QrEntity; |     suspend operator fun invoke(qrEntity: QrEntity) = repository.pushQr(qrEntity) | ||||||
| import ru.myitschool.work.domain.entities.Status; |  | ||||||
| 
 |  | ||||||
| public class PushQrUseCase { |  | ||||||
|     private final QrRepository repository; |  | ||||||
| 
 |  | ||||||
|     public PushQrUseCase(QrRepository repository) { |  | ||||||
|         this.repository = repository; |  | ||||||
|     } |  | ||||||
|     public void execute(@NonNull QrEntity qrEntity, Consumer<Status<Boolean>> callback) { |  | ||||||
|         repository.pushQr(qrEntity, status -> { |  | ||||||
|             boolean isOpened = status.getStatusCode() == 200 || status.getStatusCode() == 400 || status.getStatusCode() == 401; |  | ||||||
|             callback.accept( |  | ||||||
|                     new Status<>( |  | ||||||
|                             status.getStatusCode(), |  | ||||||
|                             isOpened ? status.getStatusCode() == 200 : null, |  | ||||||
|                             status.getErrors() |  | ||||||
|                     ) |  | ||||||
|             ); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| @ -1,13 +1,8 @@ | |||||||
| package ru.myitschool.work.domain.qr; | package ru.myitschool.work.domain.qr | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import ru.myitschool.work.domain.entities.QrEntity | ||||||
| 
 | 
 | ||||||
| import java.util.function.Consumer; | interface QrRepository { | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.domain.entities.QrEntity; |     suspend fun pushQr(qrEntity: QrEntity): Result<Unit> | ||||||
| import ru.myitschool.work.domain.entities.Status; |  | ||||||
| 
 |  | ||||||
| public interface QrRepository { |  | ||||||
| 
 |  | ||||||
|     void pushQr(@NonNull QrEntity qrEntity, @NonNull Consumer<Status<Void>> callback); |  | ||||||
| } | } | ||||||
| @ -5,7 +5,6 @@ import androidx.annotation.NonNull; | |||||||
| import java.util.function.Consumer; | import java.util.function.Consumer; | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.domain.entities.Status; | import ru.myitschool.work.domain.entities.Status; | ||||||
| import ru.myitschool.work.domain.entities.UserEntity; |  | ||||||
| 
 | 
 | ||||||
| public class GetUserByLoginUseCase { | public class GetUserByLoginUseCase { | ||||||
|     private final UserRepository repository; |     private final UserRepository repository; | ||||||
|  | |||||||
| @ -1,14 +1,8 @@ | |||||||
| package ru.myitschool.work.domain.user; | package ru.myitschool.work.domain.user | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; | import ru.myitschool.work.domain.entities.UserEntity | ||||||
| 
 | 
 | ||||||
| import java.util.function.Consumer; | interface UserRepository { | ||||||
| 
 | 
 | ||||||
| 
 |     suspend fun getCurrentUser(): UserEntity | ||||||
| import ru.myitschool.work.domain.entities.Status; |  | ||||||
| import ru.myitschool.work.domain.entities.UserEntity; |  | ||||||
| 
 |  | ||||||
| public interface UserRepository { |  | ||||||
| 
 |  | ||||||
|     void getUserByLogin(@NonNull String login, @NonNull Consumer<Status<UserEntity>> callback); |  | ||||||
| } | } | ||||||
| @ -6,9 +6,6 @@ import androidx.lifecycle.LiveData; | |||||||
| import androidx.lifecycle.MutableLiveData; | import androidx.lifecycle.MutableLiveData; | ||||||
| import androidx.lifecycle.ViewModel; | import androidx.lifecycle.ViewModel; | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.data.UserRepositoryImplementation; |  | ||||||
| import ru.myitschool.work.domain.login.IsUserExistUseCase; |  | ||||||
| 
 |  | ||||||
| public class LoginViewModel extends ViewModel { | public class LoginViewModel extends ViewModel { | ||||||
| 
 | 
 | ||||||
|     private final State INIT_STATE = new State(false); |     private final State INIT_STATE = new State(false); | ||||||
|  | |||||||
| @ -0,0 +1,22 @@ | |||||||
|  | package ru.myitschool.work.ui.login | ||||||
|  | 
 | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.view.View | ||||||
|  | import androidx.fragment.app.Fragment | ||||||
|  | import ru.myitschool.work.R | ||||||
|  | import ru.myitschool.work.databinding.FragmentSplashBinding | ||||||
|  | 
 | ||||||
|  | class SplashFragment: Fragment(R.layout.fragment_splash) { | ||||||
|  | 
 | ||||||
|  |     private var _binding: FragmentSplashBinding? = null | ||||||
|  |     private val binding: FragmentSplashBinding get() = _binding!! | ||||||
|  | 
 | ||||||
|  |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|  |         _binding = FragmentSplashBinding.bind(view) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onDestroy() { | ||||||
|  |         _binding = null | ||||||
|  |         super.onDestroy() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -8,7 +8,6 @@ import android.view.View; | |||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
| import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||||
| import androidx.fragment.app.FragmentManager; |  | ||||||
| import androidx.fragment.app.FragmentResultListener; | import androidx.fragment.app.FragmentResultListener; | ||||||
| import androidx.lifecycle.ViewModelProvider; | import androidx.lifecycle.ViewModelProvider; | ||||||
| import androidx.navigation.Navigation; | import androidx.navigation.Navigation; | ||||||
| @ -19,7 +18,6 @@ import java.text.MessageFormat; | |||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.R; | import ru.myitschool.work.R; | ||||||
| import ru.myitschool.work.databinding.FragmentUserBinding; | import ru.myitschool.work.databinding.FragmentUserBinding; | ||||||
| import ru.myitschool.work.domain.entities.UserEntity; |  | ||||||
| import ru.myitschool.work.ui.qr.scan.QrScanDestination; | import ru.myitschool.work.ui.qr.scan.QrScanDestination; | ||||||
| import ru.myitschool.work.utils.Utils; | import ru.myitschool.work.utils.Utils; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,8 +6,6 @@ import androidx.lifecycle.LiveData; | |||||||
| import androidx.lifecycle.MutableLiveData; | import androidx.lifecycle.MutableLiveData; | ||||||
| import androidx.lifecycle.ViewModel; | import androidx.lifecycle.ViewModel; | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.data.UserRepositoryImplementation; |  | ||||||
| import ru.myitschool.work.domain.entities.UserEntity; |  | ||||||
| import ru.myitschool.work.domain.user.GetUserByLoginUseCase; | import ru.myitschool.work.domain.user.GetUserByLoginUseCase; | ||||||
| 
 | 
 | ||||||
| public class UserViewModel extends ViewModel { | public class UserViewModel extends ViewModel { | ||||||
|  | |||||||
| @ -6,8 +6,6 @@ import androidx.lifecycle.LiveData; | |||||||
| import androidx.lifecycle.MutableLiveData; | import androidx.lifecycle.MutableLiveData; | ||||||
| import androidx.lifecycle.ViewModel; | import androidx.lifecycle.ViewModel; | ||||||
| 
 | 
 | ||||||
| import ru.myitschool.work.data.UserRepositoryImplementation; |  | ||||||
| import ru.myitschool.work.domain.entities.QrEntity; |  | ||||||
| import ru.myitschool.work.domain.entities.Status; | import ru.myitschool.work.domain.entities.Status; | ||||||
| import ru.myitschool.work.domain.qr.PushQrUseCase; | import ru.myitschool.work.domain.qr.PushQrUseCase; | ||||||
| 
 | 
 | ||||||
| @ -16,7 +14,7 @@ public class QrResultViewModel extends ViewModel { | |||||||
|     public final LiveData<State> stateLiveData = mutableStateLiveData; |     public final LiveData<State> stateLiveData = mutableStateLiveData; | ||||||
| 
 | 
 | ||||||
|     public final PushQrUseCase pushQrUseCase = new PushQrUseCase( |     public final PushQrUseCase pushQrUseCase = new PushQrUseCase( | ||||||
|             UserRepositoryImplementation.getInstance() |             QrRepositoryImplementation.getInstance() | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     public void update(@NonNull String login, @NonNull String qr) { |     public void update(@NonNull String login, @NonNull String qr) { | ||||||
|  | |||||||
| @ -33,6 +33,18 @@ | |||||||
|             android:background="@drawable/input_field" |             android:background="@drawable/input_field" | ||||||
|             android:hint="@string/login_hint" /> |             android:hint="@string/login_hint" /> | ||||||
| 
 | 
 | ||||||
|  |         <EditText | ||||||
|  |             android:inputType="textPassword" | ||||||
|  |             android:layout_marginTop="24dp" | ||||||
|  |             android:paddingHorizontal="20dp" | ||||||
|  |             android:fontFamily="@font/manrope_light" | ||||||
|  |             android:id="@+id/password" | ||||||
|  |             android:layout_width="match_parent" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:minHeight="50dp" | ||||||
|  |             android:background="@drawable/input_field" | ||||||
|  |             android:hint="@string/password_input_hint" /> | ||||||
|  | 
 | ||||||
|         <Button |         <Button | ||||||
|             android:foreground="?attr/selectableItemBackground" |             android:foreground="?attr/selectableItemBackground" | ||||||
|             android:layout_marginTop="8dp" |             android:layout_marginTop="8dp" | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								app/src/main/res/layout/fragment_splash.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/src/main/res/layout/fragment_splash.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="match_parent"> | ||||||
|  | 
 | ||||||
|  | </androidx.constraintlayout.widget.ConstraintLayout> | ||||||
| @ -5,6 +5,7 @@ | |||||||
|     android:id="@+id/nav_graph" |     android:id="@+id/nav_graph" | ||||||
|     app:startDestination="@id/loginFragment"> |     app:startDestination="@id/loginFragment"> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     <fragment |     <fragment | ||||||
|         android:id="@+id/userFragment" |         android:id="@+id/userFragment" | ||||||
|         android:name="ru.myitschool.work.ui.profile.UserFragment" |         android:name="ru.myitschool.work.ui.profile.UserFragment" | ||||||
|  | |||||||
| @ -11,4 +11,6 @@ | |||||||
|     <string name="error">Что-то пошло не так</string> |     <string name="error">Что-то пошло не так</string> | ||||||
|     <string name="logout_text">Выйти из аккаунта</string> |     <string name="logout_text">Выйти из аккаунта</string> | ||||||
|     <string name="last_visit">Последний вход: </string> |     <string name="last_visit">Последний вход: </string> | ||||||
|  |     <string name="password_input_hint">Введите пароль</string> | ||||||
|  |     <string name="register_process_button_text">Зарегестрироваться</string> | ||||||
| </resources> | </resources> | ||||||
| @ -34,7 +34,7 @@ object Version { | |||||||
| 
 | 
 | ||||||
|     object Android { |     object Android { | ||||||
|         object Sdk { |         object Sdk { | ||||||
|             const val min = 24 |             const val min = 28 | ||||||
|             const val compile = 34 |             const val compile = 34 | ||||||
|             const val target = 34 |             const val target = 34 | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 a1pha
						a1pha