Improve Tailscale View

This commit is contained in:
世界
2026-07-06 21:15:31 +08:00
parent 416d280695
commit ffd37880cf
7 changed files with 91 additions and 3 deletions
@@ -30,6 +30,7 @@ import androidx.compose.material.icons.filled.Terminal
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -337,6 +338,20 @@ fun TailscalePeerScreen(
fontWeight = FontWeight.Bold,
)
}
if (pingState.isDirect && pingState.endpoint.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp))
DetailRow(
label = stringResource(R.string.tailscale_ping_endpoint),
value = pingState.endpoint,
)
}
if (!pingState.isDirect && pingState.derpRegionCode.isNotEmpty()) {
Spacer(modifier = Modifier.height(8.dp))
DetailRow(
label = stringResource(R.string.tailscale_ping_derp_region),
value = pingState.derpRegionCode,
)
}
if (pingState.isRunning && pingState.latencyHistory.size > 1) {
Spacer(modifier = Modifier.height(8.dp))
Row(
@@ -386,9 +401,32 @@ fun TailscalePeerScreen(
}
}
}
} else {
}
if (pingState.error.isNotEmpty()) {
if (pingState.hasResult) {
Spacer(modifier = Modifier.height(8.dp))
}
Text(
text = "No data",
text = pingState.error,
color = MaterialTheme.colorScheme.error,
)
} else if (pingState.isRunning && !pingState.hasResult) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
CircularProgressIndicator(
modifier = Modifier.size(16.dp),
strokeWidth = 2.dp,
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = stringResource(R.string.tailscale_ping_connecting),
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
} else if (!pingState.hasResult) {
Text(
text = stringResource(R.string.tailscale_ping_no_data),
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
@@ -17,6 +17,7 @@ data class TailscalePingState(
val isDirect: Boolean = false,
val derpRegionCode: String = "",
val endpoint: String = "",
val error: String = "",
val latencyHistory: List<Float> = emptyList(),
)
@@ -31,6 +32,7 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
copy(
isRunning = true,
hasResult = false,
error = "",
latencyHistory = emptyList(),
)
}
@@ -47,7 +49,10 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
result ?: return
viewModelScope.launch {
if (!currentState.isRunning) return@launch
if (result.error.isNotEmpty()) return@launch
if (result.error.isNotEmpty()) {
updateState { copy(error = result.error) }
return@launch
}
val newHistory = currentState.latencyHistory.toMutableList()
newHistory.add(result.latencyMs.toFloat())
if (newHistory.size > maxHistorySize) {
@@ -60,6 +65,7 @@ class TailscalePingViewModel : BaseViewModel<TailscalePingState, Nothing>() {
isDirect = result.isDirect,
derpRegionCode = result.derpRegionCode,
endpoint = result.endpoint,
error = "",
latencyHistory = newHistory,
)
}
+10
View File
@@ -465,6 +465,7 @@
<string name="tailscale_open_auth_url">باز کردن لینک احراز هویت</string>
<string name="tailscale_open_auth_url_qr_code">نمایش QR کد لینک احراز هویت</string>
<string name="tailscale_this_device">این دستگاه</string>
<string name="tailscale_logout">خروج از حساب</string>
<string name="tailscale_connected">متصل</string>
<string name="tailscale_not_connected">متصل نیست</string>
<string name="tailscale_addresses">آدرس‌های Tailscale</string>
@@ -472,6 +473,15 @@
<string name="tailscale_key_expiry">انقضای کلید</string>
<string name="tailscale_exit_node">گره خروجی</string>
<string name="tailscale_active">فعال</string>
<string name="tailscale_ping">پینگ</string>
<string name="tailscale_ping_start">شروع</string>
<string name="tailscale_ping_stop">توقف</string>
<string name="tailscale_ping_direct">اتصال مستقیم</string>
<string name="tailscale_ping_derp">اتصال از طریق DERP</string>
<string name="tailscale_ping_endpoint">نقطه پایانی</string>
<string name="tailscale_ping_derp_region">منطقه DERP</string>
<string name="tailscale_ping_connecting">در حال اتصال…</string>
<string name="tailscale_ping_no_data">بدون داده</string>
<string name="tailscale_shared_in">به اشتراک گذاشته شده</string>
<string name="tailscale_expired">منقضی شده</string>
<string name="tailscale_expires_relative">انقضا %1$s</string>
@@ -471,6 +471,7 @@
<string name="tailscale_open_auth_url">Открыть URL авторизации</string>
<string name="tailscale_open_auth_url_qr_code">Показать QR-код авторизации</string>
<string name="tailscale_this_device">Это устройство</string>
<string name="tailscale_logout">Выйти</string>
<string name="tailscale_connected">Подключено</string>
<string name="tailscale_not_connected">Не подключено</string>
<string name="tailscale_addresses">Адреса Tailscale</string>
@@ -478,6 +479,15 @@
<string name="tailscale_key_expiry">Срок действия ключа</string>
<string name="tailscale_exit_node">Выходной узел</string>
<string name="tailscale_active">Активен</string>
<string name="tailscale_ping">Пинг</string>
<string name="tailscale_ping_start">Начать</string>
<string name="tailscale_ping_stop">Остановить</string>
<string name="tailscale_ping_direct">Прямое соединение</string>
<string name="tailscale_ping_derp">Соединение через DERP</string>
<string name="tailscale_ping_endpoint">Конечная точка</string>
<string name="tailscale_ping_derp_region">Регион DERP</string>
<string name="tailscale_ping_connecting">Подключение…</string>
<string name="tailscale_ping_no_data">Нет данных</string>
<string name="tailscale_shared_in">Поделено</string>
<string name="tailscale_expired">Истёк</string>
<string name="tailscale_expires_relative">Истекает %1$s</string>
@@ -462,6 +462,7 @@
<string name="tailscale_open_auth_url">打开认证链接</string>
<string name="tailscale_open_auth_url_qr_code">显示认证链接二维码</string>
<string name="tailscale_this_device">此设备</string>
<string name="tailscale_logout">登出</string>
<string name="tailscale_connected">已连接</string>
<string name="tailscale_not_connected">未连接</string>
<string name="tailscale_addresses">Tailscale 地址</string>
@@ -469,6 +470,15 @@
<string name="tailscale_key_expiry">密钥过期</string>
<string name="tailscale_exit_node">出口节点</string>
<string name="tailscale_active">活跃</string>
<string name="tailscale_ping">Ping</string>
<string name="tailscale_ping_start">启动</string>
<string name="tailscale_ping_stop">停止</string>
<string name="tailscale_ping_direct">直接连接</string>
<string name="tailscale_ping_derp">DERP 中继连接</string>
<string name="tailscale_ping_endpoint">端点</string>
<string name="tailscale_ping_derp_region">DERP 区域</string>
<string name="tailscale_ping_connecting">连接中…</string>
<string name="tailscale_ping_no_data">无数据</string>
<string name="tailscale_shared_in">共享至此</string>
<string name="tailscale_expired">已过期</string>
<string name="tailscale_expires_relative">%1$s过期</string>
@@ -465,6 +465,7 @@
<string name="tailscale_open_auth_url">開啟認證連結</string>
<string name="tailscale_open_auth_url_qr_code">顯示認證連結 QR 碼</string>
<string name="tailscale_this_device">此裝置</string>
<string name="tailscale_logout">登出</string>
<string name="tailscale_connected">已連線</string>
<string name="tailscale_not_connected">未連線</string>
<string name="tailscale_addresses">Tailscale 位址</string>
@@ -472,6 +473,15 @@
<string name="tailscale_key_expiry">金鑰到期</string>
<string name="tailscale_exit_node">出口節點</string>
<string name="tailscale_active">活躍</string>
<string name="tailscale_ping">Ping</string>
<string name="tailscale_ping_start">啟動</string>
<string name="tailscale_ping_stop">停止</string>
<string name="tailscale_ping_direct">直接連線</string>
<string name="tailscale_ping_derp">DERP 中繼連線</string>
<string name="tailscale_ping_endpoint">端點</string>
<string name="tailscale_ping_derp_region">DERP 區域</string>
<string name="tailscale_ping_connecting">連線中…</string>
<string name="tailscale_ping_no_data">無資料</string>
<string name="tailscale_shared_in">共享至此</string>
<string name="tailscale_expired">已過期</string>
<string name="tailscale_expires_relative">%1$s過期</string>
+4
View File
@@ -483,6 +483,10 @@
<string name="tailscale_ping_stop">Stop</string>
<string name="tailscale_ping_direct">Direct connection</string>
<string name="tailscale_ping_derp">DERP-relayed connection</string>
<string name="tailscale_ping_endpoint">Endpoint</string>
<string name="tailscale_ping_derp_region">DERP region</string>
<string name="tailscale_ping_connecting">Connecting…</string>
<string name="tailscale_ping_no_data">No data</string>
<string name="tailscale_shared_in">Shared in</string>
<string name="tailscale_expired">Expired</string>
<string name="tailscale_expires_relative">Expires %1$s</string>