설정 페이지 추가
This commit is contained in:
parent
3ef78b64ad
commit
cc8fab76b0
|
@ -48,6 +48,13 @@
|
|||
<activity android:name=".message.text.TextMessageWriteActivity" />
|
||||
<activity android:name=".message.text.TextMessageDetailActivity" />
|
||||
<activity android:name=".message.SelectMessageRecipientActivity" />
|
||||
<activity android:name=".settings.SettingsActivity" />
|
||||
<activity android:name=".settings.signout.SignOutActivity" />
|
||||
<activity android:name=".settings.notice.NoticeActivity" />
|
||||
<activity android:name=".settings.notice.NoticeDetailActivity" />
|
||||
<activity android:name=".settings.event.EventActivity" />
|
||||
<activity android:name=".settings.event.EventDetailActivity" />
|
||||
<activity android:name=".settings.notification.NotificationSettingsActivity" />
|
||||
|
||||
<activity
|
||||
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
||||
|
|
|
@ -15,6 +15,8 @@ object Constants {
|
|||
const val EXTRA_CAN = "extra_can"
|
||||
const val EXTRA_DATA = "extra_data"
|
||||
const val EXTRA_TERMS = "extra_terms"
|
||||
const val EXTRA_EVENT = "extra_event"
|
||||
const val EXTRA_NOTICE = "extra_notice"
|
||||
const val EXTRA_ROOM_ID = "extra_room_id"
|
||||
const val EXTRA_USER_ID = "extra_user_id"
|
||||
const val EXTRA_NICKNAME = "extra_nickname"
|
||||
|
|
|
@ -40,8 +40,15 @@ import kr.co.vividnext.sodalive.mypage.can.status.CanStatusViewModel
|
|||
import kr.co.vividnext.sodalive.network.TokenAuthenticator
|
||||
import kr.co.vividnext.sodalive.report.ReportApi
|
||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
||||
import kr.co.vividnext.sodalive.settings.SettingsViewModel
|
||||
import kr.co.vividnext.sodalive.settings.event.EventApi
|
||||
import kr.co.vividnext.sodalive.settings.event.EventRepository
|
||||
import kr.co.vividnext.sodalive.settings.event.EventViewModel
|
||||
import kr.co.vividnext.sodalive.settings.notice.NoticeApi
|
||||
import kr.co.vividnext.sodalive.settings.notice.NoticeRepository
|
||||
import kr.co.vividnext.sodalive.settings.notice.NoticeViewModel
|
||||
import kr.co.vividnext.sodalive.settings.notification.NotificationSettingsViewModel
|
||||
import kr.co.vividnext.sodalive.settings.signout.SignOutViewModel
|
||||
import kr.co.vividnext.sodalive.settings.terms.TermsApi
|
||||
import kr.co.vividnext.sodalive.settings.terms.TermsRepository
|
||||
import kr.co.vividnext.sodalive.settings.terms.TermsViewModel
|
||||
|
@ -102,6 +109,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
single { ApiBuilder().build(get(), LiveRecommendApi::class.java) }
|
||||
single { ApiBuilder().build(get(), ExplorerApi::class.java) }
|
||||
single { ApiBuilder().build(get(), MessageApi::class.java) }
|
||||
single { ApiBuilder().build(get(), NoticeApi::class.java) }
|
||||
}
|
||||
|
||||
private val viewModelModule = module {
|
||||
|
@ -129,6 +137,11 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
viewModel { VoiceMessageViewModel(get()) }
|
||||
viewModel { VoiceMessageWriteViewModel(get()) }
|
||||
viewModel { SelectMessageRecipientViewModel(get(), get()) }
|
||||
viewModel { SignOutViewModel(get()) }
|
||||
viewModel { NoticeViewModel(get()) }
|
||||
viewModel { EventViewModel(get()) }
|
||||
viewModel { NotificationSettingsViewModel(get()) }
|
||||
viewModel { SettingsViewModel(get()) }
|
||||
}
|
||||
|
||||
private val repositoryModule = module {
|
||||
|
@ -143,6 +156,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||
factory { ReportRepository(get()) }
|
||||
factory { ExplorerRepository(get()) }
|
||||
factory { MessageRepository(get()) }
|
||||
factory { NoticeRepository(get()) }
|
||||
}
|
||||
|
||||
private val moduleList = listOf(
|
||||
|
|
|
@ -21,6 +21,7 @@ import kr.co.vividnext.sodalive.mypage.auth.AuthVerifyRequest
|
|||
import kr.co.vividnext.sodalive.mypage.auth.BootpayResponse
|
||||
import kr.co.vividnext.sodalive.mypage.can.charge.CanChargeActivity
|
||||
import kr.co.vividnext.sodalive.mypage.can.status.CanStatusActivity
|
||||
import kr.co.vividnext.sodalive.settings.SettingsActivity
|
||||
import kr.co.vividnext.sodalive.settings.notification.MemberRole
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
|
@ -44,7 +45,14 @@ class MyPageFragment : BaseFragment<FragmentMyBinding>(FragmentMyBinding::inflat
|
|||
}
|
||||
|
||||
private fun setupView() {
|
||||
binding.ivSettings.setOnClickListener {}
|
||||
binding.ivSettings.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(
|
||||
requireActivity(),
|
||||
SettingsActivity::class.java
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
binding.ivEdit.setOnClickListener {}
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
package kr.co.vividnext.sodalive.settings
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
||||
import kr.co.vividnext.sodalive.BuildConfig
|
||||
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.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.databinding.ActivitySettingsBinding
|
||||
import kr.co.vividnext.sodalive.settings.event.EventActivity
|
||||
import kr.co.vividnext.sodalive.settings.notice.NoticeActivity
|
||||
import kr.co.vividnext.sodalive.settings.notification.NotificationSettingsActivity
|
||||
import kr.co.vividnext.sodalive.settings.signout.SignOutActivity
|
||||
import kr.co.vividnext.sodalive.settings.terms.TermsActivity
|
||||
import kr.co.vividnext.sodalive.splash.SplashActivity
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class SettingsActivity : BaseActivity<ActivitySettingsBinding>(ActivitySettingsBinding::inflate) {
|
||||
private val logoutDialog: SodaDialog by lazy {
|
||||
SodaDialog(
|
||||
activity = this,
|
||||
layoutInflater = layoutInflater,
|
||||
title = "알림",
|
||||
desc = "로그아웃 하시겠어요?",
|
||||
confirmButtonTitle = "확인",
|
||||
confirmButtonClick = { logout() },
|
||||
cancelButtonTitle = "취소",
|
||||
cancelButtonClick = {}
|
||||
)
|
||||
}
|
||||
|
||||
private val viewModel: SettingsViewModel by inject()
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
bindData()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun setupView() {
|
||||
binding.toolbar.tvBack.text = "설정"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
|
||||
binding.rlNotice.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(
|
||||
applicationContext,
|
||||
NoticeActivity::class.java
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
binding.rlEvent.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(
|
||||
applicationContext,
|
||||
EventActivity::class.java
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
binding.rlNotificationSettings.setOnClickListener {
|
||||
startActivity(
|
||||
Intent(
|
||||
applicationContext,
|
||||
NotificationSettingsActivity::class.java
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
binding.rlTerms.setOnClickListener {
|
||||
val intent = Intent(applicationContext, TermsActivity::class.java)
|
||||
intent.putExtra("terms", "terms")
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.rlPrivacyPolicy.setOnClickListener {
|
||||
val intent = Intent(applicationContext, TermsActivity::class.java)
|
||||
intent.putExtra("terms", "privacy")
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.rlOssLicense.setOnClickListener {
|
||||
startActivity(Intent(applicationContext, OssLicensesMenuActivity::class.java))
|
||||
OssLicensesMenuActivity.setActivityTitle("오픈소스 라이선스")
|
||||
}
|
||||
|
||||
binding.tvVersion.text = "ver ${BuildConfig.VERSION_NAME}"
|
||||
|
||||
binding.tvLogOut.setOnClickListener {
|
||||
logoutDialog.show(screenWidth)
|
||||
}
|
||||
|
||||
binding.tvSignOut.paintFlags = binding.tvSignOut.paintFlags.or(Paint.UNDERLINE_TEXT_FLAG)
|
||||
binding.tvSignOut.setOnClickListener {
|
||||
startActivity(Intent(applicationContext, SignOutActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindData() {
|
||||
viewModel.isLoading.observe(this) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth)
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(this) {
|
||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun logout() {
|
||||
viewModel.logout {
|
||||
SharedPreferenceManager.clear()
|
||||
finishAffinity()
|
||||
startActivity(Intent(applicationContext, SplashActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package kr.co.vividnext.sodalive.settings
|
||||
|
||||
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.user.UserRepository
|
||||
|
||||
class SettingsViewModel(private val userRepository: UserRepository) : BaseViewModel() {
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
fun logout(onSuccess: () -> Unit) {
|
||||
compositeDisposable.add(
|
||||
userRepository.logout(token = "Bearer ${SharedPreferenceManager.token}")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success) {
|
||||
onSuccess()
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package kr.co.vividnext.sodalive.settings.event
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
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.databinding.ActivityEventBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class EventActivity : BaseActivity<ActivityEventBinding>(ActivityEventBinding::inflate) {
|
||||
|
||||
private val viewModel: EventViewModel by inject()
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel.isLoading.observe(this) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, "이벤트를 불러오고 있습니다.")
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(this) {
|
||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.getEvents()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun setupView() {
|
||||
binding.toolbar.tvBack.text = "이벤트"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
|
||||
val adapter = EventAdapter {
|
||||
if (it.detailImageUrl != null) {
|
||||
val intent = Intent(applicationContext, EventDetailActivity::class.java)
|
||||
intent.putExtra(Constants.EXTRA_EVENT, it)
|
||||
startActivity(intent)
|
||||
} else if (!it.link.isNullOrBlank()) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(it.link)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.rvEvent.layoutManager = LinearLayoutManager(this)
|
||||
binding.rvEvent.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 = 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()
|
||||
}
|
||||
}
|
||||
|
||||
outRect.left = 13.3f.dpToPx().toInt()
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
})
|
||||
binding.rvEvent.adapter = adapter
|
||||
|
||||
viewModel.eventLiveData.observe(this) {
|
||||
adapter.items.addAll(it)
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package kr.co.vividnext.sodalive.settings.event
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.load
|
||||
import kr.co.vividnext.sodalive.databinding.ItemEventBinding
|
||||
|
||||
class EventAdapter(
|
||||
private val onClick: (EventItem) -> Unit
|
||||
) : RecyclerView.Adapter<EventAdapter.ViewHolder>() {
|
||||
|
||||
val items = mutableListOf<EventItem>()
|
||||
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemEventBinding,
|
||||
private val onClick: (EventItem) -> Unit
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(event: EventItem) {
|
||||
binding.ivEvent.load(event.thumbnailImageUrl)
|
||||
binding.root.setOnClickListener { onClick(event) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return ViewHolder(
|
||||
ItemEventBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
),
|
||||
onClick
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.count()
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package kr.co.vividnext.sodalive.settings.event
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.content.IntentCompat
|
||||
import coil.load
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
import kr.co.vividnext.sodalive.databinding.ActivityEventDetailBinding
|
||||
|
||||
class EventDetailActivity : BaseActivity<ActivityEventDetailBinding>(
|
||||
ActivityEventDetailBinding::inflate
|
||||
) {
|
||||
private lateinit var event: EventItem
|
||||
|
||||
override fun setupView() {
|
||||
event = IntentCompat.getParcelableExtra(
|
||||
intent,
|
||||
Constants.EXTRA_EVENT,
|
||||
EventItem::class.java
|
||||
)!!
|
||||
|
||||
binding.toolbar.tvBack.text = "이벤트 상세"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
if (!event.link.isNullOrBlank()) {
|
||||
binding.flParticipate.visibility = View.VISIBLE
|
||||
|
||||
val flParticipateLp =
|
||||
binding.flParticipate.layoutParams as RelativeLayout.LayoutParams
|
||||
|
||||
val ivEventLp = binding.ivEvent.layoutParams as FrameLayout.LayoutParams
|
||||
ivEventLp.bottomMargin = flParticipateLp.height
|
||||
binding.ivEvent.layoutParams = ivEventLp
|
||||
} else {
|
||||
binding.flParticipate.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.tvParticipate.setOnClickListener {
|
||||
if (!event.link.isNullOrBlank()) {
|
||||
startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(event.link)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivEvent.load(event.detailImageUrl)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package kr.co.vividnext.sodalive.settings.event
|
||||
|
||||
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
|
||||
|
||||
class EventViewModel(private val repository: EventRepository) : BaseViewModel() {
|
||||
private val _eventLiveData = MutableLiveData<List<EventItem>>()
|
||||
val eventLiveData: LiveData<List<EventItem>>
|
||||
get() = _eventLiveData
|
||||
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
private var totalCount = -1
|
||||
private var page = 1
|
||||
private val size = 10
|
||||
|
||||
fun getEvents() {
|
||||
if (totalCount < 0 || page * size < totalCount) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository.getEvents(
|
||||
page = page - 1,
|
||||
size = size,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
val data = it.data
|
||||
this.totalCount = data.totalCount
|
||||
_eventLiveData.postValue(data.eventList)
|
||||
page += 1
|
||||
} 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("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
data class GetNoticeResponse(
|
||||
@SerializedName("totalCount") val totalCount: Int,
|
||||
@SerializedName("noticeList") val noticeList: List<NoticeItem>
|
||||
)
|
||||
|
||||
@Parcelize
|
||||
data class NoticeItem(
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("content") val content: String,
|
||||
@SerializedName("date") val date: String
|
||||
) : Parcelable
|
|
@ -0,0 +1,107 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
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.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
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.databinding.ActivityNoticeBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class NoticeActivity : BaseActivity<ActivityNoticeBinding>(ActivityNoticeBinding::inflate) {
|
||||
|
||||
private val viewModel: NoticeViewModel by inject()
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel.isLoading.observe(this) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, "공지사항을 불러오고 있습니다.")
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(this) {
|
||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
|
||||
viewModel.getNotices()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun setupView() {
|
||||
binding.toolbar.tvBack.text = "공지사항"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
|
||||
val adapter = NoticeAdapter {
|
||||
val intent = Intent(applicationContext, NoticeDetailActivity::class.java)
|
||||
intent.putExtra(Constants.EXTRA_NOTICE, it)
|
||||
startActivity(intent)
|
||||
}
|
||||
binding.rvNotice.layoutManager = LinearLayoutManager(this)
|
||||
binding.rvNotice.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 = 13.3f.dpToPx().toInt()
|
||||
outRect.bottom = 0
|
||||
}
|
||||
|
||||
adapter.itemCount - 1 -> {
|
||||
outRect.top = 0
|
||||
outRect.bottom = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
|
||||
else -> {
|
||||
outRect.top = 0
|
||||
outRect.bottom = 0
|
||||
}
|
||||
}
|
||||
|
||||
outRect.left = 13.3f.dpToPx().toInt()
|
||||
outRect.right = 13.3f.dpToPx().toInt()
|
||||
}
|
||||
})
|
||||
|
||||
binding.rvNotice.adapter = adapter
|
||||
|
||||
binding.rvNotice.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 (lastVisiblePosition == itemTotalCount) {
|
||||
viewModel.getNotices()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.noticeLiveData.observe(this) {
|
||||
adapter.items.addAll(it)
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kr.co.vividnext.sodalive.databinding.ItemNoticeBinding
|
||||
|
||||
class NoticeAdapter(
|
||||
private val onClick: (NoticeItem) -> Unit
|
||||
) : RecyclerView.Adapter<NoticeAdapter.ViewHolder>() {
|
||||
|
||||
val items = mutableListOf<NoticeItem>()
|
||||
|
||||
inner class ViewHolder(
|
||||
private val binding: ItemNoticeBinding,
|
||||
private val onClick: (NoticeItem) -> Unit
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(notice: NoticeItem) {
|
||||
binding.tvTitle.text = notice.title
|
||||
binding.tvDate.text = notice.date
|
||||
binding.root.setOnClickListener { onClick(notice) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
return ViewHolder(
|
||||
ItemNoticeBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
),
|
||||
onClick
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position])
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.count()
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Query
|
||||
|
||||
interface NoticeApi {
|
||||
@GET("/notice")
|
||||
fun getNotices(
|
||||
@Query("timezone") timezone: String,
|
||||
@Query("page") page: Int,
|
||||
@Query("size") size: Int,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<GetNoticeResponse>>
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.webkit.WebSettingsCompat
|
||||
import androidx.webkit.WebViewFeature
|
||||
import kr.co.vividnext.sodalive.base.BaseActivity
|
||||
import kr.co.vividnext.sodalive.common.Constants
|
||||
import kr.co.vividnext.sodalive.databinding.ActivityNoticeDetailBinding
|
||||
|
||||
class NoticeDetailActivity : BaseActivity<ActivityNoticeDetailBinding>(
|
||||
ActivityNoticeDetailBinding::inflate
|
||||
) {
|
||||
private lateinit var notice: NoticeItem
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
override fun setupView() {
|
||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
|
||||
WebSettingsCompat.setForceDark(
|
||||
binding.webView.settings,
|
||||
WebSettingsCompat.FORCE_DARK_ON
|
||||
)
|
||||
}
|
||||
|
||||
notice = IntentCompat.getParcelableExtra(
|
||||
intent,
|
||||
Constants.EXTRA_NOTICE,
|
||||
NoticeItem::class.java
|
||||
)!!
|
||||
|
||||
binding.toolbar.tvBack.text = "공지사항 상세"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
binding.tvTitle.text = notice.title
|
||||
binding.tvDate.text = notice.date
|
||||
|
||||
val viewPort = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
|
||||
val data = viewPort + notice.content
|
||||
binding.webView.settings.apply {
|
||||
javaScriptEnabled = true // 자바스크립트 실행 허용
|
||||
javaScriptCanOpenWindowsAutomatically = false // 자바스크립트에서 새창 실 행 허용
|
||||
setSupportMultipleWindows(false) // 새 창 실행 허용
|
||||
loadWithOverviewMode = true // 메타 태그 허용
|
||||
|
||||
useWideViewPort = true // 화면 사이즈 맞추기 허용
|
||||
setSupportZoom(false) // 화면 줌 허용
|
||||
builtInZoomControls = false // 화면 확대 축소 허용 여부
|
||||
}
|
||||
binding.webView.loadData(
|
||||
data,
|
||||
"text/html; charset=utf-8",
|
||||
"utf-8"
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import java.util.TimeZone
|
||||
|
||||
class NoticeRepository(private val api: NoticeApi) {
|
||||
fun getNotices(
|
||||
page: Int,
|
||||
size: Int,
|
||||
token: String
|
||||
): Single<ApiResponse<GetNoticeResponse>> {
|
||||
return api.getNotices(TimeZone.getDefault().id, page, size, authHeader = token)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package kr.co.vividnext.sodalive.settings.notice
|
||||
|
||||
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
|
||||
|
||||
class NoticeViewModel(private val repository: NoticeRepository) : BaseViewModel() {
|
||||
private val _noticeLiveData = MutableLiveData<List<NoticeItem>>()
|
||||
val noticeLiveData: LiveData<List<NoticeItem>>
|
||||
get() = _noticeLiveData
|
||||
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
private var totalCount = -1
|
||||
private var page = 1
|
||||
private val size = 10
|
||||
|
||||
fun getNotices() {
|
||||
if (totalCount < 0 || page * size < totalCount) {
|
||||
_isLoading.value = true
|
||||
compositeDisposable.add(
|
||||
repository.getNotices(
|
||||
page = page - 1,
|
||||
size = size,
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
if (it.success && it.data != null) {
|
||||
val data = it.data
|
||||
this.totalCount = data.totalCount
|
||||
_noticeLiveData.postValue(data.noticeList)
|
||||
page += 1
|
||||
} 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("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package kr.co.vividnext.sodalive.settings.notification
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
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.databinding.ActivityNotificationSettingsBinding
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
class NotificationSettingsActivity : BaseActivity<ActivityNotificationSettingsBinding>(
|
||||
ActivityNotificationSettingsBinding::inflate
|
||||
) {
|
||||
|
||||
private val viewModel: NotificationSettingsViewModel by inject()
|
||||
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel.getNotificationSettings()
|
||||
}
|
||||
|
||||
override fun setupView() {
|
||||
binding.toolbar.tvBack.text = "알림 설정"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
|
||||
binding.ivNotifiedLive.setOnClickListener {
|
||||
viewModel.toggleFollowingChannelLiveNotice()
|
||||
}
|
||||
binding.ivNotifiedUploadContent.setOnClickListener {
|
||||
viewModel.toggleFollowingChannelUploadContentNotice()
|
||||
}
|
||||
binding.ivMessage.setOnClickListener { viewModel.toggleMessage() }
|
||||
|
||||
viewModel.followingChannelLiveNotice.observe(this) {
|
||||
binding.ivNotifiedLive.setImageResource(
|
||||
if (it) {
|
||||
R.drawable.btn_toggle_on_big
|
||||
} else {
|
||||
R.drawable.btn_toggle_off_big
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.followingChannelUploadContentNotice.observe(this) {
|
||||
binding.ivNotifiedUploadContent.setImageResource(
|
||||
if (it) {
|
||||
R.drawable.btn_toggle_on_big
|
||||
} else {
|
||||
R.drawable.btn_toggle_off_big
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.isMessage.observe(this) {
|
||||
binding.ivMessage.setImageResource(
|
||||
if (it) {
|
||||
R.drawable.btn_toggle_on_big
|
||||
} else {
|
||||
R.drawable.btn_toggle_off_big
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.isLoading.observe(this) {
|
||||
if (it) {
|
||||
loadingDialog.show(screenWidth, "")
|
||||
} else {
|
||||
loadingDialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.toastLiveData.observe(this) {
|
||||
it?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package kr.co.vividnext.sodalive.settings.notification
|
||||
|
||||
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.user.UserRepository
|
||||
|
||||
class NotificationSettingsViewModel(
|
||||
private val userRepository: UserRepository
|
||||
) : 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 _followingChannelLiveNotice = MutableLiveData(false)
|
||||
val followingChannelLiveNotice: LiveData<Boolean>
|
||||
get() = _followingChannelLiveNotice
|
||||
|
||||
private var _isMessage = MutableLiveData(false)
|
||||
val isMessage: LiveData<Boolean>
|
||||
get() = _isMessage
|
||||
|
||||
private var _followingChannelUploadContentNotice = MutableLiveData(false)
|
||||
val followingChannelUploadContentNotice: LiveData<Boolean>
|
||||
get() = _followingChannelUploadContentNotice
|
||||
|
||||
fun getNotificationSettings() {
|
||||
_isLoading.value = true
|
||||
|
||||
compositeDisposable.add(
|
||||
userRepository.getMemberInfo(token = "Bearer ${SharedPreferenceManager.token}")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
|
||||
if (it.success && it.data != null) {
|
||||
val data = it.data!!
|
||||
_isMessage.value = data.messageNotice ?: false
|
||||
_followingChannelUploadContentNotice.value =
|
||||
data.followingChannelUploadContentNotice ?: false
|
||||
_followingChannelLiveNotice.value =
|
||||
data.followingChannelLiveNotice ?: false
|
||||
} else {
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue(
|
||||
"다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun toggleFollowingChannelLiveNotice() {
|
||||
_followingChannelLiveNotice.value = !followingChannelLiveNotice.value!!
|
||||
updateNotificationSettings(live = followingChannelLiveNotice.value!!)
|
||||
}
|
||||
|
||||
fun toggleFollowingChannelUploadContentNotice() {
|
||||
_followingChannelUploadContentNotice.value = !followingChannelUploadContentNotice.value!!
|
||||
updateNotificationSettings(uploadContent = followingChannelUploadContentNotice.value!!)
|
||||
}
|
||||
|
||||
fun toggleMessage() {
|
||||
_isMessage.value = !isMessage.value!!
|
||||
updateNotificationSettings(message = isMessage.value!!)
|
||||
}
|
||||
|
||||
private fun updateNotificationSettings(
|
||||
live: Boolean? = null,
|
||||
uploadContent: Boolean? = null,
|
||||
message: Boolean? = null
|
||||
) {
|
||||
if (live != null || uploadContent != null || message != null) {
|
||||
compositeDisposable.add(
|
||||
userRepository.updateNotificationSettings(
|
||||
request = UpdateNotificationSettingRequest(
|
||||
live,
|
||||
uploadContent,
|
||||
message
|
||||
),
|
||||
token = "Bearer ${SharedPreferenceManager.token}"
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({}, {})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package kr.co.vividnext.sodalive.settings.signout
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.jakewharton.rxbinding4.widget.textChanges
|
||||
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.databinding.ActivitySignOutBinding
|
||||
import kr.co.vividnext.sodalive.splash.SplashActivity
|
||||
import org.koin.android.ext.android.inject
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class SignOutActivity : BaseActivity<ActivitySignOutBinding>(ActivitySignOutBinding::inflate) {
|
||||
private val viewModel: SignOutViewModel by inject()
|
||||
|
||||
private val reasonButtons = mutableListOf<TextView>()
|
||||
private lateinit var loadingDialog: LoadingDialog
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
bindData()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
compositeDisposable.add(
|
||||
binding.etPassword.textChanges().skip(1)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
viewModel.password = it.toString()
|
||||
}
|
||||
)
|
||||
compositeDisposable.add(
|
||||
binding.etReasonEtc.textChanges().skip(1)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
if (binding.tvReason10.isSelected) {
|
||||
viewModel.reason = it.toString()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun setupView() {
|
||||
reasonButtons.add(binding.tvReason1)
|
||||
reasonButtons.add(binding.tvReason2)
|
||||
reasonButtons.add(binding.tvReason3)
|
||||
reasonButtons.add(binding.tvReason4)
|
||||
reasonButtons.add(binding.tvReason5)
|
||||
reasonButtons.add(binding.tvReason6)
|
||||
reasonButtons.add(binding.tvReason7)
|
||||
reasonButtons.add(binding.tvReason8)
|
||||
reasonButtons.add(binding.tvReason9)
|
||||
reasonButtons.add(binding.tvReason10)
|
||||
|
||||
loadingDialog = LoadingDialog(this, layoutInflater)
|
||||
binding.toolbar.tvBack.text = "회원탈퇴"
|
||||
binding.toolbar.tvBack.setOnClickListener { finish() }
|
||||
|
||||
for (reasonButton in reasonButtons) {
|
||||
val reason = reasonButton.text.toString()
|
||||
reasonButton.setOnClickListener {
|
||||
checkboxSelectedFalse()
|
||||
reasonButton.isSelected = true
|
||||
viewModel.reason = if (reason == "기타") {
|
||||
binding.etReasonEtc.text.toString()
|
||||
} else {
|
||||
reasonButton.text.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvSignOut.setOnClickListener {
|
||||
viewModel.signOut {
|
||||
finishAffinity()
|
||||
startActivity(Intent(applicationContext, SplashActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkboxSelectedFalse() {
|
||||
for (reasonButton in reasonButtons) {
|
||||
reasonButton.isSelected = false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package kr.co.vividnext.sodalive.settings.signout
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class SignOutRequest(
|
||||
@SerializedName("reason") val reason: String,
|
||||
@SerializedName("password") val password: String
|
||||
)
|
|
@ -0,0 +1,70 @@
|
|||
package kr.co.vividnext.sodalive.settings.signout
|
||||
|
||||
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.user.UserRepository
|
||||
|
||||
class SignOutViewModel(private val repository: UserRepository) : BaseViewModel() {
|
||||
|
||||
private val _toastLiveData = MutableLiveData<String?>()
|
||||
val toastLiveData: LiveData<String?>
|
||||
get() = _toastLiveData
|
||||
|
||||
private var _isLoading = MutableLiveData(false)
|
||||
val isLoading: LiveData<Boolean>
|
||||
get() = _isLoading
|
||||
|
||||
var reason: String = ""
|
||||
var password = ""
|
||||
|
||||
fun signOut(onSuccess: () -> Unit) {
|
||||
if (!_isLoading.value!!) {
|
||||
if (reason.isBlank()) {
|
||||
_toastLiveData.postValue("계정을 삭제하려는 이유를 선택해 주세요.")
|
||||
return
|
||||
}
|
||||
|
||||
if (password.isBlank()) {
|
||||
_toastLiveData.postValue("비밀번호를 입력해 주세요.")
|
||||
return
|
||||
}
|
||||
|
||||
_isLoading.value = true
|
||||
val request = SignOutRequest(reason.trim(), password)
|
||||
|
||||
compositeDisposable.add(
|
||||
repository.signOut(request, "Bearer ${SharedPreferenceManager.token}")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
_isLoading.value = false
|
||||
|
||||
if (it.message != null) {
|
||||
_toastLiveData.postValue(it.message)
|
||||
} else {
|
||||
_toastLiveData.postValue(
|
||||
"알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
)
|
||||
}
|
||||
|
||||
if (it.success) {
|
||||
SharedPreferenceManager.clear()
|
||||
onSuccess()
|
||||
}
|
||||
},
|
||||
{
|
||||
_isLoading.value = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
_toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import kr.co.vividnext.sodalive.main.PushTokenUpdateRequest
|
|||
import kr.co.vividnext.sodalive.mypage.MyPageResponse
|
||||
import kr.co.vividnext.sodalive.settings.notification.GetMemberInfoResponse
|
||||
import kr.co.vividnext.sodalive.settings.notification.UpdateNotificationSettingRequest
|
||||
import kr.co.vividnext.sodalive.settings.signout.SignOutRequest
|
||||
import kr.co.vividnext.sodalive.user.find_password.ForgotPasswordRequest
|
||||
import kr.co.vividnext.sodalive.user.login.LoginRequest
|
||||
import kr.co.vividnext.sodalive.user.login.LoginResponse
|
||||
|
@ -88,4 +89,13 @@ interface UserApi {
|
|||
@Query("nickname") nickname: String,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<List<GetRoomDetailUser>>>
|
||||
|
||||
@POST("/member/sign_out")
|
||||
fun signOut(
|
||||
@Body request: SignOutRequest,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<Any>>
|
||||
|
||||
@POST("/member/logout")
|
||||
fun logout(@Header("Authorization") authHeader: String): Single<ApiResponse<Any>>
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import kr.co.vividnext.sodalive.mypage.MyPageResponse
|
|||
import kr.co.vividnext.sodalive.settings.notification.UpdateNotificationSettingRequest
|
||||
import kr.co.vividnext.sodalive.user.find_password.ForgotPasswordRequest
|
||||
import kr.co.vividnext.sodalive.user.login.LoginRequest
|
||||
import kr.co.vividnext.sodalive.settings.signout.SignOutRequest
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
|
||||
|
@ -70,4 +71,11 @@ class UserRepository(private val userApi: UserApi) {
|
|||
): Single<ApiResponse<List<GetRoomDetailUser>>> {
|
||||
return userApi.searchUser(nickname, authHeader = token)
|
||||
}
|
||||
|
||||
fun signOut(
|
||||
request: SignOutRequest,
|
||||
token: String
|
||||
) = userApi.signOut(request, authHeader = token)
|
||||
|
||||
fun logout(token: String) = userApi.logout(authHeader = token)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/color_3e737c" />
|
||||
<corners android:radius="10dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/color_3e737c" />
|
||||
</shape>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/toolbar">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null" />
|
||||
</ScrollView>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_participate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@drawable/bg_top_round_corner_16_7_222222"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="13.7dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_participate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_round_corner_10_3e737c"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="16dp"
|
||||
android:text="이벤트 참여하기"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18.3sp" />
|
||||
</FrameLayout>
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_notice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="13.3dp"
|
||||
android:paddingVertical="22dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp"
|
||||
tools:text="요즘 App 오픈 관련 공지사항입니다." />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_525252"
|
||||
android:textSize="12sp"
|
||||
tools:text="2021.07.01" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="26.7dp" />
|
||||
</LinearLayout>
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="13.3dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="라이브 알림"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_notified_live"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/btn_toggle_off_big" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="13.3dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="콘텐츠 업로드 알림"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_notified_upload_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/btn_toggle_on_big" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="13.3dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="메시지 알림"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="@null"
|
||||
tools:src="@drawable/btn_toggle_on_big" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,287 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="26.7dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_notice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="공지사항"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="이벤트"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_notification_settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="알림 설정"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="26.7dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_terms"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="이용약관"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_privacy_policy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="개인정보처리방침"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_oss_license"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="오픈소스 라이선스"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_forward" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:paddingVertical="16.7dp"
|
||||
android:paddingStart="16.7dp"
|
||||
android:paddingEnd="13.3dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="앱 버전 정보"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
tools:ignore="RelativeOverlap"
|
||||
tools:text="ver.0.0.1" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_log_out"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="46.7dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_222222"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="19.3dp"
|
||||
android:text="로그아웃"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_sign_out"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="26.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="회원탈퇴"
|
||||
android:textColor="@color/color_777777"
|
||||
android:textSize="14.7sp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,288 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/detail_toolbar" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolbar">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:text="정말로 탈퇴하실 거에요?\n한 번 더 생각해보지 않으실래요?"
|
||||
android:textColor="@color/color_a285eb"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:letterSpacing="0"
|
||||
android:text="계정을 삭제하려는 이유를 선택해주세요.\n서비스 개선에 중요한 자료로 활용하겠습니다."
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="닉네임을 변경하고 싶어서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="다른 사용자와의 다툼이 있어서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="이용이 불편하고 장애가 많아서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="서비스 운영이 마음에 들지 않아서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_5"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="다른 서비스가 더 좋아서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_6"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="삭제하고 싶은 내용이 있어서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_7"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="사용빈도가 낮아서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_8"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="원하는 콘텐츠나 크리에이터가 없어서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_9"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="이용요금이 비싸서"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="23.3dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reason_10"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:button="@null"
|
||||
android:drawablePadding="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="기타"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="13.3sp"
|
||||
app:drawableStartCompat="@drawable/ic_radio_button_select" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="23.3dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_reason_etc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:button="@null"
|
||||
android:fontFamily="@font/gmarket_sans_light"
|
||||
android:hint="입력해 주세요"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="textWebEditText"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textColorHint="@color/color_555555"
|
||||
android:textCursorDrawable="@drawable/edit_text_cursor"
|
||||
android:textSize="13.3sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="7.3dp"
|
||||
android:background="@color/color_88909090" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="6.7dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@color/color_232323" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="26.7dp"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="계정을 삭제하면 회원님의 모든 콘텐츠와 활동 길고, 코인충전 및 적립, 사용내역 등의 기록이 삭제됩니다. 삭제된 정보는 복구할 수 없으니 신중히 결정해주세요.\n코인 충전하기를 통해 적립한 코인은 계정 삭제시 환불이 불가합니다. 또한 환불 신청 후 환불처리가 되기 전에 계정을 삭제하는 경우 포인트 사용내역을 확인할 수 없어 환불이 불가합니다. "
|
||||
android:textColor="@color/color_ff5c49" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="26.7dp"
|
||||
android:layout_marginTop="13.3dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:text="비밀번호 확인"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/edittext_underline"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="textWebPassword"
|
||||
android:paddingHorizontal="6.7dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textColorHint="@color/color_777777"
|
||||
android:textCursorDrawable="@drawable/edit_text_cursor"
|
||||
android:textSize="13.3sp"
|
||||
android:theme="@style/EditTextStyle"
|
||||
tools:ignore="LabelFor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_sign_out"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="13.3dp"
|
||||
android:layout_marginTop="53.3dp"
|
||||
android:layout_marginBottom="13.3dp"
|
||||
android:background="@drawable/bg_round_corner_6_7_9970ff"
|
||||
android:fontFamily="@font/gmarket_sans_bold"
|
||||
android:gravity="center"
|
||||
android:paddingVertical="16dp"
|
||||
android:text="탈퇴하기"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_event"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:background="@color/black"
|
||||
android:paddingHorizontal="13.3dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_eeeeee"
|
||||
android:textSize="14.7sp"
|
||||
tools:text="요즘 App 오픈 관련 공지사항입니다." />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6.7dp"
|
||||
android:fontFamily="@font/gmarket_sans_medium"
|
||||
android:textColor="@color/color_525252"
|
||||
android:textSize="12sp"
|
||||
tools:text="2021.07.01" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@color/color_88909090" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -69,4 +69,5 @@
|
|||
<color name="color_99000000">#99000000</color>
|
||||
<color name="color_4c9970ff">#4C9970FF</color>
|
||||
<color name="color_4dd8d8d8">#4DD8D8D8</color>
|
||||
<color name="color_3e737c">#3E737C</color>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue