From 8c22a0d2f839bd158cbf06f7d4972342c63cb9e4 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 30 Mar 2024 16:40:05 +0700 Subject: [PATCH 01/74] Add inject method --- app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt b/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt index 5ac3daff..496b5ee9 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt @@ -28,6 +28,7 @@ import dev.arkbuilders.navigator.presentation.screen.settings.SettingsFragment import dev.arkbuilders.arkfilepicker.folders.FoldersRepo import dev.arkbuilders.navigator.analytics.AnalyticsModule import dev.arkbuilders.navigator.di.modules.DispatcherModule +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.GalleryUpliftFragment import javax.inject.Singleton @Singleton @@ -51,6 +52,8 @@ interface AppComponent { fun inject(resourcesFragment: ResourcesFragment) fun inject(galleryPresenter: GalleryPresenter) fun inject(galleryFragment: GalleryFragment) + fun inject(galleryFragment: GalleryUpliftFragment) + fun inject(settingsFragment: SettingsFragment) fun inject(resourcesGridPresenter: ResourcesGridPresenter) fun inject(editTagsDialogPresenter: EditTagsDialogPresenter) From 614146a93008bbea979d94d236f0a194a7215124 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 30 Mar 2024 16:40:14 +0700 Subject: [PATCH 02/74] Create fragment --- .../galleryuplift/GalleryUpliftFragment.kt | 538 ++++++++++++++++++ 1 file changed, 538 insertions(+) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt new file mode 100644 index 00000000..7ffca0aa --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -0,0 +1,538 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import android.annotation.SuppressLint +import android.content.ActivityNotFoundException +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.util.TypedValue +import android.view.View +import android.widget.Toast +import androidx.core.content.FileProvider +import androidx.core.os.bundleOf +import androidx.core.view.doOnNextLayout +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import androidx.fragment.app.setFragmentResult +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.SimpleItemAnimator +import androidx.viewpager2.widget.ViewPager2 +import by.kirich1409.viewbindingdelegate.viewBinding +import com.google.android.material.chip.Chip +import dev.arkbuilders.arkfilepicker.folders.RootAndFav +import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.arklib.user.tags.Tags +import dev.arkbuilders.arklib.utils.extension +import dev.arkbuilders.components.scorewidget.ScoreWidget +import dev.arkbuilders.navigator.BuildConfig +import dev.arkbuilders.navigator.R +import dev.arkbuilders.navigator.data.utils.LogTags +import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding +import dev.arkbuilders.navigator.databinding.PopupGalleryTagMenuBinding +import dev.arkbuilders.navigator.presentation.App +import dev.arkbuilders.navigator.presentation.dialog.DetailsAlertDialog +import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment +import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment +import dev.arkbuilders.navigator.presentation.navigation.Screens +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment +import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewsPager +import dev.arkbuilders.navigator.presentation.screen.main.MainActivity +import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper +import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader +import dev.arkbuilders.navigator.presentation.utils.makeGone +import dev.arkbuilders.navigator.presentation.utils.makeVisible +import dev.arkbuilders.navigator.presentation.view.DefaultPopup +import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer +import dev.arkbuilders.navigator.presentation.view.StackedToasts +import kotlinx.coroutines.launch +import timber.log.Timber +import java.nio.file.Path + + +class GalleryUpliftFragment : Fragment() { + private val binding by viewBinding(FragmentGalleryBinding::bind) + val viewModel: GalleryUpliftViewModel by viewModels() + private lateinit var stackedToasts: StackedToasts + private lateinit var pagerAdapter: PreviewsPager + private val scoreWidget by lazy { + ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") +// viewModel = GalleryUpliftViewModel() + super.onViewCreated(view, savedInstanceState) + App.instance.appComponent.inject(this) + } + + override fun onDestroyView() { + super.onDestroyView() + scoreWidget.onDestroyView() + } + + fun updatePagerAdapter() { + pagerAdapter.notifyDataSetChanged() + binding.viewPager.adapter?.itemCount?.let { count -> + val startAt = requireArguments().getInt(START_AT_KEY) + if (startAt < count) { + binding.viewPager.setCurrentItem( + startAt, + false + ) + } + } + } + + fun updatePagerAdapterWithDiff() { + viewModel.diffResult?.dispatchUpdatesTo(pagerAdapter) + } + + fun setupPreview( + pos: Int, + meta: Metadata + ) { + lifecycleScope.launch { + with(binding) { + setupOpenEditFABs(meta) + ExtraLoader.load( + meta, + listOf(primaryExtra, secondaryExtra), + verbose = true + ) + requireArguments().putInt(START_AT_KEY, pos) + } + } + } + + fun setPreviewsScrollingEnabled(enabled: Boolean) { + binding.viewPager.isUserInputEnabled = enabled + } + + fun setControlsVisibility(visible: Boolean) { + binding.previewControls.isVisible = visible + } + + fun editResource(resourcePath: Path) { + val intent = getExternalAppIntent( + resourcePath, + Intent.ACTION_EDIT, + false /* don't detach to get the result */ + ) + intent.apply { + putExtra("SAVE_FOLDER_PATH", resourcePath.parent.toString()) + putExtra("real_file_path_2", resourcePath.toString()) + } + try { + requireContext().startActivity(intent) + } catch (e: ActivityNotFoundException) { + Toast.makeText( + requireContext(), getString(R.string.no_app_found_to_open_this_file), + Toast.LENGTH_SHORT + ).show() + } + } + + + fun shareResource(resourcePath: Path) = + openIntentChooser( + resourcePath, + Intent.ACTION_SEND, + detachProcess = false + ) + + fun openLink(link: String) { + val intent = Intent(Intent.ACTION_VIEW) + val uri = Uri.parse(link) + intent.data = uri + startActivity(Intent.createChooser(intent, "View the link with:")) + } + + fun shareLink(link: String) { + val intent = Intent(Intent.ACTION_SEND) + intent.putExtra(Intent.EXTRA_TEXT, link) + intent.type = "text/plain" + startActivity(Intent.createChooser(intent, "Share the link with:")) + } + + fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { + DetailsAlertDialog(path, resource, metadata, requireContext()).show() + } + + fun viewInExternalApp(resourcePath: Path) { + openIntentChooser(resourcePath, Intent.ACTION_VIEW, true) + } + + fun deleteResource(pos: Int) { + binding.viewPager.apply { + setPageTransformer(null) + pagerAdapter.notifyItemRemoved(pos) + doOnNextLayout { + setPageTransformer(DepthPageTransformer()) + } + } + } + + fun displayStorageException(label: String, msg: String) { + StorageExceptionDialogFragment.newInstance(label, msg).show( + childFragmentManager, + StorageExceptionDialogFragment.TAG + ) + } + + fun notifyResourcesChanged() { + setFragmentResult(GalleryFragment.REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) + } + + fun notifyTagsChanged() { + setFragmentResult(GalleryFragment.REQUEST_TAGS_CHANGED_KEY, bundleOf()) + } + + fun notifyResourceScoresChanged() { + setFragmentResult(GalleryFragment.SCORES_CHANGED_KEY, bundleOf()) + } + + fun notifySelectedChanged( + selected: List + ) { + setFragmentResult( + GalleryFragment.SELECTED_CHANGED_KEY, + bundleOf().apply { + putBoolean( + GalleryFragment.SELECTING_ENABLED_KEY, + requireArguments().getBoolean(GalleryFragment.SELECTING_ENABLED_KEY) + ) + putParcelableArray( + GalleryFragment.SELECTED_RESOURCES_KEY, + selected.toTypedArray() + ) + } + ) + } + + fun toastIndexFailedPath(path: Path) { + stackedToasts.toast(path) + } + + + fun displayPreviewTags(resource: ResourceId, tags: Tags) { + lifecycleScope.launch { + Timber.d( + LogTags.GALLERY_SCREEN, + "displaying tags of resource $resource for preview" + ) + binding.tagsCg.removeAllViews() + + tags.forEach { tag -> + val chip = Chip(context) + chip.text = tag + + chip.setOnClickListener { + showTagMenuPopup(tag, chip) + } + binding.tagsCg.addView(chip) + } + + binding.tagsCg.addView(createEditChip()) + } + } + + fun showEditTagsDialog( + resource: ResourceId + ) { + Timber.d( + LogTags.GALLERY_SCREEN, + "showing [edit-tags] dialog for resource $resource" + ) + val dialog = EditTagsDialogFragment.newInstance( + requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, + listOf(resource), + viewModel.index, + viewModel.tagsStorage, + viewModel.statsStorage + ) + dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) + } + + + @SuppressLint("ClickableViewAccessibility") + fun setProgressVisibility(isVisible: Boolean, withText: String) { + binding.layoutProgress.apply { + root.isVisible = isVisible + + if (isVisible) { + root.setOnTouchListener { _, _ -> + return@setOnTouchListener true + } + } else { + root.setOnTouchListener(null) + } + + if (withText.isNotEmpty()) { + progressText.setVisibilityAndLoadingStatus(View.VISIBLE) + progressText.loadingText = withText + } else { + progressText.setVisibilityAndLoadingStatus(View.GONE) + } + } + } + + fun exitFullscreen() { + FullscreenHelper.setStatusBarVisibility(true, requireActivity().window) + (requireActivity() as MainActivity).setBottomNavigationVisibility(true) + } + + fun notifyCurrentItemChanged() { + binding.viewPager.post { + pagerAdapter.notifyItemChanged(binding.viewPager.currentItem) + } + } + + + fun displaySelected( + selected: Boolean, + showAnim: Boolean, + selectedCount: Int, + itemCount: Int + ) = with(binding) { + Timber.d("display ${System.currentTimeMillis()}") + cbSelected.isChecked = selected + if (!showAnim) + cbSelected.jumpDrawablesToCurrentState() + tvSelectedOf.text = "$selectedCount/$itemCount" + + return@with + } + + override fun onResume() { + super.onResume() + viewModel.onResume() + } + + fun toggleSelecting(enabled: Boolean) { + binding.layoutSelected.isVisible = enabled + binding.fabStartSelect.isVisible = !enabled + requireArguments().apply { + putBoolean(GalleryFragment.SELECTING_ENABLED_KEY, enabled) + } + if (enabled) { + viewModel.onSelectBtnClick() + } else { + binding.cbSelected.isChecked = false + } + } + + private fun setupOpenEditFABs(meta: Metadata?) = binding.apply { + openResourceFab.makeGone() + editResourceFab.makeGone() + when (meta) { + is Metadata.Video, is Metadata.Link, null -> { + // "open" capabilities only + openResourceFab.makeVisible() + } + + is Metadata.Document, is Metadata.PlainText -> { + // both "open" and "edit" capabilities + editResourceFab.makeVisible() + openResourceFab.makeVisible() + } + + is Metadata.Image -> { + // "edit" capabilities only + editResourceFab.makeVisible() + } + + else -> {} + } + } + + /** + * setFragmentResult notifies ResourcesFragment + * It is duplicated since the result can only be consumed once + */ + private fun initResultListener() { + childFragmentManager.setFragmentResultListener( + EditTagsDialogFragment.REQUEST_TAGS_CHANGED_KEY, + this + ) { _, _ -> + setFragmentResult(GalleryFragment.REQUEST_TAGS_CHANGED_KEY, bundleOf()) + viewModel.onTagsChanged() + } + + childFragmentManager.setFragmentResultListener( + StorageExceptionDialogFragment.STORAGE_CORRUPTION_DETECTED, + this + ) { _, _ -> + viewModel.router.newRootScreen(Screens.FoldersScreen()) + } + } + + private fun animatePagerAppearance() { + binding.viewPager.animate().apply { + duration = 500L + alpha(1f) + } + } + + + private fun initViewPager() = with(binding.viewPager) { + adapter = pagerAdapter + offscreenPageLimit = 2 + val rv = (getChildAt(0) as RecyclerView) + (rv.itemAnimator as SimpleItemAnimator).removeDuration = 0 + setPageTransformer(DepthPageTransformer()) + + registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + viewModel.onPageChanged(position) + } + }) + } + + private fun showTagMenuPopup(tag: Tag, tagView: View) { + val menuBinding = PopupGalleryTagMenuBinding + .inflate(requireActivity().layoutInflater) + val popup = DefaultPopup( + menuBinding, + R.style.BottomFadeScaleAnimation, + R.drawable.bg_rounded_16dp + ) + menuBinding.apply { + btnNewSelection.setOnClickListener { + viewModel.onTagSelected(tag) + popup.popupWindow.dismiss() + } + btnRemoveTag.setOnClickListener { + viewModel.onTagRemove(tag) + popup.popupWindow.dismiss() + } + } + popup.showAbove(tagView) + } + + private fun openIntentChooser( + resourcePath: Path, + actionType: String, + detachProcess: Boolean + ) { + Timber.i( + LogTags.GALLERY_SCREEN, + "Opening resource in an external application " + + "path: $resourcePath" + + "action: $actionType" + ) + + val intent = getExternalAppIntent(resourcePath, actionType, detachProcess) + val title = when (actionType) { + Intent.ACTION_VIEW -> "View the resource with:" + Intent.ACTION_EDIT -> "Edit the resource with:" + Intent.ACTION_SEND -> "Share the resource with:" + else -> "Open the resource with:" + } + startActivity(Intent.createChooser(intent, title)) + } + + + private fun getExternalAppIntent( + resourcePath: Path, + actionType: String, + detachProcess: Boolean + ): Intent { + val file = resourcePath.toFile() + val extension: String = extension(resourcePath) + val uri = FileProvider.getUriForFile( + requireContext(), + BuildConfig.APPLICATION_ID + ".provider", + file + ) + val intent = Intent().apply { + setDataAndType(uri, requireContext().contentResolver.getType(uri)) + action = actionType + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + when (actionType) { + Intent.ACTION_EDIT -> { + addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) + } + + Intent.ACTION_SEND -> { + putExtra(Intent.EXTRA_STREAM, uri) + } + } + if (detachProcess) { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + } + Timber.d( + LogTags.GALLERY_SCREEN, + "URI: ${intent.data}" + "MIME: ${intent.type}" + ) + return intent + } + + private fun getPXFromDP(dpValue: Float): Float { + return TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + dpValue, + resources.displayMetrics + ) + } + + private fun createEditChip(): Chip { + return Chip(context).also { + it.apply { + setChipIconResource(R.drawable.ic_baseline_edit_24) + chipBackgroundColor = + requireActivity().getColorStateList(R.color.colorPrimary) + chipStartPadding = getPXFromDP(12f) + chipEndPadding = getPXFromDP(12f) + textStartPadding = 0f + textEndPadding = 0f + + setOnClickListener { + val position = binding.viewPager.currentItem + Timber.d( + LogTags.GALLERY_SCREEN, + "[edit_tags] clicked at position $position" + ) + viewModel.onEditTagsDialogBtnClick() + } + } + } + } + + companion object { + private const val ROOT_AND_FAV_KEY = "rootAndFav" + private const val RESOURCES_KEY = "resources" + private const val START_AT_KEY = "startAt" + const val SELECTING_ENABLED_KEY = "selectingEnabled" + const val SELECTED_RESOURCES_KEY = "selectedResources" + const val REQUEST_TAGS_CHANGED_KEY = "tagsChangedGallery" + const val REQUEST_RESOURCES_CHANGED_KEY = "resourcesChangedGallery" + const val SCORES_CHANGED_KEY = "scoresChangedInGallery" + const val SELECTED_CHANGED_KEY = "selectedChanged" + + fun newInstance( + rootAndFav: RootAndFav, + resources: List, + startAt: Int, + selectingEnabled: Boolean = false, + selectedResources: List = emptyList(), + ) = GalleryFragment().apply { + arguments = Bundle().apply { + putParcelable(ROOT_AND_FAV_KEY, rootAndFav) + putParcelableArray(RESOURCES_KEY, resources.toTypedArray()) + putInt(START_AT_KEY, startAt) + putBoolean(SELECTING_ENABLED_KEY, selectingEnabled) + putParcelableArray( + SELECTED_RESOURCES_KEY, + selectedResources.toTypedArray() + ) + } + } + } + +} From afbd77b156439ce73f14f2dedbfd3188e7b2faba Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 30 Mar 2024 16:40:25 +0700 Subject: [PATCH 03/74] Add view model --- .../galleryuplift/GalleryUpliftViewModel.kt | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt new file mode 100644 index 00000000..8bf78a08 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -0,0 +1,79 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.recyclerview.widget.DiffUtil +import dev.arkbuilders.arklib.data.Message +import dev.arkbuilders.arklib.data.index.ResourceIndex +import dev.arkbuilders.arklib.data.index.ResourceIndexRepo +import dev.arkbuilders.arklib.data.meta.MetadataProcessor +import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo +import dev.arkbuilders.arklib.data.preview.PreviewProcessor +import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo +import dev.arkbuilders.arklib.user.score.ScoreStorage +import dev.arkbuilders.arklib.user.score.ScoreStorageRepo +import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.arklib.user.tags.TagsStorageRepo +import dev.arkbuilders.components.scorewidget.ScoreWidgetController +import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics +import dev.arkbuilders.navigator.data.preferences.Preferences +import dev.arkbuilders.navigator.data.stats.StatsStorage +import dev.arkbuilders.navigator.data.stats.StatsStorageRepo +import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase +import dev.arkbuilders.navigator.presentation.navigation.AppRouter +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import kotlinx.coroutines.flow.MutableSharedFlow +import moxy.presenterScope +import javax.inject.Inject + +class GalleryUpliftViewModel @Inject constructor( + val preferences: Preferences, + val router: AppRouter, + val indexRepo: ResourceIndexRepo, + val previewStorageRepo: PreviewProcessorRepo, + val metadataStorageRepo: MetadataProcessorRepo, + val tagsStorageRepo: TagsStorageRepo, + val statsStorageRepo: StatsStorageRepo, + val scoreStorageRepo: ScoreStorageRepo, + private val messageFlow: MutableSharedFlow = MutableSharedFlow(), + val handleGalleryExternalChangesUseCase: HandleGalleryExternalChangesUseCase, + val analytics: GalleryAnalytics +) : ViewModel() { + lateinit var index: ResourceIndex + private set + lateinit var tagsStorage: TagStorage + private set + private lateinit var previewStorage: PreviewProcessor + lateinit var metadataStorage: MetadataProcessor + private set + lateinit var statsStorage: StatsStorage + private set + private lateinit var scoreStorage: ScoreStorage + + var galleryItems: MutableList = mutableListOf() + + var diffResult: DiffUtil.DiffResult? = null + + private var currentPos = 0 + + private val currentItem: GalleryPresenter.GalleryItem + get() = galleryItems[currentPos] + + val scoreWidgetController = ScoreWidgetController( + scope = viewModelScope, + getCurrentId = { currentItem.id() }, + onScoreChanged = { +// viewState.notifyResourceScoresChanged() + } + ) + + + fun onSelectBtnClick() {} + fun onResume() {} + fun onTagsChanged() {} + fun onPageChanged(postion: Int) {} + fun onTagSelected(tag: Tag) {} + fun onTagRemove(tag: Tag) {} + fun onEditTagsDialogBtnClick() {} +} From 9db1c557c4648fb973f0517ddc93a3057f6e2903 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 30 Mar 2024 23:11:41 +0700 Subject: [PATCH 04/74] Extract flows --- .../galleryuplift/GalleryUpliftViewModel.kt | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 8bf78a08..0387923c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -3,9 +3,11 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil +import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message import dev.arkbuilders.arklib.data.index.ResourceIndex import dev.arkbuilders.arklib.data.index.ResourceIndexRepo +import dev.arkbuilders.arklib.data.meta.Metadata import dev.arkbuilders.arklib.data.meta.MetadataProcessor import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo import dev.arkbuilders.arklib.data.preview.PreviewProcessor @@ -20,11 +22,21 @@ import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.data.stats.StatsStorage import dev.arkbuilders.navigator.data.stats.StatsStorageRepo +import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import moxy.presenterScope +import timber.log.Timber +import java.io.FileReader +import java.nio.file.Path import javax.inject.Inject class GalleryUpliftViewModel @Inject constructor( @@ -56,6 +68,7 @@ class GalleryUpliftViewModel @Inject constructor( var diffResult: DiffUtil.DiffResult? = null private var currentPos = 0 + val selectedResources: MutableList = mutableListOf() private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] @@ -68,6 +81,141 @@ class GalleryUpliftViewModel @Inject constructor( } ) + private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) + val onNavigateBack: StateFlow = _onNavigateBack + + private val _deleteResource: MutableStateFlow = MutableStateFlow(false) + val deleteResource: StateFlow = _deleteResource + fun onRemoveFabClick() = viewModelScope.launch(NonCancellable) { + analytics.trackResRemove() + Timber.d( + LogTags.GALLERY_SCREEN, + "[remove_resource] clicked at position $currentPos" + ) + //TODO Trigger fragment.deleteResource +// deleteResource(currentItem.id()) + _deleteResource.emit(true) + galleryItems.removeAt(currentPos) + + if (galleryItems.isEmpty()) { + //TODO Trigger fragment.onBackClick() + _onNavigateBack.emit(true) +// onBackClick() + return@launch + } + + onTagsChanged() + _deleteResource.emit(true) +// viewState.deleteResource(currentPos) + + } + + + private val _showInfoAlert: MutableStateFlow = MutableStateFlow(false) + val showInfoAlert: StateFlow = _showInfoAlert + fun onInfoFabClick() = viewModelScope.launch { + analytics.trackResInfo() + Timber.d( + LogTags.GALLERY_SCREEN, + "[info_resource] clicked at position $currentPos" + ) + + val path = index.getPath(currentItem.id())!! + //TODO Trigger showInfoAlert + _showInfoAlert.emit(true) +// viewState.showInfoAlert(path, currentItem.resource, currentItem.metadata) + } + + + private val _shareLink: MutableStateFlow = MutableStateFlow(false) + val shareLink: StateFlow = _shareLink + + + private val _shareResource: MutableStateFlow = MutableStateFlow(false) + val shareResource: StateFlow = _shareResource + fun onShareFabClick() = viewModelScope.launch { + analytics.trackResShare() + Timber.d( + LogTags.GALLERY_SCREEN, + "[share_resource] clicked at position $currentPos" + ) + val path = index.getPath(currentItem.id())!! + + if (currentItem.metadata is Metadata.Link) { + val url = readText(path).getOrThrow() + //TODO Trigger sharelink +// viewState.shareLink(url) + _shareLink.emit(true) + return@launch + } + //TODO Trigger shareResource +// viewState.shareResource(path) + _shareResource.emit(true) + + } + + private var selectingEnabled: Boolean = false + + private val _toggleSelect: MutableStateFlow = MutableStateFlow(false) + val toggleSelect: StateFlow = _toggleSelect + fun onSelectingChanged() { + viewModelScope.launch { + selectingEnabled = !selectingEnabled + //TODO Trigger toggleSelecting + _toggleSelect.emit(selectingEnabled) +// viewState.toggleSelecting(selectingEnabled) + selectedResources.clear() + if (selectingEnabled) { + selectedResources.add(currentItem.resource.id) + } + } + } + + private val _openLink: MutableStateFlow = MutableStateFlow(false) + val openLink: StateFlow = _openLink + + + private val _viewInExternalApp: MutableStateFlow = MutableStateFlow(false) + val viewInExternalApp: StateFlow = _viewInExternalApp + fun onOpenFabClick() = viewModelScope.launch { + analytics.trackResOpen() + Timber.d( + LogTags.GALLERY_SCREEN, + "[open_resource] clicked at position $currentPos" + ) + + val id = currentItem.id() + val path = index.getPath(id)!! + + if (currentItem.metadata is Metadata.Link) { + val url = readText(path).getOrThrow() + //TODO Trigger openLink +// viewState.openLink(url) + _openLink.emit(true) + return@launch + } + + //TODO Trigger viewInExternalApp +// viewState.viewInExternalApp(path) + _viewInExternalApp.emit(true) + + } + + + private val _editResource: MutableStateFlow = MutableStateFlow(false) + val editResource: StateFlow = _editResource + fun onEditFabClick() = viewModelScope.launch { + analytics.trackResEdit() + Timber.d( + LogTags.GALLERY_SCREEN, + "[edit_resource] clicked at position $currentPos" + ) + val path = index.getPath(currentItem.id())!! + //TODO Trigger editResource +// viewState.editResource(path) + _editResource.emit(true) + } + fun onSelectBtnClick() {} fun onResume() {} @@ -76,4 +224,15 @@ class GalleryUpliftViewModel @Inject constructor( fun onTagSelected(tag: Tag) {} fun onTagRemove(tag: Tag) {} fun onEditTagsDialogBtnClick() {} + + + private suspend fun readText(source: Path): Result = + withContext(Dispatchers.IO) { + try { + val content = FileReader(source.toFile()).readText() + Result.success(content) + } catch (e: Exception) { + Result.failure(e) + } + } } From 21025723316385ec7fb7ef03faf92b117d5af61e Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 30 Mar 2024 23:11:51 +0700 Subject: [PATCH 05/74] Move logic down to viewmodel --- .../galleryuplift/GalleryUpliftFragment.kt | 96 ++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 7ffca0aa..851ab12f 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.util.TypedValue import android.view.View import android.widget.Toast +import androidx.activity.addCallback import androidx.core.content.FileProvider import androidx.core.os.bundleOf import androidx.core.view.doOnNextLayout @@ -15,7 +16,9 @@ import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SimpleItemAnimator import androidx.viewpager2.widget.ViewPager2 @@ -28,6 +31,7 @@ import dev.arkbuilders.arklib.data.meta.Metadata import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.utils.extension +import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R @@ -52,7 +56,7 @@ import dev.arkbuilders.navigator.presentation.view.StackedToasts import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path - +import kotlin.system.measureTimeMillis class GalleryUpliftFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) @@ -63,17 +67,105 @@ class GalleryUpliftFragment : Fragment() { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } + private fun onBackClick() { + Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") + notifySelectedChanged(viewModel.selectedResources) + exitFullscreen() + viewModel.router.exit() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") -// viewModel = GalleryUpliftViewModel() super.onViewCreated(view, savedInstanceState) App.instance.appComponent.inject(this) + + Timber.d( + LogTags.GALLERY_SCREEN, + "currentItem = ${binding.viewPager.currentItem}" + ) + collectState() + + animatePagerAppearance() + initResultListener() + stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope) + + FullscreenHelper.setStatusBarVisibility(false, requireActivity().window) + (requireActivity() as MainActivity).setBottomNavigationVisibility(false) + + requireActivity().onBackPressedDispatcher.addCallback(this) { + onBackClick() + } + + +// pagerAdapter = PreviewsPager(requireContext(), presenter) + + initViewPager() + scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) + + binding.apply { + val selectingEnabled = + requireArguments().getBoolean(GalleryFragment.SELECTING_ENABLED_KEY) + layoutSelected.isVisible = selectingEnabled + fabStartSelect.isVisible = !selectingEnabled + + removeResourceFab.setOnClickListener { + Toast.makeText( + requireContext(), + "Press and hold to delete", + Toast.LENGTH_SHORT + ).show() + } + + removeResourceFab.setOnLongClickListener { + val time = measureTimeMillis { + viewModel.onRemoveFabClick() + } + Timber.tag(LogTags.GALLERY_SCREEN).d("${time / 1000L}s") + true + } + + infoResourceFab.setOnClickListener { + viewModel.onInfoFabClick() + } + shareResourceFab.setOnClickListener { + viewModel.onShareFabClick() + } + fabStartSelect.setOnClickListener { + viewModel.onSelectingChanged() + } + + openResourceFab.setOnClickListener { + viewModel.onOpenFabClick() + } + + editResourceFab.setOnClickListener { + viewModel.onEditFabClick() + } + + layoutSelected.setOnClickListener { + viewModel.onSelectBtnClick() + } + + layoutSelected.setOnLongClickListener { + viewModel.onSelectingChanged() + return@setOnLongClickListener true + } + } } + override fun onDestroyView() { super.onDestroyView() scoreWidget.onDestroyView() } + private fun collectState() { + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + launch { + } + } + } + } fun updatePagerAdapter() { pagerAdapter.notifyDataSetChanged() From 10bd5927ed684d5cadb572817368885e25fe92a7 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 31 Mar 2024 09:48:03 +0700 Subject: [PATCH 06/74] Update proper data structure --- .../galleryuplift/GalleryUpliftViewModel.kt | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 0387923c..41761e2d 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message +import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.index.ResourceIndex import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata @@ -111,8 +112,15 @@ class GalleryUpliftViewModel @Inject constructor( } - private val _showInfoAlert: MutableStateFlow = MutableStateFlow(false) - val showInfoAlert: StateFlow = _showInfoAlert + private val _showInfoAlert: MutableStateFlow = MutableStateFlow(null) + val showInfoAlert: StateFlow = _showInfoAlert + + data class ShowInfoData( + val path: Path, + val resource: Resource, + val metadata: Metadata + ) + fun onInfoFabClick() = viewModelScope.launch { analytics.trackResInfo() Timber.d( @@ -122,17 +130,22 @@ class GalleryUpliftViewModel @Inject constructor( val path = index.getPath(currentItem.id())!! //TODO Trigger showInfoAlert - _showInfoAlert.emit(true) + val data = ShowInfoData( + path = path, + resource = currentItem.resource, + metadata = currentItem.metadata + ) + _showInfoAlert.emit(data) // viewState.showInfoAlert(path, currentItem.resource, currentItem.metadata) } - private val _shareLink: MutableStateFlow = MutableStateFlow(false) - val shareLink: StateFlow = _shareLink + private val _shareLink: MutableStateFlow = MutableStateFlow("") + val shareLink: StateFlow = _shareLink - private val _shareResource: MutableStateFlow = MutableStateFlow(false) - val shareResource: StateFlow = _shareResource + private val _shareResource: MutableStateFlow = MutableStateFlow(null) + val shareResource: StateFlow = _shareResource fun onShareFabClick() = viewModelScope.launch { analytics.trackResShare() Timber.d( @@ -145,13 +158,12 @@ class GalleryUpliftViewModel @Inject constructor( val url = readText(path).getOrThrow() //TODO Trigger sharelink // viewState.shareLink(url) - _shareLink.emit(true) + _shareLink.emit(url) return@launch } //TODO Trigger shareResource // viewState.shareResource(path) - _shareResource.emit(true) - + _shareResource.emit(path) } private var selectingEnabled: Boolean = false @@ -171,12 +183,13 @@ class GalleryUpliftViewModel @Inject constructor( } } - private val _openLink: MutableStateFlow = MutableStateFlow(false) - val openLink: StateFlow = _openLink + private val _openLink: MutableStateFlow = MutableStateFlow("") + val openLink: StateFlow = _openLink - private val _viewInExternalApp: MutableStateFlow = MutableStateFlow(false) - val viewInExternalApp: StateFlow = _viewInExternalApp + private val _viewInExternalApp: MutableStateFlow = + MutableStateFlow(null) + val viewInExternalApp: StateFlow = _viewInExternalApp fun onOpenFabClick() = viewModelScope.launch { analytics.trackResOpen() Timber.d( @@ -191,19 +204,19 @@ class GalleryUpliftViewModel @Inject constructor( val url = readText(path).getOrThrow() //TODO Trigger openLink // viewState.openLink(url) - _openLink.emit(true) + _openLink.emit(url) return@launch } //TODO Trigger viewInExternalApp // viewState.viewInExternalApp(path) - _viewInExternalApp.emit(true) + _viewInExternalApp.emit(path) } - private val _editResource: MutableStateFlow = MutableStateFlow(false) - val editResource: StateFlow = _editResource + private val _editResource: MutableStateFlow = MutableStateFlow(null) + val editResource: StateFlow = _editResource fun onEditFabClick() = viewModelScope.launch { analytics.trackResEdit() Timber.d( @@ -213,7 +226,7 @@ class GalleryUpliftViewModel @Inject constructor( val path = index.getPath(currentItem.id())!! //TODO Trigger editResource // viewState.editResource(path) - _editResource.emit(true) + _editResource.emit(path) } From dc8cf654550a42d3a3ea8a521585ad402dac02ad Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 31 Mar 2024 09:48:13 +0700 Subject: [PATCH 07/74] Observe data change --- .../galleryuplift/GalleryUpliftFragment.kt | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 851ab12f..d10f3b1c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -53,6 +53,7 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path @@ -158,10 +159,57 @@ class GalleryUpliftFragment : Fragment() { super.onDestroyView() scoreWidget.onDestroyView() } + private fun collectState() { viewLifecycleOwner.lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { launch { + viewModel.showInfoAlert.collect { data -> + data?.let { + showInfoAlert(it.path, it.resource, it.metadata) + } + } + } + launch { + viewModel.shareLink.collect { + shareLink(it) + } + } + launch { + viewModel.shareResource.collect { path -> + path?.let { + shareResource(path) + } + } + } + launch { + viewModel.toggleSelect.collect { + toggleSelecting(it) + } + } + launch { + viewModel.openLink.collect { + + } + } + launch { + viewModel.openLink.collect { + openLink(it) + } + } + launch { + viewModel.viewInExternalApp.collect { path -> + path?.let { + viewInExternalApp(it) + } + } + } + launch { + viewModel.editResource.collect { path -> + path?.let { + editResource(it) + } + } } } } From 516cd687dded0f8a8087adaaaf91ec49e0a35972 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 6 Apr 2024 23:33:54 +0700 Subject: [PATCH 08/74] Collect state ad update method call --- .../galleryuplift/GalleryUpliftFragment.kt | 12 ++ .../galleryuplift/GalleryUpliftViewModel.kt | 151 +++++++++++++++++- 2 files changed, 160 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index d10f3b1c..8c7fd59c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -211,6 +211,18 @@ class GalleryUpliftFragment : Fragment() { } } } + launch { + viewModel.notifyResourceChange.collect { + notifyResourcesChanged() + } + } + launch { + viewModel.notifyResourceChange.collect { + viewModel.showProgress.collect { + setProgressVisibility(it, "Changes detected, indexing") + } + } + } } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 41761e2d..d002012b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -17,6 +17,7 @@ import dev.arkbuilders.arklib.user.score.ScoreStorage import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.user.tags.TagsStorageRepo import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics @@ -27,6 +28,7 @@ import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.MutableSharedFlow @@ -34,11 +36,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moxy.presenterScope import timber.log.Timber import java.io.FileReader import java.nio.file.Path import javax.inject.Inject +import kotlin.io.path.getLastModifiedTime +import kotlin.io.path.notExists class GalleryUpliftViewModel @Inject constructor( val preferences: Preferences, @@ -111,8 +114,10 @@ class GalleryUpliftViewModel @Inject constructor( } + private val resourcesIds: List = listOf() - private val _showInfoAlert: MutableStateFlow = MutableStateFlow(null) + private val _showInfoAlert: MutableStateFlow = + MutableStateFlow(null) val showInfoAlert: StateFlow = _showInfoAlert data class ShowInfoData( @@ -233,11 +238,151 @@ class GalleryUpliftViewModel @Inject constructor( fun onSelectBtnClick() {} fun onResume() {} fun onTagsChanged() {} - fun onPageChanged(postion: Int) {} + fun onPageChanged(newPos: Int) = viewModelScope.launch { + if (galleryItems.isEmpty()) + return@launch + + checkResourceChanges(newPos) + + currentPos = newPos + + val id = currentItem.id() + val tags = tagsStorage.getTags(id) + displayPreview(id, currentItem.metadata, tags) + } + fun onTagSelected(tag: Tag) {} fun onTagRemove(tag: Tag) {} fun onEditTagsDialogBtnClick() {} + private fun displayPreview( + id: ResourceId, + meta: Metadata, + tags: Tags + ) { + // TODO Trigger setupPreview +// viewState.setupPreview(currentPos, meta) + + // TODO Trigger displayPreviewTags +// viewState.displayPreviewTags(id, tags) + scoreWidgetController.displayScore() + + // TODO Trigger displaySelected +// viewState.displaySelected( +// id in selectedResources, +// showAnim = false, +// selectedResources.size, +// galleryItems.size +// ) + } + private fun checkResourceChanges(pos: Int) = + viewModelScope.launch { + if (galleryItems.isEmpty()) { + return@launch + } + + val item = galleryItems[pos] + + val path = index.getPath(item.id()) + ?: let { + Timber.d("Resource ${item.id()} can't be found in the index") + invokeHandleGalleryExternalChangesUseCase() +// handleGalleryExternalChangesUseCase(this@GalleryPresenter) + return@launch + } + + if (path.notExists()) { + Timber.d("Resource ${item.id()} isn't stored by path $path") + invokeHandleGalleryExternalChangesUseCase() +// handleGalleryExternalChangesUseCase(this@GalleryPresenter) + return@launch + } + + if (path.getLastModifiedTime() != item.resource.modified) { + Timber.d("Index is not up-to-date regarding path $path") + invokeHandleGalleryExternalChangesUseCase() +// handleGalleryExternalChangesUseCase(this@GalleryPresenter) + return@launch + } + } + + fun provideGalleryItems(): List = + try { + val allResources = index.allResources() + resourcesIds + .filter { allResources.keys.contains(it) } + .map { id -> + val preview = previewStorage.retrieve(id).getOrThrow() + val metadata = metadataStorage.retrieve(id).getOrThrow() + val resource = allResources.getOrElse(id) { + throw NullPointerException("Resource not exist") + } + GalleryPresenter.GalleryItem(resource, preview, metadata) + }.toMutableList() + } catch (e: Exception) { + Timber.d("Can't provide gallery items") + emptyList() + } + + private val _notifyResourceChange: MutableStateFlow = + MutableStateFlow(false) + val notifyResourceChange: StateFlow = _notifyResourceChange + + private val _showProgress: MutableStateFlow = + MutableStateFlow(false) + val showProgress: StateFlow = _showProgress + private fun invokeHandleGalleryExternalChangesUseCase( + ) { + viewModelScope.launch { + withContext(Dispatchers.Main) { + // trigger show setProgressVisibility + _showProgress.value = true +// viewState.setProgressVisibility(true, "Changes detected, indexing") + } + + index.updateAll() + + withContext(Dispatchers.Main) { + _notifyResourceChange.value = true + // TODO Trigger notifyResourcesChanged +// viewState.notifyResourcesChanged() + } + + // TODO: Investigate more +// viewModelScope.launch { +// metadataStorage.busy.collect { busy -> if (!busy) cancel() +// } +// }.join() + + val newItems = provideGalleryItems() + if (newItems.isEmpty()) { + _onNavigateBack.value = true + return@launch + + } + + + diffResult = DiffUtil.calculateDiff( + ResourceDiffUtilCallback( + galleryItems.map { it.resource.id }, + newItems.map { it.resource.id } + ) + ) + + galleryItems = newItems.toMutableList() + + viewModelScope.launch { + // TODO trigger updatePagerAdapterWithDiff +// viewState.updatePagerAdapterWithDiff() + + // TODO trigger updatePagerAdapterWithDiff +// viewState.notifyCurrentItemChanged() + + // TODO trigger show setProgressVisibility +// viewState.setProgressVisibility(true, "Changes detected, indexing") } + } + } + } private suspend fun readText(source: Path): Result = withContext(Dispatchers.IO) { From 14294204d76286d22970c21c34d97074d2514094 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Tue, 9 Apr 2024 22:51:32 +0700 Subject: [PATCH 09/74] Create new view adapters version --- .../PreviewImageViewHolderUplift.kt | 156 ++++++++++++++++++ .../PreviewPlainTextViewHolderUplift.kt | 28 ++++ .../galleryuplift/PreviewsPagerUplift.kt | 81 +++++++++ 3 files changed, 265 insertions(+) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt new file mode 100644 index 00000000..d91452c4 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt @@ -0,0 +1,156 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import android.annotation.SuppressLint +import androidx.core.view.GestureDetectorCompat +import androidx.core.view.isVisible +import androidx.lifecycle.viewModelScope +import androidx.recyclerview.widget.RecyclerView +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.ortiz.touchview.OnTouchImageViewListener +import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.data.preview.PreviewLocator +import dev.arkbuilders.arklib.data.preview.PreviewStatus +import dev.arkbuilders.arklib.utils.ImageUtils +import dev.arkbuilders.navigator.databinding.ItemImageBinding +import dev.arkbuilders.navigator.presentation.utils.makeVisibleAndSetOnClickListener +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import timber.log.Timber + +@SuppressLint("ClickableViewAccessibility") +class PreviewImageViewHolderUplift( + private val binding: ItemImageBinding, + private val viewModel: GalleryUpliftViewModel, + private val gestureDetector: GestureDetectorCompat +) : RecyclerView.ViewHolder(binding.root) { + + private var joinPreviewJob: Job? = null + private var subsamplingImageLoadFailed = false + + init { + binding.ivSubsampling.setOnTouchListener { view, motionEvent -> + return@setOnTouchListener gestureDetector.onTouchEvent(motionEvent) + } + binding.ivZoom.setOnTouchListener { view, motionEvent -> + return@setOnTouchListener gestureDetector.onTouchEvent(motionEvent) + } + setZoomImageEventListener() + setSubsamplingEventListener() + } + + var pos = -1 + + suspend fun setSource( + placeholder: Int, + id: ResourceId, + meta: Metadata, + locator: PreviewLocator + ) = with(binding) { + joinPreviewJob?.cancel() + + if (meta is Metadata.Video) { + icPlay.makeVisibleAndSetOnClickListener { + viewModel.onPlayButtonClick() + } + } else { + icPlay.isVisible = false + } + + if (!locator.isGenerated()) { + progress.isVisible = true + Timber.d("join preview generation for $id") + joinPreviewJob = viewModel.viewModelScope.launch { + locator.join() + + if (!isActive) return@launch + + withContext(Dispatchers.Main) { + progress.isVisible = false + onPreviewReady(placeholder, id, meta, locator) + } + } + return@with + } + + onPreviewReady(placeholder, id, meta, locator) + } + + private fun onPreviewReady( + placeholder: Int, + id: ResourceId, + meta: Metadata, + locator: PreviewLocator + ) = with(binding) { + val status = locator.check() + if (status != PreviewStatus.FULLSCREEN) { + ivZoom.isZoomEnabled = false + ivZoom.setImageResource(placeholder) + return@with + } + + val path = locator.fullscreen() + + // Loading in parallel limited version of image with cache in ivZoom + // and full version in ivSubsampling + // User can wait up to several seconds for full version of heavy image + ImageUtils.loadImage(id, path, ivZoom, limitSize = true) + ImageUtils.loadSubsamplingImage(path, ivSubsampling) + } + + fun reset() = with(binding) { + progress.isVisible = false + ivZoom.isVisible = true + ivZoom.isZoomEnabled = true + subsamplingImageLoadFailed = false + } + + fun onRecycled() = with(binding) { + ivSubsampling.recycle() + } + + // If full version has not yet been loaded, then listen to the zoom, block it + // and show progress until it is fully loaded + private fun setZoomImageEventListener() = with(binding) { + ivZoom.setOnTouchImageViewListener(object : OnTouchImageViewListener { + override fun onMove() { + if (!subsamplingImageLoadFailed && ivZoom.isZoomed) { + progress.isVisible = true + ivZoom.isZoomEnabled = false + ivZoom.resetZoom() + } + } + }) + } + + private fun setSubsamplingEventListener() = with(binding) { + ivSubsampling.setOnImageEventListener( + object : SubsamplingScaleImageView.OnImageEventListener { + override fun onReady() { + ivZoom.isVisible = false + progress.isVisible = false + ivZoom.setImageDrawable(null) + } + + // Fallback to ivZoom + // Now this should only happen for .gif and .svg files + // Subsampling image can't handle them + override fun onImageLoadError(e: Exception?) { + subsamplingImageLoadFailed = true + progress.isVisible = false + ivZoom.isZoomEnabled = true + } + + override fun onPreviewLoadError(e: Exception?) {} + + override fun onImageLoaded() {} + + override fun onTileLoadError(e: Exception?) {} + + override fun onPreviewReleased() {} + }) + } +} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt new file mode 100644 index 00000000..995996ec --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt @@ -0,0 +1,28 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import android.annotation.SuppressLint +import androidx.core.view.GestureDetectorCompat +import androidx.recyclerview.widget.RecyclerView +import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding + +@SuppressLint("ClickableViewAccessibility") +class PreviewPlainTextViewHolderUplift( + private val binding: ItemPreviewPlainTextBinding, + private val detector: GestureDetectorCompat +) : RecyclerView.ViewHolder(binding.root) { + var pos = -1 + + init { + binding.tvContent.setOnTouchListener { view, event -> + return@setOnTouchListener detector.onTouchEvent(event) + } + } + + fun setContent(text: String) = with(binding) { + tvContent.text = text + } + + fun reset() = with(binding) { + tvContent.text = "" + } +} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt new file mode 100644 index 00000000..cbbbdec5 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt @@ -0,0 +1,81 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import android.annotation.SuppressLint +import android.content.Context +import android.view.GestureDetector +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.ViewGroup +import androidx.core.view.GestureDetectorCompat +import androidx.recyclerview.widget.RecyclerView +import dev.arkbuilders.arklib.data.meta.Kind +import dev.arkbuilders.navigator.databinding.ItemImageBinding +import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding +import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewPlainTextViewHolder + +class PreviewsPagerUplift( + val context: Context, + val viewModel: GalleryUpliftViewModel, +) : RecyclerView.Adapter() { + + override fun getItemCount() = viewModel.galleryItems.size + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + if (viewType == Kind.PLAINTEXT.ordinal) { + PreviewPlainTextViewHolder( + ItemPreviewPlainTextBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ), + getGestureDetector() + ) + } else { + PreviewImageViewHolderUplift( + ItemImageBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ), + viewModel, + getGestureDetector() + ) + } + + override fun getItemViewType(position: Int) = + viewModel.getKind(position) + + @SuppressLint("ClickableViewAccessibility") + override fun onBindViewHolder( + holder: RecyclerView.ViewHolder, + position: Int + ) { + when (holder) { + is PreviewPlainTextViewHolderUplift -> { + holder.pos = position + viewModel.bindPlainTextView(holder) + } + + is PreviewImageViewHolderUplift -> { + holder.pos = position + viewModel.bindView(holder) + } + } + } + + override fun onViewRecycled(holder: RecyclerView.ViewHolder) { + super.onViewRecycled(holder) + if (holder is PreviewImageViewHolderUplift) + holder.onRecycled() + } + + private fun getGestureDetector(): GestureDetectorCompat { + val listener = object : GestureDetector.SimpleOnGestureListener() { + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + viewModel.onPreviewsItemClick() + return true + } + } + return GestureDetectorCompat(context, listener) + } +} From 589b65853cc6aa9c4a342e4ce1c07e95bd0dc612 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Tue, 9 Apr 2024 22:51:45 +0700 Subject: [PATCH 10/74] Extract states, collect them in view --- .../galleryuplift/GalleryUpliftFragment.kt | 89 +++++- .../galleryuplift/GalleryUpliftViewModel.kt | 278 +++++++++++++++++- 2 files changed, 351 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 8c7fd59c..c33cf6ca 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -63,7 +63,7 @@ class GalleryUpliftFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) val viewModel: GalleryUpliftViewModel by viewModels() private lateinit var stackedToasts: StackedToasts - private lateinit var pagerAdapter: PreviewsPager + private lateinit var pagerAdapter: PreviewsPagerUplift private val scoreWidget by lazy { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } @@ -79,13 +79,13 @@ class GalleryUpliftFragment : Fragment() { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") super.onViewCreated(view, savedInstanceState) App.instance.appComponent.inject(this) + viewModel.onFirstViewAttach() Timber.d( LogTags.GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}" ) collectState() - animatePagerAppearance() initResultListener() stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope) @@ -98,7 +98,7 @@ class GalleryUpliftFragment : Fragment() { } -// pagerAdapter = PreviewsPager(requireContext(), presenter) + pagerAdapter = PreviewsPagerUplift(requireContext(), viewModel) initViewPager() scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) @@ -223,6 +223,83 @@ class GalleryUpliftFragment : Fragment() { } } } + launch { + viewModel.displayPreviewTags.collect { + if (it != null) { + displayPreviewTags(it.resourceId, it.tags) + } + } + } + launch { + viewModel.notifyCurrentItemChange.collect { + notifyCurrentItemChanged() + } + } + launch { + viewModel.updatePagerAdapterWithDiff.collect { + updatePagerAdapterWithDiff() + } + } + launch { + viewModel.displaySelected.collect { + it?.let { + displaySelected( + it.selected, + it.showAnim, + selectedCount = it.selectedCount, + itemCount = viewModel.galleryItems.size + ) + } + } + } + launch { + viewModel.toastIndexFailedPath.collect { + it?.let { + toastIndexFailedPath(it) + } + } + } + launch { + viewModel.notifyResourceScoresChanged.collect { + notifyResourceScoresChanged() + } + } + launch { + viewModel.updatePagerAdapter.collect { + updatePagerAdapter() + } + } + launch { + viewModel.setControlsVisibility.collect { + setControlsVisibility(it) + } + } + launch { + viewModel.onNavigateBack.collect { + onBackClick() + } + } + launch { + viewModel.deleteResource.collect { + it?.let { + deleteResource(it) + } + } + } + launch { + viewModel.setUpPreview.collect { + it?.let { + setupPreview(it.position, it.meta) + } + } + } + launch { + viewModel.showEditTagsDialog.collect { + it?.let { + showEditTagsDialog(it) + } + } + } } } } @@ -261,9 +338,9 @@ class GalleryUpliftFragment : Fragment() { } } - fun setPreviewsScrollingEnabled(enabled: Boolean) { - binding.viewPager.isUserInputEnabled = enabled - } +// fun setPreviewsScrollingEnabled(enabled: Boolean) { +// binding.viewPager.isUserInputEnabled = enabled +// } fun setControlsVisibility(visible: Boolean) { binding.previewControls.isVisible = visible diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index d002012b..732abef7 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -3,6 +3,7 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil +import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message import dev.arkbuilders.arklib.data.index.Resource @@ -13,20 +14,26 @@ import dev.arkbuilders.arklib.data.meta.MetadataProcessor import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo import dev.arkbuilders.arklib.data.preview.PreviewProcessor import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo +import dev.arkbuilders.arklib.data.stats.StatsEvent +import dev.arkbuilders.arklib.data.storage.StorageException import dev.arkbuilders.arklib.user.score.ScoreStorage import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.TagStorage import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.user.tags.TagsStorageRepo +import dev.arkbuilders.arklib.utils.ImageUtils +import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics +import dev.arkbuilders.navigator.data.preferences.PreferenceKey import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.data.stats.StatsStorage import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase import dev.arkbuilders.navigator.presentation.navigation.AppRouter +import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers @@ -34,10 +41,13 @@ import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber import java.io.FileReader +import java.nio.file.Files import java.nio.file.Path import javax.inject.Inject import kotlin.io.path.getLastModifiedTime @@ -54,7 +64,12 @@ class GalleryUpliftViewModel @Inject constructor( val scoreStorageRepo: ScoreStorageRepo, private val messageFlow: MutableSharedFlow = MutableSharedFlow(), val handleGalleryExternalChangesUseCase: HandleGalleryExternalChangesUseCase, - val analytics: GalleryAnalytics + private val resourcesIndexRepo: ResourceIndexRepo, + private val metadataProcessorRepo: MetadataProcessorRepo, + private val previewProcessorRepo: PreviewProcessorRepo, + val analytics: GalleryAnalytics, + private val rootAndFav: RootAndFav, + val folders: RootAndFav, ) : ViewModel() { lateinit var index: ResourceIndex private set @@ -74,22 +89,71 @@ class GalleryUpliftViewModel @Inject constructor( private var currentPos = 0 val selectedResources: MutableList = mutableListOf() + private lateinit var previewProcessor: PreviewProcessor + + private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] + private val _notifyResourceScoresChanged: MutableStateFlow = + MutableStateFlow(false) + val notifyResourceScoresChanged: StateFlow = + _notifyResourceScoresChanged + + fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) = + viewModelScope.launch { + view.reset() + val item = galleryItems[view.pos] + + val path = index.getPath(item.id())!! + val content = readText(path) + + content.onSuccess { + view.setContent(it) + } + } + + private var isControlsVisible = false + + private val _setControlsVisibility: MutableStateFlow = + MutableStateFlow(false) + val setControlsVisibility: StateFlow = + _setControlsVisibility + + fun onPreviewsItemClick() { + isControlsVisible = !isControlsVisible + // TODO Trigger setControlsVisibility + _setControlsVisibility.value = isControlsVisible +// viewState.setControlsVisibility(isControlsVisible) + } + + fun bindView(view: PreviewImageViewHolderUplift) = viewModelScope.launch { + view.reset() + val item = galleryItems[view.pos] + + val path = index.getPath(item.id())!! + val placeholder = ImageUtils.iconForExtension(extension(path)) + view.setSource(placeholder, item.id(), item.metadata, item.preview) + } + val scoreWidgetController = ScoreWidgetController( scope = viewModelScope, getCurrentId = { currentItem.id() }, onScoreChanged = { + _notifyResourceScoresChanged.value = true + // TODO Trigger notifyResourceScoresChanged // viewState.notifyResourceScoresChanged() } ) + fun getKind(pos: Int): Int = + galleryItems[pos].metadata.kind.ordinal + private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) val onNavigateBack: StateFlow = _onNavigateBack - private val _deleteResource: MutableStateFlow = MutableStateFlow(false) - val deleteResource: StateFlow = _deleteResource + private val _deleteResource: MutableStateFlow = MutableStateFlow(null) + val deleteResource: StateFlow = _deleteResource fun onRemoveFabClick() = viewModelScope.launch(NonCancellable) { analytics.trackResRemove() Timber.d( @@ -98,7 +162,7 @@ class GalleryUpliftViewModel @Inject constructor( ) //TODO Trigger fragment.deleteResource // deleteResource(currentItem.id()) - _deleteResource.emit(true) + deleteResource(currentItem.id()) galleryItems.removeAt(currentPos) if (galleryItems.isEmpty()) { @@ -109,17 +173,125 @@ class GalleryUpliftViewModel @Inject constructor( } onTagsChanged() - _deleteResource.emit(true) + _deleteResource.value = currentPos // viewState.deleteResource(currentPos) } + private suspend fun deleteResource(resource: ResourceId) { + Timber.d(LogTags.GALLERY_SCREEN, "deleting resource $resource") + + val path = index.getPath(resource) + + withContext(Dispatchers.IO) { + Files.delete(path) + } + + index.updateAll() + _notifyResourceChange.value = true + // TODO Trigger notifyResourcesChanged +// viewState.notifyResourcesChanged() + } + + private var sortByScores = false + + private val _toastIndexFailedPath: MutableStateFlow = + MutableStateFlow(null) + val toastIndexFailedPath: StateFlow = _toastIndexFailedPath + private val resourcesIds: List = listOf() private val _showInfoAlert: MutableStateFlow = MutableStateFlow(null) val showInfoAlert: StateFlow = _showInfoAlert + private val _init: MutableStateFlow = MutableStateFlow(false) + val init: StateFlow = _init + + private val _displayStorageException: MutableStateFlow = + MutableStateFlow(null) + val displayStorageException: StateFlow = + _displayStorageException + + private val _updatePagerAdapter: MutableStateFlow = + MutableStateFlow(false) + val updatePagerAdapter: StateFlow = _updatePagerAdapter + fun onFirstViewAttach() { + analytics.trackScreen() + Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") + viewModelScope.launch { + //TODO Trigger init + _init.value = true +// viewState.init() + _showProgress.value = true + //TODO Trigger setProgressVisibility +// viewState.setProgressVisibility(true, "Providing root index") + + index = indexRepo.provide(rootAndFav) + messageFlow.onEach { message -> + when (message) { + is Message.KindDetectFailed -> + _toastIndexFailedPath.value = message.path + //TODO Trigger toastIndexFailedPath +// viewState.toastIndexFailedPath(message.path) + } + }.launchIn(viewModelScope) + + //TODO Trigger setProgressVisibility + _showProgress.value = true +// viewState.setProgressVisibility(true, "Providing metadata storage") + metadataStorage = metadataStorageRepo.provide(index) + + //TODO Trigger setProgressVisibility + _showProgress.value = true +// viewState.setProgressVisibility(true, "Providing previews storage") + previewStorage = previewStorageRepo.provide(index) + + //TODO Trigger setProgressVisibility + _showProgress.value = true +// viewState.setProgressVisibility(true, "Proviging data storages") + + try { + tagsStorage = tagsStorageRepo.provide(index) + scoreStorage = scoreStorageRepo.provide(index) + } catch (e: StorageException) { + _displayStorageException.value = StorageExceptionGallery( + label = e.label, + messenger = e.msg + ) + // TODO Trigger displayStorageException +// viewState.displayStorageException( +// e.label, +// e.msg +// + } + + statsStorage = statsStorageRepo.provide(index) + scoreWidgetController.init(scoreStorage) + + galleryItems = provideGalleryItems().toMutableList() + + sortByScores = preferences.get(PreferenceKey.SortByScores) + + // TODO Trigger updatePagerAdapter +// viewState.updatePagerAdapter() + _updatePagerAdapter.value = true + + // TODO Trigger setProgressVisibility + _showProgress.value = false +// viewState.setProgressVisibility(false) + scoreWidgetController.setVisible(sortByScores) + } + } + + fun onPlayButtonClick() = viewModelScope.launch { + // TODO Trigger viewInExternalApp + _viewInExternalApp.value = index.getPath(currentItem.id())!! +// viewState.viewInExternalApp(index.getPath(currentItem.id())!!) + } + + data class StorageExceptionGallery(val label: String, val messenger: String) + data class ShowInfoData( val path: Path, val resource: Resource, @@ -251,22 +423,88 @@ class GalleryUpliftViewModel @Inject constructor( displayPreview(id, currentItem.metadata, tags) } - fun onTagSelected(tag: Tag) {} - fun onTagRemove(tag: Tag) {} - fun onEditTagsDialogBtnClick() {} + fun onTagSelected(tag: Tag) { + analytics.trackTagSelect() + router.navigateTo( + Screens.ResourcesScreenWithSelectedTag( + rootAndFav, tag + ) + ) + } + + private val _displayPreviewTags: MutableStateFlow = + MutableStateFlow(null) + val displayPreviewTags: StateFlow = _displayPreviewTags + + private val _notifyTagsChanged: MutableStateFlow = + MutableStateFlow(false) + val notifyTagsChanged: StateFlow = _notifyTagsChanged + + fun onTagRemove(tag: Tag) = viewModelScope.launch(NonCancellable) { + analytics.trackTagRemove() + val id = currentItem.id() + + val tags = tagsStorage.getTags(id) + val newTags = tags - tag + + // TODO Trigger displaypreviewtags + _displayPreviewTags.value = + ResourceIdTagsPreview(resourceId = id, tags = newTags) +// viewState.displayPreviewTags(id, newTags) + statsStorage.handleEvent( + StatsEvent.TagsChanged( + id, tags, newTags + ) + ) + Timber.d(LogTags.GALLERY_SCREEN, "setting new tags $newTags to $currentItem") + + tagsStorage.setTags(id, newTags) + tagsStorage.persist() + _notifyTagsChanged.value = true + // TODO Trigger notifyTagsChanged +// viewState.notifyTagsChanged() + } + + private val _showEditTagsDialog: MutableStateFlow = + MutableStateFlow(null) + val showEditTagsDialog: StateFlow = _showEditTagsDialog + fun onEditTagsDialogBtnClick() { + analytics.trackTagsEdit() + // TODO _showEditTagsDialog + _showEditTagsDialog.value = currentItem.id() +// viewState.showEditTagsDialog(currentItem.id()) + } + + + private val _setUpPreview: MutableStateFlow = + MutableStateFlow(null) + val setUpPreview: StateFlow = _setUpPreview + + private val _displaySelected: MutableStateFlow = + MutableStateFlow(null) + val displaySelected: StateFlow = _displaySelected private fun displayPreview( id: ResourceId, meta: Metadata, tags: Tags ) { + _setUpPreview.value = SetupPreview(position = currentPos, meta = meta) // TODO Trigger setupPreview // viewState.setupPreview(currentPos, meta) + _displayPreviewTags.value = + ResourceIdTagsPreview(resourceId = id, tags = tags) // TODO Trigger displayPreviewTags // viewState.displayPreviewTags(id, tags) scoreWidgetController.displayScore() + _displaySelected.value = DisplaySelected( + selected = id in selectedResources, + showAnim = false, + selectedCount = selectedResources.size, + itemCount = galleryItems.size + ) // TODO Trigger displaySelected // viewState.displaySelected( // id in selectedResources, @@ -275,6 +513,7 @@ class GalleryUpliftViewModel @Inject constructor( // galleryItems.size // ) } + private fun checkResourceChanges(pos: Int) = viewModelScope.launch { if (galleryItems.isEmpty()) { @@ -331,6 +570,15 @@ class GalleryUpliftViewModel @Inject constructor( private val _showProgress: MutableStateFlow = MutableStateFlow(false) val showProgress: StateFlow = _showProgress + + private val _notifyCurrentItemChange: MutableStateFlow = + MutableStateFlow(false) + val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange + + private val _updatePagerAdapterWithDiff: MutableStateFlow = + MutableStateFlow(false) + val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff + private fun invokeHandleGalleryExternalChangesUseCase( ) { viewModelScope.launch { @@ -358,10 +606,8 @@ class GalleryUpliftViewModel @Inject constructor( if (newItems.isEmpty()) { _onNavigateBack.value = true return@launch - } - diffResult = DiffUtil.calculateDiff( ResourceDiffUtilCallback( galleryItems.map { it.resource.id }, @@ -372,13 +618,16 @@ class GalleryUpliftViewModel @Inject constructor( galleryItems = newItems.toMutableList() viewModelScope.launch { + _updatePagerAdapterWithDiff.value = true // TODO trigger updatePagerAdapterWithDiff // viewState.updatePagerAdapterWithDiff() // TODO trigger updatePagerAdapterWithDiff + _notifyCurrentItemChange.value = true // viewState.notifyCurrentItemChanged() // TODO trigger show setProgressVisibility + _showProgress.value = true // viewState.setProgressVisibility(true, "Changes detected, indexing") } } } @@ -394,3 +643,12 @@ class GalleryUpliftViewModel @Inject constructor( } } } + +data class ResourceIdTagsPreview(val resourceId: ResourceId, val tags: Set) +data class SetupPreview(val position: Int, val meta: Metadata) +data class DisplaySelected( + val selected: Boolean, + val showAnim: Boolean, + val selectedCount: Int, + val itemCount: Int, +) From d1aae0c575e98f4e602e29435863d4501fdf0b09 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Wed, 10 Apr 2024 21:20:12 +0700 Subject: [PATCH 11/74] Add argument names --- .../presentation/screen/gallery/GalleryFragment.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt index bb8b2767..c2d43bab 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt @@ -62,12 +62,12 @@ class GalleryFragment : private val presenter by moxyPresenter { GalleryPresenter( - requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - requireArguments().getParcelableArray(RESOURCES_KEY)!!.toList() + rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, + resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!!.toList() as List, - requireArguments().getInt(START_AT_KEY), - requireArguments().getBoolean(SELECTING_ENABLED_KEY), - ( + startAt = requireArguments().getInt(START_AT_KEY), + selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), + selectedResources = ( requireArguments().getParcelableArray(SELECTED_RESOURCES_KEY)!! .toList() as List ) From 58ee95991991eea8842ec749be7c962f5f2d4c20 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Wed, 10 Apr 2024 21:20:29 +0700 Subject: [PATCH 12/74] Provide view models --- .../galleryuplift/GalleryUpliftFragment.kt | 85 +++++++++++++++++-- .../galleryuplift/GalleryUpliftViewModel.kt | 68 +++++++++++++-- 2 files changed, 135 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index c33cf6ca..461c8908 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -26,25 +26,35 @@ import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.chip.Chip import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.Message import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo +import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo +import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.Tags +import dev.arkbuilders.arklib.user.tags.TagsStorageRepo import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R +import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics +import dev.arkbuilders.navigator.data.preferences.Preferences +import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding import dev.arkbuilders.navigator.databinding.PopupGalleryTagMenuBinding +import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase import dev.arkbuilders.navigator.presentation.App import dev.arkbuilders.navigator.presentation.dialog.DetailsAlertDialog import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment +import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewsPager import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader @@ -53,15 +63,68 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts -import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path +import javax.inject.Inject import kotlin.system.measureTimeMillis + class GalleryUpliftFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) - val viewModel: GalleryUpliftViewModel by viewModels() + + @Inject + lateinit var preferences: Preferences + + @Inject + lateinit var router: AppRouter + + @Inject + lateinit var indexRepo: ResourceIndexRepo + + @Inject + lateinit var previewStorageRepo: PreviewProcessorRepo + + @Inject + lateinit var metadataStorageRepo: MetadataProcessorRepo + + @Inject + lateinit var tagsStorageRepo: TagsStorageRepo + + @Inject + lateinit var statsStorageRepo: StatsStorageRepo + + @Inject + lateinit var scoreStorageRepo: ScoreStorageRepo + + private val messageFlow: MutableSharedFlow = MutableSharedFlow() + + @Inject + lateinit var handleGalleryExternalChangesUseCase: + HandleGalleryExternalChangesUseCase + + @Inject + lateinit var analytics: GalleryAnalytics + + @Inject + lateinit var factory: GalleryUpliftViewModelFactory.Factory + + private val viewModel: GalleryUpliftViewModel by viewModels { + factory.create( + selectorNotEdit = false, +// preferences = preferences, +// router = router, +// indexRepo = indexRepo, +// previewStorageRepo = previewStorageRepo, +// metadataStorageRepo = metadataStorageRepo, +// tagsStorageRepo = tagsStorageRepo, +// statsStorageRepo = statsStorageRepo, +// scoreStorageRepo = scoreStorageRepo, +// analytics = analytics + ) + } + private lateinit var stackedToasts: StackedToasts private lateinit var pagerAdapter: PreviewsPagerUplift private val scoreWidget by lazy { @@ -80,7 +143,11 @@ class GalleryUpliftFragment : Fragment() { super.onViewCreated(view, savedInstanceState) App.instance.appComponent.inject(this) viewModel.onFirstViewAttach() - + viewModel.apply { + rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav + resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! + .toList() as List + } Timber.d( LogTags.GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}" @@ -414,15 +481,15 @@ class GalleryUpliftFragment : Fragment() { } fun notifyResourcesChanged() { - setFragmentResult(GalleryFragment.REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) + setFragmentResult(REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) } fun notifyTagsChanged() { - setFragmentResult(GalleryFragment.REQUEST_TAGS_CHANGED_KEY, bundleOf()) + setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) } fun notifyResourceScoresChanged() { - setFragmentResult(GalleryFragment.SCORES_CHANGED_KEY, bundleOf()) + setFragmentResult(SCORES_CHANGED_KEY, bundleOf()) } fun notifySelectedChanged( @@ -588,7 +655,7 @@ class GalleryUpliftFragment : Fragment() { EditTagsDialogFragment.REQUEST_TAGS_CHANGED_KEY, this ) { _, _ -> - setFragmentResult(GalleryFragment.REQUEST_TAGS_CHANGED_KEY, bundleOf()) + setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) viewModel.onTagsChanged() } @@ -750,7 +817,7 @@ class GalleryUpliftFragment : Fragment() { startAt: Int, selectingEnabled: Boolean = false, selectedResources: List = emptyList(), - ) = GalleryFragment().apply { + ) = GalleryUpliftFragment().apply { arguments = Bundle().apply { putParcelable(ROOT_AND_FAV_KEY, rootAndFav) putParcelableArray(RESOURCES_KEY, resources.toTypedArray()) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 732abef7..bd9c004a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -1,8 +1,13 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil +import dagger.Provides +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message @@ -32,6 +37,7 @@ import dev.arkbuilders.navigator.data.stats.StatsStorage import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase +import dev.arkbuilders.navigator.presentation.dialog.tagssort.TagsSortViewModel import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter @@ -54,6 +60,7 @@ import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists class GalleryUpliftViewModel @Inject constructor( + selectorNotEdit: Boolean, val preferences: Preferences, val router: AppRouter, val indexRepo: ResourceIndexRepo, @@ -62,15 +69,9 @@ class GalleryUpliftViewModel @Inject constructor( val tagsStorageRepo: TagsStorageRepo, val statsStorageRepo: StatsStorageRepo, val scoreStorageRepo: ScoreStorageRepo, - private val messageFlow: MutableSharedFlow = MutableSharedFlow(), - val handleGalleryExternalChangesUseCase: HandleGalleryExternalChangesUseCase, - private val resourcesIndexRepo: ResourceIndexRepo, - private val metadataProcessorRepo: MetadataProcessorRepo, - private val previewProcessorRepo: PreviewProcessorRepo, val analytics: GalleryAnalytics, - private val rootAndFav: RootAndFav, - val folders: RootAndFav, ) : ViewModel() { + private val messageFlow: MutableSharedFlow = MutableSharedFlow() lateinit var index: ResourceIndex private set lateinit var tagsStorage: TagStorage @@ -92,6 +93,8 @@ class GalleryUpliftViewModel @Inject constructor( private lateinit var previewProcessor: PreviewProcessor + lateinit var rootAndFav: RootAndFav + lateinit var resourcesIds: List private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] @@ -100,6 +103,10 @@ class GalleryUpliftViewModel @Inject constructor( val notifyResourceScoresChanged: StateFlow = _notifyResourceScoresChanged + init { + val a = 5 + } + fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) = viewModelScope.launch { view.reset() @@ -199,8 +206,6 @@ class GalleryUpliftViewModel @Inject constructor( MutableStateFlow(null) val toastIndexFailedPath: StateFlow = _toastIndexFailedPath - private val resourcesIds: List = listOf() - private val _showInfoAlert: MutableStateFlow = MutableStateFlow(null) val showInfoAlert: StateFlow = _showInfoAlert @@ -642,6 +647,8 @@ class GalleryUpliftViewModel @Inject constructor( Result.failure(e) } } + + } data class ResourceIdTagsPreview(val resourceId: ResourceId, val tags: Set) @@ -652,3 +659,46 @@ data class DisplaySelected( val selectedCount: Int, val itemCount: Int, ) + +class GalleryUpliftViewModelFactory @AssistedInject constructor( + @Assisted val selectorNotEdit: Boolean, + val preferences: Preferences, + val router: AppRouter, + val indexRepo: ResourceIndexRepo, + val previewStorageRepo: PreviewProcessorRepo, + val metadataStorageRepo: MetadataProcessorRepo, + val tagsStorageRepo: TagsStorageRepo, + val statsStorageRepo: StatsStorageRepo, + val scoreStorageRepo: ScoreStorageRepo, + val analytics: GalleryAnalytics, +) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + return GalleryUpliftViewModel( + selectorNotEdit = selectorNotEdit, + preferences = preferences, + router = router, + indexRepo = indexRepo, + previewStorageRepo = previewStorageRepo, + metadataStorageRepo = metadataStorageRepo, + tagsStorageRepo = tagsStorageRepo, + statsStorageRepo = statsStorageRepo, + scoreStorageRepo = scoreStorageRepo, + analytics = analytics, + ) as T + } + @AssistedFactory + interface Factory { + fun create( + @Assisted selectorNotEdit: Boolean, +// preferences: Preferences, +// router: AppRouter, +// indexRepo: ResourceIndexRepo, +// previewStorageRepo: PreviewProcessorRepo, +// metadataStorageRepo: MetadataProcessorRepo, +// tagsStorageRepo: TagsStorageRepo, +// statsStorageRepo: StatsStorageRepo, +// scoreStorageRepo: ScoreStorageRepo, +// analytics: GalleryAnalytics, + ): GalleryUpliftViewModelFactory + } +} From 74363f3fd141314ee05661a769ae18aaaaf0cdd8 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Wed, 10 Apr 2024 21:20:42 +0700 Subject: [PATCH 13/74] Navigate to new uplift gallery screen --- .../presentation/navigation/Screens.kt | 26 +++++++++++++++++++ .../adapter/ResourcesGridPresenter.kt | 12 +++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt index 26e0ae05..53e8681c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt @@ -8,6 +8,7 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import dev.arkbuilders.navigator.presentation.screen.resources.ResourcesFragment import dev.arkbuilders.navigator.presentation.screen.settings.SettingsFragment import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.GalleryUpliftFragment class Screens { class FoldersScreen : SupportAppScreen() { @@ -40,6 +41,15 @@ class Screens { GalleryFragment.newInstance(rootAndFav, resources, startAt) } + class GalleryUpliftScreen( + private val rootAndFav: RootAndFav, + val resources: List, + private val startAt: Int + ) : SupportAppScreen() { + override fun getFragment() = + GalleryUpliftFragment.newInstance(rootAndFav, resources, startAt) + } + class GalleryScreenWithSelected( private val rootAndFav: RootAndFav, val resources: List, @@ -56,6 +66,22 @@ class Screens { ) } + class GalleryScreenWithSelectedUplift( + private val rootAndFav: RootAndFav, + val resources: List, + private val startAt: Int, + private val selectedResources: List + ) : SupportAppScreen() { + override fun getFragment() = + GalleryUpliftFragment.newInstance( + rootAndFav, + resources, + startAt, + true, + selectedResources + ) + } + class SettingsScreen : SupportAppScreen() { override fun getFragment() = SettingsFragment.newInstance() } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt index c3fb6eeb..5c76bc06 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt @@ -145,8 +145,16 @@ class ResourcesGridPresenter( return@launch } +// router.navigateToFragmentUsingAdd( +// Screens.GalleryScreen( +// rootAndFav, +// selection.map { it.id() }, +// pos +// ) +// ) + router.navigateToFragmentUsingAdd( - Screens.GalleryScreen( + Screens.GalleryUpliftScreen( rootAndFav, selection.map { it.id() }, pos @@ -303,7 +311,7 @@ class ResourcesGridPresenter( fun onSelectedItemLongClick(item: FileItemViewHolder) { router.navigateToFragmentUsingAdd( - Screens.GalleryScreenWithSelected( + Screens.GalleryScreenWithSelectedUplift( rootAndFav, selection.map { it.id() }, item.position(), From cec293d423f9d7e79dc6eeac613511260150c74c Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Thu, 11 Apr 2024 22:22:41 +0700 Subject: [PATCH 14/74] Provide layout file --- .../galleryuplift/GalleryUpliftFragment.kt | 17 +++++++++++------ .../galleryuplift/GalleryUpliftViewModel.kt | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 461c8908..79aff532 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -6,7 +6,9 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import android.util.TypedValue +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.activity.addCallback import androidx.core.content.FileProvider @@ -26,7 +28,6 @@ import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.chip.Chip import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.Message import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata @@ -63,7 +64,6 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path @@ -98,8 +98,6 @@ class GalleryUpliftFragment : Fragment() { @Inject lateinit var scoreStorageRepo: ScoreStorageRepo - private val messageFlow: MutableSharedFlow = MutableSharedFlow() - @Inject lateinit var handleGalleryExternalChangesUseCase: HandleGalleryExternalChangesUseCase @@ -130,7 +128,6 @@ class GalleryUpliftFragment : Fragment() { private val scoreWidget by lazy { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } - private fun onBackClick() { Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") notifySelectedChanged(viewModel.selectedResources) @@ -138,10 +135,18 @@ class GalleryUpliftFragment : Fragment() { viewModel.router.exit() } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_gallery, container, false); + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") - super.onViewCreated(view, savedInstanceState) App.instance.appComponent.inject(this) + super.onViewCreated(view, savedInstanceState) viewModel.onFirstViewAttach() viewModel.apply { rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index bd9c004a..c5efbd6c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -59,7 +59,7 @@ import javax.inject.Inject import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists -class GalleryUpliftViewModel @Inject constructor( +class GalleryUpliftViewModel constructor( selectorNotEdit: Boolean, val preferences: Preferences, val router: AppRouter, From cee81a64eefc4c5ae599b125b40261cd06ac2934 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 14:54:59 +0700 Subject: [PATCH 15/74] Set value when navigate --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 79aff532..5b4219c0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -107,7 +107,6 @@ class GalleryUpliftFragment : Fragment() { @Inject lateinit var factory: GalleryUpliftViewModelFactory.Factory - private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( selectorNotEdit = false, @@ -128,6 +127,7 @@ class GalleryUpliftFragment : Fragment() { private val scoreWidget by lazy { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } + private fun onBackClick() { Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") notifySelectedChanged(viewModel.selectedResources) @@ -146,13 +146,14 @@ class GalleryUpliftFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) - super.onViewCreated(view, savedInstanceState) - viewModel.onFirstViewAttach() viewModel.apply { rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! .toList() as List } + super.onViewCreated(view, savedInstanceState) + viewModel.onFirstViewAttach() + Timber.d( LogTags.GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}" From 2bb2cdffd942928de2dfb047e8c3650ef3e33fbc Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 15:15:20 +0700 Subject: [PATCH 16/74] Handle state change --- .../galleryuplift/GalleryUpliftFragment.kt | 26 +++++++------------ .../galleryuplift/GalleryUpliftViewModel.kt | 14 +++++----- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 5b4219c0..4d6200fd 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -140,7 +140,7 @@ class GalleryUpliftFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_gallery, container, false); + return inflater.inflate(R.layout.fragment_gallery, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -245,7 +245,9 @@ class GalleryUpliftFragment : Fragment() { } launch { viewModel.shareLink.collect { - shareLink(it) + if (it.isNotEmpty()) { + shareLink(it) + } } } launch { @@ -262,12 +264,9 @@ class GalleryUpliftFragment : Fragment() { } launch { viewModel.openLink.collect { - - } - } - launch { - viewModel.openLink.collect { - openLink(it) + if (it.isNotEmpty()) { + openLink(it) + } } } launch { @@ -289,13 +288,6 @@ class GalleryUpliftFragment : Fragment() { notifyResourcesChanged() } } - launch { - viewModel.notifyResourceChange.collect { - viewModel.showProgress.collect { - setProgressVisibility(it, "Changes detected, indexing") - } - } - } launch { viewModel.displayPreviewTags.collect { if (it != null) { @@ -349,7 +341,9 @@ class GalleryUpliftFragment : Fragment() { } launch { viewModel.onNavigateBack.collect { - onBackClick() + if (it) { + onBackClick() + } } } launch { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index c5efbd6c..693b75c2 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -243,27 +243,27 @@ class GalleryUpliftViewModel constructor( }.launchIn(viewModelScope) //TODO Trigger setProgressVisibility - _showProgress.value = true +// _showProgress.value = true // viewState.setProgressVisibility(true, "Providing metadata storage") metadataStorage = metadataStorageRepo.provide(index) //TODO Trigger setProgressVisibility - _showProgress.value = true +// _showProgress.value = true // viewState.setProgressVisibility(true, "Providing previews storage") previewStorage = previewStorageRepo.provide(index) //TODO Trigger setProgressVisibility - _showProgress.value = true +// _showProgress.value = true // viewState.setProgressVisibility(true, "Proviging data storages") try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) } catch (e: StorageException) { - _displayStorageException.value = StorageExceptionGallery( - label = e.label, - messenger = e.msg - ) +// _displayStorageException.value = StorageExceptionGallery( +// label = e.label, +// messenger = e.msg +// ) // TODO Trigger displayStorageException // viewState.displayStorageException( // e.label, From acbf8d168ac271117d68be7cdbede6f826fc138a Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 15:16:47 +0700 Subject: [PATCH 17/74] Handle state change --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 7 +++++++ .../gallery/galleryuplift/GalleryUpliftViewModel.kt | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 4d6200fd..8ab47081 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -367,6 +367,13 @@ class GalleryUpliftFragment : Fragment() { } } } + launch { + viewModel.displayStorageException.collect { + it?.let { + displayStorageException(it.label, it.messenger) + } + } + } } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 693b75c2..28524e50 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -260,10 +260,10 @@ class GalleryUpliftViewModel constructor( tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) } catch (e: StorageException) { -// _displayStorageException.value = StorageExceptionGallery( -// label = e.label, -// messenger = e.msg -// ) + _displayStorageException.value = StorageExceptionGallery( + label = e.label, + messenger = e.msg + ) // TODO Trigger displayStorageException // viewState.displayStorageException( // e.label, From 0883fd7fcccabd3f26d3913dabad0ff2af3fc334 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 15:17:58 +0700 Subject: [PATCH 18/74] Improve coding style --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 8ab47081..049c680a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -309,8 +309,8 @@ class GalleryUpliftFragment : Fragment() { viewModel.displaySelected.collect { it?.let { displaySelected( - it.selected, - it.showAnim, + selected = it.selected, + showAnim = it.showAnim, selectedCount = it.selectedCount, itemCount = viewModel.galleryItems.size ) From b6d2cd38e3095b9092a84191c39dafa72feeeebf Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 16:47:00 +0700 Subject: [PATCH 19/74] Extract classes & refactor code usage --- .../galleryuplift/GalleryUpliftFragment.kt | 78 ++- .../galleryuplift/GalleryUpliftViewModel.kt | 489 +++++++----------- .../GalleryUpliftViewModelFactory.kt | 51 ++ .../galleryuplift/domain/DisplaySelected.kt | 8 + .../galleryuplift/domain/ProgressWithText.kt | 6 + .../domain/ResourceIdTagsPreview.kt | 5 + .../galleryuplift/domain/SetupPreview.kt | 5 + .../galleryuplift/domain/ShowEditTagsData.kt | 16 + .../galleryuplift/domain/ShowInfoData.kt | 11 + .../domain/StorageExceptionGallery.kt | 3 + 10 files changed, 358 insertions(+), 314 deletions(-) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 049c680a..239160e9 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -29,12 +29,14 @@ import com.google.android.material.chip.Chip import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.index.ResourceIndex import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.arklib.user.tags.TagStorage import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.user.tags.TagsStorageRepo import dev.arkbuilders.arklib.utils.extension @@ -44,6 +46,7 @@ import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics import dev.arkbuilders.navigator.data.preferences.Preferences +import dev.arkbuilders.navigator.data.stats.StatsStorage import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding @@ -64,6 +67,7 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path @@ -109,16 +113,7 @@ class GalleryUpliftFragment : Fragment() { lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( - selectorNotEdit = false, -// preferences = preferences, -// router = router, -// indexRepo = indexRepo, -// previewStorageRepo = previewStorageRepo, -// metadataStorageRepo = metadataStorageRepo, -// tagsStorageRepo = tagsStorageRepo, -// statsStorageRepo = statsStorageRepo, -// scoreStorageRepo = scoreStorageRepo, -// analytics = analytics + selectorNotEdit = false ) } @@ -146,11 +141,11 @@ class GalleryUpliftFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) - viewModel.apply { - rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav + viewModel.initialize( + rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! .toList() as List - } + ) super.onViewCreated(view, savedInstanceState) viewModel.onFirstViewAttach() @@ -297,12 +292,16 @@ class GalleryUpliftFragment : Fragment() { } launch { viewModel.notifyCurrentItemChange.collect { - notifyCurrentItemChanged() + if (it) { + notifyCurrentItemChanged() + } } } launch { viewModel.updatePagerAdapterWithDiff.collect { - updatePagerAdapterWithDiff() + if (it) { + updatePagerAdapterWithDiff() + } } } launch { @@ -326,7 +325,9 @@ class GalleryUpliftFragment : Fragment() { } launch { viewModel.notifyResourceScoresChanged.collect { - notifyResourceScoresChanged() + if (it) { + notifyResourceScoresChanged() + } } } launch { @@ -363,7 +364,14 @@ class GalleryUpliftFragment : Fragment() { launch { viewModel.showEditTagsDialog.collect { it?.let { - showEditTagsDialog(it) + showEditTagsDialog( + resource = it.resource, + resources = it.resources, + statsStorage = it.statsStorage, + rootAndFav = it.rootAndFav, + index = it.index, + storage = it.storage, + ) } } } @@ -374,6 +382,23 @@ class GalleryUpliftFragment : Fragment() { } } } + launch { + viewModel.notifyTagsChanged.collect { + if (it) { + notifyTagsChanged() + } + } + } + launch { + viewModel.showProgressWithText.collect { + it?.let { + setProgressVisibility( + isVisible = it.isVisible, + withText = it.text + ) + } + } + } } } } @@ -544,19 +569,24 @@ class GalleryUpliftFragment : Fragment() { } } - fun showEditTagsDialog( - resource: ResourceId + private fun showEditTagsDialog( + resource: ResourceId, + rootAndFav: RootAndFav, + resources: List, + index: ResourceIndex, + storage: TagStorage, + statsStorage: StatsStorage ) { Timber.d( LogTags.GALLERY_SCREEN, "showing [edit-tags] dialog for resource $resource" ) val dialog = EditTagsDialogFragment.newInstance( - requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - listOf(resource), - viewModel.index, - viewModel.tagsStorage, - viewModel.statsStorage + rootAndFav = rootAndFav, + resources = resources, + index = index, + storage = storage, + statsStorage = statsStorage ) dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 28524e50..e702b072 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -1,17 +1,11 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.DiffUtil -import dagger.Provides -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message -import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.index.ResourceIndex import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata @@ -36,14 +30,20 @@ import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.data.stats.StatsStorage import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags -import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase -import dev.arkbuilders.navigator.presentation.dialog.tagssort.TagsSortViewModel import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressWithText +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowInfoData +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -55,11 +55,10 @@ import timber.log.Timber import java.io.FileReader import java.nio.file.Files import java.nio.file.Path -import javax.inject.Inject import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists -class GalleryUpliftViewModel constructor( +class GalleryUpliftViewModel( selectorNotEdit: Boolean, val preferences: Preferences, val router: AppRouter, @@ -90,11 +89,8 @@ class GalleryUpliftViewModel constructor( private var currentPos = 0 val selectedResources: MutableList = mutableListOf() - private lateinit var previewProcessor: PreviewProcessor - - - lateinit var rootAndFav: RootAndFav - lateinit var resourcesIds: List + private lateinit var rootAndFav: RootAndFav + private lateinit var resourcesIds: List private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] @@ -103,11 +99,110 @@ class GalleryUpliftViewModel constructor( val notifyResourceScoresChanged: StateFlow = _notifyResourceScoresChanged - init { - val a = 5 + private val _setControlsVisibility: MutableStateFlow = + MutableStateFlow(false) + val setControlsVisibility: StateFlow = + _setControlsVisibility + + private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) + val onNavigateBack: StateFlow = _onNavigateBack + + private val _deleteResource: MutableStateFlow = MutableStateFlow(null) + val deleteResource: StateFlow = _deleteResource + + val scoreWidgetController = ScoreWidgetController( + scope = viewModelScope, + getCurrentId = { currentItem.id() }, + onScoreChanged = { + _notifyResourceScoresChanged.value = true + } + ) + + private var sortByScores = false + private var selectingEnabled: Boolean = false + + private val _toastIndexFailedPath: MutableStateFlow = + MutableStateFlow(null) + val toastIndexFailedPath: StateFlow = _toastIndexFailedPath + + private val _showInfoAlert: MutableStateFlow = + MutableStateFlow(null) + val showInfoAlert: StateFlow = _showInfoAlert + + private val _displayStorageException: MutableStateFlow = + MutableStateFlow(null) + val displayStorageException: StateFlow = + _displayStorageException + + private val _updatePagerAdapter: MutableStateFlow = + MutableStateFlow(false) + val updatePagerAdapter: StateFlow = _updatePagerAdapter + + private val _shareLink: MutableStateFlow = MutableStateFlow("") + val shareLink: StateFlow = _shareLink + + private val _shareResource: MutableStateFlow = MutableStateFlow(null) + val shareResource: StateFlow = _shareResource + + private val _editResource: MutableStateFlow = MutableStateFlow(null) + val editResource: StateFlow = _editResource + + private val _openLink: MutableStateFlow = MutableStateFlow("") + val openLink: StateFlow = _openLink + + private val _viewInExternalApp: MutableStateFlow = + MutableStateFlow(null) + val viewInExternalApp: StateFlow = _viewInExternalApp + + private val _displayPreviewTags: MutableStateFlow = + MutableStateFlow(null) + val displayPreviewTags: StateFlow = _displayPreviewTags + + private val _notifyTagsChanged: MutableStateFlow = + MutableStateFlow(false) + val notifyTagsChanged: StateFlow = _notifyTagsChanged + + private val _showEditTagsDialog: MutableStateFlow = + MutableStateFlow(null) + val showEditTagsDialog: StateFlow = _showEditTagsDialog + + private val _setUpPreview: MutableStateFlow = + MutableStateFlow(null) + val setUpPreview: StateFlow = _setUpPreview + + private val _displaySelected: MutableStateFlow = + MutableStateFlow(null) + val displaySelected: StateFlow = _displaySelected + + private val _notifyResourceChange: MutableStateFlow = + MutableStateFlow(false) + val notifyResourceChange: StateFlow = _notifyResourceChange + + private val _showProgressWithText: MutableStateFlow = + MutableStateFlow(null) + val showProgressWithText: StateFlow = _showProgressWithText + + private val _notifyCurrentItemChange: MutableStateFlow = + MutableStateFlow(false) + val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange + + private val _updatePagerAdapterWithDiff: MutableStateFlow = + MutableStateFlow(false) + val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff + + fun initialize( + rootAndFav: RootAndFav, + resourcesIds: List, + ) { + this.rootAndFav = rootAndFav + this.resourcesIds = resourcesIds + } + + fun onPreviewsItemClick() { + _setControlsVisibility.value = !_setControlsVisibility.value } - fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) = + fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) { viewModelScope.launch { view.reset() val item = galleryItems[view.pos] @@ -119,69 +214,35 @@ class GalleryUpliftViewModel constructor( view.setContent(it) } } - - private var isControlsVisible = false - - private val _setControlsVisibility: MutableStateFlow = - MutableStateFlow(false) - val setControlsVisibility: StateFlow = - _setControlsVisibility - - fun onPreviewsItemClick() { - isControlsVisible = !isControlsVisible - // TODO Trigger setControlsVisibility - _setControlsVisibility.value = isControlsVisible -// viewState.setControlsVisibility(isControlsVisible) } fun bindView(view: PreviewImageViewHolderUplift) = viewModelScope.launch { view.reset() val item = galleryItems[view.pos] - val path = index.getPath(item.id())!! val placeholder = ImageUtils.iconForExtension(extension(path)) view.setSource(placeholder, item.id(), item.metadata, item.preview) } - val scoreWidgetController = ScoreWidgetController( - scope = viewModelScope, - getCurrentId = { currentItem.id() }, - onScoreChanged = { - _notifyResourceScoresChanged.value = true - // TODO Trigger notifyResourceScoresChanged -// viewState.notifyResourceScoresChanged() - } - ) - fun getKind(pos: Int): Int = galleryItems[pos].metadata.kind.ordinal - private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) - val onNavigateBack: StateFlow = _onNavigateBack - - private val _deleteResource: MutableStateFlow = MutableStateFlow(null) - val deleteResource: StateFlow = _deleteResource fun onRemoveFabClick() = viewModelScope.launch(NonCancellable) { analytics.trackResRemove() Timber.d( LogTags.GALLERY_SCREEN, "[remove_resource] clicked at position $currentPos" ) - //TODO Trigger fragment.deleteResource -// deleteResource(currentItem.id()) deleteResource(currentItem.id()) galleryItems.removeAt(currentPos) if (galleryItems.isEmpty()) { - //TODO Trigger fragment.onBackClick() _onNavigateBack.emit(true) -// onBackClick() return@launch } onTagsChanged() _deleteResource.value = currentPos -// viewState.deleteResource(currentPos) } @@ -196,66 +257,37 @@ class GalleryUpliftViewModel constructor( index.updateAll() _notifyResourceChange.value = true - // TODO Trigger notifyResourcesChanged -// viewState.notifyResourcesChanged() } - - private var sortByScores = false - - private val _toastIndexFailedPath: MutableStateFlow = - MutableStateFlow(null) - val toastIndexFailedPath: StateFlow = _toastIndexFailedPath - - private val _showInfoAlert: MutableStateFlow = - MutableStateFlow(null) - val showInfoAlert: StateFlow = _showInfoAlert - - private val _init: MutableStateFlow = MutableStateFlow(false) - val init: StateFlow = _init - - private val _displayStorageException: MutableStateFlow = - MutableStateFlow(null) - val displayStorageException: StateFlow = - _displayStorageException - - private val _updatePagerAdapter: MutableStateFlow = - MutableStateFlow(false) - val updatePagerAdapter: StateFlow = _updatePagerAdapter fun onFirstViewAttach() { analytics.trackScreen() Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { - //TODO Trigger init - _init.value = true -// viewState.init() - _showProgress.value = true - //TODO Trigger setProgressVisibility -// viewState.setProgressVisibility(true, "Providing root index") - + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Providing root index", + ) index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { is Message.KindDetectFailed -> _toastIndexFailedPath.value = message.path - //TODO Trigger toastIndexFailedPath -// viewState.toastIndexFailedPath(message.path) } }.launchIn(viewModelScope) - //TODO Trigger setProgressVisibility -// _showProgress.value = true -// viewState.setProgressVisibility(true, "Providing metadata storage") + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Providing metadata storage", + ) metadataStorage = metadataStorageRepo.provide(index) - - //TODO Trigger setProgressVisibility -// _showProgress.value = true -// viewState.setProgressVisibility(true, "Providing previews storage") + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Providing previews storage", + ) previewStorage = previewStorageRepo.provide(index) - - //TODO Trigger setProgressVisibility -// _showProgress.value = true -// viewState.setProgressVisibility(true, "Proviging data storages") - + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Providing data storage", + ) try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) @@ -264,11 +296,6 @@ class GalleryUpliftViewModel constructor( label = e.label, messenger = e.msg ) - // TODO Trigger displayStorageException -// viewState.displayStorageException( -// e.label, -// e.msg -// } statsStorage = statsStorageRepo.provide(index) @@ -277,32 +304,20 @@ class GalleryUpliftViewModel constructor( galleryItems = provideGalleryItems().toMutableList() sortByScores = preferences.get(PreferenceKey.SortByScores) - - // TODO Trigger updatePagerAdapter -// viewState.updatePagerAdapter() _updatePagerAdapter.value = true - // TODO Trigger setProgressVisibility - _showProgress.value = false -// viewState.setProgressVisibility(false) + _showProgressWithText.value = ProgressWithText( + isVisible = false, + text = "" + ) scoreWidgetController.setVisible(sortByScores) } } fun onPlayButtonClick() = viewModelScope.launch { - // TODO Trigger viewInExternalApp _viewInExternalApp.value = index.getPath(currentItem.id())!! -// viewState.viewInExternalApp(index.getPath(currentItem.id())!!) } - data class StorageExceptionGallery(val label: String, val messenger: String) - - data class ShowInfoData( - val path: Path, - val resource: Resource, - val metadata: Metadata - ) - fun onInfoFabClick() = viewModelScope.launch { analytics.trackResInfo() Timber.d( @@ -311,23 +326,15 @@ class GalleryUpliftViewModel constructor( ) val path = index.getPath(currentItem.id())!! - //TODO Trigger showInfoAlert val data = ShowInfoData( path = path, resource = currentItem.resource, metadata = currentItem.metadata ) _showInfoAlert.emit(data) -// viewState.showInfoAlert(path, currentItem.resource, currentItem.metadata) } - private val _shareLink: MutableStateFlow = MutableStateFlow("") - val shareLink: StateFlow = _shareLink - - - private val _shareResource: MutableStateFlow = MutableStateFlow(null) - val shareResource: StateFlow = _shareResource fun onShareFabClick() = viewModelScope.launch { analytics.trackResShare() Timber.d( @@ -338,26 +345,18 @@ class GalleryUpliftViewModel constructor( if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - //TODO Trigger sharelink -// viewState.shareLink(url) _shareLink.emit(url) return@launch } - //TODO Trigger shareResource -// viewState.shareResource(path) _shareResource.emit(path) } - private var selectingEnabled: Boolean = false - private val _toggleSelect: MutableStateFlow = MutableStateFlow(false) val toggleSelect: StateFlow = _toggleSelect fun onSelectingChanged() { viewModelScope.launch { selectingEnabled = !selectingEnabled - //TODO Trigger toggleSelecting _toggleSelect.emit(selectingEnabled) -// viewState.toggleSelecting(selectingEnabled) selectedResources.clear() if (selectingEnabled) { selectedResources.add(currentItem.resource.id) @@ -365,13 +364,6 @@ class GalleryUpliftViewModel constructor( } } - private val _openLink: MutableStateFlow = MutableStateFlow("") - val openLink: StateFlow = _openLink - - - private val _viewInExternalApp: MutableStateFlow = - MutableStateFlow(null) - val viewInExternalApp: StateFlow = _viewInExternalApp fun onOpenFabClick() = viewModelScope.launch { analytics.trackResOpen() Timber.d( @@ -384,21 +376,12 @@ class GalleryUpliftViewModel constructor( if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - //TODO Trigger openLink -// viewState.openLink(url) _openLink.emit(url) return@launch } - - //TODO Trigger viewInExternalApp -// viewState.viewInExternalApp(path) _viewInExternalApp.emit(path) - } - - private val _editResource: MutableStateFlow = MutableStateFlow(null) - val editResource: StateFlow = _editResource fun onEditFabClick() = viewModelScope.launch { analytics.trackResEdit() Timber.d( @@ -406,15 +389,39 @@ class GalleryUpliftViewModel constructor( "[edit_resource] clicked at position $currentPos" ) val path = index.getPath(currentItem.id())!! - //TODO Trigger editResource -// viewState.editResource(path) _editResource.emit(path) } + fun onSelectBtnClick() { + val id = currentItem.id() + val wasSelected = id in selectedResources + + if (wasSelected) { + selectedResources.remove(id) + } else { + selectedResources.add(id) + } + + _displaySelected.value = DisplaySelected( + selected = !wasSelected, + showAnim = true, + selectedCount = selectedResources.size, + itemCount = galleryItems.size + ) + } + + fun onResume() { + checkResourceChanges(currentPos) + } + + fun onTagsChanged() { + val tags = tagsStorage.getTags(currentItem.id()) + _displayPreviewTags.value = ResourceIdTagsPreview( + resourceId = currentItem.id(), + tags = tags, + ) + } - fun onSelectBtnClick() {} - fun onResume() {} - fun onTagsChanged() {} fun onPageChanged(newPos: Int) = viewModelScope.launch { if (galleryItems.isEmpty()) return@launch @@ -437,14 +444,6 @@ class GalleryUpliftViewModel constructor( ) } - private val _displayPreviewTags: MutableStateFlow = - MutableStateFlow(null) - val displayPreviewTags: StateFlow = _displayPreviewTags - - private val _notifyTagsChanged: MutableStateFlow = - MutableStateFlow(false) - val notifyTagsChanged: StateFlow = _notifyTagsChanged - fun onTagRemove(tag: Tag) = viewModelScope.launch(NonCancellable) { analytics.trackTagRemove() val id = currentItem.id() @@ -452,10 +451,10 @@ class GalleryUpliftViewModel constructor( val tags = tagsStorage.getTags(id) val newTags = tags - tag - // TODO Trigger displaypreviewtags - _displayPreviewTags.value = - ResourceIdTagsPreview(resourceId = id, tags = newTags) -// viewState.displayPreviewTags(id, newTags) + _displayPreviewTags.value = ResourceIdTagsPreview( + resourceId = id, + tags = newTags, + ) statsStorage.handleEvent( StatsEvent.TagsChanged( id, tags, newTags @@ -467,56 +466,42 @@ class GalleryUpliftViewModel constructor( tagsStorage.setTags(id, newTags) tagsStorage.persist() _notifyTagsChanged.value = true - // TODO Trigger notifyTagsChanged -// viewState.notifyTagsChanged() } - private val _showEditTagsDialog: MutableStateFlow = - MutableStateFlow(null) - val showEditTagsDialog: StateFlow = _showEditTagsDialog fun onEditTagsDialogBtnClick() { analytics.trackTagsEdit() - // TODO _showEditTagsDialog - _showEditTagsDialog.value = currentItem.id() -// viewState.showEditTagsDialog(currentItem.id()) + _showEditTagsDialog.value = ShowEditTagsData( + resource = currentItem.id(), + resources = listOf(currentItem.id()), + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = tagsStorage, + ) } - - private val _setUpPreview: MutableStateFlow = - MutableStateFlow(null) - val setUpPreview: StateFlow = _setUpPreview - - private val _displaySelected: MutableStateFlow = - MutableStateFlow(null) - val displaySelected: StateFlow = _displaySelected private fun displayPreview( id: ResourceId, meta: Metadata, tags: Tags ) { - _setUpPreview.value = SetupPreview(position = currentPos, meta = meta) - // TODO Trigger setupPreview -// viewState.setupPreview(currentPos, meta) - - _displayPreviewTags.value = - ResourceIdTagsPreview(resourceId = id, tags = tags) - // TODO Trigger displayPreviewTags -// viewState.displayPreviewTags(id, tags) + _setUpPreview.value = SetupPreview( + position = currentPos, + meta = meta, + ) + + _displayPreviewTags.value = ResourceIdTagsPreview( + resourceId = id, + tags = tags, + ) scoreWidgetController.displayScore() _displaySelected.value = DisplaySelected( selected = id in selectedResources, showAnim = false, selectedCount = selectedResources.size, - itemCount = galleryItems.size + itemCount = galleryItems.size, ) - // TODO Trigger displaySelected -// viewState.displaySelected( -// id in selectedResources, -// showAnim = false, -// selectedResources.size, -// galleryItems.size -// ) } private fun checkResourceChanges(pos: Int) = @@ -531,26 +516,23 @@ class GalleryUpliftViewModel constructor( ?: let { Timber.d("Resource ${item.id()} can't be found in the index") invokeHandleGalleryExternalChangesUseCase() -// handleGalleryExternalChangesUseCase(this@GalleryPresenter) return@launch } if (path.notExists()) { Timber.d("Resource ${item.id()} isn't stored by path $path") invokeHandleGalleryExternalChangesUseCase() -// handleGalleryExternalChangesUseCase(this@GalleryPresenter) return@launch } if (path.getLastModifiedTime() != item.resource.modified) { Timber.d("Index is not up-to-date regarding path $path") invokeHandleGalleryExternalChangesUseCase() -// handleGalleryExternalChangesUseCase(this@GalleryPresenter) return@launch } } - fun provideGalleryItems(): List = + private fun provideGalleryItems(): List = try { val allResources = index.allResources() resourcesIds @@ -568,44 +550,28 @@ class GalleryUpliftViewModel constructor( emptyList() } - private val _notifyResourceChange: MutableStateFlow = - MutableStateFlow(false) - val notifyResourceChange: StateFlow = _notifyResourceChange - - private val _showProgress: MutableStateFlow = - MutableStateFlow(false) - val showProgress: StateFlow = _showProgress - - private val _notifyCurrentItemChange: MutableStateFlow = - MutableStateFlow(false) - val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange - - private val _updatePagerAdapterWithDiff: MutableStateFlow = - MutableStateFlow(false) - val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff private fun invokeHandleGalleryExternalChangesUseCase( ) { viewModelScope.launch { withContext(Dispatchers.Main) { - // trigger show setProgressVisibility - _showProgress.value = true -// viewState.setProgressVisibility(true, "Changes detected, indexing") + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) } index.updateAll() withContext(Dispatchers.Main) { _notifyResourceChange.value = true - // TODO Trigger notifyResourcesChanged -// viewState.notifyResourcesChanged() } - // TODO: Investigate more -// viewModelScope.launch { -// metadataStorage.busy.collect { busy -> if (!busy) cancel() -// } -// }.join() + viewModelScope.launch { + metadataStorage.busy.collect { busy -> + if (!busy) cancel() + } + }.join() val newItems = provideGalleryItems() if (newItems.isEmpty()) { @@ -624,16 +590,11 @@ class GalleryUpliftViewModel constructor( viewModelScope.launch { _updatePagerAdapterWithDiff.value = true - // TODO trigger updatePagerAdapterWithDiff -// viewState.updatePagerAdapterWithDiff() - - // TODO trigger updatePagerAdapterWithDiff _notifyCurrentItemChange.value = true -// viewState.notifyCurrentItemChanged() - - // TODO trigger show setProgressVisibility - _showProgress.value = true -// viewState.setProgressVisibility(true, "Changes detected, indexing") } + _showProgressWithText.value = ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) } } } @@ -647,58 +608,6 @@ class GalleryUpliftViewModel constructor( Result.failure(e) } } - - } -data class ResourceIdTagsPreview(val resourceId: ResourceId, val tags: Set) -data class SetupPreview(val position: Int, val meta: Metadata) -data class DisplaySelected( - val selected: Boolean, - val showAnim: Boolean, - val selectedCount: Int, - val itemCount: Int, -) - -class GalleryUpliftViewModelFactory @AssistedInject constructor( - @Assisted val selectorNotEdit: Boolean, - val preferences: Preferences, - val router: AppRouter, - val indexRepo: ResourceIndexRepo, - val previewStorageRepo: PreviewProcessorRepo, - val metadataStorageRepo: MetadataProcessorRepo, - val tagsStorageRepo: TagsStorageRepo, - val statsStorageRepo: StatsStorageRepo, - val scoreStorageRepo: ScoreStorageRepo, - val analytics: GalleryAnalytics, -) : ViewModelProvider.Factory { - override fun create(modelClass: Class): T { - return GalleryUpliftViewModel( - selectorNotEdit = selectorNotEdit, - preferences = preferences, - router = router, - indexRepo = indexRepo, - previewStorageRepo = previewStorageRepo, - metadataStorageRepo = metadataStorageRepo, - tagsStorageRepo = tagsStorageRepo, - statsStorageRepo = statsStorageRepo, - scoreStorageRepo = scoreStorageRepo, - analytics = analytics, - ) as T - } - @AssistedFactory - interface Factory { - fun create( - @Assisted selectorNotEdit: Boolean, -// preferences: Preferences, -// router: AppRouter, -// indexRepo: ResourceIndexRepo, -// previewStorageRepo: PreviewProcessorRepo, -// metadataStorageRepo: MetadataProcessorRepo, -// tagsStorageRepo: TagsStorageRepo, -// statsStorageRepo: StatsStorageRepo, -// scoreStorageRepo: ScoreStorageRepo, -// analytics: GalleryAnalytics, - ): GalleryUpliftViewModelFactory - } -} + diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt new file mode 100644 index 00000000..8c1672e5 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt @@ -0,0 +1,51 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import dev.arkbuilders.arklib.data.index.ResourceIndexRepo +import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo +import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo +import dev.arkbuilders.arklib.user.score.ScoreStorageRepo +import dev.arkbuilders.arklib.user.tags.TagsStorageRepo +import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics +import dev.arkbuilders.navigator.data.preferences.Preferences +import dev.arkbuilders.navigator.data.stats.StatsStorageRepo +import dev.arkbuilders.navigator.presentation.navigation.AppRouter + +class GalleryUpliftViewModelFactory @AssistedInject constructor( + @Assisted val selectorNotEdit: Boolean, + val preferences: Preferences, + val router: AppRouter, + val indexRepo: ResourceIndexRepo, + val previewStorageRepo: PreviewProcessorRepo, + val metadataStorageRepo: MetadataProcessorRepo, + val tagsStorageRepo: TagsStorageRepo, + val statsStorageRepo: StatsStorageRepo, + val scoreStorageRepo: ScoreStorageRepo, + val analytics: GalleryAnalytics, +) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + return GalleryUpliftViewModel( + selectorNotEdit = selectorNotEdit, + preferences = preferences, + router = router, + indexRepo = indexRepo, + previewStorageRepo = previewStorageRepo, + metadataStorageRepo = metadataStorageRepo, + tagsStorageRepo = tagsStorageRepo, + statsStorageRepo = statsStorageRepo, + scoreStorageRepo = scoreStorageRepo, + analytics = analytics, + ) as T + } + + @AssistedFactory + interface Factory { + fun create( + @Assisted selectorNotEdit: Boolean, + ): GalleryUpliftViewModelFactory + } +} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt new file mode 100644 index 00000000..724f9b5e --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt @@ -0,0 +1,8 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +data class DisplaySelected( + val selected: Boolean, + val showAnim: Boolean, + val selectedCount: Int, + val itemCount: Int, +) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt new file mode 100644 index 00000000..264d9d2e --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt @@ -0,0 +1,6 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +data class ProgressWithText( + val isVisible: Boolean, + val text: String, +) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt new file mode 100644 index 00000000..4bff0194 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt @@ -0,0 +1,5 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +import dev.arkbuilders.arklib.ResourceId + +data class ResourceIdTagsPreview(val resourceId: ResourceId, val tags: Set) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt new file mode 100644 index 00000000..959e2030 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt @@ -0,0 +1,5 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +import dev.arkbuilders.arklib.data.meta.Metadata + +data class SetupPreview(val position: Int, val meta: Metadata) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt new file mode 100644 index 00000000..25271746 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt @@ -0,0 +1,16 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +import dev.arkbuilders.arkfilepicker.folders.RootAndFav +import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.index.ResourceIndex +import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.navigator.data.stats.StatsStorage + +data class ShowEditTagsData( + val resource: ResourceId, + val rootAndFav: RootAndFav, + val resources: List, + val index: ResourceIndex, + val storage: TagStorage, + val statsStorage: StatsStorage +) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt new file mode 100644 index 00000000..ab567cb8 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt @@ -0,0 +1,11 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.meta.Metadata +import java.nio.file.Path + +data class ShowInfoData( + val path: Path, + val resource: Resource, + val metadata: Metadata +) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt new file mode 100644 index 00000000..f2631bbf --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt @@ -0,0 +1,3 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +data class StorageExceptionGallery(val label: String, val messenger: String) From 2e456f9ba6485a4190b675e6212f6ea884352904 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 17:34:52 +0700 Subject: [PATCH 20/74] Update method modifiers --- .../galleryuplift/GalleryUpliftFragment.kt | 139 ++++++------------ 1 file changed, 45 insertions(+), 94 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 239160e9..27d51ed1 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -30,33 +30,23 @@ import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.index.ResourceIndex -import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo -import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo -import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.TagStorage import dev.arkbuilders.arklib.user.tags.Tags -import dev.arkbuilders.arklib.user.tags.TagsStorageRepo import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R -import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics -import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.data.stats.StatsStorage -import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding import dev.arkbuilders.navigator.databinding.PopupGalleryTagMenuBinding -import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase import dev.arkbuilders.navigator.presentation.App import dev.arkbuilders.navigator.presentation.dialog.DetailsAlertDialog import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment -import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import dev.arkbuilders.navigator.presentation.screen.main.MainActivity @@ -67,7 +57,6 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import timber.log.Timber import java.nio.file.Path @@ -78,37 +67,6 @@ import kotlin.system.measureTimeMillis class GalleryUpliftFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) - @Inject - lateinit var preferences: Preferences - - @Inject - lateinit var router: AppRouter - - @Inject - lateinit var indexRepo: ResourceIndexRepo - - @Inject - lateinit var previewStorageRepo: PreviewProcessorRepo - - @Inject - lateinit var metadataStorageRepo: MetadataProcessorRepo - - @Inject - lateinit var tagsStorageRepo: TagsStorageRepo - - @Inject - lateinit var statsStorageRepo: StatsStorageRepo - - @Inject - lateinit var scoreStorageRepo: ScoreStorageRepo - - @Inject - lateinit var handleGalleryExternalChangesUseCase: - HandleGalleryExternalChangesUseCase - - @Inject - lateinit var analytics: GalleryAnalytics - @Inject lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { @@ -116,19 +74,13 @@ class GalleryUpliftFragment : Fragment() { selectorNotEdit = false ) } - - private lateinit var stackedToasts: StackedToasts - private lateinit var pagerAdapter: PreviewsPagerUplift private val scoreWidget by lazy { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } - private fun onBackClick() { - Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") - notifySelectedChanged(viewModel.selectedResources) - exitFullscreen() - viewModel.router.exit() - } + private lateinit var stackedToasts: StackedToasts + private lateinit var pagerAdapter: PreviewsPagerUplift + override fun onCreateView( inflater: LayoutInflater, @@ -138,6 +90,17 @@ class GalleryUpliftFragment : Fragment() { return inflater.inflate(R.layout.fragment_gallery, container, false) } + + override fun onDestroyView() { + super.onDestroyView() + scoreWidget.onDestroyView() + } + + override fun onResume() { + super.onResume() + viewModel.onResume() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) @@ -147,8 +110,6 @@ class GalleryUpliftFragment : Fragment() { .toList() as List ) super.onViewCreated(view, savedInstanceState) - viewModel.onFirstViewAttach() - Timber.d( LogTags.GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}" @@ -222,10 +183,11 @@ class GalleryUpliftFragment : Fragment() { } } - - override fun onDestroyView() { - super.onDestroyView() - scoreWidget.onDestroyView() + private fun onBackClick() { + Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") + notifySelectedChanged(viewModel.selectedResources) + exitFullscreen() + viewModel.router.exit() } private fun collectState() { @@ -403,7 +365,7 @@ class GalleryUpliftFragment : Fragment() { } } - fun updatePagerAdapter() { + private fun updatePagerAdapter() { pagerAdapter.notifyDataSetChanged() binding.viewPager.adapter?.itemCount?.let { count -> val startAt = requireArguments().getInt(START_AT_KEY) @@ -416,11 +378,11 @@ class GalleryUpliftFragment : Fragment() { } } - fun updatePagerAdapterWithDiff() { + private fun updatePagerAdapterWithDiff() { viewModel.diffResult?.dispatchUpdatesTo(pagerAdapter) } - fun setupPreview( + private fun setupPreview( pos: Int, meta: Metadata ) { @@ -437,15 +399,11 @@ class GalleryUpliftFragment : Fragment() { } } -// fun setPreviewsScrollingEnabled(enabled: Boolean) { -// binding.viewPager.isUserInputEnabled = enabled -// } - - fun setControlsVisibility(visible: Boolean) { + private fun setControlsVisibility(visible: Boolean) { binding.previewControls.isVisible = visible } - fun editResource(resourcePath: Path) { + private fun editResource(resourcePath: Path) { val intent = getExternalAppIntent( resourcePath, Intent.ACTION_EDIT, @@ -466,36 +424,36 @@ class GalleryUpliftFragment : Fragment() { } - fun shareResource(resourcePath: Path) = + private fun shareResource(resourcePath: Path) = openIntentChooser( resourcePath, Intent.ACTION_SEND, detachProcess = false ) - fun openLink(link: String) { + private fun openLink(link: String) { val intent = Intent(Intent.ACTION_VIEW) val uri = Uri.parse(link) intent.data = uri startActivity(Intent.createChooser(intent, "View the link with:")) } - fun shareLink(link: String) { + private fun shareLink(link: String) { val intent = Intent(Intent.ACTION_SEND) intent.putExtra(Intent.EXTRA_TEXT, link) intent.type = "text/plain" startActivity(Intent.createChooser(intent, "Share the link with:")) } - fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { + private fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { DetailsAlertDialog(path, resource, metadata, requireContext()).show() } - fun viewInExternalApp(resourcePath: Path) { + private fun viewInExternalApp(resourcePath: Path) { openIntentChooser(resourcePath, Intent.ACTION_VIEW, true) } - fun deleteResource(pos: Int) { + private fun deleteResource(pos: Int) { binding.viewPager.apply { setPageTransformer(null) pagerAdapter.notifyItemRemoved(pos) @@ -505,49 +463,48 @@ class GalleryUpliftFragment : Fragment() { } } - fun displayStorageException(label: String, msg: String) { + private fun displayStorageException(label: String, msg: String) { StorageExceptionDialogFragment.newInstance(label, msg).show( childFragmentManager, StorageExceptionDialogFragment.TAG ) } - fun notifyResourcesChanged() { + private fun notifyResourcesChanged() { setFragmentResult(REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) } - fun notifyTagsChanged() { + private fun notifyTagsChanged() { setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) } - fun notifyResourceScoresChanged() { + private fun notifyResourceScoresChanged() { setFragmentResult(SCORES_CHANGED_KEY, bundleOf()) } - fun notifySelectedChanged( + private fun notifySelectedChanged( selected: List ) { setFragmentResult( - GalleryFragment.SELECTED_CHANGED_KEY, + SELECTED_CHANGED_KEY, bundleOf().apply { putBoolean( - GalleryFragment.SELECTING_ENABLED_KEY, - requireArguments().getBoolean(GalleryFragment.SELECTING_ENABLED_KEY) + SELECTING_ENABLED_KEY, + requireArguments().getBoolean(SELECTING_ENABLED_KEY) ) putParcelableArray( - GalleryFragment.SELECTED_RESOURCES_KEY, + SELECTED_RESOURCES_KEY, selected.toTypedArray() ) } ) } - fun toastIndexFailedPath(path: Path) { + private fun toastIndexFailedPath(path: Path) { stackedToasts.toast(path) } - - fun displayPreviewTags(resource: ResourceId, tags: Tags) { + private fun displayPreviewTags(resource: ResourceId, tags: Tags) { lifecycleScope.launch { Timber.d( LogTags.GALLERY_SCREEN, @@ -614,19 +571,19 @@ class GalleryUpliftFragment : Fragment() { } } - fun exitFullscreen() { + private fun exitFullscreen() { FullscreenHelper.setStatusBarVisibility(true, requireActivity().window) (requireActivity() as MainActivity).setBottomNavigationVisibility(true) } - fun notifyCurrentItemChanged() { + private fun notifyCurrentItemChanged() { binding.viewPager.post { pagerAdapter.notifyItemChanged(binding.viewPager.currentItem) } } - fun displaySelected( + private fun displaySelected( selected: Boolean, showAnim: Boolean, selectedCount: Int, @@ -641,12 +598,7 @@ class GalleryUpliftFragment : Fragment() { return@with } - override fun onResume() { - super.onResume() - viewModel.onResume() - } - - fun toggleSelecting(enabled: Boolean) { + private fun toggleSelecting(enabled: Boolean) { binding.layoutSelected.isVisible = enabled binding.fabStartSelect.isVisible = !enabled requireArguments().apply { @@ -867,5 +819,4 @@ class GalleryUpliftFragment : Fragment() { } } } - } From 325df2c27caca4f3edada23624e5b3a533bc6a97 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 17:35:09 +0700 Subject: [PATCH 21/74] Update method modifiers --- .../galleryuplift/GalleryUpliftViewModel.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index e702b072..d48dcd42 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -71,15 +71,11 @@ class GalleryUpliftViewModel( val analytics: GalleryAnalytics, ) : ViewModel() { private val messageFlow: MutableSharedFlow = MutableSharedFlow() - lateinit var index: ResourceIndex - private set - lateinit var tagsStorage: TagStorage - private set + private lateinit var index: ResourceIndex + private lateinit var tagsStorage: TagStorage private lateinit var previewStorage: PreviewProcessor - lateinit var metadataStorage: MetadataProcessor - private set - lateinit var statsStorage: StatsStorage - private set + private lateinit var metadataStorage: MetadataProcessor + private lateinit var statsStorage: StatsStorage private lateinit var scoreStorage: ScoreStorage var galleryItems: MutableList = mutableListOf() @@ -196,6 +192,7 @@ class GalleryUpliftViewModel( ) { this.rootAndFav = rootAndFav this.resourcesIds = resourcesIds + onFirstViewAttach() } fun onPreviewsItemClick() { @@ -258,7 +255,8 @@ class GalleryUpliftViewModel( index.updateAll() _notifyResourceChange.value = true } - fun onFirstViewAttach() { + + private fun onFirstViewAttach() { analytics.trackScreen() Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { From 4158e9f9cc3882f8b3d817f7a232269d3d190af6 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 17:37:59 +0700 Subject: [PATCH 22/74] Reorder properties --- .../galleryuplift/GalleryUpliftViewModel.kt | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index d48dcd42..4a81face 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -70,23 +70,32 @@ class GalleryUpliftViewModel( val scoreStorageRepo: ScoreStorageRepo, val analytics: GalleryAnalytics, ) : ViewModel() { - private val messageFlow: MutableSharedFlow = MutableSharedFlow() private lateinit var index: ResourceIndex private lateinit var tagsStorage: TagStorage private lateinit var previewStorage: PreviewProcessor private lateinit var metadataStorage: MetadataProcessor private lateinit var statsStorage: StatsStorage private lateinit var scoreStorage: ScoreStorage + private lateinit var rootAndFav: RootAndFav + private lateinit var resourcesIds: List var galleryItems: MutableList = mutableListOf() - var diffResult: DiffUtil.DiffResult? = null - private var currentPos = 0 val selectedResources: MutableList = mutableListOf() + val scoreWidgetController = ScoreWidgetController( + scope = viewModelScope, + getCurrentId = { currentItem.id() }, + onScoreChanged = { + _notifyResourceScoresChanged.value = true + } + ) - private lateinit var rootAndFav: RootAndFav - private lateinit var resourcesIds: List + private var currentPos = 0 + private var sortByScores = false + private var selectingEnabled: Boolean = false + + private val messageFlow: MutableSharedFlow = MutableSharedFlow() private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] @@ -106,17 +115,6 @@ class GalleryUpliftViewModel( private val _deleteResource: MutableStateFlow = MutableStateFlow(null) val deleteResource: StateFlow = _deleteResource - val scoreWidgetController = ScoreWidgetController( - scope = viewModelScope, - getCurrentId = { currentItem.id() }, - onScoreChanged = { - _notifyResourceScoresChanged.value = true - } - ) - - private var sortByScores = false - private var selectingEnabled: Boolean = false - private val _toastIndexFailedPath: MutableStateFlow = MutableStateFlow(null) val toastIndexFailedPath: StateFlow = _toastIndexFailedPath From cf98ddf621ee32de3b72dde88fb6a752f697834f Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 13 Apr 2024 20:20:52 +0700 Subject: [PATCH 23/74] Use backing field --- .../galleryuplift/GalleryUpliftFragment.kt | 1 + .../galleryuplift/GalleryUpliftViewModel.kt | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 27d51ed1..6adeaf2b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -74,6 +74,7 @@ class GalleryUpliftFragment : Fragment() { selectorNotEdit = false ) } + private val scoreWidget by lazy { ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 4a81face..d72c1706 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -82,7 +82,9 @@ class GalleryUpliftViewModel( var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null - val selectedResources: MutableList = mutableListOf() + private val _selectedResources: MutableList = mutableListOf() + val selectedResources: List = _selectedResources + val scoreWidgetController = ScoreWidgetController( scope = viewModelScope, getCurrentId = { currentItem.id() }, @@ -353,9 +355,9 @@ class GalleryUpliftViewModel( viewModelScope.launch { selectingEnabled = !selectingEnabled _toggleSelect.emit(selectingEnabled) - selectedResources.clear() + _selectedResources.clear() if (selectingEnabled) { - selectedResources.add(currentItem.resource.id) + _selectedResources.add(currentItem.resource.id) } } } @@ -390,18 +392,18 @@ class GalleryUpliftViewModel( fun onSelectBtnClick() { val id = currentItem.id() - val wasSelected = id in selectedResources + val wasSelected = id in _selectedResources if (wasSelected) { - selectedResources.remove(id) + _selectedResources.remove(id) } else { - selectedResources.add(id) + _selectedResources.add(id) } _displaySelected.value = DisplaySelected( selected = !wasSelected, showAnim = true, - selectedCount = selectedResources.size, + selectedCount = _selectedResources.size, itemCount = galleryItems.size ) } @@ -493,9 +495,9 @@ class GalleryUpliftViewModel( scoreWidgetController.displayScore() _displaySelected.value = DisplaySelected( - selected = id in selectedResources, + selected = id in _selectedResources, showAnim = false, - selectedCount = selectedResources.size, + selectedCount = _selectedResources.size, itemCount = galleryItems.size, ) } From d2d222a720c25e4d9a432345b69fc07f4ebc59bc Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 1 Jun 2024 22:17:58 +0700 Subject: [PATCH 24/74] Create state and side effect --- .../galleryuplift/state/GalleryState.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt new file mode 100644 index 00000000..e0adc272 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -0,0 +1,46 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state + +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressWithText +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowInfoData +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery +import java.nio.file.Path + +data class GalleryState( + val currentPos: Int = 0, + val sortByScores: Boolean = false, + val selectingEnabled: Boolean = false, +) + +sealed class GallerySideEffect { + data class Progress(val text: String) : GallerySideEffect() + data object NotifyResourceScoresChanged : GallerySideEffect() + data class ControlVisible(val isVisible: Boolean) : GallerySideEffect() + data object NavigateBack : GallerySideEffect() + data object DeleteResource : GallerySideEffect() + data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() + data class ShowInfoAlert(val infoData: ShowInfoData) : GallerySideEffect() + data class DisplayStorageException(val storageException: StorageExceptionGallery) : + GallerySideEffect() + + data object UpdatePagerAdapter : GallerySideEffect() + data class ShareLink(val url: String) : GallerySideEffect() + data class ShareResource(val path: Path) : GallerySideEffect() + data class EditResource(val path: Path) : GallerySideEffect() + data class OpenLink(val url: String) : GallerySideEffect() + data class ViewInExternalApp(val path: Path) : GallerySideEffect() + data class DisplayPreviewTags(val data: ResourceIdTagsPreview) : + GallerySideEffect() + + data object NotifyTagsChanged : GallerySideEffect() + data class ShowEditTagsDialog(val data: ShowEditTagsData) : GallerySideEffect() + data class SetUpPreview(val data: SetupPreview) : GallerySideEffect() + data class DisplaySelectedFile(val data: DisplaySelected) : GallerySideEffect() + data object NotifyResourceChange: GallerySideEffect() + data class ShowProgressWithText(val text: ProgressWithText): GallerySideEffect() + data object NotifyCurrentItemChange: GallerySideEffect() + data object UpdatePagerAdapterWithDiff: GallerySideEffect() +} From c816b6fb649d14b82de093d2fe98a71c494bde19 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sat, 1 Jun 2024 22:25:04 +0700 Subject: [PATCH 25/74] Extract state to side effect --- .../galleryuplift/GalleryUpliftViewModel.kt | 554 +++++++++++++----- 1 file changed, 394 insertions(+), 160 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index d72c1706..8d3e59e4 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -40,9 +40,12 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domai import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowInfoData import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.async import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -51,6 +54,12 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.orbitmvi.orbit.Container +import org.orbitmvi.orbit.ContainerHost +import org.orbitmvi.orbit.syntax.simple.intent +import org.orbitmvi.orbit.syntax.simple.postSideEffect +import org.orbitmvi.orbit.syntax.simple.reduce +import org.orbitmvi.orbit.viewmodel.container import timber.log.Timber import java.io.FileReader import java.nio.file.Files @@ -69,7 +78,7 @@ class GalleryUpliftViewModel( val statsStorageRepo: StatsStorageRepo, val scoreStorageRepo: ScoreStorageRepo, val analytics: GalleryAnalytics, -) : ViewModel() { +) : ContainerHost, ViewModel() { private lateinit var index: ResourceIndex private lateinit var tagsStorage: TagStorage private lateinit var previewStorage: PreviewProcessor @@ -79,6 +88,9 @@ class GalleryUpliftViewModel( private lateinit var rootAndFav: RootAndFav private lateinit var resourcesIds: List + override val container: Container = + container(GalleryState()) + var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null @@ -89,7 +101,10 @@ class GalleryUpliftViewModel( scope = viewModelScope, getCurrentId = { currentItem.id() }, onScoreChanged = { - _notifyResourceScoresChanged.value = true +// _notifyResourceScoresChanged.value = true + intent { + postSideEffect(GallerySideEffect.NotifyResourceScoresChanged) + } } ) @@ -101,90 +116,90 @@ class GalleryUpliftViewModel( private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[currentPos] - private val _notifyResourceScoresChanged: MutableStateFlow = - MutableStateFlow(false) - val notifyResourceScoresChanged: StateFlow = - _notifyResourceScoresChanged +// private val _notifyResourceScoresChanged: MutableStateFlow = +// MutableStateFlow(false) +// val notifyResourceScoresChanged: StateFlow = +// _notifyResourceScoresChanged - private val _setControlsVisibility: MutableStateFlow = - MutableStateFlow(false) - val setControlsVisibility: StateFlow = - _setControlsVisibility +// private val _setControlsVisibility: MutableStateFlow = +// MutableStateFlow(false) +// val setControlsVisibility: StateFlow = +// _setControlsVisibility - private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) - val onNavigateBack: StateFlow = _onNavigateBack +// private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) +// val onNavigateBack: StateFlow = _onNavigateBack - private val _deleteResource: MutableStateFlow = MutableStateFlow(null) - val deleteResource: StateFlow = _deleteResource +// private val _deleteResource: MutableStateFlow = MutableStateFlow(null) +// val deleteResource: StateFlow = _deleteResource - private val _toastIndexFailedPath: MutableStateFlow = - MutableStateFlow(null) - val toastIndexFailedPath: StateFlow = _toastIndexFailedPath +// private val _toastIndexFailedPath: MutableStateFlow = +// MutableStateFlow(null) +// val toastIndexFailedPath: StateFlow = _toastIndexFailedPath - private val _showInfoAlert: MutableStateFlow = - MutableStateFlow(null) - val showInfoAlert: StateFlow = _showInfoAlert +// private val _showInfoAlert: MutableStateFlow = +// MutableStateFlow(null) +// val showInfoAlert: StateFlow = _showInfoAlert - private val _displayStorageException: MutableStateFlow = - MutableStateFlow(null) - val displayStorageException: StateFlow = - _displayStorageException +// private val _displayStorageException: MutableStateFlow = +// MutableStateFlow(null) +// val displayStorageException: StateFlow = +// _displayStorageException - private val _updatePagerAdapter: MutableStateFlow = - MutableStateFlow(false) - val updatePagerAdapter: StateFlow = _updatePagerAdapter +// private val _updatePagerAdapter: MutableStateFlow = +// MutableStateFlow(false) +// val updatePagerAdapter: StateFlow = _updatePagerAdapter - private val _shareLink: MutableStateFlow = MutableStateFlow("") - val shareLink: StateFlow = _shareLink +// private val _shareLink: MutableStateFlow = MutableStateFlow("") +// val shareLink: StateFlow = _shareLink - private val _shareResource: MutableStateFlow = MutableStateFlow(null) - val shareResource: StateFlow = _shareResource +// private val _shareResource: MutableStateFlow = MutableStateFlow(null) +// val shareResource: StateFlow = _shareResource - private val _editResource: MutableStateFlow = MutableStateFlow(null) - val editResource: StateFlow = _editResource +// private val _editResource: MutableStateFlow = MutableStateFlow(null) +// val editResource: StateFlow = _editResource - private val _openLink: MutableStateFlow = MutableStateFlow("") - val openLink: StateFlow = _openLink +// private val _openLink: MutableStateFlow = MutableStateFlow("") +// val openLink: StateFlow = _openLink - private val _viewInExternalApp: MutableStateFlow = - MutableStateFlow(null) - val viewInExternalApp: StateFlow = _viewInExternalApp +// private val _viewInExternalApp: MutableStateFlow = +// MutableStateFlow(null) +// val viewInExternalApp: StateFlow = _viewInExternalApp - private val _displayPreviewTags: MutableStateFlow = - MutableStateFlow(null) - val displayPreviewTags: StateFlow = _displayPreviewTags +// private val _displayPreviewTags: MutableStateFlow = +// MutableStateFlow(null) +// val displayPreviewTags: StateFlow = _displayPreviewTags - private val _notifyTagsChanged: MutableStateFlow = - MutableStateFlow(false) - val notifyTagsChanged: StateFlow = _notifyTagsChanged +// private val _notifyTagsChanged: MutableStateFlow = +// MutableStateFlow(false) +// val notifyTagsChanged: StateFlow = _notifyTagsChanged - private val _showEditTagsDialog: MutableStateFlow = - MutableStateFlow(null) - val showEditTagsDialog: StateFlow = _showEditTagsDialog +// private val _showEditTagsDialog: MutableStateFlow = +// MutableStateFlow(null) +// val showEditTagsDialog: StateFlow = _showEditTagsDialog - private val _setUpPreview: MutableStateFlow = - MutableStateFlow(null) - val setUpPreview: StateFlow = _setUpPreview +// private val _setUpPreview: MutableStateFlow = +// MutableStateFlow(null) +// val setUpPreview: StateFlow = _setUpPreview - private val _displaySelected: MutableStateFlow = - MutableStateFlow(null) - val displaySelected: StateFlow = _displaySelected +// private val _displaySelected: MutableStateFlow = +// MutableStateFlow(null) +// val displaySelected: StateFlow = _displaySelected - private val _notifyResourceChange: MutableStateFlow = - MutableStateFlow(false) - val notifyResourceChange: StateFlow = _notifyResourceChange +// private val _notifyResourceChange: MutableStateFlow = +// MutableStateFlow(false) +// val notifyResourceChange: StateFlow = _notifyResourceChange - private val _showProgressWithText: MutableStateFlow = - MutableStateFlow(null) - val showProgressWithText: StateFlow = _showProgressWithText +// private val _showProgressWithText: MutableStateFlow = +// MutableStateFlow(null) +// val showProgressWithText: StateFlow = _showProgressWithText - private val _notifyCurrentItemChange: MutableStateFlow = - MutableStateFlow(false) - val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange +// private val _notifyCurrentItemChange: MutableStateFlow = +// MutableStateFlow(false) +// val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange - private val _updatePagerAdapterWithDiff: MutableStateFlow = - MutableStateFlow(false) - val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff +// private val _updatePagerAdapterWithDiff: MutableStateFlow = +// MutableStateFlow(false) +// val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff fun initialize( rootAndFav: RootAndFav, @@ -196,7 +211,10 @@ class GalleryUpliftViewModel( } fun onPreviewsItemClick() { - _setControlsVisibility.value = !_setControlsVisibility.value + intent { + postSideEffect(GallerySideEffect.ControlVisible(isVisible = true)) + } +// _setControlsVisibility.value = !_setControlsVisibility.value } fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) { @@ -234,13 +252,18 @@ class GalleryUpliftViewModel( galleryItems.removeAt(currentPos) if (galleryItems.isEmpty()) { - _onNavigateBack.emit(true) + intent { + postSideEffect(GallerySideEffect.NavigateBack) + } +// _onNavigateBack.emit(true) return@launch } onTagsChanged() - _deleteResource.value = currentPos - +// _deleteResource.value = currentPos + intent { + postSideEffect(GallerySideEffect.DeleteResource) + } } private suspend fun deleteResource(resource: ResourceId) { @@ -253,47 +276,98 @@ class GalleryUpliftViewModel( } index.updateAll() - _notifyResourceChange.value = true + intent { + postSideEffect(GallerySideEffect.NotifyResourceChange) + } +// _notifyResourceChange.value = true } private fun onFirstViewAttach() { analytics.trackScreen() Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Providing root index", - ) + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing root index", + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Providing root index", +// ) index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { is Message.KindDetectFailed -> - _toastIndexFailedPath.value = message.path + intent { + postSideEffect( + GallerySideEffect.ToastIndexFailedPath( + message.path + ) + ) + } +// _toastIndexFailedPath.value = message.path } }.launchIn(viewModelScope) - - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Providing metadata storage", - ) + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing metadata storage", + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Providing metadata storage", +// ) metadataStorage = metadataStorageRepo.provide(index) - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Providing previews storage", - ) + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing previews storage", + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Providing previews storage", +// ) previewStorage = previewStorageRepo.provide(index) - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Providing data storage", - ) + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing data storage", + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Providing data storage", +// ) try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) } catch (e: StorageException) { - _displayStorageException.value = StorageExceptionGallery( - label = e.label, - messenger = e.msg - ) + intent { + postSideEffect( + GallerySideEffect.DisplayStorageException( + StorageExceptionGallery( + label = e.label, + messenger = e.msg + ) + ) + ) + } +// _displayStorageException.value = StorageExceptionGallery( +// label = e.label, +// messenger = e.msg +// ) } statsStorage = statsStorageRepo.provide(index) @@ -301,19 +375,39 @@ class GalleryUpliftViewModel( galleryItems = provideGalleryItems().toMutableList() - sortByScores = preferences.get(PreferenceKey.SortByScores) - _updatePagerAdapter.value = true + intent { + reduce { + viewModelScope.launch { + state.copy(sortByScores = preferences.get(PreferenceKey.SortByScores)) + } + state + } + postSideEffect( + GallerySideEffect.UpdatePagerAdapter + ) + } +// sortByScores = preferences.get(PreferenceKey.SortByScores) +// _updatePagerAdapter.value = true - _showProgressWithText.value = ProgressWithText( - isVisible = false, - text = "" - ) + + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "", + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = false, +// text = "" +// ) scoreWidgetController.setVisible(sortByScores) } } - fun onPlayButtonClick() = viewModelScope.launch { - _viewInExternalApp.value = index.getPath(currentItem.id())!! + fun onPlayButtonClick() = intent { + postSideEffect(GallerySideEffect.ViewInExternalApp(index.getPath(currentItem.id())!!)) } fun onInfoFabClick() = viewModelScope.launch { @@ -329,7 +423,10 @@ class GalleryUpliftViewModel( resource = currentItem.resource, metadata = currentItem.metadata ) - _showInfoAlert.emit(data) + intent { + postSideEffect(GallerySideEffect.ShowInfoAlert(data)) + } +// _showInfoAlert.emit(data) } @@ -343,17 +440,28 @@ class GalleryUpliftViewModel( if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - _shareLink.emit(url) + intent { + postSideEffect(GallerySideEffect.ShareLink(url)) + } +// _shareLink.emit(url) return@launch } - _shareResource.emit(path) + intent { + postSideEffect(GallerySideEffect.ShareResource(path)) + } +// _shareResource.emit(path) } private val _toggleSelect: MutableStateFlow = MutableStateFlow(false) val toggleSelect: StateFlow = _toggleSelect fun onSelectingChanged() { viewModelScope.launch { - selectingEnabled = !selectingEnabled + intent { + reduce { + state.copy(selectingEnabled = !state.selectingEnabled) + } + } +// selectingEnabled = !selectingEnabled _toggleSelect.emit(selectingEnabled) _selectedResources.clear() if (selectingEnabled) { @@ -374,10 +482,22 @@ class GalleryUpliftViewModel( if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - _openLink.emit(url) + intent { + postSideEffect(GallerySideEffect.OpenLink(url)) + } +// _openLink.emit(url) return@launch } - _viewInExternalApp.emit(path) + intent { + postSideEffect( + GallerySideEffect.ViewInExternalApp( + index.getPath( + currentItem.id() + )!! + ) + ) + } +// _viewInExternalApp.emit(path) } fun onEditFabClick() = viewModelScope.launch { @@ -387,7 +507,10 @@ class GalleryUpliftViewModel( "[edit_resource] clicked at position $currentPos" ) val path = index.getPath(currentItem.id())!! - _editResource.emit(path) +// _editResource.emit(path) + intent { + postSideEffect(GallerySideEffect.EditResource(path)) + } } fun onSelectBtnClick() { @@ -400,12 +523,24 @@ class GalleryUpliftViewModel( _selectedResources.add(id) } - _displaySelected.value = DisplaySelected( - selected = !wasSelected, - showAnim = true, - selectedCount = _selectedResources.size, - itemCount = galleryItems.size - ) + intent { + postSideEffect( + GallerySideEffect.DisplaySelectedFile( + DisplaySelected( + selected = !wasSelected, + showAnim = true, + selectedCount = _selectedResources.size, + itemCount = galleryItems.size + ) + ) + ) + } +// _displaySelected.value = DisplaySelected( +// selected = !wasSelected, +// showAnim = true, +// selectedCount = _selectedResources.size, +// itemCount = galleryItems.size +// ) } fun onResume() { @@ -413,11 +548,21 @@ class GalleryUpliftViewModel( } fun onTagsChanged() { - val tags = tagsStorage.getTags(currentItem.id()) - _displayPreviewTags.value = ResourceIdTagsPreview( - resourceId = currentItem.id(), - tags = tags, - ) + intent { + val tags = tagsStorage.getTags(currentItem.id()) + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = currentItem.id(), + tags = tags, + ) + ) + ) + } +// _displayPreviewTags.value = ResourceIdTagsPreview( +// resourceId = currentItem.id(), +// tags = tags, +// ) } fun onPageChanged(newPos: Int) = viewModelScope.launch { @@ -426,8 +571,13 @@ class GalleryUpliftViewModel( checkResourceChanges(newPos) - currentPos = newPos +// currentPos = newPos + intent { + reduce { + state.copy(currentPos = newPos) + } + } val id = currentItem.id() val tags = tagsStorage.getTags(id) displayPreview(id, currentItem.metadata, tags) @@ -449,10 +599,20 @@ class GalleryUpliftViewModel( val tags = tagsStorage.getTags(id) val newTags = tags - tag - _displayPreviewTags.value = ResourceIdTagsPreview( - resourceId = id, - tags = newTags, - ) +// _displayPreviewTags.value = ResourceIdTagsPreview( +// resourceId = id, +// tags = newTags, +// ) + intent { + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = id, + tags = newTags, + ) + ) + ) + } statsStorage.handleEvent( StatsEvent.TagsChanged( id, tags, newTags @@ -463,19 +623,36 @@ class GalleryUpliftViewModel( tagsStorage.setTags(id, newTags) tagsStorage.persist() - _notifyTagsChanged.value = true + intent { + postSideEffect(GallerySideEffect.NotifyTagsChanged) + } +// _notifyTagsChanged.value = true } fun onEditTagsDialogBtnClick() { analytics.trackTagsEdit() - _showEditTagsDialog.value = ShowEditTagsData( - resource = currentItem.id(), - resources = listOf(currentItem.id()), - statsStorage = statsStorage, - rootAndFav = rootAndFav, - index = index, - storage = tagsStorage, - ) + intent { + postSideEffect( + GallerySideEffect.ShowEditTagsDialog( + ShowEditTagsData( + resource = currentItem.id(), + resources = listOf(currentItem.id()), + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = tagsStorage, + ) + ) + ) + } +// _showEditTagsDialog.value = ShowEditTagsData( +// resource = currentItem.id(), +// resources = listOf(currentItem.id()), +// statsStorage = statsStorage, +// rootAndFav = rootAndFav, +// index = index, +// storage = tagsStorage, +// ) } private fun displayPreview( @@ -483,23 +660,55 @@ class GalleryUpliftViewModel( meta: Metadata, tags: Tags ) { - _setUpPreview.value = SetupPreview( - position = currentPos, - meta = meta, - ) - - _displayPreviewTags.value = ResourceIdTagsPreview( - resourceId = id, - tags = tags, - ) + intent { + postSideEffect( + GallerySideEffect.SetUpPreview( + SetupPreview( + position = currentPos, + meta = meta, + ) + ) + ) + } +// _setUpPreview.value = SetupPreview( +// position = currentPos, +// meta = meta, +// ) + + intent { + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = id, + tags = tags, + ) + ) + ) + } +// _displayPreviewTags.value = ResourceIdTagsPreview( +// resourceId = id, +// tags = tags, +// ) scoreWidgetController.displayScore() - _displaySelected.value = DisplaySelected( - selected = id in _selectedResources, - showAnim = false, - selectedCount = _selectedResources.size, - itemCount = galleryItems.size, - ) + intent { + postSideEffect( + GallerySideEffect.DisplaySelectedFile( + DisplaySelected( + selected = id in _selectedResources, + showAnim = false, + selectedCount = _selectedResources.size, + itemCount = galleryItems.size, + ) + ) + ) + } +// _displaySelected.value = DisplaySelected( +// selected = id in _selectedResources, +// showAnim = false, +// selectedCount = _selectedResources.size, +// itemCount = galleryItems.size, +// ) } private fun checkResourceChanges(pos: Int) = @@ -552,18 +761,29 @@ class GalleryUpliftViewModel( private fun invokeHandleGalleryExternalChangesUseCase( ) { viewModelScope.launch { - withContext(Dispatchers.Main) { - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" - ) +// withContext(Dispatchers.Main) { +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Changes detected, indexing" +// ) +// } + intent { + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) + )) } index.updateAll() - withContext(Dispatchers.Main) { - _notifyResourceChange.value = true + intent { + postSideEffect(GallerySideEffect.NotifyResourceChange) } +// withContext(Dispatchers.Main) { +// _notifyResourceChange.value = true +// } viewModelScope.launch { metadataStorage.busy.collect { busy -> @@ -573,7 +793,10 @@ class GalleryUpliftViewModel( val newItems = provideGalleryItems() if (newItems.isEmpty()) { - _onNavigateBack.value = true + intent { + postSideEffect(GallerySideEffect.NavigateBack) + } +// _onNavigateBack.value = true return@launch } @@ -588,11 +811,22 @@ class GalleryUpliftViewModel( viewModelScope.launch { _updatePagerAdapterWithDiff.value = true - _notifyCurrentItemChange.value = true - _showProgressWithText.value = ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" - ) + +// _notifyCurrentItemChange.value = true + intent { + postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) + postSideEffect(GallerySideEffect.NotifyCurrentItemChange) + postSideEffect(GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) + )) + } +// _showProgressWithText.value = ProgressWithText( +// isVisible = true, +// text = "Changes detected, indexing" +// ) } } } From 9b1d6652629873967b2409449cc9b3163e393586 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 10:58:02 +0700 Subject: [PATCH 26/74] Remove unused state, update state param --- .../screen/gallery/galleryuplift/state/GalleryState.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index e0adc272..d29b5d26 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -16,11 +16,10 @@ data class GalleryState( ) sealed class GallerySideEffect { - data class Progress(val text: String) : GallerySideEffect() data object NotifyResourceScoresChanged : GallerySideEffect() data class ControlVisible(val isVisible: Boolean) : GallerySideEffect() data object NavigateBack : GallerySideEffect() - data object DeleteResource : GallerySideEffect() + data class DeleteResource(val pos: Int) : GallerySideEffect() data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() data class ShowInfoAlert(val infoData: ShowInfoData) : GallerySideEffect() data class DisplayStorageException(val storageException: StorageExceptionGallery) : From 1780a154ce3cebe55f27397b4dd02f7b847f22e1 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 10:58:33 +0700 Subject: [PATCH 27/74] Temporarily replace flow by side effect --- .../galleryuplift/GalleryUpliftFragment.kt | 393 ++++++++++-------- 1 file changed, 221 insertions(+), 172 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 6adeaf2b..c0430861 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -49,6 +49,8 @@ import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragm import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader @@ -58,6 +60,7 @@ import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts import kotlinx.coroutines.launch +import org.orbitmvi.orbit.viewmodel.observe import timber.log.Timber import java.nio.file.Path import javax.inject.Inject @@ -182,6 +185,52 @@ class GalleryUpliftFragment : Fragment() { return@setOnLongClickListener true } } + viewModel.observe( + lifecycleOwner = this, + state = ::render, + sideEffect = ::handleSideEffect + ) + } + + private fun handleSideEffect(sideEffect: GallerySideEffect) { + with(sideEffect) { + when (this) { + is GallerySideEffect.ControlVisible -> setControlsVisibility(isVisible) + is GallerySideEffect.DeleteResource -> deleteResource(pos) + is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags(data.resourceId, data.tags) + is GallerySideEffect.DisplaySelectedFile -> displaySelected(data.selected, data.showAnim, data.selectedCount, data.itemCount) + is GallerySideEffect.DisplayStorageException -> displayStorageException(storageException.label, storageException.messenger) + is GallerySideEffect.EditResource -> editResource(path) + GallerySideEffect.NavigateBack -> onBackClick() + GallerySideEffect.NotifyCurrentItemChange -> notifyCurrentItemChanged() + GallerySideEffect.NotifyResourceChange -> notifyResourcesChanged() + GallerySideEffect.NotifyResourceScoresChanged -> notifyResourceScoresChanged() + GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() + is GallerySideEffect.OpenLink -> openLink(url) + is GallerySideEffect.SetUpPreview -> setupPreview(data.position, data.meta) + is GallerySideEffect.ShareLink -> shareLink(url) + is GallerySideEffect.ShareResource -> shareResource(path) + is GallerySideEffect.ShowEditTagsDialog -> showEditTagsDialog( + resource = data.resource, + resources = data.resources, + statsStorage = data.statsStorage, + rootAndFav = data.rootAndFav, + index = data.index, + storage = data.storage, + ) + is GallerySideEffect.ShowInfoAlert -> showInfoAlert(infoData.path, infoData.resource, infoData.metadata) + is GallerySideEffect.ShowProgressWithText -> setProgressVisibility(text.isVisible, text.text) + is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath(path) + GallerySideEffect.UpdatePagerAdapter -> updatePagerAdapter() + GallerySideEffect.UpdatePagerAdapterWithDiff -> updatePagerAdapterWithDiff() + is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) + } + } + } + + + private fun render(state: GalleryState) { + setControlsVisibility(state.selectingEnabled) } private fun onBackClick() { @@ -192,178 +241,178 @@ class GalleryUpliftFragment : Fragment() { } private fun collectState() { - viewLifecycleOwner.lifecycleScope.launch { - repeatOnLifecycle(Lifecycle.State.STARTED) { - launch { - viewModel.showInfoAlert.collect { data -> - data?.let { - showInfoAlert(it.path, it.resource, it.metadata) - } - } - } - launch { - viewModel.shareLink.collect { - if (it.isNotEmpty()) { - shareLink(it) - } - } - } - launch { - viewModel.shareResource.collect { path -> - path?.let { - shareResource(path) - } - } - } - launch { - viewModel.toggleSelect.collect { - toggleSelecting(it) - } - } - launch { - viewModel.openLink.collect { - if (it.isNotEmpty()) { - openLink(it) - } - } - } - launch { - viewModel.viewInExternalApp.collect { path -> - path?.let { - viewInExternalApp(it) - } - } - } - launch { - viewModel.editResource.collect { path -> - path?.let { - editResource(it) - } - } - } - launch { - viewModel.notifyResourceChange.collect { - notifyResourcesChanged() - } - } - launch { - viewModel.displayPreviewTags.collect { - if (it != null) { - displayPreviewTags(it.resourceId, it.tags) - } - } - } - launch { - viewModel.notifyCurrentItemChange.collect { - if (it) { - notifyCurrentItemChanged() - } - } - } - launch { - viewModel.updatePagerAdapterWithDiff.collect { - if (it) { - updatePagerAdapterWithDiff() - } - } - } - launch { - viewModel.displaySelected.collect { - it?.let { - displaySelected( - selected = it.selected, - showAnim = it.showAnim, - selectedCount = it.selectedCount, - itemCount = viewModel.galleryItems.size - ) - } - } - } - launch { - viewModel.toastIndexFailedPath.collect { - it?.let { - toastIndexFailedPath(it) - } - } - } - launch { - viewModel.notifyResourceScoresChanged.collect { - if (it) { - notifyResourceScoresChanged() - } - } - } - launch { - viewModel.updatePagerAdapter.collect { - updatePagerAdapter() - } - } - launch { - viewModel.setControlsVisibility.collect { - setControlsVisibility(it) - } - } - launch { - viewModel.onNavigateBack.collect { - if (it) { - onBackClick() - } - } - } - launch { - viewModel.deleteResource.collect { - it?.let { - deleteResource(it) - } - } - } - launch { - viewModel.setUpPreview.collect { - it?.let { - setupPreview(it.position, it.meta) - } - } - } - launch { - viewModel.showEditTagsDialog.collect { - it?.let { - showEditTagsDialog( - resource = it.resource, - resources = it.resources, - statsStorage = it.statsStorage, - rootAndFav = it.rootAndFav, - index = it.index, - storage = it.storage, - ) - } - } - } - launch { - viewModel.displayStorageException.collect { - it?.let { - displayStorageException(it.label, it.messenger) - } - } - } - launch { - viewModel.notifyTagsChanged.collect { - if (it) { - notifyTagsChanged() - } - } - } - launch { - viewModel.showProgressWithText.collect { - it?.let { - setProgressVisibility( - isVisible = it.isVisible, - withText = it.text - ) - } - } - } - } - } +// viewLifecycleOwner.lifecycleScope.launch { +// repeatOnLifecycle(Lifecycle.State.STARTED) { +// launch { +// viewModel.showInfoAlert.collect { data -> +// data?.let { +// showInfoAlert(it.path, it.resource, it.metadata) +// } +// } +// } +// launch { +// viewModel.shareLink.collect { +// if (it.isNotEmpty()) { +// shareLink(it) +// } +// } +// } +// launch { +// viewModel.shareResource.collect { path -> +// path?.let { +// shareResource(path) +// } +// } +// } +// launch { +// viewModel.toggleSelect.collect { +// toggleSelecting(it) +// } +// } +// launch { +// viewModel.openLink.collect { +// if (it.isNotEmpty()) { +// openLink(it) +// } +// } +// } +// launch { +// viewModel.viewInExternalApp.collect { path -> +// path?.let { +// viewInExternalApp(it) +// } +// } +// } +// launch { +// viewModel.editResource.collect { path -> +// path?.let { +// editResource(it) +// } +// } +// } +// launch { +// viewModel.notifyResourceChange.collect { +// notifyResourcesChanged() +// } +// } +// launch { +// viewModel.displayPreviewTags.collect { +// if (it != null) { +// displayPreviewTags(it.resourceId, it.tags) +// } +// } +// } +// launch { +// viewModel.notifyCurrentItemChange.collect { +// if (it) { +// notifyCurrentItemChanged() +// } +// } +// } +// launch { +// viewModel.updatePagerAdapterWithDiff.collect { +// if (it) { +// updatePagerAdapterWithDiff() +// } +// } +// } +// launch { +// viewModel.displaySelected.collect { +// it?.let { +// displaySelected( +// selected = it.selected, +// showAnim = it.showAnim, +// selectedCount = it.selectedCount, +// itemCount = viewModel.galleryItems.size +// ) +// } +// } +// } +// launch { +// viewModel.toastIndexFailedPath.collect { +// it?.let { +// toastIndexFailedPath(it) +// } +// } +// } +// launch { +// viewModel.notifyResourceScoresChanged.collect { +// if (it) { +// notifyResourceScoresChanged() +// } +// } +// } +// launch { +// viewModel.updatePagerAdapter.collect { +// updatePagerAdapter() +// } +// } +// launch { +// viewModel.setControlsVisibility.collect { +// setControlsVisibility(it) +// } +// } +// launch { +// viewModel.onNavigateBack.collect { +// if (it) { +// onBackClick() +// } +// } +// } +// launch { +// viewModel.deleteResource.collect { +// it?.let { +// deleteResource(it) +// } +// } +// } +// launch { +// viewModel.setUpPreview.collect { +// it?.let { +// setupPreview(it.position, it.meta) +// } +// } +// } +// launch { +// viewModel.showEditTagsDialog.collect { +// it?.let { +// showEditTagsDialog( +// resource = it.resource, +// resources = it.resources, +// statsStorage = it.statsStorage, +// rootAndFav = it.rootAndFav, +// index = it.index, +// storage = it.storage, +// ) +// } +// } +// } +// launch { +// viewModel.displayStorageException.collect { +// it?.let { +// displayStorageException(it.label, it.messenger) +// } +// } +// } +// launch { +// viewModel.notifyTagsChanged.collect { +// if (it) { +// notifyTagsChanged() +// } +// } +// } +// launch { +// viewModel.showProgressWithText.collect { +// it?.let { +// setProgressVisibility( +// isVisible = it.isVisible, +// withText = it.text +// ) +// } +// } +// } +// } +// } } private fun updatePagerAdapter() { From 62dcdb32c2c05f7840c32b57119a63d2db7bca62 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 10:58:44 +0700 Subject: [PATCH 28/74] Trigger side effect --- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 8d3e59e4..3d3a5b26 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -262,7 +262,7 @@ class GalleryUpliftViewModel( onTagsChanged() // _deleteResource.value = currentPos intent { - postSideEffect(GallerySideEffect.DeleteResource) + postSideEffect(GallerySideEffect.DeleteResource(currentPos)) } } @@ -393,7 +393,7 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.ShowProgressWithText( ProgressWithText( - isVisible = true, + isVisible = false, text = "", ) )) @@ -810,7 +810,7 @@ class GalleryUpliftViewModel( galleryItems = newItems.toMutableList() viewModelScope.launch { - _updatePagerAdapterWithDiff.value = true +// _updatePagerAdapterWithDiff.value = true // _notifyCurrentItemChange.value = true intent { From 6d5122070911714c2111f207309ecc9adaf6e901 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 19:10:43 +0700 Subject: [PATCH 29/74] Extract side effect --- .../galleryuplift/GalleryUpliftFragment.kt | 3 +- .../galleryuplift/GalleryUpliftViewModel.kt | 231 ++---------------- .../galleryuplift/state/GalleryState.kt | 1 + 3 files changed, 22 insertions(+), 213 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index c0430861..392d9d3a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -18,9 +18,7 @@ import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult import androidx.fragment.app.viewModels -import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope -import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SimpleItemAnimator import androidx.viewpager2.widget.ViewPager2 @@ -224,6 +222,7 @@ class GalleryUpliftFragment : Fragment() { GallerySideEffect.UpdatePagerAdapter -> updatePagerAdapter() GallerySideEffect.UpdatePagerAdapterWithDiff -> updatePagerAdapterWithDiff() is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) + is GallerySideEffect.ToggleSelect -> toggleSelecting(isEnabled) } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 3d3a5b26..c4d9e99e 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -45,11 +45,8 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.async import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -101,105 +98,19 @@ class GalleryUpliftViewModel( scope = viewModelScope, getCurrentId = { currentItem.id() }, onScoreChanged = { -// _notifyResourceScoresChanged.value = true intent { postSideEffect(GallerySideEffect.NotifyResourceScoresChanged) } } ) - private var currentPos = 0 +// private var currentPos = 0 private var sortByScores = false private var selectingEnabled: Boolean = false private val messageFlow: MutableSharedFlow = MutableSharedFlow() private val currentItem: GalleryPresenter.GalleryItem - get() = galleryItems[currentPos] - -// private val _notifyResourceScoresChanged: MutableStateFlow = -// MutableStateFlow(false) -// val notifyResourceScoresChanged: StateFlow = -// _notifyResourceScoresChanged - -// private val _setControlsVisibility: MutableStateFlow = -// MutableStateFlow(false) -// val setControlsVisibility: StateFlow = -// _setControlsVisibility - -// private val _onNavigateBack: MutableStateFlow = MutableStateFlow(false) -// val onNavigateBack: StateFlow = _onNavigateBack - -// private val _deleteResource: MutableStateFlow = MutableStateFlow(null) -// val deleteResource: StateFlow = _deleteResource - -// private val _toastIndexFailedPath: MutableStateFlow = -// MutableStateFlow(null) -// val toastIndexFailedPath: StateFlow = _toastIndexFailedPath - -// private val _showInfoAlert: MutableStateFlow = -// MutableStateFlow(null) -// val showInfoAlert: StateFlow = _showInfoAlert - -// private val _displayStorageException: MutableStateFlow = -// MutableStateFlow(null) -// val displayStorageException: StateFlow = -// _displayStorageException - -// private val _updatePagerAdapter: MutableStateFlow = -// MutableStateFlow(false) -// val updatePagerAdapter: StateFlow = _updatePagerAdapter - -// private val _shareLink: MutableStateFlow = MutableStateFlow("") -// val shareLink: StateFlow = _shareLink - -// private val _shareResource: MutableStateFlow = MutableStateFlow(null) -// val shareResource: StateFlow = _shareResource - -// private val _editResource: MutableStateFlow = MutableStateFlow(null) -// val editResource: StateFlow = _editResource - -// private val _openLink: MutableStateFlow = MutableStateFlow("") -// val openLink: StateFlow = _openLink - -// private val _viewInExternalApp: MutableStateFlow = -// MutableStateFlow(null) -// val viewInExternalApp: StateFlow = _viewInExternalApp - -// private val _displayPreviewTags: MutableStateFlow = -// MutableStateFlow(null) -// val displayPreviewTags: StateFlow = _displayPreviewTags - -// private val _notifyTagsChanged: MutableStateFlow = -// MutableStateFlow(false) -// val notifyTagsChanged: StateFlow = _notifyTagsChanged - -// private val _showEditTagsDialog: MutableStateFlow = -// MutableStateFlow(null) -// val showEditTagsDialog: StateFlow = _showEditTagsDialog - -// private val _setUpPreview: MutableStateFlow = -// MutableStateFlow(null) -// val setUpPreview: StateFlow = _setUpPreview - -// private val _displaySelected: MutableStateFlow = -// MutableStateFlow(null) -// val displaySelected: StateFlow = _displaySelected - -// private val _notifyResourceChange: MutableStateFlow = -// MutableStateFlow(false) -// val notifyResourceChange: StateFlow = _notifyResourceChange - -// private val _showProgressWithText: MutableStateFlow = -// MutableStateFlow(null) -// val showProgressWithText: StateFlow = _showProgressWithText - -// private val _notifyCurrentItemChange: MutableStateFlow = -// MutableStateFlow(false) -// val notifyCurrentItemChange: StateFlow = _notifyCurrentItemChange - -// private val _updatePagerAdapterWithDiff: MutableStateFlow = -// MutableStateFlow(false) -// val updatePagerAdapterWithDiff: StateFlow = _updatePagerAdapterWithDiff + get() = galleryItems[container.stateFlow.value.currentPos] fun initialize( rootAndFav: RootAndFav, @@ -214,7 +125,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.ControlVisible(isVisible = true)) } -// _setControlsVisibility.value = !_setControlsVisibility.value } fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) { @@ -246,23 +156,21 @@ class GalleryUpliftViewModel( analytics.trackResRemove() Timber.d( LogTags.GALLERY_SCREEN, - "[remove_resource] clicked at position $currentPos" + "[remove_resource] clicked at position ${container.stateFlow.value.currentPos}" ) deleteResource(currentItem.id()) - galleryItems.removeAt(currentPos) + galleryItems.removeAt(container.stateFlow.value.currentPos) if (galleryItems.isEmpty()) { intent { postSideEffect(GallerySideEffect.NavigateBack) } -// _onNavigateBack.emit(true) return@launch } onTagsChanged() -// _deleteResource.value = currentPos intent { - postSideEffect(GallerySideEffect.DeleteResource(currentPos)) + postSideEffect(GallerySideEffect.DeleteResource(container.stateFlow.value.currentPos)) } } @@ -279,7 +187,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.NotifyResourceChange) } -// _notifyResourceChange.value = true } private fun onFirstViewAttach() { @@ -294,10 +201,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Providing root index", -// ) index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { @@ -309,7 +212,6 @@ class GalleryUpliftViewModel( ) ) } -// _toastIndexFailedPath.value = message.path } }.launchIn(viewModelScope) intent { @@ -320,10 +222,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Providing metadata storage", -// ) metadataStorage = metadataStorageRepo.provide(index) intent { postSideEffect(GallerySideEffect.ShowProgressWithText( @@ -333,10 +231,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Providing previews storage", -// ) previewStorage = previewStorageRepo.provide(index) intent { postSideEffect(GallerySideEffect.ShowProgressWithText( @@ -346,10 +240,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Providing data storage", -// ) try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) @@ -364,10 +254,6 @@ class GalleryUpliftViewModel( ) ) } -// _displayStorageException.value = StorageExceptionGallery( -// label = e.label, -// messenger = e.msg -// ) } statsStorage = statsStorageRepo.provide(index) @@ -386,9 +272,6 @@ class GalleryUpliftViewModel( GallerySideEffect.UpdatePagerAdapter ) } -// sortByScores = preferences.get(PreferenceKey.SortByScores) -// _updatePagerAdapter.value = true - intent { postSideEffect(GallerySideEffect.ShowProgressWithText( @@ -398,10 +281,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = false, -// text = "" -// ) scoreWidgetController.setVisible(sortByScores) } } @@ -414,7 +293,7 @@ class GalleryUpliftViewModel( analytics.trackResInfo() Timber.d( LogTags.GALLERY_SCREEN, - "[info_resource] clicked at position $currentPos" + "[info_resource] clicked at position ${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! @@ -426,7 +305,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.ShowInfoAlert(data)) } -// _showInfoAlert.emit(data) } @@ -434,7 +312,7 @@ class GalleryUpliftViewModel( analytics.trackResShare() Timber.d( LogTags.GALLERY_SCREEN, - "[share_resource] clicked at position $currentPos" + "[share_resource] clicked at position ${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! @@ -443,30 +321,22 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.ShareLink(url)) } -// _shareLink.emit(url) return@launch } intent { postSideEffect(GallerySideEffect.ShareResource(path)) } -// _shareResource.emit(path) } - - private val _toggleSelect: MutableStateFlow = MutableStateFlow(false) - val toggleSelect: StateFlow = _toggleSelect fun onSelectingChanged() { - viewModelScope.launch { - intent { - reduce { - state.copy(selectingEnabled = !state.selectingEnabled) - } - } -// selectingEnabled = !selectingEnabled - _toggleSelect.emit(selectingEnabled) - _selectedResources.clear() - if (selectingEnabled) { - _selectedResources.add(currentItem.resource.id) + intent { + reduce { + state.copy(selectingEnabled = !state.selectingEnabled) } + postSideEffect(GallerySideEffect.ToggleSelect(selectingEnabled)) + } + _selectedResources.clear() + if (selectingEnabled) { + _selectedResources.add(currentItem.resource.id) } } @@ -474,7 +344,7 @@ class GalleryUpliftViewModel( analytics.trackResOpen() Timber.d( LogTags.GALLERY_SCREEN, - "[open_resource] clicked at position $currentPos" + "[open_resource] clicked at position ${container.stateFlow.value.currentPos}" ) val id = currentItem.id() @@ -485,7 +355,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.OpenLink(url)) } -// _openLink.emit(url) return@launch } intent { @@ -497,17 +366,15 @@ class GalleryUpliftViewModel( ) ) } -// _viewInExternalApp.emit(path) } fun onEditFabClick() = viewModelScope.launch { analytics.trackResEdit() Timber.d( LogTags.GALLERY_SCREEN, - "[edit_resource] clicked at position $currentPos" + "[edit_resource] clicked at position ${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! -// _editResource.emit(path) intent { postSideEffect(GallerySideEffect.EditResource(path)) } @@ -535,16 +402,10 @@ class GalleryUpliftViewModel( ) ) } -// _displaySelected.value = DisplaySelected( -// selected = !wasSelected, -// showAnim = true, -// selectedCount = _selectedResources.size, -// itemCount = galleryItems.size -// ) } fun onResume() { - checkResourceChanges(currentPos) + checkResourceChanges(container.stateFlow.value.currentPos) } fun onTagsChanged() { @@ -559,10 +420,6 @@ class GalleryUpliftViewModel( ) ) } -// _displayPreviewTags.value = ResourceIdTagsPreview( -// resourceId = currentItem.id(), -// tags = tags, -// ) } fun onPageChanged(newPos: Int) = viewModelScope.launch { @@ -570,9 +427,6 @@ class GalleryUpliftViewModel( return@launch checkResourceChanges(newPos) - - -// currentPos = newPos intent { reduce { state.copy(currentPos = newPos) @@ -599,10 +453,6 @@ class GalleryUpliftViewModel( val tags = tagsStorage.getTags(id) val newTags = tags - tag -// _displayPreviewTags.value = ResourceIdTagsPreview( -// resourceId = id, -// tags = newTags, -// ) intent { postSideEffect( GallerySideEffect.DisplayPreviewTags( @@ -626,7 +476,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.NotifyTagsChanged) } -// _notifyTagsChanged.value = true } fun onEditTagsDialogBtnClick() { @@ -645,14 +494,6 @@ class GalleryUpliftViewModel( ) ) } -// _showEditTagsDialog.value = ShowEditTagsData( -// resource = currentItem.id(), -// resources = listOf(currentItem.id()), -// statsStorage = statsStorage, -// rootAndFav = rootAndFav, -// index = index, -// storage = tagsStorage, -// ) } private fun displayPreview( @@ -664,16 +505,12 @@ class GalleryUpliftViewModel( postSideEffect( GallerySideEffect.SetUpPreview( SetupPreview( - position = currentPos, + position = container.stateFlow.value.currentPos, meta = meta, ) ) ) } -// _setUpPreview.value = SetupPreview( -// position = currentPos, -// meta = meta, -// ) intent { postSideEffect( @@ -685,10 +522,6 @@ class GalleryUpliftViewModel( ) ) } -// _displayPreviewTags.value = ResourceIdTagsPreview( -// resourceId = id, -// tags = tags, -// ) scoreWidgetController.displayScore() intent { @@ -703,12 +536,6 @@ class GalleryUpliftViewModel( ) ) } -// _displaySelected.value = DisplaySelected( -// selected = id in _selectedResources, -// showAnim = false, -// selectedCount = _selectedResources.size, -// itemCount = galleryItems.size, -// ) } private fun checkResourceChanges(pos: Int) = @@ -758,15 +585,8 @@ class GalleryUpliftViewModel( } - private fun invokeHandleGalleryExternalChangesUseCase( - ) { + private fun invokeHandleGalleryExternalChangesUseCase() { viewModelScope.launch { -// withContext(Dispatchers.Main) { -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Changes detected, indexing" -// ) -// } intent { postSideEffect(GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -781,9 +601,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.NotifyResourceChange) } -// withContext(Dispatchers.Main) { -// _notifyResourceChange.value = true -// } viewModelScope.launch { metadataStorage.busy.collect { busy -> @@ -796,7 +613,6 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.NavigateBack) } -// _onNavigateBack.value = true return@launch } @@ -810,9 +626,6 @@ class GalleryUpliftViewModel( galleryItems = newItems.toMutableList() viewModelScope.launch { -// _updatePagerAdapterWithDiff.value = true - -// _notifyCurrentItemChange.value = true intent { postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) postSideEffect(GallerySideEffect.NotifyCurrentItemChange) @@ -823,10 +636,6 @@ class GalleryUpliftViewModel( ) )) } -// _showProgressWithText.value = ProgressWithText( -// isVisible = true, -// text = "Changes detected, indexing" -// ) } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index d29b5d26..1c4d69b0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -42,4 +42,5 @@ sealed class GallerySideEffect { data class ShowProgressWithText(val text: ProgressWithText): GallerySideEffect() data object NotifyCurrentItemChange: GallerySideEffect() data object UpdatePagerAdapterWithDiff: GallerySideEffect() + data class ToggleSelect(val isEnabled: Boolean) : GallerySideEffect() } From 5981d6c425b044b4df6e2886144baf5c001bd453 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 19:15:44 +0700 Subject: [PATCH 30/74] Extract side effect --- .../gallery/galleryuplift/GalleryUpliftViewModel.kt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index c4d9e99e..0e041337 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -104,10 +104,6 @@ class GalleryUpliftViewModel( } ) -// private var currentPos = 0 - private var sortByScores = false - private var selectingEnabled: Boolean = false - private val messageFlow: MutableSharedFlow = MutableSharedFlow() private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[container.stateFlow.value.currentPos] @@ -281,7 +277,7 @@ class GalleryUpliftViewModel( ) )) } - scoreWidgetController.setVisible(sortByScores) + scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } } @@ -332,10 +328,10 @@ class GalleryUpliftViewModel( reduce { state.copy(selectingEnabled = !state.selectingEnabled) } - postSideEffect(GallerySideEffect.ToggleSelect(selectingEnabled)) + postSideEffect(GallerySideEffect.ToggleSelect(container.stateFlow.value.selectingEnabled)) } _selectedResources.clear() - if (selectingEnabled) { + if (container.stateFlow.value.selectingEnabled) { _selectedResources.add(currentItem.resource.id) } } From 16e1a6fa45140150cc5519409c4215210d94b01c Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 19:57:45 +0700 Subject: [PATCH 31/74] Fix klihnt check --- .../galleryuplift/GalleryUpliftFragment.kt | 176 ------------------ .../galleryuplift/GalleryUpliftViewModel.kt | 117 ++++++------ .../galleryuplift/state/GalleryState.kt | 8 +- 3 files changed, 56 insertions(+), 245 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 392d9d3a..969324a7 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -116,7 +116,6 @@ class GalleryUpliftFragment : Fragment() { LogTags.GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}" ) - collectState() animatePagerAppearance() initResultListener() stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope) @@ -239,181 +238,6 @@ class GalleryUpliftFragment : Fragment() { viewModel.router.exit() } - private fun collectState() { -// viewLifecycleOwner.lifecycleScope.launch { -// repeatOnLifecycle(Lifecycle.State.STARTED) { -// launch { -// viewModel.showInfoAlert.collect { data -> -// data?.let { -// showInfoAlert(it.path, it.resource, it.metadata) -// } -// } -// } -// launch { -// viewModel.shareLink.collect { -// if (it.isNotEmpty()) { -// shareLink(it) -// } -// } -// } -// launch { -// viewModel.shareResource.collect { path -> -// path?.let { -// shareResource(path) -// } -// } -// } -// launch { -// viewModel.toggleSelect.collect { -// toggleSelecting(it) -// } -// } -// launch { -// viewModel.openLink.collect { -// if (it.isNotEmpty()) { -// openLink(it) -// } -// } -// } -// launch { -// viewModel.viewInExternalApp.collect { path -> -// path?.let { -// viewInExternalApp(it) -// } -// } -// } -// launch { -// viewModel.editResource.collect { path -> -// path?.let { -// editResource(it) -// } -// } -// } -// launch { -// viewModel.notifyResourceChange.collect { -// notifyResourcesChanged() -// } -// } -// launch { -// viewModel.displayPreviewTags.collect { -// if (it != null) { -// displayPreviewTags(it.resourceId, it.tags) -// } -// } -// } -// launch { -// viewModel.notifyCurrentItemChange.collect { -// if (it) { -// notifyCurrentItemChanged() -// } -// } -// } -// launch { -// viewModel.updatePagerAdapterWithDiff.collect { -// if (it) { -// updatePagerAdapterWithDiff() -// } -// } -// } -// launch { -// viewModel.displaySelected.collect { -// it?.let { -// displaySelected( -// selected = it.selected, -// showAnim = it.showAnim, -// selectedCount = it.selectedCount, -// itemCount = viewModel.galleryItems.size -// ) -// } -// } -// } -// launch { -// viewModel.toastIndexFailedPath.collect { -// it?.let { -// toastIndexFailedPath(it) -// } -// } -// } -// launch { -// viewModel.notifyResourceScoresChanged.collect { -// if (it) { -// notifyResourceScoresChanged() -// } -// } -// } -// launch { -// viewModel.updatePagerAdapter.collect { -// updatePagerAdapter() -// } -// } -// launch { -// viewModel.setControlsVisibility.collect { -// setControlsVisibility(it) -// } -// } -// launch { -// viewModel.onNavigateBack.collect { -// if (it) { -// onBackClick() -// } -// } -// } -// launch { -// viewModel.deleteResource.collect { -// it?.let { -// deleteResource(it) -// } -// } -// } -// launch { -// viewModel.setUpPreview.collect { -// it?.let { -// setupPreview(it.position, it.meta) -// } -// } -// } -// launch { -// viewModel.showEditTagsDialog.collect { -// it?.let { -// showEditTagsDialog( -// resource = it.resource, -// resources = it.resources, -// statsStorage = it.statsStorage, -// rootAndFav = it.rootAndFav, -// index = it.index, -// storage = it.storage, -// ) -// } -// } -// } -// launch { -// viewModel.displayStorageException.collect { -// it?.let { -// displayStorageException(it.label, it.messenger) -// } -// } -// } -// launch { -// viewModel.notifyTagsChanged.collect { -// if (it) { -// notifyTagsChanged() -// } -// } -// } -// launch { -// viewModel.showProgressWithText.collect { -// it?.let { -// setProgressVisibility( -// isVisible = it.isVisible, -// withText = it.text -// ) -// } -// } -// } -// } -// } - } - private fun updatePagerAdapter() { pagerAdapter.notifyDataSetChanged() binding.viewPager.adapter?.itemCount?.let { count -> diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 0e041337..fdd1d751 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -85,8 +85,7 @@ class GalleryUpliftViewModel( private lateinit var rootAndFav: RootAndFav private lateinit var resourcesIds: List - override val container: Container = - container(GalleryState()) + override val container: Container = container(GalleryState()) var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null @@ -127,10 +126,8 @@ class GalleryUpliftViewModel( viewModelScope.launch { view.reset() val item = galleryItems[view.pos] - val path = index.getPath(item.id())!! val content = readText(path) - content.onSuccess { view.setContent(it) } @@ -156,14 +153,12 @@ class GalleryUpliftViewModel( ) deleteResource(currentItem.id()) galleryItems.removeAt(container.stateFlow.value.currentPos) - if (galleryItems.isEmpty()) { intent { postSideEffect(GallerySideEffect.NavigateBack) } return@launch } - onTagsChanged() intent { postSideEffect(GallerySideEffect.DeleteResource(container.stateFlow.value.currentPos)) @@ -172,13 +167,10 @@ class GalleryUpliftViewModel( private suspend fun deleteResource(resource: ResourceId) { Timber.d(LogTags.GALLERY_SCREEN, "deleting resource $resource") - - val path = index.getPath(resource) - withContext(Dispatchers.IO) { + val path = index.getPath(resource) Files.delete(path) } - index.updateAll() intent { postSideEffect(GallerySideEffect.NotifyResourceChange) @@ -190,12 +182,14 @@ class GalleryUpliftViewModel( Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing root index", + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing root index", + ) ) - )) + ) } index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> @@ -211,30 +205,36 @@ class GalleryUpliftViewModel( } }.launchIn(viewModelScope) intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing metadata storage", + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing metadata storage", + ) ) - )) + ) } metadataStorage = metadataStorageRepo.provide(index) intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing previews storage", + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing previews storage", + ) ) - )) + ) } previewStorage = previewStorageRepo.provide(index) intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing data storage", + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Providing data storage", + ) ) - )) + ) } try { tagsStorage = tagsStorageRepo.provide(index) @@ -251,12 +251,9 @@ class GalleryUpliftViewModel( ) } } - statsStorage = statsStorageRepo.provide(index) scoreWidgetController.init(scoreStorage) - galleryItems = provideGalleryItems().toMutableList() - intent { reduce { viewModelScope.launch { @@ -267,15 +264,14 @@ class GalleryUpliftViewModel( postSideEffect( GallerySideEffect.UpdatePagerAdapter ) - } - - intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = false, - text = "", + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = false, + text = "", + ) ) - )) + ) } scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } @@ -291,7 +287,6 @@ class GalleryUpliftViewModel( LogTags.GALLERY_SCREEN, "[info_resource] clicked at position ${container.stateFlow.value.currentPos}" ) - val path = index.getPath(currentItem.id())!! val data = ShowInfoData( path = path, @@ -311,7 +306,6 @@ class GalleryUpliftViewModel( "[share_resource] clicked at position ${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! - if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() intent { @@ -323,6 +317,7 @@ class GalleryUpliftViewModel( postSideEffect(GallerySideEffect.ShareResource(path)) } } + fun onSelectingChanged() { intent { reduce { @@ -342,10 +337,8 @@ class GalleryUpliftViewModel( LogTags.GALLERY_SCREEN, "[open_resource] clicked at position ${container.stateFlow.value.currentPos}" ) - val id = currentItem.id() val path = index.getPath(id)!! - if (currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() intent { @@ -379,7 +372,6 @@ class GalleryUpliftViewModel( fun onSelectBtnClick() { val id = currentItem.id() val wasSelected = id in _selectedResources - if (wasSelected) { _selectedResources.remove(id) } else { @@ -421,7 +413,6 @@ class GalleryUpliftViewModel( fun onPageChanged(newPos: Int) = viewModelScope.launch { if (galleryItems.isEmpty()) return@launch - checkResourceChanges(newPos) intent { reduce { @@ -445,7 +436,6 @@ class GalleryUpliftViewModel( fun onTagRemove(tag: Tag) = viewModelScope.launch(NonCancellable) { analytics.trackTagRemove() val id = currentItem.id() - val tags = tagsStorage.getTags(id) val newTags = tags - tag @@ -466,7 +456,6 @@ class GalleryUpliftViewModel( ) Timber.d(LogTags.GALLERY_SCREEN, "setting new tags $newTags to $currentItem") - tagsStorage.setTags(id, newTags) tagsStorage.persist() intent { @@ -539,22 +528,18 @@ class GalleryUpliftViewModel( if (galleryItems.isEmpty()) { return@launch } - val item = galleryItems[pos] - val path = index.getPath(item.id()) ?: let { Timber.d("Resource ${item.id()} can't be found in the index") invokeHandleGalleryExternalChangesUseCase() return@launch } - if (path.notExists()) { Timber.d("Resource ${item.id()} isn't stored by path $path") invokeHandleGalleryExternalChangesUseCase() return@launch } - if (path.getLastModifiedTime() != item.resource.modified) { Timber.d("Index is not up-to-date regarding path $path") invokeHandleGalleryExternalChangesUseCase() @@ -584,12 +569,14 @@ class GalleryUpliftViewModel( private fun invokeHandleGalleryExternalChangesUseCase() { viewModelScope.launch { intent { - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) ) - )) + ) } index.updateAll() @@ -625,12 +612,14 @@ class GalleryUpliftViewModel( intent { postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) postSideEffect(GallerySideEffect.NotifyCurrentItemChange) - postSideEffect(GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" + ) ) - )) + ) } } } @@ -646,5 +635,3 @@ class GalleryUpliftViewModel( } } } - - diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 1c4d69b0..73cb6e62 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -38,9 +38,9 @@ sealed class GallerySideEffect { data class ShowEditTagsDialog(val data: ShowEditTagsData) : GallerySideEffect() data class SetUpPreview(val data: SetupPreview) : GallerySideEffect() data class DisplaySelectedFile(val data: DisplaySelected) : GallerySideEffect() - data object NotifyResourceChange: GallerySideEffect() - data class ShowProgressWithText(val text: ProgressWithText): GallerySideEffect() - data object NotifyCurrentItemChange: GallerySideEffect() - data object UpdatePagerAdapterWithDiff: GallerySideEffect() + data object NotifyResourceChange : GallerySideEffect() + data class ShowProgressWithText(val text: ProgressWithText) : GallerySideEffect() + data object NotifyCurrentItemChange : GallerySideEffect() + data object UpdatePagerAdapterWithDiff : GallerySideEffect() data class ToggleSelect(val isEnabled: Boolean) : GallerySideEffect() } From 970d0a0ad325c7db3c2e96e22a7f6709f0e2709e Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 20:05:10 +0700 Subject: [PATCH 32/74] Fix klihnt check --- .../galleryuplift/GalleryUpliftFragment.kt | 15 --------------- .../galleryuplift/GalleryUpliftViewModel.kt | 1 - 2 files changed, 16 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 969324a7..de57c3f2 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -64,7 +64,6 @@ import java.nio.file.Path import javax.inject.Inject import kotlin.system.measureTimeMillis - class GalleryUpliftFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) @@ -83,7 +82,6 @@ class GalleryUpliftFragment : Fragment() { private lateinit var stackedToasts: StackedToasts private lateinit var pagerAdapter: PreviewsPagerUplift - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -92,7 +90,6 @@ class GalleryUpliftFragment : Fragment() { return inflater.inflate(R.layout.fragment_gallery, container, false) } - override fun onDestroyView() { super.onDestroyView() scoreWidget.onDestroyView() @@ -126,19 +123,15 @@ class GalleryUpliftFragment : Fragment() { requireActivity().onBackPressedDispatcher.addCallback(this) { onBackClick() } - - pagerAdapter = PreviewsPagerUplift(requireContext(), viewModel) initViewPager() scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) - binding.apply { val selectingEnabled = requireArguments().getBoolean(GalleryFragment.SELECTING_ENABLED_KEY) layoutSelected.isVisible = selectingEnabled fabStartSelect.isVisible = !selectingEnabled - removeResourceFab.setOnClickListener { Toast.makeText( requireContext(), @@ -146,7 +139,6 @@ class GalleryUpliftFragment : Fragment() { Toast.LENGTH_SHORT ).show() } - removeResourceFab.setOnLongClickListener { val time = measureTimeMillis { viewModel.onRemoveFabClick() @@ -154,7 +146,6 @@ class GalleryUpliftFragment : Fragment() { Timber.tag(LogTags.GALLERY_SCREEN).d("${time / 1000L}s") true } - infoResourceFab.setOnClickListener { viewModel.onInfoFabClick() } @@ -226,7 +217,6 @@ class GalleryUpliftFragment : Fragment() { } } - private fun render(state: GalleryState) { setControlsVisibility(state.selectingEnabled) } @@ -296,7 +286,6 @@ class GalleryUpliftFragment : Fragment() { } } - private fun shareResource(resourcePath: Path) = openIntentChooser( resourcePath, @@ -421,7 +410,6 @@ class GalleryUpliftFragment : Fragment() { dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) } - @SuppressLint("ClickableViewAccessibility") fun setProgressVisibility(isVisible: Boolean, withText: String) { binding.layoutProgress.apply { @@ -455,7 +443,6 @@ class GalleryUpliftFragment : Fragment() { } } - private fun displaySelected( selected: Boolean, showAnim: Boolean, @@ -536,7 +523,6 @@ class GalleryUpliftFragment : Fragment() { } } - private fun initViewPager() = with(binding.viewPager) { adapter = pagerAdapter offscreenPageLimit = 2 @@ -594,7 +580,6 @@ class GalleryUpliftFragment : Fragment() { startActivity(Intent.createChooser(intent, title)) } - private fun getExternalAppIntent( resourcePath: Path, actionType: String, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index fdd1d751..6eefa466 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -565,7 +565,6 @@ class GalleryUpliftViewModel( emptyList() } - private fun invokeHandleGalleryExternalChangesUseCase() { viewModelScope.launch { intent { From 1a0a7910e7cd9bcc38c8512ff0bff973045bd78a Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 20:13:33 +0700 Subject: [PATCH 33/74] Fix klihnt check --- .../screen/gallery/GalleryFragment.kt | 4 +- .../galleryuplift/GalleryUpliftFragment.kt | 54 +++++++++++++++---- .../galleryuplift/GalleryUpliftViewModel.kt | 31 ++++++++--- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt index c2d43bab..269edbe0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt @@ -63,8 +63,8 @@ class GalleryFragment : private val presenter by moxyPresenter { GalleryPresenter( rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!!.toList() - as List, + resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! + .toList() as List, startAt = requireArguments().getInt(START_AT_KEY), selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), selectedResources = ( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index de57c3f2..ed8a9f58 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -183,11 +183,28 @@ class GalleryUpliftFragment : Fragment() { private fun handleSideEffect(sideEffect: GallerySideEffect) { with(sideEffect) { when (this) { - is GallerySideEffect.ControlVisible -> setControlsVisibility(isVisible) + is GallerySideEffect.ControlVisible -> + setControlsVisibility(visible = isVisible) + is GallerySideEffect.DeleteResource -> deleteResource(pos) - is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags(data.resourceId, data.tags) - is GallerySideEffect.DisplaySelectedFile -> displaySelected(data.selected, data.showAnim, data.selectedCount, data.itemCount) - is GallerySideEffect.DisplayStorageException -> displayStorageException(storageException.label, storageException.messenger) + is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( + resource = data.resourceId, + tags = data.tags + ) + + is GallerySideEffect.DisplaySelectedFile -> displaySelected( + selected = data.selected, + showAnim = data.showAnim, + selectedCount = data.selectedCount, + itemCount = data.itemCount + ) + + is GallerySideEffect.DisplayStorageException -> + displayStorageException( + label = storageException.label, + msg = storageException.messenger + ) + is GallerySideEffect.EditResource -> editResource(path) GallerySideEffect.NavigateBack -> onBackClick() GallerySideEffect.NotifyCurrentItemChange -> notifyCurrentItemChanged() @@ -195,7 +212,11 @@ class GalleryUpliftFragment : Fragment() { GallerySideEffect.NotifyResourceScoresChanged -> notifyResourceScoresChanged() GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() is GallerySideEffect.OpenLink -> openLink(url) - is GallerySideEffect.SetUpPreview -> setupPreview(data.position, data.meta) + is GallerySideEffect.SetUpPreview -> setupPreview( + pos = data.position, + meta = data.meta + ) + is GallerySideEffect.ShareLink -> shareLink(url) is GallerySideEffect.ShareResource -> shareResource(path) is GallerySideEffect.ShowEditTagsDialog -> showEditTagsDialog( @@ -206,11 +227,26 @@ class GalleryUpliftFragment : Fragment() { index = data.index, storage = data.storage, ) - is GallerySideEffect.ShowInfoAlert -> showInfoAlert(infoData.path, infoData.resource, infoData.metadata) - is GallerySideEffect.ShowProgressWithText -> setProgressVisibility(text.isVisible, text.text) - is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath(path) + + is GallerySideEffect.ShowInfoAlert -> showInfoAlert( + path = infoData.path, + resource = infoData.resource, + metadata = infoData.metadata + ) + + is GallerySideEffect.ShowProgressWithText -> setProgressVisibility( + isVisible = text.isVisible, + withText = text.text + ) + + is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath( + path + ) + GallerySideEffect.UpdatePagerAdapter -> updatePagerAdapter() - GallerySideEffect.UpdatePagerAdapterWithDiff -> updatePagerAdapterWithDiff() + GallerySideEffect.UpdatePagerAdapterWithDiff -> + updatePagerAdapterWithDiff() + is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) is GallerySideEffect.ToggleSelect -> toggleSelecting(isEnabled) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 6eefa466..a87d367f 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -85,7 +85,8 @@ class GalleryUpliftViewModel( private lateinit var rootAndFav: RootAndFav private lateinit var resourcesIds: List - override val container: Container = container(GalleryState()) + override val container: Container = + container(GalleryState()) var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null @@ -149,7 +150,10 @@ class GalleryUpliftViewModel( analytics.trackResRemove() Timber.d( LogTags.GALLERY_SCREEN, - "[remove_resource] clicked at position ${container.stateFlow.value.currentPos}" + buildString { + append("[remove_resource] clicked at position ") + append("${container.stateFlow.value.currentPos}") + } ) deleteResource(currentItem.id()) galleryItems.removeAt(container.stateFlow.value.currentPos) @@ -161,7 +165,9 @@ class GalleryUpliftViewModel( } onTagsChanged() intent { - postSideEffect(GallerySideEffect.DeleteResource(container.stateFlow.value.currentPos)) + postSideEffect( + GallerySideEffect.DeleteResource(container.stateFlow.value.currentPos) + ) } } @@ -257,7 +263,9 @@ class GalleryUpliftViewModel( intent { reduce { viewModelScope.launch { - state.copy(sortByScores = preferences.get(PreferenceKey.SortByScores)) + state.copy( + sortByScores = preferences.get(PreferenceKey.SortByScores) + ) } state } @@ -278,7 +286,11 @@ class GalleryUpliftViewModel( } fun onPlayButtonClick() = intent { - postSideEffect(GallerySideEffect.ViewInExternalApp(index.getPath(currentItem.id())!!)) + postSideEffect( + GallerySideEffect.ViewInExternalApp( + index.getPath(currentItem.id())!! + ) + ) } fun onInfoFabClick() = viewModelScope.launch { @@ -303,7 +315,8 @@ class GalleryUpliftViewModel( analytics.trackResShare() Timber.d( LogTags.GALLERY_SCREEN, - "[share_resource] clicked at position ${container.stateFlow.value.currentPos}" + "[share_resource] clicked at position " + + "${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! if (currentItem.metadata is Metadata.Link) { @@ -323,7 +336,11 @@ class GalleryUpliftViewModel( reduce { state.copy(selectingEnabled = !state.selectingEnabled) } - postSideEffect(GallerySideEffect.ToggleSelect(container.stateFlow.value.selectingEnabled)) + postSideEffect( + GallerySideEffect.ToggleSelect( + container.stateFlow.value.selectingEnabled + ) + ) } _selectedResources.clear() if (container.stateFlow.value.selectingEnabled) { From 6a5aec349aaa51bfd696e72c641e676fe720154f Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 20:18:43 +0700 Subject: [PATCH 34/74] Fix klihnt check --- .../galleryuplift/GalleryUpliftFragment.kt | 8 ++++++-- .../galleryuplift/GalleryUpliftViewModel.kt | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index ed8a9f58..edf68ed8 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -207,9 +207,13 @@ class GalleryUpliftFragment : Fragment() { is GallerySideEffect.EditResource -> editResource(path) GallerySideEffect.NavigateBack -> onBackClick() - GallerySideEffect.NotifyCurrentItemChange -> notifyCurrentItemChanged() + GallerySideEffect.NotifyCurrentItemChange -> + notifyCurrentItemChanged() + GallerySideEffect.NotifyResourceChange -> notifyResourcesChanged() - GallerySideEffect.NotifyResourceScoresChanged -> notifyResourceScoresChanged() + GallerySideEffect.NotifyResourceScoresChanged -> + notifyResourceScoresChanged() + GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() is GallerySideEffect.OpenLink -> openLink(url) is GallerySideEffect.SetUpPreview -> setupPreview( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index a87d367f..3f5c9bbd 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -166,7 +166,9 @@ class GalleryUpliftViewModel( onTagsChanged() intent { postSideEffect( - GallerySideEffect.DeleteResource(container.stateFlow.value.currentPos) + GallerySideEffect.DeleteResource( + container.stateFlow.value.currentPos + ) ) } } @@ -264,7 +266,9 @@ class GalleryUpliftViewModel( reduce { viewModelScope.launch { state.copy( - sortByScores = preferences.get(PreferenceKey.SortByScores) + sortByScores = preferences.get( + PreferenceKey.SortByScores + ) ) } state @@ -297,7 +301,8 @@ class GalleryUpliftViewModel( analytics.trackResInfo() Timber.d( LogTags.GALLERY_SCREEN, - "[info_resource] clicked at position ${container.stateFlow.value.currentPos}" + "[info_resource] clicked at position" + + " ${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! val data = ShowInfoData( @@ -352,7 +357,8 @@ class GalleryUpliftViewModel( analytics.trackResOpen() Timber.d( LogTags.GALLERY_SCREEN, - "[open_resource] clicked at position ${container.stateFlow.value.currentPos}" + "[open_resource] clicked at position " + + "${container.stateFlow.value.currentPos}" ) val id = currentItem.id() val path = index.getPath(id)!! @@ -378,7 +384,8 @@ class GalleryUpliftViewModel( analytics.trackResEdit() Timber.d( LogTags.GALLERY_SCREEN, - "[edit_resource] clicked at position ${container.stateFlow.value.currentPos}" + "[edit_resource] clicked at position " + + "${container.stateFlow.value.currentPos}" ) val path = index.getPath(currentItem.id())!! intent { From 18fd42cb750b10e154146be9c4ddd85b0d517a92 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 20:21:23 +0700 Subject: [PATCH 35/74] Fix klihnt check --- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 1 - .../screen/gallery/galleryuplift/state/GalleryState.kt | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 3f5c9bbd..94b6a69b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -315,7 +315,6 @@ class GalleryUpliftViewModel( } } - fun onShareFabClick() = viewModelScope.launch { analytics.trackResShare() Timber.d( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 73cb6e62..c5348471 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -22,8 +22,9 @@ sealed class GallerySideEffect { data class DeleteResource(val pos: Int) : GallerySideEffect() data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() data class ShowInfoAlert(val infoData: ShowInfoData) : GallerySideEffect() - data class DisplayStorageException(val storageException: StorageExceptionGallery) : - GallerySideEffect() + data class DisplayStorageException( + val storageException: StorageExceptionGallery + ) : GallerySideEffect() data object UpdatePagerAdapter : GallerySideEffect() data class ShareLink(val url: String) : GallerySideEffect() From 3848f7e4a60b940e547def8575c74e8faacb2e06 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 2 Jun 2024 21:35:43 +0700 Subject: [PATCH 36/74] Improve default value --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index edf68ed8..4a4f5651 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -71,7 +71,7 @@ class GalleryUpliftFragment : Fragment() { lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( - selectorNotEdit = false + requireArguments().getBoolean(SELECTING_ENABLED_KEY) ) } From 71532b4d01292899249ca6399d8bd820b67a5000 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Fri, 14 Jun 2024 11:27:19 +0700 Subject: [PATCH 37/74] Init state, simplify code flow --- .../galleryuplift/GalleryUpliftFragment.kt | 15 ++++++++------- .../galleryuplift/GalleryUpliftViewModel.kt | 19 +++++-------------- .../GalleryUpliftViewModelFactory.kt | 14 +++++++++++--- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 4a4f5651..d1cf365b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -71,8 +71,13 @@ class GalleryUpliftFragment : Fragment() { lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( - requireArguments().getBoolean(SELECTING_ENABLED_KEY) - ) + selectingEnabled =requireArguments().getBoolean(SELECTING_ENABLED_KEY), + rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, + resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! + .toList() as List + ).apply { + App.instance.appComponent.inject(this@GalleryUpliftFragment) + } } private val scoreWidget by lazy { @@ -103,11 +108,7 @@ class GalleryUpliftFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) - viewModel.initialize( - rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! - .toList() as List - ) + viewModel.onFirstViewAttach() super.onViewCreated(view, savedInstanceState) Timber.d( LogTags.GALLERY_SCREEN, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 94b6a69b..95100b4f 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -65,7 +65,9 @@ import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists class GalleryUpliftViewModel( - selectorNotEdit: Boolean, + selectingEnabled: Boolean, + private val rootAndFav: RootAndFav, + private val resourcesIds: List, val preferences: Preferences, val router: AppRouter, val indexRepo: ResourceIndexRepo, @@ -82,11 +84,9 @@ class GalleryUpliftViewModel( private lateinit var metadataStorage: MetadataProcessor private lateinit var statsStorage: StatsStorage private lateinit var scoreStorage: ScoreStorage - private lateinit var rootAndFav: RootAndFav - private lateinit var resourcesIds: List override val container: Container = - container(GalleryState()) + container(GalleryState(selectingEnabled = selectingEnabled)) var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null @@ -108,15 +108,6 @@ class GalleryUpliftViewModel( private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[container.stateFlow.value.currentPos] - fun initialize( - rootAndFav: RootAndFav, - resourcesIds: List, - ) { - this.rootAndFav = rootAndFav - this.resourcesIds = resourcesIds - onFirstViewAttach() - } - fun onPreviewsItemClick() { intent { postSideEffect(GallerySideEffect.ControlVisible(isVisible = true)) @@ -185,7 +176,7 @@ class GalleryUpliftViewModel( } } - private fun onFirstViewAttach() { + fun onFirstViewAttach() { analytics.trackScreen() Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt index 8c1672e5..34ff4d78 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt @@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModelProvider import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import dev.arkbuilders.arkfilepicker.folders.RootAndFav +import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.index.ResourceIndexRepo import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo @@ -16,7 +18,9 @@ import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.presentation.navigation.AppRouter class GalleryUpliftViewModelFactory @AssistedInject constructor( - @Assisted val selectorNotEdit: Boolean, + @Assisted val selectingEnabled: Boolean, + @Assisted private val rootAndFav: RootAndFav, + @Assisted private val resourcesIds: List, val preferences: Preferences, val router: AppRouter, val indexRepo: ResourceIndexRepo, @@ -29,7 +33,9 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { return GalleryUpliftViewModel( - selectorNotEdit = selectorNotEdit, + selectingEnabled = selectingEnabled, + rootAndFav = rootAndFav, + resourcesIds = resourcesIds, preferences = preferences, router = router, indexRepo = indexRepo, @@ -45,7 +51,9 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @AssistedFactory interface Factory { fun create( - @Assisted selectorNotEdit: Boolean, + @Assisted selectingEnabled: Boolean, + @Assisted rootAndFav: RootAndFav, + @Assisted resourcesIds: List, ): GalleryUpliftViewModelFactory } } From 52d722ddf8bc4e7eea5faef2f8db19cd35442de0 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Fri, 14 Jun 2024 11:37:56 +0700 Subject: [PATCH 38/74] Rename method --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 2 +- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index d1cf365b..5a320669 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -108,7 +108,7 @@ class GalleryUpliftFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) - viewModel.onFirstViewAttach() + viewModel.initStorages() super.onViewCreated(view, savedInstanceState) Timber.d( LogTags.GALLERY_SCREEN, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 95100b4f..684b0d32 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -176,7 +176,7 @@ class GalleryUpliftViewModel( } } - fun onFirstViewAttach() { + fun initStorages() { analytics.trackScreen() Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") viewModelScope.launch { From fb0e062d0576e9407b0ee1ed5759182d71ac21a8 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Fri, 14 Jun 2024 11:41:36 +0700 Subject: [PATCH 39/74] Reformat code --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 5a320669..649693c0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -71,7 +71,7 @@ class GalleryUpliftFragment : Fragment() { lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( - selectingEnabled =requireArguments().getBoolean(SELECTING_ENABLED_KEY), + selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! .toList() as List From a5482af1c2ab749914ebae0d436fc3c90b9d6f4e Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 16 Jun 2024 21:59:01 +0700 Subject: [PATCH 40/74] Fix wrong order of method call, simplify post effect call by reducing intent block --- .../galleryuplift/GalleryUpliftViewModel.kt | 206 +++++++++--------- 1 file changed, 99 insertions(+), 107 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 684b0d32..1fe09f75 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -138,24 +138,24 @@ class GalleryUpliftViewModel( galleryItems[pos].metadata.kind.ordinal fun onRemoveFabClick() = viewModelScope.launch(NonCancellable) { - analytics.trackResRemove() - Timber.d( - LogTags.GALLERY_SCREEN, - buildString { - append("[remove_resource] clicked at position ") - append("${container.stateFlow.value.currentPos}") - } - ) - deleteResource(currentItem.id()) - galleryItems.removeAt(container.stateFlow.value.currentPos) - if (galleryItems.isEmpty()) { - intent { - postSideEffect(GallerySideEffect.NavigateBack) - } - return@launch - } - onTagsChanged() intent { + analytics.trackResRemove() + Timber.d( + LogTags.GALLERY_SCREEN, + buildString { + append("[remove_resource] clicked at position ") + append("${container.stateFlow.value.currentPos}") + } + ) + deleteResource(currentItem.id()) + galleryItems.removeAt(container.stateFlow.value.currentPos) + if (galleryItems.isEmpty()) { + intent { + postSideEffect(GallerySideEffect.NavigateBack) + } + return@intent + } + onTagsChanged() postSideEffect( GallerySideEffect.DeleteResource( container.stateFlow.value.currentPos @@ -165,22 +165,26 @@ class GalleryUpliftViewModel( } private suspend fun deleteResource(resource: ResourceId) { - Timber.d(LogTags.GALLERY_SCREEN, "deleting resource $resource") - withContext(Dispatchers.IO) { - val path = index.getPath(resource) - Files.delete(path) - } - index.updateAll() intent { + Timber.d(LogTags.GALLERY_SCREEN, "deleting resource $resource") + withContext(Dispatchers.IO) { + val path = index.getPath(resource) + Files.delete(path) + } + index.updateAll() + postSideEffect(GallerySideEffect.NotifyResourceChange) } } fun initStorages() { - analytics.trackScreen() - Timber.d(LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter") - viewModelScope.launch { - intent { + intent { + analytics.trackScreen() + Timber.d( + LogTags.GALLERY_SCREEN, + "first view attached in GalleryPresenter" + ) + viewModelScope.launch { postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -189,21 +193,19 @@ class GalleryUpliftViewModel( ) ) ) - } - index = indexRepo.provide(rootAndFav) - messageFlow.onEach { message -> - when (message) { - is Message.KindDetectFailed -> - intent { - postSideEffect( - GallerySideEffect.ToastIndexFailedPath( - message.path + index = indexRepo.provide(rootAndFav) + messageFlow.onEach { message -> + when (message) { + is Message.KindDetectFailed -> + intent { + postSideEffect( + GallerySideEffect.ToastIndexFailedPath( + message.path + ) ) - ) - } - } - }.launchIn(viewModelScope) - intent { + } + } + }.launchIn(viewModelScope) postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -212,9 +214,7 @@ class GalleryUpliftViewModel( ) ) ) - } - metadataStorage = metadataStorageRepo.provide(index) - intent { + metadataStorage = metadataStorageRepo.provide(index) postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -223,9 +223,7 @@ class GalleryUpliftViewModel( ) ) ) - } - previewStorage = previewStorageRepo.provide(index) - intent { + previewStorage = previewStorageRepo.provide(index) postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -234,12 +232,11 @@ class GalleryUpliftViewModel( ) ) ) - } - try { - tagsStorage = tagsStorageRepo.provide(index) - scoreStorage = scoreStorageRepo.provide(index) - } catch (e: StorageException) { - intent { + + try { + tagsStorage = tagsStorageRepo.provide(index) + scoreStorage = scoreStorageRepo.provide(index) + } catch (e: StorageException) { postSideEffect( GallerySideEffect.DisplayStorageException( StorageExceptionGallery( @@ -248,12 +245,11 @@ class GalleryUpliftViewModel( ) ) ) + } - } - statsStorage = statsStorageRepo.provide(index) - scoreWidgetController.init(scoreStorage) - galleryItems = provideGalleryItems().toMutableList() - intent { + statsStorage = statsStorageRepo.provide(index) + scoreWidgetController.init(scoreStorage) + galleryItems = provideGalleryItems().toMutableList() reduce { viewModelScope.launch { state.copy( @@ -264,9 +260,7 @@ class GalleryUpliftViewModel( } state } - postSideEffect( - GallerySideEffect.UpdatePagerAdapter - ) + postSideEffect(GallerySideEffect.UpdatePagerAdapter) postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressWithText( @@ -275,9 +269,10 @@ class GalleryUpliftViewModel( ) ) ) + scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } - scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } + } fun onPlayButtonClick() = intent { @@ -427,15 +422,15 @@ class GalleryUpliftViewModel( fun onPageChanged(newPos: Int) = viewModelScope.launch { if (galleryItems.isEmpty()) return@launch - checkResourceChanges(newPos) intent { reduce { state.copy(currentPos = newPos) } + checkResourceChanges(newPos) + val id = currentItem.id() + val tags = tagsStorage.getTags(id) + displayPreview(id, currentItem.metadata, tags) } - val id = currentItem.id() - val tags = tagsStorage.getTags(id) - displayPreview(id, currentItem.metadata, tags) } fun onTagSelected(tag: Tag) { @@ -509,9 +504,6 @@ class GalleryUpliftViewModel( ) ) ) - } - - intent { postSideEffect( GallerySideEffect.DisplayPreviewTags( ResourceIdTagsPreview( @@ -520,10 +512,15 @@ class GalleryUpliftViewModel( ) ) ) - } - scoreWidgetController.displayScore() - - intent { + scoreWidgetController.displayScore() + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = id, + tags = tags, + ) + ) + ) postSideEffect( GallerySideEffect.DisplaySelectedFile( DisplaySelected( @@ -590,50 +587,45 @@ class GalleryUpliftViewModel( ) ) ) - } - - index.updateAll() - - intent { + index.updateAll() postSideEffect(GallerySideEffect.NotifyResourceChange) - } - viewModelScope.launch { - metadataStorage.busy.collect { busy -> - if (!busy) cancel() - } - }.join() + viewModelScope.launch { + metadataStorage.busy.collect { busy -> + if (!busy) cancel() + } + }.join() - val newItems = provideGalleryItems() - if (newItems.isEmpty()) { - intent { + val newItems = provideGalleryItems() + if (newItems.isEmpty()) { postSideEffect(GallerySideEffect.NavigateBack) + return@intent + } + if (newItems.isEmpty()) { + intent { + postSideEffect(GallerySideEffect.NavigateBack) + } + return@intent } - return@launch - } - diffResult = DiffUtil.calculateDiff( - ResourceDiffUtilCallback( - galleryItems.map { it.resource.id }, - newItems.map { it.resource.id } + diffResult = DiffUtil.calculateDiff( + ResourceDiffUtilCallback( + galleryItems.map { it.resource.id }, + newItems.map { it.resource.id } + ) ) - ) - - galleryItems = newItems.toMutableList() - viewModelScope.launch { - intent { - postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) - postSideEffect(GallerySideEffect.NotifyCurrentItemChange) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" - ) + galleryItems = newItems.toMutableList() + postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) + postSideEffect(GallerySideEffect.NotifyCurrentItemChange) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressWithText( + isVisible = true, + text = "Changes detected, indexing" ) ) - } + ) } } } From ab3b641f7838c589a7f935da1ccae161dcffa68e Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 16 Jun 2024 22:04:09 +0700 Subject: [PATCH 41/74] Remove space --- .../galleryuplift/GalleryUpliftViewModel.kt | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 1fe09f75..3c71fb0a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -272,7 +272,6 @@ class GalleryUpliftViewModel( scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } } - } fun onPlayButtonClick() = intent { @@ -443,12 +442,11 @@ class GalleryUpliftViewModel( } fun onTagRemove(tag: Tag) = viewModelScope.launch(NonCancellable) { - analytics.trackTagRemove() - val id = currentItem.id() - val tags = tagsStorage.getTags(id) - val newTags = tags - tag - intent { + analytics.trackTagRemove() + val id = currentItem.id() + val tags = tagsStorage.getTags(id) + val newTags = tags - tag postSideEffect( GallerySideEffect.DisplayPreviewTags( ResourceIdTagsPreview( @@ -457,24 +455,24 @@ class GalleryUpliftViewModel( ) ) ) - } - statsStorage.handleEvent( - StatsEvent.TagsChanged( - id, tags, newTags + statsStorage.handleEvent( + StatsEvent.TagsChanged( + id, tags, newTags + ) ) - ) - - Timber.d(LogTags.GALLERY_SCREEN, "setting new tags $newTags to $currentItem") - tagsStorage.setTags(id, newTags) - tagsStorage.persist() - intent { + Timber.d( + LogTags.GALLERY_SCREEN, + "setting new tags $newTags to $currentItem" + ) + tagsStorage.setTags(id, newTags) + tagsStorage.persist() postSideEffect(GallerySideEffect.NotifyTagsChanged) } } fun onEditTagsDialogBtnClick() { - analytics.trackTagsEdit() intent { + analytics.trackTagsEdit() postSideEffect( GallerySideEffect.ShowEditTagsDialog( ShowEditTagsData( From 6966bd520f6e053b22183303ac6aa0489145f946 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Thu, 20 Jun 2024 00:14:55 +0700 Subject: [PATCH 42/74] Fix score widget not shown --- .../galleryuplift/GalleryUpliftFragment.kt | 2 ++ .../galleryuplift/GalleryUpliftViewModel.kt | 15 +++++---------- .../gallery/galleryuplift/state/GalleryState.kt | 1 - 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 649693c0..e8b73a98 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -35,6 +35,7 @@ import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget +import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R import dev.arkbuilders.navigator.data.stats.StatsStorage @@ -58,6 +59,7 @@ import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts import kotlinx.coroutines.launch +import moxy.presenterScope import org.orbitmvi.orbit.viewmodel.observe import timber.log.Timber import java.nio.file.Path diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 3c71fb0a..a454528d 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -250,15 +250,11 @@ class GalleryUpliftViewModel( statsStorage = statsStorageRepo.provide(index) scoreWidgetController.init(scoreStorage) galleryItems = provideGalleryItems().toMutableList() - reduce { - viewModelScope.launch { - state.copy( - sortByScores = preferences.get( - PreferenceKey.SortByScores - ) - ) - } - state + viewModelScope.launch { + val result = preferences.get( + PreferenceKey.SortByScores + ) + scoreWidgetController.setVisible(result) } postSideEffect(GallerySideEffect.UpdatePagerAdapter) postSideEffect( @@ -269,7 +265,6 @@ class GalleryUpliftViewModel( ) ) ) - scoreWidgetController.setVisible(container.stateFlow.value.sortByScores) } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index c5348471..13eef281 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -11,7 +11,6 @@ import java.nio.file.Path data class GalleryState( val currentPos: Int = 0, - val sortByScores: Boolean = false, val selectingEnabled: Boolean = false, ) From f5ad7ace8bc7aaec1e80ec7685dbd6ef0afeed2f Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:49:55 +0700 Subject: [PATCH 43/74] Remove unused class --- .../screen/gallery/galleryuplift/domain/ProgressWithText.kt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt deleted file mode 100644 index 264d9d2e..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ProgressWithText.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -data class ProgressWithText( - val isVisible: Boolean, - val text: String, -) From 84bd6d5a703e84312a6012e5063dc0eafcd01792 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:50:11 +0700 Subject: [PATCH 44/74] Extract state of progress --- .../gallery/galleryuplift/state/GalleryState.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 13eef281..6bb3e12d 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -1,7 +1,6 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressWithText import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData @@ -14,6 +13,15 @@ data class GalleryState( val selectingEnabled: Boolean = false, ) +sealed interface ProgressState { + data object ProvidingRootIndex: ProgressState + data object ProvidingMetaDataStorage: ProgressState + data object ProvidingPreviewStorage: ProgressState + data object ProvidingDataStorage: ProgressState + data object Indexing: ProgressState + data object HideProgress: ProgressState +} + sealed class GallerySideEffect { data object NotifyResourceScoresChanged : GallerySideEffect() data class ControlVisible(val isVisible: Boolean) : GallerySideEffect() @@ -39,7 +47,7 @@ sealed class GallerySideEffect { data class SetUpPreview(val data: SetupPreview) : GallerySideEffect() data class DisplaySelectedFile(val data: DisplaySelected) : GallerySideEffect() data object NotifyResourceChange : GallerySideEffect() - data class ShowProgressWithText(val text: ProgressWithText) : GallerySideEffect() + data class ShowProgressWithText(val state: ProgressState) : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() data object UpdatePagerAdapterWithDiff : GallerySideEffect() data class ToggleSelect(val isEnabled: Boolean) : GallerySideEffect() From 9d3576e3320ee7211a41ac9bbb93ae09eed72c39 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:50:26 +0700 Subject: [PATCH 45/74] Use new progress state --- .../galleryuplift/GalleryUpliftFragment.kt | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index e8b73a98..35d61479 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -50,6 +50,7 @@ import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.ProgressState import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader @@ -59,7 +60,6 @@ import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts import kotlinx.coroutines.launch -import moxy.presenterScope import org.orbitmvi.orbit.viewmodel.observe import timber.log.Timber import java.nio.file.Path @@ -241,9 +241,8 @@ class GalleryUpliftFragment : Fragment() { metadata = infoData.metadata ) - is GallerySideEffect.ShowProgressWithText -> setProgressVisibility( - isVisible = text.isVisible, - withText = text.text + is GallerySideEffect.ShowProgressWithText -> handleProgressState( + state ) is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath( @@ -453,8 +452,42 @@ class GalleryUpliftFragment : Fragment() { dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) } + private fun handleProgressState(state: ProgressState) { + when (state) { + ProgressState.HideProgress -> setProgressVisibility( + isVisible = false, + withText = "" + ) + + ProgressState.Indexing -> setProgressVisibility( + isVisible = true, + withText = getString(R.string.progress_text_changes_detected_indexing) + ) + + ProgressState.ProvidingDataStorage -> setProgressVisibility( + isVisible = true, + withText = getString(R.string.progress_text_providing_data_storage) + ) + + ProgressState.ProvidingMetaDataStorage -> setProgressVisibility( + isVisible = true, + withText = getString(R.string.progress_text_providing_metadata_storage) + ) + + ProgressState.ProvidingPreviewStorage -> setProgressVisibility( + isVisible = true, + withText = getString(R.string.progress_text_providing_previews_storage) + ) + + ProgressState.ProvidingRootIndex -> setProgressVisibility( + isVisible = true, + withText = getString(R.string.progress_text_providing_root_index) + ) + } + } + @SuppressLint("ClickableViewAccessibility") - fun setProgressVisibility(isVisible: Boolean, withText: String) { + private fun setProgressVisibility(isVisible: Boolean, withText: String) { binding.layoutProgress.apply { root.isVisible = isVisible From 6b5965d92a843288ec3234a7556bcb10c0845a3d Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:50:33 +0700 Subject: [PATCH 46/74] Use new progress state --- .../galleryuplift/GalleryUpliftViewModel.kt | 65 +++++-------------- 1 file changed, 16 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index a454528d..5f9af9d1 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -34,7 +34,6 @@ import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressWithText import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData @@ -42,6 +41,7 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domai import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.ProgressState import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable @@ -185,14 +185,7 @@ class GalleryUpliftViewModel( "first view attached in GalleryPresenter" ) viewModelScope.launch { - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing root index", - ) - ) - ) + postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingRootIndex)) index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { @@ -206,32 +199,11 @@ class GalleryUpliftViewModel( } } }.launchIn(viewModelScope) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing metadata storage", - ) - ) - ) + postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingMetaDataStorage)) metadataStorage = metadataStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing previews storage", - ) - ) - ) + postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingPreviewStorage)) previewStorage = previewStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Providing data storage", - ) - ) - ) + postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingDataStorage)) try { tagsStorage = tagsStorageRepo.provide(index) @@ -257,14 +229,7 @@ class GalleryUpliftViewModel( scoreWidgetController.setVisible(result) } postSideEffect(GallerySideEffect.UpdatePagerAdapter) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = false, - text = "", - ) - ) - ) + postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.HideProgress)) } } } @@ -574,10 +539,11 @@ class GalleryUpliftViewModel( intent { postSideEffect( GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" - ) + ProgressState.Indexing +// ProgressWithText( +// isVisible = true, +// text = "Changes detected, indexing" +// ) ) ) index.updateAll() @@ -613,10 +579,11 @@ class GalleryUpliftViewModel( postSideEffect(GallerySideEffect.NotifyCurrentItemChange) postSideEffect( GallerySideEffect.ShowProgressWithText( - ProgressWithText( - isVisible = true, - text = "Changes detected, indexing" - ) + ProgressState.Indexing +// ProgressWithText( +// isVisible = true, +// text = "Changes detected, indexing" +// ) ) ) } From c542b8425d614eb8a4095fde84b17a58e26c5a4d Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:50:43 +0700 Subject: [PATCH 47/74] Extract strings --- app/src/main/res/values/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c5ed6d76..c11dd963 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -131,4 +131,9 @@ Close Corrupted Storage %1$s storage is corrupted. \nCause: %2$s. \nOpening the folder isn\'t safe + Changes detected, indexing + Providing data storage + Providing metadata storage + Providing previews storage + Providing root index From ba5f639b3e6c48c9ad113e1fb45ec91a2f9df511 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 09:53:39 +0700 Subject: [PATCH 48/74] Fix klint code format --- .../gallery/galleryuplift/GalleryUpliftViewModel.kt | 4 +++- .../gallery/galleryuplift/state/GalleryState.kt | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 5f9af9d1..4f2ac161 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -229,7 +229,9 @@ class GalleryUpliftViewModel( scoreWidgetController.setVisible(result) } postSideEffect(GallerySideEffect.UpdatePagerAdapter) - postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.HideProgress)) + postSideEffect( + GallerySideEffect.ShowProgressWithText(ProgressState.HideProgress) + ) } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 6bb3e12d..98300709 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -14,12 +14,12 @@ data class GalleryState( ) sealed interface ProgressState { - data object ProvidingRootIndex: ProgressState - data object ProvidingMetaDataStorage: ProgressState - data object ProvidingPreviewStorage: ProgressState - data object ProvidingDataStorage: ProgressState - data object Indexing: ProgressState - data object HideProgress: ProgressState + data object ProvidingRootIndex : ProgressState + data object ProvidingMetaDataStorage : ProgressState + data object ProvidingPreviewStorage : ProgressState + data object ProvidingDataStorage : ProgressState + data object Indexing : ProgressState + data object HideProgress : ProgressState } sealed class GallerySideEffect { From d6ae001094075815090baf4c893c19eecb13f4b7 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 10:00:13 +0700 Subject: [PATCH 49/74] Fix klint code format --- .../galleryuplift/GalleryUpliftFragment.kt | 25 ++++++++-------- .../galleryuplift/GalleryUpliftViewModel.kt | 29 +++++++++++++++---- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 35d61479..eb3daab8 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -35,7 +35,6 @@ import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget -import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R import dev.arkbuilders.navigator.data.stats.StatsStorage @@ -455,33 +454,33 @@ class GalleryUpliftFragment : Fragment() { private fun handleProgressState(state: ProgressState) { when (state) { ProgressState.HideProgress -> setProgressVisibility( - isVisible = false, - withText = "" + false, + "" ) ProgressState.Indexing -> setProgressVisibility( - isVisible = true, - withText = getString(R.string.progress_text_changes_detected_indexing) + true, + getString(R.string.progress_text_changes_detected_indexing) ) ProgressState.ProvidingDataStorage -> setProgressVisibility( - isVisible = true, - withText = getString(R.string.progress_text_providing_data_storage) + true, + getString(R.string.progress_text_providing_data_storage) ) ProgressState.ProvidingMetaDataStorage -> setProgressVisibility( - isVisible = true, - withText = getString(R.string.progress_text_providing_metadata_storage) + true, + getString(R.string.progress_text_providing_metadata_storage) ) ProgressState.ProvidingPreviewStorage -> setProgressVisibility( - isVisible = true, - withText = getString(R.string.progress_text_providing_previews_storage) + true, + getString(R.string.progress_text_providing_previews_storage) ) ProgressState.ProvidingRootIndex -> setProgressVisibility( - isVisible = true, - withText = getString(R.string.progress_text_providing_root_index) + true, + getString(R.string.progress_text_providing_root_index) ) } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 4f2ac161..6636f7f3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -185,7 +185,11 @@ class GalleryUpliftViewModel( "first view attached in GalleryPresenter" ) viewModelScope.launch { - postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingRootIndex)) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingRootIndex + ) + ) index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { @@ -199,12 +203,23 @@ class GalleryUpliftViewModel( } } }.launchIn(viewModelScope) - postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingMetaDataStorage)) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingMetaDataStorage + ) + ) metadataStorage = metadataStorageRepo.provide(index) - postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingPreviewStorage)) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingPreviewStorage + ) + ) previewStorage = previewStorageRepo.provide(index) - postSideEffect(GallerySideEffect.ShowProgressWithText(ProgressState.ProvidingDataStorage)) - + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingDataStorage + ) + ) try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) @@ -230,7 +245,9 @@ class GalleryUpliftViewModel( } postSideEffect(GallerySideEffect.UpdatePagerAdapter) postSideEffect( - GallerySideEffect.ShowProgressWithText(ProgressState.HideProgress) + GallerySideEffect.ShowProgressWithText( + ProgressState.HideProgress + ) ) } } From 78495fc02aad79e337fc52dbac00a9b07d16bcd5 Mon Sep 17 00:00:00 2001 From: Hieu Vu Date: Sun, 23 Jun 2024 10:02:49 +0700 Subject: [PATCH 50/74] Fix klint code format --- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 6636f7f3..a14b24f8 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -232,7 +232,6 @@ class GalleryUpliftViewModel( ) ) ) - } statsStorage = statsStorageRepo.provide(index) scoreWidgetController.init(scoreStorage) From 64e7e05657c550907fabe29af38edc7b9bf30ead Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Tue, 3 Sep 2024 22:08:16 +0600 Subject: [PATCH 51/74] Move controlsVisible to state --- .../screen/gallery/galleryuplift/GalleryUpliftFragment.kt | 5 +---- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 2 +- .../screen/gallery/galleryuplift/state/GalleryState.kt | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index eb3daab8..181d025a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -185,9 +185,6 @@ class GalleryUpliftFragment : Fragment() { private fun handleSideEffect(sideEffect: GallerySideEffect) { with(sideEffect) { when (this) { - is GallerySideEffect.ControlVisible -> - setControlsVisibility(visible = isVisible) - is GallerySideEffect.DeleteResource -> deleteResource(pos) is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( resource = data.resourceId, @@ -259,7 +256,7 @@ class GalleryUpliftFragment : Fragment() { } private fun render(state: GalleryState) { - setControlsVisibility(state.selectingEnabled) + setControlsVisibility(state.controlsVisible) } private fun onBackClick() { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index a14b24f8..9aa2987b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -110,7 +110,7 @@ class GalleryUpliftViewModel( fun onPreviewsItemClick() { intent { - postSideEffect(GallerySideEffect.ControlVisible(isVisible = true)) + reduce { state.copy(controlsVisible = !state.controlsVisible) } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 98300709..c196565e 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -11,6 +11,7 @@ import java.nio.file.Path data class GalleryState( val currentPos: Int = 0, val selectingEnabled: Boolean = false, + val controlsVisible: Boolean = true, ) sealed interface ProgressState { @@ -24,7 +25,6 @@ sealed interface ProgressState { sealed class GallerySideEffect { data object NotifyResourceScoresChanged : GallerySideEffect() - data class ControlVisible(val isVisible: Boolean) : GallerySideEffect() data object NavigateBack : GallerySideEffect() data class DeleteResource(val pos: Int) : GallerySideEffect() data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() From bfba730ee1053562761011521cf7554ccafab7f4 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Tue, 3 Sep 2024 22:12:39 +0600 Subject: [PATCH 52/74] Move rootAndFav to state --- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 7 ++++++- .../screen/gallery/galleryuplift/state/GalleryState.kt | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 9aa2987b..146a573f 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -86,7 +86,12 @@ class GalleryUpliftViewModel( private lateinit var scoreStorage: ScoreStorage override val container: Container = - container(GalleryState(selectingEnabled = selectingEnabled)) + container( + GalleryState( + rootAndFav = rootAndFav, + selectingEnabled = selectingEnabled + ) + ) var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index c196565e..1574a509 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -1,5 +1,6 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state +import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview @@ -9,6 +10,7 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domai import java.nio.file.Path data class GalleryState( + val rootAndFav: RootAndFav, val currentPos: Int = 0, val selectingEnabled: Boolean = false, val controlsVisible: Boolean = true, From ed4437417d8228710da0e9677c373c5ff22bab77 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Tue, 3 Sep 2024 22:58:54 +0600 Subject: [PATCH 53/74] call initStorages from viewmodel init --- .../galleryuplift/GalleryUpliftFragment.kt | 1 - .../galleryuplift/GalleryUpliftViewModel.kt | 152 +++++++++--------- 2 files changed, 77 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 181d025a..592a98e0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -109,7 +109,6 @@ class GalleryUpliftFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") App.instance.appComponent.inject(this) - viewModel.initStorages() super.onViewCreated(view, savedInstanceState) Timber.d( LogTags.GALLERY_SCREEN, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 146a573f..b25ae8bf 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -113,6 +113,10 @@ class GalleryUpliftViewModel( private val currentItem: GalleryPresenter.GalleryItem get() = galleryItems[container.stateFlow.value.currentPos] + init { + initStorages() + } + fun onPreviewsItemClick() { intent { reduce { state.copy(controlsVisible = !state.controlsVisible) } @@ -182,81 +186,6 @@ class GalleryUpliftViewModel( } } - fun initStorages() { - intent { - analytics.trackScreen() - Timber.d( - LogTags.GALLERY_SCREEN, - "first view attached in GalleryPresenter" - ) - viewModelScope.launch { - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingRootIndex - ) - ) - index = indexRepo.provide(rootAndFav) - messageFlow.onEach { message -> - when (message) { - is Message.KindDetectFailed -> - intent { - postSideEffect( - GallerySideEffect.ToastIndexFailedPath( - message.path - ) - ) - } - } - }.launchIn(viewModelScope) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingMetaDataStorage - ) - ) - metadataStorage = metadataStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingPreviewStorage - ) - ) - previewStorage = previewStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingDataStorage - ) - ) - try { - tagsStorage = tagsStorageRepo.provide(index) - scoreStorage = scoreStorageRepo.provide(index) - } catch (e: StorageException) { - postSideEffect( - GallerySideEffect.DisplayStorageException( - StorageExceptionGallery( - label = e.label, - messenger = e.msg - ) - ) - ) - } - statsStorage = statsStorageRepo.provide(index) - scoreWidgetController.init(scoreStorage) - galleryItems = provideGalleryItems().toMutableList() - viewModelScope.launch { - val result = preferences.get( - PreferenceKey.SortByScores - ) - scoreWidgetController.setVisible(result) - } - postSideEffect(GallerySideEffect.UpdatePagerAdapter) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.HideProgress - ) - ) - } - } - } - fun onPlayButtonClick() = intent { postSideEffect( GallerySideEffect.ViewInExternalApp( @@ -622,4 +551,77 @@ class GalleryUpliftViewModel( Result.failure(e) } } + + private fun initStorages() = intent { + analytics.trackScreen() + Timber.d( + LogTags.GALLERY_SCREEN, + "first view attached in GalleryPresenter" + ) + viewModelScope.launch { + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingRootIndex + ) + ) + index = indexRepo.provide(rootAndFav) + messageFlow.onEach { message -> + when (message) { + is Message.KindDetectFailed -> + intent { + postSideEffect( + GallerySideEffect.ToastIndexFailedPath( + message.path + ) + ) + } + } + }.launchIn(viewModelScope) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingMetaDataStorage + ) + ) + metadataStorage = metadataStorageRepo.provide(index) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingPreviewStorage + ) + ) + previewStorage = previewStorageRepo.provide(index) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingDataStorage + ) + ) + try { + tagsStorage = tagsStorageRepo.provide(index) + scoreStorage = scoreStorageRepo.provide(index) + } catch (e: StorageException) { + postSideEffect( + GallerySideEffect.DisplayStorageException( + StorageExceptionGallery( + label = e.label, + messenger = e.msg + ) + ) + ) + } + statsStorage = statsStorageRepo.provide(index) + scoreWidgetController.init(scoreStorage) + galleryItems = provideGalleryItems().toMutableList() + viewModelScope.launch { + val result = preferences.get( + PreferenceKey.SortByScores + ) + scoreWidgetController.setVisible(result) + } + postSideEffect(GallerySideEffect.UpdatePagerAdapter) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.HideProgress + ) + ) + } + } } From 439537e893308f4b185ff4dc9af5822ac0510c1e Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 00:01:21 +0600 Subject: [PATCH 54/74] Handle startPos in viewModel --- .../galleryuplift/GalleryUpliftFragment.kt | 20 +-- .../galleryuplift/GalleryUpliftViewModel.kt | 115 +++++++++--------- .../GalleryUpliftViewModelFactory.kt | 3 + .../galleryuplift/state/GalleryState.kt | 1 + 4 files changed, 74 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 592a98e0..1591adfb 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -72,6 +72,7 @@ class GalleryUpliftFragment : Fragment() { lateinit var factory: GalleryUpliftViewModelFactory.Factory private val viewModel: GalleryUpliftViewModel by viewModels { factory.create( + startPos = requireArguments().getInt(START_AT_KEY), selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! @@ -184,6 +185,16 @@ class GalleryUpliftFragment : Fragment() { private fun handleSideEffect(sideEffect: GallerySideEffect) { with(sideEffect) { when (this) { + is GallerySideEffect.ScrollToPage -> { + binding.viewPager.adapter?.itemCount?.let { count -> + if (this.pos < count) { + binding.viewPager.setCurrentItem( + this.pos, + false + ) + } + } + } is GallerySideEffect.DeleteResource -> deleteResource(pos) is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( resource = data.resourceId, @@ -267,15 +278,6 @@ class GalleryUpliftFragment : Fragment() { private fun updatePagerAdapter() { pagerAdapter.notifyDataSetChanged() - binding.viewPager.adapter?.itemCount?.let { count -> - val startAt = requireArguments().getInt(START_AT_KEY) - if (startAt < count) { - binding.viewPager.setCurrentItem( - startAt, - false - ) - } - } } private fun updatePagerAdapterWithDiff() { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index b25ae8bf..0a470b01 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -65,6 +65,7 @@ import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists class GalleryUpliftViewModel( + startPos: Int, selectingEnabled: Boolean, private val rootAndFav: RootAndFav, private val resourcesIds: List, @@ -89,6 +90,7 @@ class GalleryUpliftViewModel( container( GalleryState( rootAndFav = rootAndFav, + currentPos = startPos, selectingEnabled = selectingEnabled ) ) @@ -115,6 +117,9 @@ class GalleryUpliftViewModel( init { initStorages() + intent { + postSideEffect(GallerySideEffect.ScrollToPage(state.currentPos)) + } } fun onPreviewsItemClick() { @@ -558,70 +563,68 @@ class GalleryUpliftViewModel( LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter" ) - viewModelScope.launch { - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingRootIndex - ) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingRootIndex ) - index = indexRepo.provide(rootAndFav) - messageFlow.onEach { message -> - when (message) { - is Message.KindDetectFailed -> - intent { - postSideEffect( - GallerySideEffect.ToastIndexFailedPath( - message.path - ) + ) + index = indexRepo.provide(rootAndFav) + messageFlow.onEach { message -> + when (message) { + is Message.KindDetectFailed -> + intent { + postSideEffect( + GallerySideEffect.ToastIndexFailedPath( + message.path ) - } - } - }.launchIn(viewModelScope) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingMetaDataStorage - ) + ) + } + } + }.launchIn(viewModelScope) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingMetaDataStorage ) - metadataStorage = metadataStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingPreviewStorage - ) + ) + metadataStorage = metadataStorageRepo.provide(index) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingPreviewStorage ) - previewStorage = previewStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingDataStorage - ) + ) + previewStorage = previewStorageRepo.provide(index) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.ProvidingDataStorage ) - try { - tagsStorage = tagsStorageRepo.provide(index) - scoreStorage = scoreStorageRepo.provide(index) - } catch (e: StorageException) { - postSideEffect( - GallerySideEffect.DisplayStorageException( - StorageExceptionGallery( - label = e.label, - messenger = e.msg - ) - ) - ) - } - statsStorage = statsStorageRepo.provide(index) - scoreWidgetController.init(scoreStorage) - galleryItems = provideGalleryItems().toMutableList() - viewModelScope.launch { - val result = preferences.get( - PreferenceKey.SortByScores - ) - scoreWidgetController.setVisible(result) - } - postSideEffect(GallerySideEffect.UpdatePagerAdapter) + ) + try { + tagsStorage = tagsStorageRepo.provide(index) + scoreStorage = scoreStorageRepo.provide(index) + } catch (e: StorageException) { postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.HideProgress + GallerySideEffect.DisplayStorageException( + StorageExceptionGallery( + label = e.label, + messenger = e.msg + ) ) ) } + statsStorage = statsStorageRepo.provide(index) + scoreWidgetController.init(scoreStorage) + galleryItems = provideGalleryItems().toMutableList() + viewModelScope.launch { + val result = preferences.get( + PreferenceKey.SortByScores + ) + scoreWidgetController.setVisible(result) + } + postSideEffect(GallerySideEffect.UpdatePagerAdapter) + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.HideProgress + ) + ) } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt index 34ff4d78..6cb7c4f4 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt @@ -18,6 +18,7 @@ import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.presentation.navigation.AppRouter class GalleryUpliftViewModelFactory @AssistedInject constructor( + @Assisted val startPos: Int, @Assisted val selectingEnabled: Boolean, @Assisted private val rootAndFav: RootAndFav, @Assisted private val resourcesIds: List, @@ -33,6 +34,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { return GalleryUpliftViewModel( + startPos = startPos, selectingEnabled = selectingEnabled, rootAndFav = rootAndFav, resourcesIds = resourcesIds, @@ -51,6 +53,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @AssistedFactory interface Factory { fun create( + @Assisted startPos: Int, @Assisted selectingEnabled: Boolean, @Assisted rootAndFav: RootAndFav, @Assisted resourcesIds: List, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 1574a509..5424d993 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -26,6 +26,7 @@ sealed interface ProgressState { } sealed class GallerySideEffect { + data class ScrollToPage(val pos: Int): GallerySideEffect() data object NotifyResourceScoresChanged : GallerySideEffect() data object NavigateBack : GallerySideEffect() data class DeleteResource(val pos: Int) : GallerySideEffect() From 0b742bc0a8ea462cbac20738e0ef501e8d773110 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 00:32:22 +0600 Subject: [PATCH 55/74] update pager items in render, move gallery items to state --- .../galleryuplift/GalleryUpliftFragment.kt | 1 + .../galleryuplift/GalleryUpliftViewModel.kt | 7 +++++-- .../galleryuplift/PreviewsPagerUplift.kt | 21 ++++++++++++++++++- .../galleryuplift/state/GalleryState.kt | 2 ++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 1591adfb..d73d1aff 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -266,6 +266,7 @@ class GalleryUpliftFragment : Fragment() { } private fun render(state: GalleryState) { + pagerAdapter.dispatchUpdates(state.galleryItems) setControlsVisibility(state.controlsVisible) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 0a470b01..a1739a66 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -53,6 +53,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.orbitmvi.orbit.Container import org.orbitmvi.orbit.ContainerHost +import org.orbitmvi.orbit.syntax.simple.blockingIntent import org.orbitmvi.orbit.syntax.simple.intent import org.orbitmvi.orbit.syntax.simple.postSideEffect import org.orbitmvi.orbit.syntax.simple.reduce @@ -557,7 +558,7 @@ class GalleryUpliftViewModel( } } - private fun initStorages() = intent { + private fun initStorages() = blockingIntent { analytics.trackScreen() Timber.d( LogTags.GALLERY_SCREEN, @@ -620,7 +621,9 @@ class GalleryUpliftViewModel( ) scoreWidgetController.setVisible(result) } - postSideEffect(GallerySideEffect.UpdatePagerAdapter) + reduce { + state.copy(galleryItems = galleryItems) + } postSideEffect( GallerySideEffect.ShowProgressWithText( ProgressState.HideProgress diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt index cbbbdec5..345279d2 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt @@ -7,18 +7,37 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.ViewGroup import androidx.core.view.GestureDetectorCompat +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import dev.arkbuilders.arklib.data.meta.Kind import dev.arkbuilders.navigator.databinding.ItemImageBinding import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewPlainTextViewHolder +import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback class PreviewsPagerUplift( val context: Context, val viewModel: GalleryUpliftViewModel, ) : RecyclerView.Adapter() { + private var galleryItems = emptyList() - override fun getItemCount() = viewModel.galleryItems.size + fun dispatchUpdates(newItems: List) { + if (newItems == galleryItems) + return + val diff = DiffUtil.calculateDiff( + ResourceDiffUtilCallback( + galleryItems.map { it.resource.id }, + newItems.map { it.resource.id } + ) + ) + galleryItems = newItems + diff.dispatchUpdatesTo(this) + } + + override fun getItemCount(): Int { + return galleryItems.size + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = if (viewType == Kind.PLAINTEXT.ordinal) { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 5424d993..8a0a3521 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -1,6 +1,7 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state import dev.arkbuilders.arkfilepicker.folders.RootAndFav +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview @@ -12,6 +13,7 @@ import java.nio.file.Path data class GalleryState( val rootAndFav: RootAndFav, val currentPos: Int = 0, + val galleryItems: List = emptyList(), val selectingEnabled: Boolean = false, val controlsVisible: Boolean = true, ) From 811a17da39b59f0cdc3203d3644a143739b0e789 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 00:43:05 +0600 Subject: [PATCH 56/74] Add path to GalleryItem, replace GalleryPresenter.GalleryItem --- .../galleryuplift/GalleryUpliftViewModel.kt | 11 ++++++----- .../gallery/galleryuplift/PreviewsPagerUplift.kt | 6 +++--- .../gallery/galleryuplift/domain/GalleryItem.kt | 15 +++++++++++++++ .../gallery/galleryuplift/state/GalleryState.kt | 4 ++-- 4 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index a1739a66..c7fec60e 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -32,8 +32,8 @@ import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData @@ -96,7 +96,7 @@ class GalleryUpliftViewModel( ) ) - var galleryItems: MutableList = mutableListOf() + var galleryItems: MutableList = mutableListOf() var diffResult: DiffUtil.DiffResult? = null private val _selectedResources: MutableList = mutableListOf() @@ -113,7 +113,7 @@ class GalleryUpliftViewModel( ) private val messageFlow: MutableSharedFlow = MutableSharedFlow() - private val currentItem: GalleryPresenter.GalleryItem + private val currentItem: GalleryItem get() = galleryItems[container.stateFlow.value.currentPos] init { @@ -474,18 +474,19 @@ class GalleryUpliftViewModel( } } - private fun provideGalleryItems(): List = + private fun provideGalleryItems(): List = try { val allResources = index.allResources() resourcesIds .filter { allResources.keys.contains(it) } .map { id -> + val path = index.getPath(id)!! val preview = previewStorage.retrieve(id).getOrThrow() val metadata = metadataStorage.retrieve(id).getOrThrow() val resource = allResources.getOrElse(id) { throw NullPointerException("Resource not exist") } - GalleryPresenter.GalleryItem(resource, preview, metadata) + GalleryItem(resource, preview, metadata, path) }.toMutableList() } catch (e: Exception) { Timber.d("Can't provide gallery items") diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt index 345279d2..8658964c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt @@ -12,7 +12,7 @@ import androidx.recyclerview.widget.RecyclerView import dev.arkbuilders.arklib.data.meta.Kind import dev.arkbuilders.navigator.databinding.ItemImageBinding import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewPlainTextViewHolder import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback @@ -20,9 +20,9 @@ class PreviewsPagerUplift( val context: Context, val viewModel: GalleryUpliftViewModel, ) : RecyclerView.Adapter() { - private var galleryItems = emptyList() + private var galleryItems = emptyList() - fun dispatchUpdates(newItems: List) { + fun dispatchUpdates(newItems: List) { if (newItems == galleryItems) return val diff = DiffUtil.calculateDiff( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt new file mode 100644 index 00000000..5e6e3c67 --- /dev/null +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt @@ -0,0 +1,15 @@ +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain + +import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.data.preview.PreviewLocator +import java.nio.file.Path + +data class GalleryItem( + val resource: Resource, + val preview: PreviewLocator, + val metadata: Metadata, + val path: Path +) { + fun id() = resource.id +} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 8a0a3521..a0d2f115 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -1,8 +1,8 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData @@ -13,7 +13,7 @@ import java.nio.file.Path data class GalleryState( val rootAndFav: RootAndFav, val currentPos: Int = 0, - val galleryItems: List = emptyList(), + val galleryItems: List = emptyList(), val selectingEnabled: Boolean = false, val controlsVisible: Boolean = true, ) From 9322a71ee794d5e4af48456fc904634fe8a76d9f Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 01:05:52 +0600 Subject: [PATCH 57/74] dont bind viewholders in viewmodel --- .../galleryuplift/GalleryUpliftFragment.kt | 4 +- .../galleryuplift/GalleryUpliftViewModel.kt | 23 -------- .../PreviewPlainTextViewHolderUplift.kt | 4 -- .../galleryuplift/PreviewsPagerUplift.kt | 55 +++++++++++++++---- 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index d73d1aff..2a5b4d0b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -125,7 +125,8 @@ class GalleryUpliftFragment : Fragment() { requireActivity().onBackPressedDispatcher.addCallback(this) { onBackClick() } - pagerAdapter = PreviewsPagerUplift(requireContext(), viewModel) + pagerAdapter = + PreviewsPagerUplift(lifecycleScope, requireContext(), viewModel) initViewPager() scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) @@ -195,6 +196,7 @@ class GalleryUpliftFragment : Fragment() { } } } + is GallerySideEffect.DeleteResource -> deleteResource(pos) is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( resource = data.resourceId, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index c7fec60e..255794a8 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -129,29 +129,6 @@ class GalleryUpliftViewModel( } } - fun bindPlainTextView(view: PreviewPlainTextViewHolderUplift) { - viewModelScope.launch { - view.reset() - val item = galleryItems[view.pos] - val path = index.getPath(item.id())!! - val content = readText(path) - content.onSuccess { - view.setContent(it) - } - } - } - - fun bindView(view: PreviewImageViewHolderUplift) = viewModelScope.launch { - view.reset() - val item = galleryItems[view.pos] - val path = index.getPath(item.id())!! - val placeholder = ImageUtils.iconForExtension(extension(path)) - view.setSource(placeholder, item.id(), item.metadata, item.preview) - } - - fun getKind(pos: Int): Int = - galleryItems[pos].metadata.kind.ordinal - fun onRemoveFabClick() = viewModelScope.launch(NonCancellable) { intent { analytics.trackResRemove() diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt index 995996ec..d9da3883 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt @@ -21,8 +21,4 @@ class PreviewPlainTextViewHolderUplift( fun setContent(text: String) = with(binding) { tvContent.text = text } - - fun reset() = with(binding) { - tvContent.text = "" - } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt index 8658964c..04d2ece0 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt @@ -10,13 +10,21 @@ import androidx.core.view.GestureDetectorCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import dev.arkbuilders.arklib.data.meta.Kind +import dev.arkbuilders.arklib.utils.ImageUtils +import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.navigator.databinding.ItemImageBinding import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewPlainTextViewHolder import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.FileReader +import java.nio.file.Path class PreviewsPagerUplift( + val lifecycleScope: CoroutineScope, val context: Context, val viewModel: GalleryUpliftViewModel, ) : RecyclerView.Adapter() { @@ -41,7 +49,7 @@ class PreviewsPagerUplift( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = if (viewType == Kind.PLAINTEXT.ordinal) { - PreviewPlainTextViewHolder( + PreviewPlainTextViewHolderUplift( ItemPreviewPlainTextBinding.inflate( LayoutInflater.from(parent.context), parent, @@ -62,22 +70,37 @@ class PreviewsPagerUplift( } override fun getItemViewType(position: Int) = - viewModel.getKind(position) + galleryItems[position].metadata.kind.ordinal @SuppressLint("ClickableViewAccessibility") override fun onBindViewHolder( holder: RecyclerView.ViewHolder, position: Int ) { - when (holder) { - is PreviewPlainTextViewHolderUplift -> { - holder.pos = position - viewModel.bindPlainTextView(holder) - } + lifecycleScope.launch { + when (holder) { + is PreviewPlainTextViewHolderUplift -> { + holder.pos = position + val item = galleryItems[position] + val text = readText(item.path) + text.onSuccess { + holder.setContent(it) + } + } - is PreviewImageViewHolderUplift -> { - holder.pos = position - viewModel.bindView(holder) + is PreviewImageViewHolderUplift -> { + holder.reset() + holder.pos = position + val item = galleryItems[position] + val placeholder = + ImageUtils.iconForExtension(extension(item.path)) + holder.setSource( + placeholder, + item.id(), + item.metadata, + item.preview + ) + } } } } @@ -97,4 +120,14 @@ class PreviewsPagerUplift( } return GestureDetectorCompat(context, listener) } + + private suspend fun readText(source: Path): Result = + withContext(Dispatchers.IO) { + try { + val content = FileReader(source.toFile()).readText() + Result.success(content) + } catch (e: Exception) { + Result.failure(e) + } + } } From 87891510de56d912943786b552c48001bdc44b37 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 03:41:47 +0600 Subject: [PATCH 58/74] disable StrictMode --- .../java/dev/arkbuilders/navigator/presentation/App.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/App.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/App.kt index 32cbf108..ee9da216 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/App.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/App.kt @@ -1,7 +1,6 @@ package dev.arkbuilders.navigator.presentation import android.app.Application -import android.os.StrictMode import dev.arkbuilders.arkfilepicker.folders.FoldersRepo import dev.arkbuilders.arklib.initArkLib import dev.arkbuilders.arklib.initRustLogger @@ -30,9 +29,9 @@ class App : Application() { private set init { - if (BuildConfig.DEBUG) { - StrictMode.enableDefaults() - } +// if (BuildConfig.DEBUG) { +// StrictMode.enableDefaults() +// } } override fun onCreate() { From d6b4ddcc4f41c739b548e061ce94f164993be70f Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 04:01:30 +0600 Subject: [PATCH 59/74] refactor onRemoveFabClick --- .../galleryuplift/GalleryUpliftViewModel.kt | 35 +++++++++---------- .../galleryuplift/state/GalleryState.kt | 4 ++- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 255794a8..f7da35b3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -21,8 +21,6 @@ import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.TagStorage import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.user.tags.TagsStorageRepo -import dev.arkbuilders.arklib.utils.ImageUtils -import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics import dev.arkbuilders.navigator.data.preferences.PreferenceKey @@ -136,23 +134,22 @@ class GalleryUpliftViewModel( LogTags.GALLERY_SCREEN, buildString { append("[remove_resource] clicked at position ") - append("${container.stateFlow.value.currentPos}") + append("${state.currentPos}") } ) - deleteResource(currentItem.id()) - galleryItems.removeAt(container.stateFlow.value.currentPos) - if (galleryItems.isEmpty()) { + deleteResource(state.currentItem().id()) + val newGalleryItems = state.galleryItems.toMutableList() + newGalleryItems.removeAt(state.currentPos) + if (newGalleryItems.isEmpty()) { intent { postSideEffect(GallerySideEffect.NavigateBack) } return@intent } onTagsChanged() - postSideEffect( - GallerySideEffect.DeleteResource( - container.stateFlow.value.currentPos - ) - ) + reduce { + state.copy(galleryItems = newGalleryItems) + } } } @@ -428,26 +425,26 @@ class GalleryUpliftViewModel( } private fun checkResourceChanges(pos: Int) = - viewModelScope.launch { - if (galleryItems.isEmpty()) { - return@launch + intent { + if (state.galleryItems.isEmpty()) { + return@intent } - val item = galleryItems[pos] + val item = state.currentItem() val path = index.getPath(item.id()) ?: let { Timber.d("Resource ${item.id()} can't be found in the index") invokeHandleGalleryExternalChangesUseCase() - return@launch + return@intent } if (path.notExists()) { Timber.d("Resource ${item.id()} isn't stored by path $path") invokeHandleGalleryExternalChangesUseCase() - return@launch + return@intent } if (path.getLastModifiedTime() != item.resource.modified) { Timber.d("Index is not up-to-date regarding path $path") invokeHandleGalleryExternalChangesUseCase() - return@launch + return@intent } } @@ -515,7 +512,7 @@ class GalleryUpliftViewModel( postSideEffect(GallerySideEffect.NotifyCurrentItemChange) postSideEffect( GallerySideEffect.ShowProgressWithText( - ProgressState.Indexing + ProgressState.HideProgress // ProgressWithText( // isVisible = true, // text = "Changes detected, indexing" diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index a0d2f115..f1ee256d 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -16,7 +16,9 @@ data class GalleryState( val galleryItems: List = emptyList(), val selectingEnabled: Boolean = false, val controlsVisible: Boolean = true, -) +) { + fun currentItem() = galleryItems[currentPos] +} sealed interface ProgressState { data object ProvidingRootIndex : ProgressState From 0849571a23c488f6c24f2a557112cad0221a98e3 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 04:06:30 +0600 Subject: [PATCH 60/74] make GalleryState.currentItem as property --- .../screen/gallery/galleryuplift/GalleryUpliftViewModel.kt | 4 ++-- .../screen/gallery/galleryuplift/state/GalleryState.kt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index f7da35b3..fcb8f5a3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -137,7 +137,7 @@ class GalleryUpliftViewModel( append("${state.currentPos}") } ) - deleteResource(state.currentItem().id()) + deleteResource(state.currentItem.id()) val newGalleryItems = state.galleryItems.toMutableList() newGalleryItems.removeAt(state.currentPos) if (newGalleryItems.isEmpty()) { @@ -429,7 +429,7 @@ class GalleryUpliftViewModel( if (state.galleryItems.isEmpty()) { return@intent } - val item = state.currentItem() + val item = state.galleryItems[pos] val path = index.getPath(item.id()) ?: let { Timber.d("Resource ${item.id()} can't be found in the index") diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index f1ee256d..7f5d6848 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -17,7 +17,8 @@ data class GalleryState( val selectingEnabled: Boolean = false, val controlsVisible: Boolean = true, ) { - fun currentItem() = galleryItems[currentPos] + val currentItem: GalleryItem + get() = galleryItems[currentPos] } sealed interface ProgressState { From 911382efd35686b5be55ef729a80fe6457092894 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 04:14:40 +0600 Subject: [PATCH 61/74] Use currentItem from state not from viewmodel property --- .../galleryuplift/GalleryUpliftViewModel.kt | 212 ++++++++---------- 1 file changed, 98 insertions(+), 114 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index fcb8f5a3..b2209911 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -102,7 +102,7 @@ class GalleryUpliftViewModel( val scoreWidgetController = ScoreWidgetController( scope = viewModelScope, - getCurrentId = { currentItem.id() }, + getCurrentId = { container.stateFlow.value.currentItem.id() }, onScoreChanged = { intent { postSideEffect(GallerySideEffect.NotifyResourceScoresChanged) @@ -111,8 +111,6 @@ class GalleryUpliftViewModel( ) private val messageFlow: MutableSharedFlow = MutableSharedFlow() - private val currentItem: GalleryItem - get() = galleryItems[container.stateFlow.value.currentPos] init { initStorages() @@ -169,108 +167,97 @@ class GalleryUpliftViewModel( fun onPlayButtonClick() = intent { postSideEffect( GallerySideEffect.ViewInExternalApp( - index.getPath(currentItem.id())!! + index.getPath(state.currentItem.id())!! ) ) } - fun onInfoFabClick() = viewModelScope.launch { + fun onInfoFabClick() = intent { analytics.trackResInfo() Timber.d( LogTags.GALLERY_SCREEN, "[info_resource] clicked at position" + " ${container.stateFlow.value.currentPos}" ) - val path = index.getPath(currentItem.id())!! + val path = index.getPath(state.currentItem.id())!! val data = ShowInfoData( path = path, - resource = currentItem.resource, - metadata = currentItem.metadata + resource = state.currentItem.resource, + metadata = state.currentItem.metadata ) intent { postSideEffect(GallerySideEffect.ShowInfoAlert(data)) } } - fun onShareFabClick() = viewModelScope.launch { + fun onShareFabClick() = intent { analytics.trackResShare() Timber.d( LogTags.GALLERY_SCREEN, "[share_resource] clicked at position " + "${container.stateFlow.value.currentPos}" ) - val path = index.getPath(currentItem.id())!! - if (currentItem.metadata is Metadata.Link) { + val path = index.getPath(state.currentItem.id())!! + if (state.currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - intent { - postSideEffect(GallerySideEffect.ShareLink(url)) - } - return@launch - } - intent { - postSideEffect(GallerySideEffect.ShareResource(path)) + postSideEffect(GallerySideEffect.ShareLink(url)) + return@intent } + postSideEffect(GallerySideEffect.ShareResource(path)) } - fun onSelectingChanged() { - intent { - reduce { - state.copy(selectingEnabled = !state.selectingEnabled) - } - postSideEffect( - GallerySideEffect.ToggleSelect( - container.stateFlow.value.selectingEnabled - ) - ) + fun onSelectingChanged() = intent { + reduce { + state.copy(selectingEnabled = !state.selectingEnabled) } + postSideEffect( + GallerySideEffect.ToggleSelect( + container.stateFlow.value.selectingEnabled + ) + ) + _selectedResources.clear() if (container.stateFlow.value.selectingEnabled) { - _selectedResources.add(currentItem.resource.id) + _selectedResources.add(state.currentItem.id()) } } - fun onOpenFabClick() = viewModelScope.launch { + fun onOpenFabClick() = intent { analytics.trackResOpen() Timber.d( LogTags.GALLERY_SCREEN, "[open_resource] clicked at position " + "${container.stateFlow.value.currentPos}" ) - val id = currentItem.id() + val id = state.currentItem.id() val path = index.getPath(id)!! - if (currentItem.metadata is Metadata.Link) { + if (state.currentItem.metadata is Metadata.Link) { val url = readText(path).getOrThrow() - intent { - postSideEffect(GallerySideEffect.OpenLink(url)) - } - return@launch + postSideEffect(GallerySideEffect.OpenLink(url)) + return@intent } - intent { - postSideEffect( - GallerySideEffect.ViewInExternalApp( - index.getPath( - currentItem.id() - )!! - ) + postSideEffect( + GallerySideEffect.ViewInExternalApp( + index.getPath( + state.currentItem.id() + )!! ) - } + ) } - fun onEditFabClick() = viewModelScope.launch { + fun onEditFabClick() = intent { analytics.trackResEdit() Timber.d( LogTags.GALLERY_SCREEN, "[edit_resource] clicked at position " + "${container.stateFlow.value.currentPos}" ) - val path = index.getPath(currentItem.id())!! - intent { - postSideEffect(GallerySideEffect.EditResource(path)) - } + val path = index.getPath(state.currentItem.id())!! + postSideEffect(GallerySideEffect.EditResource(path)) } - fun onSelectBtnClick() { - val id = currentItem.id() + fun onSelectBtnClick() = intent { + val id = state.currentItem.id() val wasSelected = id in _selectedResources if (wasSelected) { _selectedResources.remove(id) @@ -292,35 +279,34 @@ class GalleryUpliftViewModel( } } - fun onResume() { - checkResourceChanges(container.stateFlow.value.currentPos) + fun onResume() = intent { + checkResourceChanges(state.currentPos) } - fun onTagsChanged() { - intent { - val tags = tagsStorage.getTags(currentItem.id()) - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = currentItem.id(), - tags = tags, - ) + fun onTagsChanged() = intent { + val tags = tagsStorage.getTags(state.currentItem.id()) + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = state.currentItem.id(), + tags = tags, ) ) - } + ) } - fun onPageChanged(newPos: Int) = viewModelScope.launch { + + fun onPageChanged(newPos: Int) = intent { if (galleryItems.isEmpty()) - return@launch + return@intent intent { reduce { state.copy(currentPos = newPos) } checkResourceChanges(newPos) - val id = currentItem.id() + val id = state.currentItem.id() val tags = tagsStorage.getTags(id) - displayPreview(id, currentItem.metadata, tags) + displayPreview(id, state.currentItem.metadata, tags) } } @@ -333,10 +319,10 @@ class GalleryUpliftViewModel( ) } - fun onTagRemove(tag: Tag) = viewModelScope.launch(NonCancellable) { + fun onTagRemove(tag: Tag) = intent { intent { analytics.trackTagRemove() - val id = currentItem.id() + val id = state.currentItem.id() val tags = tagsStorage.getTags(id) val newTags = tags - tag postSideEffect( @@ -354,7 +340,7 @@ class GalleryUpliftViewModel( ) Timber.d( LogTags.GALLERY_SCREEN, - "setting new tags $newTags to $currentItem" + "setting new tags $newTags to $state.currentItem" ) tagsStorage.setTags(id, newTags) tagsStorage.persist() @@ -362,68 +348,66 @@ class GalleryUpliftViewModel( } } - fun onEditTagsDialogBtnClick() { - intent { - analytics.trackTagsEdit() - postSideEffect( - GallerySideEffect.ShowEditTagsDialog( - ShowEditTagsData( - resource = currentItem.id(), - resources = listOf(currentItem.id()), - statsStorage = statsStorage, - rootAndFav = rootAndFav, - index = index, - storage = tagsStorage, - ) + fun onEditTagsDialogBtnClick() = intent { + analytics.trackTagsEdit() + postSideEffect( + GallerySideEffect.ShowEditTagsDialog( + ShowEditTagsData( + resource = state.currentItem.id(), + resources = listOf(state.currentItem.id()), + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = tagsStorage, ) ) - } + ) } + private fun displayPreview( id: ResourceId, meta: Metadata, tags: Tags - ) { - intent { - postSideEffect( - GallerySideEffect.SetUpPreview( - SetupPreview( - position = container.stateFlow.value.currentPos, - meta = meta, - ) + ) = intent { + postSideEffect( + GallerySideEffect.SetUpPreview( + SetupPreview( + position = state.currentPos, + meta = meta, ) ) - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = id, - tags = tags, - ) + ) + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = id, + tags = tags, ) ) - scoreWidgetController.displayScore() - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = id, - tags = tags, - ) + ) + scoreWidgetController.displayScore() + postSideEffect( + GallerySideEffect.DisplayPreviewTags( + ResourceIdTagsPreview( + resourceId = id, + tags = tags, ) ) - postSideEffect( - GallerySideEffect.DisplaySelectedFile( - DisplaySelected( - selected = id in _selectedResources, - showAnim = false, - selectedCount = _selectedResources.size, - itemCount = galleryItems.size, - ) + ) + postSideEffect( + GallerySideEffect.DisplaySelectedFile( + DisplaySelected( + selected = id in _selectedResources, + showAnim = false, + selectedCount = _selectedResources.size, + itemCount = galleryItems.size, ) ) - } + ) } + private fun checkResourceChanges(pos: Int) = intent { if (state.galleryItems.isEmpty()) { From 03e417d58988fe397e44973b802eebd5ff493f3a Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 06:33:58 +0600 Subject: [PATCH 62/74] remove updateAdapter sideEffect and diffResult from viewmodel --- .../galleryuplift/GalleryUpliftFragment.kt | 12 ---- .../galleryuplift/GalleryUpliftViewModel.kt | 72 +++++++------------ .../galleryuplift/state/GalleryState.kt | 2 - 3 files changed, 26 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 2a5b4d0b..1cdeabb1 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -257,10 +257,6 @@ class GalleryUpliftFragment : Fragment() { path ) - GallerySideEffect.UpdatePagerAdapter -> updatePagerAdapter() - GallerySideEffect.UpdatePagerAdapterWithDiff -> - updatePagerAdapterWithDiff() - is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) is GallerySideEffect.ToggleSelect -> toggleSelecting(isEnabled) } @@ -279,14 +275,6 @@ class GalleryUpliftFragment : Fragment() { viewModel.router.exit() } - private fun updatePagerAdapter() { - pagerAdapter.notifyDataSetChanged() - } - - private fun updatePagerAdapterWithDiff() { - viewModel.diffResult?.dispatchUpdatesTo(pagerAdapter) - } - private fun setupPreview( pos: Int, meta: Metadata diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index b2209911..5e0efe47 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -2,7 +2,6 @@ package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.recyclerview.widget.DiffUtil import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.data.Message @@ -40,7 +39,6 @@ import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domai import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.ProgressState -import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.cancel @@ -95,7 +93,6 @@ class GalleryUpliftViewModel( ) var galleryItems: MutableList = mutableListOf() - var diffResult: DiffUtil.DiffResult? = null private val _selectedResources: MutableList = mutableListOf() val selectedResources: List = _selectedResources @@ -451,60 +448,43 @@ class GalleryUpliftViewModel( emptyList() } - private fun invokeHandleGalleryExternalChangesUseCase() { - viewModelScope.launch { - intent { - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.Indexing + private fun invokeHandleGalleryExternalChangesUseCase() = intent { + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.Indexing // ProgressWithText( // isVisible = true, // text = "Changes detected, indexing" // ) - ) - ) - index.updateAll() - postSideEffect(GallerySideEffect.NotifyResourceChange) - - viewModelScope.launch { - metadataStorage.busy.collect { busy -> - if (!busy) cancel() - } - }.join() + ) + ) + index.updateAll() + postSideEffect(GallerySideEffect.NotifyResourceChange) - val newItems = provideGalleryItems() - if (newItems.isEmpty()) { - postSideEffect(GallerySideEffect.NavigateBack) - return@intent - } - if (newItems.isEmpty()) { - intent { - postSideEffect(GallerySideEffect.NavigateBack) - } - return@intent - } + viewModelScope.launch { + metadataStorage.busy.collect { busy -> + if (!busy) cancel() + } + }.join() - diffResult = DiffUtil.calculateDiff( - ResourceDiffUtilCallback( - galleryItems.map { it.resource.id }, - newItems.map { it.resource.id } - ) - ) + val newItems = provideGalleryItems() + if (newItems.isEmpty()) { + postSideEffect(GallerySideEffect.NavigateBack) + return@intent + } - galleryItems = newItems.toMutableList() - postSideEffect(GallerySideEffect.UpdatePagerAdapterWithDiff) - postSideEffect(GallerySideEffect.NotifyCurrentItemChange) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.HideProgress + reduce { + state.copy(galleryItems = newItems) + } + postSideEffect( + GallerySideEffect.ShowProgressWithText( + ProgressState.HideProgress // ProgressWithText( // isVisible = true, // text = "Changes detected, indexing" // ) - ) - ) - } - } + ) + ) } private suspend fun readText(source: Path): Result = diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt index 7f5d6848..66ace349 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt @@ -41,7 +41,6 @@ sealed class GallerySideEffect { val storageException: StorageExceptionGallery ) : GallerySideEffect() - data object UpdatePagerAdapter : GallerySideEffect() data class ShareLink(val url: String) : GallerySideEffect() data class ShareResource(val path: Path) : GallerySideEffect() data class EditResource(val path: Path) : GallerySideEffect() @@ -57,6 +56,5 @@ sealed class GallerySideEffect { data object NotifyResourceChange : GallerySideEffect() data class ShowProgressWithText(val state: ProgressState) : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() - data object UpdatePagerAdapterWithDiff : GallerySideEffect() data class ToggleSelect(val isEnabled: Boolean) : GallerySideEffect() } From 769d0bcf68a14d2129a72d3252a3faec504eb0ea Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 07:03:01 +0600 Subject: [PATCH 63/74] use state gallery items instead of viewmodel property --- .../galleryuplift/GalleryUpliftViewModel.kt | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 5e0efe47..47bb5310 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -92,8 +92,6 @@ class GalleryUpliftViewModel( ) ) - var galleryItems: MutableList = mutableListOf() - private val _selectedResources: MutableList = mutableListOf() val selectedResources: List = _selectedResources @@ -262,18 +260,16 @@ class GalleryUpliftViewModel( _selectedResources.add(id) } - intent { - postSideEffect( - GallerySideEffect.DisplaySelectedFile( - DisplaySelected( - selected = !wasSelected, - showAnim = true, - selectedCount = _selectedResources.size, - itemCount = galleryItems.size - ) + postSideEffect( + GallerySideEffect.DisplaySelectedFile( + DisplaySelected( + selected = !wasSelected, + showAnim = true, + selectedCount = _selectedResources.size, + itemCount = state.galleryItems.size ) ) - } + ) } fun onResume() = intent { @@ -294,7 +290,7 @@ class GalleryUpliftViewModel( fun onPageChanged(newPos: Int) = intent { - if (galleryItems.isEmpty()) + if (state.galleryItems.isEmpty()) return@intent intent { reduce { @@ -398,7 +394,7 @@ class GalleryUpliftViewModel( selected = id in _selectedResources, showAnim = false, selectedCount = _selectedResources.size, - itemCount = galleryItems.size, + itemCount = state.galleryItems.size, ) ) ) @@ -553,7 +549,7 @@ class GalleryUpliftViewModel( } statsStorage = statsStorageRepo.provide(index) scoreWidgetController.init(scoreStorage) - galleryItems = provideGalleryItems().toMutableList() + val galleryItems = provideGalleryItems() viewModelScope.launch { val result = preferences.get( PreferenceKey.SortByScores From c6e87a3f6de00d52a05f7a0fdbda12c039d9221f Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 10:08:55 +0600 Subject: [PATCH 64/74] Refactor side effects and domain models --- .../galleryuplift/GalleryUpliftFragment.kt | 44 ++++----- .../galleryuplift/GalleryUpliftViewModel.kt | 97 +++++++------------ .../galleryuplift/domain/DisplaySelected.kt | 8 -- .../{state => domain}/GalleryState.kt | 57 ++++++++--- .../domain/ResourceIdTagsPreview.kt | 5 - .../galleryuplift/domain/SetupPreview.kt | 5 - .../galleryuplift/domain/ShowEditTagsData.kt | 16 --- .../galleryuplift/domain/ShowInfoData.kt | 11 --- .../domain/StorageExceptionGallery.kt | 3 - 9 files changed, 97 insertions(+), 149 deletions(-) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/{state => domain}/GalleryState.kt (58%) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 1cdeabb1..3b5aa996 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -47,9 +47,9 @@ import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragm import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment import dev.arkbuilders.navigator.presentation.navigation.Screens import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.ProgressState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressState import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader @@ -199,21 +199,21 @@ class GalleryUpliftFragment : Fragment() { is GallerySideEffect.DeleteResource -> deleteResource(pos) is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( - resource = data.resourceId, - tags = data.tags + resource = resourceId, + tags = tags ) is GallerySideEffect.DisplaySelectedFile -> displaySelected( - selected = data.selected, - showAnim = data.showAnim, - selectedCount = data.selectedCount, - itemCount = data.itemCount + selected = selected, + showAnim = showAnim, + selectedCount = selectedCount, + itemCount = itemCount ) is GallerySideEffect.DisplayStorageException -> displayStorageException( - label = storageException.label, - msg = storageException.messenger + label = label, + msg = messenger ) is GallerySideEffect.EditResource -> editResource(path) @@ -228,25 +228,25 @@ class GalleryUpliftFragment : Fragment() { GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() is GallerySideEffect.OpenLink -> openLink(url) is GallerySideEffect.SetUpPreview -> setupPreview( - pos = data.position, - meta = data.meta + pos = position, + meta = meta ) is GallerySideEffect.ShareLink -> shareLink(url) is GallerySideEffect.ShareResource -> shareResource(path) is GallerySideEffect.ShowEditTagsDialog -> showEditTagsDialog( - resource = data.resource, - resources = data.resources, - statsStorage = data.statsStorage, - rootAndFav = data.rootAndFav, - index = data.index, - storage = data.storage, + resource = resource, + resources = resources, + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = storage, ) is GallerySideEffect.ShowInfoAlert -> showInfoAlert( - path = infoData.path, - resource = infoData.resource, - metadata = infoData.metadata + path = path, + resource = resource, + metadata = metadata ) is GallerySideEffect.ShowProgressWithText -> handleProgressState( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 47bb5310..182a6df3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -29,16 +29,10 @@ import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowInfoData -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GallerySideEffect -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.GalleryState -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state.ProgressState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressState import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.cancel @@ -175,13 +169,14 @@ class GalleryUpliftViewModel( " ${container.stateFlow.value.currentPos}" ) val path = index.getPath(state.currentItem.id())!! - val data = ShowInfoData( - path = path, - resource = state.currentItem.resource, - metadata = state.currentItem.metadata - ) intent { - postSideEffect(GallerySideEffect.ShowInfoAlert(data)) + postSideEffect( + GallerySideEffect.ShowInfoAlert( + path = path, + resource = state.currentItem.resource, + metadata = state.currentItem.metadata + ) + ) } } @@ -262,12 +257,10 @@ class GalleryUpliftViewModel( postSideEffect( GallerySideEffect.DisplaySelectedFile( - DisplaySelected( - selected = !wasSelected, - showAnim = true, - selectedCount = _selectedResources.size, - itemCount = state.galleryItems.size - ) + selected = !wasSelected, + showAnim = true, + selectedCount = _selectedResources.size, + itemCount = state.galleryItems.size ) ) } @@ -280,10 +273,8 @@ class GalleryUpliftViewModel( val tags = tagsStorage.getTags(state.currentItem.id()) postSideEffect( GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = state.currentItem.id(), - tags = tags, - ) + resourceId = state.currentItem.id(), + tags = tags, ) ) } @@ -320,10 +311,8 @@ class GalleryUpliftViewModel( val newTags = tags - tag postSideEffect( GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = id, - tags = newTags, - ) + resourceId = id, + tags = newTags, ) ) statsStorage.handleEvent( @@ -345,14 +334,12 @@ class GalleryUpliftViewModel( analytics.trackTagsEdit() postSideEffect( GallerySideEffect.ShowEditTagsDialog( - ShowEditTagsData( - resource = state.currentItem.id(), - resources = listOf(state.currentItem.id()), - statsStorage = statsStorage, - rootAndFav = rootAndFav, - index = index, - storage = tagsStorage, - ) + resource = state.currentItem.id(), + resources = listOf(state.currentItem.id()), + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = tagsStorage, ) ) } @@ -365,37 +352,23 @@ class GalleryUpliftViewModel( ) = intent { postSideEffect( GallerySideEffect.SetUpPreview( - SetupPreview( - position = state.currentPos, - meta = meta, - ) + position = state.currentPos, + meta = meta, ) ) postSideEffect( GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = id, - tags = tags, - ) + resourceId = id, + tags = tags, ) ) scoreWidgetController.displayScore() - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - ResourceIdTagsPreview( - resourceId = id, - tags = tags, - ) - ) - ) postSideEffect( GallerySideEffect.DisplaySelectedFile( - DisplaySelected( - selected = id in _selectedResources, - showAnim = false, - selectedCount = _selectedResources.size, - itemCount = state.galleryItems.size, - ) + selected = id in _selectedResources, + showAnim = false, + selectedCount = _selectedResources.size, + itemCount = state.galleryItems.size, ) ) } @@ -540,10 +513,8 @@ class GalleryUpliftViewModel( } catch (e: StorageException) { postSideEffect( GallerySideEffect.DisplayStorageException( - StorageExceptionGallery( - label = e.label, - messenger = e.msg - ) + label = e.label, + messenger = e.msg ) ) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt deleted file mode 100644 index 724f9b5e..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/DisplaySelected.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -data class DisplaySelected( - val selected: Boolean, - val showAnim: Boolean, - val selectedCount: Int, - val itemCount: Int, -) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt similarity index 58% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index 66ace349..cabb64c3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/state/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -1,13 +1,12 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.state +package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.DisplaySelected -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ResourceIdTagsPreview -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.SetupPreview -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowEditTagsData -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ShowInfoData -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.StorageExceptionGallery +import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.index.ResourceIndex +import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.navigator.data.stats.StatsStorage import java.nio.file.Path data class GalleryState( @@ -31,14 +30,20 @@ sealed interface ProgressState { } sealed class GallerySideEffect { - data class ScrollToPage(val pos: Int): GallerySideEffect() + data class ScrollToPage(val pos: Int) : GallerySideEffect() data object NotifyResourceScoresChanged : GallerySideEffect() data object NavigateBack : GallerySideEffect() data class DeleteResource(val pos: Int) : GallerySideEffect() data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() - data class ShowInfoAlert(val infoData: ShowInfoData) : GallerySideEffect() + data class ShowInfoAlert( + val path: Path, + val resource: Resource, + val metadata: Metadata + ) : GallerySideEffect() + data class DisplayStorageException( - val storageException: StorageExceptionGallery + val label: String, + val messenger: String ) : GallerySideEffect() data class ShareLink(val url: String) : GallerySideEffect() @@ -46,13 +51,33 @@ sealed class GallerySideEffect { data class EditResource(val path: Path) : GallerySideEffect() data class OpenLink(val url: String) : GallerySideEffect() data class ViewInExternalApp(val path: Path) : GallerySideEffect() - data class DisplayPreviewTags(val data: ResourceIdTagsPreview) : - GallerySideEffect() + data class DisplayPreviewTags( + val resourceId: ResourceId, + val tags: Set + ) : GallerySideEffect() data object NotifyTagsChanged : GallerySideEffect() - data class ShowEditTagsDialog(val data: ShowEditTagsData) : GallerySideEffect() - data class SetUpPreview(val data: SetupPreview) : GallerySideEffect() - data class DisplaySelectedFile(val data: DisplaySelected) : GallerySideEffect() + data class ShowEditTagsDialog( + val resource: ResourceId, + val rootAndFav: RootAndFav, + val resources: List, + val index: ResourceIndex, + val storage: TagStorage, + val statsStorage: StatsStorage + ) : GallerySideEffect() + + data class SetUpPreview( + val position: Int, + val meta: Metadata + ) : GallerySideEffect() + + data class DisplaySelectedFile( + val selected: Boolean, + val showAnim: Boolean, + val selectedCount: Int, + val itemCount: Int, + ) : GallerySideEffect() + data object NotifyResourceChange : GallerySideEffect() data class ShowProgressWithText(val state: ProgressState) : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt deleted file mode 100644 index 4bff0194..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ResourceIdTagsPreview.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -import dev.arkbuilders.arklib.ResourceId - -data class ResourceIdTagsPreview(val resourceId: ResourceId, val tags: Set) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt deleted file mode 100644 index 959e2030..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/SetupPreview.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -import dev.arkbuilders.arklib.data.meta.Metadata - -data class SetupPreview(val position: Int, val meta: Metadata) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt deleted file mode 100644 index 25271746..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowEditTagsData.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.index.ResourceIndex -import dev.arkbuilders.arklib.user.tags.TagStorage -import dev.arkbuilders.navigator.data.stats.StatsStorage - -data class ShowEditTagsData( - val resource: ResourceId, - val rootAndFav: RootAndFav, - val resources: List, - val index: ResourceIndex, - val storage: TagStorage, - val statsStorage: StatsStorage -) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt deleted file mode 100644 index ab567cb8..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/ShowInfoData.kt +++ /dev/null @@ -1,11 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -import dev.arkbuilders.arklib.data.index.Resource -import dev.arkbuilders.arklib.data.meta.Metadata -import java.nio.file.Path - -data class ShowInfoData( - val path: Path, - val resource: Resource, - val metadata: Metadata -) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt deleted file mode 100644 index f2631bbf..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/StorageExceptionGallery.kt +++ /dev/null @@ -1,3 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain - -data class StorageExceptionGallery(val label: String, val messenger: String) From dc862e5f64bb01efe8241c4fff8441c630eb8b85 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Wed, 4 Sep 2024 11:03:51 +0600 Subject: [PATCH 65/74] Refactor selecting and move selectedResources to state --- .../galleryuplift/GalleryUpliftFragment.kt | 35 ++++----- .../galleryuplift/GalleryUpliftViewModel.kt | 71 ++++++++----------- .../GalleryUpliftViewModelFactory.kt | 7 +- .../galleryuplift/domain/GalleryState.kt | 13 ++-- 4 files changed, 56 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 3b5aa996..e966b4fd 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -74,9 +74,12 @@ class GalleryUpliftFragment : Fragment() { factory.create( startPos = requireArguments().getInt(START_AT_KEY), selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), + selectedResources = requireArguments() + .getParcelableArray(SELECTED_RESOURCES_KEY)!! + .toList() as List, rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! - .toList() as List + .toList() as List, ).apply { App.instance.appComponent.inject(this@GalleryUpliftFragment) } @@ -156,7 +159,7 @@ class GalleryUpliftFragment : Fragment() { viewModel.onShareFabClick() } fabStartSelect.setOnClickListener { - viewModel.onSelectingChanged() + viewModel.onSelectingChanged(true) } openResourceFab.setOnClickListener { @@ -172,7 +175,7 @@ class GalleryUpliftFragment : Fragment() { } layoutSelected.setOnLongClickListener { - viewModel.onSelectingChanged() + viewModel.onSelectingChanged(false) return@setOnLongClickListener true } } @@ -203,13 +206,6 @@ class GalleryUpliftFragment : Fragment() { tags = tags ) - is GallerySideEffect.DisplaySelectedFile -> displaySelected( - selected = selected, - showAnim = showAnim, - selectedCount = selectedCount, - itemCount = itemCount - ) - is GallerySideEffect.DisplayStorageException -> displayStorageException( label = label, @@ -258,7 +254,8 @@ class GalleryUpliftFragment : Fragment() { ) is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) - is GallerySideEffect.ToggleSelect -> toggleSelecting(isEnabled) + is GallerySideEffect.AbortSelectAnimation -> + binding.cbSelected.jumpDrawablesToCurrentState() } } } @@ -266,11 +263,17 @@ class GalleryUpliftFragment : Fragment() { private fun render(state: GalleryState) { pagerAdapter.dispatchUpdates(state.galleryItems) setControlsVisibility(state.controlsVisible) + toggleSelecting(state.selectingEnabled) + displaySelected( + state.currentItemSelected, + state.selectedResources.size, + state.galleryItems.size + ) } private fun onBackClick() { Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") - notifySelectedChanged(viewModel.selectedResources) + notifySelectedChanged(viewModel.container.stateFlow.value.selectedResources) exitFullscreen() viewModel.router.exit() } @@ -509,14 +512,11 @@ class GalleryUpliftFragment : Fragment() { private fun displaySelected( selected: Boolean, - showAnim: Boolean, selectedCount: Int, itemCount: Int ) = with(binding) { Timber.d("display ${System.currentTimeMillis()}") cbSelected.isChecked = selected - if (!showAnim) - cbSelected.jumpDrawablesToCurrentState() tvSelectedOf.text = "$selectedCount/$itemCount" return@with @@ -528,11 +528,6 @@ class GalleryUpliftFragment : Fragment() { requireArguments().apply { putBoolean(GalleryFragment.SELECTING_ENABLED_KEY, enabled) } - if (enabled) { - viewModel.onSelectBtnClick() - } else { - binding.cbSelected.isChecked = false - } } private fun setupOpenEditFABs(meta: Metadata?) = binding.apply { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 182a6df3..9c968986 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -58,6 +58,7 @@ import kotlin.io.path.notExists class GalleryUpliftViewModel( startPos: Int, selectingEnabled: Boolean, + selectedResources: List, private val rootAndFav: RootAndFav, private val resourcesIds: List, val preferences: Preferences, @@ -82,13 +83,11 @@ class GalleryUpliftViewModel( GalleryState( rootAndFav = rootAndFav, currentPos = startPos, - selectingEnabled = selectingEnabled + selectingEnabled = selectingEnabled, + selectedResources = selectedResources ) ) - private val _selectedResources: MutableList = mutableListOf() - val selectedResources: List = _selectedResources - val scoreWidgetController = ScoreWidgetController( scope = viewModelScope, getCurrentId = { container.stateFlow.value.currentItem.id() }, @@ -196,19 +195,20 @@ class GalleryUpliftViewModel( postSideEffect(GallerySideEffect.ShareResource(path)) } - fun onSelectingChanged() = intent { + fun onSelectingChanged(enabled: Boolean) = intent { reduce { - state.copy(selectingEnabled = !state.selectingEnabled) + state.copy(selectingEnabled = enabled) } - postSideEffect( - GallerySideEffect.ToggleSelect( - container.stateFlow.value.selectingEnabled - ) - ) - _selectedResources.clear() - if (container.stateFlow.value.selectingEnabled) { - _selectedResources.add(state.currentItem.id()) + reduce { + if (enabled) { + state.copy( + selectedResources = state.selectedResources + + state.currentItem.id() + ) + } else { + state.copy(selectedResources = emptyList()) + } } } @@ -248,21 +248,17 @@ class GalleryUpliftViewModel( fun onSelectBtnClick() = intent { val id = state.currentItem.id() - val wasSelected = id in _selectedResources + val newSelectedList = state.selectedResources.toMutableList() + val wasSelected = id in state.selectedResources if (wasSelected) { - _selectedResources.remove(id) + newSelectedList.remove(id) } else { - _selectedResources.add(id) + newSelectedList.add(id) } - postSideEffect( - GallerySideEffect.DisplaySelectedFile( - selected = !wasSelected, - showAnim = true, - selectedCount = _selectedResources.size, - itemCount = state.galleryItems.size - ) - ) + reduce { + state.copy(selectedResources = newSelectedList) + } } fun onResume() = intent { @@ -283,15 +279,16 @@ class GalleryUpliftViewModel( fun onPageChanged(newPos: Int) = intent { if (state.galleryItems.isEmpty()) return@intent - intent { - reduce { - state.copy(currentPos = newPos) - } - checkResourceChanges(newPos) - val id = state.currentItem.id() - val tags = tagsStorage.getTags(id) - displayPreview(id, state.currentItem.metadata, tags) + + reduce { + state.copy(currentPos = newPos) } + postSideEffect(GallerySideEffect.AbortSelectAnimation) + + checkResourceChanges(newPos) + val id = state.currentItem.id() + val tags = tagsStorage.getTags(id) + displayPreview(id, state.currentItem.metadata, tags) } fun onTagSelected(tag: Tag) { @@ -363,14 +360,6 @@ class GalleryUpliftViewModel( ) ) scoreWidgetController.displayScore() - postSideEffect( - GallerySideEffect.DisplaySelectedFile( - selected = id in _selectedResources, - showAnim = false, - selectedCount = _selectedResources.size, - itemCount = state.galleryItems.size, - ) - ) } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt index 6cb7c4f4..4a185d4e 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt @@ -21,7 +21,8 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @Assisted val startPos: Int, @Assisted val selectingEnabled: Boolean, @Assisted private val rootAndFav: RootAndFav, - @Assisted private val resourcesIds: List, + @Assisted("all") private val resourcesIds: List, + @Assisted("selected") private val selectedResources: List, val preferences: Preferences, val router: AppRouter, val indexRepo: ResourceIndexRepo, @@ -36,6 +37,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( return GalleryUpliftViewModel( startPos = startPos, selectingEnabled = selectingEnabled, + selectedResources = selectedResources, rootAndFav = rootAndFav, resourcesIds = resourcesIds, preferences = preferences, @@ -56,7 +58,8 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @Assisted startPos: Int, @Assisted selectingEnabled: Boolean, @Assisted rootAndFav: RootAndFav, - @Assisted resourcesIds: List, + @Assisted("all") resourcesIds: List, + @Assisted("selected") selectedResources: List, ): GalleryUpliftViewModelFactory } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index cabb64c3..eeb28d38 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -14,10 +14,14 @@ data class GalleryState( val currentPos: Int = 0, val galleryItems: List = emptyList(), val selectingEnabled: Boolean = false, + val selectedResources: List = emptyList(), val controlsVisible: Boolean = true, ) { val currentItem: GalleryItem get() = galleryItems[currentPos] + + val currentItemSelected: Boolean + get() = currentItem.id() in selectedResources } sealed interface ProgressState { @@ -71,15 +75,10 @@ sealed class GallerySideEffect { val meta: Metadata ) : GallerySideEffect() - data class DisplaySelectedFile( - val selected: Boolean, - val showAnim: Boolean, - val selectedCount: Int, - val itemCount: Int, - ) : GallerySideEffect() + // workaround to not show checkbox select animation when we change page + data object AbortSelectAnimation: GallerySideEffect() data object NotifyResourceChange : GallerySideEffect() data class ShowProgressWithText(val state: ProgressState) : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() - data class ToggleSelect(val isEnabled: Boolean) : GallerySideEffect() } From 7f68bf03a7b20969e5724339b39c5ac96018fe9d Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 02:22:26 +0600 Subject: [PATCH 66/74] Move progress state to screen state --- .../galleryuplift/GalleryUpliftFragment.kt | 5 +- .../galleryuplift/GalleryUpliftViewModel.kt | 66 +++++++------------ .../galleryuplift/domain/GalleryState.kt | 2 +- 3 files changed, 24 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index e966b4fd..94fd07eb 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -245,10 +245,6 @@ class GalleryUpliftFragment : Fragment() { metadata = metadata ) - is GallerySideEffect.ShowProgressWithText -> handleProgressState( - state - ) - is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath( path ) @@ -269,6 +265,7 @@ class GalleryUpliftFragment : Fragment() { state.selectedResources.size, state.galleryItems.size ) + handleProgressState(state.progressState) } private fun onBackClick() { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 9c968986..d9e82867 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -407,15 +407,9 @@ class GalleryUpliftViewModel( } private fun invokeHandleGalleryExternalChangesUseCase() = intent { - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.Indexing -// ProgressWithText( -// isVisible = true, -// text = "Changes detected, indexing" -// ) - ) - ) + reduce { + state.copy(progressState = ProgressState.Indexing) + } index.updateAll() postSideEffect(GallerySideEffect.NotifyResourceChange) @@ -434,15 +428,9 @@ class GalleryUpliftViewModel( reduce { state.copy(galleryItems = newItems) } - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.HideProgress -// ProgressWithText( -// isVisible = true, -// text = "Changes detected, indexing" -// ) - ) - ) + reduce { + state.copy(progressState = ProgressState.HideProgress) + } } private suspend fun readText(source: Path): Result = @@ -461,11 +449,9 @@ class GalleryUpliftViewModel( LogTags.GALLERY_SCREEN, "first view attached in GalleryPresenter" ) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingRootIndex - ) - ) + reduce { + state.copy(progressState = ProgressState.ProvidingRootIndex) + } index = indexRepo.provide(rootAndFav) messageFlow.onEach { message -> when (message) { @@ -479,23 +465,17 @@ class GalleryUpliftViewModel( } } }.launchIn(viewModelScope) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingMetaDataStorage - ) - ) + reduce { + state.copy(progressState = ProgressState.ProvidingMetaDataStorage) + } metadataStorage = metadataStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingPreviewStorage - ) - ) + reduce { + state.copy(progressState = ProgressState.ProvidingPreviewStorage) + } previewStorage = previewStorageRepo.provide(index) - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.ProvidingDataStorage - ) - ) + reduce { + state.copy(progressState = ProgressState.ProvidingDataStorage) + } try { tagsStorage = tagsStorageRepo.provide(index) scoreStorage = scoreStorageRepo.provide(index) @@ -517,12 +497,10 @@ class GalleryUpliftViewModel( scoreWidgetController.setVisible(result) } reduce { - state.copy(galleryItems = galleryItems) - } - postSideEffect( - GallerySideEffect.ShowProgressWithText( - ProgressState.HideProgress + state.copy( + galleryItems = galleryItems, + progressState = ProgressState.HideProgress ) - ) + } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index eeb28d38..a237e6d4 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -16,6 +16,7 @@ data class GalleryState( val selectingEnabled: Boolean = false, val selectedResources: List = emptyList(), val controlsVisible: Boolean = true, + val progressState: ProgressState = ProgressState.HideProgress ) { val currentItem: GalleryItem get() = galleryItems[currentPos] @@ -79,6 +80,5 @@ sealed class GallerySideEffect { data object AbortSelectAnimation: GallerySideEffect() data object NotifyResourceChange : GallerySideEffect() - data class ShowProgressWithText(val state: ProgressState) : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() } From 0bd196e179cd79a2fea28bde157cf0042bfd321b Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 05:05:30 +0600 Subject: [PATCH 67/74] Move tags to state --- .../galleryuplift/GalleryUpliftFragment.kt | 39 ++++++++++--------- .../galleryuplift/GalleryUpliftViewModel.kt | 29 +++++--------- .../galleryuplift/domain/GalleryState.kt | 8 ++-- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 94fd07eb..e539525c 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -92,6 +92,9 @@ class GalleryUpliftFragment : Fragment() { private lateinit var stackedToasts: StackedToasts private lateinit var pagerAdapter: PreviewsPagerUplift + // avoid pointless update on render if there are no changes + private var cacheTags: Tags? = null + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -201,10 +204,6 @@ class GalleryUpliftFragment : Fragment() { } is GallerySideEffect.DeleteResource -> deleteResource(pos) - is GallerySideEffect.DisplayPreviewTags -> displayPreviewTags( - resource = resourceId, - tags = tags - ) is GallerySideEffect.DisplayStorageException -> displayStorageException( @@ -266,6 +265,10 @@ class GalleryUpliftFragment : Fragment() { state.galleryItems.size ) handleProgressState(state.progressState) + if (state.tags != cacheTags) { + displayPreviewTags(state.currentItem.id(), state.tags) + cacheTags = state.tags + } } private fun onBackClick() { @@ -397,25 +400,23 @@ class GalleryUpliftFragment : Fragment() { } private fun displayPreviewTags(resource: ResourceId, tags: Tags) { - lifecycleScope.launch { - Timber.d( - LogTags.GALLERY_SCREEN, - "displaying tags of resource $resource for preview" - ) - binding.tagsCg.removeAllViews() + Timber.d( + LogTags.GALLERY_SCREEN, + "displaying tags of resource $resource for preview" + ) + binding.tagsCg.removeAllViews() - tags.forEach { tag -> - val chip = Chip(context) - chip.text = tag + tags.forEach { tag -> + val chip = Chip(context) + chip.text = tag - chip.setOnClickListener { - showTagMenuPopup(tag, chip) - } - binding.tagsCg.addView(chip) + chip.setOnClickListener { + showTagMenuPopup(tag, chip) } - - binding.tagsCg.addView(createEditChip()) + binding.tagsCg.addView(chip) } + + binding.tagsCg.addView(createEditChip()) } private fun showEditTagsDialog( diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index d9e82867..9f03e752 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -267,12 +267,9 @@ class GalleryUpliftViewModel( fun onTagsChanged() = intent { val tags = tagsStorage.getTags(state.currentItem.id()) - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - resourceId = state.currentItem.id(), - tags = tags, - ) - ) + reduce { + state.copy(tags = tags) + } } @@ -283,11 +280,14 @@ class GalleryUpliftViewModel( reduce { state.copy(currentPos = newPos) } - postSideEffect(GallerySideEffect.AbortSelectAnimation) checkResourceChanges(newPos) val id = state.currentItem.id() val tags = tagsStorage.getTags(id) + reduce { + state.copy(tags = tags) + } + postSideEffect(GallerySideEffect.AbortSelectAnimation) displayPreview(id, state.currentItem.metadata, tags) } @@ -306,12 +306,9 @@ class GalleryUpliftViewModel( val id = state.currentItem.id() val tags = tagsStorage.getTags(id) val newTags = tags - tag - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - resourceId = id, - tags = newTags, - ) - ) + reduce { + state.copy(tags = newTags) + } statsStorage.handleEvent( StatsEvent.TagsChanged( id, tags, newTags @@ -353,12 +350,6 @@ class GalleryUpliftViewModel( meta = meta, ) ) - postSideEffect( - GallerySideEffect.DisplayPreviewTags( - resourceId = id, - tags = tags, - ) - ) scoreWidgetController.displayScore() } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index a237e6d4..67e315d4 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -6,6 +6,7 @@ import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.index.ResourceIndex import dev.arkbuilders.arklib.data.meta.Metadata import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.navigator.data.stats.StatsStorage import java.nio.file.Path @@ -16,7 +17,8 @@ data class GalleryState( val selectingEnabled: Boolean = false, val selectedResources: List = emptyList(), val controlsVisible: Boolean = true, - val progressState: ProgressState = ProgressState.HideProgress + val progressState: ProgressState = ProgressState.HideProgress, + val tags: Tags = emptySet() ) { val currentItem: GalleryItem get() = galleryItems[currentPos] @@ -56,10 +58,6 @@ sealed class GallerySideEffect { data class EditResource(val path: Path) : GallerySideEffect() data class OpenLink(val url: String) : GallerySideEffect() data class ViewInExternalApp(val path: Path) : GallerySideEffect() - data class DisplayPreviewTags( - val resourceId: ResourceId, - val tags: Set - ) : GallerySideEffect() data object NotifyTagsChanged : GallerySideEffect() data class ShowEditTagsDialog( From d3fdcbf79dcfd892ce59cf1caf81318b79518861 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 05:10:49 +0600 Subject: [PATCH 68/74] Handle setupPreview in render --- .../galleryuplift/GalleryUpliftFragment.kt | 24 +++++++------------ .../galleryuplift/GalleryUpliftViewModel.kt | 20 ++-------------- .../galleryuplift/domain/GalleryState.kt | 5 ---- 3 files changed, 11 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index e539525c..9b29f976 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -58,7 +58,6 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts -import kotlinx.coroutines.launch import org.orbitmvi.orbit.viewmodel.observe import timber.log.Timber import java.nio.file.Path @@ -222,10 +221,6 @@ class GalleryUpliftFragment : Fragment() { GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() is GallerySideEffect.OpenLink -> openLink(url) - is GallerySideEffect.SetUpPreview -> setupPreview( - pos = position, - meta = meta - ) is GallerySideEffect.ShareLink -> shareLink(url) is GallerySideEffect.ShareResource -> shareResource(path) @@ -269,6 +264,7 @@ class GalleryUpliftFragment : Fragment() { displayPreviewTags(state.currentItem.id(), state.tags) cacheTags = state.tags } + setupPreview(state.currentPos, state.currentItem.metadata) } private fun onBackClick() { @@ -282,16 +278,14 @@ class GalleryUpliftFragment : Fragment() { pos: Int, meta: Metadata ) { - lifecycleScope.launch { - with(binding) { - setupOpenEditFABs(meta) - ExtraLoader.load( - meta, - listOf(primaryExtra, secondaryExtra), - verbose = true - ) - requireArguments().putInt(START_AT_KEY, pos) - } + with(binding) { + setupOpenEditFABs(meta) + ExtraLoader.load( + meta, + listOf(primaryExtra, secondaryExtra), + verbose = true + ) + requireArguments().putInt(START_AT_KEY, pos) } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 9f03e752..58d51411 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -18,7 +18,6 @@ import dev.arkbuilders.arklib.user.score.ScoreStorage import dev.arkbuilders.arklib.user.score.ScoreStorageRepo import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.arklib.user.tags.TagStorage -import dev.arkbuilders.arklib.user.tags.Tags import dev.arkbuilders.arklib.user.tags.TagsStorageRepo import dev.arkbuilders.components.scorewidget.ScoreWidgetController import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics @@ -280,6 +279,7 @@ class GalleryUpliftViewModel( reduce { state.copy(currentPos = newPos) } + postSideEffect(GallerySideEffect.AbortSelectAnimation) checkResourceChanges(newPos) val id = state.currentItem.id() @@ -287,8 +287,7 @@ class GalleryUpliftViewModel( reduce { state.copy(tags = tags) } - postSideEffect(GallerySideEffect.AbortSelectAnimation) - displayPreview(id, state.currentItem.metadata, tags) + scoreWidgetController.displayScore() } fun onTagSelected(tag: Tag) { @@ -339,21 +338,6 @@ class GalleryUpliftViewModel( } - private fun displayPreview( - id: ResourceId, - meta: Metadata, - tags: Tags - ) = intent { - postSideEffect( - GallerySideEffect.SetUpPreview( - position = state.currentPos, - meta = meta, - ) - ) - scoreWidgetController.displayScore() - } - - private fun checkResourceChanges(pos: Int) = intent { if (state.galleryItems.isEmpty()) { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index 67e315d4..433c511b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -69,11 +69,6 @@ sealed class GallerySideEffect { val statsStorage: StatsStorage ) : GallerySideEffect() - data class SetUpPreview( - val position: Int, - val meta: Metadata - ) : GallerySideEffect() - // workaround to not show checkbox select animation when we change page data object AbortSelectAnimation: GallerySideEffect() From d823ab0b61241b1ca5b5b4775d2031eb45d02d98 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 05:21:06 +0600 Subject: [PATCH 69/74] Optimize render --- .../galleryuplift/GalleryUpliftFragment.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 9b29f976..c26dc014 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -92,7 +92,7 @@ class GalleryUpliftFragment : Fragment() { private lateinit var pagerAdapter: PreviewsPagerUplift // avoid pointless update on render if there are no changes - private var cacheTags: Tags? = null + private var cacheState: GalleryState? = null override fun onCreateView( inflater: LayoutInflater, @@ -252,7 +252,7 @@ class GalleryUpliftFragment : Fragment() { private fun render(state: GalleryState) { pagerAdapter.dispatchUpdates(state.galleryItems) - setControlsVisibility(state.controlsVisible) + binding.previewControls.isVisible = state.controlsVisible toggleSelecting(state.selectingEnabled) displaySelected( state.currentItemSelected, @@ -260,11 +260,15 @@ class GalleryUpliftFragment : Fragment() { state.galleryItems.size ) handleProgressState(state.progressState) - if (state.tags != cacheTags) { + if (state.tags != cacheState?.tags) { displayPreviewTags(state.currentItem.id(), state.tags) - cacheTags = state.tags } - setupPreview(state.currentPos, state.currentItem.metadata) + if (state.currentPos != cacheState?.currentPos || + state.currentItem.metadata != cacheState?.currentItem?.metadata + ) { + setupPreview(state.currentPos, state.currentItem.metadata) + } + cacheState = state } private fun onBackClick() { @@ -289,10 +293,6 @@ class GalleryUpliftFragment : Fragment() { } } - private fun setControlsVisibility(visible: Boolean) { - binding.previewControls.isVisible = visible - } - private fun editResource(resourcePath: Path) { val intent = getExternalAppIntent( resourcePath, From 40f0c1035c7f85381825f8f3efdf36ebcd2f9bdd Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 06:38:10 +0600 Subject: [PATCH 70/74] Move rootAndFav to state --- .../gallery/galleryuplift/GalleryUpliftViewModel.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 58d51411..398335e3 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -58,7 +58,7 @@ class GalleryUpliftViewModel( startPos: Int, selectingEnabled: Boolean, selectedResources: List, - private val rootAndFav: RootAndFav, + rootAndFav: RootAndFav, private val resourcesIds: List, val preferences: Preferences, val router: AppRouter, @@ -290,11 +290,11 @@ class GalleryUpliftViewModel( scoreWidgetController.displayScore() } - fun onTagSelected(tag: Tag) { + fun onTagSelected(tag: Tag) = intent { analytics.trackTagSelect() router.navigateTo( Screens.ResourcesScreenWithSelectedTag( - rootAndFav, tag + state.rootAndFav, tag ) ) } @@ -330,7 +330,7 @@ class GalleryUpliftViewModel( resource = state.currentItem.id(), resources = listOf(state.currentItem.id()), statsStorage = statsStorage, - rootAndFav = rootAndFav, + rootAndFav = state.rootAndFav, index = index, storage = tagsStorage, ) @@ -427,7 +427,7 @@ class GalleryUpliftViewModel( reduce { state.copy(progressState = ProgressState.ProvidingRootIndex) } - index = indexRepo.provide(rootAndFav) + index = indexRepo.provide(state.rootAndFav) messageFlow.onEach { message -> when (message) { is Message.KindDetectFailed -> From 3ff5299a27340919aaa5ce686dbc3f65b99e8739 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 06:53:14 +0600 Subject: [PATCH 71/74] Move resourcesIds to state --- .../galleryuplift/GalleryUpliftViewModel.kt | 15 +++++++++------ .../gallery/galleryuplift/domain/GalleryState.kt | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 398335e3..7d789cdc 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -59,7 +59,7 @@ class GalleryUpliftViewModel( selectingEnabled: Boolean, selectedResources: List, rootAndFav: RootAndFav, - private val resourcesIds: List, + resourcesIds: List, val preferences: Preferences, val router: AppRouter, val indexRepo: ResourceIndexRepo, @@ -81,6 +81,7 @@ class GalleryUpliftViewModel( container( GalleryState( rootAndFav = rootAndFav, + resourcesIds = resourcesIds, currentPos = startPos, selectingEnabled = selectingEnabled, selectedResources = selectedResources @@ -290,11 +291,11 @@ class GalleryUpliftViewModel( scoreWidgetController.displayScore() } - fun onTagSelected(tag: Tag) = intent { + fun onTagSelected(tag: Tag) { analytics.trackTagSelect() router.navigateTo( Screens.ResourcesScreenWithSelectedTag( - state.rootAndFav, tag + container.stateFlow.value.rootAndFav, tag ) ) } @@ -362,7 +363,9 @@ class GalleryUpliftViewModel( } } - private fun provideGalleryItems(): List = + private fun provideGalleryItems( + resourcesIds: List + ): List = try { val allResources = index.allResources() resourcesIds @@ -394,7 +397,7 @@ class GalleryUpliftViewModel( } }.join() - val newItems = provideGalleryItems() + val newItems = provideGalleryItems(state.resourcesIds) if (newItems.isEmpty()) { postSideEffect(GallerySideEffect.NavigateBack) return@intent @@ -464,7 +467,7 @@ class GalleryUpliftViewModel( } statsStorage = statsStorageRepo.provide(index) scoreWidgetController.init(scoreStorage) - val galleryItems = provideGalleryItems() + val galleryItems = provideGalleryItems(state.resourcesIds) viewModelScope.launch { val result = preferences.get( PreferenceKey.SortByScores diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index 433c511b..e7dbe678 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -13,6 +13,7 @@ import java.nio.file.Path data class GalleryState( val rootAndFav: RootAndFav, val currentPos: Int = 0, + val resourcesIds: List = emptyList(), val galleryItems: List = emptyList(), val selectingEnabled: Boolean = false, val selectedResources: List = emptyList(), From 495325bbd37e7788d6277a3e098f7c86e563c91e Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 06:54:58 +0600 Subject: [PATCH 72/74] minor --- .../gallery/galleryuplift/GalleryUpliftFragment.kt | 12 ------------ .../gallery/galleryuplift/domain/GalleryState.kt | 1 - 2 files changed, 13 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index c26dc014..28a05126 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -202,8 +202,6 @@ class GalleryUpliftFragment : Fragment() { } } - is GallerySideEffect.DeleteResource -> deleteResource(pos) - is GallerySideEffect.DisplayStorageException -> displayStorageException( label = label, @@ -342,16 +340,6 @@ class GalleryUpliftFragment : Fragment() { openIntentChooser(resourcePath, Intent.ACTION_VIEW, true) } - private fun deleteResource(pos: Int) { - binding.viewPager.apply { - setPageTransformer(null) - pagerAdapter.notifyItemRemoved(pos) - doOnNextLayout { - setPageTransformer(DepthPageTransformer()) - } - } - } - private fun displayStorageException(label: String, msg: String) { StorageExceptionDialogFragment.newInstance(label, msg).show( childFragmentManager, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index e7dbe678..5a4eb6c1 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -41,7 +41,6 @@ sealed class GallerySideEffect { data class ScrollToPage(val pos: Int) : GallerySideEffect() data object NotifyResourceScoresChanged : GallerySideEffect() data object NavigateBack : GallerySideEffect() - data class DeleteResource(val pos: Int) : GallerySideEffect() data class ToastIndexFailedPath(val path: Path) : GallerySideEffect() data class ShowInfoAlert( val path: Path, From a928af387d294da031ff583198ffdaf63a353b97 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Thu, 5 Sep 2024 10:23:13 +0600 Subject: [PATCH 73/74] ktlint formatting --- .../galleryuplift/GalleryUpliftFragment.kt | 10 +++++----- .../galleryuplift/GalleryUpliftViewModel.kt | 20 ++++++++++--------- .../GalleryUpliftViewModelFactory.kt | 6 +++--- .../PreviewImageViewHolderUplift.kt | 3 ++- .../galleryuplift/PreviewsPagerUplift.kt | 8 +++++--- .../galleryuplift/domain/GalleryState.kt | 2 +- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt index 28a05126..5c556fb5 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt @@ -13,7 +13,6 @@ import android.widget.Toast import androidx.activity.addCallback import androidx.core.content.FileProvider import androidx.core.os.bundleOf -import androidx.core.view.doOnNextLayout import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult @@ -78,7 +77,7 @@ class GalleryUpliftFragment : Fragment() { .toList() as List, rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! - .toList() as List, + .toList() as List ).apply { App.instance.appComponent.inject(this@GalleryUpliftFragment) } @@ -228,7 +227,7 @@ class GalleryUpliftFragment : Fragment() { statsStorage = statsStorage, rootAndFav = rootAndFav, index = index, - storage = storage, + storage = storage ) is GallerySideEffect.ShowInfoAlert -> showInfoAlert( @@ -305,7 +304,8 @@ class GalleryUpliftFragment : Fragment() { requireContext().startActivity(intent) } catch (e: ActivityNotFoundException) { Toast.makeText( - requireContext(), getString(R.string.no_app_found_to_open_this_file), + requireContext(), + getString(R.string.no_app_found_to_open_this_file), Toast.LENGTH_SHORT ).show() } @@ -702,7 +702,7 @@ class GalleryUpliftFragment : Fragment() { resources: List, startAt: Int, selectingEnabled: Boolean = false, - selectedResources: List = emptyList(), + selectedResources: List = emptyList() ) = GalleryUpliftFragment().apply { arguments = Bundle().apply { putParcelable(ROOT_AND_FAV_KEY, rootAndFav) diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt index 7d789cdc..28e1076a 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt @@ -68,7 +68,7 @@ class GalleryUpliftViewModel( val tagsStorageRepo: TagsStorageRepo, val statsStorageRepo: StatsStorageRepo, val scoreStorageRepo: ScoreStorageRepo, - val analytics: GalleryAnalytics, + val analytics: GalleryAnalytics ) : ContainerHost, ViewModel() { private lateinit var index: ResourceIndex private lateinit var tagsStorage: TagStorage @@ -203,8 +203,8 @@ class GalleryUpliftViewModel( reduce { if (enabled) { state.copy( - selectedResources = state.selectedResources - + state.currentItem.id() + selectedResources = state.selectedResources + + state.currentItem.id() ) } else { state.copy(selectedResources = emptyList()) @@ -272,10 +272,10 @@ class GalleryUpliftViewModel( } } - fun onPageChanged(newPos: Int) = intent { - if (state.galleryItems.isEmpty()) + if (state.galleryItems.isEmpty()) { return@intent + } reduce { state.copy(currentPos = newPos) @@ -295,7 +295,8 @@ class GalleryUpliftViewModel( analytics.trackTagSelect() router.navigateTo( Screens.ResourcesScreenWithSelectedTag( - container.stateFlow.value.rootAndFav, tag + container.stateFlow.value.rootAndFav, + tag ) ) } @@ -311,7 +312,9 @@ class GalleryUpliftViewModel( } statsStorage.handleEvent( StatsEvent.TagsChanged( - id, tags, newTags + id, + tags, + newTags ) ) Timber.d( @@ -333,12 +336,11 @@ class GalleryUpliftViewModel( statsStorage = statsStorage, rootAndFav = state.rootAndFav, index = index, - storage = tagsStorage, + storage = tagsStorage ) ) } - private fun checkResourceChanges(pos: Int) = intent { if (state.galleryItems.isEmpty()) { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt index 4a185d4e..a682631b 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt @@ -31,7 +31,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( val tagsStorageRepo: TagsStorageRepo, val statsStorageRepo: StatsStorageRepo, val scoreStorageRepo: ScoreStorageRepo, - val analytics: GalleryAnalytics, + val analytics: GalleryAnalytics ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { return GalleryUpliftViewModel( @@ -48,7 +48,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( tagsStorageRepo = tagsStorageRepo, statsStorageRepo = statsStorageRepo, scoreStorageRepo = scoreStorageRepo, - analytics = analytics, + analytics = analytics ) as T } @@ -59,7 +59,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @Assisted selectingEnabled: Boolean, @Assisted rootAndFav: RootAndFav, @Assisted("all") resourcesIds: List, - @Assisted("selected") selectedResources: List, + @Assisted("selected") selectedResources: List ): GalleryUpliftViewModelFactory } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt index d91452c4..a4b6260e 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt @@ -151,6 +151,7 @@ class PreviewImageViewHolderUplift( override fun onTileLoadError(e: Exception?) {} override fun onPreviewReleased() {} - }) + } + ) } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt index 04d2ece0..28bbf238 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt @@ -26,13 +26,14 @@ import java.nio.file.Path class PreviewsPagerUplift( val lifecycleScope: CoroutineScope, val context: Context, - val viewModel: GalleryUpliftViewModel, + val viewModel: GalleryUpliftViewModel ) : RecyclerView.Adapter() { private var galleryItems = emptyList() fun dispatchUpdates(newItems: List) { - if (newItems == galleryItems) + if (newItems == galleryItems) { return + } val diff = DiffUtil.calculateDiff( ResourceDiffUtilCallback( galleryItems.map { it.resource.id }, @@ -107,8 +108,9 @@ class PreviewsPagerUplift( override fun onViewRecycled(holder: RecyclerView.ViewHolder) { super.onViewRecycled(holder) - if (holder is PreviewImageViewHolderUplift) + if (holder is PreviewImageViewHolderUplift) { holder.onRecycled() + } } private fun getGestureDetector(): GestureDetectorCompat { diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt index 5a4eb6c1..cd51b296 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt @@ -70,7 +70,7 @@ sealed class GallerySideEffect { ) : GallerySideEffect() // workaround to not show checkbox select animation when we change page - data object AbortSelectAnimation: GallerySideEffect() + data object AbortSelectAnimation : GallerySideEffect() data object NotifyResourceChange : GallerySideEffect() data object NotifyCurrentItemChange : GallerySideEffect() From 7977711c696dd39e6a4e503956a6da2196e65560 Mon Sep 17 00:00:00 2001 From: mdrlzy Date: Sun, 20 Oct 2024 20:17:45 +0600 Subject: [PATCH 74/74] Remove old gallery screen --- .../arkbuilders/navigator/di/AppComponent.kt | 12 +- .../HandleGalleryExternalChangesUseCase.kt | 58 -- .../presentation/navigation/Screens.kt | 30 +- .../screen/gallery/GalleryFragment.kt | 500 +++++++----- .../screen/gallery/GalleryPresenter.kt | 456 ----------- .../screen/gallery/GalleryView.kt | 75 -- ...UpliftViewModel.kt => GalleryViewModel.kt} | 12 +- ...lFactory.kt => GalleryViewModelFactory.kt} | 8 +- .../{galleryuplift => }/domain/GalleryItem.kt | 2 +- .../domain/GalleryState.kt | 2 +- .../galleryuplift/GalleryUpliftFragment.kt | 719 ------------------ .../PreviewImageViewHolderUplift.kt | 157 ---- .../PreviewPlainTextViewHolderUplift.kt | 24 - .../PreviewImageViewHolder.kt | 12 +- .../PreviewPlainTextViewHolder.kt | 6 +- .../PreviewsPager.kt} | 19 +- .../gallery/previewpager/PreviewsPager.kt | 81 -- .../screen/resources/ResourcesFragment.kt | 2 +- .../adapter/ResourcesGridPresenter.kt | 12 +- 19 files changed, 336 insertions(+), 1851 deletions(-) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/domain/HandleGalleryExternalChangesUseCase.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryPresenter.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryView.kt rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{galleryuplift/GalleryUpliftViewModel.kt => GalleryViewModel.kt} (97%) rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{galleryuplift/GalleryUpliftViewModelFactory.kt => GalleryViewModelFactory.kt} (91%) rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{galleryuplift => }/domain/GalleryItem.kt (80%) rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{galleryuplift => }/domain/GalleryState.kt (97%) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{previewpager => pager}/PreviewImageViewHolder.kt (94%) rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{previewpager => pager}/PreviewPlainTextViewHolder.kt (82%) rename app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/{galleryuplift/PreviewsPagerUplift.kt => pager/PreviewsPager.kt} (89%) delete mode 100644 app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewsPager.kt diff --git a/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt b/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt index 1e027928..8f696c33 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/di/AppComponent.kt @@ -3,10 +3,13 @@ package dev.arkbuilders.navigator.di import android.content.Context import dagger.BindsInstance import dagger.Component +import dev.arkbuilders.arkfilepicker.folders.FoldersRepo +import dev.arkbuilders.navigator.analytics.AnalyticsModule import dev.arkbuilders.navigator.data.StorageBackup import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.di.modules.AppModule import dev.arkbuilders.navigator.di.modules.CiceroneModule +import dev.arkbuilders.navigator.di.modules.DispatcherModule import dev.arkbuilders.navigator.di.modules.RepoModule import dev.arkbuilders.navigator.presentation.App import dev.arkbuilders.navigator.presentation.dialog.ExplainPermsDialog @@ -17,18 +20,12 @@ import dev.arkbuilders.navigator.presentation.dialog.sort.SortDialogPresenter import dev.arkbuilders.navigator.presentation.dialog.tagssort.TagsSortDialogFragment import dev.arkbuilders.navigator.presentation.screen.folders.FoldersFragment import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewImageViewHolder import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.screen.resources.ResourcesFragment import dev.arkbuilders.navigator.presentation.screen.resources.ResourcesPresenter import dev.arkbuilders.navigator.presentation.screen.resources.adapter.FileItemViewHolder import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourcesGridPresenter import dev.arkbuilders.navigator.presentation.screen.settings.SettingsFragment -import dev.arkbuilders.arkfilepicker.folders.FoldersRepo -import dev.arkbuilders.navigator.analytics.AnalyticsModule -import dev.arkbuilders.navigator.di.modules.DispatcherModule -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.GalleryUpliftFragment import javax.inject.Singleton @Singleton @@ -49,15 +46,12 @@ interface AppComponent { fun inject(foldersFragment: FoldersFragment) fun inject(resourcesPresenter: ResourcesPresenter) fun inject(resourcesFragment: ResourcesFragment) - fun inject(galleryPresenter: GalleryPresenter) fun inject(galleryFragment: GalleryFragment) - fun inject(galleryFragment: GalleryUpliftFragment) fun inject(settingsFragment: SettingsFragment) fun inject(resourcesGridPresenter: ResourcesGridPresenter) fun inject(editTagsDialogPresenter: EditTagsDialogPresenter) fun inject(fileItemViewHolder: FileItemViewHolder) - fun inject(previewImageViewHolder: PreviewImageViewHolder) fun inject(sortDialogPresenter: SortDialogPresenter) fun inject(tagsSortDialogFragment: TagsSortDialogFragment) fun inject(rootPickerDialogFragment: RootPickerDialogFragment) diff --git a/app/src/main/java/dev/arkbuilders/navigator/domain/HandleGalleryExternalChangesUseCase.kt b/app/src/main/java/dev/arkbuilders/navigator/domain/HandleGalleryExternalChangesUseCase.kt deleted file mode 100644 index 9dce8cc0..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/domain/HandleGalleryExternalChangesUseCase.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.arkbuilders.navigator.domain - -import androidx.recyclerview.widget.DiffUtil -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter -import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.presenterScope -import javax.inject.Inject - -class HandleGalleryExternalChangesUseCase @Inject constructor() { - operator fun invoke( - presenter: GalleryPresenter - ) = with(presenter) { - presenterScope.launch { - withContext(Dispatchers.Main) { - viewState.setProgressVisibility(true, "Changes detected, indexing") - } - - index.updateAll() - - withContext(Dispatchers.Main) { - viewState.notifyResourcesChanged() - } - - presenterScope.launch { - metadataStorage.busy.collect { busy -> - if (!busy) { - cancel() - } - } - }.join() - - val newItems = provideGalleryItems() - if (newItems.isEmpty()) { - onBackClick() - return@launch - } - - diffResult = DiffUtil.calculateDiff( - ResourceDiffUtilCallback( - galleryItems.map { it.resource.id }, - newItems.map { it.resource.id } - ) - ) - - galleryItems = newItems.toMutableList() - - withContext(Dispatchers.Main) { - viewState.updatePagerAdapterWithDiff() - viewState.notifyCurrentItemChanged() - viewState.setProgressVisibility(false) - } - } - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt index 71c40b6e..290864d6 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/navigation/Screens.kt @@ -1,14 +1,13 @@ package dev.arkbuilders.navigator.presentation.navigation -import ru.terrakok.cicerone.android.support.SupportAppScreen import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.user.tags.Tag import dev.arkbuilders.navigator.presentation.screen.folders.FoldersFragment import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import dev.arkbuilders.navigator.presentation.screen.resources.ResourcesFragment import dev.arkbuilders.navigator.presentation.screen.settings.SettingsFragment -import dev.arkbuilders.arklib.user.tags.Tag -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.GalleryUpliftFragment +import ru.terrakok.cicerone.android.support.SupportAppScreen class Screens { class FoldersScreen : SupportAppScreen() { @@ -42,15 +41,6 @@ class Screens { GalleryFragment.newInstance(rootAndFav, resources, startAt) } - class GalleryUpliftScreen( - private val rootAndFav: RootAndFav, - val resources: List, - private val startAt: Int - ) : SupportAppScreen() { - override fun getFragment() = - GalleryUpliftFragment.newInstance(rootAndFav, resources, startAt) - } - class GalleryScreenWithSelected( private val rootAndFav: RootAndFav, val resources: List, @@ -67,22 +57,6 @@ class Screens { ) } - class GalleryScreenWithSelectedUplift( - private val rootAndFav: RootAndFav, - val resources: List, - private val startAt: Int, - private val selectedResources: List - ) : SupportAppScreen() { - override fun getFragment() = - GalleryUpliftFragment.newInstance( - rootAndFav, - resources, - startAt, - true, - selectedResources - ) - } - class SettingsScreen : SupportAppScreen() { override fun getFragment() = SettingsFragment.newInstance() } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt index 02d68b95..69ad7996 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryFragment.kt @@ -6,25 +6,38 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import android.util.TypedValue +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.activity.addCallback import androidx.core.content.FileProvider import androidx.core.os.bundleOf -import androidx.core.view.doOnNextLayout import androidx.core.view.isVisible +import androidx.fragment.app.Fragment import androidx.fragment.app.setFragmentResult +import androidx.fragment.app.viewModels import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.SimpleItemAnimator import androidx.viewpager2.widget.ViewPager2 import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.chip.Chip +import dev.arkbuilders.arkfilepicker.folders.RootAndFav +import dev.arkbuilders.arklib.ResourceId +import dev.arkbuilders.arklib.data.index.Resource +import dev.arkbuilders.arklib.data.index.ResourceIndex +import dev.arkbuilders.arklib.data.meta.Metadata +import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.arklib.user.tags.TagStorage +import dev.arkbuilders.arklib.user.tags.Tags +import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.components.databinding.ScoreWidgetBinding import dev.arkbuilders.components.scorewidget.ScoreWidget import dev.arkbuilders.navigator.BuildConfig import dev.arkbuilders.navigator.R -import dev.arkbuilders.navigator.data.utils.LogTags.GALLERY_SCREEN +import dev.arkbuilders.navigator.data.stats.StatsStorage +import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding import dev.arkbuilders.navigator.databinding.PopupGalleryTagMenuBinding import dev.arkbuilders.navigator.presentation.App @@ -32,7 +45,10 @@ import dev.arkbuilders.navigator.presentation.dialog.DetailsAlertDialog import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewsPager +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.ProgressState +import dev.arkbuilders.navigator.presentation.screen.gallery.pager.PreviewsPager import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader @@ -41,54 +57,48 @@ import dev.arkbuilders.navigator.presentation.utils.makeVisible import dev.arkbuilders.navigator.presentation.view.DefaultPopup import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer import dev.arkbuilders.navigator.presentation.view.StackedToasts -import kotlinx.coroutines.launch -import moxy.MvpAppCompatFragment -import moxy.ktx.moxyPresenter -import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.index.Resource -import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.user.tags.Tag -import dev.arkbuilders.arklib.user.tags.Tags -import dev.arkbuilders.arklib.utils.extension +import org.orbitmvi.orbit.viewmodel.observe import timber.log.Timber import java.nio.file.Path +import javax.inject.Inject import kotlin.system.measureTimeMillis -class GalleryFragment : - MvpAppCompatFragment(R.layout.fragment_gallery), GalleryView { - +class GalleryFragment : Fragment() { private val binding by viewBinding(FragmentGalleryBinding::bind) - private val presenter by moxyPresenter { - GalleryPresenter( + @Inject + lateinit var factory: GalleryViewModelFactory.Factory + private val viewModel: GalleryViewModel by viewModels { + factory.create( + startPos = requireArguments().getInt(START_AT_KEY), + selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), + selectedResources = requireArguments() + .getParcelableArray(SELECTED_RESOURCES_KEY)!! + .toList() as List, rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! - .toList() as List, - startAt = requireArguments().getInt(START_AT_KEY), - selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), - selectedResources = ( - requireArguments().getParcelableArray(SELECTED_RESOURCES_KEY)!! - .toList() as List - ) - .toMutableList() + .toList() as List ).apply { - - Timber.d(GALLERY_SCREEN, "creating GalleryPresenter") - - App.instance.appComponent.inject(this) + App.instance.appComponent.inject(this@GalleryFragment) } } - private lateinit var stackedToasts: StackedToasts - private lateinit var pagerAdapter: PreviewsPager + private val scoreWidget by lazy { - ScoreWidget(presenter.scoreWidgetController, viewLifecycleOwner) + ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - Timber.d(GALLERY_SCREEN, "view created in GalleryFragment") - super.onViewCreated(view, savedInstanceState) - App.instance.appComponent.inject(this) + private lateinit var stackedToasts: StackedToasts + private lateinit var pagerAdapter: PreviewsPager + + // avoid pointless update on render if there are no changes + private var cacheState: GalleryState? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_gallery, container, false) } override fun onDestroyView() { @@ -96,9 +106,19 @@ class GalleryFragment : scoreWidget.onDestroyView() } - override fun init() { - Timber.d(GALLERY_SCREEN, "currentItem = ${binding.viewPager.currentItem}") + override fun onResume() { + super.onResume() + viewModel.onResume() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") + App.instance.appComponent.inject(this) + super.onViewCreated(view, savedInstanceState) + Timber.d( + LogTags.GALLERY_SCREEN, + "currentItem = ${binding.viewPager.currentItem}" + ) animatePagerAppearance() initResultListener() stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope) @@ -107,20 +127,18 @@ class GalleryFragment : (requireActivity() as MainActivity).setBottomNavigationVisibility(false) requireActivity().onBackPressedDispatcher.addCallback(this) { - presenter.onBackClick() + onBackClick() } - - pagerAdapter = PreviewsPager(requireContext(), presenter) + pagerAdapter = + PreviewsPager(lifecycleScope, requireContext(), viewModel) initViewPager() scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) - binding.apply { val selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY) layoutSelected.isVisible = selectingEnabled fabStartSelect.isVisible = !selectingEnabled - removeResourceFab.setOnClickListener { Toast.makeText( requireContext(), @@ -128,87 +146,151 @@ class GalleryFragment : Toast.LENGTH_SHORT ).show() } - removeResourceFab.setOnLongClickListener { val time = measureTimeMillis { - presenter.onRemoveFabClick() + viewModel.onRemoveFabClick() } - Timber.tag(GALLERY_SCREEN).d("${time / 1000L}s") + Timber.tag(LogTags.GALLERY_SCREEN).d("${time / 1000L}s") true } - infoResourceFab.setOnClickListener { - presenter.onInfoFabClick() + viewModel.onInfoFabClick() } shareResourceFab.setOnClickListener { - presenter.onShareFabClick() + viewModel.onShareFabClick() } fabStartSelect.setOnClickListener { - presenter.onSelectingChanged() + viewModel.onSelectingChanged(true) } openResourceFab.setOnClickListener { - presenter.onOpenFabClick() + viewModel.onOpenFabClick() } editResourceFab.setOnClickListener { - presenter.onEditFabClick() + viewModel.onEditFabClick() } layoutSelected.setOnClickListener { - presenter.onSelectBtnClick() + viewModel.onSelectBtnClick() } layoutSelected.setOnLongClickListener { - presenter.onSelectingChanged() + viewModel.onSelectingChanged(false) return@setOnLongClickListener true } } + viewModel.observe( + lifecycleOwner = this, + state = ::render, + sideEffect = ::handleSideEffect + ) } - override fun updatePagerAdapter() { - pagerAdapter.notifyDataSetChanged() - binding.viewPager.adapter?.itemCount?.let { count -> - val startAt = requireArguments().getInt(START_AT_KEY) - if (startAt < count) { - binding.viewPager.setCurrentItem( - startAt, - false + private fun handleSideEffect(sideEffect: GallerySideEffect) { + with(sideEffect) { + when (this) { + is GallerySideEffect.ScrollToPage -> { + binding.viewPager.adapter?.itemCount?.let { count -> + if (this.pos < count) { + binding.viewPager.setCurrentItem( + this.pos, + false + ) + } + } + } + + is GallerySideEffect.DisplayStorageException -> + displayStorageException( + label = label, + msg = messenger + ) + + is GallerySideEffect.EditResource -> editResource(path) + GallerySideEffect.NavigateBack -> onBackClick() + GallerySideEffect.NotifyCurrentItemChange -> + notifyCurrentItemChanged() + + GallerySideEffect.NotifyResourceChange -> notifyResourcesChanged() + GallerySideEffect.NotifyResourceScoresChanged -> + notifyResourceScoresChanged() + + GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() + is GallerySideEffect.OpenLink -> openLink(url) + + is GallerySideEffect.ShareLink -> shareLink(url) + is GallerySideEffect.ShareResource -> shareResource(path) + is GallerySideEffect.ShowEditTagsDialog -> showEditTagsDialog( + resource = resource, + resources = resources, + statsStorage = statsStorage, + rootAndFav = rootAndFav, + index = index, + storage = storage + ) + + is GallerySideEffect.ShowInfoAlert -> showInfoAlert( + path = path, + resource = resource, + metadata = metadata ) + + is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath( + path + ) + + is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) + is GallerySideEffect.AbortSelectAnimation -> + binding.cbSelected.jumpDrawablesToCurrentState() } } } - override fun updatePagerAdapterWithDiff() { - presenter.diffResult?.dispatchUpdatesTo(pagerAdapter) + private fun render(state: GalleryState) { + pagerAdapter.dispatchUpdates(state.galleryItems) + binding.previewControls.isVisible = state.controlsVisible + toggleSelecting(state.selectingEnabled) + displaySelected( + state.currentItemSelected, + state.selectedResources.size, + state.galleryItems.size + ) + handleProgressState(state.progressState) + if (state.tags != cacheState?.tags) { + displayPreviewTags(state.currentItem.id(), state.tags) + } + if (state.currentPos != cacheState?.currentPos || + state.currentItem.metadata != cacheState?.currentItem?.metadata + ) { + setupPreview(state.currentPos, state.currentItem.metadata) + } + cacheState = state } - override fun setupPreview( + private fun onBackClick() { + Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") + notifySelectedChanged(viewModel.container.stateFlow.value.selectedResources) + exitFullscreen() + viewModel.router.exit() + } + + private fun setupPreview( pos: Int, meta: Metadata ) { - lifecycleScope.launch { - with(binding) { - setupOpenEditFABs(meta) - ExtraLoader.load( - meta, - listOf(primaryExtra, secondaryExtra), - verbose = true - ) - requireArguments().putInt(START_AT_KEY, pos) - } + with(binding) { + setupOpenEditFABs(meta) + ExtraLoader.load( + meta, + listOf(primaryExtra, secondaryExtra), + verbose = true + ) + requireArguments().putInt(START_AT_KEY, pos) } } - override fun setPreviewsScrollingEnabled(enabled: Boolean) { - binding.viewPager.isUserInputEnabled = enabled - } - - override fun setControlsVisibility(visible: Boolean) { - binding.previewControls.isVisible = visible - } - - override fun editResource(resourcePath: Path) { + private fun editResource(resourcePath: Path) { val intent = getExternalAppIntent( resourcePath, Intent.ACTION_EDIT, @@ -229,65 +311,55 @@ class GalleryFragment : } } - override fun shareResource(resourcePath: Path) = + private fun shareResource(resourcePath: Path) = openIntentChooser( resourcePath, Intent.ACTION_SEND, detachProcess = false ) - override fun openLink(link: String) { + private fun openLink(link: String) { val intent = Intent(Intent.ACTION_VIEW) val uri = Uri.parse(link) intent.data = uri startActivity(Intent.createChooser(intent, "View the link with:")) } - override fun shareLink(link: String) { + private fun shareLink(link: String) { val intent = Intent(Intent.ACTION_SEND) intent.putExtra(Intent.EXTRA_TEXT, link) intent.type = "text/plain" startActivity(Intent.createChooser(intent, "Share the link with:")) } - override fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { + private fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { DetailsAlertDialog(path, resource, metadata, requireContext()).show() } - override fun viewInExternalApp(resourcePath: Path) { + private fun viewInExternalApp(resourcePath: Path) { openIntentChooser(resourcePath, Intent.ACTION_VIEW, true) } - override fun deleteResource(pos: Int) { - binding.viewPager.apply { - setPageTransformer(null) - pagerAdapter.notifyItemRemoved(pos) - doOnNextLayout { - setPageTransformer(DepthPageTransformer()) - } - } - } - - override fun displayStorageException(label: String, msg: String) { + private fun displayStorageException(label: String, msg: String) { StorageExceptionDialogFragment.newInstance(label, msg).show( childFragmentManager, StorageExceptionDialogFragment.TAG ) } - override fun notifyResourcesChanged() { + private fun notifyResourcesChanged() { setFragmentResult(REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) } - override fun notifyTagsChanged() { + private fun notifyTagsChanged() { setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) } - override fun notifyResourceScoresChanged() { + private fun notifyResourceScoresChanged() { setFragmentResult(SCORES_CHANGED_KEY, bundleOf()) } - override fun notifySelectedChanged( + private fun notifySelectedChanged( selected: List ) { setFragmentResult( @@ -297,56 +369,96 @@ class GalleryFragment : SELECTING_ENABLED_KEY, requireArguments().getBoolean(SELECTING_ENABLED_KEY) ) - putParcelableArray(SELECTED_RESOURCES_KEY, selected.toTypedArray()) + putParcelableArray( + SELECTED_RESOURCES_KEY, + selected.toTypedArray() + ) } ) } - override fun toastIndexFailedPath(path: Path) { + private fun toastIndexFailedPath(path: Path) { stackedToasts.toast(path) } - override fun displayPreviewTags(resource: ResourceId, tags: Tags) { - lifecycleScope.launch { - Timber.d( - GALLERY_SCREEN, - "displaying tags of resource $resource for preview" - ) - binding.tagsCg.removeAllViews() + private fun displayPreviewTags(resource: ResourceId, tags: Tags) { + Timber.d( + LogTags.GALLERY_SCREEN, + "displaying tags of resource $resource for preview" + ) + binding.tagsCg.removeAllViews() - tags.forEach { tag -> - val chip = Chip(context) - chip.text = tag + tags.forEach { tag -> + val chip = Chip(context) + chip.text = tag - chip.setOnClickListener { - showTagMenuPopup(tag, chip) - } - binding.tagsCg.addView(chip) + chip.setOnClickListener { + showTagMenuPopup(tag, chip) } - - binding.tagsCg.addView(createEditChip()) + binding.tagsCg.addView(chip) } + + binding.tagsCg.addView(createEditChip()) } - override fun showEditTagsDialog( - resource: ResourceId + private fun showEditTagsDialog( + resource: ResourceId, + rootAndFav: RootAndFav, + resources: List, + index: ResourceIndex, + storage: TagStorage, + statsStorage: StatsStorage ) { Timber.d( - GALLERY_SCREEN, + LogTags.GALLERY_SCREEN, "showing [edit-tags] dialog for resource $resource" ) val dialog = EditTagsDialogFragment.newInstance( - requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - listOf(resource), - presenter.index, - presenter.tagsStorage, - presenter.statsStorage + rootAndFav = rootAndFav, + resources = resources, + index = index, + storage = storage, + statsStorage = statsStorage ) dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) } + private fun handleProgressState(state: ProgressState) { + when (state) { + ProgressState.HideProgress -> setProgressVisibility( + false, + "" + ) + + ProgressState.Indexing -> setProgressVisibility( + true, + getString(R.string.progress_text_changes_detected_indexing) + ) + + ProgressState.ProvidingDataStorage -> setProgressVisibility( + true, + getString(R.string.progress_text_providing_data_storage) + ) + + ProgressState.ProvidingMetaDataStorage -> setProgressVisibility( + true, + getString(R.string.progress_text_providing_metadata_storage) + ) + + ProgressState.ProvidingPreviewStorage -> setProgressVisibility( + true, + getString(R.string.progress_text_providing_previews_storage) + ) + + ProgressState.ProvidingRootIndex -> setProgressVisibility( + true, + getString(R.string.progress_text_providing_root_index) + ) + } + } + @SuppressLint("ClickableViewAccessibility") - override fun setProgressVisibility(isVisible: Boolean, withText: String) { + private fun setProgressVisibility(isVisible: Boolean, withText: String) { binding.layoutProgress.apply { root.isVisible = isVisible @@ -367,84 +479,59 @@ class GalleryFragment : } } - override fun exitFullscreen() { + private fun exitFullscreen() { FullscreenHelper.setStatusBarVisibility(true, requireActivity().window) (requireActivity() as MainActivity).setBottomNavigationVisibility(true) } - override fun notifyCurrentItemChanged() { + private fun notifyCurrentItemChanged() { binding.viewPager.post { pagerAdapter.notifyItemChanged(binding.viewPager.currentItem) } } - override fun displaySelected( + private fun displaySelected( selected: Boolean, - showAnim: Boolean, selectedCount: Int, itemCount: Int ) = with(binding) { Timber.d("display ${System.currentTimeMillis()}") cbSelected.isChecked = selected - if (!showAnim) { - cbSelected.jumpDrawablesToCurrentState() - } tvSelectedOf.text = "$selectedCount/$itemCount" return@with } - override fun onResume() { - super.onResume() - presenter.onResume() - } - - override fun toggleSelecting(enabled: Boolean) { + private fun toggleSelecting(enabled: Boolean) { binding.layoutSelected.isVisible = enabled binding.fabStartSelect.isVisible = !enabled requireArguments().apply { putBoolean(SELECTING_ENABLED_KEY, enabled) } - if (enabled) { - presenter.onSelectBtnClick() - } else { - binding.cbSelected.isChecked = false - } } - private fun initViewPager() = with(binding.viewPager) { - adapter = pagerAdapter - offscreenPageLimit = 2 - val rv = (getChildAt(0) as RecyclerView) - (rv.itemAnimator as SimpleItemAnimator).removeDuration = 0 - setPageTransformer(DepthPageTransformer()) - - registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - presenter.onPageChanged(position) + private fun setupOpenEditFABs(meta: Metadata?) = binding.apply { + openResourceFab.makeGone() + editResourceFab.makeGone() + when (meta) { + is Metadata.Video, is Metadata.Link, null -> { + // "open" capabilities only + openResourceFab.makeVisible() } - }) - } - private fun showTagMenuPopup(tag: Tag, tagView: View) { - val menuBinding = PopupGalleryTagMenuBinding - .inflate(requireActivity().layoutInflater) - val popup = DefaultPopup( - menuBinding, - R.style.BottomFadeScaleAnimation, - R.drawable.bg_rounded_16dp - ) - menuBinding.apply { - btnNewSelection.setOnClickListener { - presenter.onTagSelected(tag) - popup.popupWindow.dismiss() + is Metadata.Document, is Metadata.PlainText -> { + // both "open" and "edit" capabilities + editResourceFab.makeVisible() + openResourceFab.makeVisible() } - btnRemoveTag.setOnClickListener { - presenter.onTagRemove(tag) - popup.popupWindow.dismiss() + + is Metadata.Image -> { + // "edit" capabilities only + editResourceFab.makeVisible() } + + else -> {} } - popup.showAbove(tagView) } /** @@ -457,14 +544,14 @@ class GalleryFragment : this ) { _, _ -> setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) - presenter.onTagsChanged() + viewModel.onTagsChanged() } childFragmentManager.setFragmentResultListener( StorageExceptionDialogFragment.STORAGE_CORRUPTION_DETECTED, this ) { _, _ -> - presenter.router.newRootScreen(Screens.FoldersScreen()) + viewModel.router.newRootScreen(Screens.FoldersScreen()) } } @@ -475,28 +562,39 @@ class GalleryFragment : } } - private fun setupOpenEditFABs(meta: Metadata?) = binding.apply { - openResourceFab.makeGone() - editResourceFab.makeGone() - when (meta) { - is Metadata.Video, is Metadata.Link, null -> { - // "open" capabilities only - openResourceFab.makeVisible() - } + private fun initViewPager() = with(binding.viewPager) { + adapter = pagerAdapter + offscreenPageLimit = 2 + val rv = (getChildAt(0) as RecyclerView) + (rv.itemAnimator as SimpleItemAnimator).removeDuration = 0 + setPageTransformer(DepthPageTransformer()) - is Metadata.Document, is Metadata.PlainText -> { - // both "open" and "edit" capabilities - editResourceFab.makeVisible() - openResourceFab.makeVisible() + registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + viewModel.onPageChanged(position) } + }) + } - is Metadata.Image -> { - // "edit" capabilities only - editResourceFab.makeVisible() + private fun showTagMenuPopup(tag: Tag, tagView: View) { + val menuBinding = PopupGalleryTagMenuBinding + .inflate(requireActivity().layoutInflater) + val popup = DefaultPopup( + menuBinding, + R.style.BottomFadeScaleAnimation, + R.drawable.bg_rounded_16dp + ) + menuBinding.apply { + btnNewSelection.setOnClickListener { + viewModel.onTagSelected(tag) + popup.popupWindow.dismiss() + } + btnRemoveTag.setOnClickListener { + viewModel.onTagRemove(tag) + popup.popupWindow.dismiss() } - - else -> {} } + popup.showAbove(tagView) } private fun openIntentChooser( @@ -505,7 +603,7 @@ class GalleryFragment : detachProcess: Boolean ) { Timber.i( - GALLERY_SCREEN, + LogTags.GALLERY_SCREEN, "Opening resource in an external application " + "path: $resourcePath" + "action: $actionType" @@ -551,7 +649,7 @@ class GalleryFragment : } } Timber.d( - GALLERY_SCREEN, + LogTags.GALLERY_SCREEN, "URI: ${intent.data}" + "MIME: ${intent.type}" ) return intent @@ -579,10 +677,10 @@ class GalleryFragment : setOnClickListener { val position = binding.viewPager.currentItem Timber.d( - GALLERY_SCREEN, + LogTags.GALLERY_SCREEN, "[edit_tags] clicked at position $position" ) - presenter.onEditTagsDialogBtnClick() + viewModel.onEditTagsDialogBtnClick() } } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryPresenter.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryPresenter.kt deleted file mode 100644 index 0569361f..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryPresenter.kt +++ /dev/null @@ -1,456 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery - -import androidx.recyclerview.widget.DiffUtil -import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.Message -import dev.arkbuilders.arklib.data.index.Resource -import dev.arkbuilders.arklib.data.index.ResourceIndex -import dev.arkbuilders.arklib.data.index.ResourceIndexRepo -import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.data.meta.MetadataProcessor -import dev.arkbuilders.arklib.data.meta.MetadataProcessorRepo -import dev.arkbuilders.arklib.data.preview.PreviewLocator -import dev.arkbuilders.arklib.data.preview.PreviewProcessor -import dev.arkbuilders.arklib.data.preview.PreviewProcessorRepo -import dev.arkbuilders.arklib.data.stats.StatsEvent -import dev.arkbuilders.arklib.data.storage.StorageException -import dev.arkbuilders.arklib.user.score.ScoreStorage -import dev.arkbuilders.arklib.user.score.ScoreStorageRepo -import dev.arkbuilders.arklib.user.tags.Tag -import dev.arkbuilders.arklib.user.tags.TagStorage -import dev.arkbuilders.arklib.user.tags.Tags -import dev.arkbuilders.arklib.user.tags.TagsStorageRepo -import dev.arkbuilders.arklib.utils.ImageUtils -import dev.arkbuilders.arklib.utils.extension -import dev.arkbuilders.components.scorewidget.ScoreWidgetController -import dev.arkbuilders.navigator.analytics.gallery.GalleryAnalytics -import dev.arkbuilders.navigator.data.preferences.PreferenceKey -import dev.arkbuilders.navigator.data.preferences.Preferences -import dev.arkbuilders.navigator.data.stats.StatsStorage -import dev.arkbuilders.navigator.data.stats.StatsStorageRepo -import dev.arkbuilders.navigator.data.utils.LogTags.GALLERY_SCREEN -import dev.arkbuilders.navigator.domain.HandleGalleryExternalChangesUseCase -import dev.arkbuilders.navigator.presentation.navigation.AppRouter -import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewImageViewHolder -import dev.arkbuilders.navigator.presentation.screen.gallery.previewpager.PreviewPlainTextViewHolder -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.MvpPresenter -import moxy.presenterScope -import timber.log.Timber -import java.io.FileReader -import java.nio.file.Files -import java.nio.file.Path -import javax.inject.Inject -import kotlin.io.path.getLastModifiedTime -import kotlin.io.path.notExists - -class GalleryPresenter( - private val rootAndFav: RootAndFav, - private val resourcesIds: List, - startAt: Int, - private var selectingEnabled: Boolean, - private val selectedResources: MutableList, - private val defaultDispatcher: CoroutineDispatcher = Dispatchers.IO -) : MvpPresenter() { - - val scoreWidgetController = ScoreWidgetController( - presenterScope, - getCurrentId = { currentItem.id() }, - onScoreChanged = { viewState.notifyResourceScoresChanged() } - ) - - lateinit var index: ResourceIndex - private set - lateinit var tagsStorage: TagStorage - private set - private lateinit var previewStorage: PreviewProcessor - lateinit var metadataStorage: MetadataProcessor - private set - lateinit var statsStorage: StatsStorage - private set - private lateinit var scoreStorage: ScoreStorage - - data class GalleryItem( - val resource: Resource, - val preview: PreviewLocator, - val metadata: Metadata - ) { - fun id() = resource.id - } - - var galleryItems: MutableList = mutableListOf() - - var diffResult: DiffUtil.DiffResult? = null - - private var currentPos = startAt - - private val currentItem: GalleryItem - get() = galleryItems[currentPos] - - private var sortByScores = false - private var isControlsVisible = false - - @Inject - lateinit var preferences: Preferences - - @Inject - lateinit var router: AppRouter - - @Inject - lateinit var indexRepo: ResourceIndexRepo - - @Inject - lateinit var previewStorageRepo: PreviewProcessorRepo - - @Inject - lateinit var metadataStorageRepo: MetadataProcessorRepo - - @Inject - lateinit var tagsStorageRepo: TagsStorageRepo - - @Inject - lateinit var statsStorageRepo: StatsStorageRepo - - @Inject - lateinit var scoreStorageRepo: ScoreStorageRepo - - private val messageFlow: MutableSharedFlow = MutableSharedFlow() - - @Inject - lateinit var handleGalleryExternalChangesUseCase: - HandleGalleryExternalChangesUseCase - - @Inject - lateinit var analytics: GalleryAnalytics - - override fun onFirstViewAttach() { - analytics.trackScreen() - Timber.d(GALLERY_SCREEN, "first view attached in GalleryPresenter") - super.onFirstViewAttach() - presenterScope.launch { - viewState.init() - viewState.setProgressVisibility(true, "Providing root index") - - index = indexRepo.provide(rootAndFav) - messageFlow.onEach { message -> - when (message) { - is Message.KindDetectFailed -> viewState.toastIndexFailedPath( - message.path - ) - } - }.launchIn(presenterScope) - - viewState.setProgressVisibility(true, "Providing metadata storage") - metadataStorage = metadataStorageRepo.provide(index) - - viewState.setProgressVisibility(true, "Providing previews storage") - previewStorage = previewStorageRepo.provide(index) - - viewState.setProgressVisibility(true, "Proviging data storages") - - try { - tagsStorage = tagsStorageRepo.provide(index) - scoreStorage = scoreStorageRepo.provide(index) - } catch (e: StorageException) { - viewState.displayStorageException( - e.label, - e.msg - ) - } - - statsStorage = statsStorageRepo.provide(index) - scoreWidgetController.init(scoreStorage) - - galleryItems = provideGalleryItems().toMutableList() - - sortByScores = preferences.get(PreferenceKey.SortByScores) - - viewState.updatePagerAdapter() - viewState.setProgressVisibility(false) - scoreWidgetController.setVisible(sortByScores) - } - } - - fun onPageChanged(newPos: Int) = presenterScope.launch { - if (galleryItems.isEmpty()) { - return@launch - } - - checkResourceChanges(newPos) - - currentPos = newPos - - val id = currentItem.id() - val tags = tagsStorage.getTags(id) - displayPreview(id, currentItem.metadata, tags) - } - - fun onResume() { - checkResourceChanges(currentPos) - } - - fun getKind(pos: Int): Int = - galleryItems[pos].metadata.kind.ordinal - - fun bindView(view: PreviewImageViewHolder) = presenterScope.launch { - view.reset() - val item = galleryItems[view.pos] - - val path = index.getPath(item.id())!! - val placeholder = ImageUtils.iconForExtension(extension(path)) - view.setSource(placeholder, item.id(), item.metadata, item.preview) - } - - fun bindPlainTextView(view: PreviewPlainTextViewHolder) = presenterScope.launch { - view.reset() - val item = galleryItems[view.pos] - - val path = index.getPath(item.id())!! - val content = readText(path) - - content.onSuccess { - view.setContent(it) - } - } - - fun onTagsChanged() { - val tags = tagsStorage.getTags(currentItem.id()) - viewState.displayPreviewTags(currentItem.id(), tags) - } - - fun onOpenFabClick() = presenterScope.launch { - analytics.trackResOpen() - Timber.d(GALLERY_SCREEN, "[open_resource] clicked at position $currentPos") - - val id = currentItem.id() - val path = index.getPath(id)!! - - if (currentItem.metadata is Metadata.Link) { - val url = readText(path).getOrThrow() - viewState.openLink(url) - - return@launch - } - - viewState.viewInExternalApp(path) - } - - fun onInfoFabClick() = presenterScope.launch { - analytics.trackResInfo() - Timber.d(GALLERY_SCREEN, "[info_resource] clicked at position $currentPos") - - val path = index.getPath(currentItem.id())!! - viewState.showInfoAlert(path, currentItem.resource, currentItem.metadata) - } - - fun onShareFabClick() = presenterScope.launch { - analytics.trackResShare() - Timber.d(GALLERY_SCREEN, "[share_resource] clicked at position $currentPos") - val path = index.getPath(currentItem.id())!! - - if (currentItem.metadata is Metadata.Link) { - val url = readText(path).getOrThrow() - viewState.shareLink(url) - return@launch - } - - viewState.shareResource(path) - } - - fun onEditFabClick() = presenterScope.launch { - analytics.trackResEdit() - Timber.d(GALLERY_SCREEN, "[edit_resource] clicked at position $currentPos") - val path = index.getPath(currentItem.id())!! - viewState.editResource(path) - } - - fun onRemoveFabClick() = presenterScope.launch(NonCancellable) { - analytics.trackResRemove() - Timber.d(GALLERY_SCREEN, "[remove_resource] clicked at position $currentPos") - deleteResource(currentItem.id()) - galleryItems.removeAt(currentPos) - - if (galleryItems.isEmpty()) { - onBackClick() - return@launch - } - - onTagsChanged() - viewState.deleteResource(currentPos) - } - - fun onTagSelected(tag: Tag) { - analytics.trackTagSelect() - router.navigateTo( - Screens.ResourcesScreenWithSelectedTag( - rootAndFav, - tag - ) - ) - } - - fun onTagRemove(tag: Tag) = presenterScope.launch(NonCancellable) { - analytics.trackTagRemove() - val id = currentItem.id() - - val tags = tagsStorage.getTags(id) - val newTags = tags - tag - - viewState.displayPreviewTags(id, newTags) - statsStorage.handleEvent( - StatsEvent.TagsChanged( - id, - tags, - newTags - ) - ) - - Timber.d(GALLERY_SCREEN, "setting new tags $newTags to $currentItem") - - tagsStorage.setTags(id, newTags) - tagsStorage.persist() - viewState.notifyTagsChanged() - } - - fun onSelectBtnClick() { - val id = currentItem.id() - val wasSelected = id in selectedResources - - if (wasSelected) { - selectedResources.remove(id) - } else { - selectedResources.add(id) - } - - viewState.displaySelected( - !wasSelected, - showAnim = true, - selectedResources.size, - galleryItems.size - ) - } - - fun onEditTagsDialogBtnClick() { - analytics.trackTagsEdit() - viewState.showEditTagsDialog(currentItem.id()) - } - - private fun checkResourceChanges(pos: Int) = - presenterScope.launch(defaultDispatcher) { - if (galleryItems.isEmpty()) { - return@launch - } - - val item = galleryItems[pos] - - val path = index.getPath(item.id()) - ?: let { - Timber.d("Resource ${item.id()} can't be found in the index") - handleGalleryExternalChangesUseCase(this@GalleryPresenter) - return@launch - } - - if (path.notExists()) { - Timber.d("Resource ${item.id()} isn't stored by path $path") - handleGalleryExternalChangesUseCase(this@GalleryPresenter) - return@launch - } - - if (path.getLastModifiedTime() != item.resource.modified) { - Timber.d("Index is not up-to-date regarding path $path") - handleGalleryExternalChangesUseCase(this@GalleryPresenter) - return@launch - } - } - - private suspend fun deleteResource(resource: ResourceId) { - Timber.d(GALLERY_SCREEN, "deleting resource $resource") - - val path = index.getPath(resource) - - withContext(defaultDispatcher) { - Files.delete(path) - } - - index.updateAll() - viewState.notifyResourcesChanged() - } - - private fun displayPreview( - id: ResourceId, - meta: Metadata, - tags: Tags - ) { - viewState.setupPreview(currentPos, meta) - viewState.displayPreviewTags(id, tags) - scoreWidgetController.displayScore() - viewState.displaySelected( - id in selectedResources, - showAnim = false, - selectedResources.size, - galleryItems.size - ) - } - - fun onPreviewsItemClick() { - isControlsVisible = !isControlsVisible - viewState.setControlsVisibility(isControlsVisible) - } - - fun onSelectingChanged() { - selectingEnabled = !selectingEnabled - viewState.toggleSelecting(selectingEnabled) - selectedResources.clear() - if (selectingEnabled) { - selectedResources.add(currentItem.resource.id) - } - } - - fun onPlayButtonClick() = presenterScope.launch { - viewState.viewInExternalApp(index.getPath(currentItem.id())!!) - } - - fun onBackClick() { - Timber.d(GALLERY_SCREEN, "quitting from GalleryPresenter") - viewState.notifySelectedChanged(selectedResources) - viewState.exitFullscreen() - router.exit() - } - - fun provideGalleryItems(): List = - try { - val allResources = index.allResources() - resourcesIds - .filter { allResources.keys.contains(it) } - .map { id -> - val preview = previewStorage.retrieve(id).getOrThrow() - val metadata = metadataStorage.retrieve(id).getOrThrow() - val resource = allResources.getOrElse(id) { - throw NullPointerException("Resource not exist") - } - GalleryItem(resource, preview, metadata) - }.toMutableList() - } catch (e: Exception) { - Timber.d("Can't provide gallery items") - emptyList() - } - - private suspend fun readText(source: Path): Result = - withContext(defaultDispatcher) { - try { - val content = FileReader(source.toFile()).readText() - Result.success(content) - } catch (e: Exception) { - Result.failure(e) - } - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryView.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryView.kt deleted file mode 100644 index 4d856a2d..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryView.kt +++ /dev/null @@ -1,75 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery - -import dev.arkbuilders.navigator.presentation.common.CommonMvpView -import moxy.viewstate.strategy.AddToEndSingleStrategy -import moxy.viewstate.strategy.SkipStrategy -import moxy.viewstate.strategy.StateStrategyType -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.index.Resource -import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.user.tags.Tags -import java.nio.file.Path - -@StateStrategyType(AddToEndSingleStrategy::class) -interface GalleryView : CommonMvpView { - fun init() - fun updatePagerAdapter() - fun updatePagerAdapterWithDiff() - fun setControlsVisibility(visible: Boolean) - fun exitFullscreen() - fun setPreviewsScrollingEnabled(enabled: Boolean) - fun setupPreview(pos: Int, meta: Metadata) - fun displayPreviewTags(resource: ResourceId, tags: Tags) - fun setProgressVisibility(isVisible: Boolean, withText: String = "") - fun displaySelected( - selected: Boolean, - showAnim: Boolean, - selectedCount: Int, - itemCount: Int - ) - - @StateStrategyType(SkipStrategy::class) - fun openLink(link: String) - - @StateStrategyType(SkipStrategy::class) - fun shareLink(link: String) - - @StateStrategyType(SkipStrategy::class) - fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) - - @StateStrategyType(SkipStrategy::class) - fun viewInExternalApp(resourcePath: Path) - - @StateStrategyType(SkipStrategy::class) - fun editResource(resourcePath: Path) - - @StateStrategyType(SkipStrategy::class) - fun shareResource(resourcePath: Path) - - @StateStrategyType(SkipStrategy::class) - fun showEditTagsDialog(resource: ResourceId) - - @StateStrategyType(SkipStrategy::class) - fun deleteResource(pos: Int) - - @StateStrategyType(SkipStrategy::class) - fun toggleSelecting(enabled: Boolean) - - @StateStrategyType(SkipStrategy::class) - fun notifyResourcesChanged() - - @StateStrategyType(SkipStrategy::class) - fun notifyTagsChanged() - - @StateStrategyType(SkipStrategy::class) - fun notifyCurrentItemChanged() - - @StateStrategyType(SkipStrategy::class) - fun notifyResourceScoresChanged() - - @StateStrategyType(SkipStrategy::class) - fun notifySelectedChanged(selected: List) - - @StateStrategyType(SkipStrategy::class) - fun displayStorageException(label: String, msg: String) -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModel.kt similarity index 97% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModel.kt index 28e1076a..5d5c90ee 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModel.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModel.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift +package dev.arkbuilders.navigator.presentation.screen.gallery import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -28,10 +28,10 @@ import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.data.utils.LogTags import dev.arkbuilders.navigator.presentation.navigation.AppRouter import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GallerySideEffect -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryState -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressState +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GalleryItem +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GallerySideEffect +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GalleryState +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.ProgressState import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.cancel @@ -54,7 +54,7 @@ import java.nio.file.Path import kotlin.io.path.getLastModifiedTime import kotlin.io.path.notExists -class GalleryUpliftViewModel( +class GalleryViewModel( startPos: Int, selectingEnabled: Boolean, selectedResources: List, diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModelFactory.kt similarity index 91% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModelFactory.kt index a682631b..68cc6ccd 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftViewModelFactory.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/GalleryViewModelFactory.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift +package dev.arkbuilders.navigator.presentation.screen.gallery import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -17,7 +17,7 @@ import dev.arkbuilders.navigator.data.preferences.Preferences import dev.arkbuilders.navigator.data.stats.StatsStorageRepo import dev.arkbuilders.navigator.presentation.navigation.AppRouter -class GalleryUpliftViewModelFactory @AssistedInject constructor( +class GalleryViewModelFactory @AssistedInject constructor( @Assisted val startPos: Int, @Assisted val selectingEnabled: Boolean, @Assisted private val rootAndFav: RootAndFav, @@ -34,7 +34,7 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( val analytics: GalleryAnalytics ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return GalleryUpliftViewModel( + return GalleryViewModel( startPos = startPos, selectingEnabled = selectingEnabled, selectedResources = selectedResources, @@ -60,6 +60,6 @@ class GalleryUpliftViewModelFactory @AssistedInject constructor( @Assisted rootAndFav: RootAndFav, @Assisted("all") resourcesIds: List, @Assisted("selected") selectedResources: List - ): GalleryUpliftViewModelFactory + ): GalleryViewModelFactory } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryItem.kt similarity index 80% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryItem.kt index 5e6e3c67..55fa2337 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryItem.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryItem.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain +package dev.arkbuilders.navigator.presentation.screen.gallery.domain import dev.arkbuilders.arklib.data.index.Resource import dev.arkbuilders.arklib.data.meta.Metadata diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryState.kt similarity index 97% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryState.kt index cd51b296..92e95e16 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/domain/GalleryState.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/domain/GalleryState.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain +package dev.arkbuilders.navigator.presentation.screen.gallery.domain import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arklib.ResourceId diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt deleted file mode 100644 index 5c556fb5..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/GalleryUpliftFragment.kt +++ /dev/null @@ -1,719 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift - -import android.annotation.SuppressLint -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.util.TypedValue -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.activity.addCallback -import androidx.core.content.FileProvider -import androidx.core.os.bundleOf -import androidx.core.view.isVisible -import androidx.fragment.app.Fragment -import androidx.fragment.app.setFragmentResult -import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.SimpleItemAnimator -import androidx.viewpager2.widget.ViewPager2 -import by.kirich1409.viewbindingdelegate.viewBinding -import com.google.android.material.chip.Chip -import dev.arkbuilders.arkfilepicker.folders.RootAndFav -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.index.Resource -import dev.arkbuilders.arklib.data.index.ResourceIndex -import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.user.tags.Tag -import dev.arkbuilders.arklib.user.tags.TagStorage -import dev.arkbuilders.arklib.user.tags.Tags -import dev.arkbuilders.arklib.utils.extension -import dev.arkbuilders.components.databinding.ScoreWidgetBinding -import dev.arkbuilders.components.scorewidget.ScoreWidget -import dev.arkbuilders.navigator.BuildConfig -import dev.arkbuilders.navigator.R -import dev.arkbuilders.navigator.data.stats.StatsStorage -import dev.arkbuilders.navigator.data.utils.LogTags -import dev.arkbuilders.navigator.databinding.FragmentGalleryBinding -import dev.arkbuilders.navigator.databinding.PopupGalleryTagMenuBinding -import dev.arkbuilders.navigator.presentation.App -import dev.arkbuilders.navigator.presentation.dialog.DetailsAlertDialog -import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment -import dev.arkbuilders.navigator.presentation.dialog.edittags.EditTagsDialogFragment -import dev.arkbuilders.navigator.presentation.navigation.Screens -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GallerySideEffect -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryState -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.ProgressState -import dev.arkbuilders.navigator.presentation.screen.main.MainActivity -import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper -import dev.arkbuilders.navigator.presentation.utils.extra.ExtraLoader -import dev.arkbuilders.navigator.presentation.utils.makeGone -import dev.arkbuilders.navigator.presentation.utils.makeVisible -import dev.arkbuilders.navigator.presentation.view.DefaultPopup -import dev.arkbuilders.navigator.presentation.view.DepthPageTransformer -import dev.arkbuilders.navigator.presentation.view.StackedToasts -import org.orbitmvi.orbit.viewmodel.observe -import timber.log.Timber -import java.nio.file.Path -import javax.inject.Inject -import kotlin.system.measureTimeMillis - -class GalleryUpliftFragment : Fragment() { - private val binding by viewBinding(FragmentGalleryBinding::bind) - - @Inject - lateinit var factory: GalleryUpliftViewModelFactory.Factory - private val viewModel: GalleryUpliftViewModel by viewModels { - factory.create( - startPos = requireArguments().getInt(START_AT_KEY), - selectingEnabled = requireArguments().getBoolean(SELECTING_ENABLED_KEY), - selectedResources = requireArguments() - .getParcelableArray(SELECTED_RESOURCES_KEY)!! - .toList() as List, - rootAndFav = requireArguments()[ROOT_AND_FAV_KEY] as RootAndFav, - resourcesIds = requireArguments().getParcelableArray(RESOURCES_KEY)!! - .toList() as List - ).apply { - App.instance.appComponent.inject(this@GalleryUpliftFragment) - } - } - - private val scoreWidget by lazy { - ScoreWidget(viewModel.scoreWidgetController, viewLifecycleOwner) - } - - private lateinit var stackedToasts: StackedToasts - private lateinit var pagerAdapter: PreviewsPagerUplift - - // avoid pointless update on render if there are no changes - private var cacheState: GalleryState? = null - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.fragment_gallery, container, false) - } - - override fun onDestroyView() { - super.onDestroyView() - scoreWidget.onDestroyView() - } - - override fun onResume() { - super.onResume() - viewModel.onResume() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - Timber.d(LogTags.GALLERY_SCREEN, "view created in GalleryFragment") - App.instance.appComponent.inject(this) - super.onViewCreated(view, savedInstanceState) - Timber.d( - LogTags.GALLERY_SCREEN, - "currentItem = ${binding.viewPager.currentItem}" - ) - animatePagerAppearance() - initResultListener() - stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope) - - FullscreenHelper.setStatusBarVisibility(false, requireActivity().window) - (requireActivity() as MainActivity).setBottomNavigationVisibility(false) - - requireActivity().onBackPressedDispatcher.addCallback(this) { - onBackClick() - } - pagerAdapter = - PreviewsPagerUplift(lifecycleScope, requireContext(), viewModel) - - initViewPager() - scoreWidget.init(ScoreWidgetBinding.bind(binding.scoreWidget)) - binding.apply { - val selectingEnabled = - requireArguments().getBoolean(GalleryFragment.SELECTING_ENABLED_KEY) - layoutSelected.isVisible = selectingEnabled - fabStartSelect.isVisible = !selectingEnabled - removeResourceFab.setOnClickListener { - Toast.makeText( - requireContext(), - "Press and hold to delete", - Toast.LENGTH_SHORT - ).show() - } - removeResourceFab.setOnLongClickListener { - val time = measureTimeMillis { - viewModel.onRemoveFabClick() - } - Timber.tag(LogTags.GALLERY_SCREEN).d("${time / 1000L}s") - true - } - infoResourceFab.setOnClickListener { - viewModel.onInfoFabClick() - } - shareResourceFab.setOnClickListener { - viewModel.onShareFabClick() - } - fabStartSelect.setOnClickListener { - viewModel.onSelectingChanged(true) - } - - openResourceFab.setOnClickListener { - viewModel.onOpenFabClick() - } - - editResourceFab.setOnClickListener { - viewModel.onEditFabClick() - } - - layoutSelected.setOnClickListener { - viewModel.onSelectBtnClick() - } - - layoutSelected.setOnLongClickListener { - viewModel.onSelectingChanged(false) - return@setOnLongClickListener true - } - } - viewModel.observe( - lifecycleOwner = this, - state = ::render, - sideEffect = ::handleSideEffect - ) - } - - private fun handleSideEffect(sideEffect: GallerySideEffect) { - with(sideEffect) { - when (this) { - is GallerySideEffect.ScrollToPage -> { - binding.viewPager.adapter?.itemCount?.let { count -> - if (this.pos < count) { - binding.viewPager.setCurrentItem( - this.pos, - false - ) - } - } - } - - is GallerySideEffect.DisplayStorageException -> - displayStorageException( - label = label, - msg = messenger - ) - - is GallerySideEffect.EditResource -> editResource(path) - GallerySideEffect.NavigateBack -> onBackClick() - GallerySideEffect.NotifyCurrentItemChange -> - notifyCurrentItemChanged() - - GallerySideEffect.NotifyResourceChange -> notifyResourcesChanged() - GallerySideEffect.NotifyResourceScoresChanged -> - notifyResourceScoresChanged() - - GallerySideEffect.NotifyTagsChanged -> notifyTagsChanged() - is GallerySideEffect.OpenLink -> openLink(url) - - is GallerySideEffect.ShareLink -> shareLink(url) - is GallerySideEffect.ShareResource -> shareResource(path) - is GallerySideEffect.ShowEditTagsDialog -> showEditTagsDialog( - resource = resource, - resources = resources, - statsStorage = statsStorage, - rootAndFav = rootAndFav, - index = index, - storage = storage - ) - - is GallerySideEffect.ShowInfoAlert -> showInfoAlert( - path = path, - resource = resource, - metadata = metadata - ) - - is GallerySideEffect.ToastIndexFailedPath -> toastIndexFailedPath( - path - ) - - is GallerySideEffect.ViewInExternalApp -> viewInExternalApp(path) - is GallerySideEffect.AbortSelectAnimation -> - binding.cbSelected.jumpDrawablesToCurrentState() - } - } - } - - private fun render(state: GalleryState) { - pagerAdapter.dispatchUpdates(state.galleryItems) - binding.previewControls.isVisible = state.controlsVisible - toggleSelecting(state.selectingEnabled) - displaySelected( - state.currentItemSelected, - state.selectedResources.size, - state.galleryItems.size - ) - handleProgressState(state.progressState) - if (state.tags != cacheState?.tags) { - displayPreviewTags(state.currentItem.id(), state.tags) - } - if (state.currentPos != cacheState?.currentPos || - state.currentItem.metadata != cacheState?.currentItem?.metadata - ) { - setupPreview(state.currentPos, state.currentItem.metadata) - } - cacheState = state - } - - private fun onBackClick() { - Timber.d(LogTags.GALLERY_SCREEN, "quitting from GalleryPresenter") - notifySelectedChanged(viewModel.container.stateFlow.value.selectedResources) - exitFullscreen() - viewModel.router.exit() - } - - private fun setupPreview( - pos: Int, - meta: Metadata - ) { - with(binding) { - setupOpenEditFABs(meta) - ExtraLoader.load( - meta, - listOf(primaryExtra, secondaryExtra), - verbose = true - ) - requireArguments().putInt(START_AT_KEY, pos) - } - } - - private fun editResource(resourcePath: Path) { - val intent = getExternalAppIntent( - resourcePath, - Intent.ACTION_EDIT, - false /* don't detach to get the result */ - ) - intent.apply { - putExtra("SAVE_FOLDER_PATH", resourcePath.parent.toString()) - putExtra("real_file_path_2", resourcePath.toString()) - } - try { - requireContext().startActivity(intent) - } catch (e: ActivityNotFoundException) { - Toast.makeText( - requireContext(), - getString(R.string.no_app_found_to_open_this_file), - Toast.LENGTH_SHORT - ).show() - } - } - - private fun shareResource(resourcePath: Path) = - openIntentChooser( - resourcePath, - Intent.ACTION_SEND, - detachProcess = false - ) - - private fun openLink(link: String) { - val intent = Intent(Intent.ACTION_VIEW) - val uri = Uri.parse(link) - intent.data = uri - startActivity(Intent.createChooser(intent, "View the link with:")) - } - - private fun shareLink(link: String) { - val intent = Intent(Intent.ACTION_SEND) - intent.putExtra(Intent.EXTRA_TEXT, link) - intent.type = "text/plain" - startActivity(Intent.createChooser(intent, "Share the link with:")) - } - - private fun showInfoAlert(path: Path, resource: Resource, metadata: Metadata) { - DetailsAlertDialog(path, resource, metadata, requireContext()).show() - } - - private fun viewInExternalApp(resourcePath: Path) { - openIntentChooser(resourcePath, Intent.ACTION_VIEW, true) - } - - private fun displayStorageException(label: String, msg: String) { - StorageExceptionDialogFragment.newInstance(label, msg).show( - childFragmentManager, - StorageExceptionDialogFragment.TAG - ) - } - - private fun notifyResourcesChanged() { - setFragmentResult(REQUEST_RESOURCES_CHANGED_KEY, bundleOf()) - } - - private fun notifyTagsChanged() { - setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) - } - - private fun notifyResourceScoresChanged() { - setFragmentResult(SCORES_CHANGED_KEY, bundleOf()) - } - - private fun notifySelectedChanged( - selected: List - ) { - setFragmentResult( - SELECTED_CHANGED_KEY, - bundleOf().apply { - putBoolean( - SELECTING_ENABLED_KEY, - requireArguments().getBoolean(SELECTING_ENABLED_KEY) - ) - putParcelableArray( - SELECTED_RESOURCES_KEY, - selected.toTypedArray() - ) - } - ) - } - - private fun toastIndexFailedPath(path: Path) { - stackedToasts.toast(path) - } - - private fun displayPreviewTags(resource: ResourceId, tags: Tags) { - Timber.d( - LogTags.GALLERY_SCREEN, - "displaying tags of resource $resource for preview" - ) - binding.tagsCg.removeAllViews() - - tags.forEach { tag -> - val chip = Chip(context) - chip.text = tag - - chip.setOnClickListener { - showTagMenuPopup(tag, chip) - } - binding.tagsCg.addView(chip) - } - - binding.tagsCg.addView(createEditChip()) - } - - private fun showEditTagsDialog( - resource: ResourceId, - rootAndFav: RootAndFav, - resources: List, - index: ResourceIndex, - storage: TagStorage, - statsStorage: StatsStorage - ) { - Timber.d( - LogTags.GALLERY_SCREEN, - "showing [edit-tags] dialog for resource $resource" - ) - val dialog = EditTagsDialogFragment.newInstance( - rootAndFav = rootAndFav, - resources = resources, - index = index, - storage = storage, - statsStorage = statsStorage - ) - dialog.show(childFragmentManager, EditTagsDialogFragment.FRAGMENT_TAG) - } - - private fun handleProgressState(state: ProgressState) { - when (state) { - ProgressState.HideProgress -> setProgressVisibility( - false, - "" - ) - - ProgressState.Indexing -> setProgressVisibility( - true, - getString(R.string.progress_text_changes_detected_indexing) - ) - - ProgressState.ProvidingDataStorage -> setProgressVisibility( - true, - getString(R.string.progress_text_providing_data_storage) - ) - - ProgressState.ProvidingMetaDataStorage -> setProgressVisibility( - true, - getString(R.string.progress_text_providing_metadata_storage) - ) - - ProgressState.ProvidingPreviewStorage -> setProgressVisibility( - true, - getString(R.string.progress_text_providing_previews_storage) - ) - - ProgressState.ProvidingRootIndex -> setProgressVisibility( - true, - getString(R.string.progress_text_providing_root_index) - ) - } - } - - @SuppressLint("ClickableViewAccessibility") - private fun setProgressVisibility(isVisible: Boolean, withText: String) { - binding.layoutProgress.apply { - root.isVisible = isVisible - - if (isVisible) { - root.setOnTouchListener { _, _ -> - return@setOnTouchListener true - } - } else { - root.setOnTouchListener(null) - } - - if (withText.isNotEmpty()) { - progressText.setVisibilityAndLoadingStatus(View.VISIBLE) - progressText.loadingText = withText - } else { - progressText.setVisibilityAndLoadingStatus(View.GONE) - } - } - } - - private fun exitFullscreen() { - FullscreenHelper.setStatusBarVisibility(true, requireActivity().window) - (requireActivity() as MainActivity).setBottomNavigationVisibility(true) - } - - private fun notifyCurrentItemChanged() { - binding.viewPager.post { - pagerAdapter.notifyItemChanged(binding.viewPager.currentItem) - } - } - - private fun displaySelected( - selected: Boolean, - selectedCount: Int, - itemCount: Int - ) = with(binding) { - Timber.d("display ${System.currentTimeMillis()}") - cbSelected.isChecked = selected - tvSelectedOf.text = "$selectedCount/$itemCount" - - return@with - } - - private fun toggleSelecting(enabled: Boolean) { - binding.layoutSelected.isVisible = enabled - binding.fabStartSelect.isVisible = !enabled - requireArguments().apply { - putBoolean(GalleryFragment.SELECTING_ENABLED_KEY, enabled) - } - } - - private fun setupOpenEditFABs(meta: Metadata?) = binding.apply { - openResourceFab.makeGone() - editResourceFab.makeGone() - when (meta) { - is Metadata.Video, is Metadata.Link, null -> { - // "open" capabilities only - openResourceFab.makeVisible() - } - - is Metadata.Document, is Metadata.PlainText -> { - // both "open" and "edit" capabilities - editResourceFab.makeVisible() - openResourceFab.makeVisible() - } - - is Metadata.Image -> { - // "edit" capabilities only - editResourceFab.makeVisible() - } - - else -> {} - } - } - - /** - * setFragmentResult notifies ResourcesFragment - * It is duplicated since the result can only be consumed once - */ - private fun initResultListener() { - childFragmentManager.setFragmentResultListener( - EditTagsDialogFragment.REQUEST_TAGS_CHANGED_KEY, - this - ) { _, _ -> - setFragmentResult(REQUEST_TAGS_CHANGED_KEY, bundleOf()) - viewModel.onTagsChanged() - } - - childFragmentManager.setFragmentResultListener( - StorageExceptionDialogFragment.STORAGE_CORRUPTION_DETECTED, - this - ) { _, _ -> - viewModel.router.newRootScreen(Screens.FoldersScreen()) - } - } - - private fun animatePagerAppearance() { - binding.viewPager.animate().apply { - duration = 500L - alpha(1f) - } - } - - private fun initViewPager() = with(binding.viewPager) { - adapter = pagerAdapter - offscreenPageLimit = 2 - val rv = (getChildAt(0) as RecyclerView) - (rv.itemAnimator as SimpleItemAnimator).removeDuration = 0 - setPageTransformer(DepthPageTransformer()) - - registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - viewModel.onPageChanged(position) - } - }) - } - - private fun showTagMenuPopup(tag: Tag, tagView: View) { - val menuBinding = PopupGalleryTagMenuBinding - .inflate(requireActivity().layoutInflater) - val popup = DefaultPopup( - menuBinding, - R.style.BottomFadeScaleAnimation, - R.drawable.bg_rounded_16dp - ) - menuBinding.apply { - btnNewSelection.setOnClickListener { - viewModel.onTagSelected(tag) - popup.popupWindow.dismiss() - } - btnRemoveTag.setOnClickListener { - viewModel.onTagRemove(tag) - popup.popupWindow.dismiss() - } - } - popup.showAbove(tagView) - } - - private fun openIntentChooser( - resourcePath: Path, - actionType: String, - detachProcess: Boolean - ) { - Timber.i( - LogTags.GALLERY_SCREEN, - "Opening resource in an external application " + - "path: $resourcePath" + - "action: $actionType" - ) - - val intent = getExternalAppIntent(resourcePath, actionType, detachProcess) - val title = when (actionType) { - Intent.ACTION_VIEW -> "View the resource with:" - Intent.ACTION_EDIT -> "Edit the resource with:" - Intent.ACTION_SEND -> "Share the resource with:" - else -> "Open the resource with:" - } - startActivity(Intent.createChooser(intent, title)) - } - - private fun getExternalAppIntent( - resourcePath: Path, - actionType: String, - detachProcess: Boolean - ): Intent { - val file = resourcePath.toFile() - val extension: String = extension(resourcePath) - val uri = FileProvider.getUriForFile( - requireContext(), - BuildConfig.APPLICATION_ID + ".provider", - file - ) - val intent = Intent().apply { - setDataAndType(uri, requireContext().contentResolver.getType(uri)) - action = actionType - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - when (actionType) { - Intent.ACTION_EDIT -> { - addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) - } - - Intent.ACTION_SEND -> { - putExtra(Intent.EXTRA_STREAM, uri) - } - } - if (detachProcess) { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - } - Timber.d( - LogTags.GALLERY_SCREEN, - "URI: ${intent.data}" + "MIME: ${intent.type}" - ) - return intent - } - - private fun getPXFromDP(dpValue: Float): Float { - return TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - dpValue, - resources.displayMetrics - ) - } - - private fun createEditChip(): Chip { - return Chip(context).also { - it.apply { - setChipIconResource(R.drawable.ic_baseline_edit_24) - chipBackgroundColor = - requireActivity().getColorStateList(R.color.colorPrimary) - chipStartPadding = getPXFromDP(12f) - chipEndPadding = getPXFromDP(12f) - textStartPadding = 0f - textEndPadding = 0f - - setOnClickListener { - val position = binding.viewPager.currentItem - Timber.d( - LogTags.GALLERY_SCREEN, - "[edit_tags] clicked at position $position" - ) - viewModel.onEditTagsDialogBtnClick() - } - } - } - } - - companion object { - private const val ROOT_AND_FAV_KEY = "rootAndFav" - private const val RESOURCES_KEY = "resources" - private const val START_AT_KEY = "startAt" - const val SELECTING_ENABLED_KEY = "selectingEnabled" - const val SELECTED_RESOURCES_KEY = "selectedResources" - const val REQUEST_TAGS_CHANGED_KEY = "tagsChangedGallery" - const val REQUEST_RESOURCES_CHANGED_KEY = "resourcesChangedGallery" - const val SCORES_CHANGED_KEY = "scoresChangedInGallery" - const val SELECTED_CHANGED_KEY = "selectedChanged" - - fun newInstance( - rootAndFav: RootAndFav, - resources: List, - startAt: Int, - selectingEnabled: Boolean = false, - selectedResources: List = emptyList() - ) = GalleryUpliftFragment().apply { - arguments = Bundle().apply { - putParcelable(ROOT_AND_FAV_KEY, rootAndFav) - putParcelableArray(RESOURCES_KEY, resources.toTypedArray()) - putInt(START_AT_KEY, startAt) - putBoolean(SELECTING_ENABLED_KEY, selectingEnabled) - putParcelableArray( - SELECTED_RESOURCES_KEY, - selectedResources.toTypedArray() - ) - } - } - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt deleted file mode 100644 index a4b6260e..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewImageViewHolderUplift.kt +++ /dev/null @@ -1,157 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift - -import android.annotation.SuppressLint -import androidx.core.view.GestureDetectorCompat -import androidx.core.view.isVisible -import androidx.lifecycle.viewModelScope -import androidx.recyclerview.widget.RecyclerView -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import com.ortiz.touchview.OnTouchImageViewListener -import dev.arkbuilders.arklib.ResourceId -import dev.arkbuilders.arklib.data.meta.Metadata -import dev.arkbuilders.arklib.data.preview.PreviewLocator -import dev.arkbuilders.arklib.data.preview.PreviewStatus -import dev.arkbuilders.arklib.utils.ImageUtils -import dev.arkbuilders.navigator.databinding.ItemImageBinding -import dev.arkbuilders.navigator.presentation.utils.makeVisibleAndSetOnClickListener -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import timber.log.Timber - -@SuppressLint("ClickableViewAccessibility") -class PreviewImageViewHolderUplift( - private val binding: ItemImageBinding, - private val viewModel: GalleryUpliftViewModel, - private val gestureDetector: GestureDetectorCompat -) : RecyclerView.ViewHolder(binding.root) { - - private var joinPreviewJob: Job? = null - private var subsamplingImageLoadFailed = false - - init { - binding.ivSubsampling.setOnTouchListener { view, motionEvent -> - return@setOnTouchListener gestureDetector.onTouchEvent(motionEvent) - } - binding.ivZoom.setOnTouchListener { view, motionEvent -> - return@setOnTouchListener gestureDetector.onTouchEvent(motionEvent) - } - setZoomImageEventListener() - setSubsamplingEventListener() - } - - var pos = -1 - - suspend fun setSource( - placeholder: Int, - id: ResourceId, - meta: Metadata, - locator: PreviewLocator - ) = with(binding) { - joinPreviewJob?.cancel() - - if (meta is Metadata.Video) { - icPlay.makeVisibleAndSetOnClickListener { - viewModel.onPlayButtonClick() - } - } else { - icPlay.isVisible = false - } - - if (!locator.isGenerated()) { - progress.isVisible = true - Timber.d("join preview generation for $id") - joinPreviewJob = viewModel.viewModelScope.launch { - locator.join() - - if (!isActive) return@launch - - withContext(Dispatchers.Main) { - progress.isVisible = false - onPreviewReady(placeholder, id, meta, locator) - } - } - return@with - } - - onPreviewReady(placeholder, id, meta, locator) - } - - private fun onPreviewReady( - placeholder: Int, - id: ResourceId, - meta: Metadata, - locator: PreviewLocator - ) = with(binding) { - val status = locator.check() - if (status != PreviewStatus.FULLSCREEN) { - ivZoom.isZoomEnabled = false - ivZoom.setImageResource(placeholder) - return@with - } - - val path = locator.fullscreen() - - // Loading in parallel limited version of image with cache in ivZoom - // and full version in ivSubsampling - // User can wait up to several seconds for full version of heavy image - ImageUtils.loadImage(id, path, ivZoom, limitSize = true) - ImageUtils.loadSubsamplingImage(path, ivSubsampling) - } - - fun reset() = with(binding) { - progress.isVisible = false - ivZoom.isVisible = true - ivZoom.isZoomEnabled = true - subsamplingImageLoadFailed = false - } - - fun onRecycled() = with(binding) { - ivSubsampling.recycle() - } - - // If full version has not yet been loaded, then listen to the zoom, block it - // and show progress until it is fully loaded - private fun setZoomImageEventListener() = with(binding) { - ivZoom.setOnTouchImageViewListener(object : OnTouchImageViewListener { - override fun onMove() { - if (!subsamplingImageLoadFailed && ivZoom.isZoomed) { - progress.isVisible = true - ivZoom.isZoomEnabled = false - ivZoom.resetZoom() - } - } - }) - } - - private fun setSubsamplingEventListener() = with(binding) { - ivSubsampling.setOnImageEventListener( - object : SubsamplingScaleImageView.OnImageEventListener { - override fun onReady() { - ivZoom.isVisible = false - progress.isVisible = false - ivZoom.setImageDrawable(null) - } - - // Fallback to ivZoom - // Now this should only happen for .gif and .svg files - // Subsampling image can't handle them - override fun onImageLoadError(e: Exception?) { - subsamplingImageLoadFailed = true - progress.isVisible = false - ivZoom.isZoomEnabled = true - } - - override fun onPreviewLoadError(e: Exception?) {} - - override fun onImageLoaded() {} - - override fun onTileLoadError(e: Exception?) {} - - override fun onPreviewReleased() {} - } - ) - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt deleted file mode 100644 index d9da3883..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewPlainTextViewHolderUplift.kt +++ /dev/null @@ -1,24 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift - -import android.annotation.SuppressLint -import androidx.core.view.GestureDetectorCompat -import androidx.recyclerview.widget.RecyclerView -import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding - -@SuppressLint("ClickableViewAccessibility") -class PreviewPlainTextViewHolderUplift( - private val binding: ItemPreviewPlainTextBinding, - private val detector: GestureDetectorCompat -) : RecyclerView.ViewHolder(binding.root) { - var pos = -1 - - init { - binding.tvContent.setOnTouchListener { view, event -> - return@setOnTouchListener detector.onTouchEvent(event) - } - } - - fun setContent(text: String) = with(binding) { - tvContent.text = text - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewImageViewHolder.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewImageViewHolder.kt similarity index 94% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewImageViewHolder.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewImageViewHolder.kt index 244b2221..5f973863 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewImageViewHolder.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewImageViewHolder.kt @@ -1,8 +1,9 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.previewpager +package dev.arkbuilders.navigator.presentation.screen.gallery.pager import android.annotation.SuppressLint import androidx.core.view.GestureDetectorCompat import androidx.core.view.isVisible +import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.ortiz.touchview.OnTouchImageViewListener @@ -12,20 +13,19 @@ import dev.arkbuilders.arklib.data.preview.PreviewLocator import dev.arkbuilders.arklib.data.preview.PreviewStatus import dev.arkbuilders.arklib.utils.ImageUtils import dev.arkbuilders.navigator.databinding.ItemImageBinding -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryViewModel import dev.arkbuilders.navigator.presentation.utils.makeVisibleAndSetOnClickListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moxy.presenterScope import timber.log.Timber @SuppressLint("ClickableViewAccessibility") class PreviewImageViewHolder( private val binding: ItemImageBinding, - private val presenter: GalleryPresenter, + private val viewModel: GalleryViewModel, private val gestureDetector: GestureDetectorCompat ) : RecyclerView.ViewHolder(binding.root) { @@ -55,7 +55,7 @@ class PreviewImageViewHolder( if (meta is Metadata.Video) { icPlay.makeVisibleAndSetOnClickListener { - presenter.onPlayButtonClick() + viewModel.onPlayButtonClick() } } else { icPlay.isVisible = false @@ -64,7 +64,7 @@ class PreviewImageViewHolder( if (!locator.isGenerated()) { progress.isVisible = true Timber.d("join preview generation for $id") - joinPreviewJob = presenter.presenterScope.launch { + joinPreviewJob = viewModel.viewModelScope.launch { locator.join() if (!isActive) return@launch diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewPlainTextViewHolder.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewPlainTextViewHolder.kt similarity index 82% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewPlainTextViewHolder.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewPlainTextViewHolder.kt index 4f9ccdef..f32d0c5d 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewPlainTextViewHolder.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewPlainTextViewHolder.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.previewpager +package dev.arkbuilders.navigator.presentation.screen.gallery.pager import android.annotation.SuppressLint import androidx.core.view.GestureDetectorCompat @@ -21,8 +21,4 @@ class PreviewPlainTextViewHolder( fun setContent(text: String) = with(binding) { tvContent.text = text } - - fun reset() = with(binding) { - tvContent.text = "" - } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewsPager.kt similarity index 89% rename from app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt rename to app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewsPager.kt index 28bbf238..defcae2f 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/galleryuplift/PreviewsPagerUplift.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/pager/PreviewsPager.kt @@ -1,4 +1,4 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift +package dev.arkbuilders.navigator.presentation.screen.gallery.pager import android.annotation.SuppressLint import android.content.Context @@ -14,7 +14,8 @@ import dev.arkbuilders.arklib.utils.ImageUtils import dev.arkbuilders.arklib.utils.extension import dev.arkbuilders.navigator.databinding.ItemImageBinding import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding -import dev.arkbuilders.navigator.presentation.screen.gallery.galleryuplift.domain.GalleryItem +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryViewModel +import dev.arkbuilders.navigator.presentation.screen.gallery.domain.GalleryItem import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourceDiffUtilCallback import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -23,10 +24,10 @@ import kotlinx.coroutines.withContext import java.io.FileReader import java.nio.file.Path -class PreviewsPagerUplift( +class PreviewsPager( val lifecycleScope: CoroutineScope, val context: Context, - val viewModel: GalleryUpliftViewModel + val viewModel: GalleryViewModel ) : RecyclerView.Adapter() { private var galleryItems = emptyList() @@ -50,7 +51,7 @@ class PreviewsPagerUplift( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = if (viewType == Kind.PLAINTEXT.ordinal) { - PreviewPlainTextViewHolderUplift( + PreviewPlainTextViewHolder( ItemPreviewPlainTextBinding.inflate( LayoutInflater.from(parent.context), parent, @@ -59,7 +60,7 @@ class PreviewsPagerUplift( getGestureDetector() ) } else { - PreviewImageViewHolderUplift( + PreviewImageViewHolder( ItemImageBinding.inflate( LayoutInflater.from(parent.context), parent, @@ -80,7 +81,7 @@ class PreviewsPagerUplift( ) { lifecycleScope.launch { when (holder) { - is PreviewPlainTextViewHolderUplift -> { + is PreviewPlainTextViewHolder -> { holder.pos = position val item = galleryItems[position] val text = readText(item.path) @@ -89,7 +90,7 @@ class PreviewsPagerUplift( } } - is PreviewImageViewHolderUplift -> { + is PreviewImageViewHolder -> { holder.reset() holder.pos = position val item = galleryItems[position] @@ -108,7 +109,7 @@ class PreviewsPagerUplift( override fun onViewRecycled(holder: RecyclerView.ViewHolder) { super.onViewRecycled(holder) - if (holder is PreviewImageViewHolderUplift) { + if (holder is PreviewImageViewHolder) { holder.onRecycled() } } diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewsPager.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewsPager.kt deleted file mode 100644 index e20b451e..00000000 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/gallery/previewpager/PreviewsPager.kt +++ /dev/null @@ -1,81 +0,0 @@ -package dev.arkbuilders.navigator.presentation.screen.gallery.previewpager - -import android.annotation.SuppressLint -import android.content.Context -import android.view.GestureDetector -import android.view.LayoutInflater -import android.view.MotionEvent -import android.view.ViewGroup -import androidx.core.view.GestureDetectorCompat -import androidx.recyclerview.widget.RecyclerView -import dev.arkbuilders.navigator.databinding.ItemImageBinding -import dev.arkbuilders.navigator.databinding.ItemPreviewPlainTextBinding -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryPresenter -import dev.arkbuilders.arklib.data.meta.Kind - -class PreviewsPager( - val context: Context, - val presenter: GalleryPresenter -) : RecyclerView.Adapter() { - - override fun getItemCount() = presenter.galleryItems.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = - if (viewType == Kind.PLAINTEXT.ordinal) { - PreviewPlainTextViewHolder( - ItemPreviewPlainTextBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ), - getGestureDetector() - ) - } else { - PreviewImageViewHolder( - ItemImageBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ), - presenter, - getGestureDetector() - ) - } - - override fun getItemViewType(position: Int) = - presenter.getKind(position) - - @SuppressLint("ClickableViewAccessibility") - override fun onBindViewHolder( - holder: RecyclerView.ViewHolder, - position: Int - ) { - when (holder) { - is PreviewPlainTextViewHolder -> { - holder.pos = position - presenter.bindPlainTextView(holder) - } - is PreviewImageViewHolder -> { - holder.pos = position - presenter.bindView(holder) - } - } - } - - override fun onViewRecycled(holder: RecyclerView.ViewHolder) { - super.onViewRecycled(holder) - if (holder is PreviewImageViewHolder) { - holder.onRecycled() - } - } - - private fun getGestureDetector(): GestureDetectorCompat { - val listener = object : GestureDetector.SimpleOnGestureListener() { - override fun onSingleTapConfirmed(e: MotionEvent): Boolean { - presenter.onPreviewsItemClick() - return true - } - } - return GestureDetectorCompat(context, listener) - } -} diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/ResourcesFragment.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/ResourcesFragment.kt index 7f70b0ff..68c41a24 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/ResourcesFragment.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/ResourcesFragment.kt @@ -28,7 +28,6 @@ import dev.arkbuilders.navigator.presentation.dialog.ConfirmationDialogFragment import dev.arkbuilders.navigator.presentation.dialog.StorageExceptionDialogFragment import dev.arkbuilders.navigator.presentation.dialog.sort.SortDialogFragment import dev.arkbuilders.navigator.presentation.dialog.tagssort.TagsSortDialogFragment -import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import dev.arkbuilders.navigator.presentation.screen.main.MainActivity import dev.arkbuilders.navigator.presentation.screen.resources.adapter.ResourcesRVAdapter import dev.arkbuilders.navigator.presentation.utils.FullscreenHelper @@ -44,6 +43,7 @@ import dev.arkbuilders.arkfilepicker.folders.RootAndFav import dev.arkbuilders.arkfilepicker.presentation.onArkPathPicked import dev.arkbuilders.arklib.ResourceId import dev.arkbuilders.arklib.user.tags.Tag +import dev.arkbuilders.navigator.presentation.screen.gallery.GalleryFragment import timber.log.Timber import java.nio.file.Path import javax.inject.Inject diff --git a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt index c2a5f3e7..be4cdbfd 100644 --- a/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt +++ b/app/src/main/java/dev/arkbuilders/navigator/presentation/screen/resources/adapter/ResourcesGridPresenter.kt @@ -146,16 +146,8 @@ class ResourcesGridPresenter( } } -// router.navigateToFragmentUsingAdd( -// Screens.GalleryScreen( -// rootAndFav, -// selection.map { it.id() }, -// pos -// ) -// ) - router.navigateToFragmentUsingAdd( - Screens.GalleryUpliftScreen( + Screens.GalleryScreen( rootAndFav, selection.map { it.id() }, pos @@ -315,7 +307,7 @@ class ResourcesGridPresenter( fun onSelectedItemLongClick(item: FileItemViewHolder) { router.navigateToFragmentUsingAdd( - Screens.GalleryScreenWithSelectedUplift( + Screens.GalleryScreenWithSelected( rootAndFav, selection.map { it.id() }, item.position(),