mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 03:32:38 +08:00
perf: upload github file link
This commit is contained in:
parent
c07d29e876
commit
53a035bcd9
|
@ -44,6 +44,7 @@ import li.songe.gkd.service.fixRestartService
|
||||||
import li.songe.gkd.service.updateLauncherAppId
|
import li.songe.gkd.service.updateLauncherAppId
|
||||||
import li.songe.gkd.ui.component.BuildDialog
|
import li.songe.gkd.ui.component.BuildDialog
|
||||||
import li.songe.gkd.ui.theme.AppTheme
|
import li.songe.gkd.ui.theme.AppTheme
|
||||||
|
import li.songe.gkd.util.EditGithubCookieDlg
|
||||||
import li.songe.gkd.util.LocalNavController
|
import li.songe.gkd.util.LocalNavController
|
||||||
import li.songe.gkd.util.UpgradeDialog
|
import li.songe.gkd.util.UpgradeDialog
|
||||||
import li.songe.gkd.util.appInfoCacheFlow
|
import li.songe.gkd.util.appInfoCacheFlow
|
||||||
|
@ -93,6 +94,8 @@ class MainActivity : ComponentActivity() {
|
||||||
ShizukuErrorDialog(mainVm.shizukuErrorFlow)
|
ShizukuErrorDialog(mainVm.shizukuErrorFlow)
|
||||||
AuthDialog(mainVm.authReasonFlow)
|
AuthDialog(mainVm.authReasonFlow)
|
||||||
BuildDialog(mainVm.dialogFlow)
|
BuildDialog(mainVm.dialogFlow)
|
||||||
|
mainVm.uploadOptions.ShowDialog()
|
||||||
|
EditGithubCookieDlg(mainVm.showEditCookieDlgFlow)
|
||||||
if (META.updateEnabled) {
|
if (META.updateEnabled) {
|
||||||
UpgradeDialog(mainVm.updateStatus)
|
UpgradeDialog(mainVm.updateStatus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import li.songe.gkd.data.SubsItem
|
||||||
import li.songe.gkd.db.DbSet
|
import li.songe.gkd.db.DbSet
|
||||||
import li.songe.gkd.permission.AuthReason
|
import li.songe.gkd.permission.AuthReason
|
||||||
import li.songe.gkd.ui.component.AlertDialogOptions
|
import li.songe.gkd.ui.component.AlertDialogOptions
|
||||||
|
import li.songe.gkd.ui.component.UploadOptions
|
||||||
import li.songe.gkd.util.LOCAL_SUBS_ID
|
import li.songe.gkd.util.LOCAL_SUBS_ID
|
||||||
import li.songe.gkd.util.UpdateStatus
|
import li.songe.gkd.util.UpdateStatus
|
||||||
import li.songe.gkd.util.checkUpdate
|
import li.songe.gkd.util.checkUpdate
|
||||||
|
@ -43,6 +44,10 @@ class MainViewModel : ViewModel() {
|
||||||
|
|
||||||
val shizukuErrorFlow = MutableStateFlow(false)
|
val shizukuErrorFlow = MutableStateFlow(false)
|
||||||
|
|
||||||
|
val uploadOptions = UploadOptions(this)
|
||||||
|
|
||||||
|
val showEditCookieDlgFlow = MutableStateFlow(false)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launchTry(Dispatchers.IO) {
|
viewModelScope.launchTry(Dispatchers.IO) {
|
||||||
val subsItems = DbSet.subsItemDao.queryAll()
|
val subsItems = DbSet.subsItemDao.queryAll()
|
||||||
|
|
|
@ -48,7 +48,6 @@ import androidx.compose.ui.text.style.TextDecoration
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -88,10 +87,8 @@ import li.songe.gkd.util.toast
|
||||||
fun AboutPage() {
|
fun AboutPage() {
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val context = LocalContext.current as MainActivity
|
val context = LocalContext.current as MainActivity
|
||||||
val vm = viewModel<AboutVm>()
|
|
||||||
val store by storeFlow.collectAsState()
|
val store by storeFlow.collectAsState()
|
||||||
|
|
||||||
vm.uploadOptions.ShowDialog()
|
|
||||||
var showInfoDlg by remember { mutableStateOf(false) }
|
var showInfoDlg by remember { mutableStateOf(false) }
|
||||||
if (showInfoDlg) {
|
if (showInfoDlg) {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
|
@ -176,7 +173,9 @@ fun AboutPage() {
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable(onClick = throttle {
|
.clickable(onClick = throttle {
|
||||||
showShareLogDlg = false
|
showShareLogDlg = false
|
||||||
vm.uploadOptions.startTask(getFile = { buildLogFile() })
|
context.mainVm.uploadOptions.startTask(
|
||||||
|
getFile = { buildLogFile() }
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.then(modifier)
|
.then(modifier)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package li.songe.gkd.ui
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import li.songe.gkd.ui.component.UploadOptions
|
|
||||||
|
|
||||||
class AboutVm : ViewModel() {
|
|
||||||
val uploadOptions = UploadOptions(viewModelScope)
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import android.content.Context
|
||||||
import android.media.projection.MediaProjectionManager
|
import android.media.projection.MediaProjectionManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
@ -19,7 +18,6 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
@ -58,7 +56,6 @@ import com.ramcosta.composedestinations.generated.destinations.ActivityLogPageDe
|
||||||
import com.ramcosta.composedestinations.generated.destinations.SnapshotPageDestination
|
import com.ramcosta.composedestinations.generated.destinations.SnapshotPageDestination
|
||||||
import com.ramcosta.composedestinations.utils.toDestinationsNavigator
|
import com.ramcosta.composedestinations.utils.toDestinationsNavigator
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.update
|
|
||||||
import li.songe.gkd.MainActivity
|
import li.songe.gkd.MainActivity
|
||||||
import li.songe.gkd.appScope
|
import li.songe.gkd.appScope
|
||||||
import li.songe.gkd.debug.FloatingService
|
import li.songe.gkd.debug.FloatingService
|
||||||
|
@ -81,7 +78,6 @@ import li.songe.gkd.util.LocalNavController
|
||||||
import li.songe.gkd.util.ProfileTransitions
|
import li.songe.gkd.util.ProfileTransitions
|
||||||
import li.songe.gkd.util.launchAsFn
|
import li.songe.gkd.util.launchAsFn
|
||||||
import li.songe.gkd.util.openUri
|
import li.songe.gkd.util.openUri
|
||||||
import li.songe.gkd.util.privacyStoreFlow
|
|
||||||
import li.songe.gkd.util.storeFlow
|
import li.songe.gkd.util.storeFlow
|
||||||
import li.songe.gkd.util.throttle
|
import li.songe.gkd.util.throttle
|
||||||
import li.songe.gkd.util.toast
|
import li.songe.gkd.util.toast
|
||||||
|
@ -155,62 +151,6 @@ fun AdvancedPage() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var showEditCookieDlg by remember { mutableStateOf(false) }
|
|
||||||
if (showEditCookieDlg) {
|
|
||||||
val privacyStore by privacyStoreFlow.collectAsState()
|
|
||||||
var value by remember {
|
|
||||||
mutableStateOf(privacyStore.githubCookie ?: "")
|
|
||||||
}
|
|
||||||
AlertDialog(
|
|
||||||
onDismissRequest = {
|
|
||||||
if (value.isEmpty()) {
|
|
||||||
showEditCookieDlg = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title = {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
) {
|
|
||||||
Text(text = "Github Cookie")
|
|
||||||
IconButton(onClick = throttle {
|
|
||||||
context.openUri("https://gkd.li/?r=1")
|
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
text = {
|
|
||||||
OutlinedTextField(
|
|
||||||
value = value,
|
|
||||||
onValueChange = {
|
|
||||||
value = it.filter { c -> c != '\n' && c != '\r' }
|
|
||||||
},
|
|
||||||
placeholder = { Text(text = "请输入 Github Cookie") },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
maxLines = 10,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
confirmButton = {
|
|
||||||
TextButton(onClick = {
|
|
||||||
showEditCookieDlg = false
|
|
||||||
privacyStoreFlow.update { it.copy(githubCookie = value.trim()) }
|
|
||||||
}) {
|
|
||||||
Text(text = "确认")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dismissButton = {
|
|
||||||
TextButton(onClick = { showEditCookieDlg = false }) {
|
|
||||||
Text(text = "取消")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
|
@ -454,7 +394,7 @@ fun AdvancedPage() {
|
||||||
},
|
},
|
||||||
imageVector = Icons.Default.Edit,
|
imageVector = Icons.Default.Edit,
|
||||||
onClick = {
|
onClick = {
|
||||||
showEditCookieDlg = true
|
context.mainVm.showEditCookieDlgFlow.value = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,6 @@ fun SnapshotPage() {
|
||||||
val vm = viewModel<SnapshotVm>()
|
val vm = viewModel<SnapshotVm>()
|
||||||
val snapshots by vm.snapshotsState.collectAsState()
|
val snapshots by vm.snapshotsState.collectAsState()
|
||||||
|
|
||||||
vm.uploadOptions.ShowDialog()
|
|
||||||
|
|
||||||
var selectedSnapshot by remember {
|
var selectedSnapshot by remember {
|
||||||
mutableStateOf<Snapshot?>(null)
|
mutableStateOf<Snapshot?>(null)
|
||||||
}
|
}
|
||||||
|
@ -246,8 +244,9 @@ fun SnapshotPage() {
|
||||||
text = "生成链接(需科学上网)", modifier = Modifier
|
text = "生成链接(需科学上网)", modifier = Modifier
|
||||||
.clickable(onClick = throttle {
|
.clickable(onClick = throttle {
|
||||||
selectedSnapshot = null
|
selectedSnapshot = null
|
||||||
vm.uploadOptions.startTask(
|
context.mainVm.uploadOptions.startTask(
|
||||||
getFile = { SnapshotExt.getSnapshotZipFile(snapshotVal.id) },
|
getFile = { SnapshotExt.getSnapshotZipFile(snapshotVal.id) },
|
||||||
|
showHref = { IMPORT_SHORT_URL + it.id },
|
||||||
onSuccessResult = vm.viewModelScope.launchAsFn<GithubPoliciesAsset>(
|
onSuccessResult = vm.viewModelScope.launchAsFn<GithubPoliciesAsset>(
|
||||||
Dispatchers.IO
|
Dispatchers.IO
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -5,15 +5,8 @@ import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import li.songe.gkd.db.DbSet
|
import li.songe.gkd.db.DbSet
|
||||||
import li.songe.gkd.ui.component.UploadOptions
|
|
||||||
import li.songe.gkd.util.IMPORT_SHORT_URL
|
|
||||||
|
|
||||||
class SnapshotVm : ViewModel() {
|
class SnapshotVm : ViewModel() {
|
||||||
val snapshotsState = DbSet.snapshotDao.query()
|
val snapshotsState = DbSet.snapshotDao.query()
|
||||||
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
|
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
|
||||||
|
|
||||||
val uploadOptions = UploadOptions(
|
|
||||||
scope = viewModelScope,
|
|
||||||
showHref = { IMPORT_SHORT_URL + it.id }
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -6,13 +6,15 @@ import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.blankj.utilcode.util.ClipboardUtils
|
import com.blankj.utilcode.util.ClipboardUtils
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import li.songe.gkd.MainViewModel
|
||||||
import li.songe.gkd.data.GithubPoliciesAsset
|
import li.songe.gkd.data.GithubPoliciesAsset
|
||||||
|
import li.songe.gkd.util.GithubCookieException
|
||||||
import li.songe.gkd.util.LoadStatus
|
import li.songe.gkd.util.LoadStatus
|
||||||
import li.songe.gkd.util.launchTry
|
import li.songe.gkd.util.launchTry
|
||||||
import li.songe.gkd.util.privacyStoreFlow
|
import li.songe.gkd.util.privacyStoreFlow
|
||||||
|
@ -21,8 +23,7 @@ import li.songe.gkd.util.uploadFileToGithub
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class UploadOptions(
|
class UploadOptions(
|
||||||
private val scope: CoroutineScope,
|
private val mainVm: MainViewModel,
|
||||||
private val showHref: (GithubPoliciesAsset) -> String = { it.shortHref }
|
|
||||||
) {
|
) {
|
||||||
private val statusFlow = MutableStateFlow<LoadStatus<GithubPoliciesAsset>?>(null)
|
private val statusFlow = MutableStateFlow<LoadStatus<GithubPoliciesAsset>?>(null)
|
||||||
private var job: Job? = null
|
private var job: Job? = null
|
||||||
|
@ -30,7 +31,7 @@ class UploadOptions(
|
||||||
cookie: String,
|
cookie: String,
|
||||||
getFile: suspend () -> File,
|
getFile: suspend () -> File,
|
||||||
onSuccessResult: ((GithubPoliciesAsset) -> Unit)?
|
onSuccessResult: ((GithubPoliciesAsset) -> Unit)?
|
||||||
) = scope.launchTry(Dispatchers.IO) {
|
) = mainVm.viewModelScope.launchTry(Dispatchers.IO) {
|
||||||
statusFlow.value = LoadStatus.Loading()
|
statusFlow.value = LoadStatus.Loading()
|
||||||
try {
|
try {
|
||||||
val policiesAsset = uploadFileToGithub(cookie, getFile()) {
|
val policiesAsset = uploadFileToGithub(cookie, getFile()) {
|
||||||
|
@ -47,18 +48,23 @@ class UploadOptions(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private var showHref: (GithubPoliciesAsset) -> String = { it.shortHref }
|
||||||
fun startTask(
|
fun startTask(
|
||||||
getFile: suspend () -> File,
|
getFile: suspend () -> File,
|
||||||
|
showHref: (GithubPoliciesAsset) -> String = { it.shortHref },
|
||||||
onSuccessResult: ((GithubPoliciesAsset) -> Unit)? = null
|
onSuccessResult: ((GithubPoliciesAsset) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
val cookie = privacyStoreFlow.value.githubCookie
|
val cookie = privacyStoreFlow.value.githubCookie
|
||||||
if (cookie.isNullOrBlank()) {
|
if (cookie.isNullOrBlank()) {
|
||||||
toast("请先设置 cookie 后再上传")
|
toast("请先设置 cookie 后再上传")
|
||||||
|
mainVm.showEditCookieDlgFlow.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (job != null || statusFlow.value is LoadStatus.Loading) {
|
if (job != null || statusFlow.value is LoadStatus.Loading) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.showHref = showHref
|
||||||
job = buildTask(cookie, getFile, onSuccessResult)
|
job = buildTask(cookie, getFile, onSuccessResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +129,16 @@ class UploadOptions(
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onDismissRequest = { statusFlow.value = null },
|
onDismissRequest = { statusFlow.value = null },
|
||||||
|
dismissButton = if (status.exception is GithubCookieException) ({
|
||||||
|
TextButton(onClick = {
|
||||||
|
statusFlow.value = null
|
||||||
|
mainVm.showEditCookieDlgFlow.value = true
|
||||||
|
}) {
|
||||||
|
Text(text = "更换 Cookie")
|
||||||
|
}
|
||||||
|
}) else {
|
||||||
|
null
|
||||||
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = {
|
TextButton(onClick = {
|
||||||
statusFlow.value = null
|
statusFlow.value = null
|
||||||
|
|
|
@ -1,5 +1,24 @@
|
||||||
package li.songe.gkd.util
|
package li.songe.gkd.util
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import io.ktor.client.call.body
|
import io.ktor.client.call.body
|
||||||
import io.ktor.client.plugins.onUpload
|
import io.ktor.client.plugins.onUpload
|
||||||
import io.ktor.client.request.forms.MultiPartFormDataContent
|
import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||||
|
@ -13,7 +32,10 @@ import io.ktor.client.statement.bodyAsText
|
||||||
import io.ktor.http.Headers
|
import io.ktor.http.Headers
|
||||||
import io.ktor.http.HttpHeaders
|
import io.ktor.http.HttpHeaders
|
||||||
import io.ktor.http.HttpMessageBuilder
|
import io.ktor.http.HttpMessageBuilder
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import li.songe.gkd.app
|
||||||
import li.songe.gkd.data.GithubPoliciesAsset
|
import li.songe.gkd.data.GithubPoliciesAsset
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
@ -50,12 +72,14 @@ private data class Authenticity(
|
||||||
val authenticityToken: String,
|
val authenticityToken: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class GithubCookieException(override val message: String) : Exception(message)
|
||||||
|
|
||||||
private suspend fun getAuthenticity(cookie: String): Authenticity {
|
private suspend fun getAuthenticity(cookie: String): Authenticity {
|
||||||
val text = client.get(GITHUB_UPLOAD_URL) {
|
val text = client.get(GITHUB_UPLOAD_URL) {
|
||||||
setCommonHeaders(cookie)
|
setCommonHeaders(cookie)
|
||||||
}.bodyAsText()
|
}.bodyAsText()
|
||||||
if (!text.contains("data-login")) {
|
if (!text.contains("data-login")) {
|
||||||
error("用户未登录, 请更换 cookie")
|
throw GithubCookieException("未检测到用户登录, 请更换 cookie")
|
||||||
}
|
}
|
||||||
val repositoryId =
|
val repositoryId =
|
||||||
repositoryIdRegex.find(text)?.groupValues?.get(1) ?: error("repositoryId not found")
|
repositoryIdRegex.find(text)?.groupValues?.get(1) ?: error("repositoryId not found")
|
||||||
|
@ -114,3 +138,62 @@ suspend fun uploadFileToGithub(
|
||||||
return policiesResp.asset
|
return policiesResp.asset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun EditGithubCookieDlg(showEditCookieDlgFlow: MutableStateFlow<Boolean>) {
|
||||||
|
val showEditCookieDlg by showEditCookieDlgFlow.collectAsState()
|
||||||
|
if (showEditCookieDlg) {
|
||||||
|
val privacyStore by privacyStoreFlow.collectAsState()
|
||||||
|
var value by remember {
|
||||||
|
mutableStateOf(privacyStore.githubCookie ?: "")
|
||||||
|
}
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = {
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
showEditCookieDlgFlow.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
Text(text = "Github Cookie")
|
||||||
|
IconButton(onClick = throttle {
|
||||||
|
app.openUri("https://gkd.li/?r=1")
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = value,
|
||||||
|
onValueChange = {
|
||||||
|
value = it.filter { c -> c != '\n' && c != '\r' }
|
||||||
|
},
|
||||||
|
placeholder = { Text(text = "请输入 Github Cookie") },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
maxLines = 10,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = {
|
||||||
|
showEditCookieDlgFlow.value = false
|
||||||
|
privacyStoreFlow.update { it.copy(githubCookie = value.trim()) }
|
||||||
|
}) {
|
||||||
|
Text(text = "确认")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = { showEditCookieDlgFlow.value = false }) {
|
||||||
|
Text(text = "取消")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user