diff --git a/app/src/main/java/com/runnect/runnect/binding/BaseVisitorFragment.kt b/app/src/main/java/com/runnect/runnect/binding/BaseVisitorFragment.kt index db1bdad5..620dd389 100644 --- a/app/src/main/java/com/runnect/runnect/binding/BaseVisitorFragment.kt +++ b/app/src/main/java/com/runnect/runnect/binding/BaseVisitorFragment.kt @@ -8,20 +8,23 @@ import androidx.annotation.LayoutRes import androidx.core.view.isVisible import androidx.databinding.ViewDataBinding import com.runnect.runnect.R -import com.runnect.runnect.presentation.MainActivity +import com.runnect.runnect.presentation.event.VisitorModeManager import com.runnect.runnect.presentation.login.LoginActivity +import javax.inject.Inject abstract class BaseVisitorFragment( @LayoutRes private val layoutRes: Int ) : BindingFragment(layoutRes) { - + @Inject + lateinit var visitorModeManager: VisitorModeManager + abstract val visitorContainer: View abstract val contentViews: List - + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - if (MainActivity.isVisitorMode) { + + if (visitorModeManager.isVisitorMode) { showVisitorMode() } else { showContent() diff --git a/app/src/main/java/com/runnect/runnect/presentation/MainActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/MainActivity.kt index 63aa4f3b..54c3c8b3 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/MainActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/MainActivity.kt @@ -12,17 +12,18 @@ import com.runnect.runnect.BuildConfig.REMOTE_KEY_APP_VERSION import com.runnect.runnect.R import com.runnect.runnect.binding.BindingActivity import com.runnect.runnect.databinding.ActivityMainBinding -import com.runnect.runnect.presentation.discover.DiscoverFragment -import com.runnect.runnect.presentation.storage.StorageScrapFragment +import com.runnect.runnect.presentation.event.VisitorModeManager import com.runnect.runnect.util.analytics.Analytics import com.runnect.runnect.util.analytics.EventName import com.runnect.runnect.util.analytics.EventName.EVENT_VIEW_HOME -import com.runnect.runnect.util.preference.AuthUtil.getAccessToken -import com.runnect.runnect.util.preference.StatusType.LoginStatus import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject @AndroidEntryPoint class MainActivity : BindingActivity(R.layout.activity_main) { + @Inject + lateinit var visitorModeManager: VisitorModeManager + private var isChangeToStorage: Boolean = false private var isChangeToDiscover: Boolean = false private var fragmentReplacementDirection: String? = null @@ -33,18 +34,11 @@ class MainActivity : BindingActivity(R.layout.activity_main Analytics.logClickedItemEvent(EVENT_VIEW_HOME) initRemoteConfig() - checkVisitorMode() checkIntentValue() initView() addListener() } - private fun checkVisitorMode() { - val accessToken = this.getAccessToken() - val loginStatus = LoginStatus.getLoginStatus(accessToken) - isVisitorMode = loginStatus == LoginStatus.VISITOR - } - private fun checkIntentValue() { fragmentReplacementDirection = intent.getStringExtra(EXTRA_FRAGMENT_REPLACEMENT_DIRECTION) @@ -102,12 +96,13 @@ class MainActivity : BindingActivity(R.layout.activity_main } private fun logClickEvent(menuItemId: Int) { + val isVisitor = visitorModeManager.isVisitorMode with(EventName) { when (menuItemId) { - R.id.menu_main_drawing -> if (isVisitorMode) EVENT_CLICK_JOIN_IN_COURSE_DRAWING else EVENT_CLICK_NAV_COURSE_DRAWING - R.id.menu_main_storage -> if (isVisitorMode) EVENT_CLICK_JOIN_IN_STORAGE else EVENT_CLICK_NAV_STORAGE - R.id.menu_main_discover -> if (isVisitorMode) EVENT_CLICK_JOIN_IN_COURSE_DISCOVERY else EVENT_CLICK_NAV_COURSE_DISCOVERY - R.id.menu_main_my_page -> if (isVisitorMode) EVENT_CLICK_JOIN_IN_MY_PAGE else EVENT_CLICK_NAV_MY_PAGE + R.id.menu_main_drawing -> if (isVisitor) EVENT_CLICK_JOIN_IN_COURSE_DRAWING else EVENT_CLICK_NAV_COURSE_DRAWING + R.id.menu_main_storage -> if (isVisitor) EVENT_CLICK_JOIN_IN_STORAGE else EVENT_CLICK_NAV_STORAGE + R.id.menu_main_discover -> if (isVisitor) EVENT_CLICK_JOIN_IN_COURSE_DISCOVERY else EVENT_CLICK_NAV_COURSE_DISCOVERY + R.id.menu_main_my_page -> if (isVisitor) EVENT_CLICK_JOIN_IN_MY_PAGE else EVENT_CLICK_NAV_MY_PAGE else -> "" }.let(Analytics::logClickedItemEvent) } @@ -169,17 +164,5 @@ class MainActivity : BindingActivity(R.layout.activity_main companion object { const val REMOTE_CONFIG_FETCH_INTERVAL_SECONDS = 3600L const val EXTRA_FRAGMENT_REPLACEMENT_DIRECTION = "fragmentReplacementDirection" - - var isVisitorMode = false - var discoverFragment: DiscoverFragment? = null - var storageScrapFragment: StorageScrapFragment? = null - - fun updateCourseDiscoverScreen() { - discoverFragment?.refreshDiscoverCourses() - } - - fun updateStorageScrapScreen() { - storageScrapFragment?.getMyScrapCourses() - } } } diff --git a/app/src/main/java/com/runnect/runnect/presentation/MainPager.kt b/app/src/main/java/com/runnect/runnect/presentation/MainPager.kt index 04fef669..4b6ad0f9 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/MainPager.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/MainPager.kt @@ -19,9 +19,7 @@ class MainPager(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragm when (position) { 0 -> CourseMainFragment() 1 -> StorageMainFragment() - 2 -> DiscoverFragment().apply { - MainActivity.discoverFragment = this - } + 2 -> DiscoverFragment() 3 -> MyPageFragment() else -> CourseMainFragment() diff --git a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt index 314a5600..cbf88c9a 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/detail/CourseDetailActivity.kt @@ -11,6 +11,7 @@ import android.widget.EditText import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import coil3.load import com.google.firebase.dynamiclinks.DynamicLink import com.google.firebase.dynamiclinks.FirebaseDynamicLinks @@ -23,6 +24,9 @@ import com.runnect.runnect.domain.entity.CourseDetail import com.runnect.runnect.domain.entity.EditableCourseDetail import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.countdown.CountDownActivity +import com.runnect.runnect.presentation.event.ScreenRefreshEvent +import com.runnect.runnect.presentation.event.ScreenRefreshEventBus +import com.runnect.runnect.presentation.event.VisitorModeManager import com.runnect.runnect.presentation.detail.CourseDetailRootScreen.COURSE_DISCOVER import com.runnect.runnect.presentation.detail.CourseDetailRootScreen.COURSE_DISCOVER_SEARCH import com.runnect.runnect.presentation.detail.CourseDetailRootScreen.COURSE_STORAGE_SCRAP @@ -56,12 +60,20 @@ import com.runnect.runnect.util.extension.showWebBrowser import com.runnect.runnect.util.mode.ScreenMode.EditMode import com.runnect.runnect.util.mode.ScreenMode.ReadOnlyMode import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import javax.inject.Inject @AndroidEntryPoint class CourseDetailActivity : BindingActivity(R.layout.activity_course_detail) { + @Inject + lateinit var visitorModeManager: VisitorModeManager + + @Inject + lateinit var screenRefreshEventBus: ScreenRefreshEventBus + private val viewModel: CourseDetailViewModel by viewModels() - private val isVisitorMode: Boolean = MainActivity.isVisitorMode + private val isVisitorMode: Boolean get() = visitorModeManager.isVisitorMode private var isFromDeepLink: Boolean = false // 인텐트 부가 데이터 @@ -385,7 +397,9 @@ class CourseDetailActivity : } when (rootScreen) { - COURSE_STORAGE_SCRAP -> MainActivity.updateStorageScrapScreen() + COURSE_STORAGE_SCRAP -> lifecycleScope.launch { + screenRefreshEventBus.emit(ScreenRefreshEvent.RefreshStorageScrap) + } COURSE_DISCOVER -> setActivityResult() COURSE_DISCOVER_SEARCH -> setActivityResult() MY_PAGE_UPLOAD_COURSE -> setActivityResult() diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverFragment.kt index ccfdf6ed..2315051f 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/DiscoverFragment.kt @@ -18,8 +18,10 @@ import com.runnect.runnect.binding.BindingFragment import com.runnect.runnect.databinding.FragmentDiscoverBinding import com.runnect.runnect.domain.entity.DiscoverBanner import com.runnect.runnect.presentation.MainActivity -import com.runnect.runnect.presentation.MainActivity.Companion.isVisitorMode import com.runnect.runnect.presentation.detail.CourseDetailActivity +import com.runnect.runnect.presentation.event.ScreenRefreshEvent +import com.runnect.runnect.presentation.event.ScreenRefreshEventBus +import com.runnect.runnect.presentation.event.VisitorModeManager import com.runnect.runnect.presentation.detail.CourseDetailRootScreen import com.runnect.runnect.presentation.discover.adapter.BannerAdapter import com.runnect.runnect.presentation.discover.adapter.multiview.DiscoverMultiViewAdapter @@ -28,7 +30,6 @@ import com.runnect.runnect.presentation.discover.model.EditableDiscoverCourse import com.runnect.runnect.presentation.discover.pick.DiscoverPickActivity import com.runnect.runnect.presentation.discover.search.DiscoverSearchActivity import com.runnect.runnect.presentation.state.UiStateV2 -import com.runnect.runnect.presentation.storage.StorageScrapFragment import com.runnect.runnect.util.analytics.Analytics import com.runnect.runnect.util.analytics.EventName.EVENT_CLICK_DATE import com.runnect.runnect.util.analytics.EventName.EVENT_CLICK_SCRAP @@ -46,9 +47,16 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch import timber.log.Timber +import javax.inject.Inject @AndroidEntryPoint class DiscoverFragment : BindingFragment(R.layout.fragment_discover) { + @Inject + lateinit var visitorModeManager: VisitorModeManager + + @Inject + lateinit var screenRefreshEventBus: ScreenRefreshEventBus + private val viewModel: DiscoverViewModel by viewModels() private lateinit var bannerAdapter: BannerAdapter @@ -57,7 +65,6 @@ class DiscoverFragment : BindingFragment(R.layout.fragm private var bannerItemCount = 0 private lateinit var multiViewAdapter: DiscoverMultiViewAdapter - private var isFromStorageScrap = StorageScrapFragment.isFromStorageScrap private val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> @@ -106,6 +113,7 @@ class DiscoverFragment : BindingFragment(R.layout.fragm handleVisitorMode = { context?.let { showCourseScrapWarningToast(it) } }, + isVisitorMode = { visitorModeManager.isVisitorMode }, onSortButtonClick = { criteria -> viewModel.sortRecommendCourses(criteria) Analytics.logClickedItemEvent(returnEventName(criteria)) @@ -277,7 +285,7 @@ class DiscoverFragment : BindingFragment(R.layout.fragm private fun navigateToCourseUploadScreen() { val context = context ?: return - if (isVisitorMode) { + if (visitorModeManager.isVisitorMode) { showCourseUploadWarningToast(context) return } @@ -300,6 +308,17 @@ class DiscoverFragment : BindingFragment(R.layout.fragm setupRecommendCourseNextPageStateObserver() setupRecommendCourseSortStateObserver() setupCourseScrapStateObserver() + collectScreenRefreshEvents() + } + + private fun collectScreenRefreshEvents() { + viewLifeCycleScope.launch { + screenRefreshEventBus.events.collect { event -> + if (event is ScreenRefreshEvent.RefreshDiscoverCourses) { + refreshDiscoverCourses() + } + } + } } private fun setupBannerGetStateObserver() { @@ -491,10 +510,7 @@ class DiscoverFragment : BindingFragment(R.layout.fragm } private fun checkFromStorageScrap() { - if (isFromStorageScrap) { - StorageScrapFragment.isFromStorageScrap = false - MainActivity.updateStorageScrapScreen() - } + // No longer needed — screen refresh is handled via ScreenRefreshEventBus } private fun registerRefreshLayoutScrollUpCallback() { @@ -509,18 +525,6 @@ class DiscoverFragment : BindingFragment(R.layout.fragm return layoutManager.findFirstCompletelyVisibleItemPosition() > 0 } - override fun onAttach(context: Context) { - super.onAttach(context) - if (context is MainActivity) { - MainActivity.discoverFragment = this - } - } - - override fun onDestroy() { - super.onDestroy() - MainActivity.discoverFragment = null - } - companion object { private const val BANNER_SCROLL_DELAY_TIME = 5000L private const val CENTER_POS_OF_INFINITE_BANNERS = Int.MAX_VALUE / 2 diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverMarathonAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverMarathonAdapter.kt index b0d4186b..0204f9fb 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverMarathonAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverMarathonAdapter.kt @@ -8,7 +8,6 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.runnect.runnect.databinding.ItemDiscoverMarathonBinding import com.runnect.runnect.domain.entity.DiscoverMultiViewItem -import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.discover.model.EditableDiscoverCourse import com.runnect.runnect.util.callback.diff.ItemDiffCallback @@ -16,6 +15,7 @@ class DiscoverMarathonAdapter( private val onHeartButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit, private val handleVisitorMode: () -> Unit, + private val isVisitorMode: () -> Boolean, ) : ListAdapter(diffUtil) { @@ -28,7 +28,8 @@ class DiscoverMarathonAdapter( ), onHeartButtonClick, onCourseItemClick, - handleVisitorMode + handleVisitorMode, + isVisitorMode ) } @@ -41,6 +42,7 @@ class DiscoverMarathonAdapter( private val onHeartButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit, private val handleVisitorMode: () -> Unit, + private val isVisitorMode: () -> Boolean, ) : RecyclerView.ViewHolder(binding.root) { fun bind(course: DiscoverMultiViewItem.MarathonCourse) { with(binding) { @@ -57,7 +59,7 @@ class DiscoverMarathonAdapter( course: DiscoverMultiViewItem.MarathonCourse ) { imageView.setOnClickListener { view -> - if (MainActivity.isVisitorMode) { + if (isVisitorMode()) { handleVisitorMode.invoke() return@setOnClickListener } diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverRecommendAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverRecommendAdapter.kt index 99f5f836..83463c29 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverRecommendAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/DiscoverRecommendAdapter.kt @@ -8,7 +8,6 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.runnect.runnect.databinding.ItemDiscoverRecommendBinding import com.runnect.runnect.domain.entity.DiscoverMultiViewItem -import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.discover.model.EditableDiscoverCourse import com.runnect.runnect.util.callback.diff.ItemDiffCallback import timber.log.Timber @@ -17,6 +16,7 @@ class DiscoverRecommendAdapter( private val onHeartButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit, private val handleVisitorMode: () -> Unit, + private val isVisitorMode: () -> Boolean, ) : ListAdapter(diffUtil) { @@ -29,7 +29,8 @@ class DiscoverRecommendAdapter( ), onHeartButtonClick, onCourseItemClick, - handleVisitorMode + handleVisitorMode, + isVisitorMode ) } @@ -41,7 +42,8 @@ class DiscoverRecommendAdapter( private val binding: ItemDiscoverRecommendBinding, private val onHeartButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit, - private val handleVisitorMode: () -> Unit + private val handleVisitorMode: () -> Unit, + private val isVisitorMode: () -> Boolean ) : RecyclerView.ViewHolder(binding.root) { fun bind(course: DiscoverMultiViewItem.RecommendCourse) { with(binding) { @@ -58,7 +60,7 @@ class DiscoverRecommendAdapter( course: DiscoverMultiViewItem.RecommendCourse ) { imageView.setOnClickListener { view -> - if (MainActivity.isVisitorMode) { + if (isVisitorMode()) { handleVisitorMode.invoke() return@setOnClickListener } diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewAdapter.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewAdapter.kt index d4e52e6f..b072087b 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewAdapter.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewAdapter.kt @@ -10,6 +10,7 @@ class DiscoverMultiViewAdapter( private val onHeartButtonClick: (Int, Boolean) -> Unit, private val onCourseItemClick: (Int) -> Unit, private val handleVisitorMode: () -> Unit, + private val isVisitorMode: () -> Boolean, private val onSortButtonClick: (String) -> Unit ) : RecyclerView.Adapter() { private val multiViewHolderFactory by lazy { DiscoverMultiViewHolderFactory() } @@ -24,6 +25,7 @@ class DiscoverMultiViewAdapter( onHeartButtonClick = onHeartButtonClick, onCourseItemClick = onCourseItemClick, handleVisitorMode = handleVisitorMode, + isVisitorMode = isVisitorMode, onSortButtonClick = onSortButtonClick ) } diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolder.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolder.kt index 5d480ce1..95712295 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolder.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolder.kt @@ -26,11 +26,12 @@ sealed class DiscoverMultiViewHolder(binding: ViewDataBinding) : private val binding: ItemDiscoverMultiviewMarathonBinding, onHeartButtonClick: (Int, Boolean) -> Unit, onCourseItemClick: (Int) -> Unit, - handleVisitorMode: () -> Unit + handleVisitorMode: () -> Unit, + isVisitorMode: () -> Boolean ) : DiscoverMultiViewHolder(binding) { val marathonAdapter by lazy { DiscoverMarathonAdapter( - onHeartButtonClick, onCourseItemClick, handleVisitorMode + onHeartButtonClick, onCourseItemClick, handleVisitorMode, isVisitorMode ) } @@ -69,13 +70,15 @@ sealed class DiscoverMultiViewHolder(binding: ViewDataBinding) : onHeartButtonClick: (Int, Boolean) -> Unit, onCourseItemClick: (Int) -> Unit, handleVisitorMode: () -> Unit, + isVisitorMode: () -> Boolean, private val onSortButtonClick: (String) -> Unit ) : DiscoverMultiViewHolder(binding) { val recommendAdapter by lazy { DiscoverRecommendAdapter( onHeartButtonClick, onCourseItemClick, - handleVisitorMode + handleVisitorMode, + isVisitorMode ) } diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolderFactory.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolderFactory.kt index 60fb681b..c4defbdb 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolderFactory.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/adapter/multiview/DiscoverMultiViewHolderFactory.kt @@ -16,6 +16,7 @@ class DiscoverMultiViewHolderFactory { onHeartButtonClick: (Int, Boolean) -> Unit, onCourseItemClick: (Int) -> Unit, handleVisitorMode: () -> Unit, + isVisitorMode: () -> Boolean, onSortButtonClick: (String) -> Unit ): DiscoverMultiViewHolder { when (viewType) { @@ -24,7 +25,8 @@ class DiscoverMultiViewHolderFactory { binding = parent.getViewDataBinding(layoutRes = R.layout.item_discover_multiview_marathon), onHeartButtonClick = onHeartButtonClick, onCourseItemClick = onCourseItemClick, - handleVisitorMode = handleVisitorMode + handleVisitorMode = handleVisitorMode, + isVisitorMode = isVisitorMode ) marathonCourseAdapter = viewHolder.marathonAdapter return viewHolder @@ -36,6 +38,7 @@ class DiscoverMultiViewHolderFactory { onHeartButtonClick = onHeartButtonClick, onCourseItemClick = onCourseItemClick, handleVisitorMode = handleVisitorMode, + isVisitorMode = isVisitorMode, onSortButtonClick = onSortButtonClick ) recommendCourseAdapter = viewHolder.recommendAdapter diff --git a/app/src/main/java/com/runnect/runnect/presentation/discover/upload/DiscoverUploadActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/discover/upload/DiscoverUploadActivity.kt index 7ac18237..6d01f379 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/discover/upload/DiscoverUploadActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/discover/upload/DiscoverUploadActivity.kt @@ -14,6 +14,8 @@ import com.runnect.runnect.databinding.ActivityDiscoverUploadBinding import com.runnect.runnect.domain.entity.DiscoverUploadCourse import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.discover.pick.DiscoverPickActivity +import com.runnect.runnect.presentation.event.ScreenRefreshEvent +import com.runnect.runnect.presentation.event.ScreenRefreshEventBus import com.runnect.runnect.presentation.state.UiState import com.runnect.runnect.util.analytics.Analytics import com.runnect.runnect.util.analytics.EventName.EVENT_CLICK_COURSE_UPLOAD @@ -23,11 +25,17 @@ import com.runnect.runnect.util.extension.getCompatibleParcelableExtra import com.runnect.runnect.util.extension.hideKeyboard import com.runnect.runnect.util.extension.showToast import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import androidx.lifecycle.lifecycleScope +import javax.inject.Inject import timber.log.Timber @AndroidEntryPoint class DiscoverUploadActivity : BindingActivity(R.layout.activity_discover_upload) { + @Inject + lateinit var screenRefreshEventBus: ScreenRefreshEventBus + private val viewModel: DiscoverUploadViewModel by viewModels() private val uploadCourse: DiscoverUploadCourse? by lazy { intent.getCompatibleParcelableExtra( @@ -108,12 +116,14 @@ class DiscoverUploadActivity : showToast("업로드 완료!") binding.indeterminateBar.isVisible = false + lifecycleScope.launch { + screenRefreshEventBus.emit(ScreenRefreshEvent.RefreshDiscoverCourses) + } + Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(this) } - - MainActivity.updateCourseDiscoverScreen() applyScreenExitAnimation() } diff --git a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt index b2a958d9..807b9222 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/draw/DrawActivity.kt @@ -44,6 +44,7 @@ import com.runnect.runnect.databinding.BottomsheetRequireCourseNameBinding import com.runnect.runnect.databinding.CustomDialogMakeCourseBinding import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.countdown.CountDownActivity +import com.runnect.runnect.presentation.event.VisitorModeManager import com.runnect.runnect.presentation.state.UiState import com.runnect.runnect.util.DepartureSetMode import com.runnect.runnect.util.analytics.Analytics @@ -55,6 +56,7 @@ import com.runnect.runnect.util.extension.setActivityDialog import com.runnect.runnect.util.extension.showToast import com.runnect.runnect.util.multipart.ContentUriRequestBody import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject import kotlinx.coroutines.delay import kotlinx.coroutines.launch import timber.log.Timber @@ -67,6 +69,9 @@ import java.math.RoundingMode @AndroidEntryPoint class DrawActivity : BindingActivity(R.layout.activity_draw), OnMapReadyCallback { + @Inject + lateinit var visitorModeManager: VisitorModeManager + private lateinit var locationSource: FusedLocationSource private lateinit var currentLocation: LatLng private lateinit var fusedLocation: FusedLocationProviderClient // 현재 위치 반환 객체 변수 @@ -95,7 +100,7 @@ class DrawActivity : BindingActivity(R.layout.activity_draw private var distanceSum: Float = 0.0f private var sumList = mutableListOf() private var isMarkerAvailable: Boolean = false - var isVisitorMode: Boolean = MainActivity.isVisitorMode + val isVisitorMode: Boolean get() = visitorModeManager.isVisitorMode var isFirstInit: Boolean = true diff --git a/app/src/main/java/com/runnect/runnect/presentation/event/ScreenRefreshEventBus.kt b/app/src/main/java/com/runnect/runnect/presentation/event/ScreenRefreshEventBus.kt new file mode 100644 index 00000000..64136421 --- /dev/null +++ b/app/src/main/java/com/runnect/runnect/presentation/event/ScreenRefreshEventBus.kt @@ -0,0 +1,22 @@ +package com.runnect.runnect.presentation.event + +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import javax.inject.Inject +import javax.inject.Singleton + +sealed interface ScreenRefreshEvent { + data object RefreshDiscoverCourses : ScreenRefreshEvent + data object RefreshStorageScrap : ScreenRefreshEvent +} + +@Singleton +class ScreenRefreshEventBus @Inject constructor() { + private val _events = MutableSharedFlow(replay = 1) + val events: SharedFlow = _events.asSharedFlow() + + suspend fun emit(event: ScreenRefreshEvent) { + _events.emit(event) + } +} diff --git a/app/src/main/java/com/runnect/runnect/presentation/event/VisitorModeManager.kt b/app/src/main/java/com/runnect/runnect/presentation/event/VisitorModeManager.kt new file mode 100644 index 00000000..ff9f3010 --- /dev/null +++ b/app/src/main/java/com/runnect/runnect/presentation/event/VisitorModeManager.kt @@ -0,0 +1,19 @@ +package com.runnect.runnect.presentation.event + +import android.content.Context +import com.runnect.runnect.util.preference.AuthUtil.getAccessToken +import com.runnect.runnect.util.preference.StatusType.LoginStatus +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class VisitorModeManager @Inject constructor( + @ApplicationContext private val context: Context +) { + val isVisitorMode: Boolean + get() { + val accessToken = context.getAccessToken() + return LoginStatus.getLoginStatus(accessToken) == LoginStatus.VISITOR + } +} diff --git a/app/src/main/java/com/runnect/runnect/presentation/storage/StorageScrapFragment.kt b/app/src/main/java/com/runnect/runnect/presentation/storage/StorageScrapFragment.kt index de7288cf..ae50ca65 100644 --- a/app/src/main/java/com/runnect/runnect/presentation/storage/StorageScrapFragment.kt +++ b/app/src/main/java/com/runnect/runnect/presentation/storage/StorageScrapFragment.kt @@ -1,12 +1,12 @@ package com.runnect.runnect.presentation.storage import android.content.ContentValues -import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View import androidx.core.view.isVisible import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import com.runnect.runnect.R import com.runnect.runnect.binding.BindingFragment @@ -14,6 +14,8 @@ import com.runnect.runnect.domain.entity.MyScrapCourse import com.runnect.runnect.databinding.FragmentStorageScrapBinding import com.runnect.runnect.presentation.MainActivity import com.runnect.runnect.presentation.detail.CourseDetailActivity +import com.runnect.runnect.presentation.event.ScreenRefreshEvent +import com.runnect.runnect.presentation.event.ScreenRefreshEventBus import com.runnect.runnect.presentation.detail.CourseDetailRootScreen import com.runnect.runnect.presentation.state.UiStateV2 import com.runnect.runnect.presentation.storage.adapter.StorageScrapAdapter @@ -23,7 +25,9 @@ import com.runnect.runnect.util.callback.listener.OnHeartButtonClick import com.runnect.runnect.util.callback.listener.OnScrapItemClick import com.runnect.runnect.util.extension.showSnackbar import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import timber.log.Timber +import javax.inject.Inject @AndroidEntryPoint class StorageScrapFragment : @@ -31,6 +35,9 @@ class StorageScrapFragment : OnHeartButtonClick, OnScrapItemClick, ItemCount { + @Inject + lateinit var screenRefreshEventBus: ScreenRefreshEventBus + val viewModel: StorageViewModel by viewModels() private lateinit var storageScrapAdapter: StorageScrapAdapter @@ -81,8 +88,6 @@ class StorageScrapFragment : private fun initGoToScrapButtonClickListener() { binding.btnStorageNoScrap.setOnClickListener { - isFromStorageScrap = true - val intent = Intent(activity, MainActivity::class.java).apply { putExtra(EXTRA_FRAGMENT_REPLACEMENT_DIRECTION, "fromMyScrap") } @@ -105,6 +110,17 @@ class StorageScrapFragment : setupItemSizeObserver() setupMyScrapCourseGetStateObserver() setupCourseScrapStateObserver() + collectScreenRefreshEvents() + } + + private fun collectScreenRefreshEvents() { + viewLifecycleOwner.lifecycleScope.launch { + screenRefreshEventBus.events.collect { event -> + if (event is ScreenRefreshEvent.RefreshStorageScrap) { + getMyScrapCourses() + } + } + } } private fun setupCourseScrapStateObserver() { @@ -205,20 +221,7 @@ class StorageScrapFragment : ) } - override fun onAttach(context: Context) { - super.onAttach(context) - if (context is MainActivity) { - MainActivity.storageScrapFragment = this - } - } - - override fun onDestroy() { - super.onDestroy() - MainActivity.storageScrapFragment = null - } - companion object { - var isFromStorageScrap = false const val EXTRA_FRAGMENT_REPLACEMENT_DIRECTION = "fragmentReplacementDirection" const val EXTRA_PUBLIC_COURSE_ID = "publicCourseId" const val EXTRA_ROOT_SCREEN = "rootScreen"