fix(live-room): 매니저 SNS 아이콘 노출 방식을 동적 렌더링으로 통일한다

This commit is contained in:
2026-03-24 13:35:15 +09:00
parent a893d85632
commit 08524bd79a
3 changed files with 92 additions and 60 deletions

View File

@@ -10,6 +10,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.URLUtil import android.webkit.URLUtil
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.Toast import android.widget.Toast
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
@@ -44,6 +45,11 @@ class LiveRoomDetailFragment(
private val onClickCancel: () -> Unit private val onClickCancel: () -> Unit
) : BottomSheetDialogFragment() { ) : BottomSheetDialogFragment() {
private data class SnsItem(
val url: String,
val iconResId: Int
)
private val viewModel: LiveRoomDetailViewModel by inject() private val viewModel: LiveRoomDetailViewModel by inject()
private lateinit var binding: FragmentLiveRoomDetailBinding private lateinit var binding: FragmentLiveRoomDetailBinding
@@ -273,41 +279,7 @@ class LiveRoomDetailFragment(
transformations(CircleCropTransformation()) transformations(CircleCropTransformation())
} }
if ( bindManagerSnsItems(manager)
manager.kakaoOpenChatUrl.isNullOrBlank() ||
!URLUtil.isValidUrl(manager.kakaoOpenChatUrl)
) {
binding.ivManagerOpenChat.visibility = View.GONE
} else {
binding.ivManagerOpenChat.visibility = View.VISIBLE
binding.ivManagerOpenChat.setOnClickListener {
startActivity(Intent(Intent.ACTION_VIEW, manager.kakaoOpenChatUrl.toUri()))
}
}
if (
manager.instagramUrl.isNullOrBlank() ||
!URLUtil.isValidUrl(manager.instagramUrl)
) {
binding.ivManagerInstagram.visibility = View.GONE
} else {
binding.ivManagerInstagram.visibility = View.VISIBLE
binding.ivManagerInstagram.setOnClickListener {
startActivity(Intent(Intent.ACTION_VIEW, manager.instagramUrl.toUri()))
}
}
if (
manager.youtubeUrl.isNullOrBlank() ||
!URLUtil.isValidUrl(manager.youtubeUrl)
) {
binding.ivManagerYoutube.visibility = View.GONE
} else {
binding.ivManagerYoutube.visibility = View.VISIBLE
binding.ivManagerYoutube.setOnClickListener {
startActivity(Intent(Intent.ACTION_VIEW, manager.youtubeUrl.toUri()))
}
}
if (manager.isCreator) { if (manager.isCreator) {
binding.tvManagerProfile.visibility = View.VISIBLE binding.tvManagerProfile.visibility = View.VISIBLE
@@ -321,6 +293,66 @@ class LiveRoomDetailFragment(
} }
} }
private fun bindManagerSnsItems(manager: GetRoomDetailManager) {
val snsItems = listOf(
SnsItem(
url = manager.youtubeUrl?.trim().orEmpty(),
iconResId = R.drawable.ic_sns_youtube
),
SnsItem(
url = manager.instagramUrl?.trim().orEmpty(),
iconResId = R.drawable.ic_sns_instagram
),
SnsItem(
url = manager.xUrl?.trim().orEmpty(),
iconResId = R.drawable.ic_sns_x
),
SnsItem(
url = manager.fancimmUrl?.trim().orEmpty(),
iconResId = R.drawable.ic_sns_fancimm
),
SnsItem(
url = manager.kakaoOpenChatUrl?.trim().orEmpty(),
iconResId = R.drawable.ic_sns_kakao
)
).filter { item ->
item.url.isNotBlank() && URLUtil.isValidUrl(item.url)
}
binding.llManagerSnsIcons.removeAllViews()
binding.llManagerSnsIcons.visibility = if (snsItems.isEmpty()) {
View.GONE
} else {
View.VISIBLE
}
snsItems.forEachIndexed { index, item ->
val imageView = ImageView(requireContext()).apply {
setImageResource(item.iconResId)
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply {
if (index > 0) {
marginStart = 8.dpToPx().toInt()
}
}
setOnClickListener {
openUrl(item.url)
}
}
binding.llManagerSnsIcons.addView(imageView)
}
}
private fun openUrl(url: String) {
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
if (intent.resolveActivity(requireActivity().packageManager) != null) {
startActivity(intent)
}
}
private fun setParticipantUserSummary(participatingUsers: List<GetRoomDetailUser>) { private fun setParticipantUserSummary(participatingUsers: List<GetRoomDetailUser>) {
val userCount = if (participatingUsers.size > 10) { val userCount = if (participatingUsers.size > 10) {
10 10

View File

@@ -248,33 +248,11 @@
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/ll_manager_sns_icons"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_manager_open_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_website_blue" />
<ImageView
android:id="@+id/iv_manager_instagram"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@null"
android:src="@drawable/ic_instagram_blue" />
<ImageView
android:id="@+id/iv_manager_youtube"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@null"
android:src="@drawable/ic_youtube_play_blue" />
</LinearLayout>
<TextView <TextView
android:id="@+id/tv_manager_profile" android:id="@+id/tv_manager_profile"

View File

@@ -0,0 +1,22 @@
# 라이브 상세 SNS 아이콘 변경
## 구현 체크리스트
- [x] `LiveRoomDetailFragment`의 SNS 아이콘 렌더링을 `CreatorDetailDialog`와 동일한 아이콘 세트(`ic_sns_*`) 및 동적 노출 방식으로 변경한다.
- [x] `GetRoomDetailManager``youtubeUrl`, `instagramUrl`, `kakaoOpenChatUrl`, `fancimmUrl`, `xUrl`를 모두 SNS 표시 대상에 포함한다.
- [x] 레이아웃에서 매니저 SNS 아이콘 영역을 동적 추가 구조로 정리한다.
- [x] 수정 파일 진단, 테스트/빌드를 실행해 결과를 확인한다.
## 검증 기록
- LSP 진단 시도
- 명령: `lsp_diagnostics` (`LiveRoomDetailFragment.kt`, `fragment_live_room_detail.xml`)
- 결과: 현재 실행 환경에 Kotlin/XML LSP 서버가 설정되어 있지 않아 진단 불가(`No LSP server configured for extension: .kt/.xml`).
- 단위 테스트 + 빌드
- 명령: `./gradlew :app:testDebugUnitTest :app:assembleDebug`
- 결과: `BUILD SUCCESSFUL`
- 디바이스 설치 확인
- 명령: `./gradlew :app:installDebug`
- 결과: `Installed on 1 device.`
- 수동 QA 실행(실기기)
- 명령: `adb shell am start -n kr.co.vividnext.sodalive/.splash.SplashActivity`
- 결과: 앱 실행은 성공했으나 원격 설정에 의한 필수 업데이트 다이얼로그(`업데이트 후 사용가능합니다.`)가 표시되어 라이브 상세 진입 경로까지 진행 불가.
- 추가 확인: `adb shell am start -n kr.co.vividnext.sodalive/.live.now.all.LiveNowAllActivity` 실행 시 비-exported Activity로 `Permission Denial` 발생.