diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 66df27f..aac1411 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -143,7 +143,7 @@
-
+
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt
index 454680a..5294857 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt
@@ -59,6 +59,8 @@ import kr.co.vividnext.sodalive.live.room.create.LiveRoomCreateViewModel
import kr.co.vividnext.sodalive.live.room.detail.LiveRoomDetailViewModel
import kr.co.vividnext.sodalive.live.room.donation.LiveRoomDonationMessageViewModel
import kr.co.vividnext.sodalive.live.room.menu.MenuApi
+import kr.co.vividnext.sodalive.live.room.menu.MenuConfigRepository
+import kr.co.vividnext.sodalive.live.room.menu.MenuConfigViewModel
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.update.LiveRoomEditViewModel
@@ -260,6 +262,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
viewModel { AlarmListViewModel(get()) }
viewModel { BlockMemberViewModel(get()) }
viewModel { UserViewModel(get(), get()) }
+ viewModel { MenuConfigViewModel(get()) }
}
private val repositoryModule = module {
@@ -287,6 +290,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
factory { RouletteRepository(get()) }
factory { CreatorCommunityRepository(get()) }
factory { AlarmListRepository(get()) }
+ factory { MenuConfigRepository(get()) }
}
private val moduleList = listOf(
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt
index ed346ed..bc01df3 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt
@@ -52,7 +52,7 @@ 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.live.LiveViewModel
-import kr.co.vividnext.sodalive.live.menu.MenuConfigActivity
+import kr.co.vividnext.sodalive.live.room.menu.MenuConfigActivity
import kr.co.vividnext.sodalive.live.reservation.complete.LiveReservationCompleteActivity
import kr.co.vividnext.sodalive.live.room.LiveRoomActivity
import kr.co.vividnext.sodalive.live.room.dialog.LivePaymentDialog
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/menu/MenuConfigActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/menu/MenuConfigActivity.kt
deleted file mode 100644
index df1ec69..0000000
--- a/app/src/main/java/kr/co/vividnext/sodalive/live/menu/MenuConfigActivity.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package kr.co.vividnext.sodalive.live.menu
-
-import kr.co.vividnext.sodalive.base.BaseActivity
-import kr.co.vividnext.sodalive.databinding.ActivityMenuConfigBinding
-
-class MenuConfigActivity : BaseActivity(
- ActivityMenuConfigBinding::inflate
-) {
- override fun setupView() {
- }
-}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/GetMenuPresetResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/GetMenuPresetResponse.kt
index 50dbc0c..5ab0732 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/GetMenuPresetResponse.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/GetMenuPresetResponse.kt
@@ -6,6 +6,6 @@ import com.google.gson.annotations.SerializedName
@Keep
data class GetMenuPresetResponse(
@SerializedName("id") val id: Long,
- @SerializedName("menu") val menu: String,
+ @SerializedName("menu") var menu: String,
@SerializedName("isActive") val isActive: Boolean
)
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuApi.kt
index dffa1d5..214c561 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuApi.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuApi.kt
@@ -2,8 +2,10 @@ package kr.co.vividnext.sodalive.live.room.menu
import io.reactivex.rxjava3.core.Single
import kr.co.vividnext.sodalive.common.ApiResponse
+import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
+import retrofit2.http.POST
import retrofit2.http.Query
interface MenuApi {
@@ -12,4 +14,10 @@ interface MenuApi {
@Query("creatorId") creatorId: Long,
@Header("Authorization") authHeader: String
): Single>>
+
+ @POST("/live/room/menu")
+ fun saveMenu(
+ @Body request: UpdateLiveMenuRequest,
+ @Header("Authorization") authHeader: String
+ ): Single>
}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigActivity.kt
new file mode 100644
index 0000000..d3e7c47
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigActivity.kt
@@ -0,0 +1,186 @@
+package kr.co.vividnext.sodalive.live.room.menu
+
+import android.app.Service
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.View
+import android.view.inputmethod.InputMethodManager
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+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.base.SodaDialog
+import kr.co.vividnext.sodalive.common.LoadingDialog
+import kr.co.vividnext.sodalive.databinding.ActivityMenuConfigBinding
+import kr.co.vividnext.sodalive.live.room.create.LiveRoomCreateViewModel
+import org.koin.android.ext.android.inject
+import java.util.concurrent.TimeUnit
+
+class MenuConfigActivity : BaseActivity(
+ ActivityMenuConfigBinding::inflate
+) {
+ private val viewModel: MenuConfigViewModel by inject()
+
+ private lateinit var imm: InputMethodManager
+ private lateinit var loadingDialog: LoadingDialog
+
+ private val handler = Handler(Looper.getMainLooper())
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ bindData()
+ viewModel.getAllMenuPreset()
+ }
+
+ override fun setupView() {
+ binding.toolbar.tvBack.text = "메뉴 설정"
+ binding.toolbar.tvBack.setOnClickListener { finish() }
+
+ loadingDialog = LoadingDialog(this, layoutInflater)
+ imm = getSystemService(
+ Service.INPUT_METHOD_SERVICE
+ ) as InputMethodManager
+
+ binding.tvSave.setOnClickListener {
+ handler.postDelayed({
+ imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)
+ }, 100)
+
+ // 저장 액션
+ viewModel.saveMenu()
+ }
+
+ binding.llSelectMenu1.setOnClickListener {
+ viewModel.selectMenuPreset(LiveRoomCreateViewModel.SelectedMenu.MENU_1)
+ }
+
+ binding.llSelectMenu2.setOnClickListener {
+ viewModel.selectMenuPreset(LiveRoomCreateViewModel.SelectedMenu.MENU_2)
+ }
+
+ binding.llSelectMenu3.setOnClickListener {
+ viewModel.selectMenuPreset(LiveRoomCreateViewModel.SelectedMenu.MENU_3)
+ }
+ }
+
+ private fun bindData() {
+ viewModel.toastLiveData.observe(this) { it?.let { showToast(it) } }
+ viewModel.isLoading.observe(this) {
+ if (it) {
+ loadingDialog.show(screenWidth)
+ } else {
+ loadingDialog.dismiss()
+ }
+ }
+
+ viewModel.selectedMenuLiveData.observe(this) {
+ deselectAllMenuPreset()
+
+ when (it) {
+ LiveRoomCreateViewModel.SelectedMenu.MENU_2 -> selectMenuPresetButton(
+ binding.ivSelectMenu2,
+ binding.llSelectMenu2,
+ binding.tvSelectMenu2
+ )
+
+ LiveRoomCreateViewModel.SelectedMenu.MENU_3 -> selectMenuPresetButton(
+ binding.ivSelectMenu3,
+ binding.llSelectMenu3,
+ binding.tvSelectMenu3
+ )
+
+ else -> selectMenuPresetButton(
+ binding.ivSelectMenu1,
+ binding.llSelectMenu1,
+ binding.tvSelectMenu1
+ )
+ }
+ }
+
+ viewModel.selectedMenuTextLiveData.observe(this) {
+ binding.etMenu.setText(it)
+ }
+
+ compositeDisposable.add(
+ binding.etMenu.textChanges().skip(1)
+ .debounce(100, TimeUnit.MILLISECONDS)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribeOn(Schedulers.io())
+ .subscribe {
+ viewModel.menuText = it.toString()
+ }
+ )
+ }
+
+ private fun deselectAllMenuPreset() {
+ binding.ivSelectMenu1.visibility = View.GONE
+ binding.ivSelectMenu2.visibility = View.GONE
+ binding.ivSelectMenu3.visibility = View.GONE
+
+ binding.llSelectMenu1.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
+ binding.tvSelectMenu1.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_3bb9f1
+ )
+ )
+
+ if (viewModel.countMenu() > 0) {
+ binding.llSelectMenu2.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
+ binding.tvSelectMenu2.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_3bb9f1
+ )
+ )
+ } else {
+ binding.llSelectMenu2.setBackgroundResource(R.drawable.bg_round_corner_6_7_777777)
+ binding.tvSelectMenu2.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_555555
+ )
+ )
+ }
+
+ if (viewModel.countMenu() > 1) {
+ binding.llSelectMenu3.setBackgroundResource(R.drawable.bg_round_corner_6_7_13181b)
+ binding.tvSelectMenu3.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_3bb9f1
+ )
+ )
+ } else {
+ binding.llSelectMenu3.setBackgroundResource(R.drawable.bg_round_corner_6_7_777777)
+ binding.tvSelectMenu3.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_555555
+ )
+ )
+ }
+ }
+
+ private fun selectMenuPresetButton(
+ ivSelectMenuPreset: ImageView,
+ llSelectMenuPreset: LinearLayout,
+ tvSelectMenuPreset: TextView
+ ) {
+ ivSelectMenuPreset.visibility = View.VISIBLE
+ llSelectMenuPreset.setBackgroundResource(R.drawable.bg_round_corner_6_7_3bb9f1)
+ tvSelectMenuPreset.setTextColor(
+ ContextCompat.getColor(
+ applicationContext,
+ R.color.color_eeeeee
+ )
+ )
+ }
+}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigRepository.kt
new file mode 100644
index 0000000..869c818
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigRepository.kt
@@ -0,0 +1,17 @@
+package kr.co.vividnext.sodalive.live.room.menu
+
+class MenuConfigRepository(private val api: MenuApi) {
+ fun getAllMenu(creatorId: Long, token: String) = api.getAllMenu(
+ creatorId = creatorId,
+ authHeader = token
+ )
+
+ fun saveMenu(menuId: Long, menu: String, token: String) = api.saveMenu(
+ request = UpdateLiveMenuRequest(
+ id = menuId,
+ menu = menu,
+ isActive = false
+ ),
+ authHeader = token
+ )
+}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigViewModel.kt
new file mode 100644
index 0000000..66973c2
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/MenuConfigViewModel.kt
@@ -0,0 +1,147 @@
+package kr.co.vividnext.sodalive.live.room.menu
+
+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.room.create.LiveRoomCreateViewModel
+
+class MenuConfigViewModel(private val repository: MenuConfigRepository) : BaseViewModel() {
+
+ private var _isLoading = MutableLiveData(false)
+ val isLoading: LiveData
+ get() = _isLoading
+
+ private val _toastLiveData = MutableLiveData()
+ val toastLiveData: LiveData
+ get() = _toastLiveData
+
+ private val _selectedMenuLiveData = MutableLiveData()
+ val selectedMenuLiveData: LiveData
+ get() = _selectedMenuLiveData
+
+ private val _selectedMenuTextLiveData = MutableLiveData("")
+ val selectedMenuTextLiveData: LiveData
+ get() = _selectedMenuTextLiveData
+
+ private var menuId = 0L
+ private val menuList = mutableListOf()
+
+ var menuText: String = ""
+
+ fun getAllMenuPreset(selectedMenu: LiveRoomCreateViewModel.SelectedMenu = LiveRoomCreateViewModel.SelectedMenu.MENU_1) {
+ _isLoading.value = true
+
+ compositeDisposable.add(
+ repository.getAllMenu(
+ creatorId = SharedPreferenceManager.userId,
+ token = "Bearer ${SharedPreferenceManager.token}"
+ )
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ {
+ if (it.success) {
+ val data = it.data ?: listOf()
+ menuList.clear()
+ menuList.addAll(data)
+ selectMenuPreset(selectedMenu)
+ } 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 selectMenuPreset(selectedMenuPreset: LiveRoomCreateViewModel.SelectedMenu) {
+ if (
+ menuList.isEmpty() &&
+ (
+ selectedMenuPreset == LiveRoomCreateViewModel.SelectedMenu.MENU_2 ||
+ selectedMenuPreset == LiveRoomCreateViewModel.SelectedMenu.MENU_3
+ )
+ ) {
+ _toastLiveData.value = "메뉴 1을 먼저 설정하세요"
+ return
+ }
+
+ if (menuList.size == 1 && selectedMenuPreset == LiveRoomCreateViewModel.SelectedMenu.MENU_3) {
+ _toastLiveData.value = "메뉴 1과 메뉴 2를 먼저 설정하세요"
+ return
+ }
+
+ if (_selectedMenuLiveData.value != selectedMenuPreset) {
+ _selectedMenuLiveData.value = selectedMenuPreset
+
+ if (menuList.size > selectedMenuPreset.ordinal) {
+ val menuPreset = menuList[selectedMenuPreset.ordinal]
+
+ menuText = menuPreset.menu
+ menuId = menuPreset.id
+ _selectedMenuTextLiveData.value = menuPreset.menu
+ } else {
+ menuText = ""
+ menuId = 0
+ _selectedMenuTextLiveData.value = ""
+ }
+ }
+ }
+
+ fun saveMenu() {
+ if (menuText == _selectedMenuTextLiveData.value) {
+ _toastLiveData.postValue("저장되었습니다.")
+ return
+ }
+
+ _isLoading.value = true
+ compositeDisposable.add(
+ repository.saveMenu(
+ menuId = menuId,
+ menu = menuText,
+ token = "Bearer ${SharedPreferenceManager.token}"
+ )
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ {
+ if (it.success) {
+ _toastLiveData.postValue("저장되었습니다.")
+ getAllMenuPreset(selectedMenu = _selectedMenuLiveData.value!!)
+ } 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 countMenu() = menuList.size
+}
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt
new file mode 100644
index 0000000..853792d
--- /dev/null
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt
@@ -0,0 +1,14 @@
+package kr.co.vividnext.sodalive.live.room.menu
+
+import androidx.annotation.Keep
+import com.google.gson.annotations.SerializedName
+
+@Keep
+data class UpdateLiveMenuRequest(
+ @SerializedName("id")
+ val id: Long,
+ @SerializedName("menu")
+ val menu: String,
+ @SerializedName("isActive")
+ val isActive: Boolean = false
+)
diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/config/RouletteConfigActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/config/RouletteConfigActivity.kt
index 05e4221..914ca97 100644
--- a/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/config/RouletteConfigActivity.kt
+++ b/app/src/main/java/kr/co/vividnext/sodalive/live/roulette/config/RouletteConfigActivity.kt
@@ -59,7 +59,7 @@ class RouletteConfigActivity : BaseActivity(
}
override fun setupView() {
- binding.tvBack.text = "룰렛설정"
+ binding.tvBack.text = "룰렛 설정"
binding.tvBack.setOnClickListener { finish() }
loadingDialog = LoadingDialog(this, layoutInflater)
diff --git a/app/src/main/res/layout/activity_menu_config.xml b/app/src/main/res/layout/activity_menu_config.xml
index c6a1517..d95c521 100644
--- a/app/src/main/res/layout/activity_menu_config.xml
+++ b/app/src/main/res/layout/activity_menu_config.xml
@@ -1,17 +1,151 @@
+ android:layout_height="match_parent"
+ android:background="@color/black">
-
+
+
+ app:layout_constraintTop_toBottomOf="@+id/toolbar">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+