From 1767cfb4eed83831f8a274b62bea82b29b5ed264 Mon Sep 17 00:00:00 2001 From: erik-everardo Date: Sun, 7 Jan 2024 01:17:16 -0600 Subject: [PATCH] cambiar imagen de perfil --- .../profile/data/remote/ProfileApi.kt | 4 +++ .../data/repository/ProfileRepositoryImpl.kt | 17 +++++++++++++ .../profile/domain/ProfileRepository.kt | 3 +++ .../domain/use_case/SetProfileImage.kt | 11 ++++++++ .../profile/presentation/ProfileViewModel.kt | 25 +++++++++++-------- .../profile/ui/ProfileMainFragment.kt | 8 +++--- .../main/java/com/isolaatti/utils/UrlGen.kt | 11 +++++++- 7 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/com/isolaatti/profile/domain/use_case/SetProfileImage.kt diff --git a/app/src/main/java/com/isolaatti/profile/data/remote/ProfileApi.kt b/app/src/main/java/com/isolaatti/profile/data/remote/ProfileApi.kt index 0aca5f5..e6f4c7a 100644 --- a/app/src/main/java/com/isolaatti/profile/data/remote/ProfileApi.kt +++ b/app/src/main/java/com/isolaatti/profile/data/remote/ProfileApi.kt @@ -4,10 +4,14 @@ import retrofit2.Call import retrofit2.http.GET import retrofit2.http.POST import retrofit2.http.Path +import retrofit2.http.Query interface ProfileApi { @GET("Fetch/UserProfile/{userId}") fun userProfile(@Path("userId") userId: Int): Call + @POST("EditProfile/SetProfilePhoto") + fun setProfileImage(@Query("imageId") imageId: String): Call + } \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/profile/data/repository/ProfileRepositoryImpl.kt b/app/src/main/java/com/isolaatti/profile/data/repository/ProfileRepositoryImpl.kt index ccc398e..65ee69e 100644 --- a/app/src/main/java/com/isolaatti/profile/data/repository/ProfileRepositoryImpl.kt +++ b/app/src/main/java/com/isolaatti/profile/data/repository/ProfileRepositoryImpl.kt @@ -1,6 +1,7 @@ package com.isolaatti.profile.data.repository import android.util.Log +import com.isolaatti.images.common.domain.entity.Image import com.isolaatti.profile.data.remote.ProfileApi import com.isolaatti.profile.domain.ProfileRepository import com.isolaatti.profile.domain.entity.UserProfile @@ -28,4 +29,20 @@ class ProfileRepositoryImpl @Inject constructor(private val profileApi: ProfileA emit(Resource.Error(Resource.Error.ErrorType.NetworkError)) } } + + override fun setProfileImage(image: Image): Flow> = flow { + + try { + val result = profileApi.setProfileImage(image.id).awaitResponse() + + if(result.isSuccessful) { + emit(Resource.Success(true)) + } else { + emit(Resource.Error(Resource.Error.mapErrorCode(result.code()))) + } + } catch (e: Exception) { + Log.e("ProfileRepositoryImpl", e.message.toString()) + emit(Resource.Error(Resource.Error.ErrorType.NetworkError)) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/profile/domain/ProfileRepository.kt b/app/src/main/java/com/isolaatti/profile/domain/ProfileRepository.kt index ac4afea..ef09dd8 100644 --- a/app/src/main/java/com/isolaatti/profile/domain/ProfileRepository.kt +++ b/app/src/main/java/com/isolaatti/profile/domain/ProfileRepository.kt @@ -1,9 +1,12 @@ package com.isolaatti.profile.domain +import com.isolaatti.images.common.domain.entity.Image import com.isolaatti.profile.domain.entity.UserProfile import com.isolaatti.utils.Resource import kotlinx.coroutines.flow.Flow interface ProfileRepository { fun getProfile(userId: Int): Flow> + + fun setProfileImage(image: Image): Flow> } \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/profile/domain/use_case/SetProfileImage.kt b/app/src/main/java/com/isolaatti/profile/domain/use_case/SetProfileImage.kt new file mode 100644 index 0000000..c933a54 --- /dev/null +++ b/app/src/main/java/com/isolaatti/profile/domain/use_case/SetProfileImage.kt @@ -0,0 +1,11 @@ +package com.isolaatti.profile.domain.use_case + +import com.isolaatti.images.common.domain.entity.Image +import com.isolaatti.profile.domain.ProfileRepository +import com.isolaatti.utils.Resource +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class SetProfileImage @Inject constructor(private val profileRepository: ProfileRepository) { + operator fun invoke(image: Image): Flow> = profileRepository.setProfileImage(image) +} \ No newline at end of file diff --git a/app/src/main/java/com/isolaatti/profile/presentation/ProfileViewModel.kt b/app/src/main/java/com/isolaatti/profile/presentation/ProfileViewModel.kt index a85185e..bc027b3 100644 --- a/app/src/main/java/com/isolaatti/profile/presentation/ProfileViewModel.kt +++ b/app/src/main/java/com/isolaatti/profile/presentation/ProfileViewModel.kt @@ -2,18 +2,15 @@ package com.isolaatti.profile.presentation import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.isolaatti.followers.domain.FollowingState -import com.isolaatti.posting.posts.data.remote.FeedDto -import com.isolaatti.posting.posts.data.remote.FeedFilterDto +import com.isolaatti.images.common.domain.entity.Image import com.isolaatti.posting.posts.presentation.PostListingViewModelBase import com.isolaatti.posting.posts.presentation.UpdateEvent -import com.isolaatti.profile.data.remote.UserProfileDto -import com.isolaatti.profile.domain.ProfileRepository import com.isolaatti.profile.domain.entity.UserProfile import com.isolaatti.profile.domain.use_case.GetProfile import com.isolaatti.profile.domain.use_case.GetProfilePosts +import com.isolaatti.profile.domain.use_case.SetProfileImage import com.isolaatti.utils.Resource import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -21,14 +18,14 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import java.time.Month import javax.inject.Inject @HiltViewModel -class ProfileViewModel @Inject constructor(private val getProfileUseCase: GetProfile, private val getProfilePostsUseCase: GetProfilePosts) : PostListingViewModelBase() { +class ProfileViewModel @Inject constructor( + private val getProfileUseCase: GetProfile, + private val getProfilePostsUseCase: GetProfilePosts, + private val setProfileImageUC: SetProfileImage +) : PostListingViewModelBase() { private val _profile = MutableLiveData() val profile: LiveData get() = _profile @@ -78,6 +75,14 @@ class ProfileViewModel @Inject constructor(private val getProfileUseCase: GetPro } } + fun setProfileImage(image: Image) { + viewModelScope.launch { + setProfileImageUC(image).onEach { + _profile.postValue(_profile.value?.copy(profileImageId = image.id)) + }.flowOn(Dispatchers.IO).launchIn(this) + } + } + override fun getFeed(refresh: Boolean) { viewModelScope.launch { if(refresh) { diff --git a/app/src/main/java/com/isolaatti/profile/ui/ProfileMainFragment.kt b/app/src/main/java/com/isolaatti/profile/ui/ProfileMainFragment.kt index edb4183..0c63b11 100644 --- a/app/src/main/java/com/isolaatti/profile/ui/ProfileMainFragment.kt +++ b/app/src/main/java/com/isolaatti/profile/ui/ProfileMainFragment.kt @@ -33,7 +33,6 @@ import com.isolaatti.common.options_bottom_sheet.presentation.BottomSheetPostOpt import com.isolaatti.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment import com.isolaatti.databinding.FragmentDiscussionsBinding import com.isolaatti.followers.domain.FollowingState -import com.isolaatti.images.image_chooser.ui.ImageChooserActivity import com.isolaatti.images.image_chooser.ui.ImageChooserContract import com.isolaatti.images.image_list.ui.ImagesFragment import com.isolaatti.posting.comments.ui.BottomSheetPostComments @@ -84,8 +83,11 @@ class ProfileMainFragment : Fragment() { viewModel.onPostAddedAtTheBeginning(it) } - private val chooseImageLauncher = registerForActivityResult(ImageChooserContract()) { + private val chooseImageLauncher = registerForActivityResult(ImageChooserContract()) { image -> // here change profile picture + if(image != null) { + viewModel.setProfileImage(image) + } } private val editDiscussion = registerForActivityResult(EditPostContract()) { @@ -116,7 +118,7 @@ class ProfileMainFragment : Fragment() { } private val profileObserver = Observer { profile -> - viewBinding.profileImageView.load(UrlGen.userProfileImage(profile.userId), imageLoader) + viewBinding.profileImageView.load(UrlGen.userProfileImage(profile.userId, invalidateCache = true), imageLoader) title = profile.name viewBinding.textViewUsername.text = profile.name diff --git a/app/src/main/java/com/isolaatti/utils/UrlGen.kt b/app/src/main/java/com/isolaatti/utils/UrlGen.kt index ee60dd1..05950f4 100644 --- a/app/src/main/java/com/isolaatti/utils/UrlGen.kt +++ b/app/src/main/java/com/isolaatti/utils/UrlGen.kt @@ -6,7 +6,16 @@ object UrlGen { const val IMAGE_MODE_SMALL = "small" const val IMAGE_MODE_REDUCED = "reduced" const val IMAGE_MODE_ORIGINAL = "original" - fun userProfileImage(userId: Int) = "${BASE_URL}images/profile_image/of_user/$userId?mode=small" + + private var timestamp: Long = System.currentTimeMillis() + fun userProfileImage(userId: Int, invalidateCache: Boolean = false): String { + + if(invalidateCache) { + timestamp = System.currentTimeMillis() + } + + return "${BASE_URL}images/profile_image/of_user/$userId?mode=small&ts=$timestamp" + } fun userProfileImageFullQuality(userId: Int) = "${BASE_URL}images/profile_image/of_user/$userId?mode=original" fun imageUrl(imageId: String, mode: String? = IMAGE_MODE_ORIGINAL) = "${BASE_URL}images/image/${imageId}?mode=${mode}" } \ No newline at end of file