diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt index 03822c6a..06c5d8d7 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/GroupServerFragment.kt @@ -280,4 +280,38 @@ class GroupServerFragment : BaseFragment(), ownerActivity.importConfigViaSub() binding.refreshLayout.isRefreshing = false } + + /** + * Scrolls to the currently selected server in the RecyclerView + */ + fun scrollToSelectedServer() { + val selectedGuid = MmkvManager.getSelectServer() + if (selectedGuid.isNullOrEmpty()) { + ownerActivity.toast(R.string.title_file_chooser) + return + } + + // Find the position of the selected server + val serversCache = mainViewModel.serversCache + val position = serversCache.indexOfFirst { it.guid == selectedGuid } + val recyclerView = binding.recyclerView + + if (position >= 0) { + // Get the layout manager + val layoutManager = recyclerView.layoutManager as? GridLayoutManager + + if (layoutManager != null) { + // Scroll to position with offset to center it on screen + // First scroll to position, then adjust to center + recyclerView.post { + layoutManager.scrollToPositionWithOffset(position, recyclerView.height / 3) + } + } else { + // Fallback to smooth scroll if layout manager is not GridLayoutManager + recyclerView.smoothScrollToPosition(position) + } + } else { + ownerActivity.toast(R.string.toast_server_not_found_in_group) + } + } } \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt index 7b42d865..c835cc92 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt @@ -94,6 +94,7 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect }) binding.fab.setOnClickListener { handleFabAction() } + binding.fabLocate.setOnClickListener { locateSelectedServer() } binding.layoutTest.setOnClickListener { handleLayoutTestClick() } setupGroupTab() @@ -569,6 +570,47 @@ class MainActivity : HelperBaseActivity(), NavigationView.OnNavigationItemSelect } } + /** + * Locates and scrolls to the currently selected server. + * If the selected server is in a different group, automatically switches to that group first. + */ + private fun locateSelectedServer() { + val targetSubscriptionId = mainViewModel.findSubscriptionIdBySelect() + if (targetSubscriptionId.isNullOrEmpty()) { + toast(R.string.title_file_chooser) + return + } + + val targetGroupIndex = groupPagerAdapter.groups.indexOfFirst { it.id == targetSubscriptionId } + if (targetGroupIndex < 0) { + toast(R.string.toast_server_not_found_in_group) + return + } + + // Switch to target group if needed, then scroll to the server + if (binding.viewPager.currentItem != targetGroupIndex) { + binding.viewPager.setCurrentItem(targetGroupIndex, true) + binding.viewPager.postDelayed({ scrollToSelectedServer(targetGroupIndex) }, 1000) + } else { + scrollToSelectedServer(targetGroupIndex) + } + } + + /** + * Scrolls to the selected server in the specified fragment. + * @param groupIndex The index of the group/fragment to scroll in + */ + private fun scrollToSelectedServer(groupIndex: Int) { + val itemId = groupPagerAdapter.getItemId(groupIndex) + val fragment = supportFragmentManager.findFragmentByTag("f$itemId") as? GroupServerFragment + + if (fragment?.isAdded == true && fragment.view != null) { + fragment.scrollToSelectedServer() + } else { + toast(R.string.toast_fragment_not_available) + } + } + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_BUTTON_B) { moveTaskToBack(false) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt index 0f56d56a..e9e07f59 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/MainViewModel.kt @@ -402,6 +402,17 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { reloadServerList() } + fun findSubscriptionIdBySelect(): String? { + // Get the selected server GUID + val selectedGuid = MmkvManager.getSelectServer() + if (selectedGuid.isNullOrEmpty()) { + return null + } + + val config = MmkvManager.decodeServerConfig(selectedGuid) + return config?.subscriptionId + } + fun onTestsFinished() { viewModelScope.launch(Dispatchers.Default) { if (MmkvManager.decodeSettingsBool(AppConfig.PREF_AUTO_REMOVE_INVALID_AFTER_TEST)) { @@ -468,4 +479,4 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } } } -} +} \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/layout/activity_main.xml b/V2rayNG/app/src/main/res/layout/activity_main.xml index 24cfe60b..87648213 100644 --- a/V2rayNG/app/src/main/res/layout/activity_main.xml +++ b/V2rayNG/app/src/main/res/layout/activity_main.xml @@ -96,6 +96,18 @@ android:layout_gravity="bottom|end" android:layout_marginEnd="@dimen/padding_spacing_dp16"> + + Update %d configurations Updated %1$d configs (%2$d success, %3$d failed, %4$d skipped) No subscriptions + Selected server not found in current group + Unable to locate current view بدء الخدمة تأكيد diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index 32dacfb3..c12d7f1b 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -298,6 +298,8 @@ Update %d configurations Updated %1$d configs (%2$d success, %3$d failed, %4$d skipped) No subscriptions + Selected server not found in current group + Unable to locate current view সার্ভিস শুরু করুন নিশ্চিত করুন diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index d58e6742..7a65f62d 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -299,6 +299,8 @@ ورۊ کردن %d کانفیگ %1$d کانفیگ ورۊ وابی (مووفق: %2$d، شکست خرده: %3$d، رڌ وابیڌه: %4$d) بؽ اشتراک + Selected server not found in current group + Unable to locate current view ره وندن خدمات قوۊل diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index 52d3b8f0..7f9b4f73 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -296,6 +296,8 @@ آپدیت کردن %d کانفیگ Updated %1$d configs (%2$d success, %3$d failed, %4$d skipped) No subscriptions + Selected server not found in current group + Unable to locate current view شروع خدمات تایید diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index f12a4e50..0fbe243d 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -297,6 +297,8 @@ Обновлено профилей: %d Обновлено профилей: %1$d (успешно: %2$d, ошибок: %3$d, пропущено: %4$d) Нет подписок + Selected server not found in current group + Unable to locate current view Запуск службы Подтвердить diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index 7c15e378..83aae0b9 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -299,6 +299,8 @@ Update %d configurations Updated %1$d configs (%2$d success, %3$d failed, %4$d skipped) No subscriptions + Selected server not found in current group + Unable to locate current view Khởi động v2rayNG Xác nhận diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 90c30b95..78bd8f02 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -297,6 +297,8 @@ 更新 %d 个配置 更新了 %1$d 个配置(%2$d 个成功,%3$d 个失败,%4$d 个跳过) 无订阅 + 当前分组中未找到选中的服务器 + 无法定位当前视图 启动服务 确定 diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 79f911d1..96e5c0fe 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -297,6 +297,8 @@ 更新 %d 個配置 更新了 %1$d 個配置(%2$d 個成功,%3$d 個失敗,%4$d 個跳過) 無訂閱 + 當前分組中未找到選中的伺服器 + 無法定位當前視圖 啟動服務 確定 diff --git a/V2rayNG/app/src/main/res/values/dimens.xml b/V2rayNG/app/src/main/res/values/dimens.xml index 9de2f26f..945ba3fe 100644 --- a/V2rayNG/app/src/main/res/values/dimens.xml +++ b/V2rayNG/app/src/main/res/values/dimens.xml @@ -7,5 +7,6 @@ 36dp 48dp 64dp + 120dp 160dp diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 35459db8..9faa9a1f 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -303,6 +303,8 @@ Update %d configs Updated %1$d configs (%2$d success, %3$d failed, %4$d skipped) No subscriptions + Selected server not found in current group + Unable to locate current view Start Service Confirm