Compare commits
No commits in common. "6fbb98ca7beaeb31aa032cbee8508b2493a22726" and "7e3272777331c8f42cd23506b1a84d81aaf183af" have entirely different histories.
6fbb98ca7b
...
7e32727773
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="deploymentTargetDropDown">
|
|
||||||
<value>
|
|
||||||
<entry key="app">
|
|
||||||
<State />
|
|
||||||
</entry>
|
|
||||||
</value>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectMigrations">
|
|
||||||
<option name="MigrateToGradleLocalJavaHome">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -40,8 +40,8 @@ android {
|
||||||
applicationId "kr.co.vividnext.sodalive"
|
applicationId "kr.co.vividnext.sodalive"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 19
|
versionCode 10
|
||||||
versionName "1.4.1"
|
versionName "1.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
@ -138,7 +138,7 @@ dependencies {
|
||||||
implementation "io.github.bootpay:android:4.3.4"
|
implementation "io.github.bootpay:android:4.3.4"
|
||||||
|
|
||||||
// agora
|
// agora
|
||||||
implementation "io.agora.rtc:voice-sdk:4.2.6"
|
implementation "io.agora.rtc:voice-sdk:4.1.0-1"
|
||||||
implementation 'io.agora.rtm:rtm-sdk:1.5.3'
|
implementation 'io.agora.rtm:rtm-sdk:1.5.3'
|
||||||
|
|
||||||
// sound visualizer
|
// sound visualizer
|
||||||
|
@ -149,4 +149,7 @@ dependencies {
|
||||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||||
|
|
||||||
implementation "com.michalsvec:single-row-calednar:1.0.0"
|
implementation "com.michalsvec:single-row-calednar:1.0.0"
|
||||||
|
|
||||||
|
// PointClick Maven Remote Repo
|
||||||
|
implementation 'kr.co.pointclick.sdk.offerwall:pointclick-sdk-offerwall:1.0.17'
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
|
@ -86,7 +85,6 @@
|
||||||
<activity android:name=".mypage.can.status.CanStatusActivity" />
|
<activity android:name=".mypage.can.status.CanStatusActivity" />
|
||||||
<activity android:name=".mypage.can.charge.CanChargeActivity" />
|
<activity android:name=".mypage.can.charge.CanChargeActivity" />
|
||||||
<activity android:name=".mypage.can.payment.CanPaymentActivity" />
|
<activity android:name=".mypage.can.payment.CanPaymentActivity" />
|
||||||
<activity android:name=".mypage.can.coupon.CanCouponActivity" />
|
|
||||||
<activity android:name=".live.room.create.LiveRoomCreateActivity" />
|
<activity android:name=".live.room.create.LiveRoomCreateActivity" />
|
||||||
<activity android:name=".live.room.update.LiveRoomEditActivity" />
|
<activity android:name=".live.room.update.LiveRoomEditActivity" />
|
||||||
<activity android:name=".live.reservation.complete.LiveReservationCompleteActivity" />
|
<activity android:name=".live.reservation.complete.LiveReservationCompleteActivity" />
|
||||||
|
@ -96,10 +94,8 @@
|
||||||
<activity android:name=".explorer.profile.UserProfileActivity" />
|
<activity android:name=".explorer.profile.UserProfileActivity" />
|
||||||
<activity android:name=".explorer.profile.donation.UserProfileDonationAllViewActivity" />
|
<activity android:name=".explorer.profile.donation.UserProfileDonationAllViewActivity" />
|
||||||
<activity android:name=".explorer.profile.fantalk.UserProfileFantalkAllViewActivity" />
|
<activity android:name=".explorer.profile.fantalk.UserProfileFantalkAllViewActivity" />
|
||||||
|
<activity android:name=".explorer.profile.CreatorNoticeWriteActivity" />
|
||||||
<activity android:name=".explorer.profile.follow.UserFollowerListActivity" />
|
<activity android:name=".explorer.profile.follow.UserFollowerListActivity" />
|
||||||
<activity android:name=".explorer.profile.creator_community.all.CreatorCommunityAllActivity" />
|
|
||||||
<activity android:name=".explorer.profile.creator_community.write.CreatorCommunityWriteActivity" />
|
|
||||||
<activity android:name=".explorer.profile.creator_community.modify.CreatorCommunityModifyActivity" />
|
|
||||||
<activity android:name=".message.text.TextMessageWriteActivity" />
|
<activity android:name=".message.text.TextMessageWriteActivity" />
|
||||||
<activity android:name=".message.text.TextMessageDetailActivity" />
|
<activity android:name=".message.text.TextMessageDetailActivity" />
|
||||||
<activity android:name=".message.SelectMessageRecipientActivity" />
|
<activity android:name=".message.SelectMessageRecipientActivity" />
|
||||||
|
@ -128,7 +124,6 @@
|
||||||
<activity android:name=".audio_content.curation.AudioContentCurationActivity" />
|
<activity android:name=".audio_content.curation.AudioContentCurationActivity" />
|
||||||
<activity android:name=".audio_content.all.AudioContentNewAllActivity" />
|
<activity android:name=".audio_content.all.AudioContentNewAllActivity" />
|
||||||
<activity android:name=".audio_content.all.AudioContentRankingAllActivity" />
|
<activity android:name=".audio_content.all.AudioContentRankingAllActivity" />
|
||||||
<activity android:name=".live.roulette.config.RouletteConfigActivity" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
||||||
|
@ -139,13 +134,9 @@
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".common.SodaLiveService"
|
android:name=".common.SodaLiveService"
|
||||||
android:foregroundServiceType="microphone|mediaPlayback"
|
|
||||||
android:stopWithTask="false" />
|
android:stopWithTask="false" />
|
||||||
|
|
||||||
<service
|
<service android:name=".audio_content.AudioContentPlayService" />
|
||||||
android:name=".audio_content.AudioContentPlayService"
|
|
||||||
android:foregroundServiceType="mediaPlayback"
|
|
||||||
android:stopWithTask="false" />
|
|
||||||
|
|
||||||
<!-- [START firebase_service] -->
|
<!-- [START firebase_service] -->
|
||||||
<service
|
<service
|
||||||
|
|
|
@ -8,7 +8,6 @@ import androidx.appcompat.app.AppCompatDelegate
|
||||||
import com.orhanobut.logger.AndroidLogAdapter
|
import com.orhanobut.logger.AndroidLogAdapter
|
||||||
import com.orhanobut.logger.Logger
|
import com.orhanobut.logger.Logger
|
||||||
import kr.co.vividnext.sodalive.BuildConfig
|
import kr.co.vividnext.sodalive.BuildConfig
|
||||||
import kr.co.vividnext.sodalive.common.ImageLoaderProvider
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.di.AppDI
|
import kr.co.vividnext.sodalive.di.AppDI
|
||||||
|
|
||||||
|
@ -27,8 +26,6 @@ class SodaLiveApp : Application() {
|
||||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||||
|
|
||||||
SharedPreferenceManager.init(applicationContext)
|
SharedPreferenceManager.init(applicationContext)
|
||||||
|
|
||||||
ImageLoaderProvider.init(applicationContext)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isDebuggable(): Boolean {
|
private fun isDebuggable(): Boolean {
|
||||||
|
|
|
@ -43,7 +43,6 @@ class AudioContentActivity : BaseActivity<ActivityAudioContentBinding>(
|
||||||
) {
|
) {
|
||||||
if (it.resultCode == Activity.RESULT_OK) {
|
if (it.resultCode == Activity.RESULT_OK) {
|
||||||
viewModel.page = 1
|
viewModel.page = 1
|
||||||
viewModel.isLast = false
|
|
||||||
viewModel.getAudioContentList(userId = userId) { finish() }
|
viewModel.getAudioContentList(userId = userId) { finish() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content
|
package kr.co.vividnext.sodalive.audio_content
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
|
@ -34,12 +33,6 @@ class AudioContentAdapter(
|
||||||
binding.tvLikeCount.text = item.likeCount.moneyFormat()
|
binding.tvLikeCount.text = item.likeCount.moneyFormat()
|
||||||
binding.tvCommentCount.text = item.commentCount.moneyFormat()
|
binding.tvCommentCount.text = item.commentCount.moneyFormat()
|
||||||
|
|
||||||
binding.tvScheduledToOpen.visibility = if (item.isScheduledToOpen) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.price < 1) {
|
if (item.price < 1) {
|
||||||
binding.tvPrice.text = "무료"
|
binding.tvPrice.text = "무료"
|
||||||
binding.tvPrice.setCompoundDrawables(null, null, null, null)
|
binding.tvPrice.setCompoundDrawables(null, null, null, null)
|
||||||
|
|
|
@ -10,11 +10,9 @@ import kr.co.vividnext.sodalive.audio_content.detail.GetAudioContentDetailRespon
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.PutAudioContentLikeRequest
|
import kr.co.vividnext.sodalive.audio_content.detail.PutAudioContentLikeRequest
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.PutAudioContentLikeResponse
|
import kr.co.vividnext.sodalive.audio_content.detail.PutAudioContentLikeResponse
|
||||||
import kr.co.vividnext.sodalive.audio_content.donation.AudioContentDonationRequest
|
import kr.co.vividnext.sodalive.audio_content.donation.AudioContentDonationRequest
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentCurationResponse
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainResponse
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking
|
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.order.GetAudioContentOrderListResponse
|
import kr.co.vividnext.sodalive.audio_content.order.GetAudioContentOrderListResponse
|
||||||
import kr.co.vividnext.sodalive.audio_content.order.OrderRequest
|
import kr.co.vividnext.sodalive.audio_content.order.OrderRequest
|
||||||
import kr.co.vividnext.sodalive.audio_content.upload.theme.GetAudioContentThemeResponse
|
import kr.co.vividnext.sodalive.audio_content.upload.theme.GetAudioContentThemeResponse
|
||||||
|
@ -127,6 +125,11 @@ interface AudioContentApi {
|
||||||
@Header("Authorization") authHeader: String
|
@Header("Authorization") authHeader: String
|
||||||
): Single<ApiResponse<Any>>
|
): Single<ApiResponse<Any>>
|
||||||
|
|
||||||
|
@GET("/audio-content/main")
|
||||||
|
fun getMain(
|
||||||
|
@Header("Authorization") authHeader: String
|
||||||
|
): Single<ApiResponse<GetAudioContentMainResponse>>
|
||||||
|
|
||||||
@GET("/audio-content/main/new")
|
@GET("/audio-content/main/new")
|
||||||
fun getNewContentOfTheme(
|
fun getNewContentOfTheme(
|
||||||
@Query("theme") theme: String,
|
@Query("theme") theme: String,
|
||||||
|
@ -179,26 +182,4 @@ interface AudioContentApi {
|
||||||
@Query("sort-type") sortType: String,
|
@Query("sort-type") sortType: String,
|
||||||
@Header("Authorization") authHeader: String
|
@Header("Authorization") authHeader: String
|
||||||
): Single<ApiResponse<GetAudioContentRanking>>
|
): Single<ApiResponse<GetAudioContentRanking>>
|
||||||
|
|
||||||
@GET("/audio-content/main/curation-list")
|
|
||||||
fun getCurationList(
|
|
||||||
@Query("page") page: Int,
|
|
||||||
@Query("size") size: Int,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetAudioContentCurationResponse>>>
|
|
||||||
|
|
||||||
@GET("/audio-content/main/new-content-upload-creator")
|
|
||||||
fun getNewContentUploadCreatorList(
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetNewContentUploadCreator>>>
|
|
||||||
|
|
||||||
@GET("/audio-content/main/banner-list")
|
|
||||||
fun getMainBannerList(
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetAudioContentBannerResponse>>>
|
|
||||||
|
|
||||||
@GET("/audio-content/main/order-list")
|
|
||||||
fun getMainOrderList(
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetAudioContentMainItem>>>
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,8 @@ class AudioContentRepository(
|
||||||
token: String
|
token: String
|
||||||
) = api.likeContent(request, authHeader = token)
|
) = api.likeContent(request, authHeader = token)
|
||||||
|
|
||||||
|
fun getMain(token: String) = api.getMain(authHeader = token)
|
||||||
|
|
||||||
fun getNewContentOfTheme(theme: String, token: String) = api.getNewContentOfTheme(
|
fun getNewContentOfTheme(theme: String, token: String) = api.getNewContentOfTheme(
|
||||||
theme = theme,
|
theme = theme,
|
||||||
authHeader = token
|
authHeader = token
|
||||||
|
@ -175,17 +177,4 @@ class AudioContentRepository(
|
||||||
sortType = sortType,
|
sortType = sortType,
|
||||||
authHeader = token
|
authHeader = token
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getCurationList(page: Int, size: Int, token: String) = api.getCurationList(
|
|
||||||
page = page - 1,
|
|
||||||
size = size,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getNewContentUploadCreatorList(
|
|
||||||
token: String
|
|
||||||
) = api.getNewContentUploadCreatorList(authHeader = token)
|
|
||||||
|
|
||||||
fun getMainBannerList(token: String) = api.getMainBannerList(authHeader = token)
|
|
||||||
fun getMainOrderList(token: String) = api.getMainOrderList(authHeader = token)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ class AudioContentViewModel(private val repository: AudioContentRepository) : Ba
|
||||||
PRICE_LOW
|
PRICE_LOW
|
||||||
}
|
}
|
||||||
|
|
||||||
var isLast = false
|
private var isLast = false
|
||||||
var page = 1
|
var page = 1
|
||||||
private val size = 10
|
private val size = 10
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
|
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainNewContentThemeAdapter
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
|
|
@ -9,7 +9,7 @@ import android.widget.Toast
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
|
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainNewContentThemeAdapter
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
|
|
@ -44,27 +44,27 @@ class AudioContentCommentAdapter(
|
||||||
binding.tvDonationCan.text = can.moneyFormat()
|
binding.tvDonationCan.text = can.moneyFormat()
|
||||||
binding.llDonationCan.setBackgroundResource(
|
binding.llDonationCan.setBackgroundResource(
|
||||||
when {
|
when {
|
||||||
can >= 10000 -> {
|
can >= 100000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_973a3a
|
R.drawable.bg_round_corner_10_7_973a3a
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 5000 -> {
|
can >= 50000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_d85e37
|
R.drawable.bg_round_corner_10_7_d85e37
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 1000 -> {
|
can >= 10000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_d38c38
|
R.drawable.bg_round_corner_10_7_d38c38
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 500 -> {
|
can >= 5000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_59548f
|
R.drawable.bg_round_corner_10_7_59548f
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 100 -> {
|
can >= 1000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_4d6aa4
|
R.drawable.bg_round_corner_10_7_4d6aa4
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 50 -> {
|
can >= 500 -> {
|
||||||
R.drawable.bg_round_corner_10_7_2d7390
|
R.drawable.bg_round_corner_10_7_2d7390
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,27 +124,27 @@ class AudioContentCommentReplyHeaderViewHolder(
|
||||||
binding.tvDonationCan.text = can.moneyFormat()
|
binding.tvDonationCan.text = can.moneyFormat()
|
||||||
binding.llDonationCan.setBackgroundResource(
|
binding.llDonationCan.setBackgroundResource(
|
||||||
when {
|
when {
|
||||||
can >= 10000 -> {
|
can >= 100000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_973a3a
|
R.drawable.bg_round_corner_10_7_973a3a
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 5000 -> {
|
can >= 50000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_d85e37
|
R.drawable.bg_round_corner_10_7_d85e37
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 1000 -> {
|
can >= 10000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_d38c38
|
R.drawable.bg_round_corner_10_7_d38c38
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 500 -> {
|
can >= 5000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_59548f
|
R.drawable.bg_round_corner_10_7_59548f
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 100 -> {
|
can >= 1000 -> {
|
||||||
R.drawable.bg_round_corner_10_7_4d6aa4
|
R.drawable.bg_round_corner_10_7_4d6aa4
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 50 -> {
|
can >= 500 -> {
|
||||||
R.drawable.bg_round_corner_10_7_2d7390
|
R.drawable.bg_round_corner_10_7_2d7390
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ import android.widget.RelativeLayout
|
||||||
import android.widget.SeekBar
|
import android.widget.SeekBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
|
@ -61,6 +60,10 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
private var creatorId: Long = 0
|
private var creatorId: Long = 0
|
||||||
|
|
||||||
private var refresh = false
|
private var refresh = false
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
setResult(RESULT_OK)
|
||||||
|
}
|
||||||
private var title = ""
|
private var title = ""
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
|
@ -94,11 +97,7 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val intentFilter = IntentFilter(Constants.ACTION_AUDIO_CONTENT_RECEIVER)
|
val intentFilter = IntentFilter(Constants.ACTION_AUDIO_CONTENT_RECEIVER)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
registerReceiver(audioContentReceiver, intentFilter)
|
||||||
registerReceiver(audioContentReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED)
|
|
||||||
} else {
|
|
||||||
registerReceiver(audioContentReceiver, intentFilter)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
viewModel.getAudioContentDetail(audioContentId = audioContentId) { finish() }
|
viewModel.getAudioContentDetail(audioContentId = audioContentId) { finish() }
|
||||||
|
@ -284,7 +283,6 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.menu_modify -> {
|
R.id.menu_modify -> {
|
||||||
refresh = true
|
refresh = true
|
||||||
setResult(RESULT_OK)
|
|
||||||
startActivity(
|
startActivity(
|
||||||
Intent(applicationContext, AudioContentModifyActivity::class.java)
|
Intent(applicationContext, AudioContentModifyActivity::class.java)
|
||||||
.apply {
|
.apply {
|
||||||
|
@ -498,30 +496,14 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupPurchaseButton(response: GetAudioContentDetailResponse) {
|
private fun setupPurchaseButton(response: GetAudioContentDetailResponse) {
|
||||||
if (response.releaseDate != null) {
|
if (
|
||||||
binding.llPurchase.visibility = View.VISIBLE
|
|
||||||
binding.llPurchasePrice.visibility = View.GONE
|
|
||||||
binding.tvReleaseDate.visibility = View.VISIBLE
|
|
||||||
binding.llPurchase.background = ContextCompat.getDrawable(
|
|
||||||
applicationContext,
|
|
||||||
R.drawable.bg_round_corner_5_3_525252
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.tvReleaseDate.text = response.releaseDate
|
|
||||||
} else if (
|
|
||||||
response.price > 0 &&
|
response.price > 0 &&
|
||||||
!response.existOrdered &&
|
!response.existOrdered &&
|
||||||
response.orderType == null &&
|
response.orderType == null &&
|
||||||
response.creator.creatorId != SharedPreferenceManager.userId
|
response.creator.creatorId != SharedPreferenceManager.userId
|
||||||
) {
|
) {
|
||||||
binding.tvReleaseDate.visibility = View.GONE
|
|
||||||
binding.llPurchase.visibility = View.VISIBLE
|
binding.llPurchase.visibility = View.VISIBLE
|
||||||
binding.llPurchasePrice.visibility = View.VISIBLE
|
|
||||||
binding.tvPrice.text = response.price.toString()
|
binding.tvPrice.text = response.price.toString()
|
||||||
binding.llPurchase.background = ContextCompat.getDrawable(
|
|
||||||
applicationContext,
|
|
||||||
R.drawable.bg_round_corner_5_3_3bb9f1
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.tvStrPurchaseOrRental.text = if (response.isOnlyRental) {
|
binding.tvStrPurchaseOrRental.text = if (response.isOnlyRental) {
|
||||||
" 대여하기"
|
" 대여하기"
|
||||||
|
@ -547,36 +529,22 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
.apply(RequestOptions().override((screenWidth - 13.3f.dpToPx()).toInt()))
|
.apply(RequestOptions().override((screenWidth - 13.3f.dpToPx()).toInt()))
|
||||||
.into(binding.ivCover)
|
.into(binding.ivCover)
|
||||||
|
|
||||||
if (
|
binding.ivPlayOrPause.setOnClickListener {
|
||||||
response.releaseDate == null ||
|
startService(
|
||||||
response.creator.creatorId == SharedPreferenceManager.userId
|
Intent(this, AudioContentPlayService::class.java).apply {
|
||||||
) {
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_COVER_IMAGE_URL, response.coverImageUrl)
|
||||||
binding.ivPlayOrPause.visibility = View.VISIBLE
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_URL, response.contentUrl)
|
||||||
binding.ivPlayOrPause.setOnClickListener {
|
putExtra(Constants.EXTRA_NICKNAME, response.creator.nickname)
|
||||||
startService(
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_TITLE, response.title)
|
||||||
Intent(this, AudioContentPlayService::class.java).apply {
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, response.contentId)
|
||||||
putExtra(
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_CREATOR_ID, response.creator.creatorId)
|
||||||
Constants.EXTRA_AUDIO_CONTENT_COVER_IMAGE_URL,
|
putExtra(Constants.EXTRA_AUDIO_CONTENT_FREE, response.price <= 0)
|
||||||
response.coverImageUrl
|
putExtra(
|
||||||
)
|
Constants.EXTRA_AUDIO_CONTENT_PREVIEW,
|
||||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_URL, response.contentUrl)
|
!response.existOrdered && response.price > 0
|
||||||
putExtra(Constants.EXTRA_NICKNAME, response.creator.nickname)
|
)
|
||||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_TITLE, response.title)
|
}
|
||||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_ID, response.contentId)
|
)
|
||||||
putExtra(
|
|
||||||
Constants.EXTRA_AUDIO_CONTENT_CREATOR_ID,
|
|
||||||
response.creator.creatorId
|
|
||||||
)
|
|
||||||
putExtra(Constants.EXTRA_AUDIO_CONTENT_FREE, response.price <= 0)
|
|
||||||
putExtra(
|
|
||||||
Constants.EXTRA_AUDIO_CONTENT_PREVIEW,
|
|
||||||
!response.existOrdered && response.price > 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.ivPlayOrPause.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvTotalDuration.text = " / ${response.duration}"
|
binding.tvTotalDuration.text = " / ${response.duration}"
|
||||||
|
@ -584,11 +552,6 @@ class AudioContentDetailActivity : BaseActivity<ActivityAudioContentDetailBindin
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun setupInfoArea(response: GetAudioContentDetailResponse) {
|
private fun setupInfoArea(response: GetAudioContentDetailResponse) {
|
||||||
binding.tvScheduledToOpen.visibility = if (response.releaseDate != null) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
binding.tvTheme.text = response.themeStr
|
binding.tvTheme.text = response.themeStr
|
||||||
binding.tv19.visibility = if (response.isAdult) {
|
binding.tv19.visibility = if (response.isAdult) {
|
||||||
View.VISIBLE
|
View.VISIBLE
|
||||||
|
|
|
@ -14,7 +14,6 @@ data class GetAudioContentDetailResponse(
|
||||||
@SerializedName("tag") val tag: String,
|
@SerializedName("tag") val tag: String,
|
||||||
@SerializedName("price") val price: Int,
|
@SerializedName("price") val price: Int,
|
||||||
@SerializedName("duration") val duration: String,
|
@SerializedName("duration") val duration: String,
|
||||||
@SerializedName("releaseDate") val releaseDate: String?,
|
|
||||||
@SerializedName("isAdult") val isAdult: Boolean,
|
@SerializedName("isAdult") val isAdult: Boolean,
|
||||||
@SerializedName("isMosaic") val isMosaic: Boolean,
|
@SerializedName("isMosaic") val isMosaic: Boolean,
|
||||||
@SerializedName("isOnlyRental") val isOnlyRental: Boolean,
|
@SerializedName("isOnlyRental") val isOnlyRental: Boolean,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.banner
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
@ -11,7 +11,6 @@ import com.bumptech.glide.request.transition.Transition
|
||||||
import com.zhpan.bannerview.BaseBannerAdapter
|
import com.zhpan.bannerview.BaseBannerAdapter
|
||||||
import com.zhpan.bannerview.BaseViewHolder
|
import com.zhpan.bannerview.BaseViewHolder
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
|
|
||||||
|
|
||||||
class AudioContentMainBannerAdapter(
|
class AudioContentMainBannerAdapter(
|
||||||
private val context: Context,
|
private val context: Context,
|
|
@ -1,4 +1,4 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.curation
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -8,9 +8,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainContentAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentCurationResponse
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainCurationBinding
|
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainCurationBinding
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
||||||
|
@ -92,11 +89,8 @@ class AudioContentMainCurationAdapter(
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
fun addItems(items: List<GetAudioContentCurationResponse>) {
|
fun addItems(items: List<GetAudioContentCurationResponse>) {
|
||||||
|
this.items.clear()
|
||||||
this.items.addAll(items)
|
this.items.addAll(items)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clear() {
|
|
||||||
this.items.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -17,26 +17,17 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.zhpan.bannerview.BaseBannerAdapter
|
import com.zhpan.bannerview.BaseBannerAdapter
|
||||||
import com.zhpan.indicator.enums.IndicatorSlideMode
|
import com.zhpan.indicator.enums.IndicatorSlideMode
|
||||||
import com.zhpan.indicator.enums.IndicatorStyle
|
import com.zhpan.indicator.enums.IndicatorStyle
|
||||||
|
import kr.co.pointclick.sdk.offerwall.core.PointClickAd
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.all.AudioContentNewAllActivity
|
import kr.co.vividnext.sodalive.audio_content.all.AudioContentNewAllActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.all.AudioContentRankingAllActivity
|
import kr.co.vividnext.sodalive.audio_content.all.AudioContentRankingAllActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.curation.AudioContentCurationActivity
|
import kr.co.vividnext.sodalive.audio_content.curation.AudioContentCurationActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentThemeAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingAdapter
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListActivity
|
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
|
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadActivity
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
import kr.co.vividnext.sodalive.base.BaseFragment
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
import kr.co.vividnext.sodalive.common.Constants
|
||||||
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentMainBinding
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
||||||
|
@ -49,37 +40,32 @@ import kotlin.math.roundToInt
|
||||||
class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
FragmentAudioContentMainBinding::inflate
|
FragmentAudioContentMainBinding::inflate
|
||||||
) {
|
) {
|
||||||
private val newContentCreatorViewModel: AudioContentMainNewContentCreatorViewModel by inject()
|
private val viewModel: AudioContentMainViewModel by inject()
|
||||||
|
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
private lateinit var imm: InputMethodManager
|
||||||
|
|
||||||
private lateinit var newContentCreatorAdapter: AudioContentMainNewContentCreatorAdapter
|
private lateinit var newContentCreatorAdapter: AudioContentMainNewContentCreatorAdapter
|
||||||
|
|
||||||
private val bannerViewModel: AudioContentMainBannerViewModel by inject()
|
|
||||||
private lateinit var bannerAdapter: AudioContentMainBannerAdapter
|
private lateinit var bannerAdapter: AudioContentMainBannerAdapter
|
||||||
|
|
||||||
private val orderListViewModel: AudioContentMainOrderListViewModel by inject()
|
|
||||||
private lateinit var orderListAdapter: AudioContentMainContentAdapter
|
private lateinit var orderListAdapter: AudioContentMainContentAdapter
|
||||||
|
|
||||||
private val newContentViewModel: AudioContentMainNewContentViewModel by inject()
|
|
||||||
private lateinit var newContentThemeAdapter: AudioContentMainNewContentThemeAdapter
|
private lateinit var newContentThemeAdapter: AudioContentMainNewContentThemeAdapter
|
||||||
private lateinit var newContentAdapter: AudioContentMainContentAdapter
|
private lateinit var newContentAdapter: AudioContentMainContentAdapter
|
||||||
|
|
||||||
private val contentRankingViewModel: AudioContentMainRankingViewModel by inject()
|
|
||||||
private lateinit var contentRankingSortAdapter: AudioContentMainNewContentThemeAdapter
|
private lateinit var contentRankingSortAdapter: AudioContentMainNewContentThemeAdapter
|
||||||
private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter
|
private lateinit var contentRankingAdapter: AudioContentMainRankingAdapter
|
||||||
|
|
||||||
private val curationViewModel: AudioContentMainCurationViewModel by inject()
|
|
||||||
private lateinit var curationAdapter: AudioContentMainCurationAdapter
|
private lateinit var curationAdapter: AudioContentMainCurationAdapter
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
setupView()
|
|
||||||
|
|
||||||
curationViewModel.getCurationList()
|
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
||||||
bannerViewModel.getMainBannerList()
|
imm = requireContext().getSystemService(
|
||||||
newContentViewModel.getThemeList()
|
Service.INPUT_METHOD_SERVICE
|
||||||
newContentViewModel.getNewContentOfTheme("전체")
|
) as InputMethodManager
|
||||||
contentRankingViewModel.getContentRanking()
|
|
||||||
contentRankingViewModel.getContentRankingSortType()
|
setupView()
|
||||||
newContentCreatorViewModel.getNewContentUploadCreatorList()
|
bindData()
|
||||||
|
|
||||||
|
viewModel.getMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupView() {
|
private fun setupView() {
|
||||||
|
@ -108,13 +94,11 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
|
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
curationViewModel.refresh()
|
viewModel.getMain()
|
||||||
bannerViewModel.getMainBannerList()
|
}
|
||||||
newContentViewModel.getThemeList()
|
|
||||||
newContentViewModel.getNewContentOfTheme("전체")
|
binding.ivCanFree.setOnClickListener {
|
||||||
contentRankingViewModel.getContentRanking()
|
PointClickAd.showOfferwall(requireActivity(), "무료충전")
|
||||||
contentRankingViewModel.getContentRankingSortType()
|
|
||||||
newContentCreatorViewModel.getNewContentUploadCreatorList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,21 +144,6 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvNewContentCreator.adapter = newContentCreatorAdapter
|
binding.rvNewContentCreator.adapter = newContentCreatorAdapter
|
||||||
|
|
||||||
newContentCreatorViewModel.newContentUploadCreatorListLiveData.observe(viewLifecycleOwner) {
|
|
||||||
newContentCreatorAdapter.addItems(it)
|
|
||||||
binding.rvNewContentCreator.visibility = if (
|
|
||||||
newContentCreatorAdapter.itemCount <= 0 && it.isEmpty()
|
|
||||||
) {
|
|
||||||
View.GONE
|
|
||||||
} else {
|
|
||||||
View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newContentCreatorViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupBanner() {
|
private fun setupBanner() {
|
||||||
|
@ -239,21 +208,6 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
)
|
)
|
||||||
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
.setIndicatorSliderWidth(4f.dpToPx().toInt(), 10f.dpToPx().toInt())
|
||||||
.setIndicatorHeight(4f.dpToPx().toInt())
|
.setIndicatorHeight(4f.dpToPx().toInt())
|
||||||
|
|
||||||
bannerViewModel.bannerLiveData.observe(viewLifecycleOwner) {
|
|
||||||
if (bannerAdapter.itemCount <= 0 && it.isEmpty()) {
|
|
||||||
binding.rvBanner.visibility = View.GONE
|
|
||||||
binding.indicatorBanner.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
binding.rvBanner.visibility = View.VISIBLE
|
|
||||||
binding.indicatorBanner.visibility = View.VISIBLE
|
|
||||||
binding.rvBanner.refreshData(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bannerViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupOrderList() {
|
private fun setupOrderList() {
|
||||||
|
@ -312,26 +266,11 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
binding.tvMyStashViewAll.setOnClickListener {
|
binding.tvMyStashViewAll.setOnClickListener {
|
||||||
startActivity(Intent(requireContext(), AudioContentOrderListActivity::class.java))
|
startActivity(Intent(requireContext(), AudioContentOrderListActivity::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
orderListViewModel.orderListLiveData.observe(viewLifecycleOwner) {
|
|
||||||
orderListAdapter.addItems(it)
|
|
||||||
binding.llMyStash.visibility = if (
|
|
||||||
orderListAdapter.itemCount <= 0 && it.isEmpty()
|
|
||||||
) {
|
|
||||||
View.GONE
|
|
||||||
} else {
|
|
||||||
View.VISIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
orderListViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupNewContentTheme() {
|
private fun setupNewContentTheme() {
|
||||||
newContentThemeAdapter = AudioContentMainNewContentThemeAdapter {
|
newContentThemeAdapter = AudioContentMainNewContentThemeAdapter {
|
||||||
newContentViewModel.getNewContentOfTheme(theme = it)
|
viewModel.getNewContentOfTheme(theme = it)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.rvNewContentTheme.layoutManager = LinearLayoutManager(
|
binding.rvNewContentTheme.layoutManager = LinearLayoutManager(
|
||||||
|
@ -369,11 +308,6 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvNewContentTheme.adapter = newContentThemeAdapter
|
binding.rvNewContentTheme.adapter = newContentThemeAdapter
|
||||||
|
|
||||||
newContentViewModel.themeListLiveData.observe(viewLifecycleOwner) {
|
|
||||||
binding.llNewContent.visibility = View.VISIBLE
|
|
||||||
newContentThemeAdapter.addItems(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupNewContent() {
|
private fun setupNewContent() {
|
||||||
|
@ -433,27 +367,11 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvNewContent.adapter = newContentAdapter
|
binding.rvNewContent.adapter = newContentAdapter
|
||||||
|
|
||||||
newContentViewModel.newContentListLiveData.observe(viewLifecycleOwner) {
|
|
||||||
newContentAdapter.addItems(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
newContentViewModel.isLoading.observe(viewLifecycleOwner) {
|
|
||||||
binding.pbNewContent.visibility = if (it) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newContentViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupContentRankingSortType() {
|
private fun setupContentRankingSortType() {
|
||||||
contentRankingSortAdapter = AudioContentMainNewContentThemeAdapter {
|
contentRankingSortAdapter = AudioContentMainNewContentThemeAdapter {
|
||||||
contentRankingViewModel.getContentRanking(sort = it)
|
viewModel.getContentRanking(sort = it)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.rvContentRankingSort.layoutManager = LinearLayoutManager(
|
binding.rvContentRankingSort.layoutManager = LinearLayoutManager(
|
||||||
|
@ -491,14 +409,8 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvContentRankingSort.adapter = contentRankingSortAdapter
|
binding.rvContentRankingSort.adapter = contentRankingSortAdapter
|
||||||
|
|
||||||
contentRankingViewModel.contentRankingSortListLiveData.observe(viewLifecycleOwner) {
|
|
||||||
binding.llContentRanking.visibility = View.VISIBLE
|
|
||||||
contentRankingSortAdapter.addItems(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun setupContentRanking() {
|
private fun setupContentRanking() {
|
||||||
binding.ivContentRankingAll.setOnClickListener {
|
binding.ivContentRankingAll.setOnClickListener {
|
||||||
startActivity(Intent(requireContext(), AudioContentRankingAllActivity::class.java))
|
startActivity(Intent(requireContext(), AudioContentRankingAllActivity::class.java))
|
||||||
|
@ -537,16 +449,6 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvContentRanking.adapter = contentRankingAdapter
|
binding.rvContentRanking.adapter = contentRankingAdapter
|
||||||
|
|
||||||
contentRankingViewModel.contentRankingLiveData.observe(viewLifecycleOwner) {
|
|
||||||
binding.llContentRanking.visibility = View.VISIBLE
|
|
||||||
binding.tvDate.text = "${it.startDate}~${it.endDate}"
|
|
||||||
contentRankingAdapter.addItems(it.items)
|
|
||||||
}
|
|
||||||
|
|
||||||
contentRankingViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCuration() {
|
private fun setupCuration() {
|
||||||
|
@ -609,50 +511,85 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.rvCuration.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
|
|
||||||
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
|
||||||
.findLastCompletelyVisibleItemPosition()
|
|
||||||
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
|
||||||
|
|
||||||
// 스크롤이 끝에 도달했는지 확인
|
|
||||||
if (!recyclerView.canScrollVertically(1) &&
|
|
||||||
lastVisibleItemPosition == itemTotalCount
|
|
||||||
) {
|
|
||||||
curationViewModel.getCurationList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
binding.rvCuration.adapter = curationAdapter
|
binding.rvCuration.adapter = curationAdapter
|
||||||
|
}
|
||||||
|
|
||||||
curationViewModel.curationListLiveData.observe(viewLifecycleOwner) {
|
@SuppressLint("SetTextI18n")
|
||||||
if (curationViewModel.page == 2) {
|
private fun bindData() {
|
||||||
curationAdapter.clear()
|
viewModel.isLoading.observe(viewLifecycleOwner) {
|
||||||
}
|
if (it) {
|
||||||
|
loadingDialog.show(screenWidth)
|
||||||
curationAdapter.addItems(it)
|
|
||||||
|
|
||||||
binding.rvCuration.visibility = if (curationAdapter.itemCount <= 0 && it.isEmpty()) {
|
|
||||||
View.GONE
|
|
||||||
} else {
|
} else {
|
||||||
View.VISIBLE
|
loadingDialog.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curationViewModel.isLoading.observe(viewLifecycleOwner) {
|
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
||||||
binding.pbCuration.visibility = if (it) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curationViewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.newContentUploadCreatorListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
newContentCreatorAdapter.addItems(it)
|
||||||
|
binding.rvNewContentCreator.visibility = if (
|
||||||
|
newContentCreatorAdapter.itemCount <= 0 && it.isEmpty()
|
||||||
|
) {
|
||||||
|
View.GONE
|
||||||
|
} else {
|
||||||
|
View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.bannerLiveData.observe(viewLifecycleOwner) {
|
||||||
|
if (bannerAdapter.itemCount <= 0 && it.isEmpty()) {
|
||||||
|
binding.rvBanner.visibility = View.GONE
|
||||||
|
binding.indicatorBanner.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.rvBanner.visibility = View.VISIBLE
|
||||||
|
binding.indicatorBanner.visibility = View.VISIBLE
|
||||||
|
binding.rvBanner.refreshData(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.orderListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
orderListAdapter.addItems(it)
|
||||||
|
binding.llMyStash.visibility = if (
|
||||||
|
orderListAdapter.itemCount <= 0 && it.isEmpty()
|
||||||
|
) {
|
||||||
|
View.GONE
|
||||||
|
} else {
|
||||||
|
View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.newContentListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
newContentAdapter.addItems(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.themeListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
binding.llNewContent.visibility = View.VISIBLE
|
||||||
|
newContentThemeAdapter.addItems(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.curationListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
curationAdapter.addItems(it)
|
||||||
|
binding.rvCuration.visibility = if (
|
||||||
|
curationAdapter.itemCount <= 0 && it.isEmpty()
|
||||||
|
) {
|
||||||
|
View.GONE
|
||||||
|
} else {
|
||||||
|
View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.contentRankingSortListLiveData.observe(viewLifecycleOwner) {
|
||||||
|
binding.llContentRanking.visibility = View.VISIBLE
|
||||||
|
contentRankingSortAdapter.addItems(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.contentRankingLiveData.observe(viewLifecycleOwner) {
|
||||||
|
binding.llContentRanking.visibility = View.VISIBLE
|
||||||
|
binding.tvDate.text = "${it.startDate}~${it.endDate}"
|
||||||
|
contentRankingAdapter.addItems(it.items)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainNewContentCreatorBinding
|
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainNewContentCreatorBinding
|
||||||
|
|
||||||
class AudioContentMainNewContentCreatorAdapter(
|
class AudioContentMainNewContentCreatorAdapter(
|
|
@ -1,4 +1,4 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.new_content
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -28,9 +28,9 @@ class AudioContentMainNewContentThemeAdapter(
|
||||||
(selectedTheme == "" && theme == "매출")
|
(selectedTheme == "" && theme == "매출")
|
||||||
) {
|
) {
|
||||||
binding.tvTheme.setBackgroundResource(
|
binding.tvTheme.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvTheme.setTextColor(ContextCompat.getColor(context, R.color.color_3bb9f1))
|
binding.tvTheme.setTextColor(ContextCompat.getColor(context, R.color.color_9970ff))
|
||||||
} else {
|
} else {
|
||||||
binding.tvTheme.setBackgroundResource(
|
binding.tvTheme.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_777777
|
R.drawable.bg_round_corner_16_7_transparent_777777
|
|
@ -1,4 +1,4 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.ranking
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRankingItem
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainRankingBinding
|
import kr.co.vividnext.sodalive.databinding.ItemAudioContentMainRankingBinding
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
package kr.co.vividnext.sodalive.audio_content.main
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.orhanobut.logger.Logger
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
|
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
||||||
|
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||||
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
|
|
||||||
|
class AudioContentMainViewModel(
|
||||||
|
private val repository: AudioContentRepository
|
||||||
|
) : BaseViewModel() {
|
||||||
|
private val _toastLiveData = MutableLiveData<String?>()
|
||||||
|
val toastLiveData: LiveData<String?>
|
||||||
|
get() = _toastLiveData
|
||||||
|
|
||||||
|
private var _isLoading = MutableLiveData(false)
|
||||||
|
val isLoading: LiveData<Boolean>
|
||||||
|
get() = _isLoading
|
||||||
|
|
||||||
|
private var _newContentUploadCreatorListLiveData =
|
||||||
|
MutableLiveData<List<GetNewContentUploadCreator>>()
|
||||||
|
val newContentUploadCreatorListLiveData: LiveData<List<GetNewContentUploadCreator>>
|
||||||
|
get() = _newContentUploadCreatorListLiveData
|
||||||
|
|
||||||
|
private var _newContentListLiveData = MutableLiveData<List<GetAudioContentMainItem>>()
|
||||||
|
val newContentListLiveData: LiveData<List<GetAudioContentMainItem>>
|
||||||
|
get() = _newContentListLiveData
|
||||||
|
|
||||||
|
private var _bannerLiveData = MutableLiveData<List<GetAudioContentBannerResponse>>()
|
||||||
|
val bannerLiveData: LiveData<List<GetAudioContentBannerResponse>>
|
||||||
|
get() = _bannerLiveData
|
||||||
|
|
||||||
|
private var _orderListLiveData = MutableLiveData<List<GetAudioContentMainItem>>()
|
||||||
|
val orderListLiveData: LiveData<List<GetAudioContentMainItem>>
|
||||||
|
get() = _orderListLiveData
|
||||||
|
|
||||||
|
private var _themeListLiveData = MutableLiveData<List<String>>()
|
||||||
|
val themeListLiveData: LiveData<List<String>>
|
||||||
|
get() = _themeListLiveData
|
||||||
|
|
||||||
|
private var _curationListLiveData = MutableLiveData<List<GetAudioContentCurationResponse>>()
|
||||||
|
val curationListLiveData: LiveData<List<GetAudioContentCurationResponse>>
|
||||||
|
get() = _curationListLiveData
|
||||||
|
|
||||||
|
private var _contentRankingSortListLiveData = MutableLiveData<List<String>>()
|
||||||
|
val contentRankingSortListLiveData: LiveData<List<String>>
|
||||||
|
get() = _contentRankingSortListLiveData
|
||||||
|
|
||||||
|
private var _contentRankingLiveData = MutableLiveData<GetAudioContentRanking>()
|
||||||
|
val contentRankingLiveData: LiveData<GetAudioContentRanking>
|
||||||
|
get() = _contentRankingLiveData
|
||||||
|
|
||||||
|
fun getMain() {
|
||||||
|
_isLoading.value = true
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.getMain(token = "Bearer ${SharedPreferenceManager.token}")
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
val data = it.data
|
||||||
|
_newContentUploadCreatorListLiveData.value =
|
||||||
|
data.newContentUploadCreatorList
|
||||||
|
_newContentListLiveData.value = data.newContentList
|
||||||
|
_orderListLiveData.value = data.orderList
|
||||||
|
_bannerLiveData.value = data.bannerList
|
||||||
|
_curationListLiveData.value = data.curationList
|
||||||
|
_contentRankingLiveData.value = data.contentRanking
|
||||||
|
_contentRankingSortListLiveData.value = data.contentRankingSortTypeList
|
||||||
|
|
||||||
|
val themeList = listOf("전체").union(data.themeList).toList()
|
||||||
|
_themeListLiveData.value = themeList
|
||||||
|
} else {
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isLoading.value = false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_isLoading.value = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNewContentOfTheme(theme: String) {
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.getNewContentOfTheme(
|
||||||
|
theme = if (theme == "전체") {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
theme
|
||||||
|
},
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
_newContentListLiveData.value = it.data!!
|
||||||
|
} else {
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getContentRanking(sort: String) {
|
||||||
|
_isLoading.value = true
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.getContentRanking(
|
||||||
|
page = 1,
|
||||||
|
size = 12,
|
||||||
|
sortType = sort,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
if (it.success && it.data != null) {
|
||||||
|
_isLoading.value = false
|
||||||
|
_contentRankingLiveData.value = it.data!!
|
||||||
|
} else {
|
||||||
|
_isLoading.value = false
|
||||||
|
if (it.message != null) {
|
||||||
|
_toastLiveData.postValue(it.message)
|
||||||
|
} else {
|
||||||
|
_toastLiveData.postValue(
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,18 @@ package kr.co.vividnext.sodalive.audio_content.main
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import kr.co.vividnext.sodalive.settings.event.EventItem
|
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||||
|
|
||||||
|
data class GetAudioContentMainResponse(
|
||||||
|
@SerializedName("newContentUploadCreatorList")
|
||||||
|
val newContentUploadCreatorList: List<GetNewContentUploadCreator>,
|
||||||
|
@SerializedName("bannerList") val bannerList: List<GetAudioContentBannerResponse>,
|
||||||
|
@SerializedName("orderList") val orderList: List<GetAudioContentMainItem>,
|
||||||
|
@SerializedName("themeList") val themeList: List<String>,
|
||||||
|
@SerializedName("newContentList") val newContentList: List<GetAudioContentMainItem>,
|
||||||
|
@SerializedName("curationList") val curationList: List<GetAudioContentCurationResponse>,
|
||||||
|
@SerializedName("contentRankingSortTypeList") val contentRankingSortTypeList: List<String>,
|
||||||
|
@SerializedName("contentRanking") val contentRanking: GetAudioContentRanking
|
||||||
|
)
|
||||||
|
|
||||||
data class GetNewContentUploadCreator(
|
data class GetNewContentUploadCreator(
|
||||||
@SerializedName("creatorId") val creatorId: Long,
|
@SerializedName("creatorId") val creatorId: Long,
|
||||||
@SerializedName("creatorNickname") val creatorNickname: String,
|
@SerializedName("creatorNickname") val creatorNickname: String,
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.banner
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentBannerResponse
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainBannerViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _bannerLiveData = MutableLiveData<List<GetAudioContentBannerResponse>>()
|
|
||||||
val bannerLiveData: LiveData<List<GetAudioContentBannerResponse>>
|
|
||||||
get() = _bannerLiveData
|
|
||||||
|
|
||||||
fun getMainBannerList() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getMainBannerList(token = "Bearer ${SharedPreferenceManager.token}")
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_bannerLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"배너를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"배너를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.curation
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentCurationResponse
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainCurationViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private var _curationListLiveData = MutableLiveData<List<GetAudioContentCurationResponse>>()
|
|
||||||
val curationListLiveData: LiveData<List<GetAudioContentCurationResponse>>
|
|
||||||
get() = _curationListLiveData
|
|
||||||
|
|
||||||
var page = 1
|
|
||||||
var isLast = false
|
|
||||||
private val pageSize = 10
|
|
||||||
|
|
||||||
fun getCurationList() {
|
|
||||||
if (!_isLoading.value!! && !isLast) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getCurationList(
|
|
||||||
page = page,
|
|
||||||
size = pageSize,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
page += 1
|
|
||||||
|
|
||||||
if (it.data.isNotEmpty()) {
|
|
||||||
_curationListLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
_curationListLiveData.postValue(listOf())
|
|
||||||
isLast = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"큐레이션을 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"큐레이션을 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refresh() {
|
|
||||||
page = 1
|
|
||||||
isLast = false
|
|
||||||
getCurationList()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.new_content
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainNewContentViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private var _newContentListLiveData = MutableLiveData<List<GetAudioContentMainItem>>()
|
|
||||||
val newContentListLiveData: LiveData<List<GetAudioContentMainItem>>
|
|
||||||
get() = _newContentListLiveData
|
|
||||||
|
|
||||||
private var _themeListLiveData = MutableLiveData<List<String>>()
|
|
||||||
val themeListLiveData: LiveData<List<String>>
|
|
||||||
get() = _themeListLiveData
|
|
||||||
|
|
||||||
fun getThemeList() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getNewContentThemeList(token = "Bearer ${SharedPreferenceManager.token}")
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
val themeList = listOf("전체").union(it.data).toList()
|
|
||||||
_themeListLiveData.postValue(themeList)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNewContentOfTheme(theme: String) {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getNewContentOfTheme(
|
|
||||||
theme = if (theme == "전체") {
|
|
||||||
""
|
|
||||||
} else {
|
|
||||||
theme
|
|
||||||
},
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_newContentListLiveData.value = it.data!!
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetNewContentUploadCreator
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainNewContentCreatorViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _newContentUploadCreatorListLiveData =
|
|
||||||
MutableLiveData<List<GetNewContentUploadCreator>>()
|
|
||||||
val newContentUploadCreatorListLiveData: LiveData<List<GetNewContentUploadCreator>>
|
|
||||||
get() = _newContentUploadCreatorListLiveData
|
|
||||||
|
|
||||||
fun getNewContentUploadCreatorList() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getNewContentUploadCreatorList(
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_newContentUploadCreatorListLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"크리에이터 리스트를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.order
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentMainItem
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainOrderListViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _orderListLiveData = MutableLiveData<List<GetAudioContentMainItem>>()
|
|
||||||
val orderListLiveData: LiveData<List<GetAudioContentMainItem>>
|
|
||||||
get() = _orderListLiveData
|
|
||||||
|
|
||||||
fun getOrderList() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getMainOrderList(token = "Bearer ${SharedPreferenceManager.token}")
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_orderListLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"주문정보를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"주문정보를 불러오지 못했습니다. 다시 시도해 주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.audio_content.main.ranking
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentRepository
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.GetAudioContentRanking
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
|
|
||||||
class AudioContentMainRankingViewModel(
|
|
||||||
private val repository: AudioContentRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _contentRankingSortListLiveData = MutableLiveData<List<String>>()
|
|
||||||
val contentRankingSortListLiveData: LiveData<List<String>>
|
|
||||||
get() = _contentRankingSortListLiveData
|
|
||||||
|
|
||||||
private var _contentRankingLiveData = MutableLiveData<GetAudioContentRanking>()
|
|
||||||
val contentRankingLiveData: LiveData<GetAudioContentRanking>
|
|
||||||
get() = _contentRankingLiveData
|
|
||||||
|
|
||||||
fun getContentRankingSortType() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getContentRankingSortType(token = "Bearer ${SharedPreferenceManager.token}")
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_contentRankingSortListLiveData.value = it.data!!
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getContentRanking(sort: String = "매출") {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getContentRanking(
|
|
||||||
page = 1,
|
|
||||||
size = 12,
|
|
||||||
sortType = sort,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_contentRankingLiveData.value = it.data!!
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,6 @@ package kr.co.vividnext.sodalive.audio_content.upload
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.DatePickerDialog
|
|
||||||
import android.app.TimePickerDialog
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -30,15 +28,9 @@ import kr.co.vividnext.sodalive.common.RealPathUtil
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityAudioContentUploadBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityAudioContentUploadBinding
|
||||||
import kr.co.vividnext.sodalive.dialog.LiveDialog
|
import kr.co.vividnext.sodalive.dialog.LiveDialog
|
||||||
import kr.co.vividnext.sodalive.dialog.SodaLiveTimePickerDialog
|
|
||||||
import kr.co.vividnext.sodalive.extensions.convertDateFormat
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBinding>(
|
class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBinding>(
|
||||||
ActivityAudioContentUploadBinding::inflate
|
ActivityAudioContentUploadBinding::inflate
|
||||||
|
@ -119,26 +111,6 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val datePickerDialogListener =
|
|
||||||
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
|
||||||
viewModel.releaseDate = String.format("%d-%02d-%02d", year, monthOfYear + 1, dayOfMonth)
|
|
||||||
viewModel.setReservationDate(
|
|
||||||
String.format(
|
|
||||||
"%d.%02d.%02d",
|
|
||||||
year,
|
|
||||||
monthOfYear + 1,
|
|
||||||
dayOfMonth
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val timePickerDialogListener =
|
|
||||||
TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
|
|
||||||
val timeString = String.format("%02d:%02d", hourOfDay, minute)
|
|
||||||
viewModel.releaseTime = timeString
|
|
||||||
viewModel.setReservationTime(timeString.convertDateFormat("HH:mm", "a hh:mm"))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
checkPermissions()
|
checkPermissions()
|
||||||
|
@ -201,8 +173,6 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
binding.llOnlyRental.setOnClickListener { viewModel.setIsOnlyRental(true) }
|
binding.llOnlyRental.setOnClickListener { viewModel.setIsOnlyRental(true) }
|
||||||
binding.llCommentNo.setOnClickListener { viewModel.setAvailableComment(false) }
|
binding.llCommentNo.setOnClickListener { viewModel.setAvailableComment(false) }
|
||||||
binding.llCommentYes.setOnClickListener { viewModel.setAvailableComment(true) }
|
binding.llCommentYes.setOnClickListener { viewModel.setAvailableComment(true) }
|
||||||
binding.llActiveNow.setOnClickListener { viewModel.setActiveReservation(false) }
|
|
||||||
binding.llActiveReservation.setOnClickListener { viewModel.setActiveReservation(true) }
|
|
||||||
|
|
||||||
binding.tvCancel.setOnClickListener { finish() }
|
binding.tvCancel.setOnClickListener { finish() }
|
||||||
binding.tvUpload.setOnClickListener {
|
binding.tvUpload.setOnClickListener {
|
||||||
|
@ -219,71 +189,6 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
).show(screenWidth)
|
).show(screenWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvReservationDate.setOnClickListener {
|
|
||||||
val reservationDate = viewModel.releaseDate.split("-")
|
|
||||||
val datePicker: DatePickerDialog
|
|
||||||
|
|
||||||
if (reservationDate.isNotEmpty() && reservationDate.size == 3) {
|
|
||||||
datePicker = DatePickerDialog(
|
|
||||||
this,
|
|
||||||
R.style.DatePickerStyle,
|
|
||||||
datePickerDialogListener,
|
|
||||||
reservationDate[0].toInt(),
|
|
||||||
reservationDate[1].toInt() - 1,
|
|
||||||
reservationDate[2].toInt()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val dateString = SimpleDateFormat(
|
|
||||||
"yyyy.MM.dd",
|
|
||||||
Locale.getDefault()
|
|
||||||
).format(Date()).split(".")
|
|
||||||
|
|
||||||
datePicker = DatePickerDialog(
|
|
||||||
this,
|
|
||||||
R.style.DatePickerStyle,
|
|
||||||
datePickerDialogListener,
|
|
||||||
dateString[0].toInt(),
|
|
||||||
dateString[1].toInt() - 1,
|
|
||||||
dateString[2].toInt()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
datePicker.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvReservationTime.setOnClickListener {
|
|
||||||
val reservationTime = viewModel.releaseTime.split(":")
|
|
||||||
val timePicker: TimePickerDialog
|
|
||||||
|
|
||||||
if (reservationTime.isNotEmpty() && reservationTime.size == 2) {
|
|
||||||
timePicker = SodaLiveTimePickerDialog(
|
|
||||||
this,
|
|
||||||
R.style.TimePickerStyle,
|
|
||||||
timePickerDialogListener,
|
|
||||||
reservationTime[0].toInt(),
|
|
||||||
reservationTime[1].toInt(),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val calendar = Calendar.getInstance().apply {
|
|
||||||
add(Calendar.HOUR_OF_DAY, 1)
|
|
||||||
}
|
|
||||||
val initialHour = calendar.get(Calendar.HOUR_OF_DAY)
|
|
||||||
val initialMinute = calendar.get(Calendar.MINUTE) / 15 * 15
|
|
||||||
|
|
||||||
timePicker = SodaLiveTimePickerDialog(
|
|
||||||
this,
|
|
||||||
R.style.TimePickerStyle,
|
|
||||||
timePickerDialogListener,
|
|
||||||
initialHour,
|
|
||||||
initialMinute,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
timePicker.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkPermissions() {
|
private fun checkPermissions() {
|
||||||
|
@ -418,17 +323,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llCommentYes.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llCommentYes.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivCommentNo.visibility = View.GONE
|
binding.ivCommentNo.visibility = View.GONE
|
||||||
binding.tvCommentNo.setTextColor(
|
binding.tvCommentNo.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llCommentNo.setBackgroundResource(
|
binding.llCommentNo.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734_9970ff
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
binding.ivCommentNo.visibility = View.VISIBLE
|
binding.ivCommentNo.visibility = View.VISIBLE
|
||||||
|
@ -438,17 +343,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llCommentNo.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llCommentNo.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivCommentYes.visibility = View.GONE
|
binding.ivCommentYes.visibility = View.GONE
|
||||||
binding.tvCommentYes.setTextColor(
|
binding.tvCommentYes.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llCommentYes
|
binding.llCommentYes
|
||||||
.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734_9970ff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,16 +369,16 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
viewModel.isAdultLiveData.observe(this) {
|
viewModel.isAdultLiveData.observe(this) {
|
||||||
if (it) {
|
if (it) {
|
||||||
binding.ivAgeAll.visibility = View.GONE
|
binding.ivAgeAll.visibility = View.GONE
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
binding.tvAgeAll.setTextColor(
|
binding.tvAgeAll.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.ivAge19.visibility = View.VISIBLE
|
binding.ivAge19.visibility = View.VISIBLE
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.tvAge19.setTextColor(
|
binding.tvAge19.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -482,16 +387,16 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
binding.ivAge19.visibility = View.GONE
|
binding.ivAge19.visibility = View.GONE
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
binding.tvAge19.setTextColor(
|
binding.tvAge19.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.ivAgeAll.visibility = View.VISIBLE
|
binding.ivAgeAll.visibility = View.VISIBLE
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.tvAgeAll.setTextColor(
|
binding.tvAgeAll.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -501,69 +406,6 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.isActiveReservationLiveData.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
checkActiveReservation()
|
|
||||||
} else {
|
|
||||||
checkActiveNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.reservationDateLiveData.observe(this) {
|
|
||||||
binding.tvReservationDate.text = it
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.reservationTimeLiveData.observe(this) {
|
|
||||||
binding.tvReservationTime.text = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkActiveNow() {
|
|
||||||
binding.llReservationDatetime.visibility = View.GONE
|
|
||||||
|
|
||||||
binding.ivActiveNow.visibility = View.VISIBLE
|
|
||||||
binding.tvActiveNow.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_eeeeee
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llActiveNow.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivActiveReservation.visibility = View.GONE
|
|
||||||
binding.tvActiveReservation.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_3bb9f1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llActiveReservation.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkActiveReservation() {
|
|
||||||
binding.llReservationDatetime.visibility = View.VISIBLE
|
|
||||||
binding.ivActiveReservation.visibility = View.VISIBLE
|
|
||||||
binding.tvActiveReservation.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_eeeeee
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llActiveReservation.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivActiveNow.visibility = View.GONE
|
|
||||||
binding.tvActiveNow.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_3bb9f1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llActiveNow.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkPriceFree() {
|
private fun checkPriceFree() {
|
||||||
|
@ -580,17 +422,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llPriceFree.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llPriceFree.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivPricePaid.visibility = View.GONE
|
binding.ivPricePaid.visibility = View.GONE
|
||||||
binding.tvPricePaid.setTextColor(
|
binding.tvPricePaid.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llPricePaid.setBackgroundResource(
|
binding.llPricePaid.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734_9970ff
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.llConfigPreviewTime.visibility = View.GONE
|
binding.llConfigPreviewTime.visibility = View.GONE
|
||||||
|
@ -608,17 +450,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llPricePaid.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llPricePaid.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivPriceFree.visibility = View.GONE
|
binding.ivPriceFree.visibility = View.GONE
|
||||||
binding.tvPriceFree.setTextColor(
|
binding.tvPriceFree.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llPriceFree.setBackgroundResource(
|
binding.llPriceFree.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734_9970ff
|
||||||
)
|
)
|
||||||
binding.llConfigPreviewTime.visibility = View.VISIBLE
|
binding.llConfigPreviewTime.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
@ -632,17 +474,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llRentalAndKeep.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llRentalAndKeep.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivOnlyRental.visibility = View.GONE
|
binding.ivOnlyRental.visibility = View.GONE
|
||||||
binding.tvOnlyRental.setTextColor(
|
binding.tvOnlyRental.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llOnlyRental.setBackgroundResource(
|
binding.llOnlyRental.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734_9970ff
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,17 +497,17 @@ class AudioContentUploadActivity : BaseActivity<ActivityAudioContentUploadBindin
|
||||||
R.color.color_eeeeee
|
R.color.color_eeeeee
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llOnlyRental.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llOnlyRental.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
|
|
||||||
binding.ivRentalAndKeep.visibility = View.GONE
|
binding.ivRentalAndKeep.visibility = View.GONE
|
||||||
binding.tvRentalAndKeep.setTextColor(
|
binding.tvRentalAndKeep.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.llRentalAndKeep.setBackgroundResource(
|
binding.llRentalAndKeep.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734_9970ff
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import okio.BufferedSink
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.TimeZone
|
|
||||||
|
|
||||||
class AudioContentUploadViewModel(
|
class AudioContentUploadViewModel(
|
||||||
private val repository: AudioContentRepository
|
private val repository: AudioContentRepository
|
||||||
|
@ -50,26 +49,12 @@ class AudioContentUploadViewModel(
|
||||||
val isPriceFreeLiveData: LiveData<Boolean>
|
val isPriceFreeLiveData: LiveData<Boolean>
|
||||||
get() = _isPriceFreeLiveData
|
get() = _isPriceFreeLiveData
|
||||||
|
|
||||||
private val _isActiveReservationLiveData = MutableLiveData(false)
|
|
||||||
val isActiveReservationLiveData: LiveData<Boolean>
|
|
||||||
get() = _isActiveReservationLiveData
|
|
||||||
|
|
||||||
private val _reservationDateLiveData = MutableLiveData("날짜를 선택해주세요")
|
|
||||||
val reservationDateLiveData: LiveData<String>
|
|
||||||
get() = _reservationDateLiveData
|
|
||||||
|
|
||||||
private val _reservationTimeLiveData = MutableLiveData("시간을 설정해주세요")
|
|
||||||
val reservationTimeLiveData: LiveData<String>
|
|
||||||
get() = _reservationTimeLiveData
|
|
||||||
|
|
||||||
lateinit var getRealPathFromURI: (Uri) -> String?
|
lateinit var getRealPathFromURI: (Uri) -> String?
|
||||||
|
|
||||||
var title = ""
|
var title = ""
|
||||||
var detail = ""
|
var detail = ""
|
||||||
var tags = ""
|
var tags = ""
|
||||||
var price = 0
|
var price = 0
|
||||||
var releaseDate = ""
|
|
||||||
var releaseTime = ""
|
|
||||||
var theme: GetAudioContentThemeResponse? = null
|
var theme: GetAudioContentThemeResponse? = null
|
||||||
var coverImageUri: Uri? = null
|
var coverImageUri: Uri? = null
|
||||||
var contentUri: Uri? = null
|
var contentUri: Uri? = null
|
||||||
|
@ -96,10 +81,6 @@ class AudioContentUploadViewModel(
|
||||||
_isOnlyRentalLiveData.postValue(isOnlyRental)
|
_isOnlyRentalLiveData.postValue(isOnlyRental)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setActiveReservation(isActiveReservation: Boolean) {
|
|
||||||
_isActiveReservationLiveData.postValue(isActiveReservation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun uploadAudioContent(onSuccess: () -> Unit) {
|
fun uploadAudioContent(onSuccess: () -> Unit) {
|
||||||
if (!_isLoading.value!! && validateData()) {
|
if (!_isLoading.value!! && validateData()) {
|
||||||
_isLoading.postValue(true)
|
_isLoading.postValue(true)
|
||||||
|
@ -109,12 +90,6 @@ class AudioContentUploadViewModel(
|
||||||
detail = detail,
|
detail = detail,
|
||||||
tags = tags,
|
tags = tags,
|
||||||
price = price,
|
price = price,
|
||||||
releaseDate = if (_isActiveReservationLiveData.value!!) {
|
|
||||||
"$releaseDate $releaseTime"
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
themeId = theme!!.id,
|
themeId = theme!!.id,
|
||||||
isAdult = _isAdultLiveData.value!!,
|
isAdult = _isAdultLiveData.value!!,
|
||||||
isOnlyRental = _isOnlyRentalLiveData.value!!,
|
isOnlyRental = _isOnlyRentalLiveData.value!!,
|
||||||
|
@ -306,14 +281,6 @@ class AudioContentUploadViewModel(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
_isActiveReservationLiveData.value!! &&
|
|
||||||
(releaseDate.isBlank() || releaseTime.isBlank())
|
|
||||||
) {
|
|
||||||
_toastLiveData.postValue("예약날짜와 시간을 선택해주세요.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,12 +307,4 @@ class AudioContentUploadViewModel(
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setReservationDate(dateString: String) {
|
|
||||||
_reservationDateLiveData.postValue(dateString)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setReservationTime(timeString: String) {
|
|
||||||
_reservationTimeLiveData.postValue(timeString)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,10 @@ data class CreateAudioContentRequest(
|
||||||
@SerializedName("detail") val detail: String,
|
@SerializedName("detail") val detail: String,
|
||||||
@SerializedName("tags") val tags: String,
|
@SerializedName("tags") val tags: String,
|
||||||
@SerializedName("price") val price: Int,
|
@SerializedName("price") val price: Int,
|
||||||
@SerializedName("releaseDate") val releaseDate: String?,
|
|
||||||
@SerializedName("timezone") val timezone: String,
|
|
||||||
@SerializedName("themeId") val themeId: Long,
|
@SerializedName("themeId") val themeId: Long,
|
||||||
@SerializedName("isAdult") val isAdult: Boolean,
|
@SerializedName("isAdult") val isAdult: Boolean,
|
||||||
@SerializedName("isOnlyRental") val isOnlyRental: Boolean,
|
@SerializedName("isOnlyRental") val isOnlyRental: Boolean,
|
||||||
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean,
|
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean,
|
||||||
@SerializedName("previewStartTime") val previewStartTime: String? = null,
|
@SerializedName("previewStartTime") val previewStartTime: String? = null,
|
||||||
@SerializedName("previewEndTime") val previewEndTime: String? = null,
|
@SerializedName("previewEndTime") val previewEndTime: String? = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,7 +29,6 @@ object Constants {
|
||||||
const val EXTRA_MESSAGE_BOX = "extra_message_box"
|
const val EXTRA_MESSAGE_BOX = "extra_message_box"
|
||||||
const val EXTRA_TEXT_MESSAGE = "extra_text_message"
|
const val EXTRA_TEXT_MESSAGE = "extra_text_message"
|
||||||
const val EXTRA_LIVE_TIME_NOW = "extra_live_time_now"
|
const val EXTRA_LIVE_TIME_NOW = "extra_live_time_now"
|
||||||
const val EXTRA_RESULT_ROULETTE = "extra_result_roulette"
|
|
||||||
const val EXTRA_GO_TO_PREV_PAGE = "extra_go_to_prev_page"
|
const val EXTRA_GO_TO_PREV_PAGE = "extra_go_to_prev_page"
|
||||||
const val EXTRA_SELECT_RECIPIENT = "extra_select_recipient"
|
const val EXTRA_SELECT_RECIPIENT = "extra_select_recipient"
|
||||||
const val EXTRA_ROOM_CHANNEL_NAME = "extra_room_channel_name"
|
const val EXTRA_ROOM_CHANNEL_NAME = "extra_room_channel_name"
|
||||||
|
@ -57,8 +56,4 @@ object Constants {
|
||||||
const val LIVE_SERVICE_NOTIFICATION_ID: Int = 2
|
const val LIVE_SERVICE_NOTIFICATION_ID: Int = 2
|
||||||
const val ACTION_AUDIO_CONTENT_RECEIVER = "soda_live_action_content_receiver"
|
const val ACTION_AUDIO_CONTENT_RECEIVER = "soda_live_action_content_receiver"
|
||||||
const val ACTION_MAIN_AUDIO_CONTENT_RECEIVER = "soda_live_action_main_content_receiver"
|
const val ACTION_MAIN_AUDIO_CONTENT_RECEIVER = "soda_live_action_main_content_receiver"
|
||||||
|
|
||||||
const val EXTRA_COMMUNITY_POST_ID = "community_post_id"
|
|
||||||
const val EXTRA_COMMUNITY_CREATOR_ID = "community_creator_id"
|
|
||||||
const val EXTRA_COMMUNITY_POST_COMMENT = "community_post_comment_id"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.common
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import coil.ImageLoader
|
|
||||||
import okhttp3.Cache
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
object ImageLoaderProvider {
|
|
||||||
lateinit var imageLoader: ImageLoader
|
|
||||||
private set
|
|
||||||
|
|
||||||
val isInitialized: Boolean
|
|
||||||
get() = ::imageLoader.isInitialized
|
|
||||||
fun init(context: Context) {
|
|
||||||
val cacheSize = 250L * 1024L * 1024L // 250 MB
|
|
||||||
val cacheDirectory = File(
|
|
||||||
context.cacheDir,
|
|
||||||
"image_cache"
|
|
||||||
).apply { mkdirs() }
|
|
||||||
|
|
||||||
val cache = Cache(cacheDirectory, cacheSize)
|
|
||||||
|
|
||||||
imageLoader = ImageLoader.Builder(context)
|
|
||||||
.okHttpClient {
|
|
||||||
OkHttpClient().newBuilder()
|
|
||||||
.cache(cache)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,12 +14,7 @@ import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentReplyVi
|
||||||
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentRepository
|
import kr.co.vividnext.sodalive.audio_content.comment.AudioContentCommentRepository
|
||||||
import kr.co.vividnext.sodalive.audio_content.curation.AudioContentCurationViewModel
|
import kr.co.vividnext.sodalive.audio_content.curation.AudioContentCurationViewModel
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailViewModel
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailViewModel
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.banner.AudioContentMainBannerViewModel
|
import kr.co.vividnext.sodalive.audio_content.main.AudioContentMainViewModel
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.curation.AudioContentMainCurationViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content.AudioContentMainNewContentViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.new_content_upload_creator.AudioContentMainNewContentCreatorViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.order.AudioContentMainOrderListViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.main.ranking.AudioContentMainRankingViewModel
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.modify.AudioContentModifyViewModel
|
import kr.co.vividnext.sodalive.audio_content.modify.AudioContentModifyViewModel
|
||||||
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
|
import kr.co.vividnext.sodalive.audio_content.order.AudioContentOrderListViewModel
|
||||||
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadViewModel
|
import kr.co.vividnext.sodalive.audio_content.upload.AudioContentUploadViewModel
|
||||||
|
@ -30,12 +25,6 @@ import kr.co.vividnext.sodalive.explorer.ExplorerApi
|
||||||
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
||||||
import kr.co.vividnext.sodalive.explorer.ExplorerViewModel
|
import kr.co.vividnext.sodalive.explorer.ExplorerViewModel
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.UserProfileViewModel
|
import kr.co.vividnext.sodalive.explorer.profile.UserProfileViewModel
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityApi
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllViewModel
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreatorCommunityCommentListViewModel
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.CreatorCommunityModifyViewModel
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteViewModel
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewModel
|
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewModel
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewModel
|
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewModel
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListViewModel
|
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListViewModel
|
||||||
|
@ -54,9 +43,6 @@ import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageViewMo
|
||||||
import kr.co.vividnext.sodalive.live.room.tag.LiveTagRepository
|
import kr.co.vividnext.sodalive.live.room.tag.LiveTagRepository
|
||||||
import kr.co.vividnext.sodalive.live.room.tag.LiveTagViewModel
|
import kr.co.vividnext.sodalive.live.room.tag.LiveTagViewModel
|
||||||
import kr.co.vividnext.sodalive.live.room.update.LiveRoomEditViewModel
|
import kr.co.vividnext.sodalive.live.room.update.LiveRoomEditViewModel
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteRepository
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.config.RouletteApi
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.config.RouletteSettingsViewModel
|
|
||||||
import kr.co.vividnext.sodalive.main.MainViewModel
|
import kr.co.vividnext.sodalive.main.MainViewModel
|
||||||
import kr.co.vividnext.sodalive.message.MessageApi
|
import kr.co.vividnext.sodalive.message.MessageApi
|
||||||
import kr.co.vividnext.sodalive.message.MessageRepository
|
import kr.co.vividnext.sodalive.message.MessageRepository
|
||||||
|
@ -72,7 +58,6 @@ import kr.co.vividnext.sodalive.mypage.auth.AuthRepository
|
||||||
import kr.co.vividnext.sodalive.mypage.can.CanApi
|
import kr.co.vividnext.sodalive.mypage.can.CanApi
|
||||||
import kr.co.vividnext.sodalive.mypage.can.CanRepository
|
import kr.co.vividnext.sodalive.mypage.can.CanRepository
|
||||||
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeViewModel
|
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeViewModel
|
||||||
import kr.co.vividnext.sodalive.mypage.can.coupon.CanCouponViewModel
|
|
||||||
import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentViewModel
|
import kr.co.vividnext.sodalive.mypage.can.payment.CanPaymentViewModel
|
||||||
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusViewModel
|
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusViewModel
|
||||||
import kr.co.vividnext.sodalive.mypage.profile.ProfileUpdateViewModel
|
import kr.co.vividnext.sodalive.mypage.profile.ProfileUpdateViewModel
|
||||||
|
@ -160,8 +145,6 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
single { ApiBuilder().build(get(), AudioContentApi::class.java) }
|
single { ApiBuilder().build(get(), AudioContentApi::class.java) }
|
||||||
single { ApiBuilder().build(get(), FaqApi::class.java) }
|
single { ApiBuilder().build(get(), FaqApi::class.java) }
|
||||||
single { ApiBuilder().build(get(), MemberTagApi::class.java) }
|
single { ApiBuilder().build(get(), MemberTagApi::class.java) }
|
||||||
single { ApiBuilder().build(get(), RouletteApi::class.java) }
|
|
||||||
single { ApiBuilder().build(get(), CreatorCommunityApi::class.java) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModelModule = module {
|
private val viewModelModule = module {
|
||||||
|
@ -170,7 +153,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { TermsViewModel(get()) }
|
viewModel { TermsViewModel(get()) }
|
||||||
viewModel { FindPasswordViewModel(get()) }
|
viewModel { FindPasswordViewModel(get()) }
|
||||||
viewModel { MainViewModel(get(), get(), get(), get()) }
|
viewModel { MainViewModel(get(), get(), get(), get()) }
|
||||||
viewModel { LiveViewModel(get(), get(), get(), get()) }
|
viewModel { LiveViewModel(get(), get(), get()) }
|
||||||
viewModel { MyPageViewModel(get(), get()) }
|
viewModel { MyPageViewModel(get(), get()) }
|
||||||
viewModel { CanStatusViewModel(get()) }
|
viewModel { CanStatusViewModel(get()) }
|
||||||
viewModel { CanChargeViewModel(get()) }
|
viewModel { CanChargeViewModel(get()) }
|
||||||
|
@ -179,7 +162,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { LiveRoomCreateViewModel(get()) }
|
viewModel { LiveRoomCreateViewModel(get()) }
|
||||||
viewModel { LiveTagViewModel(get()) }
|
viewModel { LiveTagViewModel(get()) }
|
||||||
viewModel { LiveRoomEditViewModel(get()) }
|
viewModel { LiveRoomEditViewModel(get()) }
|
||||||
viewModel { LiveRoomViewModel(get(), get(), get(), get()) }
|
viewModel { LiveRoomViewModel(get(), get(), get()) }
|
||||||
viewModel { LiveRoomDonationMessageViewModel(get()) }
|
viewModel { LiveRoomDonationMessageViewModel(get()) }
|
||||||
viewModel { ExplorerViewModel(get()) }
|
viewModel { ExplorerViewModel(get()) }
|
||||||
viewModel { UserProfileViewModel(get(), get(), get()) }
|
viewModel { UserProfileViewModel(get(), get(), get()) }
|
||||||
|
@ -196,12 +179,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { SettingsViewModel(get()) }
|
viewModel { SettingsViewModel(get()) }
|
||||||
viewModel { TextMessageDetailViewModel(get()) }
|
viewModel { TextMessageDetailViewModel(get()) }
|
||||||
viewModel { LiveReservationStatusViewModel(get()) }
|
viewModel { LiveReservationStatusViewModel(get()) }
|
||||||
viewModel { AudioContentMainBannerViewModel(get()) }
|
viewModel { AudioContentMainViewModel(get()) }
|
||||||
viewModel { AudioContentMainRankingViewModel(get()) }
|
|
||||||
viewModel { AudioContentMainCurationViewModel(get()) }
|
|
||||||
viewModel { AudioContentMainOrderListViewModel(get()) }
|
|
||||||
viewModel { AudioContentMainNewContentViewModel(get()) }
|
|
||||||
viewModel { AudioContentMainNewContentCreatorViewModel(get()) }
|
|
||||||
viewModel { AudioContentViewModel(get()) }
|
viewModel { AudioContentViewModel(get()) }
|
||||||
viewModel { AudioContentOrderListViewModel(get()) }
|
viewModel { AudioContentOrderListViewModel(get()) }
|
||||||
viewModel { AudioContentUploadViewModel(get()) }
|
viewModel { AudioContentUploadViewModel(get()) }
|
||||||
|
@ -219,12 +197,6 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
viewModel { AudioContentCurationViewModel(get()) }
|
viewModel { AudioContentCurationViewModel(get()) }
|
||||||
viewModel { AudioContentNewAllViewModel(get()) }
|
viewModel { AudioContentNewAllViewModel(get()) }
|
||||||
viewModel { AudioContentRankingAllViewModel(get()) }
|
viewModel { AudioContentRankingAllViewModel(get()) }
|
||||||
viewModel { RouletteSettingsViewModel(get()) }
|
|
||||||
viewModel { CreatorCommunityAllViewModel(get(), get()) }
|
|
||||||
viewModel { CreatorCommunityCommentListViewModel(get()) }
|
|
||||||
viewModel { CreatorCommunityWriteViewModel(get()) }
|
|
||||||
viewModel { CreatorCommunityModifyViewModel(get()) }
|
|
||||||
viewModel { CanCouponViewModel(get()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repositoryModule = module {
|
private val repositoryModule = module {
|
||||||
|
@ -247,8 +219,6 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
||||||
factory { FaqRepository(get()) }
|
factory { FaqRepository(get()) }
|
||||||
factory { MemberTagRepository(get()) }
|
factory { MemberTagRepository(get()) }
|
||||||
factory { UserProfileFantalkAllViewModel(get(), get()) }
|
factory { UserProfileFantalkAllViewModel(get(), get()) }
|
||||||
factory { RouletteRepository(get()) }
|
|
||||||
factory { CreatorCommunityRepository(get()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val moduleList = listOf(
|
private val moduleList = listOf(
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.dialog
|
|
||||||
|
|
||||||
import android.app.TimePickerDialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.widget.TimePicker
|
|
||||||
|
|
||||||
class SodaLiveTimePickerDialog(
|
|
||||||
context: Context,
|
|
||||||
themeResId: Int,
|
|
||||||
private val onTimeSetListener: OnTimeSetListener,
|
|
||||||
hourOfDay: Int,
|
|
||||||
minute: Int,
|
|
||||||
is24HourView: Boolean
|
|
||||||
) : TimePickerDialog(context, themeResId, null, hourOfDay, minute, is24HourView) {
|
|
||||||
private var timePicker: TimePicker? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.setTitle("Select Time")
|
|
||||||
setOnShowListener {
|
|
||||||
timePicker = window?.findViewById(
|
|
||||||
context.resources.getIdentifier(
|
|
||||||
"android:id/timePicker",
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
timePicker?.apply {
|
|
||||||
setIs24HourView(is24HourView)
|
|
||||||
setOnTimeChangedListener { _, _, minute ->
|
|
||||||
// Snap minute to nearest quarter (0, 15, 30, 45)
|
|
||||||
val snappedMinute = minute / 15 * 15
|
|
||||||
if (snappedMinute != minute) {
|
|
||||||
this.minute = snappedMinute
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getButton(BUTTON_POSITIVE).setOnClickListener {
|
|
||||||
timePicker?.let { picker ->
|
|
||||||
onTimeSetListener.onTimeSet(picker, picker.hour, picker.minute)
|
|
||||||
}
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package kr.co.vividnext.sodalive.explorer.profile
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.orhanobut.logger.Logger
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
|
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||||
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ActivityCreatorNoticeWriteBinding
|
||||||
|
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
class CreatorNoticeWriteActivity : BaseActivity<ActivityCreatorNoticeWriteBinding>(
|
||||||
|
ActivityCreatorNoticeWriteBinding::inflate
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val repository: ExplorerRepository by inject()
|
||||||
|
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
|
override fun setupView() {
|
||||||
|
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||||
|
binding.toolbar.tvBack.text = "공지사항 쓰기"
|
||||||
|
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||||
|
|
||||||
|
val notice = intent.getStringExtra("notice")
|
||||||
|
binding.etContent.setText(notice)
|
||||||
|
|
||||||
|
binding.tvSave.setOnClickListener {
|
||||||
|
loadingDialog.show(screenWidth)
|
||||||
|
|
||||||
|
val writtenNotice = binding.etContent.text.toString()
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.writeCreatorNotice(
|
||||||
|
notice = writtenNotice,
|
||||||
|
token = "Bearer ${SharedPreferenceManager.token}"
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
|
||||||
|
val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||||
|
Toast.makeText(
|
||||||
|
applicationContext,
|
||||||
|
message,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
|
||||||
|
if (it.success) {
|
||||||
|
val dataIntent = Intent()
|
||||||
|
dataIntent.putExtra("notice", writtenNotice)
|
||||||
|
setResult(RESULT_OK, dataIntent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
Toast.makeText(
|
||||||
|
applicationContext,
|
||||||
|
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,20 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile
|
package kr.co.vividnext.sodalive.explorer.profile
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
|
|
||||||
data class GetCreatorProfileResponse(
|
data class GetCreatorProfileResponse(
|
||||||
@SerializedName("creator")
|
@SerializedName("creator")
|
||||||
val creator: CreatorResponse,
|
val creator: CreatorResponse,
|
||||||
@SerializedName("userDonationRanking")
|
@SerializedName("userDonationRanking")
|
||||||
val userDonationRanking: List<UserDonationRankingResponse>,
|
val userDonationRanking: List<UserDonationRankingResponse>,
|
||||||
|
@SerializedName("similarCreatorList")
|
||||||
|
val similarCreatorList: List<SimilarCreatorResponse>,
|
||||||
@SerializedName("liveRoomList")
|
@SerializedName("liveRoomList")
|
||||||
val liveRoomList: List<LiveRoomResponse>,
|
val liveRoomList: List<LiveRoomResponse>,
|
||||||
@SerializedName("contentList")
|
@SerializedName("contentList")
|
||||||
val contentList: List<GetAudioContentListItem>,
|
val contentList: List<GetAudioContentListItem>,
|
||||||
@SerializedName("notice")
|
@SerializedName("notice")
|
||||||
val notice: String,
|
val notice: String,
|
||||||
@SerializedName("communityPostList")
|
|
||||||
val communityPostList: List<GetCommunityPostListResponse>,
|
|
||||||
@SerializedName("cheers")
|
@SerializedName("cheers")
|
||||||
val cheers: GetCheersResponse,
|
val cheers: GetCheersResponse,
|
||||||
@SerializedName("activitySummary")
|
@SerializedName("activitySummary")
|
||||||
|
@ -46,6 +45,13 @@ data class UserDonationRankingResponse(
|
||||||
@SerializedName("donationCan") val donationCan: Int
|
@SerializedName("donationCan") val donationCan: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class SimilarCreatorResponse(
|
||||||
|
@SerializedName("userId") val userId: Long,
|
||||||
|
@SerializedName("nickname") val nickname: String,
|
||||||
|
@SerializedName("profileImage") val profileImage: String,
|
||||||
|
@SerializedName("tags") val tags: List<String>
|
||||||
|
)
|
||||||
|
|
||||||
data class LiveRoomResponse(
|
data class LiveRoomResponse(
|
||||||
@SerializedName("roomId") val roomId: Long,
|
@SerializedName("roomId") val roomId: Long,
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
|
@ -76,8 +82,7 @@ data class GetAudioContentListItem(
|
||||||
@SerializedName("duration") val duration: String?,
|
@SerializedName("duration") val duration: String?,
|
||||||
@SerializedName("likeCount") val likeCount: Int,
|
@SerializedName("likeCount") val likeCount: Int,
|
||||||
@SerializedName("commentCount") val commentCount: Int,
|
@SerializedName("commentCount") val commentCount: Int,
|
||||||
@SerializedName("isAdult") val isAdult: Boolean,
|
@SerializedName("isAdult") val isAdult: Boolean
|
||||||
@SerializedName("isScheduledToOpen") val isScheduledToOpen: Boolean
|
|
||||||
)
|
)
|
||||||
|
|
||||||
data class GetCreatorActivitySummary(
|
data class GetCreatorActivitySummary(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile
|
package kr.co.vividnext.sodalive.explorer.profile
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -10,18 +11,17 @@ import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.webkit.URLUtil
|
import android.webkit.URLUtil
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentActivity
|
import kr.co.vividnext.sodalive.audio_content.AudioContentActivity
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentAdapter
|
import kr.co.vividnext.sodalive.audio_content.AudioContentAdapter
|
||||||
|
@ -33,17 +33,12 @@ import kr.co.vividnext.sodalive.common.Constants
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityUserProfileBinding
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
import kr.co.vividnext.sodalive.explorer.profile.cheers.UserProfileCheersAdapter
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.write.CreatorCommunityWriteActivity
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAdapter
|
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAdapter
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity
|
import kr.co.vividnext.sodalive.explorer.profile.donation.UserProfileDonationAllViewActivity
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity
|
import kr.co.vividnext.sodalive.explorer.profile.fantalk.UserProfileFantalkAllViewActivity
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListActivity
|
import kr.co.vividnext.sodalive.explorer.profile.follow.UserFollowerListActivity
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||||
import kr.co.vividnext.sodalive.live.LiveViewModel
|
import kr.co.vividnext.sodalive.live.LiveViewModel
|
||||||
import kr.co.vividnext.sodalive.live.reservation.complete.LiveReservationCompleteActivity
|
import kr.co.vividnext.sodalive.live.reservation.complete.LiveReservationCompleteActivity
|
||||||
|
@ -55,9 +50,6 @@ import kr.co.vividnext.sodalive.report.ProfileReportDialog
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
import kr.co.vividnext.sodalive.report.UserReportDialog
|
import kr.co.vividnext.sodalive.report.UserReportDialog
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
ActivityUserProfileBinding::inflate
|
ActivityUserProfileBinding::inflate
|
||||||
|
@ -71,8 +63,11 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
private lateinit var liveAdapter: UserProfileLiveAdapter
|
private lateinit var liveAdapter: UserProfileLiveAdapter
|
||||||
private lateinit var audioContentAdapter: AudioContentAdapter
|
private lateinit var audioContentAdapter: AudioContentAdapter
|
||||||
private lateinit var donationAdapter: UserProfileDonationAdapter
|
private lateinit var donationAdapter: UserProfileDonationAdapter
|
||||||
|
private lateinit var similarCreatorAdapter: UserProfileSimilarCreatorAdapter
|
||||||
private lateinit var cheersAdapter: UserProfileCheersAdapter
|
private lateinit var cheersAdapter: UserProfileCheersAdapter
|
||||||
|
|
||||||
|
private lateinit var noticeWriteLauncher: ActivityResultLauncher<Intent>
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private var userId: Long = 0
|
private var userId: Long = 0
|
||||||
|
|
||||||
|
@ -81,6 +76,17 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
imm = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
|
imm = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
noticeWriteLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) {
|
||||||
|
if (it.resultCode == Activity.RESULT_OK) {
|
||||||
|
val writtenNotice = it.data?.getStringExtra("notice")
|
||||||
|
binding.tvNotice.text = writtenNotice?.ifBlank {
|
||||||
|
"공지사항이 없습니다."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (userId <= 0) {
|
if (userId <= 0) {
|
||||||
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
||||||
finish()
|
finish()
|
||||||
|
@ -116,9 +122,9 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
|
|
||||||
setupLiveView()
|
setupLiveView()
|
||||||
setupDonationView()
|
setupDonationView()
|
||||||
|
setupSimilarCreatorView()
|
||||||
setupFanTalkView()
|
setupFanTalkView()
|
||||||
setupAudioContentListView()
|
setupAudioContentListView()
|
||||||
setupCreatorCommunityView()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideKeyboard(onAfterExecute: () -> Unit) {
|
private fun hideKeyboard(onAfterExecute: () -> Unit) {
|
||||||
|
@ -304,6 +310,51 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
recyclerView.adapter = donationAdapter
|
recyclerView.adapter = donationAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupSimilarCreatorView() {
|
||||||
|
val recyclerView = binding.layoutUserProfileSimilarCreator.rvSimilarCreator
|
||||||
|
similarCreatorAdapter = UserProfileSimilarCreatorAdapter {
|
||||||
|
val intent = Intent(applicationContext, UserProfileActivity::class.java)
|
||||||
|
intent.putExtra(Constants.EXTRA_USER_ID, it.userId)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(
|
||||||
|
applicationContext,
|
||||||
|
LinearLayoutManager.VERTICAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
|
when (parent.getChildAdapterPosition(view)) {
|
||||||
|
0 -> {
|
||||||
|
outRect.top = 0
|
||||||
|
outRect.bottom = 10f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
similarCreatorAdapter.itemCount - 1 -> {
|
||||||
|
outRect.top = 10f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
outRect.top = 10f.dpToPx().toInt()
|
||||||
|
outRect.bottom = 10f.dpToPx().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recyclerView.adapter = similarCreatorAdapter
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupFanTalkView() {
|
private fun setupFanTalkView() {
|
||||||
binding.layoutUserProfileFanTalk.tvAll.setOnClickListener {
|
binding.layoutUserProfileFanTalk.tvAll.setOnClickListener {
|
||||||
val intent = Intent(
|
val intent = Intent(
|
||||||
|
@ -477,19 +528,6 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
dialog.show(screenWidth)
|
dialog.show(screenWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCreatorCommunityView() {
|
|
||||||
binding.layoutCreatorCommunityPost.ivWrite.setOnClickListener {
|
|
||||||
startActivity(Intent(applicationContext, CreatorCommunityWriteActivity::class.java))
|
|
||||||
}
|
|
||||||
binding.layoutCreatorCommunityPost.llAll.setOnClickListener {
|
|
||||||
startActivity(
|
|
||||||
Intent(applicationContext, CreatorCommunityAllActivity::class.java).apply {
|
|
||||||
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, userId)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindData() {
|
private fun bindData() {
|
||||||
liveViewModel.toastLiveData.observe(this) {
|
liveViewModel.toastLiveData.observe(this) {
|
||||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||||
|
@ -518,11 +556,20 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
viewModel.creatorProfileLiveData.observe(this) {
|
viewModel.creatorProfileLiveData.observe(this) {
|
||||||
setCheers(it.cheers)
|
setCheers(it.cheers)
|
||||||
setCreatorProfile(it.creator)
|
setCreatorProfile(it.creator)
|
||||||
|
setCreatorNotice(it.notice, it.creator.creatorId)
|
||||||
setAudioContentList(it.contentList)
|
setAudioContentList(it.contentList)
|
||||||
setLiveRoomList(it.liveRoomList)
|
setLiveRoomList(it.liveRoomList)
|
||||||
|
setSimilarCreatorList(it.similarCreatorList)
|
||||||
setUserDonationRanking(it.userDonationRanking)
|
setUserDonationRanking(it.userDonationRanking)
|
||||||
setActivitySummary(it.activitySummary)
|
setActivitySummary(it.activitySummary)
|
||||||
setCommunityPostList(it.communityPostList)
|
}
|
||||||
|
|
||||||
|
viewModel.isExpandNotice.observe(this) {
|
||||||
|
if (it) {
|
||||||
|
binding.tvNotice.maxLines = Int.MAX_VALUE
|
||||||
|
} else {
|
||||||
|
binding.tvNotice.maxLines = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,6 +684,28 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
binding.layoutUserProfileIntroduce.tvIntroduce.text = introduce
|
binding.layoutUserProfileIntroduce.tvIntroduce.text = introduce
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setCreatorNotice(notice: String, creatorId: Long) {
|
||||||
|
binding.tvNotice.text = notice.ifBlank {
|
||||||
|
"공지사항이 없습니다."
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.rlNotice.setOnClickListener {
|
||||||
|
if (creatorId == SharedPreferenceManager.userId) {
|
||||||
|
val intent = Intent(applicationContext, CreatorNoticeWriteActivity::class.java)
|
||||||
|
intent.putExtra("notice", notice)
|
||||||
|
noticeWriteLauncher.launch(intent)
|
||||||
|
} else {
|
||||||
|
viewModel.toggleExpandNotice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivWrite.visibility = if (creatorId == SharedPreferenceManager.userId) {
|
||||||
|
View.VISIBLE
|
||||||
|
} else {
|
||||||
|
View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
private fun setAudioContentList(audioContentList: List<GetAudioContentListItem>) {
|
private fun setAudioContentList(audioContentList: List<GetAudioContentListItem>) {
|
||||||
binding.layoutUserProfileAudioContent.root.visibility =
|
binding.layoutUserProfileAudioContent.root.visibility =
|
||||||
|
@ -679,6 +748,18 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun setSimilarCreatorList(similarCreatorList: List<SimilarCreatorResponse>) {
|
||||||
|
if (similarCreatorList.isEmpty()) {
|
||||||
|
binding.llUserProfileSimilarCreator.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.llUserProfileSimilarCreator.visibility = View.VISIBLE
|
||||||
|
similarCreatorAdapter.items.clear()
|
||||||
|
similarCreatorAdapter.items.addAll(similarCreatorList)
|
||||||
|
similarCreatorAdapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
private fun setUserDonationRanking(userDonationRanking: List<UserDonationRankingResponse>) {
|
private fun setUserDonationRanking(userDonationRanking: List<UserDonationRankingResponse>) {
|
||||||
if (userDonationRanking.isEmpty()) {
|
if (userDonationRanking.isEmpty()) {
|
||||||
|
@ -691,88 +772,6 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setCommunityPostList(communityPostList: List<GetCommunityPostListResponse>) {
|
|
||||||
if (communityPostList.isEmpty()) {
|
|
||||||
if (userId == SharedPreferenceManager.userId) {
|
|
||||||
binding.layoutCreatorCommunityPost.root.visibility = View.VISIBLE
|
|
||||||
binding.layoutCreatorCommunityPost.llNoPost.visibility = View.VISIBLE
|
|
||||||
binding.layoutCreatorCommunityPost.llNoPost.setOnClickListener {
|
|
||||||
startActivity(
|
|
||||||
Intent(
|
|
||||||
applicationContext,
|
|
||||||
CreatorCommunityWriteActivity::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.layoutCreatorCommunityPost.root.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.layoutCreatorCommunityPost.hsvPost.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
binding.layoutCreatorCommunityPost.root.visibility = View.VISIBLE
|
|
||||||
binding.layoutCreatorCommunityPost.llNoPost.visibility = View.GONE
|
|
||||||
binding.layoutCreatorCommunityPost.hsvPost.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
if (userId == SharedPreferenceManager.userId) {
|
|
||||||
binding.layoutCreatorCommunityPost.ivWrite.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
binding.layoutCreatorCommunityPost.ivWrite.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.layoutCreatorCommunityPost.llContainer.removeAllViews()
|
|
||||||
communityPostList.forEachIndexed { index, item ->
|
|
||||||
val layout = ItemCreatorCommunityBinding.inflate(
|
|
||||||
LayoutInflater.from(this@UserProfileActivity),
|
|
||||||
binding.layoutCreatorCommunityPost.llContainer,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
setCommunityPost(layout, item, index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setCommunityPost(
|
|
||||||
layout: ItemCreatorCommunityBinding,
|
|
||||||
item: GetCommunityPostListResponse,
|
|
||||||
index: Int
|
|
||||||
) {
|
|
||||||
layout.ivCreatorProfile.loadUrl(item.creatorProfileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
layout.tvCreatorNickname.text = item.creatorNickname
|
|
||||||
layout.tvDate.text = item.date
|
|
||||||
|
|
||||||
layout.tvContent.text = item.content
|
|
||||||
layout.ivPostImage.loadUrl(item.imageUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
|
||||||
}
|
|
||||||
|
|
||||||
layout.tvLikeCount.text = "${item.likeCount}"
|
|
||||||
layout.tvCommentCount.text = "${item.commentCount}"
|
|
||||||
|
|
||||||
layout.root.setOnClickListener {
|
|
||||||
startActivity(
|
|
||||||
Intent(applicationContext, CreatorCommunityAllActivity::class.java).apply {
|
|
||||||
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, userId)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index > 0) {
|
|
||||||
val lp = layout.root.layoutParams as LinearLayout.LayoutParams
|
|
||||||
lp.marginStart = 13.3f.dpToPx().toInt()
|
|
||||||
layout.root.layoutParams = lp
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.layoutCreatorCommunityPost.llContainer.addView(layout.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun reservationRoom(roomId: Long) {
|
private fun reservationRoom(roomId: Long) {
|
||||||
liveViewModel.getRoomDetail(roomId) {
|
liveViewModel.getRoomDetail(roomId) {
|
||||||
if (it.manager.id == SharedPreferenceManager.userId) {
|
if (it.manager.id == SharedPreferenceManager.userId) {
|
||||||
|
@ -851,15 +850,6 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
liveViewModel.enterRoom(roomId, onEnterRoomSuccess)
|
liveViewModel.enterRoom(roomId, onEnterRoomSuccess)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val beginDateFormat = SimpleDateFormat("yyyy.MM.dd EEE hh:mm a", Locale.ENGLISH)
|
|
||||||
val beginDate = beginDateFormat.parse(it.beginDateTime)!!
|
|
||||||
val now = Date()
|
|
||||||
|
|
||||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd, HH:mm", Locale.getDefault())
|
|
||||||
val diffTime: Long = now.time - beginDate.time
|
|
||||||
val hours = (diffTime / (1000 * 60 * 60)).toInt()
|
|
||||||
val mins = (diffTime / (1000 * 60)).toInt() % 60
|
|
||||||
|
|
||||||
if (it.isPrivateRoom) {
|
if (it.isPrivateRoom) {
|
||||||
LiveRoomPasswordDialog(
|
LiveRoomPasswordDialog(
|
||||||
activity = this,
|
activity = this,
|
||||||
|
@ -877,23 +867,8 @@ class UserProfileActivity : BaseActivity<ActivityUserProfileBinding>(
|
||||||
LivePaymentDialog(
|
LivePaymentDialog(
|
||||||
activity = this,
|
activity = this,
|
||||||
layoutInflater = layoutInflater,
|
layoutInflater = layoutInflater,
|
||||||
title = "유료 라이브 입장",
|
title = "${it.price.moneyFormat()}캔으로 입장",
|
||||||
startDateTime = if (hours >= 1) {
|
desc = "'${it.title}' 라이브에 참여하기 위해 결제합니다.",
|
||||||
dateFormat.format(beginDate)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
nowDateTime = if (hours >= 1) {
|
|
||||||
dateFormat.format(now)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
desc = "${it.price}캔을 차감하고\n라이브에 입장 하시겠습니까?",
|
|
||||||
desc2 = if (hours >= 1) {
|
|
||||||
"라이브를 시작한 지 ${hours}시간 ${mins}분이 지났습니다. 라이브에 입장 후 30분 이내에 라이브가 종료될 수도 있습니다."
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
confirmButtonTitle = "결제 후 입장",
|
confirmButtonTitle = "결제 후 입장",
|
||||||
confirmButtonClick = {
|
confirmButtonClick = {
|
||||||
liveViewModel.enterRoom(roomId, onEnterRoomSuccess)
|
liveViewModel.enterRoom(roomId, onEnterRoomSuccess)
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package kr.co.vividnext.sodalive.explorer.profile
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import coil.load
|
||||||
|
import coil.transform.CircleCropTransformation
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.databinding.ItemUserProfileSimilarCreatorBinding
|
||||||
|
|
||||||
|
class UserProfileSimilarCreatorAdapter(
|
||||||
|
private val onClickItem: (SimilarCreatorResponse) -> Unit
|
||||||
|
) : RecyclerView.Adapter<UserProfileSimilarCreatorAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
val items = mutableListOf<SimilarCreatorResponse>()
|
||||||
|
|
||||||
|
inner class ViewHolder(
|
||||||
|
private val binding: ItemUserProfileSimilarCreatorBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(item: SimilarCreatorResponse) {
|
||||||
|
binding.ivProfile.load(item.profileImage) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
transformations(CircleCropTransformation())
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.tvNickname.text = item.nickname
|
||||||
|
binding.tvTags.text = item.tags.joinToString(" ") { "#$it" }
|
||||||
|
binding.root.setOnClickListener { onClickItem(item) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||||
|
ItemUserProfileSimilarCreatorBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.bind(items[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.count()
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.cheers.PutModifyCheersRequest
|
import kr.co.vividnext.sodalive.explorer.profile.cheers.PutModifyCheersRequest
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
import kr.co.vividnext.sodalive.report.ReportRepository
|
||||||
import kr.co.vividnext.sodalive.report.ReportRequest
|
import kr.co.vividnext.sodalive.report.ReportRequest
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
|
@ -39,6 +38,10 @@ class UserProfileViewModel(
|
||||||
val creatorProfileLiveData: LiveData<GetCreatorProfileResponse>
|
val creatorProfileLiveData: LiveData<GetCreatorProfileResponse>
|
||||||
get() = _creatorProfileLiveData
|
get() = _creatorProfileLiveData
|
||||||
|
|
||||||
|
private val _isExpandNotice = MutableLiveData(false)
|
||||||
|
val isExpandNotice: LiveData<Boolean>
|
||||||
|
get() = _isExpandNotice
|
||||||
|
|
||||||
private var creatorNickname = ""
|
private var creatorNickname = ""
|
||||||
|
|
||||||
fun cheersReport(cheersId: Long, reason: String) {
|
fun cheersReport(cheersId: Long, reason: String) {
|
||||||
|
@ -213,6 +216,10 @@ class UserProfileViewModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toggleExpandNotice() {
|
||||||
|
_isExpandNotice.value = !isExpandNotice.value!!
|
||||||
|
}
|
||||||
|
|
||||||
fun writeCheers(parentCheersId: Long? = null, creatorId: Long, cheersContent: String) {
|
fun writeCheers(parentCheersId: Long? = null, creatorId: Long, cheersContent: String) {
|
||||||
if (cheersContent.isBlank()) {
|
if (cheersContent.isBlank()) {
|
||||||
_toastLiveData.postValue("내용을 입력하세요")
|
_toastLiveData.postValue("내용을 입력하세요")
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
|
|
||||||
class CreatorCommunityAdapter(
|
|
||||||
private val onClickItem: (Long) -> Unit
|
|
||||||
) : RecyclerView.Adapter<CreatorCommunityAdapter.ViewHolder>() {
|
|
||||||
|
|
||||||
val items = mutableListOf<GetCommunityPostListResponse>()
|
|
||||||
|
|
||||||
inner class ViewHolder(
|
|
||||||
private val binding: ItemCreatorCommunityBinding
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
|
||||||
fun bind(item: GetCommunityPostListResponse) {
|
|
||||||
binding.ivCreatorProfile.loadUrl(item.creatorProfileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
binding.tvCreatorNickname.text = item.creatorNickname
|
|
||||||
binding.tvDate.text = item.date
|
|
||||||
|
|
||||||
binding.tvContent.text = item.content
|
|
||||||
binding.ivPostImage.loadUrl(item.imageUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvLikeCount.text = "${item.likeCount}"
|
|
||||||
binding.tvCommentCount.text = "${item.commentCount}"
|
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClickItem(item.creatorId) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
|
||||||
ItemCreatorCommunityBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context),
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun getItemCount() = items.size
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
holder.bind(items[position])
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Single
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
|
||||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import retrofit2.http.Body
|
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.Header
|
|
||||||
import retrofit2.http.Multipart
|
|
||||||
import retrofit2.http.POST
|
|
||||||
import retrofit2.http.PUT
|
|
||||||
import retrofit2.http.Part
|
|
||||||
import retrofit2.http.Path
|
|
||||||
import retrofit2.http.Query
|
|
||||||
|
|
||||||
interface CreatorCommunityApi {
|
|
||||||
@POST("/creator-community")
|
|
||||||
@Multipart
|
|
||||||
fun createCommunityPost(
|
|
||||||
@Part postImage: MultipartBody.Part?,
|
|
||||||
@Part("request") request: RequestBody,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@PUT("/creator-community")
|
|
||||||
@Multipart
|
|
||||||
fun modifyCommunityPost(
|
|
||||||
@Part postImage: MultipartBody.Part?,
|
|
||||||
@Part("request") request: RequestBody,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@GET("/creator-community")
|
|
||||||
fun getCommunityPostList(
|
|
||||||
@Query("creatorId") creatorId: Long,
|
|
||||||
@Query("page") page: Int,
|
|
||||||
@Query("size") size: Int,
|
|
||||||
@Query("timezone") timezone: String,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetCommunityPostListResponse>>>
|
|
||||||
|
|
||||||
@GET("/creator-community/latest")
|
|
||||||
fun getLatestPostListFromCreatorsYouFollow(
|
|
||||||
@Query("timezone") timezone: String,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<List<GetCommunityPostListResponse>>>
|
|
||||||
|
|
||||||
@POST("/creator-community/like")
|
|
||||||
fun communityPostLike(
|
|
||||||
@Body request: PostCommunityPostLikeRequest,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@GET("/creator-community/{id}/comment")
|
|
||||||
fun getCommunityPostCommentList(
|
|
||||||
@Path("id") postId: Long,
|
|
||||||
@Query("page") page: Int,
|
|
||||||
@Query("size") size: Int,
|
|
||||||
@Query("timezone") timezone: String,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<GetCommunityPostCommentListResponse>>
|
|
||||||
|
|
||||||
@POST("/creator-community/comment")
|
|
||||||
fun createCommunityPostComment(
|
|
||||||
@Body request: CreateCommunityPostCommentRequest,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@PUT("/creator-community/comment")
|
|
||||||
fun modifyComment(
|
|
||||||
@Body request: ModifyCommentRequest,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@GET("/creator-community/comment/{id}")
|
|
||||||
fun getCommentReplyList(
|
|
||||||
@Path("id") commentId: Long,
|
|
||||||
@Query("page") page: Int,
|
|
||||||
@Query("size") size: Int,
|
|
||||||
@Query("timezone") timezone: String,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<GetCommunityPostCommentListResponse>>
|
|
||||||
|
|
||||||
@GET("/creator-community/{id}")
|
|
||||||
fun getCommunityPostDetail(
|
|
||||||
@Path("id") postId: Long,
|
|
||||||
@Query("timezone") timezone: String,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<GetCommunityPostListResponse>>
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
|
||||||
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PostCommunityPostLikeRequest
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment.CreateCommunityPostCommentRequest
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import java.util.TimeZone
|
|
||||||
|
|
||||||
class CreatorCommunityRepository(private val api: CreatorCommunityApi) {
|
|
||||||
fun getCommunityPostList(
|
|
||||||
creatorId: Long,
|
|
||||||
page: Int,
|
|
||||||
size: Int,
|
|
||||||
token: String
|
|
||||||
) = api.getCommunityPostList(
|
|
||||||
creatorId = creatorId,
|
|
||||||
page = page - 1,
|
|
||||||
size = size,
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getLatestPostListFromCreatorsYouFollow(
|
|
||||||
token: String
|
|
||||||
) = api.getLatestPostListFromCreatorsYouFollow(
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun communityPostLike(postId: Long, token: String) = api.communityPostLike(
|
|
||||||
request = PostCommunityPostLikeRequest(postId = postId),
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getCommunityPostCommentList(
|
|
||||||
postId: Long,
|
|
||||||
page: Int,
|
|
||||||
size: Int,
|
|
||||||
token: String
|
|
||||||
) = api.getCommunityPostCommentList(
|
|
||||||
postId = postId,
|
|
||||||
page = page,
|
|
||||||
size = size,
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun registerComment(
|
|
||||||
postId: Long,
|
|
||||||
comment: String,
|
|
||||||
parentId: Long? = null,
|
|
||||||
token: String
|
|
||||||
) = api.createCommunityPostComment(
|
|
||||||
request = CreateCommunityPostCommentRequest(
|
|
||||||
comment = comment,
|
|
||||||
postId = postId,
|
|
||||||
parentId = parentId
|
|
||||||
),
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun modifyComment(request: ModifyCommentRequest, token: String) = api.modifyComment(
|
|
||||||
request = request,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getCommentReplyList(commentId: Long, page: Int, size: Int, token: String) = api.getCommentReplyList(
|
|
||||||
commentId = commentId,
|
|
||||||
page = page,
|
|
||||||
size = size,
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun createCommunityPost(
|
|
||||||
postImage: MultipartBody.Part?,
|
|
||||||
request: RequestBody,
|
|
||||||
token: String
|
|
||||||
) = api.createCommunityPost(
|
|
||||||
postImage = postImage,
|
|
||||||
request = request,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun modifyCommunityPost(
|
|
||||||
postImage: MultipartBody.Part?,
|
|
||||||
request: RequestBody,
|
|
||||||
token: String
|
|
||||||
) = api.modifyCommunityPost(
|
|
||||||
postImage = postImage,
|
|
||||||
request = request,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getCommunityPostDetail(postId: Long, token: String) = api.getCommunityPostDetail(
|
|
||||||
postId = postId,
|
|
||||||
timezone = TimeZone.getDefault().id,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
|
|
||||||
data class GetCommunityPostCommentListResponse(
|
|
||||||
@SerializedName("totalCount") val totalCount: Int,
|
|
||||||
@SerializedName("items") val items: List<GetCommunityPostCommentListItem>
|
|
||||||
)
|
|
||||||
|
|
||||||
@Parcelize
|
|
||||||
data class GetCommunityPostCommentListItem(
|
|
||||||
@SerializedName("id") val id: Long,
|
|
||||||
@SerializedName("writerId") val writerId: Long,
|
|
||||||
@SerializedName("nickname") val nickname: String,
|
|
||||||
@SerializedName("profileUrl") val profileUrl: String,
|
|
||||||
@SerializedName("comment") val comment: String,
|
|
||||||
@SerializedName("date") val date: String,
|
|
||||||
@SerializedName("replyCount") val replyCount: Int,
|
|
||||||
) : Parcelable
|
|
|
@ -1,20 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class GetCommunityPostListResponse(
|
|
||||||
@SerializedName("postId") val postId: Long,
|
|
||||||
@SerializedName("creatorId") val creatorId: Long,
|
|
||||||
@SerializedName("creatorNickname") val creatorNickname: String,
|
|
||||||
@SerializedName("creatorProfileUrl") val creatorProfileUrl: String,
|
|
||||||
@SerializedName("imageUrl") val imageUrl: String?,
|
|
||||||
@SerializedName("content") val content: String,
|
|
||||||
@SerializedName("date") val date: String,
|
|
||||||
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean,
|
|
||||||
@SerializedName("isAdult") val isAdult: Boolean,
|
|
||||||
@SerializedName("isLike") var isLike: Boolean,
|
|
||||||
@SerializedName("likeCount") val likeCount: Int,
|
|
||||||
@SerializedName("commentCount") val commentCount: Int,
|
|
||||||
@SerializedName("firstComment") val firstComment: GetCommunityPostCommentListItem?,
|
|
||||||
@SerializedName("isExpand") var isExpand: Boolean = false
|
|
||||||
)
|
|
|
@ -1,195 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
|
||||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
|
||||||
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.modify.CreatorCommunityModifyActivity
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
|
|
||||||
class CreatorCommunityAllActivity : BaseActivity<ActivityCreatorCommunityAllBinding>(
|
|
||||||
ActivityCreatorCommunityAllBinding::inflate
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val viewModel: CreatorCommunityAllViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
private lateinit var adapter: CreatorCommunityAllAdapter
|
|
||||||
|
|
||||||
private var creatorId: Long = 0
|
|
||||||
|
|
||||||
private val modifyResult = registerForActivityResult(
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) { result ->
|
|
||||||
val resultCode = result.resultCode
|
|
||||||
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
viewModel.page = 1
|
|
||||||
viewModel.isLast = false
|
|
||||||
viewModel.getCommunityPostList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
creatorId = intent.getLongExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, 0)
|
|
||||||
if (creatorId <= 0) {
|
|
||||||
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
bindData()
|
|
||||||
viewModel.creatorId = creatorId
|
|
||||||
viewModel.getCommunityPostList()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupView() {
|
|
||||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
|
||||||
binding.toolbar.tvBack.text = "커뮤니티"
|
|
||||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
|
||||||
|
|
||||||
adapter = CreatorCommunityAllAdapter(
|
|
||||||
onClickLike = { viewModel.communityPostLike(it) },
|
|
||||||
writeComment = { postId, parentId, comment ->
|
|
||||||
viewModel.registerComment(
|
|
||||||
comment,
|
|
||||||
postId,
|
|
||||||
parentId
|
|
||||||
)
|
|
||||||
},
|
|
||||||
showCommentBottomSheetDialog = {
|
|
||||||
val dialog = CreatorCommunityCommentFragment(
|
|
||||||
creatorId = creatorId,
|
|
||||||
postId = it
|
|
||||||
)
|
|
||||||
dialog.show(
|
|
||||||
supportFragmentManager,
|
|
||||||
dialog.tag
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClickModify = {
|
|
||||||
modifyResult.launch(
|
|
||||||
Intent(
|
|
||||||
applicationContext,
|
|
||||||
CreatorCommunityModifyActivity::class.java
|
|
||||||
).apply {
|
|
||||||
putExtra(Constants.EXTRA_COMMUNITY_POST_ID, it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClickDelete = { postId ->
|
|
||||||
SodaDialog(
|
|
||||||
activity = this@CreatorCommunityAllActivity,
|
|
||||||
layoutInflater = layoutInflater,
|
|
||||||
title = "게시물 삭제",
|
|
||||||
desc = "삭제하시겠습니까?",
|
|
||||||
confirmButtonTitle = "삭제",
|
|
||||||
confirmButtonClick = {
|
|
||||||
viewModel.deleteCommunityPostList(postId = postId)
|
|
||||||
},
|
|
||||||
cancelButtonTitle = "취소",
|
|
||||||
cancelButtonClick = {}
|
|
||||||
).show(screenWidth)
|
|
||||||
},
|
|
||||||
onClickReport = { postId ->
|
|
||||||
CreatorCommunityReportDialog(this@CreatorCommunityAllActivity, layoutInflater) {
|
|
||||||
viewModel.report(
|
|
||||||
communityPostId = postId,
|
|
||||||
reason = it
|
|
||||||
)
|
|
||||||
}.show(screenWidth)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val recyclerView = binding.rvCreatorCommunity
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(
|
|
||||||
applicationContext,
|
|
||||||
LinearLayoutManager.VERTICAL,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
|
||||||
override fun getItemOffsets(
|
|
||||||
outRect: Rect,
|
|
||||||
view: View,
|
|
||||||
parent: RecyclerView,
|
|
||||||
state: RecyclerView.State
|
|
||||||
) {
|
|
||||||
super.getItemOffsets(outRect, view, parent, state)
|
|
||||||
|
|
||||||
outRect.left = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.right = 6.7f.dpToPx().toInt()
|
|
||||||
|
|
||||||
when (parent.getChildAdapterPosition(view)) {
|
|
||||||
0 -> {
|
|
||||||
outRect.top = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.itemCount - 1 -> {
|
|
||||||
outRect.top = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
outRect.top = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
|
|
||||||
val lastVisiblePosition = (recyclerView.layoutManager as LinearLayoutManager)
|
|
||||||
.findLastVisibleItemPosition()
|
|
||||||
val itemTotalCount = adapter.itemCount - 1
|
|
||||||
|
|
||||||
if (itemTotalCount > 0 && lastVisiblePosition == itemTotalCount) {
|
|
||||||
viewModel.getCommunityPostList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.adapter = adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
private fun bindData() {
|
|
||||||
viewModel.toastLiveData.observe(this) {
|
|
||||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isLoading.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth, "")
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.communityPostListLiveData.observe(this) {
|
|
||||||
if (viewModel.page == 2) {
|
|
||||||
adapter.items.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.items.addAll(it)
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,215 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.text.Spannable
|
|
||||||
import android.text.SpannableString
|
|
||||||
import android.text.method.LinkMovementMethod
|
|
||||||
import android.text.style.ClickableSpan
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCreatorCommunityAllBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
class CreatorCommunityAllAdapter(
|
|
||||||
private val onClickLike: (Long) -> Unit,
|
|
||||||
private val writeComment: (Long, Long?, String) -> Unit,
|
|
||||||
private val showCommentBottomSheetDialog: (Long) -> Unit,
|
|
||||||
private val onClickModify: (Long) -> Unit,
|
|
||||||
private val onClickDelete: (Long) -> Unit,
|
|
||||||
private val onClickReport: (Long) -> Unit
|
|
||||||
) : RecyclerView.Adapter<CreatorCommunityAllAdapter.ViewHolder>() {
|
|
||||||
|
|
||||||
val items = mutableListOf<GetCommunityPostListResponse>()
|
|
||||||
|
|
||||||
inner class ViewHolder(
|
|
||||||
private val context: Context,
|
|
||||||
private val binding: ItemCreatorCommunityAllBinding
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
fun bind(item: GetCommunityPostListResponse, index: Int) {
|
|
||||||
binding.tvDate.text = item.date
|
|
||||||
binding.tvNickname.text = item.creatorNickname
|
|
||||||
binding.ivCreatorProfile.loadUrl(item.creatorProfileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.bg_placeholder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
setNoticeAndClickableUrl(binding.tvContent, item.content)
|
|
||||||
binding.tvContent.setOnClickListener {
|
|
||||||
items[index] = items[index].copy(
|
|
||||||
isExpand = !item.isExpand,
|
|
||||||
)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
binding.tvContent.maxLines = if (item.isExpand) {
|
|
||||||
Int.MAX_VALUE
|
|
||||||
} else {
|
|
||||||
3
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivSeeMore.setOnClickListener {
|
|
||||||
showOptionMenu(
|
|
||||||
context = context,
|
|
||||||
v = binding.ivSeeMore,
|
|
||||||
postId = item.postId,
|
|
||||||
creatorId = item.creatorId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivLike.setImageResource(
|
|
||||||
if (item.isLike) {
|
|
||||||
R.drawable.ic_audio_content_heart_pressed
|
|
||||||
} else {
|
|
||||||
R.drawable.ic_audio_content_heart_normal
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.tvLike.text = "${item.likeCount}"
|
|
||||||
binding.llLike.setOnClickListener {
|
|
||||||
val isLike = !item.isLike
|
|
||||||
|
|
||||||
items[index] = items[index].copy(
|
|
||||||
isLike = !item.isLike,
|
|
||||||
likeCount = if (isLike) item.likeCount + 1 else item.likeCount - 1
|
|
||||||
)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
|
|
||||||
onClickLike(item.postId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.imageUrl != null) {
|
|
||||||
binding.ivContent.visibility = View.VISIBLE
|
|
||||||
binding.ivContent.loadUrl(item.imageUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.bg_placeholder)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.ivContent.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.isCommentAvailable) {
|
|
||||||
binding.llComment.visibility = View.VISIBLE
|
|
||||||
binding.tvCommentCount.text = "${item.commentCount}"
|
|
||||||
} else {
|
|
||||||
binding.llComment.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.commentCount > 0) {
|
|
||||||
binding.ivCommentProfile.load(item.firstComment!!.profileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.bg_placeholder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
binding.tvCommentText.text = item.firstComment.comment
|
|
||||||
binding.tvCommentText.visibility = View.VISIBLE
|
|
||||||
binding.rlInputComment.visibility = View.GONE
|
|
||||||
|
|
||||||
binding.llComment.setOnClickListener { showCommentBottomSheetDialog(item.postId) }
|
|
||||||
} else {
|
|
||||||
binding.tvCommentText.visibility = View.GONE
|
|
||||||
binding.rlInputComment.visibility = View.VISIBLE
|
|
||||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.bg_placeholder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivCommentSend.setOnClickListener {
|
|
||||||
val comment = binding.etComment.text.toString()
|
|
||||||
binding.etComment.setText("")
|
|
||||||
writeComment(item.postId, null, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llComment.setOnClickListener {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setNoticeAndClickableUrl(textView: TextView, text: String) {
|
|
||||||
textView.text = text
|
|
||||||
|
|
||||||
val spannable = SpannableString(text)
|
|
||||||
val pattern = Pattern.compile("https?://\\S+")
|
|
||||||
val matcher = pattern.matcher(spannable)
|
|
||||||
|
|
||||||
while (matcher.find()) {
|
|
||||||
val start = matcher.start()
|
|
||||||
val end = matcher.end()
|
|
||||||
val clickableSpan = object : ClickableSpan() {
|
|
||||||
override fun onClick(widget: View) {
|
|
||||||
val url = spannable.subSequence(start, end).toString()
|
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spannable.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
||||||
}
|
|
||||||
|
|
||||||
textView.text = spannable
|
|
||||||
textView.movementMethod = LinkMovementMethod.getInstance()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
|
||||||
parent.context,
|
|
||||||
ItemCreatorCommunityAllBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context),
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun getItemCount() = items.size
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
holder.bind(items[position], position)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showOptionMenu(
|
|
||||||
context: Context,
|
|
||||||
v: View,
|
|
||||||
postId: Long,
|
|
||||||
creatorId: Long
|
|
||||||
) {
|
|
||||||
val popup = PopupMenu(context, v)
|
|
||||||
val inflater = popup.menuInflater
|
|
||||||
|
|
||||||
if (creatorId == SharedPreferenceManager.userId) {
|
|
||||||
inflater.inflate(R.menu.community_post_creator_option_menu, popup.menu)
|
|
||||||
} else {
|
|
||||||
inflater.inflate(R.menu.community_post_option_menu, popup.menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener {
|
|
||||||
when (it.itemId) {
|
|
||||||
R.id.menu_modify -> {
|
|
||||||
onClickModify(postId)
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.menu_delete -> {
|
|
||||||
onClickDelete(postId)
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.menu_report -> {
|
|
||||||
onClickReport(postId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.show()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,223 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.modify.ModifyCommunityPostRequest
|
|
||||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
|
||||||
import kr.co.vividnext.sodalive.report.ReportRequest
|
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
|
|
||||||
class CreatorCommunityAllViewModel(
|
|
||||||
private val repository: CreatorCommunityRepository,
|
|
||||||
private val reportRepository: ReportRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private var _communityPostListLiveData = MutableLiveData<List<GetCommunityPostListResponse>>()
|
|
||||||
val communityPostListLiveData: LiveData<List<GetCommunityPostListResponse>>
|
|
||||||
get() = _communityPostListLiveData
|
|
||||||
|
|
||||||
var page = 1
|
|
||||||
var isLast = false
|
|
||||||
private val pageSize = 10
|
|
||||||
|
|
||||||
var creatorId = 0L
|
|
||||||
|
|
||||||
fun getCommunityPostList() {
|
|
||||||
if (!_isLoading.value!! && !isLast) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository
|
|
||||||
.getCommunityPostList(
|
|
||||||
creatorId = creatorId,
|
|
||||||
page = page,
|
|
||||||
size = pageSize,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
if (it.data.isNotEmpty()) {
|
|
||||||
page += 1
|
|
||||||
_communityPostListLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
isLast = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteCommunityPostList(postId: Long) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
val request = ModifyCommunityPostRequest(
|
|
||||||
creatorCommunityId = postId,
|
|
||||||
isActive = false
|
|
||||||
)
|
|
||||||
|
|
||||||
val requestJson = Gson().toJson(request)
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.modifyCommunityPost(
|
|
||||||
null,
|
|
||||||
request = requestJson.toRequestBody("text/plain".toMediaType()),
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
if (it.success) {
|
|
||||||
page = 1
|
|
||||||
isLast = false
|
|
||||||
getCommunityPostList()
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun communityPostLike(postId: Long) {
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.communityPostLike(
|
|
||||||
postId = postId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe({}, {})
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun registerComment(comment: String, postId: Long, parentId: Long? = null) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.registerComment(
|
|
||||||
postId = postId,
|
|
||||||
comment = comment,
|
|
||||||
parentId = parentId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
if (it.success) {
|
|
||||||
page = 1
|
|
||||||
isLast = false
|
|
||||||
getCommunityPostList()
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun report(communityPostId: Long, reason: String) {
|
|
||||||
_isLoading.value = true
|
|
||||||
val request = ReportRequest(
|
|
||||||
type = ReportType.COMMUNITY_POST,
|
|
||||||
reason = reason,
|
|
||||||
communityPostId = communityPostId
|
|
||||||
)
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
reportRepository.report(
|
|
||||||
request = request,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"신고가 접수되었습니다."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("신고가 접수되었습니다.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.widget.RadioButton
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import kr.co.vividnext.sodalive.databinding.DialogCommunityPostReportBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
|
|
||||||
class CreatorCommunityReportDialog(
|
|
||||||
activity: Activity,
|
|
||||||
layoutInflater: LayoutInflater,
|
|
||||||
confirmButtonClick: (String) -> Unit
|
|
||||||
) {
|
|
||||||
private val alertDialog: AlertDialog
|
|
||||||
val dialogView = DialogCommunityPostReportBinding.inflate(layoutInflater)
|
|
||||||
var reason = ""
|
|
||||||
|
|
||||||
init {
|
|
||||||
val dialogBuilder = AlertDialog.Builder(activity)
|
|
||||||
dialogBuilder.setView(dialogView.root)
|
|
||||||
|
|
||||||
alertDialog = dialogBuilder.create()
|
|
||||||
alertDialog.setCancelable(false)
|
|
||||||
alertDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
dialogView.tvCancel.setOnClickListener {
|
|
||||||
alertDialog.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvReport.setOnClickListener {
|
|
||||||
if (reason.isNotBlank()) {
|
|
||||||
alertDialog.dismiss()
|
|
||||||
confirmButtonClick(reason)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(activity, "신고 이유를 선택하세요.", Toast.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.radioGroup.setOnCheckedChangeListener { radioGroup, checkedId ->
|
|
||||||
val radioButton = radioGroup.findViewById<RadioButton>(checkedId)
|
|
||||||
reason = radioButton.text.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun show(width: Int) {
|
|
||||||
alertDialog.show()
|
|
||||||
|
|
||||||
val lp = WindowManager.LayoutParams()
|
|
||||||
lp.copyFrom(alertDialog.window?.attributes)
|
|
||||||
lp.width = width - (26.7f.dpToPx()).toInt()
|
|
||||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
|
||||||
|
|
||||||
alertDialog.window?.attributes = lp
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class PostCommunityPostLikeRequest(
|
|
||||||
@SerializedName("postId") val postId: Long
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class CreateCommunityPostCommentRequest(
|
|
||||||
@SerializedName("comment") val comment: String,
|
|
||||||
@SerializedName("postId") val postId: Long,
|
|
||||||
@SerializedName("parentId") val parentId: Long?
|
|
||||||
)
|
|
|
@ -1,128 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
|
||||||
|
|
||||||
class CreatorCommunityCommentAdapter(
|
|
||||||
private val creatorId: Long,
|
|
||||||
private val modifyComment: (Long, String) -> Unit,
|
|
||||||
private val onClickDelete: (Long) -> Unit,
|
|
||||||
private val onItemClick: (GetCommunityPostCommentListItem) -> Unit
|
|
||||||
) : RecyclerView.Adapter<CreatorCommunityCommentAdapter.ViewHolder>() {
|
|
||||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
|
||||||
|
|
||||||
inner class ViewHolder(
|
|
||||||
private val context: Context,
|
|
||||||
private val binding: ItemCommunityPostCommentBinding
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
|
||||||
|
|
||||||
fun bind(item: GetCommunityPostCommentListItem) {
|
|
||||||
binding.ivCommentProfile.load(item.profileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.bg_placeholder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvComment.text = item.comment
|
|
||||||
binding.tvCommentDate.text = item.date
|
|
||||||
binding.tvCommentNickname.text = item.nickname
|
|
||||||
|
|
||||||
binding.tvWriteReply.text = if (item.replyCount > 0) {
|
|
||||||
"답글 ${item.replyCount}개"
|
|
||||||
} else {
|
|
||||||
"답글 쓰기"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
item.writerId == SharedPreferenceManager.userId ||
|
|
||||||
creatorId == SharedPreferenceManager.userId
|
|
||||||
) {
|
|
||||||
binding.etCommentModify.setText(item.comment)
|
|
||||||
binding.ivMenu.visibility = View.VISIBLE
|
|
||||||
binding.ivMenu.setOnClickListener {
|
|
||||||
showOptionMenu(
|
|
||||||
context,
|
|
||||||
binding.ivMenu,
|
|
||||||
commentId = item.id,
|
|
||||||
writerId = item.writerId,
|
|
||||||
creatorId = creatorId,
|
|
||||||
onClickModify = {
|
|
||||||
binding.rlCommentModify.visibility = View.VISIBLE
|
|
||||||
binding.tvComment.visibility = View.GONE
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvModify.setOnClickListener {
|
|
||||||
binding.rlCommentModify.visibility = View.GONE
|
|
||||||
binding.tvComment.visibility = View.VISIBLE
|
|
||||||
modifyComment(item.id, binding.etCommentModify.text.toString())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.ivMenu.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvWriteReply.setOnClickListener { onItemClick(item) }
|
|
||||||
binding.root.setOnClickListener { onItemClick(item) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
|
||||||
parent.context,
|
|
||||||
ItemCommunityPostCommentBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context),
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
holder.bind(items.toList()[position])
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = items.size
|
|
||||||
|
|
||||||
private fun showOptionMenu(
|
|
||||||
context: Context,
|
|
||||||
v: View,
|
|
||||||
commentId: Long,
|
|
||||||
writerId: Long,
|
|
||||||
creatorId: Long,
|
|
||||||
onClickModify: () -> Unit
|
|
||||||
) {
|
|
||||||
val popup = PopupMenu(context, v)
|
|
||||||
val inflater = popup.menuInflater
|
|
||||||
|
|
||||||
if (writerId == SharedPreferenceManager.userId) {
|
|
||||||
inflater.inflate(R.menu.content_comment_option_menu, popup.menu)
|
|
||||||
} else if (creatorId == SharedPreferenceManager.userId) {
|
|
||||||
inflater.inflate(R.menu.content_comment_option_menu2, popup.menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener {
|
|
||||||
when (it.itemId) {
|
|
||||||
R.id.menu_review_modify -> {
|
|
||||||
onClickModify()
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.menu_review_delete -> {
|
|
||||||
onClickDelete(commentId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.show()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.databinding.DialogAudioContentCommentBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
|
||||||
|
|
||||||
class CreatorCommunityCommentFragment(
|
|
||||||
private val creatorId: Long,
|
|
||||||
private val postId: Long
|
|
||||||
) : BottomSheetDialogFragment() {
|
|
||||||
|
|
||||||
private lateinit var binding: DialogAudioContentCommentBinding
|
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
||||||
val dialog = super.onCreateDialog(savedInstanceState)
|
|
||||||
|
|
||||||
dialog.setOnShowListener {
|
|
||||||
val d = it as BottomSheetDialog
|
|
||||||
val bottomSheet = d.findViewById<FrameLayout>(
|
|
||||||
com.google.android.material.R.id.design_bottom_sheet
|
|
||||||
)
|
|
||||||
if (bottomSheet != null) {
|
|
||||||
BottomSheetBehavior.from(bottomSheet).state = BottomSheetBehavior.STATE_EXPANDED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dialog
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
binding = DialogAudioContentCommentBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
val commentListFragmentTag = "COMMENT_LIST_FRAGMENT"
|
|
||||||
val commentListFragment = CreatorCommunityCommentListFragment.newInstance(
|
|
||||||
creatorId = creatorId,
|
|
||||||
postId = postId
|
|
||||||
)
|
|
||||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
|
||||||
fragmentTransaction.add(R.id.fl_container, commentListFragment, commentListFragmentTag)
|
|
||||||
fragmentTransaction.addToBackStack(commentListFragmentTag)
|
|
||||||
fragmentTransaction.commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun hideCommentDialog() {
|
|
||||||
dialog?.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onClickComment(comment: GetCommunityPostCommentListItem) {
|
|
||||||
val commentReplyFragmentTag = "COMMENT_REPLY_FRAGMENT"
|
|
||||||
val commentReplyFragment = CreatorCommunityCommentReplyFragment.newInstance(
|
|
||||||
creatorId = creatorId,
|
|
||||||
postId = postId,
|
|
||||||
comment = comment
|
|
||||||
)
|
|
||||||
val fragmentTransaction = childFragmentManager.beginTransaction()
|
|
||||||
fragmentTransaction.add(R.id.fl_container, commentReplyFragment, commentReplyFragmentTag)
|
|
||||||
fragmentTransaction.addToBackStack(commentReplyFragmentTag)
|
|
||||||
fragmentTransaction.commit()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,214 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Service
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
|
||||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentListBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
|
|
||||||
class CreatorCommunityCommentListFragment : BaseFragment<FragmentAudioContentCommentListBinding>(
|
|
||||||
FragmentAudioContentCommentListBinding::inflate
|
|
||||||
) {
|
|
||||||
private val viewModel: CreatorCommunityCommentListViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var imm: InputMethodManager
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
private lateinit var adapter: CreatorCommunityCommentAdapter
|
|
||||||
|
|
||||||
private var creatorId: Long = 0
|
|
||||||
private var postId: Long = 0
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
creatorId = arguments?.getLong(Constants.EXTRA_COMMUNITY_CREATOR_ID) ?: 0
|
|
||||||
postId = arguments?.getLong(Constants.EXTRA_COMMUNITY_POST_ID) ?: 0
|
|
||||||
return super.onCreateView(inflater, container, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
|
||||||
imm = requireContext().getSystemService(
|
|
||||||
Service.INPUT_METHOD_SERVICE
|
|
||||||
) as InputMethodManager
|
|
||||||
|
|
||||||
setupView()
|
|
||||||
bindData()
|
|
||||||
viewModel.getCommentList(postId) { hideDialog() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hideDialog() {
|
|
||||||
(parentFragment as CreatorCommunityCommentFragment).hideCommentDialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupView() {
|
|
||||||
binding.ivClose.setOnClickListener { hideDialog() }
|
|
||||||
|
|
||||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivCommentSend.setOnClickListener {
|
|
||||||
hideKeyboard()
|
|
||||||
val comment = binding.etComment.text.toString()
|
|
||||||
binding.etComment.setText("")
|
|
||||||
viewModel.registerComment(postId, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter = CreatorCommunityCommentAdapter(
|
|
||||||
creatorId = creatorId,
|
|
||||||
modifyComment = { commentId, comment ->
|
|
||||||
hideKeyboard()
|
|
||||||
viewModel.modifyComment(
|
|
||||||
commentId = commentId,
|
|
||||||
postId = postId,
|
|
||||||
comment = comment
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClickDelete = {
|
|
||||||
SodaDialog(
|
|
||||||
activity = requireActivity(),
|
|
||||||
layoutInflater = layoutInflater,
|
|
||||||
title = "댓글 삭제",
|
|
||||||
desc = "삭제하시겠습니까?",
|
|
||||||
confirmButtonTitle = "삭제",
|
|
||||||
confirmButtonClick = {
|
|
||||||
viewModel.modifyComment(
|
|
||||||
commentId = it,
|
|
||||||
postId = postId,
|
|
||||||
isActive = false
|
|
||||||
)
|
|
||||||
},
|
|
||||||
cancelButtonTitle = "취소",
|
|
||||||
cancelButtonClick = {}
|
|
||||||
).show(screenWidth)
|
|
||||||
},
|
|
||||||
onItemClick = {
|
|
||||||
(parentFragment as CreatorCommunityCommentFragment).onClickComment(it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val recyclerView = binding.rvComment
|
|
||||||
recyclerView.setHasFixedSize(true)
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(
|
|
||||||
activity,
|
|
||||||
LinearLayoutManager.VERTICAL,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
|
||||||
override fun getItemOffsets(
|
|
||||||
outRect: Rect,
|
|
||||||
view: View,
|
|
||||||
parent: RecyclerView,
|
|
||||||
state: RecyclerView.State
|
|
||||||
) {
|
|
||||||
super.getItemOffsets(outRect, view, parent, state)
|
|
||||||
|
|
||||||
outRect.left = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.right = 13.3f.dpToPx().toInt()
|
|
||||||
|
|
||||||
when (parent.getChildAdapterPosition(view)) {
|
|
||||||
0 -> {
|
|
||||||
outRect.top = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.itemCount - 1 -> {
|
|
||||||
outRect.top = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
outRect.top = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 6.7f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
|
|
||||||
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
|
||||||
.findLastCompletelyVisibleItemPosition()
|
|
||||||
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
|
||||||
|
|
||||||
// 스크롤이 끝에 도달했는지 확인
|
|
||||||
if (!recyclerView.canScrollVertically(1) &&
|
|
||||||
lastVisibleItemPosition == itemTotalCount
|
|
||||||
) {
|
|
||||||
viewModel.getCommentList(postId = postId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.adapter = adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
private fun bindData() {
|
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.totalCommentCount.observe(viewLifecycleOwner) {
|
|
||||||
binding.tvCommentCount.text = "$it"
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.commentList.observe(viewLifecycleOwner) {
|
|
||||||
if (viewModel.page - 1 == 1) {
|
|
||||||
adapter.items.clear()
|
|
||||||
binding.rvComment.scrollToPosition(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.items.addAll(it)
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hideKeyboard() {
|
|
||||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun newInstance(creatorId: Long, postId: Long): CreatorCommunityCommentListFragment {
|
|
||||||
val args = Bundle()
|
|
||||||
args.putLong(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
|
|
||||||
args.putLong(Constants.EXTRA_COMMUNITY_POST_ID, postId)
|
|
||||||
|
|
||||||
val fragment = CreatorCommunityCommentListFragment()
|
|
||||||
fragment.arguments = args
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,248 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.audio_content.comment.ModifyCommentRequest
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
|
||||||
|
|
||||||
class CreatorCommunityCommentListViewModel(
|
|
||||||
private val repository: CreatorCommunityRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private var _commentList = MutableLiveData<List<GetCommunityPostCommentListItem>>()
|
|
||||||
val commentList: LiveData<List<GetCommunityPostCommentListItem>>
|
|
||||||
get() = _commentList
|
|
||||||
|
|
||||||
private var _totalCommentCount = MutableLiveData(0)
|
|
||||||
val totalCommentCount: LiveData<Int>
|
|
||||||
get() = _totalCommentCount
|
|
||||||
|
|
||||||
var page = 1
|
|
||||||
private var isLast = false
|
|
||||||
private val size = 10
|
|
||||||
|
|
||||||
fun getCommentList(postId: Long, onFailure: (() -> Unit)? = null) {
|
|
||||||
if (!_isLoading.value!! && !isLast) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getCommunityPostCommentList(
|
|
||||||
postId = postId,
|
|
||||||
page = page - 1,
|
|
||||||
size = size,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_totalCommentCount.postValue(it.data.totalCount)
|
|
||||||
|
|
||||||
page += 1
|
|
||||||
if (it.data.items.isNotEmpty()) {
|
|
||||||
_commentList.postValue(it.data.items)
|
|
||||||
} else {
|
|
||||||
isLast = true
|
|
||||||
_commentList.postValue(listOf())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun registerComment(postId: Long, comment: String, commentId: Long? = null) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.registerComment(
|
|
||||||
postId = postId,
|
|
||||||
comment = comment,
|
|
||||||
parentId = commentId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
if (it.success) {
|
|
||||||
page = 1
|
|
||||||
isLast = false
|
|
||||||
if (commentId != null) {
|
|
||||||
getCommentReplyList(commentId = commentId)
|
|
||||||
} else {
|
|
||||||
getCommentList(postId)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun modifyComment(
|
|
||||||
commentId: Long,
|
|
||||||
postId: Long,
|
|
||||||
parentCommentId: Long? = null,
|
|
||||||
comment: String? = null,
|
|
||||||
isActive: Boolean? = null
|
|
||||||
) {
|
|
||||||
if (comment == null && isActive == null) {
|
|
||||||
_toastLiveData.postValue("변경사항이 없습니다.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comment != null && comment.isBlank()) {
|
|
||||||
_toastLiveData.postValue("내용을 입력하세요")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
val request = ModifyCommentRequest(commentId = commentId)
|
|
||||||
|
|
||||||
if (comment != null) {
|
|
||||||
request.comment = comment
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isActive != null) {
|
|
||||||
request.isActive = isActive
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.modifyComment(
|
|
||||||
request = request,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
if (it.success) {
|
|
||||||
page = 1
|
|
||||||
isLast = false
|
|
||||||
|
|
||||||
if (parentCommentId != null) {
|
|
||||||
getCommentReplyList(parentCommentId)
|
|
||||||
} else {
|
|
||||||
getCommentList(postId)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val message = it.message ?: "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
_toastLiveData.postValue(message)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCommentReplyList(commentId: Long, onFailure: (() -> Unit)? = null) {
|
|
||||||
if (!_isLoading.value!! && !isLast) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getCommentReplyList(
|
|
||||||
commentId = commentId,
|
|
||||||
page = page - 1,
|
|
||||||
size = size,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
page += 1
|
|
||||||
if (it.data.items.isNotEmpty()) {
|
|
||||||
_commentList.postValue(it.data.items)
|
|
||||||
} else {
|
|
||||||
isLast = true
|
|
||||||
_commentList.postValue(listOf())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import androidx.viewbinding.ViewBinding
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentBinding
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemCommunityPostCommentReplyBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
|
|
||||||
class CreatorCommunityCommentReplyAdapter(
|
|
||||||
private val creatorId: Long,
|
|
||||||
private val modifyComment: (Long, String) -> Unit,
|
|
||||||
private val onClickDelete: (Long) -> Unit
|
|
||||||
) : RecyclerView.Adapter<CreatorCommunityCommentReplyViewHolder>() {
|
|
||||||
var items = mutableSetOf<GetCommunityPostCommentListItem>()
|
|
||||||
override fun onCreateViewHolder(
|
|
||||||
parent: ViewGroup,
|
|
||||||
viewType: Int
|
|
||||||
): CreatorCommunityCommentReplyViewHolder {
|
|
||||||
return if (viewType == 0) {
|
|
||||||
CreatorCommunityCommentReplyHeaderViewHolder(
|
|
||||||
binding = ItemCommunityPostCommentBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context),
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
CreatorCommunityCommentReplyItemViewHolder(
|
|
||||||
context = parent.context,
|
|
||||||
creatorId = creatorId,
|
|
||||||
binding = ItemCommunityPostCommentReplyBinding.inflate(
|
|
||||||
LayoutInflater.from(parent.context),
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
showOptionMenu = { context, view, commentId, writerId, creatorId, onClickModify ->
|
|
||||||
showOptionMenu(context, view, commentId, writerId, creatorId, onClickModify)
|
|
||||||
},
|
|
||||||
modifyComment = modifyComment
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: CreatorCommunityCommentReplyViewHolder, position: Int) {
|
|
||||||
holder.bind(items.toList()[position])
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = items.size
|
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
|
||||||
return position
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showOptionMenu(
|
|
||||||
context: Context,
|
|
||||||
v: View,
|
|
||||||
commentId: Long,
|
|
||||||
writerId: Long,
|
|
||||||
creatorId: Long,
|
|
||||||
onClickModify: () -> Unit
|
|
||||||
) {
|
|
||||||
val popup = PopupMenu(context, v)
|
|
||||||
val inflater = popup.menuInflater
|
|
||||||
|
|
||||||
if (writerId == SharedPreferenceManager.userId) {
|
|
||||||
inflater.inflate(R.menu.content_comment_option_menu, popup.menu)
|
|
||||||
} else if (creatorId == SharedPreferenceManager.userId) {
|
|
||||||
inflater.inflate(R.menu.content_comment_option_menu2, popup.menu)
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener {
|
|
||||||
when (it.itemId) {
|
|
||||||
R.id.menu_review_modify -> {
|
|
||||||
onClickModify()
|
|
||||||
}
|
|
||||||
|
|
||||||
R.id.menu_review_delete -> {
|
|
||||||
onClickDelete(commentId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class CreatorCommunityCommentReplyViewHolder(
|
|
||||||
binding: ViewBinding
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
|
||||||
abstract fun bind(item: GetCommunityPostCommentListItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
class CreatorCommunityCommentReplyHeaderViewHolder(
|
|
||||||
private val binding: ItemCommunityPostCommentBinding
|
|
||||||
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
|
||||||
override fun bind(item: GetCommunityPostCommentListItem) {
|
|
||||||
binding.ivCommentProfile.loadUrl(item.profileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvComment.text = item.comment
|
|
||||||
binding.tvCommentDate.text = item.date
|
|
||||||
binding.tvCommentNickname.text = item.nickname
|
|
||||||
|
|
||||||
binding.tvWriteReply.visibility = View.GONE
|
|
||||||
binding.ivMenu.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CreatorCommunityCommentReplyItemViewHolder(
|
|
||||||
private val context: Context,
|
|
||||||
private val creatorId: Long,
|
|
||||||
private val binding: ItemCommunityPostCommentReplyBinding,
|
|
||||||
private val showOptionMenu: (
|
|
||||||
Context, View, Long, Long, Long, onClickModify: () -> Unit
|
|
||||||
) -> Unit,
|
|
||||||
private val modifyComment: (Long, String) -> Unit
|
|
||||||
) : CreatorCommunityCommentReplyViewHolder(binding) {
|
|
||||||
override fun bind(item: GetCommunityPostCommentListItem) {
|
|
||||||
binding.ivCommentProfile.load(item.profileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvComment.text = item.comment
|
|
||||||
binding.tvCommentDate.text = item.date
|
|
||||||
binding.tvCommentNickname.text = item.nickname
|
|
||||||
|
|
||||||
if (
|
|
||||||
item.writerId == SharedPreferenceManager.userId ||
|
|
||||||
creatorId == SharedPreferenceManager.userId
|
|
||||||
) {
|
|
||||||
binding.etCommentModify.setText(item.comment)
|
|
||||||
binding.ivMenu.visibility = View.VISIBLE
|
|
||||||
binding.ivMenu.setOnClickListener {
|
|
||||||
showOptionMenu(
|
|
||||||
context,
|
|
||||||
binding.ivMenu,
|
|
||||||
item.id,
|
|
||||||
item.writerId,
|
|
||||||
creatorId
|
|
||||||
) {
|
|
||||||
binding.rlCommentModify.visibility = View.VISIBLE
|
|
||||||
binding.tvComment.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvModify.setOnClickListener {
|
|
||||||
binding.rlCommentModify.visibility = View.GONE
|
|
||||||
binding.tvComment.visibility = View.VISIBLE
|
|
||||||
modifyComment(item.id, binding.etCommentModify.text.toString())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.ivMenu.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,239 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.all.comment
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Service
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.os.BundleCompat
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.CircleCropTransformation
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
|
||||||
import kr.co.vividnext.sodalive.base.SodaDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentAudioContentCommentReplyBinding
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostCommentListItem
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
|
|
||||||
class CreatorCommunityCommentReplyFragment : BaseFragment<FragmentAudioContentCommentReplyBinding>(
|
|
||||||
FragmentAudioContentCommentReplyBinding::inflate
|
|
||||||
) {
|
|
||||||
private val viewModel: CreatorCommunityCommentListViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var imm: InputMethodManager
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
private lateinit var adapter: CreatorCommunityCommentReplyAdapter
|
|
||||||
|
|
||||||
private var originalComment: GetCommunityPostCommentListItem? = null
|
|
||||||
private var creatorId: Long = 0
|
|
||||||
private var postId: Long = 0
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
creatorId = arguments?.getLong(Constants.EXTRA_COMMUNITY_CREATOR_ID) ?: 0
|
|
||||||
postId = arguments?.getLong(Constants.EXTRA_COMMUNITY_POST_ID) ?: 0
|
|
||||||
originalComment = BundleCompat.getParcelable(
|
|
||||||
requireArguments(),
|
|
||||||
Constants.EXTRA_COMMUNITY_POST_COMMENT,
|
|
||||||
GetCommunityPostCommentListItem::class.java
|
|
||||||
)
|
|
||||||
return super.onCreateView(inflater, container, savedInstanceState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
if (originalComment == null) {
|
|
||||||
parentFragmentManager.popBackStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
|
||||||
imm = requireContext().getSystemService(
|
|
||||||
Service.INPUT_METHOD_SERVICE
|
|
||||||
) as InputMethodManager
|
|
||||||
|
|
||||||
setupView()
|
|
||||||
bindData()
|
|
||||||
viewModel.getCommentReplyList(commentId = originalComment!!.id) {
|
|
||||||
parentFragmentManager.popBackStack()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hideDialog() {
|
|
||||||
(parentFragment as CreatorCommunityCommentFragment).hideCommentDialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupView() {
|
|
||||||
binding.root.setOnClickListener { }
|
|
||||||
|
|
||||||
binding.tvBack.setOnClickListener {
|
|
||||||
parentFragmentManager.popBackStack()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivClose.setOnClickListener { hideDialog() }
|
|
||||||
|
|
||||||
binding.ivCommentProfile.load(SharedPreferenceManager.profileImage) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.ivCommentSend.setOnClickListener {
|
|
||||||
hideKeyboard()
|
|
||||||
val comment = binding.etComment.text.toString()
|
|
||||||
binding.etComment.setText("")
|
|
||||||
viewModel.registerComment(postId, comment, originalComment!!.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter = CreatorCommunityCommentReplyAdapter(
|
|
||||||
creatorId = creatorId,
|
|
||||||
modifyComment = { commentId, comment ->
|
|
||||||
hideKeyboard()
|
|
||||||
viewModel.modifyComment(
|
|
||||||
commentId = commentId,
|
|
||||||
postId = postId,
|
|
||||||
parentCommentId = originalComment!!.id,
|
|
||||||
comment = comment
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onClickDelete = {
|
|
||||||
SodaDialog(
|
|
||||||
activity = requireActivity(),
|
|
||||||
layoutInflater = layoutInflater,
|
|
||||||
title = "댓글 삭제",
|
|
||||||
desc = "삭제하시겠습니까?",
|
|
||||||
confirmButtonTitle = "삭제",
|
|
||||||
confirmButtonClick = {
|
|
||||||
viewModel.modifyComment(
|
|
||||||
commentId = it,
|
|
||||||
postId = postId,
|
|
||||||
parentCommentId = originalComment!!.id,
|
|
||||||
isActive = false
|
|
||||||
)
|
|
||||||
},
|
|
||||||
cancelButtonTitle = "취소",
|
|
||||||
cancelButtonClick = {}
|
|
||||||
).show(screenWidth)
|
|
||||||
},
|
|
||||||
).apply {
|
|
||||||
items.add(originalComment!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
val recyclerView = binding.rvCommentReply
|
|
||||||
recyclerView.setHasFixedSize(true)
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(
|
|
||||||
activity,
|
|
||||||
LinearLayoutManager.VERTICAL,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
|
||||||
override fun getItemOffsets(
|
|
||||||
outRect: Rect,
|
|
||||||
view: View,
|
|
||||||
parent: RecyclerView,
|
|
||||||
state: RecyclerView.State
|
|
||||||
) {
|
|
||||||
super.getItemOffsets(outRect, view, parent, state)
|
|
||||||
|
|
||||||
outRect.left = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.right = 13.3f.dpToPx().toInt()
|
|
||||||
|
|
||||||
when (parent.getChildAdapterPosition(view)) {
|
|
||||||
0 -> {
|
|
||||||
outRect.top = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 12f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.itemCount - 1 -> {
|
|
||||||
outRect.top = 12f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
outRect.top = 12f.dpToPx().toInt()
|
|
||||||
outRect.bottom = 12f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
|
|
||||||
val lastVisibleItemPosition = (recyclerView.layoutManager as LinearLayoutManager?)!!
|
|
||||||
.findLastCompletelyVisibleItemPosition()
|
|
||||||
val itemTotalCount = recyclerView.adapter!!.itemCount - 1
|
|
||||||
|
|
||||||
// 스크롤이 끝에 도달했는지 확인
|
|
||||||
if (!recyclerView.canScrollVertically(1) &&
|
|
||||||
lastVisibleItemPosition == itemTotalCount
|
|
||||||
) {
|
|
||||||
viewModel.getCommentReplyList(originalComment!!.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
recyclerView.adapter = adapter
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
private fun bindData() {
|
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.toastLiveData.observe(viewLifecycleOwner) {
|
|
||||||
it?.let { Toast.makeText(requireContext(), it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.commentList.observe(viewLifecycleOwner) {
|
|
||||||
if (viewModel.page - 1 == 1) {
|
|
||||||
adapter.items.clear()
|
|
||||||
binding.rvCommentReply.scrollToPosition(0)
|
|
||||||
adapter.items.add(originalComment!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.items.addAll(it)
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hideKeyboard() {
|
|
||||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun newInstance(
|
|
||||||
creatorId: Long,
|
|
||||||
postId: Long,
|
|
||||||
comment: GetCommunityPostCommentListItem
|
|
||||||
): CreatorCommunityCommentReplyFragment {
|
|
||||||
val args = Bundle()
|
|
||||||
args.putLong(Constants.EXTRA_COMMUNITY_POST_ID, postId)
|
|
||||||
args.putLong(Constants.EXTRA_COMMUNITY_CREATOR_ID, creatorId)
|
|
||||||
args.putParcelable(Constants.EXTRA_COMMUNITY_POST_COMMENT, comment)
|
|
||||||
|
|
||||||
val fragment = CreatorCommunityCommentReplyFragment()
|
|
||||||
fragment.arguments = args
|
|
||||||
return fragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,282 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.modify
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
|
||||||
import com.gun0912.tedpermission.PermissionListener
|
|
||||||
import com.gun0912.tedpermission.normal.TedPermission
|
|
||||||
import com.jakewharton.rxbinding4.widget.textChanges
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.RealPathUtil
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityModifyBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
|
|
||||||
class CreatorCommunityModifyActivity : BaseActivity<ActivityCreatorCommunityModifyBinding>(
|
|
||||||
ActivityCreatorCommunityModifyBinding::inflate
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val viewModel: CreatorCommunityModifyViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
|
|
||||||
private val imageResult = registerForActivityResult(
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) { result ->
|
|
||||||
val resultCode = result.resultCode
|
|
||||||
val data = result.data
|
|
||||||
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
val fileUri = data?.data
|
|
||||||
|
|
||||||
if (fileUri != null) {
|
|
||||||
binding.ivContent.background = null
|
|
||||||
binding.ivContent.load(fileUri) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(8f.dpToPx()))
|
|
||||||
}
|
|
||||||
viewModel.imageUri = fileUri
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"잘못된 파일입니다.\n다시 선택해 주세요.",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
} else if (resultCode == ImagePicker.RESULT_ERROR) {
|
|
||||||
Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
checkPermissions()
|
|
||||||
|
|
||||||
viewModel.getRealPathFromURI = {
|
|
||||||
RealPathUtil.getRealPath(applicationContext, it)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindData()
|
|
||||||
|
|
||||||
val postId = intent.getLongExtra(Constants.EXTRA_COMMUNITY_POST_ID, 0)
|
|
||||||
if (postId <= 0) {
|
|
||||||
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.postId = postId
|
|
||||||
viewModel.getCommunityPostDetail(
|
|
||||||
onFailure = {
|
|
||||||
Toast.makeText(applicationContext, "잘못된 요청입니다.", Toast.LENGTH_LONG).show()
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupView() {
|
|
||||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
|
||||||
|
|
||||||
binding.toolbar.tvBack.text = "게시글 등록"
|
|
||||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
|
||||||
|
|
||||||
binding.ivPhotoPicker.setOnClickListener {
|
|
||||||
ImagePicker.with(this)
|
|
||||||
.crop()
|
|
||||||
.galleryOnly()
|
|
||||||
.galleryMimeTypes( // Exclude gif images
|
|
||||||
mimeTypes = arrayOf(
|
|
||||||
"image/png",
|
|
||||||
"image/jpg",
|
|
||||||
"image/jpeg"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.createIntent { imageResult.launch(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SharedPreferenceManager.isAuth) {
|
|
||||||
binding.llSetAdult.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
binding.llSetAdult.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llCommentNo.setOnClickListener { viewModel.setAvailableComment(false) }
|
|
||||||
binding.llCommentYes.setOnClickListener { viewModel.setAvailableComment(true) }
|
|
||||||
binding.tvCancel.setOnClickListener { finish() }
|
|
||||||
binding.tvUpload.setOnClickListener {
|
|
||||||
viewModel.modifyCommunityPost {
|
|
||||||
setResult(RESULT_OK)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkPermissions() {
|
|
||||||
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
||||||
listOf(Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_IMAGES)
|
|
||||||
} else {
|
|
||||||
listOf(Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
TedPermission.create()
|
|
||||||
.setPermissionListener(object : PermissionListener {
|
|
||||||
override fun onPermissionGranted() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionDenied(deniedPermissions: MutableList<String>?) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setDeniedMessage(R.string.read_storage_permission_denied_message)
|
|
||||||
.setPermissions(*permissions.toTypedArray())
|
|
||||||
.check()
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun bindData() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
binding.etContent.textChanges().skip(1)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe {
|
|
||||||
binding.tvNumberOfCharacters.text = "${it.length}자"
|
|
||||||
viewModel.content = it.toString()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.toastLiveData.observe(this) {
|
|
||||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isLoading.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.imageUrlLiveData.observe(this) {
|
|
||||||
if (!it.isNullOrBlank()) {
|
|
||||||
binding.ivContent.background = null
|
|
||||||
binding.ivContent.loadUrl(it) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(8f.dpToPx()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.contentLiveData.observe(this) {
|
|
||||||
binding.etContent.setText(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isAvailableCommentLiveData.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
binding.ivCommentYes.visibility = View.VISIBLE
|
|
||||||
binding.tvCommentYes.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentYes.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivCommentNo.visibility = View.GONE
|
|
||||||
binding.tvCommentNo.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentNo.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binding.ivCommentNo.visibility = View.VISIBLE
|
|
||||||
binding.tvCommentNo.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentNo.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivCommentYes.visibility = View.GONE
|
|
||||||
binding.tvCommentYes.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentYes
|
|
||||||
.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SharedPreferenceManager.isAuth) {
|
|
||||||
binding.llAgeAll.setOnClickListener {
|
|
||||||
viewModel.setAdult(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llAge19.setOnClickListener {
|
|
||||||
viewModel.setAdult(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isAdultLiveData.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
binding.ivAgeAll.visibility = View.GONE
|
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
binding.tvAgeAll.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.ivAge19.visibility = View.VISIBLE
|
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
binding.tvAge19.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binding.ivAge19.visibility = View.GONE
|
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
binding.tvAge19.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.ivAgeAll.visibility = View.VISIBLE
|
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
binding.tvAgeAll.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,209 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.modify
|
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import okhttp3.MediaType
|
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import okio.BufferedSink
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class CreatorCommunityModifyViewModel(
|
|
||||||
private val repository: CreatorCommunityRepository
|
|
||||||
) : BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private val _imageUrlLiveData = MutableLiveData<String?>()
|
|
||||||
val imageUrlLiveData: LiveData<String?>
|
|
||||||
get() = _imageUrlLiveData
|
|
||||||
|
|
||||||
private val _contentLiveData = MutableLiveData("")
|
|
||||||
val contentLiveData: LiveData<String>
|
|
||||||
get() = _contentLiveData
|
|
||||||
|
|
||||||
private val _isAdultLiveData = MutableLiveData(false)
|
|
||||||
val isAdultLiveData: LiveData<Boolean>
|
|
||||||
get() = _isAdultLiveData
|
|
||||||
|
|
||||||
private val _isAvailableCommentLiveData = MutableLiveData(true)
|
|
||||||
val isAvailableCommentLiveData: LiveData<Boolean>
|
|
||||||
get() = _isAvailableCommentLiveData
|
|
||||||
|
|
||||||
lateinit var getRealPathFromURI: (Uri) -> String?
|
|
||||||
|
|
||||||
var postId = 0L
|
|
||||||
var content = ""
|
|
||||||
var imageUri: Uri? = null
|
|
||||||
private var communityPost: GetCommunityPostListResponse? = null
|
|
||||||
|
|
||||||
fun setAdult(isAdult: Boolean) {
|
|
||||||
_isAdultLiveData.postValue(isAdult)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setAvailableComment(isAvailableComment: Boolean) {
|
|
||||||
_isAvailableCommentLiveData.postValue(isAvailableComment)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCommunityPostDetail(onFailure: (() -> Unit)? = null) {
|
|
||||||
communityPost = null
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getCommunityPostDetail(
|
|
||||||
postId = postId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
communityPost = it.data
|
|
||||||
_imageUrlLiveData.value = it.data.imageUrl
|
|
||||||
_contentLiveData.value = it.data.content
|
|
||||||
_isAdultLiveData.value = it.data.isAdult
|
|
||||||
_isAvailableCommentLiveData.value = it.data.isCommentAvailable
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
if (onFailure != null) {
|
|
||||||
onFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun modifyCommunityPost(onSuccess: () -> Unit) {
|
|
||||||
if (!_isLoading.value!! && validateData()) {
|
|
||||||
_isLoading.value = true
|
|
||||||
val request = ModifyCommunityPostRequest(
|
|
||||||
creatorCommunityId = postId,
|
|
||||||
content = if (communityPost!!.content != content) {
|
|
||||||
content
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
isCommentAvailable = if (
|
|
||||||
communityPost!!.isCommentAvailable != _isAvailableCommentLiveData.value!!
|
|
||||||
) {
|
|
||||||
_isAvailableCommentLiveData.value!!
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
isAdult = if (communityPost!!.isAdult != _isAdultLiveData.value!!) {
|
|
||||||
_isAdultLiveData.value!!
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val requestJson = Gson().toJson(request)
|
|
||||||
|
|
||||||
val postImage = if (imageUri != null) {
|
|
||||||
val file = File(getRealPathFromURI(imageUri!!))
|
|
||||||
MultipartBody.Part.createFormData(
|
|
||||||
"postImage",
|
|
||||||
file.name,
|
|
||||||
body = object : RequestBody() {
|
|
||||||
override fun contentType(): MediaType {
|
|
||||||
return "image/*".toMediaType()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun writeTo(sink: BufferedSink) {
|
|
||||||
file.inputStream().use { inputStream ->
|
|
||||||
val buffer = ByteArray(1024)
|
|
||||||
var bytesRead: Int
|
|
||||||
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
|
|
||||||
sink.write(buffer, 0, bytesRead)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun contentLength(): Long {
|
|
||||||
return file.length()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.modifyCommunityPost(
|
|
||||||
postImage,
|
|
||||||
request = requestJson.toRequestBody("text/plain".toMediaType()),
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
if (it.success) {
|
|
||||||
onSuccess()
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateData(): Boolean {
|
|
||||||
if (content.isBlank() || content.length < 5) {
|
|
||||||
_toastLiveData.postValue("내용을 5자 이상 입력해 주세요.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.modify
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class ModifyCommunityPostRequest(
|
|
||||||
@SerializedName("creatorCommunityId") val creatorCommunityId: Long,
|
|
||||||
@SerializedName("content") val content: String? = null,
|
|
||||||
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean? = null,
|
|
||||||
@SerializedName("isAdult") val isAdult: Boolean? = null,
|
|
||||||
@SerializedName("isActive") val isActive: Boolean? = null
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.write
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class CreateCommunityPostRequest(
|
|
||||||
@SerializedName("content") val content: String,
|
|
||||||
@SerializedName("isAdult") val isAdult: Boolean,
|
|
||||||
@SerializedName("isCommentAvailable") val isCommentAvailable: Boolean
|
|
||||||
)
|
|
|
@ -1,248 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.write
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import coil.load
|
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
|
||||||
import com.gun0912.tedpermission.PermissionListener
|
|
||||||
import com.gun0912.tedpermission.normal.TedPermission
|
|
||||||
import com.jakewharton.rxbinding4.widget.textChanges
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
|
||||||
import kr.co.vividnext.sodalive.common.RealPathUtil
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityCreatorCommunityWriteBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
|
|
||||||
class CreatorCommunityWriteActivity : BaseActivity<ActivityCreatorCommunityWriteBinding>(
|
|
||||||
ActivityCreatorCommunityWriteBinding::inflate
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val viewModel: CreatorCommunityWriteViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
|
|
||||||
private val imageResult = registerForActivityResult(
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) { result ->
|
|
||||||
val resultCode = result.resultCode
|
|
||||||
val data = result.data
|
|
||||||
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
val fileUri = data?.data
|
|
||||||
|
|
||||||
if (fileUri != null) {
|
|
||||||
binding.ivContent.background = null
|
|
||||||
binding.ivContent.load(fileUri) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(8f.dpToPx()))
|
|
||||||
}
|
|
||||||
viewModel.imageUri = fileUri
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"잘못된 파일입니다.\n다시 선택해 주세요.",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
} else if (resultCode == ImagePicker.RESULT_ERROR) {
|
|
||||||
Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
checkPermissions()
|
|
||||||
|
|
||||||
viewModel.getRealPathFromURI = {
|
|
||||||
RealPathUtil.getRealPath(applicationContext, it)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindData()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupView() {
|
|
||||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
|
||||||
|
|
||||||
binding.toolbar.tvBack.text = "게시글 등록"
|
|
||||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
|
||||||
|
|
||||||
binding.ivPhotoPicker.setOnClickListener {
|
|
||||||
ImagePicker.with(this)
|
|
||||||
.crop()
|
|
||||||
.galleryOnly()
|
|
||||||
.galleryMimeTypes( // Exclude gif images
|
|
||||||
mimeTypes = arrayOf(
|
|
||||||
"image/png",
|
|
||||||
"image/jpg",
|
|
||||||
"image/jpeg"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.createIntent { imageResult.launch(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SharedPreferenceManager.isAuth) {
|
|
||||||
binding.llSetAdult.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
binding.llSetAdult.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llCommentNo.setOnClickListener { viewModel.setAvailableComment(false) }
|
|
||||||
binding.llCommentYes.setOnClickListener { viewModel.setAvailableComment(true) }
|
|
||||||
binding.tvCancel.setOnClickListener { finish() }
|
|
||||||
binding.tvUpload.setOnClickListener {
|
|
||||||
viewModel.createCommunityPost { finish() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkPermissions() {
|
|
||||||
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
||||||
listOf(Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_IMAGES)
|
|
||||||
} else {
|
|
||||||
listOf(Manifest.permission.READ_EXTERNAL_STORAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
TedPermission.create()
|
|
||||||
.setPermissionListener(object : PermissionListener {
|
|
||||||
override fun onPermissionGranted() {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionDenied(deniedPermissions: MutableList<String>?) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setDeniedMessage(R.string.read_storage_permission_denied_message)
|
|
||||||
.setPermissions(*permissions.toTypedArray())
|
|
||||||
.check()
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun bindData() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
binding.etContent.textChanges().skip(1)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe {
|
|
||||||
binding.tvNumberOfCharacters.text = "${it.length}자"
|
|
||||||
viewModel.content = it.toString()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.toastLiveData.observe(this) {
|
|
||||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isLoading.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isAvailableCommentLiveData.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
binding.ivCommentYes.visibility = View.VISIBLE
|
|
||||||
binding.tvCommentYes.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentYes.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivCommentNo.visibility = View.GONE
|
|
||||||
binding.tvCommentNo.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentNo.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binding.ivCommentNo.visibility = View.VISIBLE
|
|
||||||
binding.tvCommentNo.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentNo.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
|
|
||||||
binding.ivCommentYes.visibility = View.GONE
|
|
||||||
binding.tvCommentYes.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.llCommentYes
|
|
||||||
.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SharedPreferenceManager.isAuth) {
|
|
||||||
binding.llAgeAll.setOnClickListener {
|
|
||||||
viewModel.setAdult(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.llAge19.setOnClickListener {
|
|
||||||
viewModel.setAdult(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isAdultLiveData.observe(this) {
|
|
||||||
if (it) {
|
|
||||||
binding.ivAgeAll.visibility = View.GONE
|
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
binding.tvAgeAll.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.ivAge19.visibility = View.VISIBLE
|
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
binding.tvAge19.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
binding.ivAge19.visibility = View.GONE
|
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
|
||||||
binding.tvAge19.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.color_80d8ff
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.ivAgeAll.visibility = View.VISIBLE
|
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
|
||||||
binding.tvAgeAll.setTextColor(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
applicationContext,
|
|
||||||
R.color.white
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,136 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.explorer.profile.creator_community.write
|
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import okhttp3.MediaType
|
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import okio.BufferedSink
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class CreatorCommunityWriteViewModel(private val repository: CreatorCommunityRepository
|
|
||||||
): BaseViewModel() {
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private val _isAdultLiveData = MutableLiveData(false)
|
|
||||||
val isAdultLiveData: LiveData<Boolean>
|
|
||||||
get() = _isAdultLiveData
|
|
||||||
|
|
||||||
private val _isAvailableCommentLiveData = MutableLiveData(true)
|
|
||||||
val isAvailableCommentLiveData: LiveData<Boolean>
|
|
||||||
get() = _isAvailableCommentLiveData
|
|
||||||
|
|
||||||
lateinit var getRealPathFromURI: (Uri) -> String?
|
|
||||||
|
|
||||||
var content = ""
|
|
||||||
var imageUri: Uri? = null
|
|
||||||
|
|
||||||
fun setAdult(isAdult: Boolean) {
|
|
||||||
_isAdultLiveData.postValue(isAdult)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setAvailableComment(isAvailableComment: Boolean) {
|
|
||||||
_isAvailableCommentLiveData.postValue(isAvailableComment)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createCommunityPost(onSuccess: () -> Unit) {
|
|
||||||
if (!_isLoading.value!! && validateData()) {
|
|
||||||
_isLoading.postValue(true)
|
|
||||||
|
|
||||||
val request = CreateCommunityPostRequest(
|
|
||||||
content = content,
|
|
||||||
isAdult = _isAdultLiveData.value!!,
|
|
||||||
isCommentAvailable = _isAvailableCommentLiveData.value!!
|
|
||||||
)
|
|
||||||
|
|
||||||
val requestJson = Gson().toJson(request)
|
|
||||||
|
|
||||||
val postImage = if (imageUri != null) {
|
|
||||||
val file = File(getRealPathFromURI(imageUri!!))
|
|
||||||
MultipartBody.Part.createFormData(
|
|
||||||
"postImage",
|
|
||||||
file.name,
|
|
||||||
body = object : RequestBody() {
|
|
||||||
override fun contentType(): MediaType {
|
|
||||||
return "image/*".toMediaType()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun writeTo(sink: BufferedSink) {
|
|
||||||
file.inputStream().use { inputStream ->
|
|
||||||
val buffer = ByteArray(1024)
|
|
||||||
var bytesRead: Int
|
|
||||||
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
|
|
||||||
sink.write(buffer, 0, bytesRead)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun contentLength(): Long {
|
|
||||||
return file.length()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.createCommunityPost(
|
|
||||||
postImage = postImage,
|
|
||||||
request = requestJson.toRequestBody("text/plain".toMediaType()),
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
onSuccess()
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_isLoading.postValue(false)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.postValue(false)
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateData(): Boolean {
|
|
||||||
if (content.isBlank() || content.length < 5) {
|
|
||||||
_toastLiveData.postValue("내용을 5자 이상 입력해 주세요.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.extensions
|
|
||||||
|
|
||||||
import android.widget.ImageView
|
|
||||||
import coil.load
|
|
||||||
import coil.request.ImageRequest
|
|
||||||
import kr.co.vividnext.sodalive.common.ImageLoaderProvider
|
|
||||||
import kr.co.vividnext.sodalive.common.ImageLoaderProvider.imageLoader
|
|
||||||
|
|
||||||
fun ImageView.loadUrl(url: String?, builder: ImageRequest.Builder.() -> Unit = {}) {
|
|
||||||
if (!ImageLoaderProvider.isInitialized) {
|
|
||||||
throw IllegalStateException("ImageLoaderProvider is not initialized")
|
|
||||||
}
|
|
||||||
this.load(url, imageLoader, builder)
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ data class GetRoomListResponse(
|
||||||
@SerializedName("price") val price: Int,
|
@SerializedName("price") val price: Int,
|
||||||
@SerializedName("tags") val tags: List<String>,
|
@SerializedName("tags") val tags: List<String>,
|
||||||
@SerializedName("channelName") val channelName: String?,
|
@SerializedName("channelName") val channelName: String?,
|
||||||
@SerializedName("creatorProfileImage") val creatorProfileImage: String,
|
|
||||||
@SerializedName("creatorNickname") val creatorNickname: String,
|
@SerializedName("creatorNickname") val creatorNickname: String,
|
||||||
@SerializedName("creatorId") val creatorId: Long,
|
@SerializedName("creatorId") val creatorId: Long,
|
||||||
@SerializedName("isReservation") val isReservation: Boolean,
|
@SerializedName("isReservation") val isReservation: Boolean,
|
||||||
|
|
|
@ -27,8 +27,6 @@ import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentLiveBinding
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityAdapter
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.CreatorCommunityAllActivity
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||||
import kr.co.vividnext.sodalive.following.FollowingCreatorActivity
|
import kr.co.vividnext.sodalive.following.FollowingCreatorActivity
|
||||||
|
@ -51,9 +49,6 @@ import kr.co.vividnext.sodalive.live.room.update.LiveRoomEditActivity
|
||||||
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
|
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
|
||||||
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::inflate) {
|
||||||
|
@ -61,7 +56,6 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||||
|
|
||||||
private lateinit var liveNowAdapter: LiveNowAdapter
|
private lateinit var liveNowAdapter: LiveNowAdapter
|
||||||
private lateinit var liveReservationAdapter: LiveReservationAdapter
|
private lateinit var liveReservationAdapter: LiveReservationAdapter
|
||||||
private lateinit var creatorCommunityAdapter: CreatorCommunityAdapter
|
|
||||||
private lateinit var liveRecommendChannelAdapter: LiveRecommendChannelAdapter
|
private lateinit var liveRecommendChannelAdapter: LiveRecommendChannelAdapter
|
||||||
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
@ -97,7 +91,6 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||||
setupLiveNow()
|
setupLiveNow()
|
||||||
setupLiveReservation()
|
setupLiveReservation()
|
||||||
setupEvent()
|
setupEvent()
|
||||||
setupCommunityPost()
|
|
||||||
|
|
||||||
message = "라이브를 불러오고 있습니다."
|
message = "라이브를 불러오고 있습니다."
|
||||||
viewModel.getSummary()
|
viewModel.getSummary()
|
||||||
|
@ -501,68 +494,6 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
|
||||||
private fun setupCommunityPost() {
|
|
||||||
val recyclerView = binding.rvCommunityPost
|
|
||||||
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(
|
|
||||||
requireContext(),
|
|
||||||
LinearLayoutManager.HORIZONTAL,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
|
||||||
override fun getItemOffsets(
|
|
||||||
outRect: Rect,
|
|
||||||
view: View,
|
|
||||||
parent: RecyclerView,
|
|
||||||
state: RecyclerView.State
|
|
||||||
) {
|
|
||||||
super.getItemOffsets(outRect, view, parent, state)
|
|
||||||
|
|
||||||
when (parent.getChildAdapterPosition(view)) {
|
|
||||||
0 -> {
|
|
||||||
outRect.left = 13.3f.dpToPx().toInt()
|
|
||||||
outRect.right = 5.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
liveNowAdapter.itemCount - 1 -> {
|
|
||||||
outRect.left = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.right = 13.3f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
outRect.left = 6.7f.dpToPx().toInt()
|
|
||||||
outRect.right = 6.7f.dpToPx().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
creatorCommunityAdapter = CreatorCommunityAdapter {
|
|
||||||
startActivity(
|
|
||||||
Intent(
|
|
||||||
requireActivity(),
|
|
||||||
CreatorCommunityAllActivity::class.java
|
|
||||||
).apply {
|
|
||||||
putExtra(Constants.EXTRA_COMMUNITY_CREATOR_ID, it)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
binding.rvCommunityPost.adapter = creatorCommunityAdapter
|
|
||||||
|
|
||||||
viewModel.communityPostItemLiveData.observe(viewLifecycleOwner) {
|
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
binding.rvCommunityPost.visibility = View.VISIBLE
|
|
||||||
creatorCommunityAdapter.items.clear()
|
|
||||||
creatorCommunityAdapter.items.addAll(it)
|
|
||||||
creatorCommunityAdapter.notifyDataSetChanged()
|
|
||||||
} else {
|
|
||||||
binding.rvCommunityPost.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startLive(roomId: Long) {
|
private fun startLive(roomId: Long) {
|
||||||
val onEnterRoomSuccess = {
|
val onEnterRoomSuccess = {
|
||||||
viewModel.getSummary()
|
viewModel.getSummary()
|
||||||
|
@ -698,15 +629,6 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val beginDateFormat = SimpleDateFormat("yyyy.MM.dd EEE hh:mm a", Locale.ENGLISH)
|
|
||||||
val beginDate = beginDateFormat.parse(it.beginDateTime)!!
|
|
||||||
val now = Date()
|
|
||||||
|
|
||||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd, HH:mm", Locale.getDefault())
|
|
||||||
val diffTime: Long = now.time - beginDate.time
|
|
||||||
val hours = (diffTime / (1000 * 60 * 60)).toInt()
|
|
||||||
val mins = (diffTime / (1000 * 60)).toInt() % 60
|
|
||||||
|
|
||||||
if (it.isPrivateRoom) {
|
if (it.isPrivateRoom) {
|
||||||
LiveRoomPasswordDialog(
|
LiveRoomPasswordDialog(
|
||||||
activity = requireActivity(),
|
activity = requireActivity(),
|
||||||
|
@ -726,23 +648,8 @@ class LiveFragment : BaseFragment<FragmentLiveBinding>(FragmentLiveBinding::infl
|
||||||
LivePaymentDialog(
|
LivePaymentDialog(
|
||||||
activity = requireActivity(),
|
activity = requireActivity(),
|
||||||
layoutInflater = layoutInflater,
|
layoutInflater = layoutInflater,
|
||||||
title = "유료 라이브 입장",
|
title = "${it.price.moneyFormat()}캔으로 입장",
|
||||||
startDateTime = if (hours >= 1) {
|
desc = "'${it.title}' 라이브에 참여하기 위해 결제합니다.",
|
||||||
dateFormat.format(beginDate)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
nowDateTime = if (hours >= 1) {
|
|
||||||
dateFormat.format(now)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
desc = "${it.price}캔을 차감하고\n라이브에 입장 하시겠습니까?",
|
|
||||||
desc2 = if (hours >= 1) {
|
|
||||||
"라이브를 시작한 지 ${hours}시간 ${mins}분이 지났습니다. 라이브에 입장 후 30분 이내에 라이브가 종료될 수도 있습니다."
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
confirmButtonTitle = "결제 후 입장",
|
confirmButtonTitle = "결제 후 입장",
|
||||||
confirmButtonClick = {
|
confirmButtonClick = {
|
||||||
handler.postDelayed({
|
handler.postDelayed({
|
||||||
|
|
|
@ -8,8 +8,6 @@ import io.reactivex.rxjava3.core.Flowable
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.CreatorCommunityRepository
|
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.creator_community.GetCommunityPostListResponse
|
|
||||||
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
import kr.co.vividnext.sodalive.live.recommend.GetRecommendLiveResponse
|
||||||
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository
|
||||||
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
import kr.co.vividnext.sodalive.live.recommend_channel.GetRecommendChannelResponse
|
||||||
|
@ -26,8 +24,7 @@ import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||||
class LiveViewModel(
|
class LiveViewModel(
|
||||||
private val repository: LiveRepository,
|
private val repository: LiveRepository,
|
||||||
private val eventRepository: EventRepository,
|
private val eventRepository: EventRepository,
|
||||||
private val liveRecommendRepository: LiveRecommendRepository,
|
private val liveRecommendRepository: LiveRecommendRepository
|
||||||
private val creatorCommunityRepository: CreatorCommunityRepository
|
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
private var _isLoading = MutableLiveData(false)
|
private var _isLoading = MutableLiveData(false)
|
||||||
val isLoading: LiveData<Boolean>
|
val isLoading: LiveData<Boolean>
|
||||||
|
@ -63,10 +60,6 @@ class LiveViewModel(
|
||||||
val eventLiveData: LiveData<List<EventItem>>
|
val eventLiveData: LiveData<List<EventItem>>
|
||||||
get() = _eventLiveData
|
get() = _eventLiveData
|
||||||
|
|
||||||
private val _communityPostItemLiveData = MutableLiveData<List<GetCommunityPostListResponse>>()
|
|
||||||
val communityPostItemLiveData: LiveData<List<GetCommunityPostListResponse>>
|
|
||||||
get() = _communityPostItemLiveData
|
|
||||||
|
|
||||||
var page = 1
|
var page = 1
|
||||||
var isLast = false
|
var isLast = false
|
||||||
private val pageSize = 10
|
private val pageSize = 10
|
||||||
|
@ -142,36 +135,6 @@ class LiveViewModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLatestPostListFromCreatorsYouFollow() {
|
|
||||||
compositeDisposable.add(
|
|
||||||
creatorCommunityRepository.getLatestPostListFromCreatorsYouFollow(
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success && it.data != null) {
|
|
||||||
_communityPostItemLiveData.postValue(it.data!!)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSummary() {
|
fun getSummary() {
|
||||||
if (!_isLoading.value!!) {
|
if (!_isLoading.value!!) {
|
||||||
if (_isFollowedCreatorLive.value!!) {
|
if (_isFollowedCreatorLive.value!!) {
|
||||||
|
@ -179,7 +142,6 @@ class LiveViewModel(
|
||||||
} else {
|
} else {
|
||||||
getRecommendChannelList()
|
getRecommendChannelList()
|
||||||
}
|
}
|
||||||
getLatestPostListFromCreatorsYouFollow()
|
|
||||||
|
|
||||||
val liveNow = repository.roomList(
|
val liveNow = repository.roomList(
|
||||||
status = LiveRoomStatus.NOW,
|
status = LiveRoomStatus.NOW,
|
||||||
|
|
|
@ -5,12 +5,11 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.load
|
||||||
import coil.transform.RoundedCornersTransformation
|
import coil.transform.RoundedCornersTransformation
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemLiveNowBinding
|
import kr.co.vividnext.sodalive.databinding.ItemLiveNowBinding
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
import kr.co.vividnext.sodalive.live.GetRoomListResponse
|
||||||
|
|
||||||
class LiveNowAdapter(
|
class LiveNowAdapter(
|
||||||
|
@ -24,11 +23,13 @@ class LiveNowAdapter(
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: GetRoomListResponse) {
|
fun bind(item: GetRoomListResponse) {
|
||||||
binding.ivCover.loadUrl(item.coverImageUrl) {
|
binding.ivCover.load(item.coverImageUrl) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.ic_place_holder)
|
placeholder(R.drawable.ic_place_holder)
|
||||||
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
transformations(RoundedCornersTransformation(4.7f.dpToPx()))
|
||||||
}
|
}
|
||||||
|
binding.tvManager.text = item.creatorNickname
|
||||||
|
binding.tvNumberOfMembers.text = "${item.numberOfParticipate}"
|
||||||
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||||
View.VISIBLE
|
View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,21 +44,6 @@ class LiveNowAdapter(
|
||||||
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_643bc8)
|
binding.tvPrice.setBackgroundResource(R.drawable.bg_round_corner_10_643bc8)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.tags.isNotEmpty()) {
|
|
||||||
binding.tvTags.visibility = View.VISIBLE
|
|
||||||
binding.tvTags.text = item.tags.joinToString(" ") { "#$it" }
|
|
||||||
} else {
|
|
||||||
binding.tvTags.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvTitle.text = item.title
|
|
||||||
binding.tvNickname.text = item.creatorNickname
|
|
||||||
binding.ivProfile.loadUrl(item.creatorProfileImage) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(CircleCropTransformation())
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.root.setOnClickListener { onClick(item) }
|
binding.root.setOnClickListener { onClick(item) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,6 @@ import kr.co.vividnext.sodalive.live.room.detail.LiveRoomDetailFragment
|
||||||
import kr.co.vividnext.sodalive.live.room.dialog.LivePaymentDialog
|
import kr.co.vividnext.sodalive.live.room.dialog.LivePaymentDialog
|
||||||
import kr.co.vividnext.sodalive.live.room.dialog.LiveRoomPasswordDialog
|
import kr.co.vividnext.sodalive.live.room.dialog.LiveRoomPasswordDialog
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
||||||
ActivityLiveNowAllBinding::inflate
|
ActivityLiveNowAllBinding::inflate
|
||||||
|
@ -160,15 +157,6 @@ class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
||||||
viewModel.enterRoom(roomId, onEnterRoomSuccess)
|
viewModel.enterRoom(roomId, onEnterRoomSuccess)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val beginDateFormat = SimpleDateFormat("yyyy.MM.dd EEE hh:mm a", Locale.ENGLISH)
|
|
||||||
val beginDate = beginDateFormat.parse(it.beginDateTime)!!
|
|
||||||
val now = Date()
|
|
||||||
|
|
||||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd, HH:mm", Locale.getDefault())
|
|
||||||
val diffTime: Long = now.time - beginDate.time
|
|
||||||
val hours = (diffTime / (1000 * 60 * 60)).toInt()
|
|
||||||
val mins = (diffTime / (1000 * 60)).toInt() % 60
|
|
||||||
|
|
||||||
if (it.isPrivateRoom) {
|
if (it.isPrivateRoom) {
|
||||||
LiveRoomPasswordDialog(
|
LiveRoomPasswordDialog(
|
||||||
activity = this,
|
activity = this,
|
||||||
|
@ -186,23 +174,8 @@ class LiveNowAllActivity : BaseActivity<ActivityLiveNowAllBinding>(
|
||||||
LivePaymentDialog(
|
LivePaymentDialog(
|
||||||
activity = this,
|
activity = this,
|
||||||
layoutInflater = layoutInflater,
|
layoutInflater = layoutInflater,
|
||||||
title = "유료 라이브 입장",
|
title = "${it.price.moneyFormat()} 캔으로 입장",
|
||||||
startDateTime = if (hours >= 1) {
|
desc = "'${it.title}' 라이브에 참여하기 위해 결제합니다.",
|
||||||
dateFormat.format(beginDate)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
nowDateTime = if (hours >= 1) {
|
|
||||||
dateFormat.format(now)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
desc = "${it.price.moneyFormat()}캔을 차감하고\n라이브에 입장 하시겠습니까?",
|
|
||||||
desc2 = if (hours >= 1) {
|
|
||||||
"라이브를 시작한 지 ${hours}시간 ${mins}분이 지났습니다. 라이브에 입장 후 30분 이내에 라이브가 종료될 수도 있습니다."
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
confirmButtonTitle = "결제 후 입장",
|
confirmButtonTitle = "결제 후 입장",
|
||||||
confirmButtonClick = {
|
confirmButtonClick = {
|
||||||
viewModel.enterRoom(roomId, onEnterRoomSuccess)
|
viewModel.enterRoom(roomId, onEnterRoomSuccess)
|
||||||
|
|
|
@ -34,6 +34,8 @@ class LiveNowAllAdapter(
|
||||||
}
|
}
|
||||||
binding.tvNickname.text = item.creatorNickname
|
binding.tvNickname.text = item.creatorNickname
|
||||||
binding.tvTitle.text = item.title
|
binding.tvTitle.text = item.title
|
||||||
|
binding.tvTotal.text = "/${item.numberOfPeople}"
|
||||||
|
binding.tvNumberOfParticipants.text = item.numberOfParticipate.toString()
|
||||||
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
binding.ivLock.visibility = if (item.isPrivateRoom) {
|
||||||
View.VISIBLE
|
View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +47,7 @@ class LiveNowAllAdapter(
|
||||||
binding.tvAvailableParticipate.setTextColor(
|
binding.tvAvailableParticipate.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
context,
|
context,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,8 +26,8 @@ import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
|
@ -55,7 +55,6 @@ import kr.co.vividnext.sodalive.common.SodaLiveService
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityLiveRoomBinding
|
import kr.co.vividnext.sodalive.databinding.ActivityLiveRoomBinding
|
||||||
import kr.co.vividnext.sodalive.dialog.LiveDialog
|
import kr.co.vividnext.sodalive.dialog.LiveDialog
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomChatAdapter
|
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomChatAdapter
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomChatRawMessage
|
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomChatRawMessage
|
||||||
|
@ -64,7 +63,6 @@ import kr.co.vividnext.sodalive.live.room.chat.LiveRoomDonationChat
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomDonationStatusChat
|
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomDonationStatusChat
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomJoinChat
|
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomJoinChat
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomNormalChat
|
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomNormalChat
|
||||||
import kr.co.vividnext.sodalive.live.room.chat.LiveRoomRouletteDonationChat
|
|
||||||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationDialog
|
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationDialog
|
||||||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageDialog
|
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageDialog
|
||||||
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageViewModel
|
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageViewModel
|
||||||
|
@ -74,9 +72,6 @@ import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileDialog
|
||||||
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileListAdapter
|
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomProfileListAdapter
|
||||||
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomUserProfileDialog
|
import kr.co.vividnext.sodalive.live.room.profile.LiveRoomUserProfileDialog
|
||||||
import kr.co.vividnext.sodalive.live.room.update.LiveRoomInfoEditDialog
|
import kr.co.vividnext.sodalive.live.room.update.LiveRoomInfoEditDialog
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewDialog
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteSpinDialog
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.config.RouletteConfigActivity
|
|
||||||
import kr.co.vividnext.sodalive.report.ProfileReportDialog
|
import kr.co.vividnext.sodalive.report.ProfileReportDialog
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
import kr.co.vividnext.sodalive.report.UserReportDialog
|
import kr.co.vividnext.sodalive.report.UserReportDialog
|
||||||
|
@ -111,6 +106,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
private var isSpeakerMute = false
|
private var isSpeakerMute = false
|
||||||
private var isMicrophoneMute = false
|
private var isMicrophoneMute = false
|
||||||
private var isSpeaker = false
|
private var isSpeaker = false
|
||||||
|
private var isSpeakerFold = false
|
||||||
|
|
||||||
private var isNoChatting = false
|
private var isNoChatting = false
|
||||||
private var remainingNoChattingTime = noChattingTime
|
private var remainingNoChattingTime = noChattingTime
|
||||||
|
@ -183,27 +179,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rouletteConfigResult = registerForActivityResult(
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) { result ->
|
|
||||||
val resultCode = result.resultCode
|
|
||||||
val isActiveRoulette = result.data?.getBooleanExtra(Constants.EXTRA_RESULT_ROULETTE, false)
|
|
||||||
|
|
||||||
if (resultCode == RESULT_OK && isActiveRoulette != null) {
|
|
||||||
agora.sendRawMessageToGroup(
|
|
||||||
rawMessage = Gson().toJson(
|
|
||||||
LiveRoomChatRawMessage(
|
|
||||||
type = LiveRoomChatRawMessageType.TOGGLE_ROULETTE,
|
|
||||||
message = "",
|
|
||||||
can = 0,
|
|
||||||
donationMessage = "",
|
|
||||||
isActiveRoulette = isActiveRoulette
|
|
||||||
)
|
|
||||||
).toByteArray()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
agora = Agora(
|
agora = Agora(
|
||||||
context = this,
|
context = this,
|
||||||
|
@ -353,6 +328,8 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
isStaff = {
|
isStaff = {
|
||||||
viewModel.isEqualToManagerId(it.toInt())
|
viewModel.isEqualToManagerId(it.toInt())
|
||||||
},
|
},
|
||||||
|
onClickSendMessage = { userId, nickname ->
|
||||||
|
},
|
||||||
onClickSetManager = {
|
onClickSetManager = {
|
||||||
setManagerMessageToPeer(userId = it)
|
setManagerMessageToPeer(userId = it)
|
||||||
viewModel.setManager(roomId = roomId, userId = it) {
|
viewModel.setManager(roomId = roomId, userId = it) {
|
||||||
|
@ -453,7 +430,33 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
|
|
||||||
dialog.show(screenWidth)
|
dialog.show(screenWidth)
|
||||||
}
|
}
|
||||||
binding.tvNotification.setOnClickListener { viewModel.toggleShowNotice() }
|
binding.ivNotification.setOnClickListener { viewModel.toggleShowNotice() }
|
||||||
|
binding.rlNotice.setOnClickListener { viewModel.toggleExpandNotice() }
|
||||||
|
binding.tvSpeakerFold.setOnClickListener {
|
||||||
|
isSpeakerFold = !isSpeakerFold
|
||||||
|
|
||||||
|
if (isSpeakerFold) {
|
||||||
|
binding.rlSpeaker.visibility = View.VISIBLE
|
||||||
|
binding.rvSpeakers.visibility = View.VISIBLE
|
||||||
|
binding.tvSpeakerFold.text = "접기"
|
||||||
|
binding.tvSpeakerFold.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
R.drawable.ic_live_detail_top,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
binding.rlSpeaker.visibility = View.GONE
|
||||||
|
binding.rvSpeakers.visibility = View.GONE
|
||||||
|
binding.tvSpeakerFold.text = "펼치기"
|
||||||
|
binding.tvSpeakerFold.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
R.drawable.ic_live_detail_bottom,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.tvBgSwitch.setOnClickListener { viewModel.toggleBackgroundImage() }
|
binding.tvBgSwitch.setOnClickListener { viewModel.toggleBackgroundImage() }
|
||||||
binding.llDonation.setOnClickListener {
|
binding.llDonation.setOnClickListener {
|
||||||
|
@ -548,9 +551,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
dialog.setPositiveButton("차단") { _, _ ->
|
dialog.setPositiveButton("차단") { _, _ ->
|
||||||
roomUserProfileDialog.dismiss()
|
roomUserProfileDialog.dismiss()
|
||||||
viewModel.memberBlock(userId) {
|
viewModel.memberBlock(userId) {
|
||||||
if (viewModel.roomInfoResponse.creatorId == SharedPreferenceManager.userId) {
|
kickOut(userId)
|
||||||
kickOut(userId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dialog.setNegativeButton("취소") { _, _ -> }
|
dialog.setNegativeButton("취소") { _, _ -> }
|
||||||
|
@ -595,11 +596,11 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
binding.tvBgSwitch.setTextColor(
|
binding.tvBgSwitch.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.tvBgSwitch
|
binding.tvBgSwitch
|
||||||
.setBackgroundResource(R.drawable.bg_round_corner_5_3_transparent_3bb9f1)
|
.setBackgroundResource(R.drawable.bg_round_corner_13_3_transparent_9970ff)
|
||||||
} else {
|
} else {
|
||||||
binding.ivCover.visibility = View.GONE
|
binding.ivCover.visibility = View.GONE
|
||||||
binding.tvBgSwitch.text = "배경 OFF"
|
binding.tvBgSwitch.text = "배경 OFF"
|
||||||
|
@ -610,7 +611,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
binding.tvBgSwitch
|
binding.tvBgSwitch
|
||||||
.setBackgroundResource(R.drawable.bg_round_corner_5_3_transparent_bbbbbb)
|
.setBackgroundResource(R.drawable.bg_round_corner_13_3_transparent_bbbbbb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,6 +647,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvTitle.text = response.title
|
binding.tvTitle.text = response.title
|
||||||
|
binding.ivCover.load(response.coverImageUrl) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
}
|
||||||
|
|
||||||
binding.flDonation.visibility =
|
binding.flDonation.visibility =
|
||||||
if (response.creatorId != SharedPreferenceManager.userId) {
|
if (response.creatorId != SharedPreferenceManager.userId) {
|
||||||
|
@ -688,11 +693,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
}
|
}
|
||||||
|
|
||||||
speakerListAdapter.managerId = response.creatorId
|
speakerListAdapter.managerId = response.creatorId
|
||||||
speakerListAdapter.updateList(
|
speakerListAdapter.updateList(response.speakerList)
|
||||||
response.speakerList.filter {
|
|
||||||
it.id != response.creatorId
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (response.creatorId == SharedPreferenceManager.userId) {
|
if (response.creatorId == SharedPreferenceManager.userId) {
|
||||||
binding.ivEdit.setOnClickListener {
|
binding.ivEdit.setOnClickListener {
|
||||||
|
@ -709,7 +710,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
setNoticeAndClickableUrl(binding.tvNotice, newContent)
|
setNoticeAndClickableUrl(binding.tvNotice, newContent)
|
||||||
|
|
||||||
if (newCoverImageUri != null) {
|
if (newCoverImageUri != null) {
|
||||||
binding.ivCover.load(newCoverImageUri)
|
binding.ivCover.load(newCoverImageUri) {
|
||||||
|
crossfade(true)
|
||||||
|
placeholder(R.drawable.ic_place_holder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
agora.sendRawMessageToGroup(
|
agora.sendRawMessageToGroup(
|
||||||
|
@ -766,7 +770,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
setNoticeAndClickableUrl(binding.tvNotice, response.notice)
|
setNoticeAndClickableUrl(binding.tvNotice, response.notice)
|
||||||
|
|
||||||
binding.tvCreatorNickname.text = response.creatorNickname
|
binding.tvCreatorNickname.text = response.creatorNickname
|
||||||
binding.ivCreatorProfile.loadUrl(response.creatorProfileUrl) {
|
binding.ivCreatorProfile.load(response.creatorProfileUrl) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.ic_place_holder)
|
placeholder(R.drawable.ic_place_holder)
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
|
@ -781,7 +785,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
if (response.creatorId != SharedPreferenceManager.userId) {
|
if (response.creatorId != SharedPreferenceManager.userId) {
|
||||||
binding.ivCreatorFollow.visibility = View.VISIBLE
|
binding.ivCreatorFollow.visibility = View.VISIBLE
|
||||||
if (response.isFollowing) {
|
if (response.isFollowing) {
|
||||||
binding.ivCreatorFollow.setImageResource(R.drawable.btn_select_checked)
|
binding.ivCreatorFollow.setImageResource(R.drawable.btn_following)
|
||||||
binding.ivCreatorFollow.setOnClickListener {
|
binding.ivCreatorFollow.setOnClickListener {
|
||||||
viewModel.creatorUnFollow(
|
viewModel.creatorUnFollow(
|
||||||
creatorId = response.creatorId,
|
creatorId = response.creatorId,
|
||||||
|
@ -789,7 +793,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.ivCreatorFollow.setImageResource(R.drawable.btn_plus_round)
|
binding.ivCreatorFollow.setImageResource(R.drawable.btn_follow)
|
||||||
binding.ivCreatorFollow.setOnClickListener {
|
binding.ivCreatorFollow.setOnClickListener {
|
||||||
viewModel.creatorFollow(
|
viewModel.creatorFollow(
|
||||||
creatorId = response.creatorId,
|
creatorId = response.creatorId,
|
||||||
|
@ -801,12 +805,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
binding.ivCreatorFollow.visibility = View.GONE
|
binding.ivCreatorFollow.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
initRouletteSettingButton(isHost = response.creatorId == SharedPreferenceManager.userId)
|
|
||||||
activatingRouletteButton(
|
|
||||||
isHost = response.creatorId == SharedPreferenceManager.userId,
|
|
||||||
isActiveRoulette = response.isActiveRoulette
|
|
||||||
)
|
|
||||||
|
|
||||||
if (agora.rtmChannelIsNull()) {
|
if (agora.rtmChannelIsNull()) {
|
||||||
joinChannel(response)
|
joinChannel(response)
|
||||||
}
|
}
|
||||||
|
@ -814,74 +812,25 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
|
|
||||||
viewModel.isShowNotice.observe(this) {
|
viewModel.isShowNotice.observe(this) {
|
||||||
if (it) {
|
if (it) {
|
||||||
binding.tvNotification.setTextColor(
|
binding.ivNotification.setImageResource(R.drawable.ic_notice_selected)
|
||||||
ContextCompat.getColor(
|
binding.rlNotice.visibility = View.VISIBLE
|
||||||
applicationContext,
|
|
||||||
R.color.color_3bb9f1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.tvNotification.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_5_3_transparent_3bb9f1
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.llNotice.visibility = View.VISIBLE
|
|
||||||
} else {
|
} else {
|
||||||
binding.tvNotification.setTextColor(
|
binding.ivNotification.setImageResource(R.drawable.ic_notice_normal)
|
||||||
ContextCompat.getColor(
|
binding.rlNotice.visibility = View.GONE
|
||||||
applicationContext,
|
}
|
||||||
R.color.color_bbbbbb
|
}
|
||||||
)
|
|
||||||
)
|
|
||||||
binding.tvNotification.setBackgroundResource(
|
|
||||||
R.drawable.bg_round_corner_5_3_transparent_bbbbbb
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.llNotice.visibility = View.GONE
|
viewModel.isExpandNotice.observe(this) {
|
||||||
|
binding.tvNotice.maxLines = if (it) {
|
||||||
|
Int.MAX_VALUE
|
||||||
|
} else {
|
||||||
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.totalDonationCan.observe(this) {
|
viewModel.totalDonationCan.observe(this) {
|
||||||
binding.tvTotalCan.text = it.moneyFormat()
|
binding.tvTotalCan.text = it.moneyFormat()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.coverImageUrlLiveData.observe(this) {
|
|
||||||
binding.ivCover.loadUrl(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initRouletteSettingButton(isHost: Boolean) {
|
|
||||||
if (isHost) {
|
|
||||||
binding.flRouletteSettings.visibility = View.VISIBLE
|
|
||||||
binding.flRouletteSettings.setOnClickListener {
|
|
||||||
rouletteConfigResult.launch(
|
|
||||||
Intent(
|
|
||||||
applicationContext,
|
|
||||||
RouletteConfigActivity::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.flRouletteSettings.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun activatingRouletteButton(isHost: Boolean, isActiveRoulette: Boolean) {
|
|
||||||
if (!isHost && isActiveRoulette) {
|
|
||||||
binding.flRoulette.visibility = View.VISIBLE
|
|
||||||
binding.flRoulette.setOnClickListener {
|
|
||||||
viewModel.showRoulette {
|
|
||||||
RoulettePreviewDialog(
|
|
||||||
activity = this,
|
|
||||||
preview = it,
|
|
||||||
onClickSpin = { spinRoulette() },
|
|
||||||
layoutInflater = layoutInflater
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
binding.flRoulette.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setNoticeAndClickableUrl(textView: TextView, text: String) {
|
private fun setNoticeAndClickableUrl(textView: TextView, text: String) {
|
||||||
|
@ -988,11 +937,7 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
val rvSpeakers = binding.rvSpeakers
|
val rvSpeakers = binding.rvSpeakers
|
||||||
speakerListAdapter = LiveRoomProfileListAdapter()
|
speakerListAdapter = LiveRoomProfileListAdapter()
|
||||||
|
|
||||||
rvSpeakers.layoutManager = LinearLayoutManager(
|
rvSpeakers.layoutManager = GridLayoutManager(applicationContext, 5)
|
||||||
applicationContext,
|
|
||||||
LinearLayoutManager.HORIZONTAL,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
rvSpeakers.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
rvSpeakers.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
override fun getItemOffsets(
|
override fun getItemOffsets(
|
||||||
outRect: Rect,
|
outRect: Rect,
|
||||||
|
@ -1002,8 +947,8 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
) {
|
) {
|
||||||
super.getItemOffsets(outRect, view, parent, state)
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
outRect.left = 4f.dpToPx().toInt()
|
outRect.top = 5f.dpToPx().toInt()
|
||||||
outRect.right = 4f.dpToPx().toInt()
|
outRect.bottom = 5f.dpToPx().toInt()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
rvSpeakers.adapter = speakerListAdapter
|
rvSpeakers.adapter = speakerListAdapter
|
||||||
|
@ -1145,14 +1090,10 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
isMicrophoneMute = !isMicrophoneMute
|
isMicrophoneMute = !isMicrophoneMute
|
||||||
agora.muteLocalAudioStream(isMicrophoneMute)
|
agora.muteLocalAudioStream(isMicrophoneMute)
|
||||||
|
|
||||||
if (SharedPreferenceManager.userId == viewModel.roomInfoResponse.creatorId) {
|
if (isMicrophoneMute) {
|
||||||
setMuteSpeakerCreator(isMicrophoneMute)
|
speakerListAdapter.muteSpeakers.add(SharedPreferenceManager.userId.toInt())
|
||||||
} else {
|
} else {
|
||||||
if (isMicrophoneMute) {
|
speakerListAdapter.muteSpeakers.remove(SharedPreferenceManager.userId.toInt())
|
||||||
speakerListAdapter.muteSpeakers.add(SharedPreferenceManager.userId.toInt())
|
|
||||||
} else {
|
|
||||||
speakerListAdapter.muteSpeakers.remove(SharedPreferenceManager.userId.toInt())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,46 +1190,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun spinRoulette() {
|
|
||||||
viewModel.spinRoulette(roomId = roomId) { can, items, randomlySelectedItem ->
|
|
||||||
val rouletteRawMessage = Gson().toJson(
|
|
||||||
LiveRoomChatRawMessage(
|
|
||||||
type = LiveRoomChatRawMessageType.ROULETTE_DONATION,
|
|
||||||
message = randomlySelectedItem,
|
|
||||||
can = can,
|
|
||||||
donationMessage = "",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
RouletteSpinDialog(
|
|
||||||
activity = this@LiveRoomActivity,
|
|
||||||
items = items,
|
|
||||||
selectedItem = randomlySelectedItem,
|
|
||||||
layoutInflater = layoutInflater
|
|
||||||
) {
|
|
||||||
agora.sendRawMessageToGroup(
|
|
||||||
rawMessage = rouletteRawMessage.toByteArray(),
|
|
||||||
onSuccess = {
|
|
||||||
handler.post {
|
|
||||||
chatAdapter.items.add(
|
|
||||||
LiveRoomRouletteDonationChat(
|
|
||||||
profileUrl = SharedPreferenceManager.profileImage,
|
|
||||||
nickname = SharedPreferenceManager.nickname,
|
|
||||||
rouletteResult = randomlySelectedItem
|
|
||||||
)
|
|
||||||
)
|
|
||||||
invalidateChat()
|
|
||||||
viewModel.addDonationCan(can)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onFailure = {
|
|
||||||
viewModel.refundRouletteDonation(roomId)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun joinChannel(roomInfo: GetRoomInfoResponse) {
|
private fun joinChannel(roomInfo: GetRoomInfoResponse) {
|
||||||
loadingDialog.show(width = screenWidth, message = "라이브에 입장하고 있습니다.")
|
loadingDialog.show(width = screenWidth, message = "라이브에 입장하고 있습니다.")
|
||||||
|
|
||||||
|
@ -1360,31 +1261,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
invalidateChat()
|
invalidateChat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveRoomChatRawMessageType.TOGGLE_ROULETTE -> {
|
|
||||||
handler.post {
|
|
||||||
activatingRouletteButton(
|
|
||||||
isHost = viewModel
|
|
||||||
.roomInfoResponse
|
|
||||||
.creatorId == SharedPreferenceManager.userId,
|
|
||||||
isActiveRoulette = rawMessage.isActiveRoulette ?: false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LiveRoomChatRawMessageType.ROULETTE_DONATION -> {
|
|
||||||
handler.post {
|
|
||||||
chatAdapter.items.add(
|
|
||||||
LiveRoomRouletteDonationChat(
|
|
||||||
profileUrl = profileUrl,
|
|
||||||
nickname = nickname,
|
|
||||||
rouletteResult = rawMessage.message
|
|
||||||
)
|
|
||||||
)
|
|
||||||
invalidateChat()
|
|
||||||
viewModel.addDonationCan(rawMessage.can)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val chat = message.text
|
val chat = message.text
|
||||||
|
@ -1462,14 +1338,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setMuteSpeakerCreator(isMute: Boolean) {
|
|
||||||
binding.ivMute.visibility = if (isMute) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val rtcEventHandler = object : IRtcEngineEventHandler() {
|
private val rtcEventHandler = object : IRtcEngineEventHandler() {
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
override fun onAudioVolumeIndication(
|
override fun onAudioVolumeIndication(
|
||||||
|
@ -1477,9 +1345,6 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
totalVolume: Int
|
totalVolume: Int
|
||||||
) {
|
) {
|
||||||
super.onAudioVolumeIndication(speakers, totalVolume)
|
super.onAudioVolumeIndication(speakers, totalVolume)
|
||||||
|
|
||||||
Logger.e("onAudioVolumeIndication - $speakers")
|
|
||||||
|
|
||||||
val activeSpeakerIds = speakers
|
val activeSpeakerIds = speakers
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { it.volume > 0 }
|
.filter { it.volume > 0 }
|
||||||
|
@ -1488,17 +1353,13 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
|
|
||||||
Logger.e("onAudioVolumeIndication - $activeSpeakerIds")
|
Logger.e("onAudioVolumeIndication - $activeSpeakerIds")
|
||||||
handler.post {
|
handler.post {
|
||||||
if (!activeSpeakerIds.contains(0)) {
|
speakerListAdapter.activeSpeakers.clear()
|
||||||
speakerListAdapter.activeSpeakers.clear()
|
speakerListAdapter.activeSpeakers.addAll(activeSpeakerIds)
|
||||||
speakerListAdapter.activeSpeakers.addAll(activeSpeakerIds)
|
|
||||||
speakerListAdapter.notifyDataSetChanged()
|
|
||||||
|
|
||||||
if (activeSpeakerIds.contains(viewModel.roomInfoResponse.creatorId.toInt())) {
|
if (activeSpeakerIds.contains(0) && !isMicrophoneMute) {
|
||||||
binding.ivCreatorProfileBg.visibility = View.VISIBLE
|
speakerListAdapter.activeSpeakers.add(SharedPreferenceManager.userId.toInt())
|
||||||
} else {
|
|
||||||
binding.ivCreatorProfileBg.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
speakerListAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,16 +1389,12 @@ class LiveRoomActivity : BaseActivity<ActivityLiveRoomBinding>(ActivityLiveRoomB
|
||||||
override fun onUserMuteAudio(uid: Int, muted: Boolean) {
|
override fun onUserMuteAudio(uid: Int, muted: Boolean) {
|
||||||
super.onUserMuteAudio(uid, muted)
|
super.onUserMuteAudio(uid, muted)
|
||||||
handler.post {
|
handler.post {
|
||||||
if (uid == viewModel.roomInfoResponse.creatorId.toInt()) {
|
if (muted) {
|
||||||
setMuteSpeakerCreator(muted)
|
speakerListAdapter.muteSpeakers.add(uid)
|
||||||
} else {
|
} else {
|
||||||
if (muted) {
|
speakerListAdapter.muteSpeakers.remove(uid)
|
||||||
speakerListAdapter.muteSpeakers.add(uid)
|
|
||||||
} else {
|
|
||||||
speakerListAdapter.muteSpeakers.remove(uid)
|
|
||||||
}
|
|
||||||
speakerListAdapter.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
speakerListAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
Logger.e("onUserMuteAudio - uid: $uid, muted: $muted")
|
Logger.e("onUserMuteAudio - uid: $uid, muted: $muted")
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,6 @@ import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationStatusResp
|
||||||
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
|
import kr.co.vividnext.sodalive.live.room.info.GetRoomInfoResponse
|
||||||
import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse
|
import kr.co.vividnext.sodalive.live.room.profile.GetLiveRoomUserProfileResponse
|
||||||
import kr.co.vividnext.sodalive.live.room.update.EditLiveRoomInfoRequest
|
import kr.co.vividnext.sodalive.live.room.update.EditLiveRoomInfoRequest
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteItem
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreview
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewItem
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteRepository
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.SpinRouletteRequest
|
|
||||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
import kr.co.vividnext.sodalive.report.ReportRepository
|
||||||
import kr.co.vividnext.sodalive.report.ReportRequest
|
import kr.co.vividnext.sodalive.report.ReportRequest
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
|
@ -34,13 +29,11 @@ import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.floor
|
|
||||||
|
|
||||||
class LiveRoomViewModel(
|
class LiveRoomViewModel(
|
||||||
private val repository: LiveRepository,
|
private val repository: LiveRepository,
|
||||||
private val userRepository: UserRepository,
|
private val userRepository: UserRepository,
|
||||||
private val reportRepository: ReportRepository,
|
private val reportRepository: ReportRepository
|
||||||
private val rouletteRepository: RouletteRepository
|
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
private val _roomInfoLiveData = MutableLiveData<GetRoomInfoResponse>()
|
private val _roomInfoLiveData = MutableLiveData<GetRoomInfoResponse>()
|
||||||
val roomInfoLiveData: LiveData<GetRoomInfoResponse>
|
val roomInfoLiveData: LiveData<GetRoomInfoResponse>
|
||||||
|
@ -50,10 +43,14 @@ class LiveRoomViewModel(
|
||||||
val toastLiveData: LiveData<String?>
|
val toastLiveData: LiveData<String?>
|
||||||
get() = _toastLiveData
|
get() = _toastLiveData
|
||||||
|
|
||||||
private val _isShowNotice = MutableLiveData(false)
|
private val _isShowNotice = MutableLiveData(true)
|
||||||
val isShowNotice: LiveData<Boolean>
|
val isShowNotice: LiveData<Boolean>
|
||||||
get() = _isShowNotice
|
get() = _isShowNotice
|
||||||
|
|
||||||
|
private val _isExpandNotice = MutableLiveData(false)
|
||||||
|
val isExpandNotice: LiveData<Boolean>
|
||||||
|
get() = _isExpandNotice
|
||||||
|
|
||||||
private val _totalDonationCan = MutableLiveData(0)
|
private val _totalDonationCan = MutableLiveData(0)
|
||||||
val totalDonationCan: LiveData<Int>
|
val totalDonationCan: LiveData<Int>
|
||||||
get() = _totalDonationCan
|
get() = _totalDonationCan
|
||||||
|
@ -62,10 +59,6 @@ class LiveRoomViewModel(
|
||||||
val userProfileLiveData: LiveData<GetLiveRoomUserProfileResponse>
|
val userProfileLiveData: LiveData<GetLiveRoomUserProfileResponse>
|
||||||
get() = _userProfileLiveData
|
get() = _userProfileLiveData
|
||||||
|
|
||||||
private val _coverImageUrlLiveData = MutableLiveData("")
|
|
||||||
val coverImageUrlLiveData: LiveData<String>
|
|
||||||
get() = _coverImageUrlLiveData
|
|
||||||
|
|
||||||
lateinit var roomInfoResponse: GetRoomInfoResponse
|
lateinit var roomInfoResponse: GetRoomInfoResponse
|
||||||
|
|
||||||
fun isRoomInfoInitialized() = this::roomInfoResponse.isInitialized
|
fun isRoomInfoInitialized() = this::roomInfoResponse.isInitialized
|
||||||
|
@ -195,10 +188,6 @@ class LiveRoomViewModel(
|
||||||
Logger.e("data: ${it.data}")
|
Logger.e("data: ${it.data}")
|
||||||
_roomInfoLiveData.postValue(roomInfoResponse)
|
_roomInfoLiveData.postValue(roomInfoResponse)
|
||||||
|
|
||||||
if (_coverImageUrlLiveData.value!! != roomInfoResponse.coverImageUrl) {
|
|
||||||
_coverImageUrlLiveData.value = roomInfoResponse.coverImageUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
getTotalDonationCan(roomId = roomId)
|
getTotalDonationCan(roomId = roomId)
|
||||||
|
|
||||||
if (userId > 0 && it.data.creatorId == SharedPreferenceManager.userId) {
|
if (userId > 0 && it.data.creatorId == SharedPreferenceManager.userId) {
|
||||||
|
@ -357,6 +346,11 @@ class LiveRoomViewModel(
|
||||||
|
|
||||||
fun toggleShowNotice() {
|
fun toggleShowNotice() {
|
||||||
_isShowNotice.value = !isShowNotice.value!!
|
_isShowNotice.value = !isShowNotice.value!!
|
||||||
|
_isExpandNotice.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toggleExpandNotice() {
|
||||||
|
_isExpandNotice.value = !isExpandNotice.value!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleBackgroundImage() {
|
fun toggleBackgroundImage() {
|
||||||
|
@ -781,154 +775,4 @@ class LiveRoomViewModel(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showRoulette(complete: (RoulettePreview) -> Unit) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
rouletteRepository.getRoulette(
|
|
||||||
creatorId = roomInfoResponse.creatorId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
val data = it.data
|
|
||||||
if (
|
|
||||||
it.success &&
|
|
||||||
data != null &&
|
|
||||||
data.isActive &&
|
|
||||||
data.items.isNotEmpty()
|
|
||||||
) {
|
|
||||||
complete(
|
|
||||||
RoulettePreview(
|
|
||||||
data.can,
|
|
||||||
items = calculatePercentages(data.items)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val message = it.message ?: "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
|
||||||
_toastLiveData.postValue(message)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("룰렛을 사용할 수 없습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun spinRoulette(roomId: Long, complete: (Int, List<RouletteItem>, String) -> Unit) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
rouletteRepository.spinRoulette(
|
|
||||||
request = SpinRouletteRequest(roomId = roomId),
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
val data = it.data
|
|
||||||
if (
|
|
||||||
it.success &&
|
|
||||||
data != null &&
|
|
||||||
data.isActive &&
|
|
||||||
data.items.isNotEmpty()
|
|
||||||
) {
|
|
||||||
SharedPreferenceManager.can -= data.can
|
|
||||||
randomSelectRouletteItem(data.can, data.items, complete)
|
|
||||||
} else {
|
|
||||||
val message = it.message ?: "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
|
|
||||||
_toastLiveData.postValue(message)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("룰렛을 사용할 수 없습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refundRouletteDonation(roomId: Long) {
|
|
||||||
_isLoading.postValue(true)
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
rouletteRepository.refundRouletteDonation(
|
|
||||||
roomId,
|
|
||||||
"Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
if (it.success) {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"후원에 실패했습니다.\n다시 후원해주세요.\n" +
|
|
||||||
"계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun randomSelectRouletteItem(
|
|
||||||
can: Int,
|
|
||||||
items: List<RouletteItem>,
|
|
||||||
complete: (Int, List<RouletteItem>, String) -> Unit
|
|
||||||
) {
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
val rouletteItems = mutableListOf<String>()
|
|
||||||
items.asSequence().forEach { item ->
|
|
||||||
repeat(item.weight * 10) {
|
|
||||||
rouletteItems.add(item.title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
complete(can, items, rouletteItems.random())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculatePercentages(options: List<RouletteItem>): List<RoulettePreviewItem> {
|
|
||||||
val totalWeight = options.sumOf { it.weight }
|
|
||||||
val updatedOptions = options.asSequence().map { option ->
|
|
||||||
val percent = floor(option.weight.toDouble() / totalWeight * 10000) / 100
|
|
||||||
RoulettePreviewItem(
|
|
||||||
title = option.title,
|
|
||||||
percent = "${String.format("%.2f", percent)}%"
|
|
||||||
)
|
|
||||||
}.toList()
|
|
||||||
|
|
||||||
return updatedOptions
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,10 @@ package kr.co.vividnext.sodalive.live.room.chat
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.text.style.StyleSpan
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
@ -67,7 +65,12 @@ data class LiveRoomJoinChat(
|
||||||
)
|
)
|
||||||
|
|
||||||
spStr.setSpan(
|
spStr.setSpan(
|
||||||
StyleSpan(Typeface.BOLD),
|
CustomTypefaceSpan(
|
||||||
|
ResourcesCompat.getFont(
|
||||||
|
context,
|
||||||
|
R.font.gmarket_sans_bold
|
||||||
|
)
|
||||||
|
),
|
||||||
str.indexOf("'"),
|
str.indexOf("'"),
|
||||||
str.indexOf("'님"),
|
str.indexOf("'님"),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
@ -171,7 +174,6 @@ data class LiveRoomNormalChat(
|
||||||
itemBinding.tvNickname.text = nickname
|
itemBinding.tvNickname.text = nickname
|
||||||
|
|
||||||
itemBinding.ivBg.visibility = View.VISIBLE
|
itemBinding.ivBg.visibility = View.VISIBLE
|
||||||
itemBinding.ivRoulette.visibility = View.GONE
|
|
||||||
itemBinding.tvCreatorOrManager.visibility = View.GONE
|
itemBinding.tvCreatorOrManager.visibility = View.GONE
|
||||||
|
|
||||||
when (rank + 1) {
|
when (rank + 1) {
|
||||||
|
@ -188,7 +190,7 @@ data class LiveRoomNormalChat(
|
||||||
}
|
}
|
||||||
|
|
||||||
-1 -> {
|
-1 -> {
|
||||||
itemBinding.ivBg.setImageResource(R.drawable.bg_circle_3bb9f1)
|
itemBinding.ivBg.setImageResource(R.drawable.bg_circle_6f3dec_9970ff)
|
||||||
itemBinding.ivCrown.setImageResource(R.drawable.ic_crown)
|
itemBinding.ivCrown.setImageResource(R.drawable.ic_crown)
|
||||||
itemBinding.ivCrown.visibility = View.VISIBLE
|
itemBinding.ivCrown.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
@ -227,7 +229,7 @@ data class LiveRoomNormalChat(
|
||||||
)
|
)
|
||||||
|
|
||||||
if (SharedPreferenceManager.userId == userId) {
|
if (SharedPreferenceManager.userId == userId) {
|
||||||
itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_553bb9f1)
|
itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_999970ff)
|
||||||
} else {
|
} else {
|
||||||
itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_99000000)
|
itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_99000000)
|
||||||
}
|
}
|
||||||
|
@ -286,7 +288,6 @@ data class LiveRoomDonationChat(
|
||||||
itemBinding.ivCan.visibility = View.VISIBLE
|
itemBinding.ivCan.visibility = View.VISIBLE
|
||||||
itemBinding.ivBg.visibility = View.GONE
|
itemBinding.ivBg.visibility = View.GONE
|
||||||
itemBinding.ivCrown.visibility = View.GONE
|
itemBinding.ivCrown.visibility = View.GONE
|
||||||
itemBinding.ivRoulette.visibility = View.GONE
|
|
||||||
itemBinding.tvCreatorOrManager.visibility = View.GONE
|
itemBinding.tvCreatorOrManager.visibility = View.GONE
|
||||||
|
|
||||||
if (donationMessage.isNotBlank()) {
|
if (donationMessage.isNotBlank()) {
|
||||||
|
@ -301,89 +302,35 @@ data class LiveRoomDonationChat(
|
||||||
|
|
||||||
itemBinding.root.setBackgroundResource(
|
itemBinding.root.setBackgroundResource(
|
||||||
when {
|
when {
|
||||||
|
can >= 100000 -> {
|
||||||
|
R.drawable.bg_round_corner_6_7_c25264
|
||||||
|
}
|
||||||
|
|
||||||
|
can >= 50000 -> {
|
||||||
|
R.drawable.bg_round_corner_6_7_e6d85e37
|
||||||
|
}
|
||||||
|
|
||||||
can >= 10000 -> {
|
can >= 10000 -> {
|
||||||
R.drawable.bg_round_corner_6_7_ccc25264
|
R.drawable.bg_round_corner_6_7_e6d38c38
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 5000 -> {
|
can >= 5000 -> {
|
||||||
R.drawable.bg_round_corner_6_7_ccd85e37
|
R.drawable.bg_round_corner_6_7_e659548f
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 1000 -> {
|
can >= 1000 -> {
|
||||||
R.drawable.bg_round_corner_6_7_ccd38c38
|
R.drawable.bg_round_corner_6_7_e64d6aa4
|
||||||
}
|
}
|
||||||
|
|
||||||
can >= 500 -> {
|
can >= 500 -> {
|
||||||
R.drawable.bg_round_corner_6_7_cc59548f
|
R.drawable.bg_round_corner_6_7_e62d7390
|
||||||
}
|
|
||||||
|
|
||||||
can >= 100 -> {
|
|
||||||
R.drawable.bg_round_corner_6_7_cc4d6aa4
|
|
||||||
}
|
|
||||||
|
|
||||||
can >= 50 -> {
|
|
||||||
R.drawable.bg_round_corner_6_7_cc2d7390
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
R.drawable.bg_round_corner_6_7_cc548f7d
|
R.drawable.bg_round_corner_6_7_e6548f7d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
itemBinding.root.setPadding(33)
|
itemBinding.root.setPadding(33)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LiveRoomRouletteDonationChat(
|
|
||||||
@SerializedName("profileUrl") val profileUrl: String,
|
|
||||||
@SerializedName("nickname") val nickname: String,
|
|
||||||
@SerializedName("rouletteResult") val rouletteResult: String
|
|
||||||
) : LiveRoomChat() {
|
|
||||||
override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
|
|
||||||
val itemBinding = binding as ItemLiveRoomChatBinding
|
|
||||||
val chat = "[$rouletteResult] 당첨!"
|
|
||||||
val spChat = SpannableString(chat)
|
|
||||||
spChat.setSpan(
|
|
||||||
ForegroundColorSpan(
|
|
||||||
ContextCompat.getColor(
|
|
||||||
context,
|
|
||||||
R.color.color_ffe500
|
|
||||||
)
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
chat.indexOf("]", 0, true) + 1,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
||||||
)
|
|
||||||
|
|
||||||
val spNickname = SpannableString("${nickname}님의 룰렛 결과?")
|
|
||||||
spNickname.setSpan(
|
|
||||||
StyleSpan(Typeface.NORMAL),
|
|
||||||
0,
|
|
||||||
nickname.length,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
||||||
)
|
|
||||||
|
|
||||||
itemBinding.ivProfile.load(profileUrl) {
|
|
||||||
crossfade(true)
|
|
||||||
placeholder(R.drawable.ic_place_holder)
|
|
||||||
transformations(RoundedCornersTransformation(23.3f.dpToPx()))
|
|
||||||
}
|
|
||||||
itemBinding.tvChat.text = spChat
|
|
||||||
itemBinding.tvNickname.text = spNickname
|
|
||||||
itemBinding.ivProfile.setOnClickListener {}
|
|
||||||
|
|
||||||
itemBinding.ivCan.visibility = View.GONE
|
|
||||||
itemBinding.ivBg.visibility = View.GONE
|
|
||||||
itemBinding.ivCrown.visibility = View.GONE
|
|
||||||
itemBinding.tvCreatorOrManager.visibility = View.GONE
|
|
||||||
itemBinding.ivRoulette.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
itemBinding.tvDonationMessage.visibility = View.GONE
|
|
||||||
|
|
||||||
itemBinding.llMessageBg.setPadding(0)
|
|
||||||
itemBinding.llMessageBg.background = null
|
|
||||||
|
|
||||||
itemBinding.root.setBackgroundResource(R.drawable.bg_round_corner_6_7_ccc25264)
|
|
||||||
itemBinding.root.setPadding(33)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,21 +6,12 @@ data class LiveRoomChatRawMessage(
|
||||||
@SerializedName("type") val type: LiveRoomChatRawMessageType,
|
@SerializedName("type") val type: LiveRoomChatRawMessageType,
|
||||||
@SerializedName("message") val message: String,
|
@SerializedName("message") val message: String,
|
||||||
@SerializedName("can") val can: Int,
|
@SerializedName("can") val can: Int,
|
||||||
@SerializedName("donationMessage") val donationMessage: String?,
|
@SerializedName("donationMessage") val donationMessage: String?
|
||||||
@SerializedName("isActiveRoulette") val isActiveRoulette: Boolean? = null
|
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class LiveRoomChatRawMessageType {
|
enum class LiveRoomChatRawMessageType {
|
||||||
@SerializedName("DONATION")
|
@SerializedName("DONATION") DONATION,
|
||||||
DONATION,
|
@SerializedName("SET_MANAGER") SET_MANAGER,
|
||||||
@SerializedName("SET_MANAGER")
|
@SerializedName("EDIT_ROOM_INFO") EDIT_ROOM_INFO,
|
||||||
SET_MANAGER,
|
@SerializedName("DONATION_STATUS") DONATION_STATUS
|
||||||
@SerializedName("EDIT_ROOM_INFO")
|
|
||||||
EDIT_ROOM_INFO,
|
|
||||||
@SerializedName("DONATION_STATUS")
|
|
||||||
DONATION_STATUS,
|
|
||||||
@SerializedName("TOGGLE_ROULETTE")
|
|
||||||
TOGGLE_ROULETTE,
|
|
||||||
@SerializedName("ROULETTE_DONATION")
|
|
||||||
ROULETTE_DONATION
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,9 +365,9 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
binding.llReservationDatetime.visibility = View.GONE
|
binding.llReservationDatetime.visibility = View.GONE
|
||||||
binding.ivTimeReservation.visibility = View.GONE
|
binding.ivTimeReservation.visibility = View.GONE
|
||||||
binding.ivTimeNow.visibility = View.VISIBLE
|
binding.ivTimeNow.visibility = View.VISIBLE
|
||||||
binding.llTimeNow.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llTimeNow.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.llTimeReservation.setBackgroundResource(
|
binding.llTimeReservation.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_13181b
|
R.drawable.bg_round_corner_6_7_1f1734
|
||||||
)
|
)
|
||||||
binding.tvTimeNow.setTextColor(
|
binding.tvTimeNow.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
|
@ -379,22 +379,22 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
binding.tvTimeReservation.setTextColor(
|
binding.tvTimeReservation.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
binding.llReservationDatetime.visibility = View.VISIBLE
|
binding.llReservationDatetime.visibility = View.VISIBLE
|
||||||
binding.ivTimeReservation.visibility = View.VISIBLE
|
binding.ivTimeReservation.visibility = View.VISIBLE
|
||||||
binding.ivTimeNow.visibility = View.GONE
|
binding.ivTimeNow.visibility = View.GONE
|
||||||
binding.llTimeNow.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llTimeNow.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
binding.llTimeReservation.setBackgroundResource(
|
binding.llTimeReservation.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_6_7_3bb9f1
|
R.drawable.bg_round_corner_6_7_9970ff
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.tvTimeNow.setTextColor(
|
binding.tvTimeNow.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -413,8 +413,8 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
binding.ivPrivate.visibility = View.VISIBLE
|
binding.ivPrivate.visibility = View.VISIBLE
|
||||||
binding.ivOpen.visibility = View.GONE
|
binding.ivOpen.visibility = View.GONE
|
||||||
|
|
||||||
binding.llPrivate.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llPrivate.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.llOpen.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llOpen.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
|
|
||||||
binding.tvPrivate.setTextColor(
|
binding.tvPrivate.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
|
@ -426,7 +426,7 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
binding.tvOpen.setTextColor(
|
binding.tvOpen.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -437,13 +437,13 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
binding.ivOpen.visibility = View.VISIBLE
|
binding.ivOpen.visibility = View.VISIBLE
|
||||||
binding.ivPrivate.visibility = View.GONE
|
binding.ivPrivate.visibility = View.GONE
|
||||||
|
|
||||||
binding.llOpen.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llOpen.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.llPrivate.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llPrivate.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
|
|
||||||
binding.tvPrivate.setTextColor(
|
binding.tvPrivate.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -501,16 +501,16 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
viewModel.isAdultLiveData.observe(this) {
|
viewModel.isAdultLiveData.observe(this) {
|
||||||
if (it) {
|
if (it) {
|
||||||
binding.ivAgeAll.visibility = View.GONE
|
binding.ivAgeAll.visibility = View.GONE
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
binding.tvAgeAll.setTextColor(
|
binding.tvAgeAll.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.ivAge19.visibility = View.VISIBLE
|
binding.ivAge19.visibility = View.VISIBLE
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.tvAge19.setTextColor(
|
binding.tvAge19.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -519,16 +519,16 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
binding.ivAge19.visibility = View.GONE
|
binding.ivAge19.visibility = View.GONE
|
||||||
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
|
binding.llAge19.setBackgroundResource(R.drawable.bg_round_corner_6_7_1f1734)
|
||||||
binding.tvAge19.setTextColor(
|
binding.tvAge19.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
binding.ivAgeAll.visibility = View.VISIBLE
|
binding.ivAgeAll.visibility = View.VISIBLE
|
||||||
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
|
binding.llAgeAll.setBackgroundResource(R.drawable.bg_round_corner_6_7_9970ff)
|
||||||
binding.tvAgeAll.setTextColor(
|
binding.tvAgeAll.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
|
@ -605,7 +605,7 @@ class LiveRoomCreateActivity : BaseActivity<ActivityLiveRoomCreateBinding>(
|
||||||
priceView.setTextColor(
|
priceView.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
priceView.typeface = ResourcesCompat.getFont(
|
priceView.typeface = ResourcesCompat.getFont(
|
||||||
|
|
|
@ -20,9 +20,7 @@ import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentLiveRoomDetailBinding
|
import kr.co.vividnext.sodalive.databinding.FragmentLiveRoomDetailBinding
|
||||||
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
|
||||||
import kr.co.vividnext.sodalive.extensions.convertDateFormat
|
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class LiveRoomDetailFragment(
|
class LiveRoomDetailFragment(
|
||||||
private val roomId: Long,
|
private val roomId: Long,
|
||||||
|
@ -92,11 +90,7 @@ class LiveRoomDetailFragment(
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvTitle.text = response.title
|
binding.tvTitle.text = response.title
|
||||||
binding.tvDate.text = response.beginDateTime.convertDateFormat(
|
binding.tvDate.text = response.beginDateTime
|
||||||
from = "yyyy.MM.dd EEE hh:mm a",
|
|
||||||
to = "yyyy년 MM월 dd일 (E) a hh시 mm분",
|
|
||||||
inputLocale = Locale.ENGLISH
|
|
||||||
)
|
|
||||||
|
|
||||||
if (response.price > 0) {
|
if (response.price > 0) {
|
||||||
binding.tvCan.text = response.price.toString()
|
binding.tvCan.text = response.price.toString()
|
||||||
|
|
|
@ -1,87 +1,32 @@
|
||||||
package kr.co.vividnext.sodalive.live.room.dialog
|
package kr.co.vividnext.sodalive.live.room.dialog
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.widget.LinearLayout
|
||||||
import android.view.WindowManager
|
import kr.co.vividnext.sodalive.dialog.LiveDialog
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import kr.co.vividnext.sodalive.databinding.DialogLivePaymentBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
|
|
||||||
class LivePaymentDialog(
|
class LivePaymentDialog(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
layoutInflater: LayoutInflater,
|
layoutInflater: LayoutInflater,
|
||||||
title: String,
|
title: String,
|
||||||
desc: String,
|
desc: String,
|
||||||
desc2: String? = null,
|
|
||||||
startDateTime: String? = null,
|
|
||||||
nowDateTime: String? = null,
|
|
||||||
confirmButtonTitle: String,
|
confirmButtonTitle: String,
|
||||||
confirmButtonClick: () -> Unit,
|
confirmButtonClick: () -> Unit,
|
||||||
cancelButtonTitle: String = "",
|
cancelButtonTitle: String = "",
|
||||||
cancelButtonClick: (() -> Unit)? = null,
|
cancelButtonClick: (() -> Unit)? = null,
|
||||||
|
) : LiveDialog(
|
||||||
|
activity,
|
||||||
|
layoutInflater,
|
||||||
|
title,
|
||||||
|
desc,
|
||||||
|
confirmButtonTitle,
|
||||||
|
confirmButtonClick,
|
||||||
|
cancelButtonTitle,
|
||||||
|
cancelButtonClick
|
||||||
) {
|
) {
|
||||||
private val alertDialog: AlertDialog
|
|
||||||
private val dialogView = DialogLivePaymentBinding.inflate(layoutInflater)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val dialogBuilder = AlertDialog.Builder(activity)
|
val lp = dialogView.tvConfirm.layoutParams as LinearLayout.LayoutParams
|
||||||
dialogBuilder.setView(dialogView.root)
|
lp.weight = 2F
|
||||||
|
dialogView.tvConfirm.layoutParams = lp
|
||||||
alertDialog = dialogBuilder.create()
|
|
||||||
alertDialog.setCancelable(false)
|
|
||||||
alertDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
dialogView.tvTitle.text = title
|
|
||||||
dialogView.tvDesc.text = desc
|
|
||||||
|
|
||||||
if (startDateTime != null && nowDateTime != null) {
|
|
||||||
dialogView.tvDesc2.text = desc2
|
|
||||||
dialogView.tvNowDate.text = nowDateTime
|
|
||||||
dialogView.tvStartDate.text = startDateTime
|
|
||||||
|
|
||||||
dialogView.tvDesc2.visibility = View.VISIBLE
|
|
||||||
dialogView.llTimeNotice.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
dialogView.tvDesc2.visibility = View.GONE
|
|
||||||
dialogView.llTimeNotice.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvCancel.text = cancelButtonTitle
|
|
||||||
dialogView.tvCancel.setOnClickListener {
|
|
||||||
alertDialog.dismiss()
|
|
||||||
cancelButtonClick?.let { it() }
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvConfirm.text = confirmButtonTitle
|
|
||||||
dialogView.tvConfirm.setOnClickListener {
|
|
||||||
alertDialog.dismiss()
|
|
||||||
confirmButtonClick()
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvCancel.visibility = if (cancelButtonTitle.isNotBlank()) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvConfirm.visibility = if (confirmButtonTitle.isNotBlank()) {
|
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun show(width: Int, message: String = "") {
|
|
||||||
alertDialog.show()
|
|
||||||
|
|
||||||
val lp = WindowManager.LayoutParams()
|
|
||||||
lp.copyFrom(alertDialog.window?.attributes)
|
|
||||||
lp.width = width - (26.7f.dpToPx()).toInt()
|
|
||||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
|
||||||
|
|
||||||
alertDialog.window?.attributes = lp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ data class GetRoomInfoResponse(
|
||||||
@SerializedName("listenerList") val listenerList: List<LiveRoomMember>,
|
@SerializedName("listenerList") val listenerList: List<LiveRoomMember>,
|
||||||
@SerializedName("managerList") val managerList: List<LiveRoomMember>,
|
@SerializedName("managerList") val managerList: List<LiveRoomMember>,
|
||||||
@SerializedName("donationRankingTop3UserIds") val donationRankingTop3UserIds: List<Long>,
|
@SerializedName("donationRankingTop3UserIds") val donationRankingTop3UserIds: List<Long>,
|
||||||
@SerializedName("isActiveRoulette") val isActiveRoulette: Boolean,
|
|
||||||
@SerializedName("isPrivateRoom") val isPrivateRoom: Boolean,
|
@SerializedName("isPrivateRoom") val isPrivateRoom: Boolean,
|
||||||
@SerializedName("password") val password: String? = null
|
@SerializedName("password") val password: String? = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,11 +5,11 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomProfileBinding
|
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomProfileBinding
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||||
import kr.co.vividnext.sodalive.extensions.loadUrl
|
|
||||||
import kr.co.vividnext.sodalive.live.room.info.LiveRoomMember
|
import kr.co.vividnext.sodalive.live.room.info.LiveRoomMember
|
||||||
|
|
||||||
class LiveRoomProfileListAdapter : RecyclerView.Adapter<LiveRoomProfileListAdapter.ViewHolder>() {
|
class LiveRoomProfileListAdapter : RecyclerView.Adapter<LiveRoomProfileListAdapter.ViewHolder>() {
|
||||||
|
@ -17,10 +17,10 @@ class LiveRoomProfileListAdapter : RecyclerView.Adapter<LiveRoomProfileListAdapt
|
||||||
private val binding: ItemLiveRoomProfileBinding
|
private val binding: ItemLiveRoomProfileBinding
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
fun bind(item: LiveRoomMember) {
|
fun bind(item: LiveRoomMember) {
|
||||||
binding.ivProfile.loadUrl(item.profileImage) {
|
binding.ivProfile.load(item.profileImage) {
|
||||||
crossfade(true)
|
crossfade(true)
|
||||||
placeholder(R.drawable.ic_place_holder)
|
placeholder(R.drawable.ic_place_holder)
|
||||||
transformations(CircleCropTransformation())
|
transformations(RoundedCornersTransformation(23.3f.dpToPx()))
|
||||||
|
|
||||||
if (activeSpeakers.contains(item.id.toInt())) {
|
if (activeSpeakers.contains(item.id.toInt())) {
|
||||||
binding.ivBg.visibility = View.VISIBLE
|
binding.ivBg.visibility = View.VISIBLE
|
||||||
|
@ -35,9 +35,15 @@ class LiveRoomProfileListAdapter : RecyclerView.Adapter<LiveRoomProfileListAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
val ivMuteLp = binding.ivMute.layoutParams
|
val ivMuteLp = binding.ivMute.layoutParams
|
||||||
ivMuteLp.width = 30f.dpToPx().toInt()
|
ivMuteLp.width = 51.7f.dpToPx().toInt()
|
||||||
ivMuteLp.height = 30f.dpToPx().toInt()
|
ivMuteLp.height = 51.7f.dpToPx().toInt()
|
||||||
binding.ivMute.layoutParams = ivMuteLp
|
binding.ivMute.layoutParams = ivMuteLp
|
||||||
|
|
||||||
|
if (managerId == item.id) {
|
||||||
|
binding.ivCrown.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.ivCrown.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvNickname.text = item.nickname
|
binding.tvNickname.text = item.nickname
|
||||||
|
|
|
@ -20,6 +20,7 @@ class LiveRoomUserProfileDialog(
|
||||||
private val userProfileLiveData: LiveData<GetLiveRoomUserProfileResponse>,
|
private val userProfileLiveData: LiveData<GetLiveRoomUserProfileResponse>,
|
||||||
layoutInflater: LayoutInflater,
|
layoutInflater: LayoutInflater,
|
||||||
private val isStaff: (Long) -> Boolean,
|
private val isStaff: (Long) -> Boolean,
|
||||||
|
private val onClickSendMessage: (Long, String) -> Unit,
|
||||||
private val onClickSetManager: (Long) -> Unit,
|
private val onClickSetManager: (Long) -> Unit,
|
||||||
private val onClickReleaseManager: (Long) -> Unit,
|
private val onClickReleaseManager: (Long) -> Unit,
|
||||||
private val onClickFollow: (Long) -> Unit,
|
private val onClickFollow: (Long) -> Unit,
|
||||||
|
@ -83,8 +84,18 @@ class LiveRoomUserProfileDialog(
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogView.tvNickname.text = userProfile.nickname
|
dialogView.tvNickname.text = userProfile.nickname
|
||||||
|
dialogView.tvTags.text = userProfile.tags
|
||||||
dialogView.tvGender.text = userProfile.gender
|
dialogView.tvGender.text = userProfile.gender
|
||||||
|
dialogView.tvIntroduce.text = userProfile.introduce
|
||||||
|
|
||||||
dialogView.ivClose.setOnClickListener { alertDialog.dismiss() }
|
dialogView.ivClose.setOnClickListener { alertDialog.dismiss() }
|
||||||
|
dialogView.llSendMessage.setOnClickListener {
|
||||||
|
onClickSendMessage(
|
||||||
|
userProfile.userId,
|
||||||
|
userProfile.nickname
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
dialogView.tvIntroduce.setOnClickListener {
|
dialogView.tvIntroduce.setOnClickListener {
|
||||||
isIntroduceFold = !isIntroduceFold
|
isIntroduceFold = !isIntroduceFold
|
||||||
|
|
||||||
|
@ -158,33 +169,25 @@ class LiveRoomUserProfileDialog(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userProfile.isFollowing != null) {
|
if (userProfile.isFollowing != null) {
|
||||||
dialogView.ivFollow.visibility = View.VISIBLE
|
dialogView.llFollow.visibility = View.VISIBLE
|
||||||
|
|
||||||
if (userProfile.isFollowing) {
|
if (userProfile.isFollowing) {
|
||||||
dialogView.ivFollow.setImageResource(R.drawable.btn_following)
|
dialogView.tvFollow.text = "팔로잉"
|
||||||
dialogView.ivFollow.setOnClickListener { onClickUnFollow(userProfile.userId) }
|
dialogView.ivFollow.setImageResource(R.drawable.ic_alarm_selected)
|
||||||
|
dialogView.llFollow.setBackgroundResource(
|
||||||
|
R.drawable.bg_round_corner_23_3_3e1b93_9970ff
|
||||||
|
)
|
||||||
|
dialogView.tvFollow.setOnClickListener { onClickUnFollow(userProfile.userId) }
|
||||||
} else {
|
} else {
|
||||||
dialogView.ivFollow.setImageResource(R.drawable.btn_follow)
|
dialogView.tvFollow.text = "팔로우"
|
||||||
dialogView.ivFollow.setOnClickListener { onClickFollow(userProfile.userId) }
|
dialogView.ivFollow.setImageResource(R.drawable.ic_alarm)
|
||||||
}
|
dialogView.llFollow.setBackgroundResource(
|
||||||
|
R.drawable.bg_round_corner_23_3_transparent_9970ff
|
||||||
if (userProfile.tags.isNotBlank()) {
|
)
|
||||||
dialogView.tvTags.text = userProfile.tags
|
dialogView.tvFollow.setOnClickListener { onClickFollow(userProfile.userId) }
|
||||||
dialogView.tvTags.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
dialogView.tvTags.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userProfile.introduce.isNotBlank()) {
|
|
||||||
dialogView.tvIntroduce.text = userProfile.introduce
|
|
||||||
dialogView.tvIntroduce.visibility = View.VISIBLE
|
|
||||||
} else {
|
|
||||||
dialogView.tvIntroduce.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dialogView.tvTags.visibility = View.GONE
|
dialogView.llFollow.visibility = View.GONE
|
||||||
dialogView.ivFollow.visibility = View.GONE
|
|
||||||
dialogView.tvIntroduce.visibility = View.GONE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogView.ivMenu.setOnClickListener {
|
dialogView.ivMenu.setOnClickListener {
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class GetRouletteResponse(
|
|
||||||
@SerializedName("can") val can: Int,
|
|
||||||
@SerializedName("isActive") val isActive: Boolean,
|
|
||||||
@SerializedName("items") val items: List<RouletteItem>
|
|
||||||
)
|
|
||||||
|
|
||||||
data class RouletteItem(
|
|
||||||
@SerializedName("title") val title: String,
|
|
||||||
@SerializedName("weight") val weight: Int
|
|
||||||
)
|
|
|
@ -1,45 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.Paint
|
|
||||||
import android.graphics.Path
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.View
|
|
||||||
|
|
||||||
class RouletteInvertedTriangle @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = 0
|
|
||||||
) : View(context, attrs, defStyleAttr) {
|
|
||||||
private val trianglePath = Path()
|
|
||||||
private var trianglePaint = Paint()
|
|
||||||
|
|
||||||
private val triangleSize = 60f
|
|
||||||
|
|
||||||
init {
|
|
||||||
trianglePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
||||||
color = Color.RED // Set the color of the triangle
|
|
||||||
style = Paint.Style.FILL // Fill the triangle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas) {
|
|
||||||
super.onDraw(canvas)
|
|
||||||
// Clear the old path
|
|
||||||
trianglePath.reset()
|
|
||||||
|
|
||||||
// Define the new path for the inverted triangle
|
|
||||||
// Starting point (top of the triangle)
|
|
||||||
trianglePath.moveTo((width / 2f) - 30, -10f)
|
|
||||||
// Line to bottom left of the triangle
|
|
||||||
trianglePath.lineTo((width / 2f) + 30, -10f)
|
|
||||||
// Line to bottom right of the triangle
|
|
||||||
trianglePath.lineTo(width / 2f, 10f + triangleSize)
|
|
||||||
// Close the path to form a triangle
|
|
||||||
trianglePath.close()
|
|
||||||
|
|
||||||
canvas.drawPath(trianglePath, trianglePaint)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
data class RoulettePreview(
|
|
||||||
val can: Int,
|
|
||||||
val items: List<RoulettePreviewItem>
|
|
||||||
)
|
|
||||||
|
|
||||||
data class RoulettePreviewItem(
|
|
||||||
val title: String,
|
|
||||||
val percent: String
|
|
||||||
)
|
|
|
@ -1,106 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.Window
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.databinding.DialogRoulettePreviewBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
import kr.co.vividnext.sodalive.extensions.moneyFormat
|
|
||||||
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
|
|
||||||
|
|
||||||
class RoulettePreviewDialog(
|
|
||||||
private val activity: FragmentActivity,
|
|
||||||
private val preview: RoulettePreview,
|
|
||||||
private val title: String = "",
|
|
||||||
private val onClickSpin: (() -> Unit)? = null,
|
|
||||||
layoutInflater: LayoutInflater
|
|
||||||
) {
|
|
||||||
private val alertDialog: AlertDialog
|
|
||||||
private val dialogView = DialogRoulettePreviewBinding.inflate(layoutInflater)
|
|
||||||
|
|
||||||
init {
|
|
||||||
val dialogBuilder = AlertDialog.Builder(activity)
|
|
||||||
dialogBuilder.setView(dialogView.root)
|
|
||||||
|
|
||||||
alertDialog = dialogBuilder.create()
|
|
||||||
alertDialog.setCancelable(false)
|
|
||||||
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
alertDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
setupView()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun show() {
|
|
||||||
alertDialog.show()
|
|
||||||
|
|
||||||
val lp = WindowManager.LayoutParams()
|
|
||||||
lp.copyFrom(alertDialog.window?.attributes)
|
|
||||||
lp.width = activity.resources.displayMetrics.widthPixels - (26.7f.dpToPx()).toInt()
|
|
||||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
|
||||||
|
|
||||||
alertDialog.window?.attributes = lp
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun setupView() {
|
|
||||||
dialogView.tvCancel.setOnClickListener { alertDialog.dismiss() }
|
|
||||||
|
|
||||||
dialogView.tvSpinRoulette.text = "${preview.can}캔으로 룰렛 돌리기"
|
|
||||||
dialogView.tvSpinRoulette.setOnClickListener {
|
|
||||||
if (onClickSpin != null) {
|
|
||||||
onClickSpin!!()
|
|
||||||
}
|
|
||||||
|
|
||||||
alertDialog.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView.tvTitle.text = title.ifBlank { "룰렛" }
|
|
||||||
if (onClickSpin != null) {
|
|
||||||
dialogView.tvCan.visibility = View.VISIBLE
|
|
||||||
dialogView.tvCan.text = SharedPreferenceManager.can.moneyFormat()
|
|
||||||
dialogView.tvCan.setOnClickListener {
|
|
||||||
alertDialog.dismiss()
|
|
||||||
|
|
||||||
val intent = Intent(activity, CanChargeActivity::class.java)
|
|
||||||
intent.putExtra(Constants.EXTRA_GO_TO_PREV_PAGE, true)
|
|
||||||
activity.startActivity(intent)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dialogView.tvCan.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
preview.items.forEachIndexed { index, item ->
|
|
||||||
dialogView.llRouletteOptionContainer.addView(createOptionView(index, item))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun createOptionView(index: Int, item: RoulettePreviewItem): View {
|
|
||||||
val itemView = LayoutInflater
|
|
||||||
.from(activity)
|
|
||||||
.inflate(
|
|
||||||
R.layout.layout_roulette_preview_item,
|
|
||||||
dialogView.llRouletteOptionContainer,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
val tvItemTitle = itemView.findViewById<TextView>(R.id.tv_roulette_item_title)
|
|
||||||
val tvOrder = itemView.findViewById<TextView>(R.id.tv_order)
|
|
||||||
|
|
||||||
tvItemTitle.text = "${item.title} (${item.percent})"
|
|
||||||
tvOrder.text = "${index + 1}"
|
|
||||||
|
|
||||||
return itemView
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Single
|
|
||||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.config.CreateOrUpdateRouletteRequest
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.config.RouletteApi
|
|
||||||
|
|
||||||
class RouletteRepository(private val api: RouletteApi) {
|
|
||||||
fun createOrUpdateRoulette(
|
|
||||||
request: CreateOrUpdateRouletteRequest,
|
|
||||||
token: String
|
|
||||||
) = api.createOrUpdateRoulette(
|
|
||||||
request = request,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun getRoulette(creatorId: Long, token: String) = api.getRoulette(
|
|
||||||
creatorId = creatorId,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun spinRoulette(request: SpinRouletteRequest, token: String) = api.spinRoulette(
|
|
||||||
request = request,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
|
|
||||||
fun refundRouletteDonation(roomId: Long, token: String): Single<ApiResponse<Any>> {
|
|
||||||
return api.refundRouletteDonation(
|
|
||||||
id = roomId,
|
|
||||||
authHeader = token
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.Window
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import kr.co.vividnext.sodalive.databinding.DialogRouletteSpinBinding
|
|
||||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
|
||||||
|
|
||||||
class RouletteSpinDialog(
|
|
||||||
private val activity: FragmentActivity,
|
|
||||||
private val items: List<RouletteItem>,
|
|
||||||
private val selectedItem: String,
|
|
||||||
layoutInflater: LayoutInflater,
|
|
||||||
private val complete: () -> Unit
|
|
||||||
) {
|
|
||||||
private val alertDialog: AlertDialog
|
|
||||||
private val dialogView = DialogRouletteSpinBinding.inflate(layoutInflater)
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
|
||||||
|
|
||||||
init {
|
|
||||||
val dialogBuilder = AlertDialog.Builder(activity)
|
|
||||||
dialogBuilder.setView(dialogView.root)
|
|
||||||
|
|
||||||
alertDialog = dialogBuilder.create()
|
|
||||||
alertDialog.setCancelable(false)
|
|
||||||
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
alertDialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
setupView()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun show() {
|
|
||||||
alertDialog.show()
|
|
||||||
|
|
||||||
val lp = WindowManager.LayoutParams()
|
|
||||||
lp.copyFrom(alertDialog.window?.attributes)
|
|
||||||
lp.width = activity.resources.displayMetrics.widthPixels - (26.7f.dpToPx()).toInt()
|
|
||||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
|
||||||
|
|
||||||
alertDialog.window?.attributes = lp
|
|
||||||
rotateToOption()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupView() {
|
|
||||||
dialogView.roulette.items = items
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rotateToOption() {
|
|
||||||
dialogView.roulette.rotateToOption(selectedItem) {
|
|
||||||
handler.postDelayed({
|
|
||||||
alertDialog.dismiss()
|
|
||||||
complete()
|
|
||||||
}, 1500)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.Paint
|
|
||||||
import android.graphics.RectF
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.view.View
|
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.RotateAnimation
|
|
||||||
import kotlin.math.cos
|
|
||||||
import kotlin.math.min
|
|
||||||
import kotlin.math.sin
|
|
||||||
|
|
||||||
class RouletteView @JvmOverloads constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = 0
|
|
||||||
) : View(context, attrs, defStyleAttr) {
|
|
||||||
private var rect = RectF()
|
|
||||||
|
|
||||||
private val fillPaint = Paint()
|
|
||||||
private val textPaint = Paint()
|
|
||||||
private val strokePaint = Paint()
|
|
||||||
|
|
||||||
var items = listOf<RouletteItem>()
|
|
||||||
|
|
||||||
private val colors = listOf(
|
|
||||||
Color.parseColor("#D73535"),
|
|
||||||
Color.parseColor("#FF5151"),
|
|
||||||
Color.parseColor("#FF7C32"),
|
|
||||||
Color.parseColor("#FFAF13"),
|
|
||||||
Color.parseColor("#FFC658"),
|
|
||||||
Color.parseColor("#8BDA70"),
|
|
||||||
Color.parseColor("#06AB97"),
|
|
||||||
Color.parseColor("#12AAFF"),
|
|
||||||
Color.parseColor("#0052B3"),
|
|
||||||
Color.parseColor("#7444FF")
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
|
||||||
strokePaint.apply {
|
|
||||||
color = Color.WHITE
|
|
||||||
style = Paint.Style.STROKE
|
|
||||||
strokeWidth = 10f
|
|
||||||
isAntiAlias = true
|
|
||||||
}
|
|
||||||
|
|
||||||
fillPaint.apply {
|
|
||||||
style = Paint.Style.FILL
|
|
||||||
isAntiAlias = true
|
|
||||||
}
|
|
||||||
|
|
||||||
textPaint.apply {
|
|
||||||
color = Color.WHITE
|
|
||||||
textSize = 30f
|
|
||||||
textAlign = Paint.Align.CENTER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
||||||
super.onSizeChanged(w, h, oldw, oldh)
|
|
||||||
|
|
||||||
val diameter = min(width, height) - strokePaint.strokeWidth
|
|
||||||
rect.set(
|
|
||||||
0f + strokePaint.strokeWidth / 2,
|
|
||||||
0f + strokePaint.strokeWidth / 2,
|
|
||||||
diameter,
|
|
||||||
diameter
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas) {
|
|
||||||
super.onDraw(canvas)
|
|
||||||
|
|
||||||
val totalWeight = items.asSequence().map { it.weight }.sum()
|
|
||||||
var startAngle = -90f
|
|
||||||
|
|
||||||
val shuffledColors = colors.shuffled()
|
|
||||||
items.forEachIndexed { index, (option, weight) ->
|
|
||||||
val sweepAngle = (weight / totalWeight.toFloat()) * 360f
|
|
||||||
fillPaint.color = shuffledColors[index]
|
|
||||||
canvas.drawArc(rect, startAngle, sweepAngle, true, fillPaint)
|
|
||||||
|
|
||||||
drawOptionText(canvas, option, startAngle, sweepAngle)
|
|
||||||
startAngle += sweepAngle
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2, strokePaint)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun drawOptionText(
|
|
||||||
canvas: Canvas,
|
|
||||||
option: String,
|
|
||||||
startAngle: Float,
|
|
||||||
sweepAngle: Float
|
|
||||||
) {
|
|
||||||
val textRadius = rect.width() / 4 // Increase radius to move text outside the circle
|
|
||||||
val angle = Math.toRadians((startAngle + sweepAngle / 2).toDouble()).toFloat()
|
|
||||||
|
|
||||||
// Calculate the text position
|
|
||||||
val x = rect.centerX() + textRadius * cos(angle) + 10
|
|
||||||
val y = rect.centerY() + textRadius * sin(angle)
|
|
||||||
|
|
||||||
// Save the canvas state
|
|
||||||
val saveCount = canvas.save()
|
|
||||||
|
|
||||||
// Rotate the canvas around the text position
|
|
||||||
canvas.rotate(startAngle + sweepAngle / 2, x, y)
|
|
||||||
|
|
||||||
// Draw the text aligned with the segment
|
|
||||||
canvas.drawText(option, x, y, textPaint)
|
|
||||||
|
|
||||||
// Restore the canvas to its previous state
|
|
||||||
canvas.restoreToCount(saveCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAngleForOption(option: String): Float {
|
|
||||||
val totalWeight = items.asSequence().map { it.weight }.sum()
|
|
||||||
var startAngle = 0f
|
|
||||||
|
|
||||||
items.forEach { (currentOption, weight) ->
|
|
||||||
val sweepAngle = (weight / totalWeight.toFloat()) * 360f
|
|
||||||
if (currentOption == option) {
|
|
||||||
// Return the midpoint angle of the segment
|
|
||||||
return (startAngle + sweepAngle / 2)
|
|
||||||
}
|
|
||||||
startAngle += sweepAngle
|
|
||||||
}
|
|
||||||
return 0f
|
|
||||||
}
|
|
||||||
|
|
||||||
fun rotateToOption(option: String, complete: () -> Unit) {
|
|
||||||
val targetAngle = 0 - (getAngleForOption(option) + 360 * 10)
|
|
||||||
|
|
||||||
val rotateAnimation = RotateAnimation(
|
|
||||||
0f, targetAngle,
|
|
||||||
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
|
|
||||||
RotateAnimation.RELATIVE_TO_SELF, 0.5f
|
|
||||||
)
|
|
||||||
rotateAnimation.duration = 2000
|
|
||||||
rotateAnimation.fillAfter = true
|
|
||||||
rotateAnimation.setAnimationListener(object : Animation.AnimationListener {
|
|
||||||
override fun onAnimationStart(animation: Animation?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animation?) {
|
|
||||||
complete()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAnimationRepeat(animation: Animation?) {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
startAnimation(rotateAnimation)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
|
|
||||||
data class SpinRouletteRequest(
|
|
||||||
@SerializedName("roomId") val roomId: Long,
|
|
||||||
@SerializedName("container") val container: String = "aos"
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteItem
|
|
||||||
|
|
||||||
data class CreateOrUpdateRouletteRequest(
|
|
||||||
@SerializedName("can") val can: Int,
|
|
||||||
@SerializedName("isActive") val isActive: Boolean,
|
|
||||||
@SerializedName("items") val items: List<RouletteItem>
|
|
||||||
)
|
|
|
@ -1,38 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Single
|
|
||||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.GetRouletteResponse
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.SpinRouletteRequest
|
|
||||||
import retrofit2.http.Body
|
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.Header
|
|
||||||
import retrofit2.http.POST
|
|
||||||
import retrofit2.http.Path
|
|
||||||
import retrofit2.http.Query
|
|
||||||
|
|
||||||
interface RouletteApi {
|
|
||||||
@POST("/roulette")
|
|
||||||
fun createOrUpdateRoulette(
|
|
||||||
@Body request: CreateOrUpdateRouletteRequest,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
|
|
||||||
@GET("/roulette")
|
|
||||||
fun getRoulette(
|
|
||||||
@Query("creatorId") creatorId: Long,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<GetRouletteResponse>>
|
|
||||||
|
|
||||||
@POST("/roulette/spin")
|
|
||||||
fun spinRoulette(
|
|
||||||
@Body request: SpinRouletteRequest,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<GetRouletteResponse>>
|
|
||||||
|
|
||||||
@POST("/roulette/refund/{id}")
|
|
||||||
fun refundRouletteDonation(
|
|
||||||
@Path("id") id: Long,
|
|
||||||
@Header("Authorization") authHeader: String
|
|
||||||
): Single<ApiResponse<Any>>
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
|
||||||
import kr.co.vividnext.sodalive.databinding.ActivityRouletteConfigBinding
|
|
||||||
|
|
||||||
class RouletteConfigActivity : BaseActivity<ActivityRouletteConfigBinding>(
|
|
||||||
ActivityRouletteConfigBinding::inflate
|
|
||||||
) {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
changeFragment()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setupView() {
|
|
||||||
binding.toolbar.tvBack.text = "룰렛설정"
|
|
||||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun changeFragment(tag: String = "settings") {
|
|
||||||
val fragmentManager = supportFragmentManager
|
|
||||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
|
||||||
|
|
||||||
val currentFragment = fragmentManager.primaryNavigationFragment
|
|
||||||
if (currentFragment != null) {
|
|
||||||
fragmentTransaction.hide(currentFragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
val fragment = RouletteSettingsFragment()
|
|
||||||
fragmentTransaction.add(R.id.container, fragment, tag)
|
|
||||||
fragmentTransaction.setPrimaryNavigationFragment(fragment)
|
|
||||||
fragmentTransaction.setReorderingAllowed(true)
|
|
||||||
fragmentTransaction.commitNow()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
data class RouletteOption(var title: String, var weight: Int, var percentage: String = "50.00")
|
|
|
@ -1,188 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.Service
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.text.InputFilter
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import com.jakewharton.rxbinding4.widget.textChanges
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.R
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseFragment
|
|
||||||
import kr.co.vividnext.sodalive.common.Constants
|
|
||||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
|
||||||
import kr.co.vividnext.sodalive.databinding.FragmentRouletteSettingsBinding
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewDialog
|
|
||||||
import org.koin.android.ext.android.inject
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class RouletteSettingsFragment : BaseFragment<FragmentRouletteSettingsBinding>(
|
|
||||||
FragmentRouletteSettingsBinding::inflate
|
|
||||||
) {
|
|
||||||
private val viewModel: RouletteSettingsViewModel by inject()
|
|
||||||
|
|
||||||
private lateinit var imm: InputMethodManager
|
|
||||||
private lateinit var loadingDialog: LoadingDialog
|
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
setupView()
|
|
||||||
bindData()
|
|
||||||
viewModel.getRoulette()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupView() {
|
|
||||||
loadingDialog = LoadingDialog(requireActivity(), layoutInflater)
|
|
||||||
imm = requireActivity().getSystemService(
|
|
||||||
Service.INPUT_METHOD_SERVICE
|
|
||||||
) as InputMethodManager
|
|
||||||
|
|
||||||
binding.etSetPrice.filters = arrayOf(InputFilter { source, start, end, _, _, _ ->
|
|
||||||
// Only allow numeric input
|
|
||||||
for (i in start until end) {
|
|
||||||
if (!Character.isDigit(source[i])) {
|
|
||||||
return@InputFilter ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
null
|
|
||||||
})
|
|
||||||
|
|
||||||
binding.ivRouletteIsActive.setOnClickListener { viewModel.toggleIsActive() }
|
|
||||||
binding.ivAddOption.setOnClickListener { addOption() }
|
|
||||||
|
|
||||||
binding.tvPreview.setOnClickListener {
|
|
||||||
handler.postDelayed({
|
|
||||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
|
||||||
}, 100)
|
|
||||||
viewModel.onClickPreview()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvSave.setOnClickListener { _ ->
|
|
||||||
handler.postDelayed({
|
|
||||||
imm.hideSoftInputFromWindow(view?.windowToken, 0)
|
|
||||||
}, 100)
|
|
||||||
viewModel.createOrUpdateRoulette {
|
|
||||||
val resultIntent = Intent().apply { putExtra(Constants.EXTRA_RESULT_ROULETTE, it) }
|
|
||||||
requireActivity().setResult(Activity.RESULT_OK, resultIntent)
|
|
||||||
requireActivity().finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindData() {
|
|
||||||
viewModel.isActiveLiveData.observe(viewLifecycleOwner) {
|
|
||||||
binding.ivRouletteIsActive.setImageResource(
|
|
||||||
if (it) R.drawable.btn_toggle_on_big else R.drawable.btn_toggle_off_big
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.optionsLiveData.observe(viewLifecycleOwner) { updateOptionUi(it) }
|
|
||||||
|
|
||||||
viewModel.toastLiveData.observe(viewLifecycleOwner) { it?.let { showToast(it) } }
|
|
||||||
|
|
||||||
viewModel.canLiveData.observe(viewLifecycleOwner) {
|
|
||||||
if (it > 0) {
|
|
||||||
binding.etSetPrice.setText("$it")
|
|
||||||
} else {
|
|
||||||
binding.etSetPrice.setText("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.isLoading.observe(viewLifecycleOwner) {
|
|
||||||
if (it) {
|
|
||||||
loadingDialog.show(screenWidth)
|
|
||||||
} else {
|
|
||||||
loadingDialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.roulettePreviewLiveData.observe(viewLifecycleOwner) {
|
|
||||||
RoulettePreviewDialog(
|
|
||||||
activity = requireActivity(),
|
|
||||||
preview = it,
|
|
||||||
title = "룰렛 미리보기",
|
|
||||||
layoutInflater = layoutInflater
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
binding.etSetPrice.textChanges().skip(1)
|
|
||||||
.debounce(100, TimeUnit.MILLISECONDS)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.subscribe {
|
|
||||||
if (it.trim().isNotEmpty()) {
|
|
||||||
viewModel.can = it.toString().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addOption() {
|
|
||||||
val newOption = RouletteOption("", 1)
|
|
||||||
viewModel.addOption(newOption)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateOptionUi(options: List<RouletteOption>) {
|
|
||||||
binding.llRouletteOptionContainer.removeAllViews()
|
|
||||||
options.forEachIndexed { index, option ->
|
|
||||||
binding.llRouletteOptionContainer.addView(createOptionView(index, option))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun createOptionView(index: Int, option: RouletteOption): View {
|
|
||||||
val optionView = LayoutInflater
|
|
||||||
.from(context)
|
|
||||||
.inflate(
|
|
||||||
R.layout.layout_roulette_option,
|
|
||||||
binding.llRouletteOptionContainer,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
val etOption = optionView.findViewById<EditText>(R.id.et_option)
|
|
||||||
val tvOptionTitle = optionView.findViewById<TextView>(R.id.tv_option_title)
|
|
||||||
val tvPercentage = optionView.findViewById<TextView>(R.id.tv_option_percentage)
|
|
||||||
val ivMinus = optionView.findViewById<ImageView>(R.id.iv_minus)
|
|
||||||
val ivPlus = optionView.findViewById<ImageView>(R.id.iv_plus)
|
|
||||||
val tvDelete = optionView.findViewById<TextView>(R.id.tv_delete)
|
|
||||||
|
|
||||||
etOption.setText(option.title)
|
|
||||||
tvOptionTitle.text = "옵션 ${index + 1}"
|
|
||||||
tvPercentage.text = "${option.percentage}%"
|
|
||||||
ivMinus.setOnClickListener { viewModel.subtractWeight(index) }
|
|
||||||
ivPlus.setOnClickListener { viewModel.plusWeight(index) }
|
|
||||||
|
|
||||||
if (index == 0 || index == 1) {
|
|
||||||
tvDelete.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
tvDelete.visibility = View.VISIBLE
|
|
||||||
tvDelete.setOnClickListener { viewModel.deleteOption(index) }
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
etOption.textChanges().skip(1)
|
|
||||||
.debounce(100, TimeUnit.MILLISECONDS)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.subscribe {
|
|
||||||
viewModel.inputOption(index, it.toString())
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return optionView
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,234 +0,0 @@
|
||||||
package kr.co.vividnext.sodalive.live.roulette.config
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
|
||||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteItem
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreview
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RoulettePreviewItem
|
|
||||||
import kr.co.vividnext.sodalive.live.roulette.RouletteRepository
|
|
||||||
import kotlin.math.floor
|
|
||||||
|
|
||||||
class RouletteSettingsViewModel(private val repository: RouletteRepository) : BaseViewModel() {
|
|
||||||
|
|
||||||
private var _isLoading = MutableLiveData(false)
|
|
||||||
val isLoading: LiveData<Boolean>
|
|
||||||
get() = _isLoading
|
|
||||||
|
|
||||||
private val _toastLiveData = MutableLiveData<String?>()
|
|
||||||
val toastLiveData: LiveData<String?>
|
|
||||||
get() = _toastLiveData
|
|
||||||
|
|
||||||
private val _optionsLiveData = MutableLiveData<List<RouletteOption>>(listOf())
|
|
||||||
val optionsLiveData: LiveData<List<RouletteOption>>
|
|
||||||
get() = _optionsLiveData
|
|
||||||
|
|
||||||
private val _isActiveLiveData = MutableLiveData(false)
|
|
||||||
val isActiveLiveData: LiveData<Boolean>
|
|
||||||
get() = _isActiveLiveData
|
|
||||||
|
|
||||||
private val _canLiveData = MutableLiveData(0)
|
|
||||||
val canLiveData: LiveData<Int>
|
|
||||||
get() = _canLiveData
|
|
||||||
|
|
||||||
private val _roulettePreviewLiveData = MutableLiveData<RoulettePreview>()
|
|
||||||
val roulettePreviewLiveData: LiveData<RoulettePreview>
|
|
||||||
get() = _roulettePreviewLiveData
|
|
||||||
|
|
||||||
private val options = mutableListOf<RouletteOption>()
|
|
||||||
var can = 0
|
|
||||||
var isActive = false
|
|
||||||
|
|
||||||
fun plusWeight(optionIndex: Int) {
|
|
||||||
val currentOption = options[optionIndex]
|
|
||||||
options[optionIndex] = currentOption.copy(weight = currentOption.weight + 1)
|
|
||||||
recalculatePercentages(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun subtractWeight(optionIndex: Int) {
|
|
||||||
if (options[optionIndex].weight > 1) {
|
|
||||||
val currentOption = options[optionIndex]
|
|
||||||
options[optionIndex] = currentOption.copy(weight = currentOption.weight - 1)
|
|
||||||
recalculatePercentages(options)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addOption(newOption: RouletteOption) {
|
|
||||||
if (options.size >= 10) return
|
|
||||||
|
|
||||||
options.add(newOption)
|
|
||||||
recalculatePercentages(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteOption(index: Int) {
|
|
||||||
val updatedOptions = options.filterIndexed { currentIndex, _ -> currentIndex != index }
|
|
||||||
removeAllAndAddOptions(updatedOptions)
|
|
||||||
recalculatePercentages(updatedOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun inputOption(optionIndex: Int, title: String) {
|
|
||||||
val currentOption = options[optionIndex]
|
|
||||||
options[optionIndex] = currentOption.copy(title = title)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun recalculatePercentages(options: List<RouletteOption>) {
|
|
||||||
val totalWeight = options.sumOf { it.weight }
|
|
||||||
val updatedOptions = options.asSequence().map { option ->
|
|
||||||
val percent = floor(option.weight.toDouble() / totalWeight * 10000) / 100
|
|
||||||
option.copy(percentage = String.format("%.2f", percent))
|
|
||||||
}.toList()
|
|
||||||
|
|
||||||
removeAllAndAddOptions(updatedOptions)
|
|
||||||
_optionsLiveData.value = updatedOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toggleIsActive() {
|
|
||||||
isActive = !isActive
|
|
||||||
_isActiveLiveData.postValue(isActive)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onClickPreview() {
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
val items = mutableListOf<RoulettePreviewItem>()
|
|
||||||
for (option in options) {
|
|
||||||
if (option.title.trim().isEmpty()) {
|
|
||||||
_toastLiveData.value = "옵션은 빈칸을 할 수 없습니다."
|
|
||||||
_isLoading.value = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
items.add(RoulettePreviewItem(option.title, "${option.percentage}%"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_roulettePreviewLiveData.postValue(RoulettePreview(can, items))
|
|
||||||
_isLoading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createOrUpdateRoulette(onSuccess: (Boolean) -> Unit) {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
val items = mutableListOf<RouletteItem>()
|
|
||||||
for (option in options) {
|
|
||||||
if (option.title.trim().isEmpty()) {
|
|
||||||
_toastLiveData.value = "옵션은 빈칸을 할 수 없습니다."
|
|
||||||
_isLoading.value = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
items.add(RouletteItem(title = option.title, weight = option.weight))
|
|
||||||
}
|
|
||||||
|
|
||||||
val request = CreateOrUpdateRouletteRequest(
|
|
||||||
can = can,
|
|
||||||
isActive = isActive,
|
|
||||||
items = items
|
|
||||||
)
|
|
||||||
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.createOrUpdateRoulette(
|
|
||||||
request = request,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
if (it.success && it.data != null && it.data is Boolean) {
|
|
||||||
val message = if (it.data) {
|
|
||||||
"룰렛을 활성화 했습니다."
|
|
||||||
} else {
|
|
||||||
"룰렛을 비활성화 했습니다."
|
|
||||||
}
|
|
||||||
_toastLiveData.postValue(message)
|
|
||||||
onSuccess(it.data)
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getRoulette() {
|
|
||||||
if (!_isLoading.value!!) {
|
|
||||||
_isLoading.value = true
|
|
||||||
compositeDisposable.add(
|
|
||||||
repository.getRoulette(
|
|
||||||
creatorId = SharedPreferenceManager.userId,
|
|
||||||
token = "Bearer ${SharedPreferenceManager.token}"
|
|
||||||
)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
{
|
|
||||||
if (it.success) {
|
|
||||||
val data = it.data
|
|
||||||
|
|
||||||
if (data != null && data.items.isNotEmpty()) {
|
|
||||||
_isActiveLiveData.value = data.isActive
|
|
||||||
_canLiveData.value = data.can
|
|
||||||
|
|
||||||
isActive = data.isActive
|
|
||||||
can = data.can
|
|
||||||
|
|
||||||
val options = data.items.asSequence().map { item ->
|
|
||||||
RouletteOption(title = item.title, weight = item.weight)
|
|
||||||
}.toList()
|
|
||||||
removeAllAndAddOptions(options = options)
|
|
||||||
recalculatePercentages(options)
|
|
||||||
} else {
|
|
||||||
_isActiveLiveData.value = false
|
|
||||||
_canLiveData.value = 0
|
|
||||||
|
|
||||||
isActive = false
|
|
||||||
can = 0
|
|
||||||
|
|
||||||
options.add(RouletteOption(title = "", weight = 1))
|
|
||||||
options.add(RouletteOption(title = "", weight = 1))
|
|
||||||
recalculatePercentages(options)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.message != null) {
|
|
||||||
_toastLiveData.postValue(it.message)
|
|
||||||
} else {
|
|
||||||
_toastLiveData.postValue(
|
|
||||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_isLoading.value = false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
_isLoading.value = false
|
|
||||||
it.message?.let { message -> Logger.e(message) }
|
|
||||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeAllAndAddOptions(options: List<RouletteOption>) {
|
|
||||||
this.options.clear()
|
|
||||||
this.options.addAll(options)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,6 +19,8 @@ import com.google.firebase.messaging.FirebaseMessaging
|
||||||
import com.gun0912.tedpermission.PermissionListener
|
import com.gun0912.tedpermission.PermissionListener
|
||||||
import com.gun0912.tedpermission.normal.TedPermission
|
import com.gun0912.tedpermission.normal.TedPermission
|
||||||
import com.orhanobut.logger.Logger
|
import com.orhanobut.logger.Logger
|
||||||
|
import kr.co.pointclick.sdk.offerwall.core.PointClickAd
|
||||||
|
import kr.co.pointclick.sdk.offerwall.core.events.PackageReceiver
|
||||||
import kr.co.vividnext.sodalive.R
|
import kr.co.vividnext.sodalive.R
|
||||||
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
|
||||||
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
|
||||||
|
@ -50,9 +52,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private val audioContentReceiver = AudioContentReceiver()
|
private val audioContentReceiver = AudioContentReceiver()
|
||||||
|
|
||||||
|
private var packageReceiver: PackageReceiver? = null
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
executeDeeplink(intent)
|
executeDeeplink()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -63,17 +67,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
getMemberInfo()
|
getMemberInfo()
|
||||||
getEventPopup()
|
getEventPopup()
|
||||||
|
|
||||||
handler.postDelayed({ executeDeeplink(intent) }, 500)
|
initPointClick()
|
||||||
|
handler.postDelayed({ executeDeeplink() }, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val intentFilter = IntentFilter(Constants.ACTION_MAIN_AUDIO_CONTENT_RECEIVER)
|
val intentFilter = IntentFilter(Constants.ACTION_MAIN_AUDIO_CONTENT_RECEIVER)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
registerReceiver(audioContentReceiver, intentFilter)
|
||||||
registerReceiver(audioContentReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED)
|
|
||||||
} else {
|
|
||||||
registerReceiver(audioContentReceiver, intentFilter)
|
|
||||||
}
|
|
||||||
|
|
||||||
startService(
|
startService(
|
||||||
Intent(this, AudioContentPlayService::class.java).apply {
|
Intent(this, AudioContentPlayService::class.java).apply {
|
||||||
|
@ -87,6 +88,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
if (packageReceiver != null) {
|
||||||
|
applicationContext.unregisterReceiver(packageReceiver)
|
||||||
|
}
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun setupView() {
|
override fun setupView() {
|
||||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||||
liveFragment = LiveFragment()
|
liveFragment = LiveFragment()
|
||||||
|
@ -105,7 +113,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
setupBottomTabLayout()
|
setupBottomTabLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun executeDeeplink(intent: Intent) {
|
private fun executeDeeplink() {
|
||||||
val bundle = intent.getBundleExtra(Constants.EXTRA_DATA)
|
val bundle = intent.getBundleExtra(Constants.EXTRA_DATA)
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -366,6 +374,25 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initPointClick() {
|
||||||
|
try {
|
||||||
|
val intentFilter = IntentFilter()
|
||||||
|
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||||
|
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||||
|
intentFilter.addDataScheme("package");
|
||||||
|
|
||||||
|
packageReceiver = PackageReceiver()
|
||||||
|
applicationContext.registerReceiver(packageReceiver, intentFilter)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
PointClickAd.init(
|
||||||
|
"fc07cfb1-ef16-455c-bdad-22aa9e8fd78c",
|
||||||
|
SharedPreferenceManager.userId.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
inner class AudioContentReceiver : BroadcastReceiver() {
|
inner class AudioContentReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
val contentId = intent?.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0)
|
val contentId = intent?.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0)
|
||||||
|
|
|
@ -187,36 +187,36 @@ class TextMessageFragment : BaseFragment<FragmentTextMessageBinding>(
|
||||||
when (it) {
|
when (it) {
|
||||||
MessageBox.SENT -> {
|
MessageBox.SENT -> {
|
||||||
binding.tvSent.setBackgroundResource(
|
binding.tvSent.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvSent.setTextColor(
|
binding.tvSent.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBox.RECEIVE -> {
|
MessageBox.RECEIVE -> {
|
||||||
binding.tvReceive.setBackgroundResource(
|
binding.tvReceive.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvReceive.setTextColor(
|
binding.tvReceive.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBox.KEEP -> {
|
MessageBox.KEEP -> {
|
||||||
binding.tvKeep.setBackgroundResource(
|
binding.tvKeep.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvKeep.setTextColor(
|
binding.tvKeep.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ class TextMessageWriteActivity : BaseActivity<ActivityTextMessageWriteBinding>(
|
||||||
private fun bindData() {
|
private fun bindData() {
|
||||||
compositeDisposable.add(
|
compositeDisposable.add(
|
||||||
binding.etMessage.textChanges().skip(1)
|
binding.etMessage.textChanges().skip(1)
|
||||||
.debounce(100, TimeUnit.MILLISECONDS)
|
.debounce(500, TimeUnit.MILLISECONDS)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.subscribe {
|
.subscribe {
|
||||||
|
|
|
@ -313,36 +313,36 @@ class VoiceMessageFragment : BaseFragment<FragmentVoiceMessageBinding>(
|
||||||
when (it) {
|
when (it) {
|
||||||
MessageBox.SENT -> {
|
MessageBox.SENT -> {
|
||||||
binding.tvSent.setBackgroundResource(
|
binding.tvSent.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvSent.setTextColor(
|
binding.tvSent.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBox.RECEIVE -> {
|
MessageBox.RECEIVE -> {
|
||||||
binding.tvReceive.setBackgroundResource(
|
binding.tvReceive.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvReceive.setTextColor(
|
binding.tvReceive.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBox.KEEP -> {
|
MessageBox.KEEP -> {
|
||||||
binding.tvKeep.setBackgroundResource(
|
binding.tvKeep.setBackgroundResource(
|
||||||
R.drawable.bg_round_corner_16_7_transparent_3bb9f1
|
R.drawable.bg_round_corner_16_7_transparent_9970ff
|
||||||
)
|
)
|
||||||
binding.tvKeep.setTextColor(
|
binding.tvKeep.setTextColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
R.color.color_3bb9f1
|
R.color.color_9970ff
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue