diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt index 4347afbca..087bf4223 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt @@ -43,6 +43,8 @@ class LogViewModel( private val logItem get() = items[0] as LogRvItem private val magiskLogItem get() = items[1] as MagiskLogRvItem + val scrollPosition = KObservableField(0) + init { currentPage.addOnPropertyChangedCallback { it ?: return@addOnPropertyChangedCallback @@ -59,6 +61,10 @@ class LogViewModel( else -> "" } + fun scrollDownPressed() { + scrollPosition.value = magiskLogItem.items.size - 1 + } + fun refresh() { fetchLogs().subscribeK { logItem.update(it) } fetchMagiskLog().subscribeK { magiskLogItem.update(it) } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt index d468c5217..5c102442f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/DataBindingAdapters.kt @@ -11,8 +11,10 @@ import androidx.databinding.InverseBindingAdapter import androidx.databinding.InverseBindingListener import androidx.drawerlayout.widget.DrawerLayout import androidx.interpolator.view.animation.FastOutSlowInInterpolator +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager +import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.navigation.NavigationView import com.skoumal.teanity.extensions.subscribeK import com.topjohnwu.magisk.R @@ -176,4 +178,32 @@ fun setScrollToLast(view: RecyclerView, shouldScrollToLast: Boolean) { } else { view.adapter?.removeListener() } -} \ No newline at end of file +} + +@BindingAdapter("hide") +fun setHidden(view: FloatingActionButton, hide: Boolean) { + if (hide) view.hide() else view.show() +} + +@BindingAdapter("scrollPosition", "scrollPositionSmooth", requireAll = false) +fun setScrollPosition(view: RecyclerView, position: Int, smoothScroll: Boolean) = when { + smoothScroll -> view.smoothScrollToPosition(position) + else -> view.scrollToPosition(position) +} + +@BindingAdapter("recyclerScrollEvent") +fun setScrollListener(view: RecyclerView, listener: InverseBindingListener) { + view.addOnScrollListener(object : RecyclerView.OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + // don't change this or the recycler will stop at every line, effectively disabling smooth scroll + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + listener.onChange() + } + } + }) +} + +@InverseBindingAdapter(attribute = "scrollPosition", event = "recyclerScrollEvent") +fun getScrollPosition(view: RecyclerView) = (view.layoutManager as? LinearLayoutManager) + ?.findLastCompletelyVisibleItemPosition() + ?: -1 \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_down.xml b/app/src/main/res/drawable/ic_arrow_down.xml new file mode 100644 index 000000000..569d3a745 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_down.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_page_magisk_log.xml b/app/src/main/res/layout/item_page_magisk_log.xml index 252a47983..5bc134ba7 100644 --- a/app/src/main/res/layout/item_page_magisk_log.xml +++ b/app/src/main/res/layout/item_page_magisk_log.xml @@ -15,20 +15,39 @@ - - + + + + + + + + + - \ No newline at end of file