diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/MainActivity.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/MainActivity.kt index e448acdcc..57fa4a609 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/MainActivity.kt @@ -72,6 +72,9 @@ open class MainActivity : CompatActivity( }.dispatchOnSelf() true } + binding.mainNavigation.setOnNavigationItemReselectedListener { + navigation.onReselected() + } binding.mainNavigation.viewTreeObserver.addOnGlobalLayoutListener(navObserver) diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/ReselectionTarget.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/ReselectionTarget.kt new file mode 100644 index 000000000..e7d44d8ef --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/ReselectionTarget.kt @@ -0,0 +1,7 @@ +package com.topjohnwu.magisk.redesign + +interface ReselectionTarget { + + fun onReselected() + +} \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/compat/CompatNavigationDelegate.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/compat/CompatNavigationDelegate.kt index 6a7054960..5037e6ff3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/compat/CompatNavigationDelegate.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/compat/CompatNavigationDelegate.kt @@ -8,6 +8,7 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent import com.topjohnwu.magisk.model.navigation.Navigator +import com.topjohnwu.magisk.redesign.ReselectionTarget import timber.log.Timber class CompatNavigationDelegate( @@ -44,6 +45,10 @@ class CompatNavigationDelegate( fun onSaveInstanceState(outState: Bundle) = controller.onSaveInstanceState(outState) + fun onReselected() { + (controller.currentFrag as? ReselectionTarget)?.onReselected() + } + fun onBackPressed(): Boolean { val fragment = controller.currentFrag as? CompatFragment<*, *> diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt index b6e09ab5e..0bca3e37b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/hide/HideFragment.kt @@ -16,6 +16,7 @@ import androidx.core.view.isVisible import androidx.core.view.marginBottom import androidx.core.view.marginEnd import androidx.interpolator.view.animation.FastOutSlowInInterpolator +import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.circularreveal.CircularRevealCompat import com.google.android.material.circularreveal.CircularRevealWidget import com.google.android.material.floatingactionbutton.FloatingActionButton @@ -61,8 +62,10 @@ class HideFragment : CompatFragment() { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_focus_up -> binding.hideContent - .also { it.scrollToPosition(10) } - .also { it.smoothScrollToPosition(0) } + .takeIf { (it.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition() ?: 0 > 10 } + ?.also { it.scrollToPosition(10) } + .let { binding.hideContent } + .also { it.post { it.smoothScrollToPosition(0) } } } return super.onOptionsItemSelected(item) } diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleFragment.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleFragment.kt index 181ca3d54..bd7cd6945 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleFragment.kt @@ -2,17 +2,23 @@ package com.topjohnwu.magisk.redesign.module import android.graphics.Insets import android.os.Bundle +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem import android.view.View +import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.topjohnwu.magisk.R import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding import com.topjohnwu.magisk.redesign.MainActivity +import com.topjohnwu.magisk.redesign.ReselectionTarget import com.topjohnwu.magisk.redesign.compat.CompatFragment import com.topjohnwu.magisk.redesign.compat.hideKeyboard import com.topjohnwu.magisk.redesign.hide.MotionRevealHelper import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener import org.koin.androidx.viewmodel.ext.android.viewModel -class ModuleFragment : CompatFragment() { +class ModuleFragment : CompatFragment(), + ReselectionTarget { override val layoutRes = R.layout.fragment_module_md2 override val viewModel by viewModel() @@ -23,6 +29,7 @@ class ModuleFragment : CompatFragment override fun onStart() { super.onStart() + setHasOptionsMenu(true) activity.title = resources.getString(R.string.section_modules) } @@ -50,6 +57,35 @@ class ModuleFragment : CompatFragment super.onDestroyView() } + // --- + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_module_md2, menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.action_refresh -> viewModel.loadRemoteImplicit() + } + return super.onOptionsItemSelected(item) + } + + // --- + + override fun onReselected() { + binding.moduleRemote + .takeIf { + (it.layoutManager as? StaggeredGridLayoutManager)?.let { + it.findFirstVisibleItemPositions(IntArray(it.spanCount)).min() + } ?: 0 > 10 + } + ?.also { it.scrollToPosition(10) } + .let { binding.moduleRemote } + .also { it.post { it.smoothScrollToPosition(0) } } + } + + // --- + override fun onPreBind(binding: FragmentModuleMd2Binding) = Unit private fun setEndlessScroller() { diff --git a/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleViewModel.kt index 3c5595701..934ede1aa 100644 --- a/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/redesign/module/ModuleViewModel.kt @@ -111,6 +111,7 @@ class ModuleViewModel( .map { it.order() } .map { build(active = it) } .map { it to items.calculateDiff(it) } + .applyViewModel(this) .subscribeK { items.update(it.first, it.second) if (!items.contains(sectionRemote)) { @@ -119,6 +120,13 @@ class ModuleViewModel( moveToState() } + fun loadRemoteImplicit() = downloadRepos() + .observeOn(AndroidSchedulers.mainThread()) + .doOnComplete { items.clear(); itemsSearch.clear() } + .applyViewModel(this, false) + .subscribeK { refresh(); submitQuery() } + .add() + @Synchronized fun loadRemote() { // check for existing jobs diff --git a/app/src/main/res/drawable/ic_refresh_data_md2.xml b/app/src/main/res/drawable/ic_refresh_data_md2.xml new file mode 100644 index 000000000..5eb26cd74 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh_data_md2.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_module_md2.xml b/app/src/main/res/layout/fragment_module_md2.xml index ece026ef5..5387c7b84 100644 --- a/app/src/main/res/layout/fragment_module_md2.xml +++ b/app/src/main/res/layout/fragment_module_md2.xml @@ -24,6 +24,7 @@ adapter="@{viewModel.adapter}" dividerHorizontal="@{R.drawable.divider_l1}" dividerVertical="@{R.drawable.divider_l1}" + gone="@{viewModel.loading}" itemBinding="@{viewModel.itemBinding}" items="@{viewModel.items}" android:layout_width="match_parent" @@ -69,6 +70,27 @@ + + + + + + + + diff --git a/app/src/main/res/menu/menu_module_md2.xml b/app/src/main/res/menu/menu_module_md2.xml new file mode 100644 index 000000000..71169adea --- /dev/null +++ b/app/src/main/res/menu/menu_module_md2.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file