From c8ac3280e2133567e64f17effb4336587e1922ed Mon Sep 17 00:00:00 2001 From: Nikita Sutulov Date: Mon, 8 Apr 2024 13:04:02 +0300 Subject: [PATCH 1/3] almost finished user api interface Added UserApi interface with the methods needed. Three methods still need the response type to be added for them. --- .../android/data/dto/user/AddContactBody.kt | 7 + .../data/dto/user/ChangeAvatarResponse.kt | 10 ++ .../android/data/dto/user/ChangeInfoBody.kt | 9 ++ .../android/data/dto/user/ChangeRoleBody.kt | 5 + .../android/data/dto/user/ChangeUserBody.kt | 7 + .../android/data/dto/user/Contact.kt | 8 ++ .../android/data/dto/user/ContactType.kt | 12 ++ .../data/dto/user/GetContactsResponse.kt | 5 + ...tSelectiveDisciplinesBySemesterResponse.kt | 5 + .../user/GetSelectiveDisciplinesResponse.kt | 8 ++ .../data/dto/user/GetSelectiveResponse.kt | 5 + .../dto/user/PostSelectiveDisciplinesBody.kt | 5 + .../data/dto/user/RequestNewGroupBody.kt | 6 + .../android/data/dto/user/SimplifiedUser.kt | 10 ++ .../android/data/dto/user/UserGroupState.kt | 7 + .../data/dto/user/UserRemainingSelective.kt | 6 + .../android/data/dto/user/UserSelective.kt | 8 ++ .../data/dto/user/VerifyStudentBody.kt | 6 + .../android/data/remote/RetrofitClient.kt | 7 + .../android/data/remote/api/UserApi.kt | 135 ++++++++++++++++++ 20 files changed, 271 insertions(+) create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/AddContactBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeAvatarResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeInfoBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeRoleBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeUserBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/Contact.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/ContactType.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/GetContactsResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesBySemesterResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/PostSelectiveDisciplinesBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/RequestNewGroupBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/SimplifiedUser.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupState.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserRemainingSelective.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserSelective.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentBody.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/AddContactBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/AddContactBody.kt new file mode 100644 index 0000000..c1fc934 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/AddContactBody.kt @@ -0,0 +1,7 @@ +package com.fictadvisor.android.data.dto.user + +data class AddContactBody( + val name: ContactType, + val displayName: String, + val link: String +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeAvatarResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeAvatarResponse.kt new file mode 100644 index 0000000..f0d5b34 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeAvatarResponse.kt @@ -0,0 +1,10 @@ +package com.fictadvisor.android.data.dto.user + +data class ChangeAvatarResponse( + val id: String, + val email: String, + val username: String, + val telegramId: Long, + val avatar: String, + val state: UserGroupState +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeInfoBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeInfoBody.kt new file mode 100644 index 0000000..5667ca2 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeInfoBody.kt @@ -0,0 +1,9 @@ +package com.fictadvisor.android.data.dto.user + +data class ChangeInfoBody( + val firstName: String?, + val lastName: String?, + val middleName: String?, + val groupId: String?, + val state: UserGroupState? +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeRoleBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeRoleBody.kt new file mode 100644 index 0000000..4f7d9dc --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeRoleBody.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class ChangeRoleBody( + val roleId: String +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeUserBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeUserBody.kt new file mode 100644 index 0000000..2cc64d5 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/ChangeUserBody.kt @@ -0,0 +1,7 @@ +package com.fictadvisor.android.data.dto.user + +data class ChangeUserBody( + val email: String?, + val username: String?, + val state: UserGroupState? +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/Contact.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/Contact.kt new file mode 100644 index 0000000..39fe9f8 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/Contact.kt @@ -0,0 +1,8 @@ +package com.fictadvisor.android.data.dto.user + +data class Contact( + val link: String, + val id: String, + val name: ContactType, + val displayName: String +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/ContactType.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/ContactType.kt new file mode 100644 index 0000000..024653e --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/ContactType.kt @@ -0,0 +1,12 @@ +package com.fictadvisor.android.data.dto.user + +enum class ContactType { + YOUTUBE, + DISCORD, + TELEGRAM, + INSTAGRAM, + FACEBOOK, + GITHUB, + TWITTER, + MAIL +} \ No newline at end of file diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/GetContactsResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetContactsResponse.kt new file mode 100644 index 0000000..9870ca0 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetContactsResponse.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class GetContactsResponse( + val contacts: List +) \ No newline at end of file diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesBySemesterResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesBySemesterResponse.kt new file mode 100644 index 0000000..7978f51 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesBySemesterResponse.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class GetSelectiveDisciplinesBySemesterResponse( + val selective: List +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesResponse.kt new file mode 100644 index 0000000..7e434ff --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveDisciplinesResponse.kt @@ -0,0 +1,8 @@ +package com.fictadvisor.android.data.dto.user + +data class GetSelectiveDisciplinesResponse( + val availableSelectiveAmount: Int, + val year: Int, + val semester: Int, + val remainingSelective: List +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveResponse.kt new file mode 100644 index 0000000..e9c65e7 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/GetSelectiveResponse.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class GetSelectiveResponse( + val disciplines: List +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/PostSelectiveDisciplinesBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/PostSelectiveDisciplinesBody.kt new file mode 100644 index 0000000..e1e6631 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/PostSelectiveDisciplinesBody.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class PostSelectiveDisciplinesBody( + val disciplines: List +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/RequestNewGroupBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/RequestNewGroupBody.kt new file mode 100644 index 0000000..c68b895 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/RequestNewGroupBody.kt @@ -0,0 +1,6 @@ +package com.fictadvisor.android.data.dto.user + +data class RequestNewGroupBody( + val groupId: String, + val isCaptain: Boolean +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/SimplifiedUser.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/SimplifiedUser.kt new file mode 100644 index 0000000..c6bd0cb --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/SimplifiedUser.kt @@ -0,0 +1,10 @@ +package com.fictadvisor.android.data.dto.user + +data class SimplifiedUser( + val id: String, + val email: String, + val username: String, + val telegramId: Long?, + val avatar: String?, + val state: UserGroupState +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupState.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupState.kt new file mode 100644 index 0000000..ccc1895 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupState.kt @@ -0,0 +1,7 @@ +package com.fictadvisor.android.data.dto.user + +enum class UserGroupState { + APPROVED, + DECLINED, + PENDING +} diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserRemainingSelective.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserRemainingSelective.kt new file mode 100644 index 0000000..831f19d --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserRemainingSelective.kt @@ -0,0 +1,6 @@ +package com.fictadvisor.android.data.dto.user + +data class UserRemainingSelective( + val disciplineId: String, + val subjectName: String +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserSelective.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserSelective.kt new file mode 100644 index 0000000..100cea0 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserSelective.kt @@ -0,0 +1,8 @@ +package com.fictadvisor.android.data.dto.user + +data class UserSelective( + val semester: Int, + val year: Int, + val disciplines: List, + val amount: Int +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentBody.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentBody.kt new file mode 100644 index 0000000..aec210b --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentBody.kt @@ -0,0 +1,6 @@ +package com.fictadvisor.android.data.dto.user + +data class VerifyStudentBody( + val state: UserGroupState, + val isCaptain: Boolean +) diff --git a/app/src/main/java/com/fictadvisor/android/data/remote/RetrofitClient.kt b/app/src/main/java/com/fictadvisor/android/data/remote/RetrofitClient.kt index bcbcc9f..6be03eb 100644 --- a/app/src/main/java/com/fictadvisor/android/data/remote/RetrofitClient.kt +++ b/app/src/main/java/com/fictadvisor/android/data/remote/RetrofitClient.kt @@ -3,6 +3,7 @@ package com.fictadvisor.android.data.remote import com.fictadvisor.android.data.remote.api.AuthApi import com.fictadvisor.android.data.remote.api.GroupApi import com.fictadvisor.android.data.remote.api.ScheduleApi +import com.fictadvisor.android.data.remote.api.UserApi import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -73,4 +74,10 @@ object RetrofitClient { .create(ScheduleApi::class.java) } + val userApi: UserApi by lazy { + retrofitClient + .build() + .create(UserApi::class.java) + } + } diff --git a/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt b/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt new file mode 100644 index 0000000..ad4c955 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt @@ -0,0 +1,135 @@ +package com.fictadvisor.android.data.remote.api + +import com.fictadvisor.android.data.dto.TelegramDTO +import com.fictadvisor.android.data.dto.user.AddContactBody +import com.fictadvisor.android.data.dto.user.ChangeAvatarResponse +import com.fictadvisor.android.data.dto.user.ChangeInfoBody +import com.fictadvisor.android.data.dto.user.ChangeRoleBody +import com.fictadvisor.android.data.dto.user.ChangeUserBody +import com.fictadvisor.android.data.dto.user.Contact +import com.fictadvisor.android.data.dto.user.GetContactsResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesBySemesterResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveResponse +import com.fictadvisor.android.data.dto.user.PostSelectiveDisciplinesBody +import com.fictadvisor.android.data.dto.user.RequestNewGroupBody +import com.fictadvisor.android.data.dto.user.SimplifiedUser +import com.fictadvisor.android.data.dto.user.VerifyStudentBody +import okhttp3.MultipartBody +import okhttp3.ResponseBody +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.DELETE +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.Multipart +import retrofit2.http.PATCH +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Path +import retrofit2.http.Query + +interface UserApi { + @GET("/v2/users/{userId}") + suspend fun getUser( + @Header("Authorization") token: String, + @Path("userId") userId: String + ): Response + + @PATCH("/v2/users/{userId}") + suspend fun editUser( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: ChangeUserBody + ): Response + + @PATCH("/v2/users/{userId}/student") + suspend fun changeInfo( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: ChangeInfoBody + ) // TODO: response type for changeInfo() + + @POST("/v2/users/{userId}/telegram") + suspend fun linkTelegram( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: TelegramDTO + ) // TODO: response type for linkTelegram() + + @POST("/v2/users/{userId}/contacts") + suspend fun addContact( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: AddContactBody + ): Response + + @GET("/v2/users/{userId}/contacts") + suspend fun getContacts( + @Header("Authorization") token: String, + @Path("userId") userId: String + ): Response + + @DELETE("/v2/users/{userId}/contacts/{id}") + suspend fun deleteContact( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Path("id") id: String + ): Response + + @PATCH("/v2/users/{userId}/requestNewGroup") + suspend fun requestNewGroup( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: RequestNewGroupBody + ): Response + + @GET("/v2/users/{userId}/selectiveBySemesters") + suspend fun getSelectiveDisciplinesBySemester( + @Header("Authorization") token: String, + @Path("userId") userId: String + ): Response + + @POST("/v2/users/{userId}/selectiveDisciplines") + suspend fun postSelectiveDisciplines( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: PostSelectiveDisciplinesBody + ): Response + + @GET("/v2/users/{userId}/selectiveDisciplines") + suspend fun getSelectiveDisciplines( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Query("year") year: Int, + @Query("semester") semester: Int + ): Response + + @Multipart + @PATCH("/v2/users/{userId}/") + suspend fun changeAvatar( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Part avatar: MultipartBody.Part + ): Response + + @POST("/v2/users/{userId}/roles") + suspend fun setRole( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: ChangeRoleBody + ): Response + + @GET("/v2/users/{userId}/selective") + suspend fun getSelective( + @Header("Authorization") token: String, + @Path("userId") userId: String + ): Response + + @PATCH("/v2/users/{userId}/verifyStudent") + suspend fun verifyStudent( + @Header("Authorization") token: String, + @Path("userId") userId: String, + @Body body: VerifyStudentBody + ) // TODO: response type for verifyStudent() +} \ No newline at end of file From fb93827e6c552f952675d88084dce8fa9ed29740 Mon Sep 17 00:00:00 2001 From: Nikita Sutulov Date: Mon, 8 Apr 2024 15:32:02 +0300 Subject: [PATCH 2/3] finished user api interface --- .../android/data/dto/user/UserDTOResponse.kt | 14 ++++++++++++++ .../fictadvisor/android/data/dto/user/UserGroup.kt | 8 ++++++++ .../android/data/dto/user/UserGroupRole.kt | 7 +++++++ .../android/data/dto/user/VerifyStudentResponse.kt | 5 +++++ .../fictadvisor/android/data/remote/api/UserApi.kt | 10 ++++++---- 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserDTOResponse.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroup.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupRole.kt create mode 100644 app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentResponse.kt diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserDTOResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserDTOResponse.kt new file mode 100644 index 0000000..f246dde --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserDTOResponse.kt @@ -0,0 +1,14 @@ +package com.fictadvisor.android.data.dto.user + +data class UserDTOResponse( + val id: String, + val firstName: String, + val middleName: String, + val lastName: String, + val state: UserGroupState, + val username: String, + val email: String, + val avatar: String, + val telegramId: Long, + val group: UserGroup +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroup.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroup.kt new file mode 100644 index 0000000..3a2d74c --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroup.kt @@ -0,0 +1,8 @@ +package com.fictadvisor.android.data.dto.user + +data class UserGroup( + val id: String, + val code: String, + val role: UserGroupRole?, + val state: UserGroupState +) diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupRole.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupRole.kt new file mode 100644 index 0000000..1c1ddb2 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/UserGroupRole.kt @@ -0,0 +1,7 @@ +package com.fictadvisor.android.data.dto.user + +enum class UserGroupRole { + CAPTAIN, + MODERATOR, + STUDENT +} \ No newline at end of file diff --git a/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentResponse.kt b/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentResponse.kt new file mode 100644 index 0000000..1063bd4 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/data/dto/user/VerifyStudentResponse.kt @@ -0,0 +1,5 @@ +package com.fictadvisor.android.data.dto.user + +data class VerifyStudentResponse( + val students: List +) diff --git a/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt b/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt index ad4c955..701a2e0 100644 --- a/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt +++ b/app/src/main/java/com/fictadvisor/android/data/remote/api/UserApi.kt @@ -4,6 +4,7 @@ import com.fictadvisor.android.data.dto.TelegramDTO import com.fictadvisor.android.data.dto.user.AddContactBody import com.fictadvisor.android.data.dto.user.ChangeAvatarResponse import com.fictadvisor.android.data.dto.user.ChangeInfoBody +import com.fictadvisor.android.data.dto.user.UserDTOResponse import com.fictadvisor.android.data.dto.user.ChangeRoleBody import com.fictadvisor.android.data.dto.user.ChangeUserBody import com.fictadvisor.android.data.dto.user.Contact @@ -15,6 +16,7 @@ import com.fictadvisor.android.data.dto.user.PostSelectiveDisciplinesBody import com.fictadvisor.android.data.dto.user.RequestNewGroupBody import com.fictadvisor.android.data.dto.user.SimplifiedUser import com.fictadvisor.android.data.dto.user.VerifyStudentBody +import com.fictadvisor.android.data.dto.user.VerifyStudentResponse import okhttp3.MultipartBody import okhttp3.ResponseBody import retrofit2.Response @@ -48,14 +50,14 @@ interface UserApi { @Header("Authorization") token: String, @Path("userId") userId: String, @Body body: ChangeInfoBody - ) // TODO: response type for changeInfo() + ): Response @POST("/v2/users/{userId}/telegram") suspend fun linkTelegram( @Header("Authorization") token: String, @Path("userId") userId: String, @Body body: TelegramDTO - ) // TODO: response type for linkTelegram() + ): Response @POST("/v2/users/{userId}/contacts") suspend fun addContact( @@ -131,5 +133,5 @@ interface UserApi { @Header("Authorization") token: String, @Path("userId") userId: String, @Body body: VerifyStudentBody - ) // TODO: response type for verifyStudent() -} \ No newline at end of file + ): Response +} From 58aa5f09126a0bd4fff01417250d449dfd782391 Mon Sep 17 00:00:00 2001 From: Nikita Sutulov Date: Mon, 8 Apr 2024 16:29:41 +0300 Subject: [PATCH 3/3] added repository and ViewModel for user api --- .../android/repository/UserRepository.kt | 88 +++++ .../android/viewmodel/UserViewModel.kt | 345 ++++++++++++++++++ .../android/viewmodel/UserViewModelFactory.kt | 15 + 3 files changed, 448 insertions(+) create mode 100644 app/src/main/java/com/fictadvisor/android/repository/UserRepository.kt create mode 100644 app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModel.kt create mode 100644 app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModelFactory.kt diff --git a/app/src/main/java/com/fictadvisor/android/repository/UserRepository.kt b/app/src/main/java/com/fictadvisor/android/repository/UserRepository.kt new file mode 100644 index 0000000..ea80301 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/repository/UserRepository.kt @@ -0,0 +1,88 @@ +package com.fictadvisor.android.repository + +import com.fictadvisor.android.data.dto.TelegramDTO +import com.fictadvisor.android.data.dto.user.AddContactBody +import com.fictadvisor.android.data.dto.user.ChangeAvatarResponse +import com.fictadvisor.android.data.dto.user.ChangeInfoBody +import com.fictadvisor.android.data.dto.user.ChangeRoleBody +import com.fictadvisor.android.data.dto.user.ChangeUserBody +import com.fictadvisor.android.data.dto.user.Contact +import com.fictadvisor.android.data.dto.user.GetContactsResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesBySemesterResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveResponse +import com.fictadvisor.android.data.dto.user.PostSelectiveDisciplinesBody +import com.fictadvisor.android.data.dto.user.RequestNewGroupBody +import com.fictadvisor.android.data.dto.user.SimplifiedUser +import com.fictadvisor.android.data.dto.user.UserDTOResponse +import com.fictadvisor.android.data.dto.user.VerifyStudentBody +import com.fictadvisor.android.data.dto.user.VerifyStudentResponse +import com.fictadvisor.android.data.remote.RetrofitClient +import okhttp3.MultipartBody +import okhttp3.ResponseBody +import retrofit2.Response + +class UserRepository { + + private val userService = RetrofitClient.userApi + + suspend fun getUser(token: String, userId: String): Response { + return userService.getUser(token, userId) + } + + suspend fun editUser(token: String, userId: String, body: ChangeUserBody): Response { + return userService.editUser(token, userId, body) + } + + suspend fun changeInfo(token: String, userId: String, body: ChangeInfoBody): Response { + return userService.changeInfo(token, userId, body) + } + + suspend fun linkTelegram(token: String, userId: String, body: TelegramDTO): Response { + return userService.linkTelegram(token, userId, body) + } + + suspend fun addContact(token: String, userId: String, body: AddContactBody): Response { + return userService.addContact(token, userId, body) + } + + suspend fun getContacts(token: String, userId: String): Response { + return userService.getContacts(token, userId) + } + + suspend fun deleteContact(token: String, userId: String, id: String): Response { + return userService.deleteContact(token, userId, id) + } + + suspend fun requestNewGroup(token: String, userId: String, body: RequestNewGroupBody): Response { + return userService.requestNewGroup(token, userId, body) + } + + suspend fun getSelectiveDisciplinesBySemester(token: String, userId: String): Response { + return userService.getSelectiveDisciplinesBySemester(token, userId) + } + + suspend fun postSelectiveDisciplines(token: String, userId: String, body: PostSelectiveDisciplinesBody): Response { + return userService.postSelectiveDisciplines(token, userId, body) + } + + suspend fun getSelectiveDisciplines(token: String, userId: String, year: Int, semester: Int): Response { + return userService.getSelectiveDisciplines(token, userId, year, semester) + } + + suspend fun changeAvatar(token: String, userId: String, avatar: MultipartBody.Part): Response { + return userService.changeAvatar(token, userId, avatar) + } + + suspend fun setRole(token: String, userId: String, body: ChangeRoleBody): Response { + return userService.setRole(token, userId, body) + } + + suspend fun getSelective(token: String, userId: String): Response { + return userService.getSelective(token, userId) + } + + suspend fun verifyStudent(token: String, userId: String, body: VerifyStudentBody): Response { + return userService.verifyStudent(token, userId, body) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModel.kt b/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModel.kt new file mode 100644 index 0000000..22f4080 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModel.kt @@ -0,0 +1,345 @@ +package com.fictadvisor.android.viewmodel + +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.fictadvisor.android.data.dto.BaseResponse +import com.fictadvisor.android.data.dto.ErrorResponse +import com.fictadvisor.android.data.dto.TelegramDTO +import com.fictadvisor.android.data.dto.user.AddContactBody +import com.fictadvisor.android.data.dto.user.ChangeAvatarResponse +import com.fictadvisor.android.data.dto.user.ChangeInfoBody +import com.fictadvisor.android.data.dto.user.ChangeRoleBody +import com.fictadvisor.android.data.dto.user.ChangeUserBody +import com.fictadvisor.android.data.dto.user.Contact +import com.fictadvisor.android.data.dto.user.GetContactsResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesBySemesterResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveDisciplinesResponse +import com.fictadvisor.android.data.dto.user.GetSelectiveResponse +import com.fictadvisor.android.data.dto.user.PostSelectiveDisciplinesBody +import com.fictadvisor.android.data.dto.user.RequestNewGroupBody +import com.fictadvisor.android.data.dto.user.SimplifiedUser +import com.fictadvisor.android.data.dto.user.UserDTOResponse +import com.fictadvisor.android.data.dto.user.VerifyStudentBody +import com.fictadvisor.android.data.dto.user.VerifyStudentResponse +import com.fictadvisor.android.repository.UserRepository +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.MultipartBody +import okhttp3.ResponseBody + +class UserViewModel(private val mainRepository: UserRepository) : ViewModel() { + var job: Job? = null + val mainDispatcher = Dispatchers.Main + + private val getUserResponseMutable = MutableLiveData>() + val getUserResponse: LiveData> = getUserResponseMutable + + private val editUserResponseMutable = MutableLiveData>() + val editUserResponse: LiveData> = editUserResponseMutable + + private val changeInfoResponseMutable = MutableLiveData>() + val changeInfoResponse: LiveData> = changeInfoResponseMutable + + private val linkTelegramResponseMutable = MutableLiveData>() + val linkTelegramResponse: LiveData> = linkTelegramResponseMutable + + private val addContactResponseMutable = MutableLiveData>() + val addContactResponse: LiveData> = addContactResponseMutable + + private val getContactsResponseMutable = MutableLiveData>() + val getContactsResponse: LiveData> = getContactsResponseMutable + + private val deleteContactResponseMutable = MutableLiveData>() + val deleteContactResponse: LiveData> = deleteContactResponseMutable + + private val requestNewGroupResponseMutable = MutableLiveData>() + val requestNewGroupResponse: LiveData> = requestNewGroupResponseMutable + + private val getSelectiveDisciplinesBySemesterResponseMutable = MutableLiveData>() + val getSelectiveDisciplinesBySemesterResponse: LiveData> = getSelectiveDisciplinesBySemesterResponseMutable + + private val postSelectiveDisciplinesResponseMutable = MutableLiveData>() + val postSelectiveDisciplinesResponse: LiveData> = postSelectiveDisciplinesResponseMutable + + private val getSelectiveDisciplinesResponseMutable = MutableLiveData>() + val getSelectiveDisciplinesResponse: LiveData> = getSelectiveDisciplinesResponseMutable + + private val changeAvatarResponseMutable = MutableLiveData>() + val changeAvatarResponse: LiveData> = changeAvatarResponseMutable + + private val setRoleResponseMutable = MutableLiveData>() + val setRoleResponse: LiveData> = setRoleResponseMutable + + private val getSelectiveResponseMutable = MutableLiveData>() + val getSelectiveResponse: LiveData> = getSelectiveResponseMutable + + private val verifyStudentResponseMutable = MutableLiveData>() + val verifyStudentResponse: LiveData> = verifyStudentResponseMutable + + val exceptionHandler = CoroutineExceptionHandler { _, throwable -> + Log.e("UserViewModel", "Exception handled: ${throwable.localizedMessage}") + } + + fun getUser(token: String, userId: String) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.getUser(token, userId) + withContext(mainDispatcher) { + if (response.isSuccessful) { + getUserResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + getUserResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun editUser(token: String, userId: String, body: ChangeUserBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.editUser(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + editUserResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + editUserResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun changeInfo(token: String, userId: String, body: ChangeInfoBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.changeInfo(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + changeInfoResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + changeInfoResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun linkTelegram(token: String, userId: String, body: TelegramDTO) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.linkTelegram(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + linkTelegramResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + linkTelegramResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun addContact(token: String, userId: String, body: AddContactBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.addContact(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + addContactResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + addContactResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun getContacts(token: String, userId: String) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.getContacts(token, userId) + withContext(mainDispatcher) { + if (response.isSuccessful) { + getContactsResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + getContactsResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun deleteContact(token: String, userId: String, id: String) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.deleteContact(token, userId, id) + withContext(mainDispatcher) { + if (response.isSuccessful) { + deleteContactResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + deleteContactResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun requestNewGroup(token: String, userId: String, body: RequestNewGroupBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.requestNewGroup(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + requestNewGroupResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + requestNewGroupResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun getSelectiveDisciplinesBySemester(token: String, userId: String) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.getSelectiveDisciplinesBySemester(token, userId) + withContext(mainDispatcher) { + if (response.isSuccessful) { + getSelectiveDisciplinesBySemesterResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + getSelectiveDisciplinesBySemesterResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun postSelectiveDisciplines(token: String, userId: String, body: PostSelectiveDisciplinesBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.postSelectiveDisciplines(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + postSelectiveDisciplinesResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + postSelectiveDisciplinesResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun getSelectiveDisciplines(token: String, userId: String, year: Int, semester: Int) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.getSelectiveDisciplines(token, userId, year, semester) + withContext(mainDispatcher) { + if (response.isSuccessful) { + getSelectiveDisciplinesResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + getSelectiveDisciplinesResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun changeAvatar(token: String, userId: String, avatar: MultipartBody.Part) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.changeAvatar(token, userId, avatar) + withContext(mainDispatcher) { + if (response.isSuccessful) { + changeAvatarResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + changeAvatarResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun setRole(token: String, userId: String, body: ChangeRoleBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.setRole(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + setRoleResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + setRoleResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun getSelective(token: String, userId: String) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.getSelective(token, userId) + withContext(mainDispatcher) { + if (response.isSuccessful) { + getSelectiveResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + getSelectiveResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } + + fun verifyStudent(token: String, userId: String, body: VerifyStudentBody) { + job = CoroutineScope(Dispatchers.IO + exceptionHandler).launch { + val response = mainRepository.verifyStudent(token, userId, body) + withContext(mainDispatcher) { + if (response.isSuccessful) { + verifyStudentResponseMutable.postValue(BaseResponse.Success(response.body())) + } else { + val gson = Gson() + val type = object : TypeToken() {}.type + val errorResponse: ErrorResponse? = gson.fromJson(response.errorBody()!!.charStream(), type) + + verifyStudentResponseMutable.postValue(BaseResponse.Error(errorResponse)) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModelFactory.kt b/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModelFactory.kt new file mode 100644 index 0000000..74cb6c1 --- /dev/null +++ b/app/src/main/java/com/fictadvisor/android/viewmodel/UserViewModelFactory.kt @@ -0,0 +1,15 @@ +package com.fictadvisor.android.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.fictadvisor.android.repository.UserRepository + +class UserViewModelFactory(private val userRepository: UserRepository) : ViewModelProvider.Factory { + + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(UserViewModel::class.java)) { + return UserViewModel(userRepository) as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} \ No newline at end of file