diff --git a/data/src/main/java/org/gdsc/data/database/GroupBySearchPagingSource.kt b/data/src/main/java/org/gdsc/data/database/GroupBySearchPagingSource.kt new file mode 100644 index 00000000..a24d7c3c --- /dev/null +++ b/data/src/main/java/org/gdsc/data/database/GroupBySearchPagingSource.kt @@ -0,0 +1,33 @@ +package org.gdsc.data.database + +import androidx.paging.PagingSource +import androidx.paging.PagingState +import org.gdsc.data.network.GroupAPI +import org.gdsc.domain.model.GroupPreview +import org.gdsc.domain.model.request.GroupSearchRequest + +class GroupBySearchPagingSource( + private val api: GroupAPI, + private val groupSearchRequest: GroupSearchRequest, +): PagingSource() { + override fun getRefreshKey(state: PagingState): Int? { + return state.anchorPosition?.let { anchorPosition -> + val anchorPage = state.closestPageToPosition(anchorPosition) + anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1) + } + } + + override suspend fun load(params: LoadParams): LoadResult { + val page = params.key ?: 1 + return try { + val items = api.searchGroup(groupSearchRequest) + LoadResult.Page( + data = items.data.groupList, + prevKey = null, + nextKey = if (items.data.groupList.isEmpty()) null else page + 1 + ) + } catch (e: Exception) { + return LoadResult.Error(e) + } + } +} \ No newline at end of file diff --git a/data/src/main/java/org/gdsc/data/datasource/GroupDataSource.kt b/data/src/main/java/org/gdsc/data/datasource/GroupDataSource.kt index 8653d6e9..f4559e39 100644 --- a/data/src/main/java/org/gdsc/data/datasource/GroupDataSource.kt +++ b/data/src/main/java/org/gdsc/data/datasource/GroupDataSource.kt @@ -1,5 +1,7 @@ package org.gdsc.data.datasource +import androidx.paging.PagingData +import kotlinx.coroutines.flow.Flow import org.gdsc.domain.model.GroupPreview import org.gdsc.domain.model.response.Group @@ -10,4 +12,6 @@ interface GroupDataSource { suspend fun selectGroup(groupId: Int): String suspend fun searchGroup(keyword: String, limitCount: Int): List + + suspend fun searchPagingGroup(keyword: String): Flow> } \ No newline at end of file diff --git a/data/src/main/java/org/gdsc/data/datasource/GroupDataSourceImpl.kt b/data/src/main/java/org/gdsc/data/datasource/GroupDataSourceImpl.kt index 5ce7b982..c4cab792 100644 --- a/data/src/main/java/org/gdsc/data/datasource/GroupDataSourceImpl.kt +++ b/data/src/main/java/org/gdsc/data/datasource/GroupDataSourceImpl.kt @@ -1,7 +1,13 @@ package org.gdsc.data.datasource -import android.util.Log -import org.gdsc.data.database.GroupPaging +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import androidx.paging.cachedIn +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import org.gdsc.data.database.GroupBySearchPagingSource import org.gdsc.data.network.GroupAPI import org.gdsc.domain.model.GroupPreview import org.gdsc.domain.model.request.GroupSearchRequest @@ -10,7 +16,7 @@ import javax.inject.Inject class GroupDataSourceImpl @Inject constructor( private val groupAPI: GroupAPI, -): GroupDataSource { +) : GroupDataSource { override suspend fun getMyGroups(): List { runCatching { groupAPI.getMyGroups() @@ -36,4 +42,20 @@ class GroupDataSourceImpl @Inject constructor( override suspend fun searchGroup(keyword: String, limitCount: Int): List { return groupAPI.searchGroup(GroupSearchRequest(keyword)).data.groupList.take(limitCount) } + + override suspend fun searchPagingGroup( + keyword: String, + ): Flow> { + return Pager( + config = PagingConfig( + pageSize = 20, + enablePlaceholders = true + ) + ) { + GroupBySearchPagingSource( + groupAPI, + GroupSearchRequest(keyword)) + }.flow.cachedIn(CoroutineScope(Dispatchers.IO)) + + } } \ No newline at end of file diff --git a/data/src/main/java/org/gdsc/data/repository/GroupRepositoryImpl.kt b/data/src/main/java/org/gdsc/data/repository/GroupRepositoryImpl.kt index 6be11426..0ef2de30 100644 --- a/data/src/main/java/org/gdsc/data/repository/GroupRepositoryImpl.kt +++ b/data/src/main/java/org/gdsc/data/repository/GroupRepositoryImpl.kt @@ -1,5 +1,7 @@ package org.gdsc.data.repository +import androidx.paging.PagingData +import kotlinx.coroutines.flow.Flow import org.gdsc.data.datasource.GroupDataSource import org.gdsc.domain.model.GroupPreview import org.gdsc.domain.model.response.Group @@ -20,4 +22,8 @@ class GroupRepositoryImpl @Inject constructor( override suspend fun searchGroup(keyword: String, limitCount: Int): List { return groupDataSource.searchGroup(keyword, limitCount) } + + override suspend fun searchPagingGroup(keyword: String): Flow> { + return groupDataSource.searchPagingGroup(keyword) + } } \ No newline at end of file diff --git a/domain/src/main/java/org/gdsc/domain/repository/GroupRepository.kt b/domain/src/main/java/org/gdsc/domain/repository/GroupRepository.kt index b81a58c0..6d8f050a 100644 --- a/domain/src/main/java/org/gdsc/domain/repository/GroupRepository.kt +++ b/domain/src/main/java/org/gdsc/domain/repository/GroupRepository.kt @@ -1,5 +1,7 @@ package org.gdsc.domain.repository +import androidx.paging.PagingData +import kotlinx.coroutines.flow.Flow import org.gdsc.domain.model.GroupPreview import org.gdsc.domain.model.response.Group @@ -9,4 +11,6 @@ interface GroupRepository { suspend fun selectGroup(groupId: Int): String suspend fun searchGroup(keyword: String, limitCount: Int): List + + suspend fun searchPagingGroup(keyword: String): Flow> } \ No newline at end of file diff --git a/domain/src/main/java/org/gdsc/domain/usecase/GetGroupBySearchUseCase.kt b/domain/src/main/java/org/gdsc/domain/usecase/GetGroupBySearchUseCase.kt new file mode 100644 index 00000000..ad3a0c1e --- /dev/null +++ b/domain/src/main/java/org/gdsc/domain/usecase/GetGroupBySearchUseCase.kt @@ -0,0 +1,18 @@ +package org.gdsc.domain.usecase + +import androidx.paging.PagingData +import kotlinx.coroutines.flow.Flow +import org.gdsc.domain.model.GroupPreview +import org.gdsc.domain.repository.GroupRepository +import javax.inject.Inject + +class GetGroupBySearchUseCase @Inject constructor( + private val groupRepository: GroupRepository +) { + suspend operator fun invoke( + keyword: String, + ): Flow> { + + return groupRepository.searchPagingGroup(keyword) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchFragment.kt index 62358a27..01fdfda8 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchFragment.kt @@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController +import androidx.navigation.fragment.navArgs import com.google.android.material.chip.Chip import dagger.hilt.android.AndroidEntryPoint import org.gdsc.presentation.R @@ -30,6 +31,8 @@ class AllSearchFragment : Fragment() { private val viewModel: AllSearchViewModel by activityViewModels() + private val navArgs: AllSearchFragmentArgs by navArgs() + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -41,6 +44,9 @@ class AllSearchFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + // 그룹 전용인지 아닌지 판별하는 용도 + viewModel.isForGroupState(navArgs.isForGroup) + parent.changeToolbarTitle("검색") binding.searchBar.setSearchViewListener(searchListener) diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchViewModel.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchViewModel.kt index e18b1357..43982ffa 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchViewModel.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/AllSearchViewModel.kt @@ -16,6 +16,7 @@ import org.gdsc.domain.SortType import org.gdsc.domain.model.GroupPreview import org.gdsc.domain.model.Location import org.gdsc.domain.model.RegisteredRestaurant +import org.gdsc.domain.usecase.GetGroupBySearchUseCase import org.gdsc.domain.usecase.GetGroupBySearchWithLimitCountUseCase import org.gdsc.domain.usecase.GetRestaurantBySearchUseCase import org.gdsc.domain.usecase.GetRestaurantBySearchWithLimitCountUseCase @@ -35,7 +36,8 @@ class AllSearchViewModel @Inject constructor( private val deleteSearchedKeywordUseCase: DeleteSearchedKeywordUseCase, private val initSearchedKeywordUseCase: InitSearchedKeywordUseCase, private val getRestaurantBySearchWithLimitCountUseCase: GetRestaurantBySearchWithLimitCountUseCase, - private val getGroupBySearchWithLimitCountUseCase: GetGroupBySearchWithLimitCountUseCase + private val getGroupBySearchWithLimitCountUseCase: GetGroupBySearchWithLimitCountUseCase, + private val getGroupBySearchUseCase: GetGroupBySearchUseCase ) : ViewModel() { init { @@ -48,6 +50,10 @@ class AllSearchViewModel @Inject constructor( } } + private var _isForGroup = MutableStateFlow(false) + val isForGroup: StateFlow + get() = _isForGroup + private var _searchKeyword = MutableStateFlow("") val searchKeyword: StateFlow get() = _searchKeyword @@ -77,6 +83,12 @@ class AllSearchViewModel @Inject constructor( private var _searchedGroupPreviewState = MutableStateFlow>(emptyList()) + val searchedGroupState: StateFlow> + get() = _searchedGroupState + + private var _searchedGroupState = + MutableStateFlow>(PagingData.empty()) + val searchedGroupPreviewState: StateFlow> get() = _searchedGroupPreviewState @@ -85,6 +97,10 @@ class AllSearchViewModel @Inject constructor( val searchedKeywordsState: StateFlow> get() = _searchedKeywordsState + + fun isForGroupState(isForGroup: Boolean) { + _isForGroup.value = isForGroup + } fun setSearchKeyword(keyword: String) { _searchKeyword.value = keyword } @@ -158,6 +174,12 @@ class AllSearchViewModel @Inject constructor( val result = getGroupBySearchWithLimitCountUseCase(searchKeyword.value, 3) _searchedGroupPreviewState.value = result } + viewModelScope.launch { + getGroupBySearchUseCase(searchKeyword.value).distinctUntilChanged() + .collect { + _searchedGroupState.value = it + } + } } diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryAllFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryAllFragment.kt index caa958c7..cd0ba0f6 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryAllFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryAllFragment.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels +import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.viewbinding.ViewBinding @@ -31,12 +32,13 @@ import org.gdsc.presentation.view.allsearch.adapter.SearchCategoryRestaurantPrev @AndroidEntryPoint class SearchCategoryAllFragment( private val searchKeyword: String +) : Fragment() { ): Fragment(), ViewHolderBindListener { private var _binding: FragmentSearchCategoryAllBinding? = null private val binding get() = _binding!! - val viewModel: AllSearchViewModel by activityViewModels() + private val viewModel: AllSearchViewModel by activityViewModels() private val searchCategoryRestaurantPreviewAdapter = SearchCategoryRestaurantPreviewAdapter(this) private val searchCategoryGroupPreviewAdapter = SearchCategoryGroupPreviewAdapter(this) @@ -52,6 +54,31 @@ class SearchCategoryAllFragment( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + repeatWhenUiStarted { + viewModel.isForGroup.collect { isForGroup -> + if (isForGroup.not()) { + binding.restaurantRecyclerView.visibility = View.GONE + binding.warningNoRestaurant.root.visibility = View.VISIBLE + } else { + binding.restaurantRecyclerView.visibility = View.VISIBLE + binding.warningNoRestaurant.root.visibility = View.GONE + } + } + } + + repeatWhenUiStarted { + viewModel.searchedGroupPreviewState.collect { + if (it.isEmpty()) { + binding.groupRecyclerView.visibility = View.GONE + binding.warningNoGroup.root.visibility = View.VISIBLE + } else { + binding.groupRecyclerView.visibility = View.VISIBLE + binding.warningNoGroup.root.visibility = View.GONE + + } + } + } + viewModel.searchRestaurantPreviewWithKeyword() viewModel.searchGroupPreviewWithKeyword() @@ -63,7 +90,8 @@ class SearchCategoryAllFragment( // Todo: New Adapter With Real APi binding.recommendedRestaurantRecyclerView.adapter = searchCategoryRestaurantPreviewAdapter - binding.recommendedRestaurantRecyclerView.layoutManager = LinearLayoutManager(requireContext()) + binding.recommendedRestaurantRecyclerView.layoutManager = + LinearLayoutManager(requireContext()) binding.icRestaurant.setOnClickListener { val viewPager = requireActivity().findViewById(R.id.search_category_pager) @@ -73,6 +101,7 @@ class SearchCategoryAllFragment( viewModel.setSearchKeyword(searchKeyword) observeState() } + private fun observeState() { repeatWhenUiStarted { viewModel.searchedRestaurantPreviewState.collect { diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryGroupFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryGroupFragment.kt index 487d0ff7..5cc44206 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryGroupFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryGroupFragment.kt @@ -6,7 +6,11 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.LinearLayoutManager import org.gdsc.presentation.databinding.FragmentSearchCategoryGroupBinding +import org.gdsc.presentation.utils.repeatWhenUiStarted +import org.gdsc.presentation.view.allsearch.adapter.SearchCategoryGroupAdapter +import org.gdsc.presentation.view.allsearch.adapter.SearchCategoryGroupPreviewAdapter class SearchCategoryGroupFragment( private val searchKeyword: String @@ -27,5 +31,28 @@ class SearchCategoryGroupFragment( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + repeatWhenUiStarted { + viewModel.searchedGroupPreviewState.collect { + if (it.isEmpty()) { + binding.groupRecyclerView.visibility = View.GONE + binding.warningNoGroup.root.visibility = View.VISIBLE + } else { + binding.groupRecyclerView.visibility = View.VISIBLE + binding.warningNoGroup.root.visibility = View.GONE + + } + } + } + + val adapter = SearchCategoryGroupAdapter() + binding.groupRecyclerView.adapter = adapter + binding.groupRecyclerView.layoutManager = LinearLayoutManager(requireContext()) + + repeatWhenUiStarted { + viewModel.searchedGroupState.collect { + adapter.submitData(it) + } + } } } \ No newline at end of file diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryRestaurantFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryRestaurantFragment.kt index 25d55f90..f3e943a5 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryRestaurantFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/SearchCategoryRestaurantFragment.kt @@ -12,6 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.viewbinding.ViewBinding import com.bumptech.glide.Glide import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest import org.gdsc.domain.DrinkPossibility import org.gdsc.domain.FoodCategory @@ -46,6 +47,18 @@ class SearchCategoryRestaurantFragment( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + repeatWhenUiStarted { + viewModel.isForGroup.collect{ isForGroup -> + if (isForGroup.not()) { + binding.restaurantRecyclerView.visibility = View.GONE + binding.warningNoRestaurant.root.visibility = View.VISIBLE + } else { + binding.restaurantRecyclerView.visibility = View.VISIBLE + binding.warningNoRestaurant.root.visibility = View.GONE + } + } + } + observeState() setSpinners() diff --git a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/adapter/SearchCategoryGroupAdapter.kt b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/adapter/SearchCategoryGroupAdapter.kt index 9c835ce5..785270f8 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/allsearch/adapter/SearchCategoryGroupAdapter.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/allsearch/adapter/SearchCategoryGroupAdapter.kt @@ -6,7 +6,7 @@ import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide -import org.gdsc.domain.model.GroupInfo +import org.gdsc.domain.model.GroupPreview import org.gdsc.presentation.R import org.gdsc.presentation.base.BaseViewHolder import org.gdsc.presentation.base.ViewHolderBindListener @@ -19,12 +19,12 @@ class SearchCategoryGroupAdapter( DiffCallback ) { - companion object DiffCallback : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: GroupInfo, newItem: GroupInfo): Boolean { + companion object DiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: GroupPreview, newItem: GroupPreview): Boolean { return oldItem.groupId == newItem.groupId } - override fun areContentsTheSame(oldItem: GroupInfo, newItem: GroupInfo): Boolean { + override fun areContentsTheSame(oldItem: GroupPreview, newItem: GroupPreview): Boolean { return oldItem == newItem } } @@ -34,7 +34,21 @@ class SearchCategoryGroupAdapter( listener: ViewHolderBindListener, ) : BaseViewHolder( binding, listener - ) + ) { + fun bind(item: GroupPreview) { + binding.run { + Glide.with(itemView.context) + .load("https://picsum.photos/200") + .placeholder(R.drawable.base_profile_image) + .into(ivGroupImage) + + tvGroupName.text = item.groupName + tvIntroduction.text = item.groupIntroduce + tvMemberCount.text = item.memberCnt.toString() + tvRestaurantCount.text = item.restaurantCnt.toString() + } + } + } override fun onBindViewHolder( holder: SearchCategoryGroupViewHolder, diff --git a/presentation/src/main/java/org/gdsc/presentation/view/mypage/MyPageFragment.kt b/presentation/src/main/java/org/gdsc/presentation/view/mypage/MyPageFragment.kt index 9acd504f..e6ca3067 100644 --- a/presentation/src/main/java/org/gdsc/presentation/view/mypage/MyPageFragment.kt +++ b/presentation/src/main/java/org/gdsc/presentation/view/mypage/MyPageFragment.kt @@ -43,6 +43,9 @@ class MyPageFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) +// val navigation = MyPageFragmentDirections.actionMyPageFragmentToRestaurantDetailFragment() +// findNavController().navigate(navigation) + initUserInfo() setPager() setTabLayout() diff --git a/presentation/src/main/res/drawable/ic_jmt_new_logo_grey200.png b/presentation/src/main/res/drawable/ic_jmt_new_logo_grey200.png new file mode 100644 index 00000000..f6f0ff3a Binary files /dev/null and b/presentation/src/main/res/drawable/ic_jmt_new_logo_grey200.png differ diff --git a/presentation/src/main/res/layout/fragment_search_category_all.xml b/presentation/src/main/res/layout/fragment_search_category_all.xml index 99ac8c7d..b9776597 100644 --- a/presentation/src/main/res/layout/fragment_search_category_all.xml +++ b/presentation/src/main/res/layout/fragment_search_category_all.xml @@ -31,16 +31,30 @@ app:layout_constraintTop_toTopOf="@+id/title_restaurant" app:layout_constraintBottom_toBottomOf="@+id/title_restaurant"/> - - + android:layout_marginHorizontal="@dimen/default_spacing"> + + + + + + @@ -77,16 +91,27 @@ app:layout_constraintTop_toTopOf="@+id/title_group" app:layout_constraintBottom_toBottomOf="@+id/title_group"/> - - + app:layout_constraintEnd_toEndOf="parent"> + + + + + + android:layout_height="wrap_content" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> - + tools:layout_editor_absoluteX="0dp" /> + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/fragment_search_category_restaurant.xml b/presentation/src/main/res/layout/fragment_search_category_restaurant.xml index 24e3c9a7..9650ccd7 100644 --- a/presentation/src/main/res/layout/fragment_search_category_restaurant.xml +++ b/presentation/src/main/res/layout/fragment_search_category_restaurant.xml @@ -61,4 +61,13 @@ app:layout_constraintTop_toBottomOf="@+id/filter_lay" app:layout_constraintBottom_toBottomOf="parent" tools:layout_editor_absoluteX="0dp" /> + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/restaurant_is_only_for_people_in_group.xml b/presentation/src/main/res/layout/restaurant_is_only_for_people_in_group.xml new file mode 100644 index 00000000..42852b2f --- /dev/null +++ b/presentation/src/main/res/layout/restaurant_is_only_for_people_in_group.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/there_is_no_group.xml b/presentation/src/main/res/layout/there_is_no_group.xml new file mode 100644 index 00000000..f3da2aba --- /dev/null +++ b/presentation/src/main/res/layout/there_is_no_group.xml @@ -0,0 +1,29 @@ + + + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/navigation/main_nav_graph.xml b/presentation/src/main/res/navigation/main_nav_graph.xml index a7cd2269..95597260 100644 --- a/presentation/src/main/res/navigation/main_nav_graph.xml +++ b/presentation/src/main/res/navigation/main_nav_graph.xml @@ -31,6 +31,10 @@ +