Skip to content

Commit

Permalink
Merge pull request #101 from POLZZAK/feat/my_page_cs
Browse files Browse the repository at this point in the history
[FEAT] 고객센터
  • Loading branch information
HS0204 authored Sep 3, 2023
2 parents e78633d + ce9a7db commit 63786bb
Show file tree
Hide file tree
Showing 11 changed files with 776 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class BindableItemAdapter :

fun updateItem(item: List<BindableItem<*>>, commitCallback: (() -> Unit)? = null) {
submitList(item, commitCallback)
notifyDataSetChanged()
}

fun addItem(items: List<BindableItem<*>>, commitCallback: (() -> Unit)? = null) {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.polzzak_android.presentation.feature.myPage.model

data class FAQModel(
val type: FAQType,
val title: String,
val content: String
)

enum class FAQType {
STAMP, COUPON, ACCOUNT, POINT, LINKED
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.polzzak_android.presentation.feature.myPage.protector

import androidx.navigation.fragment.findNavController
import com.polzzak_android.R
import com.polzzak_android.databinding.FragmentProtectorMyPageBinding
import com.polzzak_android.presentation.common.base.BaseFragment
Expand Down Expand Up @@ -70,7 +71,7 @@ class ProtectorMyPageFragment : BaseFragment<FragmentProtectorMyPageBinding>(),
}

fun onClickCustomerService() {
// todo: 고객센터 클릭
findNavController().navigate(R.id.action_protectorMyPageFragment_to_protectorCSFragment)
}

fun onClickNotice() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package com.polzzak_android.presentation.feature.myPage.protector.cs

import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.TextView
import androidx.navigation.fragment.findNavController
import com.polzzak_android.R
import com.polzzak_android.databinding.FragmentProtectorCSBinding
import com.polzzak_android.databinding.ItemFaqBinding
import com.polzzak_android.presentation.common.base.BaseFragment
import com.polzzak_android.presentation.common.util.BindableItem
import com.polzzak_android.presentation.common.util.BindableItemAdapter
import com.polzzak_android.presentation.component.toolbar.ToolbarData
import com.polzzak_android.presentation.component.toolbar.ToolbarHelper
import com.polzzak_android.presentation.feature.myPage.model.FAQModel
import com.polzzak_android.presentation.feature.myPage.model.FAQType
import com.polzzak_android.presentation.feature.myPage.model.getFAQListForProtector

class ProtectorCSFragment : BaseFragment<FragmentProtectorCSBinding>() {
override val layoutResId: Int = R.layout.fragment_protector_c_s

private lateinit var toolbarHelper: ToolbarHelper

private lateinit var adapter: BindableItemAdapter
private val items = mutableListOf<BindableItem<*>>()

override fun setToolbar() {
super.setToolbar()

toolbarHelper = ToolbarHelper(
data = ToolbarData(
popStack = findNavController(),
titleText = "고객센터"
),
toolbar = binding.toolbar
)
toolbarHelper.set()
}

override fun initView() {
super.initView()
binding.fragment = this
binding.isSearchMode = false
binding.hasSearchedResult = true
setAdapter()
setSearchBarFocusListener()
}

private fun setAdapter() {
binding.csFaqRc.adapter = BindableItemAdapter()
adapter = (binding.csFaqRc.adapter as? BindableItemAdapter) ?: return

updateAdapter(type = FAQType.STAMP, view = binding.csMenuStamp)
}

fun updateAdapter(type: FAQType, view: View) {
initMenu()
selectMenu(view)

items.clear()
val faqList = getFAQListForProtector().filter {
it.type == type
}
items.addAll(faqList.map { model -> FAQItem(model = model) })
adapter.updateItem(item = items)
}

private fun updateAdapterWithSearchWord(word: String) {
items.clear()
val faqList = getFAQListForProtector().filter {
it.title.contains(word)
}
items.addAll(faqList.map { model -> FAQItem(model = model) })
adapter.updateItem(item = items)

binding.csFaqTitle.text = "검색 결과 ${faqList.size}"
binding.hasSearchedResult = faqList.isNotEmpty()
}

inner class FAQItem(
private val model: FAQModel,
) :
BindableItem<ItemFaqBinding>() {
override val layoutRes = R.layout.item_faq

private var isExpanded = false

private fun toggleExpand() {
isExpanded = !isExpanded
}

private fun applyUiState(binding: ItemFaqBinding) {
if (isExpanded) {
with(binding) {
faqContent.visibility = View.VISIBLE
faqTitle.setTextColor(binding.root.context.getColor(R.color.black))
faqArrow.setImageResource(R.drawable.ic_arrow_up)
}
} else {
with(binding) {
faqContent.visibility = View.GONE
faqTitle.setTextColor(binding.root.context.getColor(R.color.gray_700))
faqArrow.setImageResource(R.drawable.ic_arrow_down)
}
}
}

override fun bind(binding: ItemFaqBinding, position: Int) {
with(binding) {
faq = model
applyUiState(binding)
root.setOnClickListener {
toggleExpand()
applyUiState(binding)
}
}
}

override fun areItemsTheSame(other: BindableItem<*>): Boolean =
other is FAQItem && other.model.title == this.model.title

override fun areContentsTheSame(other: BindableItem<*>): Boolean =
other is FAQItem && other.model == this.model
}

private fun initMenu() {
val context = binding.root.context
val textColor = context.getColor(R.color.gray_600)

listOf(
binding.csMenuStamp,
binding.csMenuCoupon,
binding.csMenuLinked,
binding.csMenuPoint,
binding.csMenuAccount
).forEach { view ->
view.isSelected = false
view.setTextColor(textColor)
}
}

private fun selectMenu(view: View) {
val context = view.context
val isSelected = !view.isSelected
view.isSelected = isSelected
(view as TextView).setTextColor(
context.getColor(if (isSelected) R.color.white else R.color.gray_600)
)
}

private fun setSearchBarFocusListener() {
binding.csSearchBar.onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
setSearchedMode(hasFocus)
}
}

fun setSearchedMode(isSearchedMode: Boolean) {
binding.isSearchMode = isSearchedMode
val textWatcher = setSearchBarTextWatcher()

if (binding.isSearchMode == true) {
with(binding) {
updateAdapterWithSearchWord(word = binding.csSearchBar.text.toString())
csSearchBar.addTextChangedListener(textWatcher)
}
} else {
with(binding) {
csFaqTitle.text = "자주 묻는 질문"
hasSearchedResult = true
csSearchBar.removeTextChangedListener(textWatcher)
updateAdapter(type = FAQType.STAMP, view = binding.csMenuStamp)
}
}
}

private fun setSearchBarTextWatcher(): TextWatcher {
val textWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

override fun afterTextChanged(s: Editable?) {
updateAdapterWithSearchWord(word = s.toString())
if (s.toString().isEmpty()) {
binding.csSearchBar.clearFocus()
}
}
}

return textWatcher
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_arrow_down.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="8dp"
android:viewportWidth="12"
android:viewportHeight="8">
<path
android:pathData="M9.88,1.29L6,5.17L2.12,1.29C1.73,0.9 1.1,0.9 0.71,1.29C0.32,1.68 0.32,2.31 0.71,2.7L5.3,7.29C5.69,7.68 6.32,7.68 6.71,7.29L11.3,2.7C11.69,2.31 11.69,1.68 11.3,1.29C10.91,0.91 10.27,0.9 9.88,1.29Z"
android:fillColor="#9C9CA8"/>
</vector>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_arrow_up.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="8dp"
android:viewportWidth="12"
android:viewportHeight="8">
<path
android:pathData="M5.29,0.71L0.7,5.3C0.31,5.69 0.31,6.32 0.7,6.71C1.09,7.1 1.72,7.1 2.11,6.71L6,2.83L9.88,6.71C10.27,7.1 10.9,7.1 11.29,6.71C11.68,6.32 11.68,5.69 11.29,5.3L6.7,0.71C6.32,0.32 5.68,0.32 5.29,0.71Z"
android:fillColor="#45464F"/>
</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/selector_bg_cs_menu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primary" android:state_selected="true" />
<item android:drawable="@color/white" android:state_selected="false" />
</selector>
Loading

0 comments on commit 63786bb

Please sign in to comment.