11package com.xayah.feature.main.restore
22
3- import java.io.File
4- import android.util.Log
53import androidx.compose.animation.ExperimentalAnimationApi
4+ import androidx.compose.foundation.ExperimentalFoundationApi
65import androidx.compose.foundation.layout.Arrangement
76import androidx.compose.foundation.layout.Column
87import androidx.compose.foundation.layout.Row
@@ -14,9 +13,13 @@ import androidx.compose.foundation.layout.padding
1413import androidx.compose.foundation.layout.size
1514import androidx.compose.foundation.lazy.LazyColumn
1615import androidx.compose.foundation.lazy.items
16+ import androidx.compose.material.icons.Icons
17+ import androidx.compose.material.icons.outlined.Description
18+ import androidx.compose.material3.Button
1719import androidx.compose.material3.CircularProgressIndicator
1820import androidx.compose.material3.ExperimentalMaterial3Api
1921import androidx.compose.material3.HorizontalDivider
22+ import androidx.compose.material3.Icon
2023import androidx.compose.material3.LinearProgressIndicator
2124import androidx.compose.material3.MaterialTheme
2225import androidx.compose.material3.Text
@@ -25,47 +28,34 @@ import androidx.compose.material3.rememberTopAppBarState
2528import androidx.compose.runtime.Composable
2629import androidx.compose.runtime.LaunchedEffect
2730import androidx.compose.runtime.getValue
31+ import androidx.compose.runtime.rememberCoroutineScope
2832import androidx.compose.ui.Alignment
2933import androidx.compose.ui.Modifier
3034import androidx.compose.ui.text.style.TextOverflow
3135import androidx.compose.ui.unit.dp
32- import androidx.compose.foundation.ExperimentalFoundationApi
33- import androidx.compose.foundation.rememberScrollState
34- import androidx.compose.foundation.verticalScroll
3536import androidx.hilt.navigation.compose.hiltViewModel
3637import androidx.lifecycle.compose.collectAsStateWithLifecycle
3738import androidx.navigation.NavController
38- import androidx.compose.foundation.layout.IntrinsicSize
39- import androidx.compose.ui.platform.LocalContext
39+ import com.xayah.core.model.File
4040import com.xayah.core.ui.component.BodyMediumText
41+ import com.xayah.core.ui.component.Title
4142import com.xayah.core.ui.component.TitleLargeText
42- import com.xayah.core.ui.route.MainRoutes
4343import com.xayah.core.ui.theme.ThemedColorSchemeKeyTokens
4444import com.xayah.core.ui.theme.value
4545import com.xayah.core.ui.token.SizeTokens
46- import com.xayah.core.util.DateUtil
47- import com.xayah.core.util.navigateSingle
48- import com.xayah.core.model.database.MediaEntity
49- import com.xayah.core.ui.component.ProgressButton
50- import com.xayah.core.ui.component.Title
51- import androidx.compose.runtime.rememberCoroutineScope
5246import kotlinx.coroutines.launch
53- import kotlinx.serialization.encodeToString
54- import kotlinx.serialization.json.Json
55- import java.net.URLEncoder
56- import androidx.compose.material.icons.Icons
57- import androidx.compose.material.icons.outlined.Description
5847
5948@OptIn(ExperimentalMaterial3Api ::class , ExperimentalFoundationApi ::class , ExperimentalAnimationApi ::class )
6049@Composable
6150fun ResticMediaBackupDetailPage (
6251 navController : NavController ,
63- selectedFiles : List <MediaEntity >,
52+ selectedFiles : List <File >,
6453 viewModel : ResticMediaBackupViewModel = hiltViewModel()
6554) {
6655 val uiState by viewModel.uiState.collectAsStateWithLifecycle()
6756 val coroutineScope = rememberCoroutineScope()
6857
58+ // 初始进入页面时启动备份
6959 LaunchedEffect (Unit ) {
7060 viewModel.startDirectBackup(selectedFiles)
7161 }
@@ -74,86 +64,80 @@ fun ResticMediaBackupDetailPage(
7464 scrollBehavior = TopAppBarDefaults .exitUntilCollapsedScrollBehavior(rememberTopAppBarState()),
7565 title = " 文件Restic备份"
7666 ) {
77- Column (
67+ // 使用单一 LazyColumn 替代嵌套滚动
68+ LazyColumn (
7869 modifier = Modifier
7970 .fillMaxSize()
80- .padding(SizeTokens .Level16 )
81- .verticalScroll(rememberScrollState() )
71+ .padding(horizontal = SizeTokens .Level16 ),
72+ verticalArrangement = Arrangement .spacedBy( SizeTokens . Level8 )
8273 ) {
83- // 显示选中的文件列表
84- Title (title = " 备份文件列表" ) {
85- LazyColumn (
86- modifier = Modifier .fillMaxWidth(),
87- verticalArrangement = Arrangement .spacedBy(SizeTokens .Level8 )
74+ // 列表头部:间隔和标题
75+ item {
76+ Spacer (modifier = Modifier .height(SizeTokens .Level16 ))
77+ TitleLargeText (text = " 备份文件列表" )
78+ Spacer (modifier = Modifier .height(SizeTokens .Level8 ))
79+ }
80+
81+ // 文件列表内容
82+ items(selectedFiles) { file ->
83+ Row (
84+ modifier = Modifier
85+ .fillMaxWidth()
86+ .padding(vertical = SizeTokens .Level8 ),
87+ verticalAlignment = Alignment .CenterVertically ,
88+ horizontalArrangement = Arrangement .spacedBy(SizeTokens .Level12 )
8889 ) {
89- items(selectedFiles) { file ->
90- Row (
91- modifier = Modifier
92- .fillMaxWidth()
93- .padding(SizeTokens .Level8 ),
94- verticalAlignment = Alignment .CenterVertically ,
95- horizontalArrangement = Arrangement .spacedBy(SizeTokens .Level12 )
96- ) {
97- androidx.compose.material3.Icon (
98- imageVector = Icons .Outlined .Description ,
99- contentDescription = null ,
100- modifier = Modifier .size(32 .dp),
101- tint = ThemedColorSchemeKeyTokens .Primary .value
102- )
90+ Icon (
91+ imageVector = Icons .Outlined .Description ,
92+ contentDescription = null ,
93+ modifier = Modifier .size(32 .dp),
94+ tint = ThemedColorSchemeKeyTokens .Primary .value
95+ )
10396
104- Column (
105- modifier = Modifier .weight(1f )
106- ) {
107- TitleLargeText (
108- text = file.name,
109- maxLines = 1 ,
110- overflow = TextOverflow .Ellipsis
111- )
112- BodyMediumText (
113- text = file.path,
114- color = ThemedColorSchemeKeyTokens .Outline .value,
115- maxLines = 2 ,
116- overflow = TextOverflow .Ellipsis
117- )
118- }
119- }
120- HorizontalDivider ()
97+ Column (modifier = Modifier .weight(1f )) {
98+ TitleLargeText (
99+ text = file.name,
100+ maxLines = 1 ,
101+ overflow = TextOverflow .Ellipsis
102+ )
103+ BodyMediumText (
104+ text = file.path,
105+ color = ThemedColorSchemeKeyTokens .Outline .value,
106+ maxLines = 2 ,
107+ overflow = TextOverflow .Ellipsis
108+ )
121109 }
122110 }
111+ HorizontalDivider (modifier = Modifier .padding(vertical = 4 .dp))
123112 }
124113
125- Spacer (modifier = Modifier .height(SizeTokens .Level24 ))
114+ // 列表尾部:备份状态显示
115+ item {
116+ Spacer (modifier = Modifier .height(SizeTokens .Level16 ))
126117
127- // 备份进度显示
128- when ( val state = uiState) {
129- is BackupUiState . Loading -> {
130- Column (
131- modifier = Modifier .fillMaxWidth() ,
132- horizontalAlignment = Alignment . CenterHorizontally ,
133- verticalArrangement = Arrangement .spacedBy( SizeTokens . Level16 )
134- ) {
135- CircularProgressIndicator ( )
136- Text ( " 正在准备备份... " )
118+ when ( val state = uiState) {
119+ is BackupUiState . Loading -> {
120+ Column (
121+ modifier = Modifier .fillMaxWidth().padding(vertical = SizeTokens . Level24 ),
122+ horizontalAlignment = Alignment . CenterHorizontally ,
123+ verticalArrangement = Arrangement .spacedBy( SizeTokens . Level16 )
124+ ) {
125+ CircularProgressIndicator ()
126+ Text ( " 正在准备备份... " )
127+ }
137128 }
138- }
139129
140- is BackupUiState .Progress -> {
141- Column (
142- modifier = Modifier .fillMaxWidth(),
143- verticalArrangement = Arrangement .spacedBy(SizeTokens .Level16 )
144- ) {
130+ is BackupUiState .Progress -> {
145131 Title (title = " 备份进度" ) {
146- Column {
132+ Column (verticalArrangement = Arrangement .spacedBy( SizeTokens . Level8 )) {
147133 Text (
148134 text = " 当前文件: ${state.currentFileName} " ,
149135 style = MaterialTheme .typography.bodyMedium
150136 )
151- Spacer (modifier = Modifier .height(SizeTokens .Level8 ))
152137 LinearProgressIndicator (
153- progress = state.progress,
138+ progress = { state.progress } ,
154139 modifier = Modifier .fillMaxWidth()
155140 )
156- Spacer (modifier = Modifier .height(SizeTokens .Level8 ))
157141 Row (
158142 modifier = Modifier .fillMaxWidth(),
159143 horizontalArrangement = Arrangement .SpaceBetween
@@ -170,15 +154,10 @@ fun ResticMediaBackupDetailPage(
170154 }
171155 }
172156 }
173- }
174157
175- is BackupUiState .Success -> {
176- Column (
177- modifier = Modifier .fillMaxWidth(),
178- verticalArrangement = Arrangement .spacedBy(SizeTokens .Level16 )
179- ) {
158+ is BackupUiState .Success -> {
180159 Title (title = " 备份完成" ) {
181- Column {
160+ Column (verticalArrangement = Arrangement .spacedBy( SizeTokens . Level4 )) {
182161 Text (
183162 text = " 成功备份 ${state.results.size} 个文件" ,
184163 style = MaterialTheme .typography.bodyMedium
@@ -190,47 +169,40 @@ fun ResticMediaBackupDetailPage(
190169 color = ThemedColorSchemeKeyTokens .Primary .value
191170 )
192171 }
172+ Spacer (modifier = Modifier .height(SizeTokens .Level16 ))
173+ Button (
174+ onClick = { navController.popBackStack() },
175+ modifier = Modifier .fillMaxWidth()
176+ ) {
177+ Text (" 返回" )
178+ }
193179 }
194180 }
195-
196- // 返回按钮
197- androidx.compose.material3.Button (
198- onClick = {
199- navController.popBackStack()
200- },
201- modifier = Modifier .fillMaxWidth()
202- ) {
203- Text (" 返回" )
204- }
205181 }
206- }
207182
208- is BackupUiState .Error -> {
209- Column (
210- modifier = Modifier .fillMaxWidth(),
211- verticalArrangement = Arrangement .spacedBy(SizeTokens .Level16 )
212- ) {
183+ is BackupUiState .Error -> {
213184 Title (title = " 备份失败" ) {
214- Text (
215- text = state.message,
216- style = MaterialTheme .typography.bodyMedium,
217- color = MaterialTheme .colorScheme.error
218- )
219- }
220-
221- // 重试按钮
222- androidx.compose.material3.Button (
223- onClick = {
224- coroutineScope.launch {
225- viewModel.startDirectBackup(selectedFiles)
185+ Column (verticalArrangement = Arrangement .spacedBy(SizeTokens .Level16 )) {
186+ Text (
187+ text = state.message,
188+ style = MaterialTheme .typography.bodyMedium,
189+ color = MaterialTheme .colorScheme.error
190+ )
191+ Button (
192+ onClick = {
193+ coroutineScope.launch {
194+ viewModel.startDirectBackup(selectedFiles)
195+ }
196+ },
197+ modifier = Modifier .fillMaxWidth()
198+ ) {
199+ Text (" 重试" )
226200 }
227- },
228- modifier = Modifier .fillMaxWidth()
229- ) {
230- Text (" 重试" )
201+ }
231202 }
232203 }
233204 }
205+ Spacer (modifier = Modifier .height(SizeTokens .Level32 ))
234206 }
235207 }
236208 }
0 commit comments