feat: fix sync counters, polished activity rows, Files tab, new icon
- Fix SYNC_COMPLETED showing ↑0 ↓0 ✗0 when only deletions occurred: add ✕N for deleted files to the summary message (↑N ↓N ✕N ✗N format) - Fix PairDetail Activity section showing raw "SYNC_STARTED" enum names and "remote" as a plain subtitle: replace dot-based EventRow with the same polished icon-bubble rows as the global Log tab - Extract shared SyncEventRow composable + iconAndTint/label helpers to ui/shared/SyncEventRow.kt; both LogScreen and PairDetailScreen now use it - Add Files tab (4th tab between Log and Accounts): folder browser showing all synced files per pair, grouped by subdirectory, with file-type icons, size, last-synced date, and a summary header (N files, total size) - Add SyncFileStateDao.observeForPair() reactive Flow query for Files tab - Completely redesign app icon: near-black radial gradient background with three bold directional arrows in an S-pattern (coral → silver → teal), each with gradient fills and tip-glow dots — entirely different from the typical circular sync-arrow style - Bump version to 1.0.22 (build 23) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,16 +6,15 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material.icons.outlined.Circle
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.syncflow.domain.model.SyncEventType
|
||||
import com.syncflow.ui.shared.iconAndTint
|
||||
import com.syncflow.ui.shared.label
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
@@ -143,31 +142,6 @@ private fun LogEntryRow(entry: LogEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SyncEventType.iconAndTint(): Pair<ImageVector, Color> = when (this) {
|
||||
SyncEventType.SYNC_STARTED -> Icons.Default.Sync to MaterialTheme.colorScheme.secondary
|
||||
SyncEventType.SYNC_COMPLETED -> Icons.Default.CheckCircle to MaterialTheme.colorScheme.primary
|
||||
SyncEventType.SYNC_FAILED -> Icons.Default.Error to MaterialTheme.colorScheme.error
|
||||
SyncEventType.FILE_UPLOADED -> Icons.Default.CloudUpload to MaterialTheme.colorScheme.secondary
|
||||
SyncEventType.FILE_DOWNLOADED -> Icons.Default.CloudDownload to MaterialTheme.colorScheme.secondary
|
||||
SyncEventType.FILE_DELETED -> Icons.Default.DeleteForever to MaterialTheme.colorScheme.tertiary
|
||||
SyncEventType.FILE_SKIPPED -> Icons.Outlined.Circle to MaterialTheme.colorScheme.onSurfaceVariant
|
||||
SyncEventType.CONFLICT_DETECTED -> Icons.Default.Warning to MaterialTheme.colorScheme.tertiary
|
||||
SyncEventType.CONFLICT_RESOLVED -> Icons.Default.CheckCircle to MaterialTheme.colorScheme.primary
|
||||
}
|
||||
|
||||
private fun SyncEventType.label(): String = when (this) {
|
||||
SyncEventType.SYNC_STARTED -> "Sync started"
|
||||
SyncEventType.SYNC_COMPLETED -> "Sync completed"
|
||||
SyncEventType.SYNC_FAILED -> "Sync failed"
|
||||
SyncEventType.FILE_UPLOADED -> "File uploaded"
|
||||
SyncEventType.FILE_DOWNLOADED -> "File downloaded"
|
||||
SyncEventType.FILE_DELETED -> "File deleted"
|
||||
SyncEventType.FILE_SKIPPED -> "File skipped"
|
||||
SyncEventType.CONFLICT_DETECTED -> "Conflict detected"
|
||||
SyncEventType.CONFLICT_RESOLVED -> "Conflict resolved"
|
||||
}
|
||||
|
||||
private fun java.time.LocalDate.toRelativeLabel(): String {
|
||||
val today = java.time.LocalDate.now()
|
||||
return when {
|
||||
|
||||
Reference in New Issue
Block a user