Skip to content

Commit aef9090

Browse files
author
Fastace
committed
BUG:目前AppsRepo.kt 代码实现正确,但构建仍然失败。问题在于 KAPT 仍然无法处理这个类。待修复
1 parent b8e9d40 commit aef9090

4 files changed

Lines changed: 103 additions & 43 deletions

File tree

source/core/data/src/main/kotlin/com/xayah/core/data/repository/AppsRepo.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.xayah.core.data.repository
22

33
import android.content.Context
44
import android.content.Intent
5+
import android.util.Log
56
import android.content.pm.ApplicationInfo
67
import android.content.pm.LauncherApps
78
import android.content.pm.PackageManager
@@ -83,6 +84,9 @@ class AppsRepo @Inject constructor(
8384
private val pathUtil: PathUtil,
8485
private val cloudRepo: CloudRepository
8586
) {
87+
companion object {
88+
private const val TAG = "AppsRepo"
89+
}
8690
// 内部创建 ResticRepository 实例
8791
private val resticRepo: ResticRepository by lazy {
8892
val logger = ResticLogger(Dispatchers.IO)
@@ -782,6 +786,28 @@ class AppsRepo @Inject constructor(
782786
}
783787
}.withLog()
784788

789+
// 在 AppsRepo 中添加快照详情加载方法
790+
suspend fun loadSnapshotDetail(packageEntity: PackageEntity): ResticSnapshot? {
791+
return packageEntity.resticSnapshotIds.firstOrNull()?.let { snapshotId ->
792+
packageEntity.resticRepoPath?.let { repoPath ->
793+
val password = context.readResticPassword()
794+
if (password.isNullOrEmpty()) {
795+
Log.e(TAG, "Restic password is null or empty")
796+
return@let null
797+
}
798+
799+
val snapshots = resticRepo.listSnapshots(repoPath, password)
800+
snapshots.find { it.id == snapshotId }
801+
}
802+
}
803+
}
804+
805+
// 添加应用更新方法(如果 DetailsViewModel 需要)
806+
suspend fun refreshAppMetadata(app: PackageEntity) {
807+
updateApp(app, app.userId)
808+
calculateLocalAppSize(app)
809+
}
810+
785811
suspend fun calculateLocalAppSize(app: PackageEntity) {
786812
app.displayStats.apkBytes = calculateLocalAppDataSize(app, DataType.PACKAGE_APK)
787813
app.displayStats.userBytes = calculateLocalAppDataSize(app, DataType.PACKAGE_USER)

source/core/data/src/main/kotlin/com/xayah/core/data/repository/FilesRepo.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.xayah.core.data.repository
22

33
import android.content.Context
4+
import android.util.Log
45
import com.xayah.core.network.client.S3ClientImpl
56
import com.xayah.core.database.dao.MediaDao
67
import com.xayah.core.datastore.ConstantUtil
@@ -50,6 +51,9 @@ class FilesRepo @Inject constructor(
5051
private val rootService: RemoteRootService,
5152
private val cloudRepo: CloudRepository
5253
) {
54+
companion object {
55+
private const val TAG = "FilesRepo"
56+
}
5357
// 内部创建 ResticRepository 实例
5458
private val resticRepo: ResticRepository by lazy {
5559
val logger = ResticLogger(Dispatchers.IO)
@@ -370,6 +374,21 @@ class FilesRepo @Inject constructor(
370374
}
371375
}.withLog()
372376

377+
suspend fun loadSnapshotDetail(mediaEntity: MediaEntity): ResticSnapshot? {
378+
return mediaEntity.extraInfo.resticSnapshotId?.let { snapshotId ->
379+
mediaEntity.extraInfo.resticRepoPath?.let { repoPath ->
380+
val password = context.readResticPassword()
381+
if (password.isNullOrEmpty()) {
382+
Log.e(TAG, "Restic password is null or empty")
383+
return@let null
384+
}
385+
386+
val snapshots = resticRepo.listSnapshots(repoPath, password)
387+
snapshots.find { it.id == snapshotId }
388+
}
389+
}
390+
}
391+
373392
private fun renameDuplicateFile(name: String): String {
374393
val nameList = name.split("_").toMutableList()
375394
val index = nameList.first().toIntOrNull()

source/feature/main/details/src/main/kotlin/com/xayah/feature/main/details/DetailsViewModel.kt

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package com.xayah.feature.main.details
22

33
import android.content.Context
44
import android.content.pm.PackageManager
5-
import android.widget.Toast
65
import android.util.Log
6+
import android.widget.Toast
77
import androidx.lifecycle.SavedStateHandle
88
import androidx.lifecycle.ViewModel
99
import androidx.lifecycle.viewModelScope
10+
// ⭐ 修正:保留所需的 Repository 和工具类
11+
import com.xayah.core.data.R // 假设资源 R.string.failed 在此模块
1012
import com.xayah.core.data.repository.AppsRepo
1113
import com.xayah.core.data.repository.FilesRepo
1214
import com.xayah.core.data.repository.LabelsRepo
@@ -19,19 +21,13 @@ import com.xayah.core.model.database.LabelFileCrossRefEntity
1921
import com.xayah.core.model.database.MediaEntity
2022
import com.xayah.core.model.database.PackageDataStates
2123
import com.xayah.core.model.database.PackageEntity
24+
import com.xayah.core.restic.ResticSnapshot
2225
import com.xayah.core.rootservice.service.RemoteRootService
2326
import com.xayah.core.ui.route.MainRoutes
2427
import com.xayah.core.util.decodeURL
2528
import com.xayah.core.util.LogUtil
26-
import com.xayah.core.util.module.combine
2729
import com.xayah.core.util.launchOnDefault
2830
import com.xayah.core.util.withMainContext
29-
import com.xayah.core.restic.ResticRepository
30-
import com.xayah.core.restic.ResticSnapshot
31-
import com.xayah.core.datastore.readResticPassword
32-
import com.xayah.feature.main.details.DetailsUiState.Error
33-
import com.xayah.feature.main.details.DetailsUiState.Loading
34-
import com.xayah.feature.main.details.DetailsUiState.Success
3531
import dagger.hilt.android.lifecycle.HiltViewModel
3632
import dagger.hilt.android.qualifiers.ApplicationContext
3733
import kotlinx.coroutines.flow.MutableStateFlow
@@ -51,15 +47,12 @@ class DetailsViewModel @Inject constructor(
5147
private val rootService: RemoteRootService,
5248
private val appsRepo: AppsRepo,
5349
private val filesRepo: FilesRepo,
54-
private val labelsRepo: LabelsRepo,
55-
private val resticRepo: ResticRepository,
50+
private val labelsRepo: LabelsRepo
5651
) : ViewModel() {
5752
private val id: Long = savedStateHandle.get<String>(MainRoutes.ARG_ID)?.toLongOrNull() ?: 0L
5853
private val target: Target = Target.valueOf(savedStateHandle.get<String>(MainRoutes.ARG_TARGET)!!.decodeURL().trim())
5954
private val isRefreshing: MutableStateFlow<Boolean> = MutableStateFlow(false)
60-
// 添加 isProtecting 状态
6155
private val isProtecting: MutableStateFlow<Boolean> = MutableStateFlow(false)
62-
// 添加 protectProgress 状态
6356
private val protectProgress: MutableStateFlow<String?> = MutableStateFlow(null)
6457

6558
companion object {
@@ -78,7 +71,7 @@ class DetailsViewModel @Inject constructor(
7871
appsRepo.getApp(id),
7972
isRefreshing,
8073
isProtecting,
81-
protectProgress, // 添加这个
74+
protectProgress,
8275
labelsRepo.getLabelsFlow(),
8376
labelsRepo.getAppRefsFlow()
8477
) { app, isRefreshing, isProtecting, protectProgress, labels, refs ->
@@ -87,7 +80,7 @@ class DetailsViewModel @Inject constructor(
8780
uuid = UUID.randomUUID(),
8881
isRefreshing = isRefreshing,
8982
isProtecting = isProtecting,
90-
protectProgress = protectProgress, // 添加这个
83+
protectProgress = protectProgress,
9184
labels = labels,
9285
app = app,
9386
refs = refs.filter { ref ->
@@ -108,7 +101,7 @@ class DetailsViewModel @Inject constructor(
108101
filesRepo.getFile(id),
109102
isRefreshing,
110103
isProtecting,
111-
protectProgress, // 添加这个
104+
protectProgress,
112105
labelsRepo.getLabelsFlow(),
113106
labelsRepo.getFileRefsFlow()
114107
) { file, isRefreshing, isProtecting, protectProgress, labels, refs ->
@@ -117,7 +110,7 @@ class DetailsViewModel @Inject constructor(
117110
uuid = UUID.randomUUID(),
118111
isRefreshing = isRefreshing,
119112
isProtecting = isProtecting,
120-
protectProgress = protectProgress, // 添加这个
113+
protectProgress = protectProgress,
121114
labels = labels,
122115
file = file,
123116
refs = refs.filter { ref ->
@@ -287,7 +280,7 @@ class DetailsViewModel @Inject constructor(
287280

288281
fun protect() {
289282
viewModelScope.launchOnDefault {
290-
log { "protect() started" } // 1. 方法开始
283+
log { "protect() started" }
291284
isProtecting.emit(true)
292285
protectProgress.emit(null)
293286
try {
@@ -312,26 +305,26 @@ class DetailsViewModel @Inject constructor(
312305
else -> {
313306
val state = uiState.value.castTo<Success.File>()
314307
val file = state.file
315-
log { "Protecting file: ${file.name}, cloud: ${file.indexInfo.cloud}" } // 3. File 分支开始
316-
log { "Calling filesRepo.protectFile with progress callback" } // 4. 调用前
308+
log { "Protecting file: ${file.name}, cloud: ${file.indexInfo.cloud}" }
309+
log { "Calling filesRepo.protectFile with progress callback" }
317310

318311
filesRepo.protectFile(file.indexInfo.cloud, file) { currentPart, totalParts, currentFile, totalFiles ->
319-
log { "Progress callback received in ViewModel: Part $currentPart/$totalParts, File $currentFile/$totalFiles" } // 5. 回调被触发
312+
log { "Progress callback received in ViewModel: Part $currentPart/$totalParts, File $currentFile/$totalFiles" }
320313
viewModelScope.launch {
321314
protectProgress.emit("$currentPart/$totalParts")
322-
log { "protectProgress updated to: $currentPart/$totalParts" } // 6. 状态更新后
315+
log { "protectProgress updated to: $currentPart/$totalParts" }
323316
}
324317
}
325-
log { "filesRepo.protectFile completed" } // 7. 调用完成
318+
log { "filesRepo.protectFile completed" }
326319
}
327320
}
328321
} catch (e: Exception) {
329-
log { "protect() failed with exception: ${e.message}" } // 8. 异常捕获
322+
log { "protect() failed with exception: ${e.message}" }
330323
} finally {
331-
log { "protect() finally block - cleaning up" } // 9. 清理前
324+
log { "protect() finally block - cleaning up" }
332325
isProtecting.emit(false)
333326
protectProgress.emit(null)
334-
log { "protect() completed" } // 10. 方法结束
327+
log { "protect() completed" }
335328
}
336329
}
337330
}
@@ -340,27 +333,25 @@ class DetailsViewModel @Inject constructor(
340333
private val _snapshotDetailState = MutableStateFlow<ResticSnapshot?>(null)
341334
val snapshotDetailState: StateFlow<ResticSnapshot?> = _snapshotDetailState.asStateFlow()
342335

343-
// 获取快照详情
344-
fun loadSnapshotDetail(packageEntity: PackageEntity) {
336+
// 获取快照详情 - 使用扩展的 Repository 方法
337+
// 修改快照详情加载方法
338+
fun loadSnapshotDetail(entity: Any) {
345339
viewModelScope.launch {
346-
packageEntity.resticSnapshotId?.let { snapshotId ->
347-
packageEntity.resticRepoPath?.let { repoPath ->
348-
val password = context.readResticPassword()
349-
// 检查密码是否为空
350-
if (password.isNullOrEmpty()) {
351-
Log.e(TAG, "Restic password is null or empty")
352-
return@launch
340+
when (entity) {
341+
is PackageEntity -> {
342+
appsRepo.loadSnapshotDetail(entity)?.let { snapshot ->
343+
_snapshotDetailState.value = snapshot
344+
}
345+
}
346+
is MediaEntity -> {
347+
filesRepo.loadSnapshotDetail(entity)?.let { snapshot ->
348+
_snapshotDetailState.value = snapshot
353349
}
354-
355-
val snapshots = resticRepo.listSnapshots(repoPath, password)
356-
val snapshot = snapshots.find { it.id == snapshotId }
357-
_snapshotDetailState.value = snapshot
358350
}
359351
}
360352
}
361353
}
362354

363-
// 修复:将 delete() 方法移到类内部
364355
fun delete() {
365356
viewModelScope.launchOnDefault {
366357
when (uiState.value) {
@@ -400,14 +391,14 @@ sealed interface DetailsUiState {
400391
open val uuid: UUID,
401392
open val isRefreshing: Boolean,
402393
open val isProtecting: Boolean,
403-
open val protectProgress: String?, // 添加这个字段
394+
open val protectProgress: String?,
404395
open val labels: List<LabelEntity>,
405396
) : DetailsUiState {
406397
data class App(
407398
override val uuid: UUID,
408399
override val isRefreshing: Boolean,
409400
override val isProtecting: Boolean,
410-
override val protectProgress: String?, // 添加这个字段
401+
override val protectProgress: String?,
411402
override val labels: List<LabelEntity>,
412403
val app: PackageEntity,
413404
val refs: List<LabelAppCrossRefEntity>,
@@ -417,7 +408,7 @@ sealed interface DetailsUiState {
417408
override val uuid: UUID,
418409
override val isRefreshing: Boolean,
419410
override val isProtecting: Boolean,
420-
override val protectProgress: String?, // 添加这个字段
411+
override val protectProgress: String?,
421412
override val labels: List<LabelEntity>,
422413
val file: MediaEntity,
423414
val refs: List<LabelFileCrossRefEntity>,

source/feature/main/restore/src/main/kotlin/com/xayah/feature/main/restore/IndexViewModel.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ import com.xayah.core.util.encodeURL
2525
import com.xayah.core.util.encodedURLWithSpace
2626
import com.xayah.core.util.localBackupSaveDir
2727
import com.xayah.core.util.navigateSingle
28+
import com.xayah.core.data.repository.AppsRepo
29+
import com.xayah.core.data.repository.FilesRepo
30+
import com.xayah.core.database.dao.PackageDao
31+
import com.xayah.core.service.rootservice.service.RemoteRootService
32+
import com.xayah.core.data.repository.SettingsDataRepo
33+
import com.xayah.core.util.PathUtil
34+
import kotlinx.coroutines.Dispatchers
2835
import dagger.hilt.android.lifecycle.HiltViewModel
2936
import dagger.hilt.android.qualifiers.ApplicationContext
3037
import kotlinx.coroutines.flow.Flow
@@ -58,7 +65,11 @@ class IndexViewModel @Inject constructor(
5865
private val pkgRepo: PackageRepository,
5966
private val mediaRepo: MediaRepository,
6067
private val cloudRepo: CloudRepository,
61-
private val appsRepo: AppsRepo,
68+
private val appsDao: PackageDao,
69+
private val packageRepo: PackageRepository,
70+
private val rootService: RemoteRootService,
71+
private val settingsDataRepo: SettingsDataRepo,
72+
private val pathUtil: PathUtil,
6273
) : BaseViewModel<IndexUiState, IndexUiIntent, IndexUiEffect>(
6374
IndexUiState(
6475
storageIndex = 0,
@@ -70,6 +81,19 @@ class IndexViewModel @Inject constructor(
7081
mediumSize = "",
7182
)
7283
) {
84+
private val appsRepo: AppsRepo by lazy {
85+
AppsRepo(
86+
context = context,
87+
defaultDispatcher = Dispatchers.IO,
88+
appsDao = appsDao,
89+
packageRepo = packageRepo,
90+
rootService = rootService,
91+
settingsDataRepo = settingsDataRepo,
92+
pathUtil = pathUtil,
93+
cloudRepo = cloudRepo
94+
)
95+
}
96+
7397
override suspend fun onEvent(state: IndexUiState, intent: IndexUiIntent) {
7498
when (intent) {
7599
is IndexUiIntent.UpdateApps -> {

0 commit comments

Comments
 (0)