Skip to content

Commit

Permalink
#332,#334: UI improve (#342)
Browse files Browse the repository at this point in the history
* Aggregated mode must be disabled when there are no roots #332
* Resource Grid UI enhancements  #334
Co-authored-by: jack <[email protected]>
Co-authored-by: huangxin <[email protected]>
  • Loading branch information
saxihuangxing authored Apr 10, 2023
1 parent 7f4cc9c commit 6721b8d
Show file tree
Hide file tree
Showing 18 changed files with 270 additions and 158 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package space.taran.arknavigator.mvp.presenter

import android.util.Log
import kotlinx.coroutines.launch
import moxy.MvpPresenter
import moxy.presenterScope
import space.taran.arkfilepicker.folders.FoldersRepo
import space.taran.arkfilepicker.folders.RootAndFav
import space.taran.arknavigator.mvp.view.MainView
import space.taran.arknavigator.navigation.AppRouter
Expand All @@ -13,6 +16,9 @@ class MainPresenter : MvpPresenter<MainView>() {
@Inject
lateinit var router: AppRouter

@Inject
lateinit var folders: FoldersRepo

override fun onFirstViewAttach() {
Log.d(MAIN, "first view attached in MainPresenter")
super.onFirstViewAttach()
Expand All @@ -34,7 +40,16 @@ class MainPresenter : MvpPresenter<MainView>() {

fun goToResourcesScreen() {
Log.d(MAIN, "creating Resources screen")
router.newRootScreen(Screens.ResourcesScreen(RootAndFav(null, null)))
presenterScope.launch {
val folders = folders.provideFolders()
if (folders.size < 1) {
viewState.enterResourceFragmentFailed()
} else {
Log.d(MAIN, "switching to Resources screen")
router.newRootScreen(Screens.ResourcesScreen(RootAndFav(null, null)))
}
true
}
}

fun goToSettingsScreen() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ class ResourcesPresenter(
Log.d(RESOURCES_SCREEN, "first view attached in ResourcesPresenter")
super.onFirstViewAttach()

viewState.init()
presenterScope.launch {
val ascending = preferences.get(PreferenceKey.IsSortingAscending)
val sortByScores = preferences.get(PreferenceKey.SortByScores)
viewState.init(ascending, sortByScores)
viewState.setProgressVisibility(true, "Indexing")
val folders = foldersRepo.provideWithMissing()
Log.d(RESOURCES_SCREEN, "folders retrieved: $folders")
Expand Down Expand Up @@ -216,6 +218,18 @@ class ResourcesPresenter(
migrateTags(resourcesToCopy, directoryToCopy)
}

fun onAscendingChanged(isAscending: Boolean) = presenterScope.launch {
viewState.updateOrderBtn(isAscending)
preferences.set(
PreferenceKey.IsSortingAscending,
isAscending
)
}

fun onScoresSwitched(enabled: Boolean) = presenterScope.launch {
preferences.set(PreferenceKey.SortByScores, enabled)
}

fun onShuffleSwitchedOn() = presenterScope.launch(Dispatchers.Default) {
gridPresenter.shuffleResources()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,4 @@ class SortDialogPresenter : MvpPresenter<SortDialogView>() {
preferences.set(PreferenceKey.Sorting, sorting.ordinal)
viewState.closeDialog()
}

fun onAscendingSelected(ascending: Boolean) = presenterScope.launch {
preferences.set(PreferenceKey.IsSortingAscending, ascending)
viewState.closeDialog()
}

fun onScoresSwitched(enabled: Boolean) = presenterScope.launch {
preferences.set(PreferenceKey.SortByScores, enabled)
viewState.closeDialog()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ interface MainView : MvpView {

@StateStrategyType(SkipStrategy::class)
fun requestPerms()

fun enterResourceFragmentFailed()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import java.nio.file.Path

@StateStrategyType(AddToEndSingleStrategy::class)
interface ResourcesView : CommonMvpView {
fun init()
fun init(ascending: Boolean, sortByScoresEnabled: Boolean)
fun updateAdapter()
fun setProgressVisibility(isVisible: Boolean, withText: String = "")
fun setToolbarTitle(title: String)
fun setKindTagsEnabled(enabled: Boolean)
fun updateMenu()
fun updateOrderBtn(isAscending: Boolean)
fun setSelectingEnabled(enabled: Boolean)
fun setSelectingCount(selected: Int, all: Int)
fun setTagsFilterEnabled(enabled: Boolean)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import space.taran.arknavigator.mvp.presenter.MainPresenter
import space.taran.arknavigator.mvp.view.MainView
import space.taran.arknavigator.navigation.AppNavigator
import space.taran.arknavigator.ui.App
import space.taran.arknavigator.ui.fragments.utils.toast
import space.taran.arknavigator.utils.LogTags.MAIN
import space.taran.arknavigator.utils.LogTags.PERMISSIONS
import javax.inject.Inject
Expand Down Expand Up @@ -161,6 +162,11 @@ class MainActivity : MvpAppCompatActivity(), MainView {
super.onRequestPermissionsResult(requestCode, permissions, granted)
}

override fun enterResourceFragmentFailed() {
toast(R.string.toast_add_paths)
binding.bottomNavigation.selectedItemId = R.id.page_roots
}

fun setBottomNavigationVisibility(isVisible: Boolean) {
binding.bottomNavigation.isVisible = isVisible
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class FoldersFragment : MvpAppCompatFragment(), FoldersView {
devices: List<Path>,
rootsWithFavs: Map<Path, List<Path>>
) {
if (rootsWithFavs.size < 1) {
binding.noFolderHint.setVisibility(View.VISIBLE)
} else binding.noFolderHint.setVisibility(View.INVISIBLE)
foldersTree?.set(devices, rootsWithFavs)
}

Expand Down Expand Up @@ -208,6 +211,7 @@ class FoldersFragment : MvpAppCompatFragment(), FoldersView {
fun newInstance() = FoldersFragment().apply {
arguments = bundleOf()
}

fun newInstance(rescan: Boolean) = FoldersFragment().apply {
arguments = bundleOf().apply {
putBoolean(RESCAN_ROOTS_BUNDLE_KEY, rescan)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ResourcesFragment : MvpAppCompatFragment(), ResourcesView {
private var tagsSelectorAdapter: TagsSelectorAdapter? = null

private var isShuffled = false

private var isAscending = true
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -109,53 +109,66 @@ class ResourcesFragment : MvpAppCompatFragment(), ResourcesView {
App.instance.appComponent.inject(this)
}

override fun init() = with(binding) {
Log.d(RESOURCES_SCREEN, "initializing ResourcesFragment")

initResultListeners()
initMenuListeners()
stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope)

FullscreenHelper.setStatusBarVisibility(true, requireActivity().window)
(activity as MainActivity).setSelectedTab(R.id.page_tags)
(requireActivity() as MainActivity).setBottomNavigationVisibility(true)

resourcesAdapter = ResourcesRVAdapter(presenter.gridPresenter)
rvResources.adapter = resourcesAdapter
rvResources.setItemViewCacheSize(0)
rvResources.layoutManager = GridLayoutManager(context, 3)
tagsSelectorAdapter = TagsSelectorAdapter(
this@ResourcesFragment,
binding,
presenter.tagsSelectorPresenter
).also {
App.instance.appComponent.inject(it)
}

layoutDragHandler.setOnTouchListener(::dragHandlerTouchListener)
etTagsFilter.doAfterTextChanged {
presenter.tagsSelectorPresenter.onFilterChanged(it.toString())
}
switchKind.setOnCheckedChangeListener { _, checked ->
presenter.tagsSelectorPresenter.onKindTagsToggle(checked)
}
btnClear.setOnClickListener {
presenter.tagsSelectorPresenter.onClearClick()
}
btnTagsSorting.setOnClickListener {
TagsSortDialogFragment
.newInstance(selectorNotEdit = true)
.show(childFragmentManager, null)
}
override fun init(ascending: Boolean, sortByScoresEnabled: Boolean) =
with(binding) {
Log.d(RESOURCES_SCREEN, "initializing ResourcesFragment")

initResultListeners()
initMenuListeners()
stackedToasts = StackedToasts(binding.rvToasts, lifecycleScope)

FullscreenHelper.setStatusBarVisibility(true, requireActivity().window)
(activity as MainActivity).setSelectedTab(R.id.page_tags)
(requireActivity() as MainActivity).setBottomNavigationVisibility(true)

resourcesAdapter = ResourcesRVAdapter(presenter.gridPresenter)
rvResources.adapter = resourcesAdapter
rvResources.setItemViewCacheSize(0)
rvResources.layoutManager = GridLayoutManager(context, 3)
tagsSelectorAdapter = TagsSelectorAdapter(
this@ResourcesFragment,
binding,
presenter.tagsSelectorPresenter
).also {
App.instance.appComponent.inject(it)
}

this@ResourcesFragment
.requireActivity()
.onBackPressedDispatcher
.addCallback(this@ResourcesFragment) {
presenter.onBackClick()
layoutDragHandler.setOnTouchListener(::dragHandlerTouchListener)
etTagsFilter.doAfterTextChanged {
presenter.tagsSelectorPresenter.onFilterChanged(it.toString())
}
switchKind.setOnCheckedChangeListener { _, checked ->
presenter.tagsSelectorPresenter.onKindTagsToggle(checked)
}
btnClear.setOnClickListener {
presenter.tagsSelectorPresenter.onClearClick()
}
btnTagsSorting.setOnClickListener {
TagsSortDialogFragment
.newInstance(selectorNotEdit = true)
.show(childFragmentManager, null)
}
this@ResourcesFragment.updateOrderBtn(ascending)
if (sortByScoresEnabled) {
swScores.isChecked = true
swScores.jumpDrawablesToCurrentState()
}
swScores.setOnCheckedChangeListener { _, isChecked ->
Log.d(
RESOURCES_SCREEN,
"sorting by scores ${if (isChecked) "enabled" else "disabled"}"
)
presenter.onScoresSwitched(isChecked)
}
return@with
}

this@ResourcesFragment
.requireActivity()
.onBackPressedDispatcher
.addCallback(this@ResourcesFragment) {
presenter.onBackClick()
}
return@with
}

override fun onResume() {
Log.d(RESOURCES_SCREEN, "resuming in ResourcesFragment")
Expand Down Expand Up @@ -200,6 +213,15 @@ class ResourcesFragment : MvpAppCompatFragment(), ResourcesView {
return@with
}

override fun updateOrderBtn(isAscending: Boolean) = with(binding) {
this@ResourcesFragment.isAscending = isAscending
val drawable =
if (isAscending) resources.getDrawable(R.drawable.order_ascending)
else resources.getDrawable(R.drawable.order_descending)
actionBar.btnOrder.setImageDrawable(drawable)
return@with
}

override fun setSelectingEnabled(enabled: Boolean) = with(binding.actionBar) {
tvTitle.isVisible = !enabled
tvSelectedOf.isVisible = enabled
Expand Down Expand Up @@ -308,10 +330,15 @@ class ResourcesFragment : MvpAppCompatFragment(), ResourcesView {
actionBar.btnFocusMode.setOnClickListener {
presenter.tagsSelectorPresenter.onQueryModeChanged(QueryMode.FOCUS)
}

actionBar.btnOrder.apply {
setOnClickListener {
presenter.onAscendingChanged(!isAscending)
}
}
actionBar.btnShuffle.apply {
setOnClickListener {
val dice = this.drawable

@ColorInt
val diceColor = resources
.getColor(R.color.blue, requireContext().theme)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package space.taran.arknavigator.ui.fragments.dialog

import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.fragment.app.setFragmentResult
import moxy.MvpBottomSheetDialogFragment
import moxy.ktx.moxyPresenter
Expand All @@ -13,12 +18,16 @@ import space.taran.arknavigator.mvp.presenter.dialog.RootsScanDialogPresenter
import space.taran.arknavigator.mvp.view.dialog.RootsScanView
import space.taran.arknavigator.ui.fragments.utils.toast
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.exists

class RootsScanDialogFragment : MvpBottomSheetDialogFragment(), RootsScanView {
private lateinit var binding: DialogRootsScanBinding
private val presenter by moxyPresenter {
RootsScanDialogPresenter()
}
private val defaultRootsFolders =
listOf("DCIM/Camera", "Documents", "Pictures", "Downloads")

override fun onCreateView(
inflater: LayoutInflater,
Expand Down Expand Up @@ -47,6 +56,33 @@ class RootsScanDialogFragment : MvpBottomSheetDialogFragment(), RootsScanView {
btnScan.setOnClickListener {
presenter.onScanBtnClick()
}
initDefaultRootsInfo(defaultRootsFolders)
}

private fun initDefaultRootsInfo(rootsList: List<String>) {
rootsList.forEach { root ->
val view = CheckBox(context)
val params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
view.layoutParams = params
view.text = root
view.isChecked = true
val selectColor =
ContextCompat.getColor(requireContext(), R.color.colorPrimary)
val normalColor = ContextCompat.getColor(requireContext(), R.color.gray)
view.setTextColor(selectColor)
view.buttonTintList = ColorStateList.valueOf(Color.BLUE)
view.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
view.setTextColor(selectColor)
} else {
view.setTextColor(normalColor)
}
}
binding.layoutDefaultRoot.addView(view)
}
}

override fun startScan() = with(binding) {
Expand Down Expand Up @@ -76,10 +112,33 @@ class RootsScanDialogFragment : MvpBottomSheetDialogFragment(), RootsScanView {
override fun closeDialog() = dismiss()

override fun notifyRootsFound(roots: List<Path>) {
val finalRoots: MutableList<Path> = mutableListOf()
val checkedFolders: MutableList<String> = mutableListOf()
val count = binding.layoutDefaultRoot.childCount
for (i in 0 until count) {
val child = binding.layoutDefaultRoot.getChildAt(i) as CheckBox
if (child.isChecked) {
checkedFolders.add(defaultRootsFolders[i])
}
}
roots.forEach { root ->
var foundDefaultFolder = false
checkedFolders.forEach {
val defaultRoot = Paths.get(root.toString() + '/' + it)
if (defaultRoot.exists()) {
finalRoots.add(defaultRoot)
foundDefaultFolder = true
}
}
if (!foundDefaultFolder) {
finalRoots.add(root)
}
}

val bundle = Bundle().apply {
putStringArray(
RESULT_KEY_ROOTS,
roots.map(Path::toString).toTypedArray()
finalRoots.map(Path::toString).toTypedArray()
)
}
setFragmentResult(REQUEST_KEY_ROOTS_FOUND, bundle)
Expand Down
Loading

0 comments on commit 6721b8d

Please sign in to comment.