mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-30 15:58:51 +02:00
perf: optimize polling, progress caching, staggered warmup, and snapshot-based library scan
- Reduce polling interval from 800ms to 1200ms across download progress, library scan, and Android native stream - Add dirty-flag caching to Go GetMultiProgress() to skip redundant JSON marshaling - Replace eager provider initialization with staggered Timer-based warmup (400/900/1600ms) - Add snapshot-based incremental library scan to avoid large MethodChannel payloads - Move history stats and grouped album filtering to Riverpod providers for better cache invalidation - Cap home tab history preview to 48 items with deep equality wrapper to reduce rebuilds - Throttle foreground service notification updates to 2% progress buckets - Migrate PageView to PageView.builder with AutomaticKeepAliveClientMixin - Add comparison table to README
This commit is contained in:
@@ -38,7 +38,7 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
"com.zarz.spotiflac/download_progress_stream"
|
||||
private val LIBRARY_SCAN_PROGRESS_STREAM_CHANNEL =
|
||||
"com.zarz.spotiflac/library_scan_progress_stream"
|
||||
private val STREAM_POLLING_INTERVAL_MS = 800L
|
||||
private val STREAM_POLLING_INTERVAL_MS = 1200L
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
private var pendingSafTreeResult: MethodChannel.Result? = null
|
||||
private val safScanLock = Any()
|
||||
@@ -469,6 +469,32 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
lastLibraryScanProgressPayload = null
|
||||
}
|
||||
|
||||
private fun loadExistingFilesJsonFromSnapshot(snapshotPath: String): String {
|
||||
if (snapshotPath.isBlank()) {
|
||||
return "{}"
|
||||
}
|
||||
|
||||
val snapshotFile = File(snapshotPath)
|
||||
if (!snapshotFile.exists()) {
|
||||
return "{}"
|
||||
}
|
||||
|
||||
val result = JSONObject()
|
||||
snapshotFile.forEachLine { line ->
|
||||
if (line.isBlank()) return@forEachLine
|
||||
val separatorIndex = line.indexOf('\t')
|
||||
if (separatorIndex <= 0 || separatorIndex >= line.length - 1) {
|
||||
return@forEachLine
|
||||
}
|
||||
val modTime = line.substring(0, separatorIndex).toLongOrNull() ?: 0L
|
||||
val filePath = line.substring(separatorIndex + 1)
|
||||
if (filePath.isNotEmpty()) {
|
||||
result.put(filePath, modTime)
|
||||
}
|
||||
}
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
private fun resolveSafFile(treeUriStr: String, relativeDir: String, fileName: String): String {
|
||||
val obj = JSONObject()
|
||||
if (treeUriStr.isBlank() || fileName.isBlank()) {
|
||||
@@ -3186,6 +3212,18 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"scanLibraryFolderIncrementalFromSnapshot" -> {
|
||||
val folderPath = call.argument<String>("folder_path") ?: ""
|
||||
val snapshotPath = call.argument<String>("snapshot_path") ?: ""
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
safScanActive = false
|
||||
Gobackend.scanLibraryFolderIncrementalFromSnapshotJSON(
|
||||
folderPath,
|
||||
snapshotPath,
|
||||
)
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"scanSafTree" -> {
|
||||
val treeUri = call.argument<String>("tree_uri") ?: ""
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
@@ -3201,6 +3239,16 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"scanSafTreeIncrementalFromSnapshot" -> {
|
||||
val treeUri = call.argument<String>("tree_uri") ?: ""
|
||||
val snapshotPath = call.argument<String>("snapshot_path") ?: ""
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
val existingFilesJson =
|
||||
loadExistingFilesJsonFromSnapshot(snapshotPath)
|
||||
scanSafTreeIncremental(treeUri, existingFilesJson)
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"getSafFileModTimes" -> {
|
||||
val uris = call.argument<String>("uris") ?: "[]"
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
|
||||
Reference in New Issue
Block a user