fix auto proxy scroll

This commit is contained in:
Kr328 committed 2020-02-17 00:43:31 +08:00
1 parent a5064fdd4f
commit 4848a0f6d9
4 files changed
+47 -28

No files matched your search

@@ -10,6 +10,7 @@ import com.github.kr328.clash.adapter.ProxyAdapter
import com.github.kr328.clash.adapter.ProxyChipAdapter
import com.github.kr328.clash.core.model.General
import com.github.kr328.clash.core.model.Proxy
import com.github.kr328.clash.core.utils.Log
import com.github.kr328.clash.preference.UiPreferences
import com.github.kr328.clash.remote.withClash
import com.github.kr328.clash.utils.PrefixMerger
@@ -75,7 +76,7 @@ class ProxiesActivity : BaseActivity(), ScrollBinding.Callback {
chipList.itemAnimator?.changeDuration = 0
launch {
mainList.addOnScrollListener(object: RecyclerView.OnScrollListener(){
mainList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
scrollBinding.sendMasterScrolled()
}
@@ -318,24 +319,25 @@ class ProxiesActivity : BaseActivity(), ScrollBinding.Callback {
}
}
override suspend fun getCurrentMasterToken(): String {
override fun getCurrentMasterToken(): String {
return mainListAdapter.getCurrentGroup()
}
override suspend fun onMasterTokenChanged(token: String) {
override fun onMasterTokenChanged(token: String) {
chipListAdapter.selected = token
val position = chipListAdapter.chips.indexOf(token)
if (position < 0)
return
chipList.scrollToPosition(position)
chipList.smoothScrollToPosition(position)
}
override suspend fun getMasterTokenPosition(token: String): Int {
override fun getMasterTokenPosition(token: String): Int {
return mainListAdapter.getGroupPosition(token)
}
override suspend fun doMasterScroll(scroller: LinearSmoothScroller) {
override fun doMasterScroll(scroller: LinearSmoothScroller) {
mainListAdapter.layoutManager.startSmoothScroll(scroller)
}
}
@@ -22,7 +22,7 @@ class ProxyAdapter(
private val context: Context,
val onSelect: (String, String) -> Unit,
val onUrlTest: (String) -> Unit
): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val DEFAULT_SPAN_COUNT = 2
}
@@ -66,7 +66,8 @@ class ProxyAdapter(
private var rootMutex = Mutex()
private var urlTesting: Set<String> = emptySet()
private var renderList = mutableListOf<RenderInfo>()
private val activeList: MutableMap<String, Int> = mutableMapOf()
private var activeList: MutableMap<String, Int> = mutableMapOf()
private var groupPosition: MutableMap<String, Int> = mutableMapOf()
@ColorInt
private val colorSurface: Int
@ColorInt
@@ -132,25 +133,34 @@ class ProxyAdapter(
override fun getNewListSize(): Int = newRenderList.size
})
val groupCache: MutableMap<String, Int> = mutableMapOf()
val activeCache: MutableMap<String, Int> = mutableMapOf()
newRenderList.forEachIndexed { index, it ->
when ( it ) {
is ProxyGroupRenderInfo ->
groupCache[it.name] = index
is ProxyRenderInfo -> {
if ( it.info.active )
activeCache[it.name] = index
}
}
}
withContext(Dispatchers.Main) {
root = newList
renderList = newRenderList.toMutableList()
urlTesting = testing
groupPosition = groupCache
activeList = activeCache
result.dispatchUpdatesTo(this@ProxyAdapter)
}
rootMutex.unlock()
}
suspend fun getGroupPosition(name: String): Int {
return withContext(Dispatchers.Default) {
renderList.mapIndexed { index, p ->
if (p is ProxyGroupRenderInfo && p.name == name)
index
else
-1
}.singleOrNull() ?: -1
}
fun getGroupPosition(name: String): Int {
return groupPosition[name] ?: -1
}
fun getCurrentGroup(): String {
@@ -183,6 +193,8 @@ class ProxyAdapter(
is ProxyGroupHeader -> {
val current = renderList[position] as ProxyGroupRenderInfo
groupPosition[current.name] = position
holder.name.text = current.info.name
holder.urlTest.setOnClickListener {
holder.urlTest.visibility = View.GONE
@@ -191,11 +203,10 @@ class ProxyAdapter(
onUrlTest(current.name)
}
if ( urlTesting.contains(current.name) ) {
if (urlTesting.contains(current.name)) {
holder.urlTest.visibility = View.GONE
holder.urlTestProgress.visibility = View.VISIBLE
}
else {
} else {
holder.urlTest.visibility = View.VISIBLE
holder.urlTestProgress.visibility = View.GONE
}
@@ -209,7 +220,7 @@ class ProxyAdapter(
if (current.info.delay > 0)
holder.delay.text = current.info.delay.toString()
else
holder.delay.text = ""
holder.delay.text = if (current.info.selectable) "" else "N/A"
if (current.info.active) {
activeList[current.group] = position
@@ -17,7 +17,7 @@ class ClashClient(private val service: IClashManager) {
suspend fun startHealthCheck(group: String) = withContext(Dispatchers.IO) {
CompletableDeferred<Unit>().apply {
service.startHealthCheck(group, object: IStreamCallback.Stub() {
service.startHealthCheck(group, object : IStreamCallback.Stub() {
override fun complete() {
this@apply.complete(Unit)
}
@@ -1,7 +1,9 @@
package com.github.kr328.clash.utils
import android.content.Context
import android.util.DisplayMetrics
import androidx.recyclerview.widget.LinearSmoothScroller
import com.github.kr328.clash.core.utils.Log
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
@@ -10,10 +12,10 @@ class ScrollBinding(
private val callback: Callback
) {
interface Callback {
suspend fun getCurrentMasterToken(): String
suspend fun onMasterTokenChanged(token: String)
suspend fun getMasterTokenPosition(token: String): Int
suspend fun doMasterScroll(scroller: LinearSmoothScroller)
fun getCurrentMasterToken(): String
fun onMasterTokenChanged(token: String)
fun getMasterTokenPosition(token: String): Int
fun doMasterScroll(scroller: LinearSmoothScroller)
}
private val updateChannel = Channel<Unit>(Channel.CONFLATED)
@@ -23,7 +25,7 @@ class ScrollBinding(
updateChannel.offer(Unit)
}
suspend fun scrollMaster(token: String) {
fun scrollMaster(token: String) {
val position = callback.getMasterTokenPosition(token)
if (position < 0)
@@ -46,6 +48,10 @@ class ScrollBinding(
preventSlaveScroll = true
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
return super.calculateSpeedPerPixel(displayMetrics) * 0.8f
}
init {
targetPosition = position
}
@@ -61,7 +67,7 @@ class ScrollBinding(
updateChannel.receive()
val currentToken = callback.getCurrentMasterToken()
if (lastToken == currentToken)
if (preventSlaveScroll || lastToken == currentToken)
continue
lastToken = currentToken