feat(ui): 重新设计记录编辑页面 (RecordEditScreen)
- 重构 RecordEditScreen 布局:新增 Hero 照片卡片,分组卡片化基本信息(标题与笔记)与日期设定(拍摄日期与关联日历) - 引入图形化 OutlinedTextField(带图标、提示与标题快速清除)与交互式 DatePickerTile(带星期显示与清除关联) - 优化顶部 TopAppBar 操作:添加顶部右上角“保存”快捷入口,配合底部固定“保存记录”主按钮 - 保持现有所有 testTag 兼容性
This commit is contained in:
parent
9ad9e39164
commit
57da898ed7
@ -1,28 +1,45 @@
|
||||
package plus.rua.project.ui
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
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.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ChevronLeft
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.outlined.Bookmark
|
||||
import androidx.compose.material.icons.outlined.BookmarkBorder
|
||||
import androidx.compose.material.icons.outlined.CalendarToday
|
||||
import androidx.compose.material.icons.outlined.Check
|
||||
import androidx.compose.material.icons.outlined.ChevronRight
|
||||
import androidx.compose.material.icons.outlined.Edit
|
||||
import androidx.compose.material.icons.outlined.Notes
|
||||
import androidx.compose.material.icons.outlined.Title
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DatePicker
|
||||
import androidx.compose.material3.DatePickerDialog
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
@ -36,8 +53,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
@ -49,6 +67,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import com.github.panpf.sketch.AsyncImage
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.atStartOfDayIn
|
||||
@ -56,8 +76,6 @@ import kotlinx.datetime.toLocalDateTime
|
||||
import plus.rua.project.DateRecorderRepository
|
||||
import plus.rua.project.RecordEditUiState
|
||||
import plus.rua.project.RecordEditViewModel
|
||||
import plus.rua.project.formatLocalDate
|
||||
import kotlin.time.Instant
|
||||
|
||||
/**
|
||||
* 记录编辑页面,用于新建或修改一条日期记录的信息。
|
||||
@ -103,23 +121,64 @@ fun RecordEditScreen(
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
if (recordId != null) "编辑记录" else "新建记录",
|
||||
style = MaterialTheme.typography.titleLarge.copy(
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
text = if (recordId != null) "编辑记录" else "新建记录",
|
||||
style = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.SemiBold)
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ChevronLeft,
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = "返回"
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent)
|
||||
actions = {
|
||||
TextButton(
|
||||
onClick = viewModel::save,
|
||||
enabled = state.canSave
|
||||
) {
|
||||
Text(
|
||||
text = "保存",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = if (state.canSave) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.surface)
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
Surface(
|
||||
tonalElevation = 3.dp,
|
||||
color = MaterialTheme.colorScheme.surfaceContainer,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Box(modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)) {
|
||||
Button(
|
||||
onClick = viewModel::save,
|
||||
enabled = state.canSave,
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(48.dp)
|
||||
.testTag("record_edit_save")
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Check,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(
|
||||
text = "保存记录",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
) { innerPadding ->
|
||||
if (state.loading) {
|
||||
@ -139,7 +198,6 @@ fun RecordEditScreen(
|
||||
onShootDateChange = viewModel::onShootDateChange,
|
||||
onLinkedDateChange = viewModel::onLinkedDateChange,
|
||||
onClearLinkedDate = viewModel::onClearLinkedDate,
|
||||
onSave = viewModel::save,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
@ -148,7 +206,17 @@ fun RecordEditScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
/**
|
||||
* 记录编辑表单区。
|
||||
*
|
||||
* @param state UI 状态
|
||||
* @param onTitleChange 标题变更回调
|
||||
* @param onNoteChange 笔记变更回调
|
||||
* @param onShootDateChange 拍摄日期变更回调
|
||||
* @param onLinkedDateChange 关联日期变更回调
|
||||
* @param onClearLinkedDate 清除关联日期回调
|
||||
* @param modifier 布局修饰符
|
||||
*/
|
||||
@Composable
|
||||
private fun RecordEditForm(
|
||||
state: RecordEditUiState,
|
||||
@ -157,7 +225,6 @@ private fun RecordEditForm(
|
||||
onShootDateChange: (LocalDate) -> Unit,
|
||||
onLinkedDateChange: (LocalDate) -> Unit,
|
||||
onClearLinkedDate: () -> Unit,
|
||||
onSave: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var showShootDatePicker by remember { mutableStateOf(false) }
|
||||
@ -169,69 +236,180 @@ private fun RecordEditForm(
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
// 照片预览
|
||||
// 照片预览卡片
|
||||
state.photoUri?.let { uri ->
|
||||
AsyncImage(
|
||||
uri = uri,
|
||||
contentDescription = "记录照片",
|
||||
ElevatedCard(
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
colors = CardDefaults.elevatedCardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
),
|
||||
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 2.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(200.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.testTag("record_edit_photo")
|
||||
)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 180.dp, max = 260.dp)
|
||||
) {
|
||||
AsyncImage(
|
||||
uri = uri,
|
||||
contentDescription = "记录照片",
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "记录照片",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
OutlinedTextField(
|
||||
value = state.title,
|
||||
onValueChange = onTitleChange,
|
||||
label = { Text("标题") },
|
||||
singleLine = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag("record_edit_title")
|
||||
)
|
||||
|
||||
// 备注
|
||||
OutlinedTextField(
|
||||
value = state.note,
|
||||
onValueChange = onNoteChange,
|
||||
label = { Text("备注") },
|
||||
minLines = 3,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag("record_edit_note")
|
||||
)
|
||||
|
||||
// 拍摄日期
|
||||
DatePickerField(
|
||||
label = "拍摄日期",
|
||||
date = state.shootDate,
|
||||
onClick = { showShootDatePicker = true },
|
||||
modifier = Modifier.testTag("record_edit_shoot_date")
|
||||
)
|
||||
|
||||
// 关联日期(可空)
|
||||
DatePickerField(
|
||||
label = "关联日期",
|
||||
date = state.linkedDate,
|
||||
placeholder = "不关联",
|
||||
onClick = { showLinkedDatePicker = true },
|
||||
onClear = onClearLinkedDate,
|
||||
modifier = Modifier.testTag("record_edit_linked_date")
|
||||
)
|
||||
|
||||
// 保存按钮
|
||||
Button(
|
||||
onClick = onSave,
|
||||
enabled = state.canSave,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag("record_edit_save")
|
||||
// 区域一:基本信息卡片
|
||||
Surface(
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainerLow,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.4f)),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("保存")
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(14.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Edit,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Text(
|
||||
text = "基本信息",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
}
|
||||
|
||||
// 标题输入框
|
||||
OutlinedTextField(
|
||||
value = state.title,
|
||||
onValueChange = onTitleChange,
|
||||
label = { Text("记录标题") },
|
||||
placeholder = { Text("请输入记录标题...") },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Title,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
if (state.title.isNotEmpty()) {
|
||||
IconButton(onClick = { onTitleChange("") }) {
|
||||
Icon(Icons.Filled.Clear, contentDescription = "清除标题")
|
||||
}
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag("record_edit_title")
|
||||
)
|
||||
|
||||
// 备注输入框
|
||||
OutlinedTextField(
|
||||
value = state.note,
|
||||
onValueChange = onNoteChange,
|
||||
label = { Text("记录笔记 / 备注") },
|
||||
placeholder = { Text("记录当天的所思所想、天气或难忘瞬间...") },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Notes,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
minLines = 3,
|
||||
maxLines = 6,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag("record_edit_note")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 区域二:日期设定卡片
|
||||
Surface(
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainerLow,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.4f)),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(14.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.CalendarToday,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
Text(
|
||||
text = "日期设定",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
}
|
||||
|
||||
// 拍摄日期选择条目
|
||||
DatePickerTile(
|
||||
icon = Icons.Outlined.CalendarToday,
|
||||
iconTint = MaterialTheme.colorScheme.primary,
|
||||
label = "拍摄日期",
|
||||
valueText = formatChineseDateWithWeek(state.shootDate),
|
||||
onClick = { showShootDatePicker = true },
|
||||
modifier = Modifier.testTag("record_edit_shoot_date")
|
||||
)
|
||||
|
||||
// 关联日期选择条目
|
||||
val hasLinked = state.linkedDate != null
|
||||
DatePickerTile(
|
||||
icon = if (hasLinked) Icons.Outlined.Bookmark else Icons.Outlined.BookmarkBorder,
|
||||
iconTint = if (hasLinked) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
label = "关联日历",
|
||||
valueText = state.linkedDate?.let { formatChineseDateWithWeek(it) } ?: "独立记录(未关联日历)",
|
||||
onClick = { showLinkedDatePicker = true },
|
||||
onClear = if (hasLinked) onClearLinkedDate else null,
|
||||
modifier = Modifier.testTag("record_edit_linked_date")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
|
||||
if (showShootDatePicker) {
|
||||
@ -256,30 +434,98 @@ private fun RecordEditForm(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 交互式日期选择条目。
|
||||
*
|
||||
* @param icon 图标
|
||||
* @param iconTint 图标色值
|
||||
* @param label 标签名称
|
||||
* @param valueText 值显示文本
|
||||
* @param onClick 点击回调(打开 DatePicker)
|
||||
* @param onClear 清除值回调(可选)
|
||||
* @param modifier 布局修饰符
|
||||
*/
|
||||
@Composable
|
||||
private fun DatePickerField(
|
||||
private fun DatePickerTile(
|
||||
icon: ImageVector,
|
||||
iconTint: Color,
|
||||
label: String,
|
||||
date: LocalDate?,
|
||||
placeholder: String = "",
|
||||
valueText: String,
|
||||
onClick: () -> Unit,
|
||||
onClear: (() -> Unit)? = null,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
OutlinedButton(
|
||||
Surface(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)),
|
||||
modifier = modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = date?.let { formatLocalDate(it) } ?: placeholder,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
if (onClear != null && date != null) {
|
||||
TextButton(onClick = onClear) { Text("清除") }
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
Surface(
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
color = iconTint.copy(alpha = 0.12f),
|
||||
modifier = Modifier.size(36.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = label,
|
||||
tint = iconTint,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp)
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
text = valueText,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
}
|
||||
|
||||
if (onClear != null) {
|
||||
TextButton(onClick = onClear) {
|
||||
Text(
|
||||
text = "清除",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.ChevronRight,
|
||||
contentDescription = "选择日期",
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 原生 Material 3 DatePicker 弹窗。
|
||||
*
|
||||
* @param initialDate 初始选中日期
|
||||
* @param onConfirm 确认选择日期回调
|
||||
* @param onDismiss 关闭弹窗回调
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun DatePickerModal(
|
||||
@ -311,3 +557,16 @@ private fun DatePickerModal(
|
||||
DatePicker(state = datePickerState)
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatChineseDateWithWeek(date: LocalDate): String {
|
||||
val weekStr = when (date.dayOfWeek) {
|
||||
DayOfWeek.MONDAY -> "星期一"
|
||||
DayOfWeek.TUESDAY -> "星期二"
|
||||
DayOfWeek.WEDNESDAY -> "星期三"
|
||||
DayOfWeek.THURSDAY -> "星期四"
|
||||
DayOfWeek.FRIDAY -> "星期五"
|
||||
DayOfWeek.SATURDAY -> "星期六"
|
||||
DayOfWeek.SUNDAY -> "星期日"
|
||||
}
|
||||
return "${date.year}年${date.monthNumber}月${date.dayOfMonth}日 $weekStr"
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ class DateRecordDetailViewModelTest {
|
||||
|
||||
var retries = 0
|
||||
while (!vm.uiState.value.deleted && retries < 50) {
|
||||
kotlinx.coroutines.delay(10)
|
||||
Thread.sleep(20)
|
||||
retries++
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user