Skip to content

Commit

Permalink
[MERGE] #233 -> develop
Browse files Browse the repository at this point in the history
[FEAT/#233] 뷰 동적 크기 조정 및 버튼 연결, 제목 조정
  • Loading branch information
chattymin authored Mar 7, 2024
2 parents d90e8d8 + a0b56e0 commit 00b693c
Show file tree
Hide file tree
Showing 27 changed files with 691 additions and 353 deletions.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
android:screenOrientation="portrait" />

<activity
android:name="com.going.presentation.profile.trip.TripProfileActivity"
android:name="com.going.presentation.profile.participant.ParticipantProfileActivity"
android:exported="false"
android:screenOrientation="portrait" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package com.going.data.datasource

import com.going.data.dto.BaseResponse
import com.going.data.dto.request.ParticipantProfileRequestDto
import com.going.data.dto.response.ParticipantProfileResponseDto
import com.going.data.dto.response.UserProfileResponseDto
import com.going.domain.entity.request.ParticipantProfileRequestModel

interface ProfileDataSource {
suspend fun getUserProfile(): BaseResponse<UserProfileResponseDto>

suspend fun getParticipantProfile(
participantProfileRequestModel: ParticipantProfileRequestDto
): BaseResponse<ParticipantProfileResponseDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ package com.going.data.datasourceImpl

import com.going.data.datasource.ProfileDataSource
import com.going.data.dto.BaseResponse
import com.going.data.dto.request.ParticipantProfileRequestDto
import com.going.data.dto.response.ParticipantProfileResponseDto
import com.going.data.dto.response.UserProfileResponseDto
import com.going.data.service.ProfileService
import com.going.domain.entity.request.ParticipantProfileRequestModel
import javax.inject.Inject

class ProfileDataSourceImpl @Inject constructor(
private val profileService: ProfileService,
) : ProfileDataSource {
override suspend fun getUserProfile(): BaseResponse<UserProfileResponseDto> =
profileService.getUserProfile()

override suspend fun getParticipantProfile(participantProfileRequestDto: ParticipantProfileRequestDto): BaseResponse<ParticipantProfileResponseDto> =
profileService.getParticipantProfile(participantProfileRequestDto.participantId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.going.data.dto.request

import com.going.domain.entity.request.ParticipantProfileRequestModel
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ParticipantProfileRequestDto(
@SerialName("participantId")
val participantId: Long,
)

fun ParticipantProfileRequestModel.toParticipantRequestDto(): ParticipantProfileRequestDto =
ParticipantProfileRequestDto(participantId)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.going.data.dto.response

import com.going.domain.entity.response.ParticipantProfileResponseModel
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ParticipantProfileResponseDto(
@SerialName("name")
val name: String,
@SerialName("intro")
val intro: String,
@SerialName("result")
val result: Int,
@SerialName("styleA")
val styleA: Int,
@SerialName("styleB")
val styleB: Int,
@SerialName("styleC")
val styleC: Int,
@SerialName("styleD")
val styleD: Int,
@SerialName("styleE")
val styleE: Int,
@SerialName("isOwner")
val isOwner: Boolean,
) {
fun toParticipantProfileModel() = ParticipantProfileResponseModel(
name,
intro,
result,
styleA,
styleB,
styleC,
styleD,
styleE,
isOwner
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.going.data.repositoryImpl

import com.going.data.datasource.ProfileDataSource
import com.going.data.dto.request.toParticipantRequestDto
import com.going.domain.entity.request.ParticipantProfileRequestModel
import com.going.domain.entity.request.UserProfileRequestModel
import com.going.domain.entity.response.ParticipantProfileResponseModel
import com.going.domain.repository.ProfileRepository
import javax.inject.Inject

Expand All @@ -12,4 +15,11 @@ class ProfileRepositoryImpl @Inject constructor(
runCatching {
profileDataSource.getUserProfile().data.toProfileModel()
}

override suspend fun getParticipantProfile(
participantProfileRequestModel: ParticipantProfileRequestModel
): Result<ParticipantProfileResponseModel> =
runCatching {
profileDataSource.getParticipantProfile(participantProfileRequestModel.toParticipantRequestDto()).data.toParticipantProfileModel()
}
}
9 changes: 9 additions & 0 deletions data/src/main/java/com/going/data/service/ProfileService.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package com.going.data.service

import com.going.data.dto.BaseResponse
import com.going.data.dto.request.ParticipantProfileRequestDto
import com.going.data.dto.response.ParticipantProfileResponseDto
import com.going.data.dto.response.UserProfileResponseDto
import com.going.domain.entity.request.ParticipantProfileRequestModel
import retrofit2.http.GET
import retrofit2.http.Path

interface ProfileService {
@GET("api/users/profile")
suspend fun getUserProfile(): BaseResponse<UserProfileResponseDto>

@GET("api/trips/participants/{participantId}")
suspend fun getParticipantProfile(
@Path("participantId") participantId: Long
): BaseResponse<ParticipantProfileResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.going.domain.entity.request

data class ParticipantProfileRequestModel(
val participantId: Long,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.going.domain.entity.response

data class ParticipantProfileResponseModel(
val name: String,
val intro: String,
val result: Int,
val styleA: Int,
val styleB: Int,
val styleC: Int,
val styleD: Int,
val styleE: Int,
val isOwner: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.going.domain.repository

import com.going.domain.entity.request.ParticipantProfileRequestModel
import com.going.domain.entity.request.UserProfileRequestModel
import com.going.domain.entity.response.ParticipantProfileResponseModel

interface ProfileRepository {
suspend fun getUserProfile(): Result<UserProfileRequestModel>

suspend fun getParticipantProfile(participantProfileRequestModel: ParticipantProfileRequestModel): Result<ParticipantProfileResponseModel>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.going.presentation.profile.participant

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.isVisible
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import coil.load
import coil.transform.CircleCropTransformation
import com.going.domain.entity.response.ParticipantProfileResponseModel
import com.going.presentation.R
import com.going.presentation.databinding.ActivityParticipantProfileBinding
import com.going.presentation.profile.edit.ProfileEditActivity
import com.going.presentation.tendency.result.UserTendencyResultList
import com.going.presentation.util.downloadImage
import com.going.ui.base.BaseActivity
import com.going.ui.extension.getWindowHeight
import com.going.ui.extension.setOnSingleClickListener
import com.going.ui.extension.toast
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
import com.google.android.material.tabs.TabLayout
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach


@AndroidEntryPoint
class ParticipantProfileActivity :
BaseActivity<ActivityParticipantProfileBinding>(R.layout.activity_participant_profile) {
private val participantProfileViewModel by viewModels<ParticipantProfileViewModel>()
private val participantId: Long by lazy {
intent.getLongExtra(PARTICIPANT_ID, 0)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

getParticipantProfile()
observeParticipantProfileState()
setViewPager()
setViewPagerDebounce()
initBackBtnClickListener()
initSaveImgBtnClickListener()
initProfileEditBtnClickListener()
}

private fun getParticipantProfile() =
participantProfileViewModel.getUserInfoState(participantId)

private fun observeParticipantProfileState() {
participantProfileViewModel.participantProfile.flowWithLifecycle(lifecycle).onEach {
it?.let { bindData(it) } ?: toast(getString(R.string.server_error))
}.launchIn(lifecycleScope)
}

private fun bindData(profile: ParticipantProfileResponseModel) {
binding.run {
if (profile.result != -1) {
UserTendencyResultList[profile.result].run {
ivProfile.load(profileImage) {
transformations(CircleCropTransformation())
}
}
} else {
setEmptyFragment()
ivProfile.load(R.drawable.img_profile_guest) {
transformations(CircleCropTransformation())
}
}

tvProfileName.text = profile.name
tvProfileOneLine.text = profile.intro

profile.isOwner.run {
btnTripProfileDownload.isVisible = this && profile.result != -1
btnProfileEdit.isVisible = this

if (!this) tvTripProfileTitle.setText(
getString(
R.string.participant_profile_friend_title,
profile.name
)
)
}
}
}

private fun setViewPager() {
binding.vpTripProfile.adapter = ParticipantProfileViewPagerAdapter(this)
binding.vpTripProfile.isUserInputEnabled = false
}

private fun setViewPagerDebounce() {
binding.tabTripProfile.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
val params =
binding.appbarTripProfile.layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior as AppBarLayout.Behavior?

with(tab.position == 0 && participantProfileViewModel.isEmpty) {
behavior?.setDragCallback(object : DragCallback() {
override fun canDrag(appBarLayout: AppBarLayout): Boolean {
return !this@with
}
})
setFragmentHeight(this)

if (this) binding.appbarTripProfile.setExpanded(true)

}

binding.vpTripProfile.currentItem = tab.position
}

override fun onTabUnselected(tab: TabLayout.Tab) {}

override fun onTabReselected(tab: TabLayout.Tab) {}
})
}

private fun setEmptyFragment() {
val params = binding.appbarTripProfile.layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior as AppBarLayout.Behavior?

behavior?.setDragCallback(object : DragCallback() {
override fun canDrag(appBarLayout: AppBarLayout): Boolean {
return false
}
})


setFragmentHeight()
}

private fun setFragmentHeight(temp: Boolean = true) {
val displayHeight = getWindowHeight()
val toolbarHeight = binding.tbTripProfile.height
val appBarHeight = binding.appbarTripProfile.totalScrollRange
val tabHeight = binding.tabTripProfile.height

binding.vpTripProfile.layoutParams = binding.vpTripProfile.layoutParams.also {
it.height =
if (temp) displayHeight - toolbarHeight - appBarHeight - tabHeight else displayHeight
}
}

private fun initBackBtnClickListener() {
binding.btnTripProfileBack.setOnSingleClickListener {
finish()
}
}

private fun initSaveImgBtnClickListener() {
binding.btnTripProfileDownload.setOnSingleClickListener {
downloadImage(participantProfileViewModel.number)
}
}

private fun initProfileEditBtnClickListener() {
binding.btnProfileEdit.setOnSingleClickListener {
ProfileEditActivity.createIntent(
this,
binding.tvProfileName.text.toString(),
binding.tvProfileOneLine.text.toString()
).apply {
startActivity(this)
}
}
}


companion object {
private const val PARTICIPANT_ID = "PARTICIPANT_ID"

@JvmStatic
fun createIntent(
context: Context,
participantId: Long,
): Intent = Intent(context, ProfileEditActivity::class.java).apply {
putExtra(PARTICIPANT_ID, participantId)
}
}
}
Loading

0 comments on commit 00b693c

Please sign in to comment.