From 380f69a3f4fc91a99b629b86b7504b666e6a35bf Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 07:25:19 +0900 Subject: [PATCH 01/61] #212 Add dining tab --- .../koreatech/koin/domain/util/DiningUtil.kt | 1 + .../koin/ui/main/activity/MainActivity.kt | 100 ++++---- koin/src/main/res/layout/activity_main.xml | 214 +----------------- 3 files changed, 62 insertions(+), 253 deletions(-) diff --git a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt index bdda26a05..804abdcac 100644 --- a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt +++ b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt @@ -7,6 +7,7 @@ import `in`.koreatech.koin.domain.util.ext.typeFilter object DiningUtil { private val diningEndTime = listOf("09:00", "13:30", "18:30", "23:59") + val diningPlace = listOf("A코너", "B코너", "C코너", "능수관" ) fun typeFiltering(diningList: List, type: DiningType): List = diningList.typeFilter(type).arrange() diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 2c05a43df..d7b073b35 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -104,18 +104,22 @@ class MainActivity : KoinNavigationDrawerActivity() { adapter = storeCategoryRecyclerAdapter } - recyclerViewDiningType.apply { - layoutManager = - LinearLayoutManager(this@MainActivity, RecyclerView.HORIZONTAL, false) - adapter = diningTypeAdapter - } +// recyclerViewDiningType.apply { +// layoutManager = +// LinearLayoutManager(this@MainActivity, RecyclerView.HORIZONTAL, false) +// adapter = diningTypeAdapter +// } mainSwipeRefreshLayout.setOnRefreshListener { mainActivityViewModel.updateDining() } - diningContainer.setOnClickListener { - callDrawerItem(R.id.navi_item_dining) +// diningContainer.setOnClickListener { +// callDrawerItem(R.id.navi_item_dining) +// } + + DiningUtil.diningPlace.forEach { place -> + tabDining.addTab(tabDining.newTab().setText(place)) } } @@ -165,46 +169,46 @@ class MainActivity : KoinNavigationDrawerActivity() { } ) - if (list.isEmpty() || position >= diningArranged.size) { - binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true - return - } - - binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false - - listOf( - binding.textViewCardDiningMenu0, - binding.textViewCardDiningMenu2, - binding.textViewCardDiningMenu4, - binding.textViewCardDiningMenu6, - binding.textViewCardDiningMenu8, - binding.textViewCardDiningMenu1, - binding.textViewCardDiningMenu3, - binding.textViewCardDiningMenu5, - binding.textViewCardDiningMenu7, - binding.textViewCardDiningMenu9 - ).zip(diningArranged[position].menu).forEach { (textView, menu) -> - textView.text = menu - } - - val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() - val isChanged = diningArranged[position].changedAt.isNotEmpty() - with (binding.textViewDiningStatus) { - when { - isSoldOut -> { - text = context.getString(R.string.dining_soldout) - setTextColor(ContextCompat.getColor(context, R.color.dining_soldout_text)) - background = ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) - } - isChanged -> { - text = context.getString(R.string.dining_changed) - setTextColor(ContextCompat.getColor(context, R.color.dining_changed_text)) - background = ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) - } - else -> { - visibility = View.INVISIBLE - } - } - } +// if (list.isEmpty() || position >= diningArranged.size) { +// binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true +// return +// } + +// binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false +// +// listOf( +// binding.textViewCardDiningMenu0, +// binding.textViewCardDiningMenu2, +// binding.textViewCardDiningMenu4, +// binding.textViewCardDiningMenu6, +// binding.textViewCardDiningMenu8, +// binding.textViewCardDiningMenu1, +// binding.textViewCardDiningMenu3, +// binding.textViewCardDiningMenu5, +// binding.textViewCardDiningMenu7, +// binding.textViewCardDiningMenu9 +// ).zip(diningArranged[position].menu).forEach { (textView, menu) -> +// textView.text = menu +// } + +// val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() +// val isChanged = diningArranged[position].changedAt.isNotEmpty() +// with (binding.textViewDiningStatus) { +// when { +// isSoldOut -> { +// text = context.getString(R.string.dining_soldout) +// setTextColor(ContextCompat.getColor(context, R.color.dining_soldout_text)) +// background = ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) +// } +// isChanged -> { +// text = context.getString(R.string.dining_changed) +// setTextColor(ContextCompat.getColor(context, R.color.dining_changed_text)) +// background = ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) +// } +// else -> { +// visibility = View.INVISIBLE +// } +// } +// } } } diff --git a/koin/src/main/res/layout/activity_main.xml b/koin/src/main/res/layout/activity_main.xml index 0b6f6e7cd..bda749328 100644 --- a/koin/src/main/res/layout/activity_main.xml +++ b/koin/src/main/res/layout/activity_main.xml @@ -151,215 +151,19 @@ - + android:layout_marginHorizontal="24dp" + app:tabMode="scrollable" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - From c826c8f08360a17e251e0de62fc862610cabe743 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 11:32:58 +0900 Subject: [PATCH 02/61] #212 Add dining place enum class --- .../koreatech/koin/domain/model/dining/DiningPlace.kt | 10 ++++++++++ .../java/in/koreatech/koin/domain/util/DiningUtil.kt | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 domain/src/main/java/in/koreatech/koin/domain/model/dining/DiningPlace.kt diff --git a/domain/src/main/java/in/koreatech/koin/domain/model/dining/DiningPlace.kt b/domain/src/main/java/in/koreatech/koin/domain/model/dining/DiningPlace.kt new file mode 100644 index 000000000..97ea64d8d --- /dev/null +++ b/domain/src/main/java/in/koreatech/koin/domain/model/dining/DiningPlace.kt @@ -0,0 +1,10 @@ +package `in`.koreatech.koin.domain.model.dining + +enum class DiningPlace( + val place: String +) { + CornerA("A코너"), + CornerB("B코너"), + CornerC("C코너"), + Nungsu("능수관") +} \ No newline at end of file diff --git a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt index 804abdcac..bdda26a05 100644 --- a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt +++ b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt @@ -7,7 +7,6 @@ import `in`.koreatech.koin.domain.util.ext.typeFilter object DiningUtil { private val diningEndTime = listOf("09:00", "13:30", "18:30", "23:59") - val diningPlace = listOf("A코너", "B코너", "C코너", "능수관" ) fun typeFiltering(diningList: List, type: DiningType): List = diningList.typeFilter(type).arrange() From 606aed24a730ebe5a565cc2923dc119f3db0f3f9 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 11:33:35 +0900 Subject: [PATCH 03/61] #212 Add dining container view pager --- .../koin/ui/main/activity/MainActivity.kt | 12 ++++-- .../DiningContainerViewPager2Adapter.kt | 26 +++++++++++++ .../main/fragment/DiningContainerFragment.kt | 38 +++++++++++++++++++ koin/src/main/res/layout/activity_main.xml | 5 +++ .../res/layout/fragment_dining_container.xml | 25 ++++++++++++ 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 koin/src/main/java/in/koreatech/koin/ui/main/adapter/DiningContainerViewPager2Adapter.kt create mode 100644 koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt create mode 100644 koin/src/main/res/layout/fragment_dining_container.xml diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index d7b073b35..4929b3811 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -29,10 +29,13 @@ import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint +import `in`.koreatech.koin.domain.model.dining.DiningPlace import `in`.koreatech.koin.domain.util.DiningUtil import `in`.koreatech.koin.domain.util.ext.arrange import `in`.koreatech.koin.domain.util.ext.typeFilter +import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter import `in`.koreatech.koin.ui.store.contract.StoreActivityContract @AndroidEntryPoint @@ -51,6 +54,7 @@ class MainActivity : KoinNavigationDrawerActivity() { mainActivityViewModel.setSelectedPosition(it) } } + private val diningContainerAdapter by lazy { DiningContainerViewPager2Adapter(this) } private val storeCategoryRecyclerAdapter = StoreCategoryRecyclerAdapter().apply { setRecyclerViewClickListener(object : RecyclerViewClickListener { @@ -118,9 +122,11 @@ class MainActivity : KoinNavigationDrawerActivity() { // callDrawerItem(R.id.navi_item_dining) // } - DiningUtil.diningPlace.forEach { place -> - tabDining.addTab(tabDining.newTab().setText(place)) - } + pagerDiningContainer.adapter = diningContainerAdapter + + TabLayoutMediator(tabDining, pagerDiningContainer) { tab, position -> + tab.text = DiningPlace.entries[position].place + }.attach() } private fun initViewModel() = with(mainActivityViewModel) { diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/adapter/DiningContainerViewPager2Adapter.kt b/koin/src/main/java/in/koreatech/koin/ui/main/adapter/DiningContainerViewPager2Adapter.kt new file mode 100644 index 000000000..373b916fa --- /dev/null +++ b/koin/src/main/java/in/koreatech/koin/ui/main/adapter/DiningContainerViewPager2Adapter.kt @@ -0,0 +1,26 @@ +package `in`.koreatech.koin.ui.main.adapter + +import android.util.SparseArray +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import `in`.koreatech.koin.domain.model.dining.DiningPlace +import `in`.koreatech.koin.ui.main.fragment.DiningContainerFragment + +class DiningContainerViewPager2Adapter( + fragmentActivity: FragmentActivity +) : FragmentStateAdapter(fragmentActivity) { + private val fragments = SparseArray() + + override fun getItemCount(): Int = 4 + + override fun createFragment(position: Int): Fragment { + return fragments[position] ?: when (position) { + 0 -> DiningContainerFragment.newInstance(DiningPlace.CornerA.place) + 1 -> DiningContainerFragment.newInstance(DiningPlace.CornerB.place) + 2 -> DiningContainerFragment.newInstance(DiningPlace.CornerC.place) + 3 -> DiningContainerFragment.newInstance(DiningPlace.Nungsu.place) + else -> throw IllegalArgumentException("Position must be lower than $itemCount") + }.also { fragments[position] = it } + } +} \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt new file mode 100644 index 000000000..9fd6a4387 --- /dev/null +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -0,0 +1,38 @@ +package `in`.koreatech.koin.ui.main.fragment + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.util.dataBinding +import `in`.koreatech.koin.databinding.FragmentDiningContainerBinding +import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel + +class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { + private val binding by dataBinding() + private val viewModel by viewModels() + private val place by lazy { arguments?.getString(PLACE) } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initView() + } + + private fun initView() { + place.apply { + binding.textViewDiningContainer.text = this.toString() + } + } + + companion object { + private const val PLACE = "place" + fun newInstance(place: String) = + DiningContainerFragment().apply { + arguments = Bundle().apply { + putString(PLACE, place) + } + } + } +} \ No newline at end of file diff --git a/koin/src/main/res/layout/activity_main.xml b/koin/src/main/res/layout/activity_main.xml index bda749328..3cc8ff529 100644 --- a/koin/src/main/res/layout/activity_main.xml +++ b/koin/src/main/res/layout/activity_main.xml @@ -164,6 +164,11 @@ android:layout_height="1dp" android:background="#E1E1E1" /> + + diff --git a/koin/src/main/res/layout/fragment_dining_container.xml b/koin/src/main/res/layout/fragment_dining_container.xml new file mode 100644 index 000000000..33510c22f --- /dev/null +++ b/koin/src/main/res/layout/fragment_dining_container.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file From 3e1e9b8e93c91b660f4ab7e6abaab5b2c8a87ddc Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 12:06:18 +0900 Subject: [PATCH 04/61] #212 Change dining container layout --- .../koin/ui/main/activity/MainActivity.kt | 2 +- .../main/fragment/DiningContainerFragment.kt | 2 +- koin/src/main/res/layout/activity_main.xml | 8 +- .../res/layout/fragment_dining_container.xml | 221 +++++++++++++++++- koin/src/main/res/values/colors.xml | 4 + 5 files changed, 224 insertions(+), 13 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 4929b3811..434b9c004 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -145,7 +145,7 @@ class MainActivity : KoinNavigationDrawerActivity() { } observeLiveData(selectedType) { - binding.textViewDiningTime.text = it.localized(this@MainActivity) + binding.textViewDiningTodayOrTomorrow.text = it.localized(this@MainActivity) } observeLiveData(busTimer) { diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index 9fd6a4387..b9bf7e841 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -22,7 +22,7 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { private fun initView() { place.apply { - binding.textViewDiningContainer.text = this.toString() +// binding.textViewDiningContainer.text = this.toString() } } diff --git a/koin/src/main/res/layout/activity_main.xml b/koin/src/main/res/layout/activity_main.xml index 3cc8ff529..885a993eb 100644 --- a/koin/src/main/res/layout/activity_main.xml +++ b/koin/src/main/res/layout/activity_main.xml @@ -124,7 +124,7 @@ android:layout_height="wrap_content"> + tools:text="오늘" /> + app:layout_constraintStart_toEndOf="@id/text_view_dining_today_or_tomorrow" + app:layout_constraintTop_toTopOf="@id/text_view_dining_today_or_tomorrow" /> diff --git a/koin/src/main/res/layout/fragment_dining_container.xml b/koin/src/main/res/layout/fragment_dining_container.xml index 33510c22f..c788cca70 100644 --- a/koin/src/main/res/layout/fragment_dining_container.xml +++ b/koin/src/main/res/layout/fragment_dining_container.xml @@ -9,17 +9,224 @@ - + app:strokeColor="@color/container_stroke" + app:strokeWidth="1dp"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/koin/src/main/res/values/colors.xml b/koin/src/main/res/values/colors.xml index 3dcd010fd..f343c131f 100644 --- a/koin/src/main/res/values/colors.xml +++ b/koin/src/main/res/values/colors.xml @@ -6,4 +6,8 @@ #4B4B4B #EEEEEE + + #FAFAFA + #E1E1E1 + #EEEEEE \ No newline at end of file From 9ba6ee8670bc75d3452c30d3e3241c2f7c557781 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 14:38:09 +0900 Subject: [PATCH 05/61] #212 Connect menu data --- .../koin/ui/main/activity/MainActivity.kt | 115 +++--------------- .../main/fragment/DiningContainerFragment.kt | 84 ++++++++++++- 2 files changed, 98 insertions(+), 101 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 434b9c004..192a6de96 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -1,40 +1,27 @@ package `in`.koreatech.koin.ui.main.activity import `in`.koreatech.koin.R -import `in`.koreatech.koin.core.appbar.AppBarBase import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.viewpager.HorizontalMarginItemDecoration -import `in`.koreatech.koin.core.viewpager.ScaleCardPagerTransformer import `in`.koreatech.koin.core.viewpager.ScaledViewPager2Transformation import `in`.koreatech.koin.data.util.localized import `in`.koreatech.koin.databinding.ActivityMainBinding -import `in`.koreatech.koin.domain.model.dining.Dining -import `in`.koreatech.koin.domain.model.dining.DiningType import `in`.koreatech.koin.ui.main.StoreCategoryRecyclerAdapter import `in`.koreatech.koin.ui.main.adapter.BusPagerAdapter -import `in`.koreatech.koin.ui.main.adapter.DiningTypeAdapter -import `in`.koreatech.koin.ui.main.state.DiningTypeUiState import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel import `in`.koreatech.koin.ui.navigation.KoinNavigationDrawerActivity import `in`.koreatech.koin.ui.navigation.state.MenuState import `in`.koreatech.koin.util.ext.observeLiveData -import android.graphics.Point import android.os.Bundle import android.view.View -import android.view.WindowManager import androidx.activity.viewModels -import androidx.core.content.ContextCompat -import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.domain.model.dining.DiningPlace -import `in`.koreatech.koin.domain.util.DiningUtil -import `in`.koreatech.koin.domain.util.ext.arrange -import `in`.koreatech.koin.domain.util.ext.typeFilter import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter import `in`.koreatech.koin.ui.store.contract.StoreActivityContract @@ -43,16 +30,11 @@ class MainActivity : KoinNavigationDrawerActivity() { override val menuState = MenuState.Main private val binding by dataBinding(R.layout.activity_main) override val screenTitle = "코인 - 메인" - private val mainActivityViewModel by viewModels() + private val viewModel by viewModels() private val busPagerAdapter = BusPagerAdapter().apply { setOnCardClickListener { callDrawerItem(R.id.navi_item_bus, Bundle()) } - setOnSwitchClickListener { mainActivityViewModel.switchBusNode() } - } - private val diningTypeAdapter = DiningTypeAdapter().apply { - setOnItemClickListener { - mainActivityViewModel.setSelectedPosition(it) - } + setOnSwitchClickListener { viewModel.switchBusNode() } } private val diningContainerAdapter by lazy { DiningContainerViewPager2Adapter(this) } @@ -78,7 +60,7 @@ class MainActivity : KoinNavigationDrawerActivity() { override fun onResume() { super.onResume() - mainActivityViewModel.updateDining() + viewModel.updateDining() } private fun initView() = with(binding) { @@ -108,14 +90,8 @@ class MainActivity : KoinNavigationDrawerActivity() { adapter = storeCategoryRecyclerAdapter } -// recyclerViewDiningType.apply { -// layoutManager = -// LinearLayoutManager(this@MainActivity, RecyclerView.HORIZONTAL, false) -// adapter = diningTypeAdapter -// } - mainSwipeRefreshLayout.setOnRefreshListener { - mainActivityViewModel.updateDining() + viewModel.updateDining() } // diningContainer.setOnClickListener { @@ -127,23 +103,23 @@ class MainActivity : KoinNavigationDrawerActivity() { TabLayoutMediator(tabDining, pagerDiningContainer) { tab, position -> tab.text = DiningPlace.entries[position].place }.attach() + + tabDining.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { + override fun onTabSelected(tab: TabLayout.Tab) { + viewModel.setSelectedPosition(tab.position) + } + + override fun onTabUnselected(p0: TabLayout.Tab?) {} + + override fun onTabReselected(p0: TabLayout.Tab?) {} + }) } - private fun initViewModel() = with(mainActivityViewModel) { + private fun initViewModel() = with(viewModel) { observeLiveData(isLoading) { binding.mainSwipeRefreshLayout.isRefreshing = it } - observeLiveData(diningData) { - updateDining(it, selectedPosition.value ?: 0) - } - - observeLiveData(selectedPosition) { position -> - diningData.value?.let { list -> - updateDining(list, position) - } - } - observeLiveData(selectedType) { binding.textViewDiningTodayOrTomorrow.text = it.localized(this@MainActivity) } @@ -158,63 +134,4 @@ class MainActivity : KoinNavigationDrawerActivity() { bundle.putInt(StoreActivityContract.STORE_CATEGORY, position) callDrawerItem(R.id.navi_item_store, bundle) } - - fun updateDining(list: List, position: Int) { - val diningType = DiningUtil.getCurrentType() - val diningArranged = list - .typeFilter(diningType) - .arrange() - - diningTypeAdapter.submitList( - diningArranged - .mapIndexed { index, dining -> - DiningTypeUiState( - dining.place, - index == position - ) - } - ) - -// if (list.isEmpty() || position >= diningArranged.size) { -// binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true -// return -// } - -// binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false -// -// listOf( -// binding.textViewCardDiningMenu0, -// binding.textViewCardDiningMenu2, -// binding.textViewCardDiningMenu4, -// binding.textViewCardDiningMenu6, -// binding.textViewCardDiningMenu8, -// binding.textViewCardDiningMenu1, -// binding.textViewCardDiningMenu3, -// binding.textViewCardDiningMenu5, -// binding.textViewCardDiningMenu7, -// binding.textViewCardDiningMenu9 -// ).zip(diningArranged[position].menu).forEach { (textView, menu) -> -// textView.text = menu -// } - -// val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() -// val isChanged = diningArranged[position].changedAt.isNotEmpty() -// with (binding.textViewDiningStatus) { -// when { -// isSoldOut -> { -// text = context.getString(R.string.dining_soldout) -// setTextColor(ContextCompat.getColor(context, R.color.dining_soldout_text)) -// background = ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) -// } -// isChanged -> { -// text = context.getString(R.string.dining_changed) -// setTextColor(ContextCompat.getColor(context, R.color.dining_changed_text)) -// background = ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) -// } -// else -> { -// visibility = View.INVISIBLE -// } -// } -// } - } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index b9bf7e841..d4277b77c 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -2,22 +2,34 @@ package `in`.koreatech.koin.ui.main.fragment import android.os.Bundle import android.view.View +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels +import androidx.fragment.app.activityViewModels +import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.core.util.dataBinding +import `in`.koreatech.koin.data.util.localized import `in`.koreatech.koin.databinding.FragmentDiningContainerBinding +import `in`.koreatech.koin.domain.model.dining.Dining +import `in`.koreatech.koin.domain.util.DiningUtil +import `in`.koreatech.koin.domain.util.ext.arrange +import `in`.koreatech.koin.domain.util.ext.typeFilter import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel +import `in`.koreatech.koin.util.ext.observeLiveData +@AndroidEntryPoint class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { private val binding by dataBinding() - private val viewModel by viewModels() + private val viewModel by activityViewModels() private val place by lazy { arguments?.getString(PLACE) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initView() + addListener() + initViewModel() } private fun initView() { @@ -26,6 +38,74 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { } } + private fun addListener() { + + } + + private fun initViewModel() = with(viewModel) { + observeLiveData(diningData) { + updateDining(it, selectedPosition.value ?: 0) + } + + observeLiveData(selectedPosition) { position -> + diningData.value?.let { list -> + updateDining(list, position) + } + } + + observeLiveData(selectedType) { + binding.textViewDiningTime.text = it.localized(requireActivity()) + } + } + + fun updateDining(list: List, position: Int) { + val diningType = DiningUtil.getCurrentType() + val diningArranged = list + .typeFilter(diningType) + .arrange() + + if (list.isEmpty() || position >= diningArranged.size) { + binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true + return + } + binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false + + listOf( + binding.textViewDiningContainerMenu0, + binding.textViewDiningContainerMenu2, + binding.textViewDiningContainerMenu4, + binding.textViewDiningContainerMenu6, + binding.textViewDiningContainerMenu8, + binding.textViewDiningContainerMenu1, + binding.textViewDiningContainerMenu3, + binding.textViewDiningContainerMenu5, + binding.textViewDiningContainerMenu7, + binding.textViewDiningContainerMenu9 + ).zip(diningArranged[position].menu).forEach { (textView, menu) -> + textView.text = menu + } + + val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() + val isChanged = diningArranged[position].changedAt.isNotEmpty() + with (binding.textViewDiningStatus) { + when { + isSoldOut -> { + text = context.getString(R.string.dining_soldout) + setTextColor(ContextCompat.getColor(context, R.color.dining_soldout_text)) + background = ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) + } + isChanged -> { + text = context.getString(R.string.dining_changed) + setTextColor(ContextCompat.getColor(context, R.color.dining_changed_text)) + background = ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) + } + else -> { + visibility = View.INVISIBLE + } + } + } + } + companion object { private const val PLACE = "place" fun newInstance(place: String) = From 381ab3520b44b564a79d125ae26a39eb2624216a Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 16:31:04 +0900 Subject: [PATCH 06/61] #228 Fix issue related to changes in dining place selection --- .../domain/util/ext/DiningListExtensions.kt | 26 ++++++++++++---- .../koin/ui/main/activity/MainActivity.kt | 4 +-- .../main/fragment/DiningContainerFragment.kt | 30 +++++++++++-------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/domain/src/main/java/in/koreatech/koin/domain/util/ext/DiningListExtensions.kt b/domain/src/main/java/in/koreatech/koin/domain/util/ext/DiningListExtensions.kt index ff0816cfa..cb7058143 100644 --- a/domain/src/main/java/in/koreatech/koin/domain/util/ext/DiningListExtensions.kt +++ b/domain/src/main/java/in/koreatech/koin/domain/util/ext/DiningListExtensions.kt @@ -1,6 +1,7 @@ package `in`.koreatech.koin.domain.util.ext import `in`.koreatech.koin.domain.model.dining.Dining +import `in`.koreatech.koin.domain.model.dining.DiningPlace import `in`.koreatech.koin.domain.model.dining.DiningType fun List.typeFilter(type: DiningType) = this.filter { @@ -9,11 +10,26 @@ fun List.typeFilter(type: DiningType) = this.filter { fun List.arrange() = this.let { - val diningList = mutableListOf() - val campus2 = this.filter { it.place == "2캠퍼스" } val campus1 = this.filter { it.place != "2캠퍼스" } campus1.sortedBy { it.place } - diningList.addAll(campus1) - diningList.addAll(campus2) - diningList.toList() + val allPlaces = DiningPlace.entries.map { it.place } + + allPlaces.map { place -> + campus1.find { it.place == place } ?: Dining( + id = 0, + date = "", + type = "", + place = place, + priceCard = "", + priceCash = "", + kcal = "", + menu = listOf(), + imageUrl = "", + createdAt = "", + updatedAt = "", + soldoutAt = "", + changedAt = "", + error = "" + ) + } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 192a6de96..9db1bbc77 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -109,9 +109,9 @@ class MainActivity : KoinNavigationDrawerActivity() { viewModel.setSelectedPosition(tab.position) } - override fun onTabUnselected(p0: TabLayout.Tab?) {} + override fun onTabUnselected(tab: TabLayout.Tab) {} - override fun onTabReselected(p0: TabLayout.Tab?) {} + override fun onTabReselected(tab: TabLayout.Tab) {} }) } diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index d4277b77c..e87c641f2 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -63,14 +63,7 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { val diningArranged = list .typeFilter(diningType) .arrange() - - if (list.isEmpty() || position >= diningArranged.size) { - binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true - return - } - binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false - - listOf( + val menus = listOf( binding.textViewDiningContainerMenu0, binding.textViewDiningContainerMenu2, binding.textViewDiningContainerMenu4, @@ -81,24 +74,37 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { binding.textViewDiningContainerMenu5, binding.textViewDiningContainerMenu7, binding.textViewDiningContainerMenu9 - ).zip(diningArranged[position].menu).forEach { (textView, menu) -> + ) + + if (list.isEmpty() || diningArranged[position].menu.isEmpty()) { + binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true + return + } + binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false + + menus.forEach { it.text = "" } + menus.zip(diningArranged[position].menu).forEach { (textView, menu) -> textView.text = menu } val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() val isChanged = diningArranged[position].changedAt.isNotEmpty() - with (binding.textViewDiningStatus) { + with(binding.textViewDiningStatus) { when { isSoldOut -> { text = context.getString(R.string.dining_soldout) setTextColor(ContextCompat.getColor(context, R.color.dining_soldout_text)) - background = ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) + background = + ContextCompat.getDrawable(context, R.drawable.dining_soldout_fill_radius_4) } + isChanged -> { text = context.getString(R.string.dining_changed) setTextColor(ContextCompat.getColor(context, R.color.dining_changed_text)) - background = ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) + background = + ContextCompat.getDrawable(context, R.drawable.dining_changed_fill_radius_4) } + else -> { visibility = View.INVISIBLE } From 9ee2a2792bb0a2e6a570f123d18546a48bcbf524 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 17:09:12 +0900 Subject: [PATCH 07/61] #212 Show in title if menu is today or tomorrow --- .../in/koreatech/koin/data/util/DiningUtil.kt | 7 ++++- data/src/main/res/values/strings.xml | 3 ++- .../koin/ui/main/activity/MainActivity.kt | 26 +++++++++---------- .../main/fragment/DiningContainerFragment.kt | 7 ----- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/data/src/main/java/in/koreatech/koin/data/util/DiningUtil.kt b/data/src/main/java/in/koreatech/koin/data/util/DiningUtil.kt index d8352345d..6e3f1fa5b 100644 --- a/data/src/main/java/in/koreatech/koin/data/util/DiningUtil.kt +++ b/data/src/main/java/in/koreatech/koin/data/util/DiningUtil.kt @@ -8,5 +8,10 @@ fun DiningType.localized(context: Context) = when(this) { DiningType.Breakfast -> context.getString(R.string.dining_breakfast) DiningType.Lunch -> context.getString(R.string.dining_lunch) DiningType.Dinner -> context.getString(R.string.dining_dinner) - DiningType.NextBreakfast -> context.getString(R.string.dining_next_breakfast) + else -> context.getString(R.string.dining_breakfast) +} + +fun DiningType.todayOrTomorrow(context: Context) = when(this) { + DiningType.NextBreakfast -> context.getString(R.string.dining_tomorrow) + else -> context.getString(R.string.dining_today) } \ No newline at end of file diff --git a/data/src/main/res/values/strings.xml b/data/src/main/res/values/strings.xml index b51abd41f..919578216 100644 --- a/data/src/main/res/values/strings.xml +++ b/data/src/main/res/values/strings.xml @@ -61,5 +61,6 @@ 아침 점심 저녁 - 내일 아침 + 오늘 + 내일 \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 9db1bbc77..1650c7086 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -1,29 +1,29 @@ package `in`.koreatech.koin.ui.main.activity +import android.os.Bundle +import android.view.View +import androidx.activity.viewModels +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator +import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.viewpager.HorizontalMarginItemDecoration import `in`.koreatech.koin.core.viewpager.ScaledViewPager2Transformation -import `in`.koreatech.koin.data.util.localized +import `in`.koreatech.koin.data.util.todayOrTomorrow import `in`.koreatech.koin.databinding.ActivityMainBinding +import `in`.koreatech.koin.domain.model.dining.DiningPlace import `in`.koreatech.koin.ui.main.StoreCategoryRecyclerAdapter import `in`.koreatech.koin.ui.main.adapter.BusPagerAdapter +import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel import `in`.koreatech.koin.ui.navigation.KoinNavigationDrawerActivity import `in`.koreatech.koin.ui.navigation.state.MenuState -import `in`.koreatech.koin.util.ext.observeLiveData -import android.os.Bundle -import android.view.View -import androidx.activity.viewModels -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayoutMediator -import dagger.hilt.android.AndroidEntryPoint -import `in`.koreatech.koin.domain.model.dining.DiningPlace -import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter import `in`.koreatech.koin.ui.store.contract.StoreActivityContract +import `in`.koreatech.koin.util.ext.observeLiveData @AndroidEntryPoint class MainActivity : KoinNavigationDrawerActivity() { @@ -121,7 +121,7 @@ class MainActivity : KoinNavigationDrawerActivity() { } observeLiveData(selectedType) { - binding.textViewDiningTodayOrTomorrow.text = it.localized(this@MainActivity) + binding.textViewDiningTodayOrTomorrow.text = it.todayOrTomorrow(this@MainActivity) } observeLiveData(busTimer) { diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index e87c641f2..8be0868e9 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -28,17 +28,10 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { super.onViewCreated(view, savedInstanceState) initView() - addListener() initViewModel() } private fun initView() { - place.apply { -// binding.textViewDiningContainer.text = this.toString() - } - } - - private fun addListener() { } From f693a326232403122bf816cf09bff330c035dcff Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 17:40:50 +0900 Subject: [PATCH 08/61] #212 Add dining container click listener --- .../koin/ui/main/fragment/DiningContainerFragment.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index 8be0868e9..fbc1fe8c8 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -15,6 +15,7 @@ import `in`.koreatech.koin.domain.model.dining.Dining import `in`.koreatech.koin.domain.util.DiningUtil import `in`.koreatech.koin.domain.util.ext.arrange import `in`.koreatech.koin.domain.util.ext.typeFilter +import `in`.koreatech.koin.ui.main.activity.MainActivity import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel import `in`.koreatech.koin.util.ext.observeLiveData @@ -31,8 +32,13 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { initViewModel() } - private fun initView() { - + private fun initView() = with(binding) { + diningContainer.setOnClickListener { + if (activity is MainActivity) { + val mainActivity = activity as MainActivity + mainActivity.callDrawerItem(R.id.navi_item_dining) + } + } } private fun initViewModel() = with(viewModel) { From 84b351280fd5073f22bed860e916334ae78170d3 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 17:54:19 +0900 Subject: [PATCH 09/61] Modify dining detail to respond properly to dining list changes --- .../java/in/koreatech/koin/ui/dining/DiningItemsFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningItemsFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningItemsFragment.kt index d57533adb..b4398939f 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningItemsFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningItemsFragment.kt @@ -32,7 +32,8 @@ class DiningItemsFragment : Fragment(R.layout.fragment_dining_items) { lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.dining.collect { - diningAdapter.submitList(it.filter { dining -> dining.type == type}.arrange() ) + val diningList = it.filter { dining -> dining.type == type }.arrange() + diningAdapter.submitList( diningList.filter { dining -> dining.menu.isNotEmpty() } ) } } } From 2213bd7c2023f112688395268df207c2af82d23e Mon Sep 17 00:00:00 2001 From: wateralsie Date: Tue, 16 Apr 2024 18:07:14 +0900 Subject: [PATCH 10/61] Divide updateDining to two functions --- .../ui/main/fragment/DiningContainerFragment.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index fbc1fe8c8..6446040e8 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -62,6 +62,12 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { val diningArranged = list .typeFilter(diningType) .arrange() + + updateMenu(list, position, diningArranged) + updateStatus(position, diningArranged) + } + + private fun updateMenu(list: List, position: Int, arrangedList: List) { val menus = listOf( binding.textViewDiningContainerMenu0, binding.textViewDiningContainerMenu2, @@ -75,19 +81,21 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { binding.textViewDiningContainerMenu9 ) - if (list.isEmpty() || diningArranged[position].menu.isEmpty()) { + if (list.isEmpty() || arrangedList[position].menu.isEmpty()) { binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true return } binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false menus.forEach { it.text = "" } - menus.zip(diningArranged[position].menu).forEach { (textView, menu) -> + menus.zip(arrangedList[position].menu).forEach { (textView, menu) -> textView.text = menu } + } - val isSoldOut = diningArranged[position].soldoutAt.isNotEmpty() - val isChanged = diningArranged[position].changedAt.isNotEmpty() + private fun updateStatus(position: Int, arrangedList: List) { + val isSoldOut = arrangedList[position].soldoutAt.isNotEmpty() + val isChanged = arrangedList[position].changedAt.isNotEmpty() with(binding.textViewDiningStatus) { when { isSoldOut -> { From 4eb658da151854e199cfa217908cdb002104e420 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Thu, 18 Apr 2024 14:44:23 +0900 Subject: [PATCH 11/61] Change menu layout 10 -> 2 textview --- .../main/fragment/DiningContainerFragment.kt | 33 ++-- .../res/layout/fragment_dining_container.xml | 166 +++--------------- 2 files changed, 38 insertions(+), 161 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index 6446040e8..d040cdc44 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -57,39 +57,30 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { } } - fun updateDining(list: List, position: Int) { + fun updateDining(originalList: List, position: Int) { val diningType = DiningUtil.getCurrentType() - val diningArranged = list + val diningArranged = originalList .typeFilter(diningType) .arrange() - updateMenu(list, position, diningArranged) + updateMenu(originalList, diningArranged, position) updateStatus(position, diningArranged) } - private fun updateMenu(list: List, position: Int, arrangedList: List) { - val menus = listOf( - binding.textViewDiningContainerMenu0, - binding.textViewDiningContainerMenu2, - binding.textViewDiningContainerMenu4, - binding.textViewDiningContainerMenu6, - binding.textViewDiningContainerMenu8, - binding.textViewDiningContainerMenu1, - binding.textViewDiningContainerMenu3, - binding.textViewDiningContainerMenu5, - binding.textViewDiningContainerMenu7, - binding.textViewDiningContainerMenu9 - ) - - if (list.isEmpty() || arrangedList[position].menu.isEmpty()) { + private fun updateMenu(originalList: List, arrangedList: List, position: Int) { + if (originalList.isEmpty() || arrangedList[position].menu.isEmpty()) { binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = true return } binding.viewEmptyDining.emptyDiningListFrameLayout.isVisible = false - menus.forEach { it.text = "" } - menus.zip(arrangedList[position].menu).forEach { (textView, menu) -> - textView.text = menu + val menus = listOf(binding.textViewDiningContainerMenuLeft, binding.textViewDiningContainerMenuRight) + val limit = arrangedList[position].menu.size.coerceAtMost(5) + menus.forEachIndexed { index, textView -> + textView.text = when (index) { + 0 -> arrangedList[position].menu.subList(0, limit).joinToString("\n") + else -> arrangedList[position].menu.subList(limit, arrangedList[position].menu.size).joinToString("\n") + } } } diff --git a/koin/src/main/res/layout/fragment_dining_container.xml b/koin/src/main/res/layout/fragment_dining_container.xml index c788cca70..5bb57ab92 100644 --- a/koin/src/main/res/layout/fragment_dining_container.xml +++ b/koin/src/main/res/layout/fragment_dining_container.xml @@ -67,151 +67,37 @@ android:background="@color/container_stroke_inside" app:layout_constraintTop_toBottomOf="@id/text_view_dining_status" /> - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/view_dining_container_line" /> Date: Mon, 22 Apr 2024 22:14:36 +0900 Subject: [PATCH 12/61] Fix filtering major on timetable --- .../koin/ui/timetable/TimetableSelectMajorDialog.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/timetable/TimetableSelectMajorDialog.java b/koin/src/main/java/in/koreatech/koin/ui/timetable/TimetableSelectMajorDialog.java index 09dcbec1e..1c5781b7c 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/timetable/TimetableSelectMajorDialog.java +++ b/koin/src/main/java/in/koreatech/koin/ui/timetable/TimetableSelectMajorDialog.java @@ -51,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { } public void setOnCLickedDialogItemListener(OnCLickedDialogItemListener onCLickedDialogItemListener) { - onCLickedDialogItemListener = onCLickedDialogItemListener; + this.onCLickedDialogItemListener = onCLickedDialogItemListener; } public void setMajorDialogListener(MajorDialogListener majorDialogListener) { @@ -179,7 +179,7 @@ public void onClick(View view) { if (toggleButton[1].isChecked()) { OffToggleButton(1); onClickedItem(DepartmentCode.DEPARTMENT_CODE_3); - majorDialogListener.sendActivity("elecronic", 1); + majorDialogListener.sendActivity("electronic", 1); toggleButton[1].setBackgroundResource(R.drawable.button_rect_squash_radius); toggleButton[1].setTextColor(ContextCompat.getColor(getContext(), R.color.white)); } else { @@ -227,7 +227,7 @@ public void onClick(View view) { if (toggleButton[5].isChecked()) { OffToggleButton(5); onClickedItem(DepartmentCode.DEPARTMENT_CODE_2); - majorDialogListener.sendActivity("mecchanical", 5); + majorDialogListener.sendActivity("mechanical", 5); toggleButton[5].setBackgroundResource(R.drawable.button_rect_squash_radius); toggleButton[5].setTextColor(ContextCompat.getColor(getContext(), R.color.white)); } else { From d2011e8911b1baa7b680afcb40d225dcdf81f813 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 24 Apr 2024 18:47:43 +0900 Subject: [PATCH 13/61] Change dining text, image location --- koin/src/main/res/layout/item_dining.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/koin/src/main/res/layout/item_dining.xml b/koin/src/main/res/layout/item_dining.xml index c7bb6d449..5992cc7f7 100644 --- a/koin/src/main/res/layout/item_dining.xml +++ b/koin/src/main/res/layout/item_dining.xml @@ -98,10 +98,10 @@ android:layout_width="202dp" android:layout_height="132dp" android:layout_marginTop="16dp" - android:layout_marginEnd="24dp" app:cardCornerRadius="10dp" app:cardElevation="0dp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + android:layout_marginStart="24dp" app:layout_constraintTop_toBottomOf="@id/linear_layout_dining_information" app:rippleColor="@android:color/transparent" app:strokeColor="#CACACA" @@ -193,8 +193,8 @@ android:minHeight="132dp" android:textColor="@color/black" android:textSize="12sp" - app:layout_constraintEnd_toStartOf="@id/card_view_dining" - app:layout_constraintStart_toStartOf="parent" + app:layout_constraintStart_toEndOf="@id/card_view_dining" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/card_view_dining" tools:text="혼합잡곡밥&흰밥\n호박고추장국\n닭살두반장볶음(chicken) \n옥수수콘김치전\n미역줄기무침\n깍두기" /> From 56279cf6b053949351cc819445acf805b01f1d05 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 24 Apr 2024 18:57:21 +0900 Subject: [PATCH 14/61] =?UTF-8?q?Set=20=EB=8A=A5=EC=88=98=EA=B4=80,=202?= =?UTF-8?q?=EC=BA=A0=ED=8D=BC=EC=8A=A4=20image=20visibility=20gone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/ui/dining/adapter/DiningAdapter.kt | 8 + koin/src/main/res/layout/item_dining.xml | 229 +++++++++--------- 2 files changed, 126 insertions(+), 111 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index 3d56b696a..32e3be290 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -8,6 +8,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView +import android.widget.LinearLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.core.view.marginStart import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView @@ -52,6 +55,11 @@ class DiningAdapter : ListAdapter(diffCallback) with(binding) { val context = root.context textViewDiningCorner.text = dining.place + when(dining.place) { + "능수관", "2캠퍼스" -> cardViewDining.visibility = View.GONE + else -> cardViewDining.visibility = View.VISIBLE + } + textViewKcal.text = context.getString(R.string.dining_kcal, dining.kcal) textViewCashPrice.text = diff --git a/koin/src/main/res/layout/item_dining.xml b/koin/src/main/res/layout/item_dining.xml index 5992cc7f7..63b96b6c8 100644 --- a/koin/src/main/res/layout/item_dining.xml +++ b/koin/src/main/res/layout/item_dining.xml @@ -11,17 +11,17 @@ android:id="@+id/linear_layout_dining_information" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintStart_toStartOf="parent" - android:paddingTop="16dp" + android:layout_marginStart="24dp" android:gravity="center_vertical" - android:orientation="horizontal"> + android:orientation="horizontal" + android:paddingTop="16dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@id/linear_layout_dining_information" + app:layout_constraintEnd_toEndOf="parent" /> + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@id/linear_layout_dining_information" + app:layout_constraintEnd_toEndOf="parent" /> - - - - - + + + + - - - - - - - - - - - - - - - + android:background="#FAFAFA"> + + + + + + + + + + + + + + + + + - + + app:layout_constraintTop_toBottomOf="@id/linear_layout_dining_content" /> From 5b2965d136ee9a41ce9338c474282c63f537c838 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 19:15:38 +0900 Subject: [PATCH 15/61] Add Activity analytics event log function --- .../koin/core/activity/ActivityBase.kt | 34 +++++++++++++++++++ .../koin/core/constant/AnalyticsConstant.kt | 19 +++++++++++ 2 files changed, 53 insertions(+) create mode 100644 core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt diff --git a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt index a8e928ad9..d997a5446 100644 --- a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt +++ b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt @@ -10,6 +10,7 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.progressdialog.CustomProgressDialog import `in`.koreatech.koin.core.progressdialog.IProgressDialog @@ -58,6 +59,39 @@ abstract class ActivityBase : AppCompatActivity, IProgressDialog { } } + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + */ + protected fun logClickEvent(action: String, label: String, value: String) { + logEvent(action, AnalyticsConstant.Category.CLICK, label, value) + } + + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + */ + protected fun logScrollEvent(action: String, label: String, value: String) { + logEvent(action, AnalyticsConstant.Category.SCROLL, label, value) + } + + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param category: 이벤트 종류(click, scroll, ...) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + * @sample logEvent("BUSINESS", "click", "main_store_categories", "전체보기") + */ + private fun logEvent(action: String, category: String, label: String, value: String) { + Firebase.analytics.logEvent(action) { + param("event_category", category) + param("event_label", label) + param("value", value) + } + } + companion object { const val INPUT_METHOD_SERVICE: String = Context.INPUT_METHOD_SERVICE const val PAGE_TITLE = "page_title" diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt new file mode 100644 index 000000000..83c7d0007 --- /dev/null +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -0,0 +1,19 @@ +package `in`.koreatech.koin.core.constant + +object AnalyticsConstant { + + object Domain { + const val BUSINESS = "BUSINESS" + const val CAMPUS = "CAMPUS" + const val USER = "USER" + } + + object Category { + const val CLICK = "click" + const val SCROLL = "scroll" + } + + object Label { + + } +} \ No newline at end of file From 1398d58ac7261dd126f36bafbd394a5be3f3efb0 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 19:53:37 +0900 Subject: [PATCH 16/61] Add main page store click event analytics --- .../in/koreatech/koin/core/constant/AnalyticsConstant.kt | 3 ++- .../in/koreatech/koin/ui/main/activity/MainActivity.kt | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 83c7d0007..ea5bdd5dc 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -14,6 +14,7 @@ object AnalyticsConstant { } object Label { - + const val MAIN_STORE_CATEGORIES = "main_store_categories" } + } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 1650c7086..dfe9687d3 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -2,6 +2,7 @@ package `in`.koreatech.koin.ui.main.activity import android.os.Bundle import android.view.View +import android.widget.TextView import androidx.activity.viewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -9,6 +10,7 @@ import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.viewpager.HorizontalMarginItemDecoration @@ -42,6 +44,11 @@ class MainActivity : KoinNavigationDrawerActivity() { setRecyclerViewClickListener(object : RecyclerViewClickListener { override fun onClick(view: View?, position: Int) { gotoStoreActivity(position) + logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + AnalyticsConstant.Label.MAIN_STORE_CATEGORIES, + view?.findViewById(R.id.text_view_store_category)?.text.toString() + ) } override fun onLongClick(view: View?, position: Int) { From d06b6cbf769ca5e5086e9ab6cd2b7713fda6743d Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 19:57:51 +0900 Subject: [PATCH 17/61] Add StoreActivity category click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 1 + .../koin/ui/store/activity/StoreActivity.kt | 21 +++++++++++++++++++ koin/src/main/res/values/strings.xml | 10 +++++++++ 3 files changed, 32 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index ea5bdd5dc..984c53c38 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -15,6 +15,7 @@ object AnalyticsConstant { object Label { const val MAIN_STORE_CATEGORIES = "main_store_categories" + const val STORE_CATEGORIES = "store_categories" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index 832669f91..aaa359842 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -15,6 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.core.appbar.AppBarBase +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.databinding.StoreActivityMainBinding import `in`.koreatech.koin.domain.model.store.StoreCategory @@ -197,6 +198,26 @@ class StoreActivity : KoinNavigationDrawerActivity() { private fun View.setCategoryOnClick(category: StoreCategory) { setOnClickListener { + var eventValue = when(category) { + StoreCategory.Chicken -> getString(R.string.chicken) + StoreCategory.Pizza -> getString(R.string.pizza) + StoreCategory.DOSIRAK -> getString(R.string.dorisak) + StoreCategory.PorkFeet -> getString(R.string.pork_feet) + StoreCategory.Chinese -> getString(R.string.chinese) + StoreCategory.NormalFood -> getString(R.string.normal_food) + StoreCategory.Cafe -> getString(R.string.cafe) + StoreCategory.BeautySalon -> getString(R.string.beauty_salon) + StoreCategory.Etc -> getString(R.string.etc) + else -> "" + } + if(viewModel.category.value == category) + eventValue = getString(R.string.unselect_see_all) + + logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + AnalyticsConstant.Label.STORE_CATEGORIES, + eventValue) + binding.searchEditText.clearFocus() viewModel.setCategory(category) } diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 3239f24c4..ecec68477 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -371,4 +371,14 @@ 품절 변경됨 %1$s원 + 치킨 + 피자 + 도시락 + 족발 + 중국집 + 일반음식 + 카페 + 미용실 + 기타 + 미지정(전체보기) From 48eb8fd42ed20cea35bc84eaf0fa839b97c5da26 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 20:00:11 +0900 Subject: [PATCH 18/61] Add Store click event analytics --- .../java/in/koreatech/koin/ui/store/activity/StoreActivity.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index aaa359842..e3d9cc979 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -47,6 +47,10 @@ class StoreActivity : KoinNavigationDrawerActivity() { private val storeAdapter = StoreRecyclerAdapter().apply { setOnItemClickListener { storeDetailContract.launch(it.uid) + logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + "store_${it.name}_click", + it.name) } } From bd58a08ca0908d7fd474b85798cf8ae384cfa11d Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 20:02:27 +0900 Subject: [PATCH 19/61] Add StoreDetail call click event analytics --- .../koreatech/koin/ui/store/activity/StoreDetailActivity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt index 785386cb9..8a2358e9a 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt @@ -8,6 +8,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.toast.ToastUtil import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.databinding.StoreActivityDetailBinding @@ -120,6 +121,10 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { binding.storeDetailCallButton.setOnClickListener { showCallDialog() + logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + "store_${viewModel.store.value?.name ?: "Unknown"}_call", + viewModel.store.value?.name ?: "Unknown") } binding.menuSpreadTextView.setOnClickListener { From 6f8efdab6c177be41df7a5ebb7717e4ab5354f6a Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 20:03:21 +0900 Subject: [PATCH 20/61] Add StoreDetail picture click event analytics --- .../koreatech/koin/ui/store/activity/StoreDetailActivity.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt index 8a2358e9a..87a060cc3 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt @@ -85,6 +85,10 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { flyerDialogFragment = StoreFlyerDialogFragment() flyerDialogFragment?.initialPosition = position flyerDialogFragment?.show(supportFragmentManager, DIALOG_TAG) + logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + "store_${viewModel.store.value?.name ?: "Unknown"}_picture", + viewModel.store.value?.name ?: "Unknown") } } From 506d28c691e53cd01beae041effb53cf6f9972e7 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 20:58:57 +0900 Subject: [PATCH 21/61] Create EventLogger, move activity logging logic to EventLogger --- .../koin/core/activity/ActivityBase.kt | 34 +-------------- .../koin/core/analytics/EventLogger.kt | 42 +++++++++++++++++++ .../koin/ui/main/activity/MainActivity.kt | 3 +- .../koin/ui/store/activity/StoreActivity.kt | 5 ++- .../ui/store/activity/StoreDetailActivity.kt | 5 ++- 5 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt diff --git a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt index d997a5446..59a95cc32 100644 --- a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt +++ b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt @@ -10,6 +10,7 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase +import `in`.koreatech.koin.core.analytics.EventLogger import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.progressdialog.CustomProgressDialog import `in`.koreatech.koin.core.progressdialog.IProgressDialog @@ -59,39 +60,6 @@ abstract class ActivityBase : AppCompatActivity, IProgressDialog { } } - /** - * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) - * @param label: 이벤트 소분류 - * @param value: 이벤트 값 - */ - protected fun logClickEvent(action: String, label: String, value: String) { - logEvent(action, AnalyticsConstant.Category.CLICK, label, value) - } - - /** - * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) - * @param label: 이벤트 소분류 - * @param value: 이벤트 값 - */ - protected fun logScrollEvent(action: String, label: String, value: String) { - logEvent(action, AnalyticsConstant.Category.SCROLL, label, value) - } - - /** - * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) - * @param category: 이벤트 종류(click, scroll, ...) - * @param label: 이벤트 소분류 - * @param value: 이벤트 값 - * @sample logEvent("BUSINESS", "click", "main_store_categories", "전체보기") - */ - private fun logEvent(action: String, category: String, label: String, value: String) { - Firebase.analytics.logEvent(action) { - param("event_category", category) - param("event_label", label) - param("value", value) - } - } - companion object { const val INPUT_METHOD_SERVICE: String = Context.INPUT_METHOD_SERVICE const val PAGE_TITLE = "page_title" diff --git a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt new file mode 100644 index 000000000..2b04e53eb --- /dev/null +++ b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt @@ -0,0 +1,42 @@ +package `in`.koreatech.koin.core.analytics + +import com.google.firebase.analytics.ktx.analytics +import com.google.firebase.analytics.ktx.logEvent +import com.google.firebase.ktx.Firebase +import `in`.koreatech.koin.core.constant.AnalyticsConstant + +object EventLogger { + + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + */ + fun logClickEvent(action: String, label: String, value: String) { + logEvent(action, AnalyticsConstant.Category.CLICK, label, value) + } + + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + */ + fun logScrollEvent(action: String, label: String, value: String) { + logEvent(action, AnalyticsConstant.Category.SCROLL, label, value) + } + + /** + * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) + * @param category: 이벤트 종류(click, scroll, ...) + * @param label: 이벤트 소분류 + * @param value: 이벤트 값 + * @sample logEvent("BUSINESS", "click", "main_store_categories", "전체보기") + */ + private fun logEvent(action: String, category: String, label: String, value: String) { + Firebase.analytics.logEvent(action) { + param("event_category", category) + param("event_label", label) + param("value", value) + } + } +} \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index dfe9687d3..f75b85df4 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -10,6 +10,7 @@ import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding @@ -44,7 +45,7 @@ class MainActivity : KoinNavigationDrawerActivity() { setRecyclerViewClickListener(object : RecyclerViewClickListener { override fun onClick(view: View?, position: Int) { gotoStoreActivity(position) - logClickEvent( + EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, AnalyticsConstant.Label.MAIN_STORE_CATEGORIES, view?.findViewById(R.id.text_view_store_category)?.text.toString() diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index e3d9cc979..7ed9f01df 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -14,6 +14,7 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger import `in`.koreatech.koin.core.appbar.AppBarBase import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding @@ -47,7 +48,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { private val storeAdapter = StoreRecyclerAdapter().apply { setOnItemClickListener { storeDetailContract.launch(it.uid) - logClickEvent( + EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, "store_${it.name}_click", it.name) @@ -217,7 +218,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { if(viewModel.category.value == category) eventValue = getString(R.string.unselect_see_all) - logClickEvent( + EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, AnalyticsConstant.Label.STORE_CATEGORIES, eventValue) diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt index 87a060cc3..17d567e65 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt @@ -8,6 +8,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.toast.ToastUtil import `in`.koreatech.koin.core.util.dataBinding @@ -85,7 +86,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { flyerDialogFragment = StoreFlyerDialogFragment() flyerDialogFragment?.initialPosition = position flyerDialogFragment?.show(supportFragmentManager, DIALOG_TAG) - logClickEvent( + EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, "store_${viewModel.store.value?.name ?: "Unknown"}_picture", viewModel.store.value?.name ?: "Unknown") @@ -125,7 +126,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { binding.storeDetailCallButton.setOnClickListener { showCallDialog() - logClickEvent( + EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, "store_${viewModel.store.value?.name ?: "Unknown"}_call", viewModel.store.value?.name ?: "Unknown") From bf0ff79783056d6b5af8836d283e2dc542510aa6 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 21:13:58 +0900 Subject: [PATCH 22/61] Add Hamburger click event analytics --- .../koin/core/appbar/AppBarBase.java | 11 +++++- .../koin/core/constant/AnalyticsConstant.kt | 7 ++++ core/src/main/res/values/strings.xml | 1 + .../koin/ui/main/activity/MainActivity.kt | 5 +++ .../KoinNavigationDrawerActivity.kt | 38 +++++++++++++++++-- koin/src/main/res/values/strings.xml | 2 + 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java b/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java index 9408291f0..e07a4b085 100644 --- a/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java +++ b/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java @@ -17,6 +17,8 @@ import in.koreatech.koin.core.R; +import in.koreatech.koin.core.analytics.EventLogger; +import in.koreatech.koin.core.constant.AnalyticsConstant; public class AppBarBase extends AppBarLayout { @@ -50,7 +52,14 @@ public void setOnClickListener(OnClickListener onClickListener) { this.onClickListener = onClickListener; background.setOnClickListener(onClickListener); leftButton.setOnClickListener(onClickListener); - rightButton.setOnClickListener(onClickListener); + rightButton.setOnClickListener(v -> { + onClickListener.onClick(v); + EventLogger.INSTANCE.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.HAMBURGER, + getContext().getString(R.string.hamburger) + ); + }); title.setOnClickListener(onClickListener); } diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 984c53c38..2c8ecfd78 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -16,6 +16,13 @@ object AnalyticsConstant { object Label { const val MAIN_STORE_CATEGORIES = "main_store_categories" const val STORE_CATEGORIES = "store_categories" + const val HAMBURGER = "hamburger" + const val HAMBURGER_STORE = "${HAMBURGER}_store" + const val HAMBURGER_DINING = "${HAMBURGER}_dining" + const val HAMBURGER_MY_INFO_WITHOUT_LOGIN = "${HAMBURGER}_my_info_without_login" + const val HAMBURGER_MY_INFO_WITH_LOGIN = "${HAMBURGER}_my_info_with_login" + const val HAMBURGER_BUS = "${HAMBURGER}_bus" + const val USER_ONLY_OK = "user_only_ok" } } \ No newline at end of file diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index f6bee74e2..e97e247f1 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -76,4 +76,5 @@ 문의하기 님, 안녕하세요! 내 정보 + 햄버거 diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index f75b85df4..61f31ee4c 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -74,6 +74,11 @@ class MainActivity : KoinNavigationDrawerActivity() { private fun initView() = with(binding) { buttonCategory.setOnClickListener { toggleNavigationDrawer() + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.HAMBURGER, + getString(R.string.hamburger) + ) } busViewPager.apply { diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index cc422db7c..27343f2d9 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -19,6 +19,8 @@ import `in`.koreatech.koin.BuildConfig import `in`.koreatech.koin.R import `in`.koreatech.koin.core.activity.ActivityBase import `in`.koreatech.koin.core.activity.WebViewActivity +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.toast.ToastUtil import `in`.koreatech.koin.data.constant.URLConstant import `in`.koreatech.koin.domain.model.user.User @@ -203,12 +205,31 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), } observeLiveData(menuEvent) { menuState -> + var action = "" + var label = "" + var value = "" when (menuState) { - MenuState.Bus -> goToBusActivity() - MenuState.Dining -> goToDiningActivity() + MenuState.Bus -> { + action = AnalyticsConstant.Domain.CAMPUS + label = AnalyticsConstant.Label.HAMBURGER_BUS + value = getString(R.string.navigation_item_bus) + goToBusActivity() + } + MenuState.Dining -> { + action = AnalyticsConstant.Domain.CAMPUS + label = AnalyticsConstant.Label.HAMBURGER_DINING + value = getString(R.string.navigation_item_dining) + goToDiningActivity() + } MenuState.Land -> goToLandActivity() MenuState.Main -> goToMainActivity() - MenuState.Store -> goToStoreActivity() + MenuState.Store -> { + action = AnalyticsConstant.Domain.BUSINESS + label = AnalyticsConstant.Label.HAMBURGER_STORE + value = getString(R.string.nearby_stores) + goToStoreActivity() + } + MenuState.Timetable -> { if (userState.value == null || userState.value?.isAnonymous == true) { goToAnonymousTimeTableActivity() @@ -218,15 +239,19 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), } MenuState.UserInfo -> { + action = AnalyticsConstant.Domain.USER + value = getString(R.string.navigation_drawer_right_myinfo) if (userState.value == null || userState.value?.isAnonymous == true) { + label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITHOUT_LOGIN showLoginRequestDialog() } else { + label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITH_LOGIN goToUserInfoActivity() } } - else -> Unit } + EventLogger.logClickEvent(action, label, value) drawerLayout.closeDrawer() } } @@ -379,6 +404,11 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), ) intent.putExtra("FIRST_LOGIN", false) startActivity(intent) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.USER_ONLY_OK, + getString(R.string.user_only_ok) + ) overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.fade_out) } .setNegativeButton(getString(R.string.navigation_cancel)) { dialog, _ -> diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index ecec68477..c9e10f5c8 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -381,4 +381,6 @@ 미용실 기타 미지정(전체보기) + 주변상점 + 회원전용 확인 From dc6bfe672c3f4ae39ef2021dd7526c3e39530703 Mon Sep 17 00:00:00 2001 From: DoHyeok Kim Date: Thu, 25 Apr 2024 17:32:54 +0900 Subject: [PATCH 23/61] Fix SingleLiveEvent call logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Observer.onChanged() 의 매개변수가 non-null 로 변경됨에 따라 로직 변경 --- .../koreatech/koin/core/viewmodel/SingleLiveEvent.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/viewmodel/SingleLiveEvent.kt b/core/src/main/java/in/koreatech/koin/core/viewmodel/SingleLiveEvent.kt index e269f2c08..0bb42cbc8 100644 --- a/core/src/main/java/in/koreatech/koin/core/viewmodel/SingleLiveEvent.kt +++ b/core/src/main/java/in/koreatech/koin/core/viewmodel/SingleLiveEvent.kt @@ -14,13 +14,13 @@ class SingleLiveEvent : MutableLiveData() { override fun observe(owner: LifecycleOwner, observer: Observer) { if (hasActiveObservers()) { - Log.w(TAG,"Multiple observers registered but only one will be notified of changes.") + Log.w(TAG, "Multiple observers registered but only one will be notified of changes.") } // Observe the internal MutableLiveData - super.observe(owner) { t -> + super.observe(owner) { if (pending.compareAndSet(true, false)) { - observer.onChanged(t) + observer.onChanged(it) } } } @@ -32,11 +32,12 @@ class SingleLiveEvent : MutableLiveData() { } /** - * Used for cases where T is Void, to make calls cleaner. + * Used for cases where T is Unit, to make calls cleaner. */ @MainThread fun call() { - value = null + assert(value is Unit || value is Unit?) + value = Unit as T } companion object { From 6f524e3b13d92399db12791f751563a6ceada566 Mon Sep 17 00:00:00 2001 From: DoHyeok Kim Date: Thu, 25 Apr 2024 23:56:24 +0900 Subject: [PATCH 24/61] Fix to show dash on UserInfoEdit screen --- .../res/layout/activity_user_info_edited.xml | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/koin/src/main/res/layout/activity_user_info_edited.xml b/koin/src/main/res/layout/activity_user_info_edited.xml index 111d25422..43df57738 100644 --- a/koin/src/main/res/layout/activity_user_info_edited.xml +++ b/koin/src/main/res/layout/activity_user_info_edited.xml @@ -26,14 +26,12 @@ app:rightButtonBackground="@drawable/ic_create" app:titleText="내정보" /> - - - - - + app:layout_constraintTop_toBottomOf="@id/userinfoedited_textview_anonymous_nick_name" /> @@ -392,7 +387,6 @@ android:textSize="15sp" /> - + tools:text="올바른 학번을 입력해 주세요" /> - - - - + From 2e057ef98ef8f1a8c6fa70225e4009d426b394fc Mon Sep 17 00:00:00 2001 From: DoHyeok Kim Date: Thu, 25 Apr 2024 23:57:26 +0900 Subject: [PATCH 25/61] Fix to allow change user name --- .../koin/ui/userinfo/UserInfoEditActivity.kt | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt index fdd8360fb..ff459fcaa 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt @@ -87,17 +87,7 @@ class UserInfoEditActivity : KoinNavigationDrawerActivity() { userinfoeditedTextviewId.text = user.email userinfoeditedTextviewAnonymousNickName.text = user.anonymousNickname - userinfoeditedEdittextName.apply { - setText(user.name) - - if (user.name.isNullOrEmpty()) { - isEnabled = true - setDefaultBackground() - } else { - isEnabled = false - setTransparentBackground() - } - } + userinfoeditedEdittextName.setText(user.name) userinfoeditedEdittextNickName.setText(user.nickname) From 9b2b890d6cb79b7a68681e056dfc7120657a3802 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 25 Apr 2024 23:57:52 +0900 Subject: [PATCH 26/61] Add MainActivity dining click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 2 ++ .../koin/ui/main/activity/MainActivity.kt | 4 ++++ .../ui/main/fragment/DiningContainerFragment.kt | 14 ++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 2c8ecfd78..432417662 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -23,6 +23,8 @@ object AnalyticsConstant { const val HAMBURGER_MY_INFO_WITH_LOGIN = "${HAMBURGER}_my_info_with_login" const val HAMBURGER_BUS = "${HAMBURGER}_bus" const val USER_ONLY_OK = "user_only_ok" + const val MAIN_MENU_MOVEDETAILVIEW = "main_menu_moveDetailView" + const val MAIN_MENU_CORNER = "main_menu_corner" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 61f31ee4c..d7af60792 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -120,6 +120,10 @@ class MainActivity : KoinNavigationDrawerActivity() { tabDining.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { viewModel.setSelectedPosition(tab.position) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MAIN_MENU_CORNER, + tab.text.toString()) } override fun onTabUnselected(tab: TabLayout.Tab) {} diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index d040cdc44..1865d4d2d 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -1,5 +1,6 @@ package `in`.koreatech.koin.ui.main.fragment +import android.content.Intent import android.os.Bundle import android.view.View import androidx.core.content.ContextCompat @@ -8,6 +9,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.data.util.localized import `in`.koreatech.koin.databinding.FragmentDiningContainerBinding @@ -15,6 +18,7 @@ import `in`.koreatech.koin.domain.model.dining.Dining import `in`.koreatech.koin.domain.util.DiningUtil import `in`.koreatech.koin.domain.util.ext.arrange import `in`.koreatech.koin.domain.util.ext.typeFilter +import `in`.koreatech.koin.ui.dining.DiningActivity import `in`.koreatech.koin.ui.main.activity.MainActivity import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel import `in`.koreatech.koin.util.ext.observeLiveData @@ -34,10 +38,12 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { private fun initView() = with(binding) { diningContainer.setOnClickListener { - if (activity is MainActivity) { - val mainActivity = activity as MainActivity - mainActivity.callDrawerItem(R.id.navi_item_dining) - } + startActivity(Intent(requireContext(), DiningActivity::class.java)) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MAIN_MENU_MOVEDETAILVIEW, + requireContext().getString(R.string.navigation_item_dining) + ) } } From a545e9fdadd69b82e75f06be35048df2ebcd7f6a Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 00:50:31 +0900 Subject: [PATCH 27/61] Add dining time click/scroll event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 1 + .../koin/ui/dining/DiningActivity.kt | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 432417662..d7f3f8c82 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -25,6 +25,7 @@ object AnalyticsConstant { const val USER_ONLY_OK = "user_only_ok" const val MAIN_MENU_MOVEDETAILVIEW = "main_menu_moveDetailView" const val MAIN_MENU_CORNER = "main_menu_corner" + const val MENU_TIME = "menu_time" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt index 555128f34..23b884bb5 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt @@ -6,10 +6,13 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger import `in`.koreatech.koin.core.appbar.AppBarBase +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.databinding.ActivityDiningBinding import `in`.koreatech.koin.domain.model.dining.DiningType @@ -35,11 +38,14 @@ class DiningActivity : KoinNavigationDrawerActivity() { private val diningDateAdapter by lazy { DiningDateAdapter { viewModel.setSelectedDate(it) } } + private lateinit var diningViewPagerScrollCallback: ViewPager2.OnPageChangeCallback + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) + initDiningViewPagerScrollCallback() initCalendar() initViewPager() @@ -67,6 +73,7 @@ class DiningActivity : KoinNavigationDrawerActivity() { diningViewPager.apply { offscreenPageLimit = 3 adapter = DiningItemsViewPager2Adapter(this@DiningActivity) + registerOnPageChangeCallback(diningViewPagerScrollCallback) } TabLayoutMediator(tabsDiningTime, diningViewPager) { tab, position -> tab.text = when (position) { @@ -85,6 +92,17 @@ class DiningActivity : KoinNavigationDrawerActivity() { diningDateAdapter.setSelectedPosition(dates.size / 2 + 1) } } + // 스크롤이 아닌 탭 선택 이벤트만 받기 위한 구현 + repeat(binding.tabsDiningTime.tabCount) { + val tab = binding.tabsDiningTime.getTabAt(it) + tab?.view?.setOnClickListener { + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MENU_TIME, + tab.text.toString() + ) + } + } } } @@ -116,4 +134,30 @@ class DiningActivity : KoinNavigationDrawerActivity() { layoutManager?.scrollToPositionWithOffset(todayPosition, offset) } } + + private fun initDiningViewPagerScrollCallback() { + // 탭 선택이 아닌 스크롤 이벤트만 받기 위한 구현 + diningViewPagerScrollCallback = object : ViewPager2.OnPageChangeCallback() { + var isUserScrolling = false + override fun onPageScrollStateChanged(state: Int) { + super.onPageScrollStateChanged(state) + if(state == ViewPager2.SCROLL_STATE_DRAGGING){ + isUserScrolling = true + } else if(state == ViewPager2.SCROLL_STATE_IDLE){ + if(isUserScrolling){ + EventLogger.logScrollEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MENU_TIME, + binding.tabsDiningTime.getTabAt(binding.tabsDiningTime.selectedTabPosition)?.text.toString() + ) + } + isUserScrolling = false + } + } + } + } + override fun onDestroy() { + super.onDestroy() + binding.diningViewPager.unregisterOnPageChangeCallback(diningViewPagerScrollCallback) + } } \ No newline at end of file From 047afefe1fddc10361347357db695560ae8951ce Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 01:30:20 +0900 Subject: [PATCH 28/61] Add MainActivity bus card click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 2 ++ .../koin/ui/main/activity/MainActivity.kt | 21 +++++++++++++++++-- .../koin/ui/main/adapter/BusPagerAdapter.kt | 10 ++++----- .../main/viewmodel/MainActivityViewModel.kt | 1 + .../KoinNavigationDrawerActivity.kt | 2 +- koin/src/main/res/values/strings.xml | 1 + 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index d7f3f8c82..67a51b407 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -26,6 +26,8 @@ object AnalyticsConstant { const val MAIN_MENU_MOVEDETAILVIEW = "main_menu_moveDetailView" const val MAIN_MENU_CORNER = "main_menu_corner" const val MENU_TIME = "menu_time" + const val MAIN_BUS = "main_bus" + const val MAIN_BUS_CHANGETOFROM = "main_bus_changeToFrom" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index d7af60792..151eebb02 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -1,5 +1,6 @@ package `in`.koreatech.koin.ui.main.activity +import android.content.Intent import android.os.Bundle import android.view.View import android.widget.TextView @@ -16,9 +17,11 @@ import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.viewpager.HorizontalMarginItemDecoration import `in`.koreatech.koin.core.viewpager.ScaledViewPager2Transformation +import `in`.koreatech.koin.data.util.localized import `in`.koreatech.koin.data.util.todayOrTomorrow import `in`.koreatech.koin.databinding.ActivityMainBinding import `in`.koreatech.koin.domain.model.dining.DiningPlace +import `in`.koreatech.koin.ui.bus.BusActivity import `in`.koreatech.koin.ui.main.StoreCategoryRecyclerAdapter import `in`.koreatech.koin.ui.main.adapter.BusPagerAdapter import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter @@ -36,8 +39,22 @@ class MainActivity : KoinNavigationDrawerActivity() { private val viewModel by viewModels() private val busPagerAdapter = BusPagerAdapter().apply { - setOnCardClickListener { callDrawerItem(R.id.navi_item_bus, Bundle()) } - setOnSwitchClickListener { viewModel.switchBusNode() } + setOnCardClickListener { + startActivity(Intent(this@MainActivity, BusActivity::class.java)) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MAIN_BUS, + getString(R.string.bus) + ) + } + setOnSwitchClickListener { + viewModel.switchBusNode() + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MAIN_BUS_CHANGETOFROM, + it.localized(this@MainActivity) + ) + } } private val diningContainerAdapter by lazy { DiningContainerViewPager2Adapter(this) } diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/adapter/BusPagerAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/main/adapter/BusPagerAdapter.kt index 65f7624cd..2f5df7004 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/adapter/BusPagerAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/adapter/BusPagerAdapter.kt @@ -30,7 +30,7 @@ class BusPagerAdapter : RecyclerView.Adapter Unit) { + inline fun setOnSwitchClickListener(crossinline onSwitchClick: (BusArrivalInfo) -> Unit) { onSwitchClickListener = object : OnSwitchClickListener { - override fun onSwitchClick() { - onSwitchClick() + override fun onSwitchClick(busArrivalInfo: BusArrivalInfo) { + onSwitchClick(busArrivalInfo) } } } @@ -111,7 +111,7 @@ class BusPagerAdapter : RecyclerView.Adapter>(BusNode.Koreatech to BusNode.Terminal) + val busNode: LiveData> get() = _busNode private val _selectedPosition = MutableLiveData(0) val selectedPosition : LiveData get() = _selectedPosition diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index 27343f2d9..1efc50af4 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -212,7 +212,7 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), MenuState.Bus -> { action = AnalyticsConstant.Domain.CAMPUS label = AnalyticsConstant.Label.HAMBURGER_BUS - value = getString(R.string.navigation_item_bus) + value = getString(R.string.bus) goToBusActivity() } MenuState.Dining -> { diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index c9e10f5c8..192e30aa5 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -383,4 +383,5 @@ 미지정(전체보기) 주변상점 회원전용 확인 + 버스 From 174b67d2c2bf991471a3164d9409b2d17e90aab4 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 14:35:20 +0900 Subject: [PATCH 29/61] Add MainActivity bus card scroll event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 1 + .../koin/ui/main/activity/MainActivity.kt | 30 ++++++++++++++++++- .../main/viewmodel/MainActivityViewModel.kt | 1 - 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 67a51b407..3796d406d 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -28,6 +28,7 @@ object AnalyticsConstant { const val MENU_TIME = "menu_time" const val MAIN_BUS = "main_bus" const val MAIN_BUS_CHANGETOFROM = "main_bus_changeToFrom" + const val MAIN_BUS_SCROLL = "main_bus_scroll" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 151eebb02..6ddfb85c4 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -7,6 +7,7 @@ import android.widget.TextView import androidx.activity.viewModels import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint @@ -16,10 +17,10 @@ import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.recyclerview.RecyclerViewClickListener import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.viewpager.HorizontalMarginItemDecoration -import `in`.koreatech.koin.core.viewpager.ScaledViewPager2Transformation import `in`.koreatech.koin.data.util.localized import `in`.koreatech.koin.data.util.todayOrTomorrow import `in`.koreatech.koin.databinding.ActivityMainBinding +import `in`.koreatech.koin.domain.model.bus.timer.BusArrivalInfo import `in`.koreatech.koin.domain.model.dining.DiningPlace import `in`.koreatech.koin.ui.bus.BusActivity import `in`.koreatech.koin.ui.main.StoreCategoryRecyclerAdapter @@ -56,6 +57,9 @@ class MainActivity : KoinNavigationDrawerActivity() { ) } } + private lateinit var busViewPagerScrollCallback: ViewPager2.OnPageChangeCallback + private var isBusScrollCallbackInitialized = false + private val diningContainerAdapter by lazy { DiningContainerViewPager2Adapter(this) } private val storeCategoryRecyclerAdapter = StoreCategoryRecyclerAdapter().apply { @@ -160,12 +164,36 @@ class MainActivity : KoinNavigationDrawerActivity() { observeLiveData(busTimer) { busPagerAdapter.setBusTimerItems(it) + if (!isBusScrollCallbackInitialized) { + initBusViewPagerScrollCallback(it) + isBusScrollCallbackInitialized = true + } } } + private fun initBusViewPagerScrollCallback(busArrivalInfos: List) { + busViewPagerScrollCallback = object : ViewPager2.OnPageChangeCallback() { + var prev = 0 + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + EventLogger.logScrollEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MAIN_BUS_SCROLL, + busArrivalInfos[prev % 3].localized(this@MainActivity) + ">" + busArrivalInfos[position % 3].localized(this@MainActivity) + ) + prev = position + } + }.also { binding.busViewPager.registerOnPageChangeCallback(it) } + } + private fun gotoStoreActivity(position: Int) { val bundle = Bundle() bundle.putInt(StoreActivityContract.STORE_CATEGORY, position) callDrawerItem(R.id.navi_item_store, bundle) } + + override fun onDestroy() { + super.onDestroy() + binding.busViewPager.unregisterOnPageChangeCallback(busViewPagerScrollCallback) + } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/viewmodel/MainActivityViewModel.kt b/koin/src/main/java/in/koreatech/koin/ui/main/viewmodel/MainActivityViewModel.kt index a90b81115..549e71f07 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/viewmodel/MainActivityViewModel.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/viewmodel/MainActivityViewModel.kt @@ -25,7 +25,6 @@ class MainActivityViewModel @Inject constructor( ) : BaseViewModel() { private val _busNode = MutableLiveData>(BusNode.Koreatech to BusNode.Terminal) - val busNode: LiveData> get() = _busNode private val _selectedPosition = MutableLiveData(0) val selectedPosition : LiveData get() = _selectedPosition From 661e3b41a2991399775bd0cecefafac135c14b98 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 14:57:56 +0900 Subject: [PATCH 30/61] Add BusMainFragment spinner click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 2 ++ .../koin/ui/bus/fragment/BusMainFragment.kt | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 3796d406d..89d4b6b49 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -29,6 +29,8 @@ object AnalyticsConstant { const val MAIN_BUS = "main_bus" const val MAIN_BUS_CHANGETOFROM = "main_bus_changeToFrom" const val MAIN_BUS_SCROLL = "main_bus_scroll" + const val BUS_DEPARTURE = "bus_departure" + const val BUS_ARRIVAL = "bus_arrival" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt index e75bf77b1..183c84676 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt @@ -24,6 +24,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding @AndroidEntryPoint @@ -41,14 +43,40 @@ class BusMainFragment : Fragment(R.layout.bus_main_fragment) { initViewModel() } + private var isUserSelection = false private fun initView() = with(binding) { busDepartureSpinner.setSelection(BusNode.Koreatech.spinnerSelection) busArrivalSpinner.setSelection(BusNode.Terminal.spinnerSelection) + busDepartureSpinner.setOnTouchListener { _, _ -> + isUserSelection = true + busDepartureSpinner.performClick() + } busDepartureSpinner.setOnItemSelectedListener { _, _, position, _ -> viewModel.setDeparture(position.busNodeSelection) + if(isUserSelection) { + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_DEPARTURE, + resources.getStringArray(R.array.bus_place)[position] + ) + isUserSelection = false + } + } + + busArrivalSpinner.setOnTouchListener { _, _ -> + isUserSelection = true + busArrivalSpinner.performClick() } busArrivalSpinner.setOnItemSelectedListener { _, _, position, _ -> viewModel.setArrival(position.busNodeSelection) + if(isUserSelection) { + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_ARRIVAL, + resources.getStringArray(R.array.bus_place)[position] + ) + isUserSelection = false + } } recyclerView.apply { layoutManager = LinearLayoutManager(requireContext()) From 3f6121371c01e9c28e55ddf5e1d3a8ada70a81b9 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 15:14:00 +0900 Subject: [PATCH 31/61] Add BusTimetableFragment click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 4 ++++ data/src/main/res/values/strings.xml | 1 + .../ui/bus/fragment/BusTimetableFragment.kt | 17 +++++++++++++++++ .../bus/fragment/ExpressBusTimetableFragment.kt | 7 +++++++ .../bus/fragment/ShuttleBusTimetableFragment.kt | 12 ++++++++++++ 5 files changed, 41 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 89d4b6b49..f09a96a41 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -31,6 +31,10 @@ object AnalyticsConstant { const val MAIN_BUS_SCROLL = "main_bus_scroll" const val BUS_DEPARTURE = "bus_departure" const val BUS_ARRIVAL = "bus_arrival" + const val BUS_TIMETABLE = "bus_timetable" + const val BUS_TIMETABLE_AREA = "bus_timetable_area" + const val BUS_TIMETABLE_TIME = "bus_timetable_time" + const val BUS_TIMETABLE_EXPRESS = "bus_timetable_express" } } \ No newline at end of file diff --git a/data/src/main/res/values/strings.xml b/data/src/main/res/values/strings.xml index 919578216..d59d863ed 100644 --- a/data/src/main/res/values/strings.xml +++ b/data/src/main/res/values/strings.xml @@ -41,6 +41,7 @@ 통학버스 대성고속 셔틀버스 + 학교셔틀 %1$d번 버스 기계공학부 diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusTimetableFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusTimetableFragment.kt index 317bc0eab..f23636b97 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusTimetableFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusTimetableFragment.kt @@ -12,6 +12,8 @@ import android.view.View import androidx.fragment.app.commit import androidx.fragment.app.viewModels import dagger.hilt.android.AndroidEntryPoint +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant @AndroidEntryPoint class BusTimetableFragment : DataBindingFragment() { @@ -39,12 +41,27 @@ class BusTimetableFragment : DataBindingFragment() binding.busTimetableBustypeShuttle.setOnClickListener { busTimetableViewModel.setBusType(BusType.Shuttle) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE, + getString(R.string.bus_name_school_shuttle) + ) } binding.busTimetableBustypeDaesung.setOnClickListener { busTimetableViewModel.setBusType(BusType.Express) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE, + getString(R.string.bus_name_express) + ) } binding.busTimetableBustypeCity.setOnClickListener { busTimetableViewModel.setBusType(BusType.City) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE, + getString(R.string.bus_name_city) + ) } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt index 094bdf497..70231199f 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt @@ -23,6 +23,8 @@ import androidx.core.view.isVisible import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant @AndroidEntryPoint class ExpressBusTimetableFragment : DataBindingFragment() { @@ -47,6 +49,11 @@ class ExpressBusTimetableFragment : DataBindingFragment expressBusTimetableViewModel.setCoursePosition(position) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE_EXPRESS, + busTimetableCoursesSpinner.selectedItem.toString() + ) } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt index b88eda563..6cc9538ed 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt @@ -8,6 +8,8 @@ import androidx.fragment.app.viewModels import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.fragment.DataBindingFragment import `in`.koreatech.koin.core.progressdialog.IProgressDialog import `in`.koreatech.koin.databinding.LayoutShuttleBusTimetableBinding @@ -42,10 +44,20 @@ class ShuttleBusTimetableFragment : DataBindingFragment shuttleBusTimetableViewModel.setCoursePosition(position) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE_AREA, + busTimetableCoursesSpinner.selectedItem.toString() + ) } busTimetableRoutesSpinner.setOnItemSelectedListener { _, _, position, _ -> shuttleBusTimetableViewModel.setRoutePosition(position) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.BUS_TIMETABLE_TIME, + busTimetableRoutesSpinner.selectedItem.toString() + ) } } From 05d14a7df122e27291f91e7e7ce877a29ef8f855 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 16:25:48 +0900 Subject: [PATCH 32/61] Add Dining menu image click event analytics --- .../koin/core/constant/AnalyticsConstant.kt | 1 + .../in/koreatech/koin/domain/util/DiningUtil.kt | 10 ++++++++++ .../koin/ui/dining/adapter/DiningAdapter.kt | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index f09a96a41..7e85ae1a8 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -35,6 +35,7 @@ object AnalyticsConstant { const val BUS_TIMETABLE_AREA = "bus_timetable_area" const val BUS_TIMETABLE_TIME = "bus_timetable_time" const val BUS_TIMETABLE_EXPRESS = "bus_timetable_express" + const val MENU_IMAGE = "menu_image" } } \ No newline at end of file diff --git a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt index bdda26a05..bfb433115 100644 --- a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt +++ b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt @@ -40,4 +40,14 @@ object DiningUtil { } return null } + + fun getKoreanName(type: String): String { + return when (type) { + DiningType.Breakfast.typeEnglish -> DiningType.Breakfast.typeKorean + DiningType.Lunch.typeEnglish -> DiningType.Lunch.typeKorean + DiningType.Dinner.typeEnglish -> DiningType.Dinner.typeKorean + DiningType.NextBreakfast.typeEnglish -> DiningType.NextBreakfast.typeKorean + else -> "" + } + } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index 3d56b696a..02713b93b 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -13,8 +13,11 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.databinding.ItemDiningBinding import `in`.koreatech.koin.domain.model.dining.Dining +import `in`.koreatech.koin.domain.util.DiningUtil class DiningAdapter : ListAdapter(diffCallback) { @@ -85,6 +88,19 @@ class DiningAdapter : ListAdapter(diffCallback) .load(dining.imageUrl) .into(imageView) dialog.show() + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MENU_IMAGE, + DiningUtil.getKoreanName(dining.type) + "_" + dining.place + ) + } + } else { + cardViewDining.setOnClickListener { + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.MENU_IMAGE, + DiningUtil.getKoreanName(dining.type) + "_" + dining.place + ) } } From 8013c7d54309fc24f53f0c8ff4416665ec7e9f56 Mon Sep 17 00:00:00 2001 From: DoHyeok Kim Date: Fri, 26 Apr 2024 16:37:18 +0900 Subject: [PATCH 33/61] Add toast when nickname is same as before --- .../koin/ui/userinfo/UserInfoEditActivity.kt | 38 ++++++++++++++----- .../ui/userinfo/state/NicknameCheckState.kt | 5 +++ .../viewmodel/UserInfoEditViewModel.kt | 25 +++++++----- koin/src/main/res/values/strings.xml | 3 ++ 4 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 koin/src/main/java/in/koreatech/koin/ui/userinfo/state/NicknameCheckState.kt diff --git a/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt index ff459fcaa..d66597925 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/userinfo/UserInfoEditActivity.kt @@ -1,21 +1,27 @@ package `in`.koreatech.koin.ui.userinfo +import android.os.Bundle +import androidx.activity.viewModels +import androidx.core.widget.addTextChangedListener +import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.core.toast.ToastUtil import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.core.util.setAppBarButtonClickedListener import `in`.koreatech.koin.databinding.ActivityUserInfoEditedBinding import `in`.koreatech.koin.domain.model.user.Gender +import `in`.koreatech.koin.domain.model.user.User import `in`.koreatech.koin.ui.navigation.KoinNavigationDrawerActivity import `in`.koreatech.koin.ui.navigation.state.MenuState import `in`.koreatech.koin.ui.userinfo.contract.UserInfoEditContract +import `in`.koreatech.koin.ui.userinfo.state.NicknameCheckState import `in`.koreatech.koin.ui.userinfo.viewmodel.UserInfoEditViewModel -import `in`.koreatech.koin.util.ext.* -import android.os.Bundle -import androidx.activity.viewModels -import androidx.core.widget.addTextChangedListener -import dagger.hilt.android.AndroidEntryPoint -import `in`.koreatech.koin.domain.model.user.User +import `in`.koreatech.koin.util.ext.observeLiveData +import `in`.koreatech.koin.util.ext.setDefaultBackground +import `in`.koreatech.koin.util.ext.setTransparentBackground +import `in`.koreatech.koin.util.ext.splitPhoneNumber +import `in`.koreatech.koin.util.ext.textString +import `in`.koreatech.koin.util.ext.withLoading @AndroidEntryPoint class UserInfoEditActivity : KoinNavigationDrawerActivity() { @@ -77,11 +83,12 @@ class UserInfoEditActivity : KoinNavigationDrawerActivity() { withLoading(this@UserInfoEditActivity, this) observeLiveData(user) { user -> - when(user) { + when (user) { User.Anonymous -> { ToastUtil.getInstance().makeShort(getString(R.string.user_info_anonymous)) finish() } + is User.Student -> with(binding) { userinfoeditedTextviewId.text = user.email @@ -146,8 +153,21 @@ class UserInfoEditActivity : KoinNavigationDrawerActivity() { } observeLiveData(nicknameDuplicatedEvent) { - if (it) ToastUtil.getInstance().makeShort(R.string.error_nickname_duplicated) - else ToastUtil.getInstance().makeShort(R.string.nickname_available) + ToastUtil.getInstance().makeShort( + when (it) { + NicknameCheckState.POSSIBLE -> { + R.string.nickname_available + } + + NicknameCheckState.SAME_AS_BEFORE -> { + R.string.edit_user_error_same_as_before + } + + NicknameCheckState.EXIST -> { + R.string.error_nickname_duplicated + } + } + ) } observeLiveData(userInfoEditedEvent) { diff --git a/koin/src/main/java/in/koreatech/koin/ui/userinfo/state/NicknameCheckState.kt b/koin/src/main/java/in/koreatech/koin/ui/userinfo/state/NicknameCheckState.kt new file mode 100644 index 000000000..859c267f3 --- /dev/null +++ b/koin/src/main/java/in/koreatech/koin/ui/userinfo/state/NicknameCheckState.kt @@ -0,0 +1,5 @@ +package `in`.koreatech.koin.ui.userinfo.state + +enum class NicknameCheckState { + EXIST, POSSIBLE, SAME_AS_BEFORE +} \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/userinfo/viewmodel/UserInfoEditViewModel.kt b/koin/src/main/java/in/koreatech/koin/ui/userinfo/viewmodel/UserInfoEditViewModel.kt index 9e4a4f61f..82df9264e 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/userinfo/viewmodel/UserInfoEditViewModel.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/userinfo/viewmodel/UserInfoEditViewModel.kt @@ -1,5 +1,9 @@ package `in`.koreatech.koin.ui.userinfo.viewmodel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel import `in`.koreatech.koin.core.viewmodel.BaseViewModel import `in`.koreatech.koin.core.viewmodel.SingleLiveEvent import `in`.koreatech.koin.domain.model.user.Gender @@ -8,13 +12,10 @@ import `in`.koreatech.koin.domain.usecase.dept.GetDeptNameFromStudentIdUseCase import `in`.koreatech.koin.domain.usecase.user.CheckNicknameValidationUseCase import `in`.koreatech.koin.domain.usecase.user.GetUserInfoUseCase import `in`.koreatech.koin.domain.usecase.user.UpdateStudentUserInfoUseCase -import `in`.koreatech.koin.ui.userinfo.state.NicknameState -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.viewModelScope -import dagger.hilt.android.lifecycle.HiltViewModel import `in`.koreatech.koin.domain.util.onFailure import `in`.koreatech.koin.domain.util.onSuccess +import `in`.koreatech.koin.ui.userinfo.state.NicknameCheckState +import `in`.koreatech.koin.ui.userinfo.state.NicknameState import javax.inject.Inject @HiltViewModel @@ -37,8 +38,8 @@ class UserInfoEditViewModel @Inject constructor( private val _nicknameState = MutableLiveData() val nicknameState: LiveData get() = _nicknameState - private val _nicknameDuplicatedEvent = SingleLiveEvent() - val nicknameDuplicatedEvent: LiveData get() = _nicknameDuplicatedEvent + private val _nicknameDuplicatedEvent = SingleLiveEvent() + val nicknameDuplicatedEvent: LiveData get() = _nicknameDuplicatedEvent private val _toastErrorMessage = SingleLiveEvent() val toastErrorMessage: LiveData get() = _toastErrorMessage @@ -50,7 +51,7 @@ class UserInfoEditViewModel @Inject constructor( getUserInfoUseCase() .onSuccess { user -> _user.value = user - _nicknameState.value = when(user) { + _nicknameState.value = when (user) { User.Anonymous -> NicknameState.newNickname("") is User.Student -> { user.nickname?.let { @@ -73,10 +74,16 @@ class UserInfoEditViewModel @Inject constructor( fun checkNickname(nickname: String) = viewModelScope.launchWithLoading { _nicknameState.value = NicknameState.newNickname(nickname) + if (nickname == (user.value as User.Student).nickname) { + _nicknameState.value = _nicknameState.value?.copy(isNicknameDuplicated = false) + _nicknameDuplicatedEvent.value = NicknameCheckState.SAME_AS_BEFORE + return@launchWithLoading + } + checkNicknameValidationUseCase(nickname).let { (isDuplicated, error) -> isDuplicated?.let { _nicknameState.value = _nicknameState.value?.copy(isNicknameDuplicated = it) - _nicknameDuplicatedEvent.value = it + _nicknameDuplicatedEvent.value = if (it) NicknameCheckState.EXIST else NicknameCheckState.POSSIBLE } error?.let { _toastErrorMessage.value = it.message } } diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 3239f24c4..dcb8fb7eb 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -225,6 +225,9 @@ 사용자 정보가 수정되었습니다. 사용 가능한 닉네임입니다 + + 기존의 닉네임과 동일합니다 + 더 이상 데이터를 불러올 수 없습니다. 아침 From be3a4c8c1d46a1d34f476e703ced16ba34bacb2f Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 17:46:32 +0900 Subject: [PATCH 34/61] Add Store search click event analytics, Modify get name logic --- .../koin/core/constant/AnalyticsConstant.kt | 1 + .../koin/ui/store/activity/StoreActivity.kt | 53 ++++++++++++------- koin/src/main/res/values/strings.xml | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 7e85ae1a8..50ee928a6 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -16,6 +16,7 @@ object AnalyticsConstant { object Label { const val MAIN_STORE_CATEGORIES = "main_store_categories" const val STORE_CATEGORIES = "store_categories" + const val STORE_CATEGORIES_SEARCH = "store_categories_search" const val HAMBURGER = "hamburger" const val HAMBURGER_STORE = "${HAMBURGER}_store" const val HAMBURGER_DINING = "${HAMBURGER}_dining" diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index 7ed9f01df..215de808f 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -2,6 +2,7 @@ package `in`.koreatech.koin.ui.store.activity import android.os.Bundle import android.util.Log +import android.view.MotionEvent import android.view.View import android.widget.TextView import androidx.activity.viewModels @@ -107,6 +108,18 @@ class StoreActivity : KoinNavigationDrawerActivity() { isSearchMode = hasFocus } + binding.searchEditText.setOnTouchListener { v, event -> + if(event.action == MotionEvent.ACTION_DOWN) { + EventLogger.logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + AnalyticsConstant.Label.STORE_CATEGORIES_SEARCH, + "search in " + getStoreCategoryName(viewModel.category.value) + ) + } + v.performClick() + } + + binding.storeRecyclerview.apply { layoutManager = LinearLayoutManager(this@StoreActivity) adapter = storeAdapter @@ -201,30 +214,34 @@ class StoreActivity : KoinNavigationDrawerActivity() { binding.storeCategoryEtcTextview.setCategorySelected(category == StoreCategory.Etc) } + private fun getStoreCategoryName(category: StoreCategory?): String { + return when(category) { + StoreCategory.Chicken -> getString(R.string.chicken) + StoreCategory.Pizza -> getString(R.string.pizza) + StoreCategory.DOSIRAK -> getString(R.string.dorisak) + StoreCategory.PorkFeet -> getString(R.string.pork_feet) + StoreCategory.Chinese -> getString(R.string.chinese) + StoreCategory.NormalFood -> getString(R.string.normal_food) + StoreCategory.Cafe -> getString(R.string.cafe) + StoreCategory.BeautySalon -> getString(R.string.beauty_salon) + StoreCategory.Etc -> getString(R.string.etc) + null -> getString(R.string.see_all) + else -> "" + } + } + private fun View.setCategoryOnClick(category: StoreCategory) { setOnClickListener { - var eventValue = when(category) { - StoreCategory.Chicken -> getString(R.string.chicken) - StoreCategory.Pizza -> getString(R.string.pizza) - StoreCategory.DOSIRAK -> getString(R.string.dorisak) - StoreCategory.PorkFeet -> getString(R.string.pork_feet) - StoreCategory.Chinese -> getString(R.string.chinese) - StoreCategory.NormalFood -> getString(R.string.normal_food) - StoreCategory.Cafe -> getString(R.string.cafe) - StoreCategory.BeautySalon -> getString(R.string.beauty_salon) - StoreCategory.Etc -> getString(R.string.etc) - else -> "" - } - if(viewModel.category.value == category) - eventValue = getString(R.string.unselect_see_all) + binding.searchEditText.clearFocus() + viewModel.setCategory(category) + + val eventValue = getStoreCategoryName(viewModel.category.value) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, AnalyticsConstant.Label.STORE_CATEGORIES, - eventValue) - - binding.searchEditText.clearFocus() - viewModel.setCategory(category) + eventValue + ) } } diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 192e30aa5..10e6e578c 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -380,8 +380,8 @@ 카페 미용실 기타 - 미지정(전체보기) 주변상점 회원전용 확인 버스 + 전체보기 From 538991306c43a374f726954a26adcf4767cdb4e3 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 18:48:14 +0900 Subject: [PATCH 35/61] Add Sign up click event analytics --- .../koreatech/koin/core/constant/AnalyticsConstant.kt | 2 ++ .../java/in/koreatech/koin/ui/login/LoginActivity.kt | 11 +++++++---- .../koin/ui/signup/SignUpWithDetailInfoActivity.kt | 7 +++++++ koin/src/main/res/layout/activity_login.xml | 2 +- koin/src/main/res/values/strings.xml | 3 ++- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 50ee928a6..9971b5f70 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -37,6 +37,8 @@ object AnalyticsConstant { const val BUS_TIMETABLE_TIME = "bus_timetable_time" const val BUS_TIMETABLE_EXPRESS = "bus_timetable_express" const val MENU_IMAGE = "menu_image" + const val START_SIGN_UP = "start_sign_up" + const val COMPLETE_SIGN_UP = "complete_sign_up" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt index 912fb3a42..d763ae43e 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt @@ -2,17 +2,17 @@ package `in`.koreatech.koin.ui.login import android.content.Intent import android.os.Bundle -import android.util.Log import android.view.MotionEvent import androidx.activity.viewModels import androidx.lifecycle.Lifecycle -import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.common.UiStatus import `in`.koreatech.koin.core.activity.ActivityBase +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.util.dataBinding import `in`.koreatech.koin.databinding.ActivityLoginBinding import `in`.koreatech.koin.ui.businesslogin.BusinessLoginActivity @@ -24,8 +24,6 @@ import `in`.koreatech.koin.util.SnackbarUtil import `in`.koreatech.koin.util.ext.hideKeyboard import `in`.koreatech.koin.util.ext.textString import `in`.koreatech.koin.util.ext.withLoading -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @AndroidEntryPoint @@ -99,6 +97,11 @@ class LoginActivity : ActivityBase(R.layout.activity_login) { loginButtonSignup.setOnClickListener { startActivity(Intent(this@LoginActivity, SignupActivity::class.java)) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.START_SIGN_UP, + getString(R.string.sign_up) + ) } forgotPasswordLinearLayout.setOnClickListener { diff --git a/koin/src/main/java/in/koreatech/koin/ui/signup/SignUpWithDetailInfoActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/signup/SignUpWithDetailInfoActivity.kt index e4391b0cc..87bb5509a 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/signup/SignUpWithDetailInfoActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/signup/SignUpWithDetailInfoActivity.kt @@ -11,6 +11,8 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R import `in`.koreatech.koin.core.activity.ActivityBase +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.databinding.ActivitySignUpWithDetailInfoBinding import `in`.koreatech.koin.domain.error.signup.SignupAlreadySentEmailException import `in`.koreatech.koin.domain.model.user.Gender @@ -93,6 +95,11 @@ class SignupWithDetailInfoActivity : ActivityBase() { studentNumber = signupUserEdittextStudentId.text.toString(), isCheckNickname = signupViewModel.isCheckedNickname ) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.COMPLETE_SIGN_UP, + getString(R.string.complete_sign_up) + ) } } } diff --git a/koin/src/main/res/layout/activity_login.xml b/koin/src/main/res/layout/activity_login.xml index cde0243ad..44b311600 100644 --- a/koin/src/main/res/layout/activity_login.xml +++ b/koin/src/main/res/layout/activity_login.xml @@ -265,7 +265,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:background="@color/colorPrimary" - android:text="회원가입" + android:text="@string/sign_up" android:textColor="@color/white" android:textSize="15sp" app:fontName="Normal" diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 10e6e578c..7ae14d479 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ 코인\n커뮤니티 - 회원 가입 + 회원가입 @@ -384,4 +384,5 @@ 회원전용 확인 버스 전체보기 + 회원가입 완료 From dbfb8413f13092d4570f3196901f502874116e9a Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 18:52:38 +0900 Subject: [PATCH 36/61] Add Login click event analytics --- .../in/koreatech/koin/core/constant/AnalyticsConstant.kt | 1 + .../main/java/in/koreatech/koin/ui/login/LoginActivity.kt | 5 +++++ koin/src/main/res/values/strings.xml | 1 + 3 files changed, 7 insertions(+) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 9971b5f70..ddc4ae8fe 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -37,6 +37,7 @@ object AnalyticsConstant { const val BUS_TIMETABLE_TIME = "bus_timetable_time" const val BUS_TIMETABLE_EXPRESS = "bus_timetable_express" const val MENU_IMAGE = "menu_image" + const val LOGIN = "login" const val START_SIGN_UP = "start_sign_up" const val COMPLETE_SIGN_UP = "complete_sign_up" } diff --git a/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt index d763ae43e..4d51877ab 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/login/LoginActivity.kt @@ -93,6 +93,11 @@ class LoginActivity : ActivityBase(R.layout.activity_login) { password = loginEdittextPw.text.toString().trim() ) } + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.LOGIN, + getString(R.string.login) + ) } loginButtonSignup.setOnClickListener { diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 7ae14d479..181e402e5 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -2,6 +2,7 @@ 코인\n커뮤니티 회원가입 + 로그인 From 9dc0eebfd358176c27bc58733c03ddc6857c7370 Mon Sep 17 00:00:00 2001 From: Strone Date: Fri, 26 Apr 2024 22:00:50 +0900 Subject: [PATCH 37/61] Change dining date background --- .../koin/ui/dining/DiningActivity.kt | 4 +- .../ui/dining/adapter/DiningDateAdapter.kt | 42 ++++++++++--------- .../background_date_today_indicator.xml | 11 +++++ koin/src/main/res/layout/item_dining_date.xml | 22 ++++++++-- 4 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 koin/src/main/res/drawable/background_date_today_indicator.xml diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt index 555128f34..00eda24e0 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/DiningActivity.kt @@ -82,7 +82,7 @@ class DiningActivity : KoinNavigationDrawerActivity() { DiningType.Dinner -> tabsDiningTime.selectTab(tabsDiningTime.getTabAt(2)) DiningType.NextBreakfast -> { tabsDiningTime.selectTab(tabsDiningTime.getTabAt(0)) - diningDateAdapter.setSelectedPosition(dates.size / 2 + 1) + diningDateAdapter.selectPosition(dates.size / 2 + 1) } } } @@ -102,7 +102,7 @@ class DiningActivity : KoinNavigationDrawerActivity() { diningDateAdapter.submitList(dates) val todayPos = dates.size / 2 - diningDateAdapter.setSelectedPosition(todayPos) + diningDateAdapter.selectPosition(todayPos) scrollDateTodayToCenter(todayPos) } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt index 2fafab1d0..17888df05 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt @@ -12,9 +12,7 @@ import androidx.recyclerview.widget.RecyclerView import `in`.koreatech.koin.R import `in`.koreatech.koin.databinding.ItemDiningDateBinding import `in`.koreatech.koin.domain.util.DateFormatUtil -import java.util.Calendar import java.util.Date -import java.util.Locale class DiningDateAdapter( private val onClick: (Date) -> Unit @@ -22,7 +20,7 @@ class DiningDateAdapter( private var selectedPosition = 0 - fun setSelectedPosition(position: Int) { + fun selectPosition(position: Int) { selectedPosition = position } @@ -48,7 +46,8 @@ class DiningDateAdapter( textViewDayOfTheWeek.text = DateFormatUtil.getDayOfWeek(date) textViewDay.text = date.date.toString() - if (position < itemCount / 2) { + backgroundTodayIndicator.visibility = View.INVISIBLE + if (position < itemCount / 2) { // 오늘 이전 textViewDay.setTextColor( ContextCompat.getColor( context, @@ -61,7 +60,7 @@ class DiningDateAdapter( R.color.gray9 ) ) - } else { + } else if (position > itemCount / 2) { // 오늘 이후 textViewDay.setTextColor(Color.BLACK) textViewDayOfTheWeek.setTextColor( ContextCompat.getColor( @@ -69,23 +68,26 @@ class DiningDateAdapter( R.color.gray14 ) ) + } else { // 오늘 + textViewDay.setTextColor( + ContextCompat.getColor( + context, + R.color.colorPrimary + ) + ) + textViewDayOfTheWeek.setTextColor( + ContextCompat.getColor( + context, + R.color.gray9 + ) + ) + backgroundTodayIndicator.visibility = View.VISIBLE } - backgroundSelectedDate.visibility = View.INVISIBLE - backgroundSelectedDateToday.visibility = View.INVISIBLE + groupSelectedDate.visibility = View.INVISIBLE if (position == selectedPosition) { - if (DateUtils.isToday(date.time)) { - textViewDay.setTextColor(Color.WHITE) - backgroundSelectedDateToday.visibility = View.VISIBLE - } else { - textViewDay.setTextColor( - ContextCompat.getColor( - context, - R.color.colorPrimary - ) - ) - backgroundSelectedDate.visibility = View.VISIBLE - } + groupSelectedDate.visibility = View.VISIBLE + textViewDay.setTextColor(Color.WHITE) } root.setOnClickListener { @@ -97,7 +99,7 @@ class DiningDateAdapter( ) else notifyItemRangeChanged(position, selectedPosition - position + 1) - setSelectedPosition(position) + selectPosition(position) } } } diff --git a/koin/src/main/res/drawable/background_date_today_indicator.xml b/koin/src/main/res/drawable/background_date_today_indicator.xml new file mode 100644 index 000000000..a85adcb87 --- /dev/null +++ b/koin/src/main/res/drawable/background_date_today_indicator.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/koin/src/main/res/layout/item_dining_date.xml b/koin/src/main/res/layout/item_dining_date.xml index b9a307378..0ee1f9516 100644 --- a/koin/src/main/res/layout/item_dining_date.xml +++ b/koin/src/main/res/layout/item_dining_date.xml @@ -23,7 +23,7 @@ tools:text="월" /> + + + + Date: Mon, 29 Apr 2024 14:32:24 +0900 Subject: [PATCH 38/61] Change store label --- .../java/in/koreatech/koin/core/constant/AnalyticsConstant.kt | 3 +++ .../java/in/koreatech/koin/ui/store/activity/StoreActivity.kt | 2 +- .../koreatech/koin/ui/store/activity/StoreDetailActivity.kt | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index ddc4ae8fe..8b712ddb3 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -40,6 +40,9 @@ object AnalyticsConstant { const val LOGIN = "login" const val START_SIGN_UP = "start_sign_up" const val COMPLETE_SIGN_UP = "complete_sign_up" + const val STORE_PICTURE = "store_picture" + const val STORE_CALL = "store_call" + const val STORE_CLICK = "store_click" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index 215de808f..a0a193bd1 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -51,7 +51,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { storeDetailContract.launch(it.uid) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - "store_${it.name}_click", + AnalyticsConstant.Label.STORE_CLICK, it.name) } } diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt index 17d567e65..0169d181b 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt @@ -88,7 +88,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { flyerDialogFragment?.show(supportFragmentManager, DIALOG_TAG) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - "store_${viewModel.store.value?.name ?: "Unknown"}_picture", + AnalyticsConstant.Label.STORE_PICTURE, viewModel.store.value?.name ?: "Unknown") } } @@ -128,7 +128,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { showCallDialog() EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - "store_${viewModel.store.value?.name ?: "Unknown"}_call", + AnalyticsConstant.Label.STORE_CALL, viewModel.store.value?.name ?: "Unknown") } From 86341b205454d1f5ea16b882449e294935d3b819 Mon Sep 17 00:00:00 2001 From: Strone Date: Mon, 29 Apr 2024 14:40:50 +0900 Subject: [PATCH 39/61] Change description store -> shop --- .../koin/core/constant/AnalyticsConstant.kt | 14 +++++++------- .../koin/ui/main/activity/MainActivity.kt | 2 +- .../ui/navigation/KoinNavigationDrawerActivity.kt | 2 +- .../koin/ui/store/activity/StoreActivity.kt | 7 +++---- .../koin/ui/store/activity/StoreDetailActivity.kt | 4 ++-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt index 8b712ddb3..6871441fa 100644 --- a/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt +++ b/core/src/main/java/in/koreatech/koin/core/constant/AnalyticsConstant.kt @@ -14,11 +14,11 @@ object AnalyticsConstant { } object Label { - const val MAIN_STORE_CATEGORIES = "main_store_categories" - const val STORE_CATEGORIES = "store_categories" - const val STORE_CATEGORIES_SEARCH = "store_categories_search" + const val MAIN_SHOP_CATEGORIES = "main_shop_categories" + const val SHOP_CATEGORIES = "shop_categories" + const val SHOP_CATEGORIES_SEARCH = "shop_categories_search" const val HAMBURGER = "hamburger" - const val HAMBURGER_STORE = "${HAMBURGER}_store" + const val HAMBURGER_SHOP = "${HAMBURGER}_shop" const val HAMBURGER_DINING = "${HAMBURGER}_dining" const val HAMBURGER_MY_INFO_WITHOUT_LOGIN = "${HAMBURGER}_my_info_without_login" const val HAMBURGER_MY_INFO_WITH_LOGIN = "${HAMBURGER}_my_info_with_login" @@ -40,9 +40,9 @@ object AnalyticsConstant { const val LOGIN = "login" const val START_SIGN_UP = "start_sign_up" const val COMPLETE_SIGN_UP = "complete_sign_up" - const val STORE_PICTURE = "store_picture" - const val STORE_CALL = "store_call" - const val STORE_CLICK = "store_click" + const val SHOP_PICTURE = "shop_picture" + const val SHOP_CALL = "shop_call" + const val SHOP_CLICK = "shop_click" } } \ No newline at end of file diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 6ddfb85c4..f68fc21a2 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -68,7 +68,7 @@ class MainActivity : KoinNavigationDrawerActivity() { gotoStoreActivity(position) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.MAIN_STORE_CATEGORIES, + AnalyticsConstant.Label.MAIN_SHOP_CATEGORIES, view?.findViewById(R.id.text_view_store_category)?.text.toString() ) } diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index 1efc50af4..2d9841393 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -225,7 +225,7 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), MenuState.Main -> goToMainActivity() MenuState.Store -> { action = AnalyticsConstant.Domain.BUSINESS - label = AnalyticsConstant.Label.HAMBURGER_STORE + label = AnalyticsConstant.Label.HAMBURGER_SHOP value = getString(R.string.nearby_stores) goToStoreActivity() } diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index a0a193bd1..0a4cee26a 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -1,7 +1,6 @@ package `in`.koreatech.koin.ui.store.activity import android.os.Bundle -import android.util.Log import android.view.MotionEvent import android.view.View import android.widget.TextView @@ -51,7 +50,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { storeDetailContract.launch(it.uid) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.STORE_CLICK, + AnalyticsConstant.Label.SHOP_CLICK, it.name) } } @@ -112,7 +111,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { if(event.action == MotionEvent.ACTION_DOWN) { EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.STORE_CATEGORIES_SEARCH, + AnalyticsConstant.Label.SHOP_CATEGORIES_SEARCH, "search in " + getStoreCategoryName(viewModel.category.value) ) } @@ -239,7 +238,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.STORE_CATEGORIES, + AnalyticsConstant.Label.SHOP_CATEGORIES, eventValue ) } diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt index 0169d181b..652e08cbd 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreDetailActivity.kt @@ -88,7 +88,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { flyerDialogFragment?.show(supportFragmentManager, DIALOG_TAG) EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.STORE_PICTURE, + AnalyticsConstant.Label.SHOP_PICTURE, viewModel.store.value?.name ?: "Unknown") } } @@ -128,7 +128,7 @@ class StoreDetailActivity : KoinNavigationDrawerActivity() { showCallDialog() EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, - AnalyticsConstant.Label.STORE_CALL, + AnalyticsConstant.Label.SHOP_CALL, viewModel.store.value?.name ?: "Unknown") } From 97e791e0abea688f605d347bb751450b73750f8f Mon Sep 17 00:00:00 2001 From: Strone Date: Sat, 27 Apr 2024 02:13:15 +0900 Subject: [PATCH 40/61] Add Dining Dialog PhotoView --- .../koin/ui/dining/adapter/DiningAdapter.kt | 162 ++++++++++++------ .../main/res/layout/dialog_dining_image.xml | 32 ++-- koin/src/main/res/values/strings.xml | 1 + 3 files changed, 132 insertions(+), 63 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index 32e3be290..6223c4ba4 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -1,20 +1,22 @@ package `in`.koreatech.koin.ui.dining.adapter -import android.annotation.SuppressLint import android.app.Dialog +import android.content.Context import android.graphics.Color +import android.graphics.Rect import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.util.TypedValue import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.ImageView -import android.widget.LinearLayout -import androidx.constraintlayout.widget.ConstraintSet -import androidx.core.view.marginStart -import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import com.github.chrisbanes.photoview.PhotoView import `in`.koreatech.koin.R import `in`.koreatech.koin.databinding.ItemDiningBinding import `in`.koreatech.koin.domain.model.dining.Dining @@ -31,6 +33,64 @@ class DiningAdapter : ListAdapter(diffCallback) class DiningViewHolder(private val binding: ItemDiningBinding) : RecyclerView.ViewHolder(binding.root) { + fun bind(dining: Dining) { + with(binding) { + val context = root.context + + setDiningImageVisibility(context, dining) + setDiningDataText(context, dining) + setEmptyDataVisibility(dining) + + if(dining.imageUrl.isNotEmpty()) { + cardViewDining.strokeWidth = 0 + textViewNoPhoto.visibility = View.INVISIBLE + imageViewNoPhoto.visibility = View.INVISIBLE + imageViewDining.visibility = View.VISIBLE + Glide.with(context) + .load(dining.imageUrl) + .into(imageViewDining) + + val dialog = createZoomableDialog(context) + cardViewDining.setOnClickListener { + dialog.show() + val imageView = dialog.findViewById(R.id.photo_view_dining) + Glide.with(context) + .load(dining.imageUrl) + .into(imageView) + } + } else { + cardViewDining.strokeWidth = + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, context.resources.displayMetrics).toInt() + textViewNoPhoto.visibility = View.VISIBLE + imageViewNoPhoto.visibility = View.VISIBLE + imageViewDining.visibility = View.INVISIBLE + cardViewDining.setOnClickListener(null) + } + + if(dining.changedAt.isNotEmpty()) { + textViewDiningChanged.visibility = View.VISIBLE + } else { + textViewDiningChanged.visibility = View.INVISIBLE + } + + if(dining.soldoutAt.isNotEmpty()) { + groupSoldOut.visibility = View.VISIBLE + textViewDiningSoldOut.visibility = View.VISIBLE + textViewDiningChanged.visibility = View.INVISIBLE + } else { + groupSoldOut.visibility = View.INVISIBLE + textViewDiningSoldOut.visibility = View.INVISIBLE + } + } + } + + private fun setDiningImageVisibility(context: Context, dining: Dining) { + when(dining.place) { + context.getString(R.string.dining_nungsu), + context.getString(R.string.dining_2campus) -> binding.cardViewDining.visibility = View.GONE + else -> binding.cardViewDining.visibility = View.VISIBLE + } + } private fun setEmptyDataVisibility(dining: Dining) { with(binding) { if(dining.kcal.isEmpty()) { @@ -50,16 +110,9 @@ class DiningAdapter : ListAdapter(diffCallback) } } } - - fun bind(dining: Dining) { + private fun setDiningDataText(context: Context, dining: Dining) { with(binding) { - val context = root.context textViewDiningCorner.text = dining.place - when(dining.place) { - "능수관", "2캠퍼스" -> cardViewDining.visibility = View.GONE - else -> cardViewDining.visibility = View.VISIBLE - } - textViewKcal.text = context.getString(R.string.dining_kcal, dining.kcal) textViewCashPrice.text = @@ -67,49 +120,60 @@ class DiningAdapter : ListAdapter(diffCallback) textViewCardPrice.text = context.getString(R.string.price, dining.priceCard) textViewDiningMenuItems.text = dining.menu.joinToString("\n") - - setEmptyDataVisibility(dining) + } + } + private fun createZoomableDialog(context: Context) : Dialog = object : Dialog(context) { - if(dining.imageUrl.isNotEmpty()) { - Glide.with(context) - .load(dining.imageUrl) - .into(imageViewDining) + private var isUserImageInteraction = false + private val ACTION_POINTER_DOWN = 261 + private lateinit var photoView : PhotoView + private lateinit var imageViewClose : ImageView - cardViewDining.strokeWidth = 0 - textViewNoPhoto.visibility = View.INVISIBLE - imageViewNoPhoto.visibility = View.INVISIBLE + override fun onStart() { + super.onStart() + window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) + window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + } - val dialog = Dialog(context).apply { - setContentView(R.layout.dialog_dining_image) - window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) - } - val closeButton = dialog.findViewById(R.id.image_view_close) - closeButton.setOnClickListener { - dialog.dismiss() - } - cardViewDining.setOnClickListener { - val imageView = dialog.findViewById(R.id.image_view_dining) - Glide.with(context) - .load(dining.imageUrl) - .into(imageView) - dialog.show() - } - } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.dialog_dining_image) - if(dining.changedAt.isNotEmpty()) { - textViewDiningChanged.visibility = View.VISIBLE - } else { - textViewDiningChanged.visibility = View.INVISIBLE + photoView = findViewById(R.id.photo_view_dining) + imageViewClose = findViewById(R.id.image_view_close) + + imageViewClose.setOnClickListener { + dismiss() } + } - if(dining.soldoutAt.isNotEmpty()) { - groupSoldOut.visibility = View.VISIBLE - textViewDiningSoldOut.visibility = View.VISIBLE - textViewDiningChanged.visibility = View.INVISIBLE - } else { - groupSoldOut.visibility = View.INVISIBLE - textViewDiningSoldOut.visibility = View.INVISIBLE + override fun onTouchEvent(event: MotionEvent): Boolean { + if(event.action == ACTION_POINTER_DOWN) + isUserImageInteraction = true + + // 이미지 영역 밖 터치 시 dismiss + if(event.action == MotionEvent.ACTION_UP) { + if (!isUserImageInteraction) { + val rect = Rect() + window!!.decorView.getWindowVisibleDisplayFrame(rect) + val statusBarHeight = rect.top + photoView.getGlobalVisibleRect(rect) + + with(photoView) { + rect.apply { + right = rect.left + displayRect.right.toInt() + left += displayRect.left.toInt() + bottom = rect.top + displayRect.bottom.toInt() + statusBarHeight + top += displayRect.top.toInt() + statusBarHeight + } + } + if (!rect.contains(event.rawX.toInt(), event.rawY.toInt())) { + dismiss() + } + } + isUserImageInteraction = false } + return super.onTouchEvent(event) } } } diff --git a/koin/src/main/res/layout/dialog_dining_image.xml b/koin/src/main/res/layout/dialog_dining_image.xml index 423e35feb..cf60924bf 100644 --- a/koin/src/main/res/layout/dialog_dining_image.xml +++ b/koin/src/main/res/layout/dialog_dining_image.xml @@ -1,7 +1,10 @@ - + app:layout_constraintEnd_toEndOf="@id/photo_view_dining" + app:layout_constraintBottom_toTopOf="@id/photo_view_dining" /> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> \ No newline at end of file diff --git a/koin/src/main/res/values/strings.xml b/koin/src/main/res/values/strings.xml index 3239f24c4..9b811e717 100644 --- a/koin/src/main/res/values/strings.xml +++ b/koin/src/main/res/values/strings.xml @@ -238,6 +238,7 @@ 일품식 양식 능수관 + 2캠퍼스 학교에서 식단이 업로드 되지 않았습니다. 품절 변경됨 From ce639040f54a94eff0164ca4d11fe59173c2a84a Mon Sep 17 00:00:00 2001 From: Strone Date: Tue, 30 Apr 2024 11:22:26 +0900 Subject: [PATCH 41/61] Use Reflection isInitialized --- .../java/in/koreatech/koin/ui/main/activity/MainActivity.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index f68fc21a2..1203cfe18 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -58,7 +58,6 @@ class MainActivity : KoinNavigationDrawerActivity() { } } private lateinit var busViewPagerScrollCallback: ViewPager2.OnPageChangeCallback - private var isBusScrollCallbackInitialized = false private val diningContainerAdapter by lazy { DiningContainerViewPager2Adapter(this) } @@ -164,9 +163,8 @@ class MainActivity : KoinNavigationDrawerActivity() { observeLiveData(busTimer) { busPagerAdapter.setBusTimerItems(it) - if (!isBusScrollCallbackInitialized) { + if (this@MainActivity::busViewPagerScrollCallback.isInitialized.not()) { initBusViewPagerScrollCallback(it) - isBusScrollCallbackInitialized = true } } } From 2ccb7a3810636d35b64ff74eaf393d51e8c4b6d6 Mon Sep 17 00:00:00 2001 From: Strone Date: Tue, 30 Apr 2024 11:37:00 +0900 Subject: [PATCH 42/61] Change navi item analytics click event logic --- .../main/fragment/DiningContainerFragment.kt | 5 +- .../KoinNavigationDrawerActivity.kt | 68 +++++++++++-------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index 1865d4d2d..e88ca4053 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -38,7 +38,10 @@ class DiningContainerFragment : Fragment(R.layout.fragment_dining_container) { private fun initView() = with(binding) { diningContainer.setOnClickListener { - startActivity(Intent(requireContext(), DiningActivity::class.java)) + if (activity is MainActivity) { + val mainActivity = activity as MainActivity + mainActivity.callDrawerItem(R.id.navi_item_dining) + } EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.MAIN_MENU_MOVEDETAILVIEW, diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index 2d9841393..4e08d8494 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -132,6 +132,43 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), else -> { koinNavigationDrawerViewModel.selectMenu(state) + var action = "" + var label = "" + var value = "" + when(state) { + MenuState.Store -> { + action = AnalyticsConstant.Domain.BUSINESS + label = AnalyticsConstant.Label.HAMBURGER_SHOP + value = getString(R.string.nearby_stores) + } + MenuState.Bus -> { + action = AnalyticsConstant.Domain.CAMPUS + label = AnalyticsConstant.Label.HAMBURGER_BUS + value = getString(R.string.bus) + } + MenuState.Dining -> { + action = AnalyticsConstant.Domain.CAMPUS + label = AnalyticsConstant.Label.HAMBURGER_DINING + value = getString(R.string.navigation_item_dining) + } + MenuState.UserInfo -> { + action = AnalyticsConstant.Domain.USER + value = getString(R.string.navigation_drawer_right_myinfo) + if (koinNavigationDrawerViewModel.userState.value == null || koinNavigationDrawerViewModel.userState.value?.isAnonymous == true) { + label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITHOUT_LOGIN + showLoginRequestDialog() + } else { + label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITH_LOGIN + goToUserInfoActivity() + } + } + else -> Unit + } + EventLogger.logClickEvent( + action, + label, + value + ) } } } @@ -139,6 +176,7 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), findViewById(R.id.navi_item_myinfo).setOnClickListener { koinNavigationDrawerViewModel.selectMenu(MenuState.UserInfo) + } val leftArrowButton = findViewById(R.id.drawer_left_arrow_button) @@ -205,31 +243,12 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), } observeLiveData(menuEvent) { menuState -> - var action = "" - var label = "" - var value = "" when (menuState) { - MenuState.Bus -> { - action = AnalyticsConstant.Domain.CAMPUS - label = AnalyticsConstant.Label.HAMBURGER_BUS - value = getString(R.string.bus) - goToBusActivity() - } - MenuState.Dining -> { - action = AnalyticsConstant.Domain.CAMPUS - label = AnalyticsConstant.Label.HAMBURGER_DINING - value = getString(R.string.navigation_item_dining) - goToDiningActivity() - } + MenuState.Bus -> goToBusActivity() + MenuState.Dining -> goToDiningActivity() MenuState.Land -> goToLandActivity() MenuState.Main -> goToMainActivity() - MenuState.Store -> { - action = AnalyticsConstant.Domain.BUSINESS - label = AnalyticsConstant.Label.HAMBURGER_SHOP - value = getString(R.string.nearby_stores) - goToStoreActivity() - } - + MenuState.Store -> goToStoreActivity() MenuState.Timetable -> { if (userState.value == null || userState.value?.isAnonymous == true) { goToAnonymousTimeTableActivity() @@ -239,19 +258,14 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), } MenuState.UserInfo -> { - action = AnalyticsConstant.Domain.USER - value = getString(R.string.navigation_drawer_right_myinfo) if (userState.value == null || userState.value?.isAnonymous == true) { - label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITHOUT_LOGIN showLoginRequestDialog() } else { - label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITH_LOGIN goToUserInfoActivity() } } else -> Unit } - EventLogger.logClickEvent(action, label, value) drawerLayout.closeDrawer() } } From 88a12f98254000201d2854ff096ad1c014d977f9 Mon Sep 17 00:00:00 2001 From: Strone Date: Tue, 30 Apr 2024 12:59:27 +0900 Subject: [PATCH 43/61] Consider configuration change, use viewmodel --- .../koin/ui/bus/fragment/BusMainFragment.kt | 13 ++++---- .../fragment/ExpressBusTimetableFragment.kt | 30 +++++++++---------- .../fragment/ShuttleBusTimetableFragment.kt | 17 +++++++++-- .../bus/viewmodel/BusMainFragmentViewModel.kt | 1 + 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt index 183c84676..c5613c3cc 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/BusMainFragment.kt @@ -43,39 +43,38 @@ class BusMainFragment : Fragment(R.layout.bus_main_fragment) { initViewModel() } - private var isUserSelection = false private fun initView() = with(binding) { busDepartureSpinner.setSelection(BusNode.Koreatech.spinnerSelection) busArrivalSpinner.setSelection(BusNode.Terminal.spinnerSelection) busDepartureSpinner.setOnTouchListener { _, _ -> - isUserSelection = true + viewModel.isUserSelection = true busDepartureSpinner.performClick() } busDepartureSpinner.setOnItemSelectedListener { _, _, position, _ -> viewModel.setDeparture(position.busNodeSelection) - if(isUserSelection) { + if(viewModel.isUserSelection) { EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.BUS_DEPARTURE, resources.getStringArray(R.array.bus_place)[position] ) - isUserSelection = false + viewModel.isUserSelection = false } } busArrivalSpinner.setOnTouchListener { _, _ -> - isUserSelection = true + viewModel.isUserSelection = true busArrivalSpinner.performClick() } busArrivalSpinner.setOnItemSelectedListener { _, _, position, _ -> viewModel.setArrival(position.busNodeSelection) - if(isUserSelection) { + if(viewModel.isUserSelection) { EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.BUS_ARRIVAL, resources.getStringArray(R.array.bus_place)[position] ) - isUserSelection = false + viewModel.isUserSelection = false } } recyclerView.apply { diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt index 70231199f..6f6863f57 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ExpressBusTimetableFragment.kt @@ -1,30 +1,25 @@ package `in`.koreatech.koin.ui.bus.fragment +import android.os.Bundle +import android.view.View +import android.widget.ArrayAdapter +import androidx.core.view.isVisible +import androidx.fragment.app.viewModels +import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint import `in`.koreatech.koin.R +import `in`.koreatech.koin.core.analytics.EventLogger +import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.fragment.DataBindingFragment import `in`.koreatech.koin.core.progressdialog.IProgressDialog import `in`.koreatech.koin.databinding.LayoutExpressBusTimetableBinding -import `in`.koreatech.koin.databinding.LayoutShuttleBusTimetableBinding import `in`.koreatech.koin.ui.bus.adpater.timetable.ExpressBusTimetableAdapter -import `in`.koreatech.koin.ui.bus.adpater.timetable.ShuttleBusTimetableAdapter import `in`.koreatech.koin.ui.bus.state.toExpressBusTimetableUiItem -import `in`.koreatech.koin.ui.bus.state.toShuttleBusTimetableUiItem import `in`.koreatech.koin.ui.bus.viewmodel.ExpressBusTimetableViewModel -import `in`.koreatech.koin.ui.bus.viewmodel.ShuttleBusTimetableViewModel -import `in`.koreatech.koin.util.SnackbarUtil import `in`.koreatech.koin.util.ext.observeLiveData import `in`.koreatech.koin.util.ext.setOnItemSelectedListener import `in`.koreatech.koin.util.ext.withLoading import `in`.koreatech.koin.util.ext.withToastError -import android.os.Bundle -import android.view.View -import android.widget.ArrayAdapter -import androidx.core.view.isVisible -import androidx.fragment.app.viewModels -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import `in`.koreatech.koin.core.analytics.EventLogger -import `in`.koreatech.koin.core.constant.AnalyticsConstant @AndroidEntryPoint class ExpressBusTimetableFragment : DataBindingFragment() { @@ -32,6 +27,7 @@ class ExpressBusTimetableFragment : DataBindingFragment() private val expressBusTimetableAdapter = ExpressBusTimetableAdapter() + private var isInitialization = true override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -49,6 +45,10 @@ class ExpressBusTimetableFragment : DataBindingFragment expressBusTimetableViewModel.setCoursePosition(position) + if (isInitialization) { + isInitialization = false + return@setOnItemSelectedListener + } EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.BUS_TIMETABLE_EXPRESS, @@ -63,7 +63,7 @@ class ExpressBusTimetableFragment : DataBindingFragment - if(courses.isNullOrEmpty()) { + if (courses.isNullOrEmpty()) { binding.busTimetableCoursesSpinner.isVisible = false } else { binding.busTimetableCoursesSpinner.isVisible = true diff --git a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt index 6cc9538ed..d1757558c 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/bus/fragment/ShuttleBusTimetableFragment.kt @@ -27,6 +27,8 @@ class ShuttleBusTimetableFragment : DataBindingFragment() private val shuttleBusTimetableAdapter = ShuttleBusTimetableAdapter() + private var isCourseInitialization = true + private var isRouteInitialization = true override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -44,6 +46,10 @@ class ShuttleBusTimetableFragment : DataBindingFragment shuttleBusTimetableViewModel.setCoursePosition(position) + if (isCourseInitialization) { + isCourseInitialization = false + return@setOnItemSelectedListener + } EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.BUS_TIMETABLE_AREA, @@ -53,6 +59,10 @@ class ShuttleBusTimetableFragment : DataBindingFragment shuttleBusTimetableViewModel.setRoutePosition(position) + if (isRouteInitialization) { + isRouteInitialization = false + return@setOnItemSelectedListener + } EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.BUS_TIMETABLE_TIME, @@ -67,7 +77,7 @@ class ShuttleBusTimetableFragment : DataBindingFragment - if(courses.isNullOrEmpty()) { + if (courses.isNullOrEmpty()) { binding.busTimetableCoursesSpinner.isVisible = false } else { binding.busTimetableCoursesSpinner.isVisible = true @@ -93,7 +103,7 @@ class ShuttleBusTimetableFragment : DataBindingFragment(BusNode.Koreatech) private val _arrival = MutableLiveData(BusNode.Terminal) + var isUserSelection = false val departure: LiveData get() = _departure val arrival: LiveData get() = _arrival From 2fbe342fbd0ed1ed46230c0a93bfa8eaccf8dbb4 Mon Sep 17 00:00:00 2001 From: Strone Date: Tue, 30 Apr 2024 13:23:37 +0900 Subject: [PATCH 44/61] Set not to log if is debug --- .../java/in/koreatech/koin/core/analytics/EventLogger.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt index 2b04e53eb..2d89f5390 100644 --- a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt +++ b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt @@ -1,8 +1,10 @@ package `in`.koreatech.koin.core.analytics +import android.os.Build import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase +import `in`.koreatech.koin.core.BuildConfig import `in`.koreatech.koin.core.constant.AnalyticsConstant object EventLogger { @@ -30,9 +32,10 @@ object EventLogger { * @param category: 이벤트 종류(click, scroll, ...) * @param label: 이벤트 소분류 * @param value: 이벤트 값 - * @sample logEvent("BUSINESS", "click", "main_store_categories", "전체보기") + * @sample logEvent("BUSINESS", "click", "main_shop_categories", "전체보기") */ private fun logEvent(action: String, category: String, label: String, value: String) { + if(BuildConfig.IS_DEBUG) return Firebase.analytics.logEvent(action) { param("event_category", category) param("event_label", label) From 709fda41701e76486af17aed03835ffc10cf5cd0 Mon Sep 17 00:00:00 2001 From: Strone Date: Tue, 30 Apr 2024 23:12:27 +0900 Subject: [PATCH 45/61] Modify dialog PhotoView logic --- .../koin/ui/dining/adapter/DiningAdapter.kt | 49 +++++++++++++++---- .../main/res/layout/dialog_dining_image.xml | 14 +----- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index 6223c4ba4..b45857d4d 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -1,21 +1,26 @@ package `in`.koreatech.koin.ui.dining.adapter +import android.annotation.SuppressLint import android.app.Dialog import android.content.Context import android.graphics.Color import android.graphics.Rect import android.graphics.drawable.ColorDrawable +import android.graphics.drawable.Drawable import android.os.Bundle import android.util.TypedValue import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import android.widget.ImageView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.engine.GlideException +import com.bumptech.glide.request.RequestListener +import com.bumptech.glide.request.target.Target import com.github.chrisbanes.photoview.PhotoView import `in`.koreatech.koin.R import `in`.koreatech.koin.databinding.ItemDiningBinding @@ -53,10 +58,31 @@ class DiningAdapter : ListAdapter(diffCallback) val dialog = createZoomableDialog(context) cardViewDining.setOnClickListener { dialog.show() - val imageView = dialog.findViewById(R.id.photo_view_dining) + val photoView = dialog.findViewById(R.id.photo_view_dining) Glide.with(context) .load(dining.imageUrl) - .into(imageView) + .listener(object : RequestListener { + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean = false + + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean + ): Boolean { + photoView.post { + photoView.scale = DIALOG_MIN_SCALE + } + return false + } + }) + .into(photoView) } } else { cardViewDining.strokeWidth = @@ -125,9 +151,7 @@ class DiningAdapter : ListAdapter(diffCallback) private fun createZoomableDialog(context: Context) : Dialog = object : Dialog(context) { private var isUserImageInteraction = false - private val ACTION_POINTER_DOWN = 261 private lateinit var photoView : PhotoView - private lateinit var imageViewClose : ImageView override fun onStart() { super.onStart() @@ -135,15 +159,20 @@ class DiningAdapter : ListAdapter(diffCallback) window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) } + @SuppressLint("ClickableViewAccessibility") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.dialog_dining_image) photoView = findViewById(R.id.photo_view_dining) - imageViewClose = findViewById(R.id.image_view_close) - - imageViewClose.setOnClickListener { - dismiss() + photoView.apply { + setOnTouchListener { v, event -> + attacher.onTouch(v, event) + if (event?.action == 261 || event?.action == MotionEvent.ACTION_UP) + false + else true + } + minimumScale = DIALOG_MIN_SCALE } } @@ -179,6 +208,8 @@ class DiningAdapter : ListAdapter(diffCallback) } companion object { + private const val DIALOG_MIN_SCALE = 0.75f + private const val ACTION_POINTER_DOWN = 261 private val diffCallback = object : DiffUtil.ItemCallback() { override fun areItemsTheSame( oldItem: Dining, diff --git a/koin/src/main/res/layout/dialog_dining_image.xml b/koin/src/main/res/layout/dialog_dining_image.xml index cf60924bf..ecbe395b6 100644 --- a/koin/src/main/res/layout/dialog_dining_image.xml +++ b/koin/src/main/res/layout/dialog_dining_image.xml @@ -7,21 +7,11 @@ android:clipChildren="false" xmlns:app="http://schemas.android.com/apk/res-auto"> - - Date: Wed, 1 May 2024 00:09:17 +0900 Subject: [PATCH 46/61] Change date background ui logic --- .../ui/dining/adapter/DiningDateAdapter.kt | 8 +++---- koin/src/main/res/layout/item_dining_date.xml | 24 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt index 17888df05..dcf6c86f2 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningDateAdapter.kt @@ -46,7 +46,7 @@ class DiningDateAdapter( textViewDayOfTheWeek.text = DateFormatUtil.getDayOfWeek(date) textViewDay.text = date.date.toString() - backgroundTodayIndicator.visibility = View.INVISIBLE + groupTodayIndicator.visibility = View.INVISIBLE if (position < itemCount / 2) { // 오늘 이전 textViewDay.setTextColor( ContextCompat.getColor( @@ -81,12 +81,12 @@ class DiningDateAdapter( R.color.gray9 ) ) - backgroundTodayIndicator.visibility = View.VISIBLE + groupTodayIndicator.visibility = View.VISIBLE } - groupSelectedDate.visibility = View.INVISIBLE + backgroundSelectedDate.visibility = View.INVISIBLE if (position == selectedPosition) { - groupSelectedDate.visibility = View.VISIBLE + backgroundSelectedDate.visibility = View.VISIBLE textViewDay.setTextColor(Color.WHITE) } diff --git a/koin/src/main/res/layout/item_dining_date.xml b/koin/src/main/res/layout/item_dining_date.xml index 0ee1f9516..8f7b6c19c 100644 --- a/koin/src/main/res/layout/item_dining_date.xml +++ b/koin/src/main/res/layout/item_dining_date.xml @@ -22,36 +22,36 @@ app:layout_constraintVertical_chainStyle="packed" tools:text="월" /> + + - - Date: Wed, 1 May 2024 01:01:54 +0900 Subject: [PATCH 47/61] Modify text height --- koin/src/main/res/layout/item_dining.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/koin/src/main/res/layout/item_dining.xml b/koin/src/main/res/layout/item_dining.xml index 63b96b6c8..69852597d 100644 --- a/koin/src/main/res/layout/item_dining.xml +++ b/koin/src/main/res/layout/item_dining.xml @@ -12,7 +12,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" - android:gravity="center_vertical" android:orientation="horizontal" android:paddingTop="16dp" app:layout_constraintStart_toStartOf="parent" From 1251c4bb593e6ce4f31b6d69e446fcdb9cab0308 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 02:14:13 +0900 Subject: [PATCH 48/61] Remove unnecessary import --- .../main/java/in/koreatech/koin/core/analytics/EventLogger.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt index 2d89f5390..cf464e56a 100644 --- a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt +++ b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt @@ -1,6 +1,5 @@ package `in`.koreatech.koin.core.analytics -import android.os.Build import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase From da2266846a2c45d42f965a458e40129fe4cff503 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 02:27:03 +0900 Subject: [PATCH 49/61] Remove use of startActivty -> use callDrawerItem --- .../java/in/koreatech/koin/core/activity/ActivityBase.kt | 2 -- .../in/koreatech/koin/ui/main/activity/MainActivity.kt | 4 +--- .../koin/ui/main/fragment/DiningContainerFragment.kt | 2 -- .../koin/ui/navigation/KoinNavigationDrawerActivity.kt | 7 +------ 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt index 59a95cc32..a8e928ad9 100644 --- a/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt +++ b/core/src/main/java/in/koreatech/koin/core/activity/ActivityBase.kt @@ -10,8 +10,6 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.analytics import com.google.firebase.analytics.ktx.logEvent import com.google.firebase.ktx.Firebase -import `in`.koreatech.koin.core.analytics.EventLogger -import `in`.koreatech.koin.core.constant.AnalyticsConstant import `in`.koreatech.koin.core.progressdialog.CustomProgressDialog import `in`.koreatech.koin.core.progressdialog.IProgressDialog diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt index 1203cfe18..bb21637aa 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/activity/MainActivity.kt @@ -1,6 +1,5 @@ package `in`.koreatech.koin.ui.main.activity -import android.content.Intent import android.os.Bundle import android.view.View import android.widget.TextView @@ -22,7 +21,6 @@ import `in`.koreatech.koin.data.util.todayOrTomorrow import `in`.koreatech.koin.databinding.ActivityMainBinding import `in`.koreatech.koin.domain.model.bus.timer.BusArrivalInfo import `in`.koreatech.koin.domain.model.dining.DiningPlace -import `in`.koreatech.koin.ui.bus.BusActivity import `in`.koreatech.koin.ui.main.StoreCategoryRecyclerAdapter import `in`.koreatech.koin.ui.main.adapter.BusPagerAdapter import `in`.koreatech.koin.ui.main.adapter.DiningContainerViewPager2Adapter @@ -41,7 +39,7 @@ class MainActivity : KoinNavigationDrawerActivity() { private val busPagerAdapter = BusPagerAdapter().apply { setOnCardClickListener { - startActivity(Intent(this@MainActivity, BusActivity::class.java)) + callDrawerItem(R.id.navi_item_bus, Bundle()) EventLogger.logClickEvent( AnalyticsConstant.Domain.CAMPUS, AnalyticsConstant.Label.MAIN_BUS, diff --git a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt index e88ca4053..12124ff86 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/main/fragment/DiningContainerFragment.kt @@ -1,6 +1,5 @@ package `in`.koreatech.koin.ui.main.fragment -import android.content.Intent import android.os.Bundle import android.view.View import androidx.core.content.ContextCompat @@ -18,7 +17,6 @@ import `in`.koreatech.koin.domain.model.dining.Dining import `in`.koreatech.koin.domain.util.DiningUtil import `in`.koreatech.koin.domain.util.ext.arrange import `in`.koreatech.koin.domain.util.ext.typeFilter -import `in`.koreatech.koin.ui.dining.DiningActivity import `in`.koreatech.koin.ui.main.activity.MainActivity import `in`.koreatech.koin.ui.main.viewmodel.MainActivityViewModel import `in`.koreatech.koin.util.ext.observeLiveData diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index 4e08d8494..d861c66a4 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -164,11 +164,7 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), } else -> Unit } - EventLogger.logClickEvent( - action, - label, - value - ) + EventLogger.logClickEvent(action, label, value) } } } @@ -176,7 +172,6 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), findViewById(R.id.navi_item_myinfo).setOnClickListener { koinNavigationDrawerViewModel.selectMenu(MenuState.UserInfo) - } val leftArrowButton = findViewById(R.id.drawer_left_arrow_button) From 2fa7b4bba8ce6ce4c70e3a95607cbf558dc44355 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 02:34:22 +0900 Subject: [PATCH 50/61] Fix visibility logic --- .../in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index b45857d4d..ab4d6aba8 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -119,6 +119,12 @@ class DiningAdapter : ListAdapter(diffCallback) } private fun setEmptyDataVisibility(dining: Dining) { with(binding) { + textViewKcal.visibility = View.VISIBLE + dividerDot.visibility = View.VISIBLE + textViewCashPrice.visibility = View.VISIBLE + dividerSlash.visibility = View.VISIBLE + textViewCardPrice.visibility = View.VISIBLE + if(dining.kcal.isEmpty()) { textViewKcal.visibility = View.GONE dividerDot.visibility = View.GONE @@ -168,7 +174,7 @@ class DiningAdapter : ListAdapter(diffCallback) photoView.apply { setOnTouchListener { v, event -> attacher.onTouch(v, event) - if (event?.action == 261 || event?.action == MotionEvent.ACTION_UP) + if (event?.action == ACTION_POINTER_DOWN || event?.action == MotionEvent.ACTION_UP) false else true } From d33786166ecbcc04a1c838616eb748454427f0c4 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 11:26:56 +0900 Subject: [PATCH 51/61] Add dialog close button --- .../koreatech/koin/ui/dining/adapter/DiningAdapter.kt | 8 ++++++++ koin/src/main/res/layout/dialog_dining_image.xml | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index ab4d6aba8..a56f64852 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -13,6 +13,8 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -78,6 +80,12 @@ class DiningAdapter : ListAdapter(diffCallback) ): Boolean { photoView.post { photoView.scale = DIALOG_MIN_SCALE + + val closeButton = dialog.findViewById(R.id.close_button_dining) + val lp = closeButton.layoutParams as FrameLayout.LayoutParams + val rectF = photoView.displayRect + lp.setMargins(0, rectF.top.toInt() - closeButton.height - 8, rectF.left.toInt(), 0) + closeButton.layoutParams = lp } return false } diff --git a/koin/src/main/res/layout/dialog_dining_image.xml b/koin/src/main/res/layout/dialog_dining_image.xml index ecbe395b6..7da37f822 100644 --- a/koin/src/main/res/layout/dialog_dining_image.xml +++ b/koin/src/main/res/layout/dialog_dining_image.xml @@ -1,5 +1,5 @@ - + + - \ No newline at end of file + \ No newline at end of file From e9f0a96c63dbc614c4d2945781b20c54c23b0981 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 11:38:38 +0900 Subject: [PATCH 52/61] Make close button invisible until its position fixed --- .../java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt | 1 + koin/src/main/res/layout/dialog_dining_image.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index a56f64852..cf1221a31 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -86,6 +86,7 @@ class DiningAdapter : ListAdapter(diffCallback) val rectF = photoView.displayRect lp.setMargins(0, rectF.top.toInt() - closeButton.height - 8, rectF.left.toInt(), 0) closeButton.layoutParams = lp + closeButton.visibility = View.VISIBLE } return false } diff --git a/koin/src/main/res/layout/dialog_dining_image.xml b/koin/src/main/res/layout/dialog_dining_image.xml index 7da37f822..f7c9eda6f 100644 --- a/koin/src/main/res/layout/dialog_dining_image.xml +++ b/koin/src/main/res/layout/dialog_dining_image.xml @@ -12,6 +12,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" + android:visibility="invisible" android:src="@drawable/ic_close_round" /> Date: Wed, 1 May 2024 12:07:36 +0900 Subject: [PATCH 53/61] Modify unnecessary logic --- .../koin/ui/dining/adapter/DiningAdapter.kt | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index cf1221a31..b7c052745 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -201,17 +201,8 @@ class DiningAdapter : ListAdapter(diffCallback) val rect = Rect() window!!.decorView.getWindowVisibleDisplayFrame(rect) val statusBarHeight = rect.top - photoView.getGlobalVisibleRect(rect) - - with(photoView) { - rect.apply { - right = rect.left + displayRect.right.toInt() - left += displayRect.left.toInt() - bottom = rect.top + displayRect.bottom.toInt() + statusBarHeight - top += displayRect.top.toInt() + statusBarHeight - } - } - if (!rect.contains(event.rawX.toInt(), event.rawY.toInt())) { + + if (!photoView.displayRect.contains(event.rawX, event.rawY - statusBarHeight)) { dismiss() } } From 0cb2f7f27084c514901199d28309b6ff696fadf8 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 15:16:10 +0900 Subject: [PATCH 54/61] Set data invisible when it == 0 --- .../in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt index b7c052745..eb98834c0 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/dining/adapter/DiningAdapter.kt @@ -134,19 +134,19 @@ class DiningAdapter : ListAdapter(diffCallback) dividerSlash.visibility = View.VISIBLE textViewCardPrice.visibility = View.VISIBLE - if(dining.kcal.isEmpty()) { + if(dining.kcal.isEmpty() || dining.kcal == "0") { textViewKcal.visibility = View.GONE dividerDot.visibility = View.GONE } - if(dining.priceCash.isEmpty()) { + if(dining.priceCash.isEmpty() || dining.priceCash == "0") { textViewCashPrice.visibility = View.GONE dividerSlash.visibility = View.GONE } - if(dining.priceCard.isEmpty()) { + if(dining.priceCard.isEmpty() || dining.priceCard == "0") { textViewCardPrice.visibility = View.GONE dividerSlash.visibility = View.GONE } - if(dining.priceCard.isEmpty() && dining.priceCash.isEmpty()) { + if((dining.priceCard.isEmpty() || dining.priceCard == "0") && (dining.priceCash.isEmpty() || dining.priceCash == "0")) { dividerDot.visibility = View.GONE } } From e91519eec1aef3fe616a8e8a8e0be3e32ea57dc7 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 17:54:47 +0900 Subject: [PATCH 55/61] Set untranslatable type description --- .../src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt index bfb433115..5dfa1fea5 100644 --- a/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt +++ b/domain/src/main/java/in/koreatech/koin/domain/util/DiningUtil.kt @@ -47,7 +47,7 @@ object DiningUtil { DiningType.Lunch.typeEnglish -> DiningType.Lunch.typeKorean DiningType.Dinner.typeEnglish -> DiningType.Dinner.typeKorean DiningType.NextBreakfast.typeEnglish -> DiningType.NextBreakfast.typeKorean - else -> "" + else -> "Unknown type" } } } \ No newline at end of file From a04c386d06e69773eefa30a6bc6ca2fe6a1fd1e5 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 17:57:13 +0900 Subject: [PATCH 56/61] Make parameters constant --- .../in/koreatech/koin/core/analytics/EventLogger.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt index cf464e56a..8b868881f 100644 --- a/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt +++ b/core/src/main/java/in/koreatech/koin/core/analytics/EventLogger.kt @@ -8,6 +8,10 @@ import `in`.koreatech.koin.core.constant.AnalyticsConstant object EventLogger { + private const val EVENT_CATEGORY = "event_category" + private const val EVENT_LABEL = "event_label" + private const val VALUE = "value" + /** * @param action: 이벤트 발생 도메인(BUSINESS, CAMPUS, USER) * @param label: 이벤트 소분류 @@ -34,11 +38,11 @@ object EventLogger { * @sample logEvent("BUSINESS", "click", "main_shop_categories", "전체보기") */ private fun logEvent(action: String, category: String, label: String, value: String) { - if(BuildConfig.IS_DEBUG) return + if (BuildConfig.IS_DEBUG) return Firebase.analytics.logEvent(action) { - param("event_category", category) - param("event_label", label) - param("value", value) + param(EVENT_CATEGORY, category) + param(EVENT_LABEL, label) + param(VALUE, value) } } } \ No newline at end of file From 824ae39e09dd4e0da89bcc3d6791d9df6511c00f Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 18:08:43 +0900 Subject: [PATCH 57/61] Remove unnecassary variable usage --- .../KoinNavigationDrawerActivity.kt | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt index d861c66a4..fd2494137 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/navigation/KoinNavigationDrawerActivity.kt @@ -132,39 +132,51 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), else -> { koinNavigationDrawerViewModel.selectMenu(state) - var action = "" - var label = "" - var value = "" - when(state) { + when (state) { MenuState.Store -> { - action = AnalyticsConstant.Domain.BUSINESS - label = AnalyticsConstant.Label.HAMBURGER_SHOP - value = getString(R.string.nearby_stores) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.BUSINESS, + AnalyticsConstant.Label.HAMBURGER_SHOP, + getString(R.string.nearby_stores) + ) } + MenuState.Bus -> { - action = AnalyticsConstant.Domain.CAMPUS - label = AnalyticsConstant.Label.HAMBURGER_BUS - value = getString(R.string.bus) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.HAMBURGER_BUS, + getString(R.string.bus) + ) } + MenuState.Dining -> { - action = AnalyticsConstant.Domain.CAMPUS - label = AnalyticsConstant.Label.HAMBURGER_DINING - value = getString(R.string.navigation_item_dining) + EventLogger.logClickEvent( + AnalyticsConstant.Domain.CAMPUS, + AnalyticsConstant.Label.HAMBURGER_DINING, + getString(R.string.navigation_item_dining) + ) } + MenuState.UserInfo -> { - action = AnalyticsConstant.Domain.USER - value = getString(R.string.navigation_drawer_right_myinfo) if (koinNavigationDrawerViewModel.userState.value == null || koinNavigationDrawerViewModel.userState.value?.isAnonymous == true) { - label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITHOUT_LOGIN + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITHOUT_LOGIN, + getString(R.string.navigation_drawer_right_myinfo) + ) showLoginRequestDialog() } else { - label = AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITH_LOGIN + EventLogger.logClickEvent( + AnalyticsConstant.Domain.USER, + AnalyticsConstant.Label.HAMBURGER_MY_INFO_WITH_LOGIN, + getString(R.string.navigation_drawer_right_myinfo) + ) goToUserInfoActivity() } } + else -> Unit } - EventLogger.logClickEvent(action, label, value) } } } @@ -259,6 +271,7 @@ abstract class KoinNavigationDrawerActivity : ActivityBase(), goToUserInfoActivity() } } + else -> Unit } drawerLayout.closeDrawer() From 2cc5f5bcacc7541dff46606f7da8e85d1239f7dd Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 18:13:06 +0900 Subject: [PATCH 58/61] Use StoreCategory.All --- .../java/in/koreatech/koin/ui/store/activity/StoreActivity.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index 0a4cee26a..0fd0bf444 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -224,8 +224,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { StoreCategory.Cafe -> getString(R.string.cafe) StoreCategory.BeautySalon -> getString(R.string.beauty_salon) StoreCategory.Etc -> getString(R.string.etc) - null -> getString(R.string.see_all) - else -> "" + StoreCategory.All, null -> getString(R.string.see_all) } } From be16867d0afb1913028e464cf1f1e2fde6957068 Mon Sep 17 00:00:00 2001 From: Strone Date: Wed, 1 May 2024 18:14:28 +0900 Subject: [PATCH 59/61] Apply lint --- .../koin/core/appbar/AppBarBase.java | 6 +-- .../koin/ui/store/activity/StoreActivity.kt | 51 ++++++++++--------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java b/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java index e07a4b085..206541414 100644 --- a/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java +++ b/core/src/main/java/in/koreatech/koin/core/appbar/AppBarBase.java @@ -52,7 +52,7 @@ public void setOnClickListener(OnClickListener onClickListener) { this.onClickListener = onClickListener; background.setOnClickListener(onClickListener); leftButton.setOnClickListener(onClickListener); - rightButton.setOnClickListener(v -> { + rightButton.setOnClickListener( v -> { onClickListener.onClick(v); EventLogger.INSTANCE.logClickEvent( AnalyticsConstant.Domain.USER, @@ -116,7 +116,7 @@ private void setTypeArray(TypedArray typedArray) { leftButton.setBackground(leftButtonBackground); leftButton.setText(leftButtonString); leftButton.setVisibility(leftButtonVisibility); - if(leftButtonHeight!= -1 || leftButtonWidth != -1){ + if (leftButtonHeight != -1 || leftButtonWidth != -1) { leftButton.setHeight(leftButtonHeight); leftButton.setWidth(leftButtonWidth); } @@ -125,7 +125,7 @@ private void setTypeArray(TypedArray typedArray) { rightButton.setBackground(rightButtonBackground); rightButton.setText(rightButtonString); rightButton.setVisibility(rightButtonVisibility); - if(leftButtonHeight!= -1 || leftButtonWidth != -1){ + if (leftButtonHeight != -1 || leftButtonWidth != -1) { rightButton.setHeight(rightButtonHeight); rightButton.setWidth(rightButtonWidth); } diff --git a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt index 0fd0bf444..c10f847b2 100644 --- a/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt +++ b/koin/src/main/java/in/koreatech/koin/ui/store/activity/StoreActivity.kt @@ -51,7 +51,8 @@ class StoreActivity : KoinNavigationDrawerActivity() { EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, AnalyticsConstant.Label.SHOP_CLICK, - it.name) + it.name + ) } } @@ -63,29 +64,29 @@ class StoreActivity : KoinNavigationDrawerActivity() { field = value } - private var showRemoveQueryButton : Boolean = false - set(value) { - if (!value) { - binding.searchImageView.background = ContextCompat.getDrawable( - this, - R.drawable.ic_search - ) - binding.searchImageView.layoutParams.apply { - width = dpToPx(24) - height = dpToPx(24) - } - } else { - binding.searchImageView.background = ContextCompat.getDrawable( - this, - R.drawable.ic_search_close - ) - binding.searchImageView.layoutParams.apply { - width = dpToPx(16) - height = dpToPx(16) + private var showRemoveQueryButton: Boolean = false + set(value) { + if (!value) { + binding.searchImageView.background = ContextCompat.getDrawable( + this, + R.drawable.ic_search + ) + binding.searchImageView.layoutParams.apply { + width = dpToPx(24) + height = dpToPx(24) + } + } else { + binding.searchImageView.background = ContextCompat.getDrawable( + this, + R.drawable.ic_search_close + ) + binding.searchImageView.layoutParams.apply { + width = dpToPx(16) + height = dpToPx(16) + } } + field = value } - field = value - } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -108,7 +109,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { } binding.searchEditText.setOnTouchListener { v, event -> - if(event.action == MotionEvent.ACTION_DOWN) { + if (event.action == MotionEvent.ACTION_DOWN) { EventLogger.logClickEvent( AnalyticsConstant.Domain.BUSINESS, AnalyticsConstant.Label.SHOP_CATEGORIES_SEARCH, @@ -129,7 +130,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { } binding.searchImageView.setOnClickListener { - if(showRemoveQueryButton) binding.searchEditText.setText("") + if (showRemoveQueryButton) binding.searchEditText.setText("") } handleCategoryClickEvent() @@ -214,7 +215,7 @@ class StoreActivity : KoinNavigationDrawerActivity() { } private fun getStoreCategoryName(category: StoreCategory?): String { - return when(category) { + return when (category) { StoreCategory.Chicken -> getString(R.string.chicken) StoreCategory.Pizza -> getString(R.string.pizza) StoreCategory.DOSIRAK -> getString(R.string.dorisak) From cd7a66700519b4fea40f71b4ce5ee0d99a01bc96 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 2 May 2024 12:31:02 +0900 Subject: [PATCH 60/61] Update bus timetable api response key --- .../in/koreatech/koin/data/response/bus/BusRouteResponse.kt | 4 ++-- .../koin/data/response/bus/ShuttleBusRouteResponse.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/src/main/java/in/koreatech/koin/data/response/bus/BusRouteResponse.kt b/data/src/main/java/in/koreatech/koin/data/response/bus/BusRouteResponse.kt index 6e67ec1b9..258407f3a 100644 --- a/data/src/main/java/in/koreatech/koin/data/response/bus/BusRouteResponse.kt +++ b/data/src/main/java/in/koreatech/koin/data/response/bus/BusRouteResponse.kt @@ -8,8 +8,8 @@ data class ShuttleBusRouteResponse( ) data class ShuttleBusNodeInfoResponse( - @SerializedName("node_name") val nodeName: String, - @SerializedName("arrival_time") val arrivalTime: String + @SerializedName("nodeName") val nodeName: String, + @SerializedName("arrivalTime") val arrivalTime: String ) data class ExpressBusRouteResponse( diff --git a/data/src/main/java/in/koreatech/koin/data/response/bus/ShuttleBusRouteResponse.kt b/data/src/main/java/in/koreatech/koin/data/response/bus/ShuttleBusRouteResponse.kt index 0adababca..7a501d36a 100644 --- a/data/src/main/java/in/koreatech/koin/data/response/bus/ShuttleBusRouteResponse.kt +++ b/data/src/main/java/in/koreatech/koin/data/response/bus/ShuttleBusRouteResponse.kt @@ -3,11 +3,11 @@ package `in`.koreatech.koin.data.response.bus import com.google.gson.annotations.SerializedName data class ShuttleBusTimetableResponse( - @SerializedName("bus_timetables") val routes: List, + @SerializedName("bus_timetable") val routes: List, @SerializedName("updated_at") val updatedAt: String ) data class ExpressBusTimetableResponse( - @SerializedName("bus_timetables") val routes: List, + @SerializedName("bus_timetable") val routes: List, @SerializedName("updated_at") val updatedAt: String ) \ No newline at end of file From 6dcfac0198b763c1f3caf187d16a02794e0fee90 Mon Sep 17 00:00:00 2001 From: Strone Date: Thu, 2 May 2024 12:42:22 +0900 Subject: [PATCH 61/61] Update v3.4.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 91e5528db..c6286c321 100644 --- a/build.gradle +++ b/build.gradle @@ -12,8 +12,8 @@ buildscript { compileSdkVersion = 34 minSdkVersion = 21 targetSdkVersion = 34 - versionName = "3.3.1" - minVersionCode = 30301 + versionName = "3.4.0" + minVersionCode = 30400 } dependencies {