Add github token settings for updater

This commit is contained in:
世界
2026-07-14 23:04:36 +08:00
parent 26a2b05b06
commit 18dc46edca
12 changed files with 124 additions and 6 deletions
@@ -25,8 +25,8 @@ class GitHubUpdateChecker : Closeable {
private val json = Json { ignoreUnknownKeys = true }
fun checkUpdate(track: UpdateTrack): UpdateInfo? {
val releases = getReleases()
fun checkUpdate(track: UpdateTrack, githubToken: String): UpdateInfo? {
val releases = getReleases(githubToken)
var selected: ReleaseCandidate? = null
for (release in releases) {
@@ -64,10 +64,14 @@ class GitHubUpdateChecker : Closeable {
)
}
private fun getReleases(): List<GitHubRelease> {
private fun getReleases(githubToken: String): List<GitHubRelease> {
val request = client.newRequest()
request.setURL(RELEASES_URL)
request.setHeader("Accept", "application/vnd.github.v3+json")
val token = githubToken.trim()
if (token.isNotEmpty()) {
request.setHeader("Authorization", "Bearer $token")
}
request.setUserAgent(HTTPClient.userAgent)
val response = request.execute()
@@ -65,7 +65,7 @@ class UpdateWorker(private val appContext: Context, params: WorkerParameters) :
UpdateSource.FDROID -> checkFDroidUpdate(appContext)
UpdateSource.GITHUB -> {
val track = UpdateTrack.fromString(Settings.updateTrack)
GitHubUpdateChecker().use { it.checkUpdate(track) }
GitHubUpdateChecker().use { it.checkUpdate(track, Settings.githubToken) }
}
}
@@ -27,17 +27,21 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material.icons.filled.Terminal
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.outlined.AdminPanelSettings
import androidx.compose.material.icons.outlined.Autorenew
import androidx.compose.material.icons.outlined.DeleteForever
import androidx.compose.material.icons.outlined.DeleteSweep
import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Key
import androidx.compose.material.icons.outlined.Language
import androidx.compose.material.icons.outlined.NewReleases
import androidx.compose.material.icons.outlined.Notifications
@@ -59,6 +63,7 @@ import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
@@ -79,6 +84,9 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.core.app.NotificationManagerCompat
import androidx.core.os.LocaleListCompat
@@ -141,6 +149,8 @@ fun AppSettingsScreen(
var currentSource by remember { mutableStateOf(Settings.updateSource) }
var showTrackDialog by remember { mutableStateOf(false) }
var currentTrack by remember { mutableStateOf(Settings.updateTrack) }
var showGitHubTokenDialog by remember { mutableStateOf(false) }
var githubToken by remember { mutableStateOf(Settings.githubToken) }
var checkUpdateEnabled by remember { mutableStateOf(Settings.checkUpdateEnabled) }
var showErrorDialog by remember { mutableStateOf<String?>(null) }
@@ -255,6 +265,20 @@ fun AppSettingsScreen(
)
}
if (showGitHubTokenDialog) {
GitHubTokenDialog(
currentToken = githubToken,
onSave = { token ->
githubToken = token
scope.launch(Dispatchers.IO) {
Settings.githubToken = token
}
showGitHubTokenDialog = false
},
onDismiss = { showGitHubTokenDialog = false },
)
}
showErrorDialog?.let { message ->
AlertDialog(
onDismissRequest = { showErrorDialog = null },
@@ -781,6 +805,9 @@ fun AppSettingsScreen(
if (Vendor.hasCustomUpdate) {
count += 1
}
if (Vendor.hasCustomUpdate && !isFDroid) {
count += 1
}
if (isFDroid) {
count += 1
}
@@ -884,6 +911,38 @@ fun AppSettingsScreen(
)
}
if (Vendor.hasCustomUpdate && !isFDroid) {
ListItem(
headlineContent = {
Text(
stringResource(R.string.github_token),
style = MaterialTheme.typography.bodyLarge,
)
},
supportingContent = {
Text(
stringResource(R.string.github_token_description),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
},
leadingContent = {
Icon(
imageVector = Icons.Outlined.Key,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary,
)
},
modifier =
updateItemModifier()
.clickable { showGitHubTokenDialog = true },
colors =
ListItemDefaults.colors(
containerColor = Color.Transparent,
),
)
}
if (isFDroid) {
ListItem(
headlineContent = {
@@ -1408,6 +1467,49 @@ private fun UpdateTrackDialog(
)
}
@Composable
private fun GitHubTokenDialog(
currentToken: String,
onSave: (String) -> Unit,
onDismiss: () -> Unit,
) {
var token by remember(currentToken) { mutableStateOf(currentToken) }
var tokenVisible by remember { mutableStateOf(false) }
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(stringResource(R.string.github_token)) },
text = {
OutlinedTextField(
value = token,
onValueChange = { token = it },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
visualTransformation = if (tokenVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
IconButton(onClick = { tokenVisible = !tokenVisible }) {
Icon(
imageVector = if (tokenVisible) Icons.Default.VisibilityOff else Icons.Default.Visibility,
contentDescription = null,
)
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
)
},
confirmButton = {
TextButton(onClick = { onSave(token.trim()) }) {
Text(stringResource(R.string.save))
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text(stringResource(R.string.cancel))
}
},
)
}
@Composable
private fun LanguageDialog(
currentTag: String,
@@ -7,6 +7,7 @@ object SettingsKey {
const val UPDATE_CHECK_PROMPTED = "update_check_prompted"
const val UPDATE_SOURCE = "update_source"
const val UPDATE_TRACK = "update_track"
const val GITHUB_TOKEN = "github_token"
const val FDROID_MIRROR_URL = "fdroid_mirror_url"
const val FDROID_CUSTOM_MIRRORS = "fdroid_custom_mirrors"
const val SILENT_INSTALL_ENABLED = "silent_install_enabled"
@@ -56,6 +56,7 @@ object Settings {
"stable"
}
}
var githubToken by dataStore.string(SettingsKey.GITHUB_TOKEN) { "" }
var silentInstallEnabled by dataStore.boolean(SettingsKey.SILENT_INSTALL_ENABLED) { false }
var silentInstallMethod by dataStore.string(SettingsKey.SILENT_INSTALL_METHOD) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+2
View File
@@ -286,6 +286,8 @@
<string name="update_source">منبع به‌روزرسانی</string>
<string name="update_source_github">GitHub</string>
<string name="update_source_fdroid">F-Droid</string>
<string name="github_token">توکن GitHub</string>
<string name="github_token_description">دریافت محدودیت نرخ بالاتر برای API گیت‌هاب</string>
<string name="fdroid_mirror">آینه F-Droid</string>
<string name="fdroid_mirror_test_all">انتخاب خودکار بر اساس تأخیر</string>
<string name="fdroid_mirror_testing">در حال تست…</string>
@@ -286,6 +286,8 @@
<string name="update_source">Источник обновлений</string>
<string name="update_source_github">GitHub</string>
<string name="update_source_fdroid">F-Droid</string>
<string name="github_token">Токен GitHub</string>
<string name="github_token_description">Получите более высокие лимиты запросов GitHub API</string>
<string name="fdroid_mirror">Зеркало F-Droid</string>
<string name="fdroid_mirror_test_all">Автовыбор по задержке</string>
<string name="fdroid_mirror_testing">Тестирование…</string>
@@ -286,6 +286,8 @@
<string name="update_source">更新来源</string>
<string name="update_source_github">GitHub</string>
<string name="update_source_fdroid">F-Droid</string>
<string name="github_token">GitHub Token</string>
<string name="github_token_description">获取更高的 GitHub API 速率限制</string>
<string name="fdroid_mirror">F-Droid 镜像</string>
<string name="fdroid_mirror_test_all">根据延迟自动选择</string>
<string name="fdroid_mirror_testing">测试中…</string>
@@ -286,6 +286,8 @@
<string name="update_source">更新來源</string>
<string name="update_source_github">GitHub</string>
<string name="update_source_fdroid">F-Droid</string>
<string name="github_token">GitHub Token</string>
<string name="github_token_description">取得更高的 GitHub API 速率限制</string>
<string name="fdroid_mirror">F-Droid 鏡像</string>
<string name="fdroid_mirror_test_all">依延遲自動選擇</string>
<string name="fdroid_mirror_testing">測試中…</string>
+2
View File
@@ -275,6 +275,8 @@
<string name="update_source">Update Source</string>
<string name="update_source_github">GitHub</string>
<string name="update_source_fdroid">F-Droid</string>
<string name="github_token">GitHub Token</string>
<string name="github_token_description">Get higher GitHub API rate limits</string>
<string name="update_track">Update Track</string>
<string name="update_track_stable">Stable</string>
<string name="update_track_beta">Beta</string>
+1 -1
View File
@@ -104,7 +104,7 @@ object Vendor : VendorInterface {
UpdateSource.GITHUB -> {
val track = UpdateTrack.fromString(Settings.updateTrack)
GitHubUpdateChecker().use { checker ->
checker.checkUpdate(track)
checker.checkUpdate(track, Settings.githubToken)
}
}
}
@@ -98,7 +98,7 @@ object Vendor : VendorInterface {
override fun checkUpdateAsync(): UpdateInfo? {
val track = UpdateTrack.fromString(Settings.updateTrack)
return GitHubUpdateChecker().use { checker ->
checker.checkUpdate(track)
checker.checkUpdate(track, Settings.githubToken)
}
}