diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/GetCommunityPostListResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/GetCommunityPostListResponse.kt index a581988..ac50ddb 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/GetCommunityPostListResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/GetCommunityPostListResponse.kt @@ -8,6 +8,7 @@ data class GetCommunityPostListResponse( @SerializedName("creatorNickname") val creatorNickname: String, @SerializedName("creatorProfileUrl") val creatorProfileUrl: String, @SerializedName("imageUrl") val imageUrl: String?, + @SerializedName("audioUrl") val audioUrl: String?, @SerializedName("content") val content: String, @SerializedName("price") val price: Int, @SerializedName("date") val date: String, diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.kt index 2eb5080..05fa603 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllActivity.kt @@ -15,6 +15,7 @@ import kr.co.vividnext.sodalive.common.Constants import kr.co.vividnext.sodalive.common.LoadingDialog import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityAllBinding import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreatorCommunityCommentFragment +import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player.CreatorCommunityMediaPlayerManager import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.CreatorCommunityModifyActivity import kr.co.vividnext.sodalive.extensions.dpToPx import org.koin.android.ext.android.inject @@ -27,6 +28,7 @@ class CreatorCommunityAllActivity : BaseActivity PurchaseCommunityPostDialog( activity = this@CreatorCommunityAllActivity, diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllAdapter.kt index 9a4dbe4..3562137 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllAdapter.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/CreatorCommunityAllAdapter.kt @@ -23,6 +23,7 @@ import kr.co.vividnext.sodalive.common.SharedPreferenceManager import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityAllBinding import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse +import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player.CreatorCommunityContentItem import kr.co.vividnext.sodalive.extensions.dpToPx import kr.co.vividnext.sodalive.extensions.loadUrl import java.util.regex.Pattern @@ -35,6 +36,8 @@ class CreatorCommunityAllAdapter( private val onClickModify: (Long) -> Unit, private val onClickDelete: (Long) -> Unit, private val onClickReport: (Long) -> Unit, + private val onClickAudioContentPlayOrPause: (CreatorCommunityContentItem) -> Unit, + private val isAudioContentPlaying: (Long) -> Boolean, private val onClickPurchaseContent: (Long, Int, onSuccess: (GetCommunityPostListResponse) -> Unit) -> Unit ) : RecyclerView.Adapter() { @@ -63,6 +66,7 @@ class CreatorCommunityAllAdapter( binding.ivContent.visibility = View.GONE binding.llComment.visibility = View.GONE binding.ivSeeMore.visibility = View.GONE + binding.ivPlayOrPause.visibility = View.GONE binding.llLockPost.visibility = View.VISIBLE val lockPostWidth = (screenWidth - 42f.dpToPx()).toInt() @@ -100,6 +104,28 @@ class CreatorCommunityAllAdapter( ) } + if (item.audioUrl != null && item.imageUrl != null) { + binding.ivPlayOrPause.visibility = View.VISIBLE + binding.ivPlayOrPause.setImageResource( + if (isAudioContentPlaying(item.postId)) { + R.drawable.btn_audio_content_pause + } else { + R.drawable.btn_audio_content_play + } + ) + binding.ivPlayOrPause.setOnClickListener { + onClickAudioContentPlayOrPause( + CreatorCommunityContentItem( + item.postId, + item.audioUrl + ) + ) + } + } else { + binding.ivPlayOrPause.visibility = View.GONE + binding.ivPlayOrPause.setOnClickListener {} + } + setImageContent(binding.ivContent, item.imageUrl) setContentLike(item.isLike, item.likeCount, item.postId, index) setNoticeAndClickableUrl(binding.tvContent, item.content, item.isExpand, index) @@ -283,4 +309,9 @@ class CreatorCommunityAllAdapter( popup.show() } + + @SuppressLint("NotifyDataSetChanged") + fun updateUI() { + notifyDataSetChanged() + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/player/CreatorCommunityMediaPlayerManager.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/player/CreatorCommunityMediaPlayerManager.kt new file mode 100644 index 0000000..8be8c65 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/creator_community/all/player/CreatorCommunityMediaPlayerManager.kt @@ -0,0 +1,97 @@ +package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player + +import android.content.Context +import android.media.AudioAttributes +import android.media.MediaPlayer +import android.net.Uri +import android.widget.Toast +import java.io.IOException + +data class CreatorCommunityContentItem(val contentId: Long, val url: String) + +class CreatorCommunityMediaPlayerManager( + private val context: Context, + private val updateUI: () -> Unit +) { + private var mediaPlayer: MediaPlayer? = null + private var currentPlayingContentId: Long? = null + private var isPaused: Boolean = false + + private fun playContent(creatorCommunityContentItem: CreatorCommunityContentItem) { + if (currentPlayingContentId == creatorCommunityContentItem.contentId && isPaused) { + resumeContent() + return + } + + stopContent() + + mediaPlayer = MediaPlayer().apply { + setAudioAttributes( + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) + .setUsage(AudioAttributes.USAGE_MEDIA) + .build() + ) + + try { + setDataSource(context, Uri.parse(creatorCommunityContentItem.url)) + prepareAsync() // 비동기적으로 준비 + setOnPreparedListener { + start() + updateUI() // 준비 완료 후 UI 업데이트 + } + } catch (e: IOException) { + e.printStackTrace() + Toast.makeText(context, "콘텐츠를 재생하지 못했습니다.\n다시 시도해 주세요", Toast.LENGTH_SHORT).show() + } + + setOnCompletionListener { + currentPlayingContentId = null + updateUI() // 재생 완료 후 UI 업데이트 + } + } + + currentPlayingContentId = creatorCommunityContentItem.contentId + isPaused = false + updateUI() + } + + fun pauseContent() { + mediaPlayer?.pause() + isPaused = true + updateUI() + } + + private fun resumeContent() { + mediaPlayer?.start() + isPaused = false + updateUI() + } + + fun stopContent() { + mediaPlayer?.let { + it.stop() + it.release() + mediaPlayer = null + } + currentPlayingContentId = null + isPaused = false + updateUI() + } + + fun toggleContent(creatorCommunityContentItem: CreatorCommunityContentItem) { + if (currentPlayingContentId == creatorCommunityContentItem.contentId) { + if (mediaPlayer?.isPlaying == true) { + pauseContent() + } else { + resumeContent() + } + } else { + playContent(creatorCommunityContentItem) + } + } + + fun isPlayingContent(contentId: Long): Boolean { + return currentPlayingContentId == contentId && mediaPlayer?.isPlaying == true + } +} diff --git a/app/src/main/res/layout/item_creator_community_all.xml b/app/src/main/res/layout/item_creator_community_all.xml index 853e353..7074fa3 100644 --- a/app/src/main/res/layout/item_creator_community_all.xml +++ b/app/src/main/res/layout/item_creator_community_all.xml @@ -75,15 +75,30 @@ android:visibility="gone" tools:text="너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!너무 조하유 앞으로도 좋은 라이브 많이 들려주세요!" /> - + android:layout_marginTop="13.3dp"> + + + + +