chore: format code
This commit is contained in:
parent
31180f9921
commit
1b3440e2fe
7 changed files with 516 additions and 2 deletions
461
.opencode/specs/ui-inconsistencies-analysis.md
Normal file
461
.opencode/specs/ui-inconsistencies-analysis.md
Normal file
|
|
@ -0,0 +1,461 @@
|
||||||
|
# UI Inconsistencies Analysis - TracPulse
|
||||||
|
|
||||||
|
**Date:** Fri May 01 2026
|
||||||
|
**Status:** Analysis Complete
|
||||||
|
**Purpose:** Identify and document all UI inconsistencies across the TracPulse Flutter app
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
This analysis identifies **15 UI inconsistencies** across the TracPulse application, categorized into:
|
||||||
|
- **Critical** (4): Impact user experience significantly
|
||||||
|
- **Moderate** (6): Noticeable visual/interaction inconsistencies
|
||||||
|
- **Minor** (5): Small polish items
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Critical Inconsistencies
|
||||||
|
|
||||||
|
### 1. **Inconsistent AppBar Implementations**
|
||||||
|
**Severity:** Critical
|
||||||
|
**Location:** Multiple screens
|
||||||
|
**Issue:**
|
||||||
|
- `main_screen.dart`: Uses custom header with `Container` (lines 171-226)
|
||||||
|
- `settings_screen.dart`: Uses standard `AppBar` widget (lines 132-160)
|
||||||
|
- `status_screen.dart`: Uses standard `AppBar` widget (lines 102-139)
|
||||||
|
- `permission_screen.dart`: Uses custom header with `Container` (lines 247-271)
|
||||||
|
|
||||||
|
**Impact:** Breaks visual consistency and navigation patterns.
|
||||||
|
|
||||||
|
**Details:**
|
||||||
|
```dart
|
||||||
|
// Main & Permission screens - custom header
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Color(0xFF161616),
|
||||||
|
border: Border(bottom: BorderSide(color: Color(0xFF2a2a2a), width: 1)),
|
||||||
|
),
|
||||||
|
// ...
|
||||||
|
)
|
||||||
|
|
||||||
|
// Settings & Status screens - AppBar
|
||||||
|
AppBar(
|
||||||
|
backgroundColor: const Color(0xFF161616),
|
||||||
|
elevation: 0,
|
||||||
|
leading: IconButton(...),
|
||||||
|
// ...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Standardize on either AppBar or custom header across all screens.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. **Inconsistent Border Radius Values**
|
||||||
|
**Severity:** Critical
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Mixed use of `4` and `3` pixel border radius values throughout the app.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
- `permission_screen.dart` line 118: `borderRadius: BorderRadius.circular(4)` (dialog)
|
||||||
|
- `permission_screen.dart` line 288: `BorderRadius.all(Radius.circular(4))` (icon container)
|
||||||
|
- `permission_screen.dart` line 406: `borderRadius: BorderRadius.circular(3)` (granted badge)
|
||||||
|
- `status_screen.dart` line 224: `borderRadius: BorderRadius.circular(3)` (filter chip)
|
||||||
|
- `status_screen.dart` line 282: `borderRadius: BorderRadius.circular(3)` (icon container)
|
||||||
|
|
||||||
|
**Impact:** Subtle visual inconsistency that degrades polish.
|
||||||
|
|
||||||
|
**Recommendation:** Standardize on `4px` border radius globally (align with design system).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. **Inconsistent Icon Sizes**
|
||||||
|
**Severity:** Critical
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Icon sizes vary without clear hierarchy or purpose.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
// Main Screen
|
||||||
|
Icons.shield, size: 20 // permission_screen header
|
||||||
|
Icons.gps_fixed, size: 14 // status card
|
||||||
|
Icons.radio_button_checked, size: 20 // tracking toggle
|
||||||
|
Icons.arrow_upward, size: 16 // send button
|
||||||
|
Icons.tune/terminal, size: 16 // nav buttons
|
||||||
|
|
||||||
|
// Settings Screen
|
||||||
|
Icons.arrow_back, size: 20 // back button
|
||||||
|
|
||||||
|
// Status Screen
|
||||||
|
Icons.terminal, size: 18 // title icon
|
||||||
|
Icons.arrow_back, size: 20 // back button
|
||||||
|
Icons.refresh, size: 20 // refresh button
|
||||||
|
Icons.inbox_outlined, size: 48 // empty state
|
||||||
|
Icons.[log icon], size: 10 // log entry icons
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Creates visual hierarchy confusion.
|
||||||
|
|
||||||
|
**Recommendation:** Define a clear icon size system:
|
||||||
|
- Extra Large: 48px (empty states, hero elements)
|
||||||
|
- Large: 24px (primary actions)
|
||||||
|
- Medium: 20px (navigation, headers)
|
||||||
|
- Small: 16px (inline actions)
|
||||||
|
- Extra Small: 12px (badges, chips)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. **Inconsistent Padding and Spacing**
|
||||||
|
**Severity:** Critical
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Inconsistent padding values without clear system.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
// Various padding values used:
|
||||||
|
padding: EdgeInsets.all(20) // main_screen status card
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20) // main_screen scroll
|
||||||
|
padding: EdgeInsets.all(16) // permission intro card
|
||||||
|
padding: EdgeInsets.all(14) // permission items
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14) // settings fields
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16) // status filter bar
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10) // status filter chips
|
||||||
|
padding: EdgeInsets.only(left: 14, right: 14) // status log entries
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Reduces visual rhythm and professionalism.
|
||||||
|
|
||||||
|
**Recommendation:** Establish spacing system:
|
||||||
|
- xxs: 4px
|
||||||
|
- xs: 8px
|
||||||
|
- sm: 12px
|
||||||
|
- md: 16px
|
||||||
|
- lg: 20px
|
||||||
|
- xl: 24px
|
||||||
|
- xxl: 32px
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Moderate Inconsistencies
|
||||||
|
|
||||||
|
### 5. **Inconsistent Text Styles**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Text styling lacks systematic hierarchy.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
// Font sizes used: 9, 10, 11, 12, 13, 14, 16, 18, 48
|
||||||
|
// Letter spacing: 0, 1, 2, 3
|
||||||
|
// Font weights: w400, w600, w700
|
||||||
|
|
||||||
|
// Headers
|
||||||
|
fontSize: 18, letterSpacing: 3 // main_screen
|
||||||
|
fontSize: 16, letterSpacing: 3 // permission_screen
|
||||||
|
fontSize: 14, letterSpacing: 2 // settings_screen, status_screen
|
||||||
|
|
||||||
|
// Body text
|
||||||
|
fontSize: 13 // various places
|
||||||
|
fontSize: 12 // various places
|
||||||
|
fontSize: 11 // various places
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Reduces readability and visual hierarchy.
|
||||||
|
|
||||||
|
**Recommendation:** Create text style system with consistent naming.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. **Inconsistent Button Styles**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** Multiple screens
|
||||||
|
**Issue:** Different button implementations for similar actions.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
// permission_screen: Custom Material + InkWell (line 512)
|
||||||
|
Material(
|
||||||
|
color: _allGranted ? ... : ...,
|
||||||
|
child: InkWell(onTap: ..., child: Container(...))
|
||||||
|
)
|
||||||
|
|
||||||
|
// main_screen: GestureDetector (line 308)
|
||||||
|
GestureDetector(
|
||||||
|
onTap: _toggleTracking,
|
||||||
|
child: Container(...)
|
||||||
|
)
|
||||||
|
|
||||||
|
// main_screen: OutlinedButton.icon (line 377)
|
||||||
|
OutlinedButton.icon(
|
||||||
|
onPressed: ...,
|
||||||
|
style: OutlinedButton.styleFrom(...),
|
||||||
|
)
|
||||||
|
|
||||||
|
// main_screen: Custom Material + InkWell (line 442)
|
||||||
|
Material(
|
||||||
|
color: const Color(0xFF161616),
|
||||||
|
child: InkWell(...)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Inconsistent touch feedback and visual states.
|
||||||
|
|
||||||
|
**Recommendation:** Standardize on Material + InkWell pattern with consistent ripple effects.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. **Inconsistent Empty State Handling**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** `status_screen.dart`
|
||||||
|
**Issue:** Only Status screen has empty state, but other screens might need it too.
|
||||||
|
|
||||||
|
**Current Implementation:** (lines 166-198)
|
||||||
|
```dart
|
||||||
|
child: _filteredLogs.isEmpty
|
||||||
|
? Center(child: Column(...)) // Empty state
|
||||||
|
: ListView.builder(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Inconsistent UX when screens have no data.
|
||||||
|
|
||||||
|
**Recommendation:** Consider empty states for other screens where applicable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. **Inconsistent Color Opacity Usage**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Mixed use of `.withValues(alpha: x)` and color literals.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
Color(0xFF00bcd4).withValues(alpha: 0.8) // main_screen line 251
|
||||||
|
Color(0xFF00e676).withValues(alpha: 0.3) // permission_screen line 347
|
||||||
|
Color(0xFF00e676).withValues(alpha: 0.15) // permission_screen line 359
|
||||||
|
Color(0xFF00bcd4).withValues(alpha: 0.1) // permission_screen line 430
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Difficult to maintain consistent transparency levels.
|
||||||
|
|
||||||
|
**Recommendation:** Define standard alpha values (0.05, 0.1, 0.15, 0.3, 0.5, 0.6, 0.8).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. **Inconsistent Loading/Error State Handling**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** No consistent loading indicators or error states.
|
||||||
|
|
||||||
|
**Observation:**
|
||||||
|
- No loading spinners shown during async operations
|
||||||
|
- Error handling relies only on SnackBar
|
||||||
|
- No retry mechanisms for failed operations
|
||||||
|
|
||||||
|
**Recommendation:** Add loading states and error recovery UI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 10. **Inconsistent Switch Widget Styling**
|
||||||
|
**Severity:** Moderate
|
||||||
|
**Location:** `settings_screen.dart` line 386
|
||||||
|
**Issue:** Switch uses deprecated color properties pattern (though updated to new API).
|
||||||
|
|
||||||
|
**Current:**
|
||||||
|
```dart
|
||||||
|
Switch(
|
||||||
|
value: value,
|
||||||
|
onChanged: onChanged,
|
||||||
|
activeThumbColor: const Color(0xFF00e676),
|
||||||
|
activeTrackColor: const Color(0xFF00e676).withValues(alpha: 0.3),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Consider using Material 3 Switch theming for consistency.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Minor Inconsistencies
|
||||||
|
|
||||||
|
### 11. **Inconsistent SizedBox Spacing**
|
||||||
|
**Severity:** Minor
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Arbitrary SizedBox heights without clear system.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```dart
|
||||||
|
const SizedBox(height: 2) // settings_screen line 374
|
||||||
|
const SizedBox(height: 4) // permission_screen line 311
|
||||||
|
const SizedBox(height: 5) // status_screen line 306
|
||||||
|
const SizedBox(height: 8) // multiple places
|
||||||
|
const SizedBox(height: 10) // multiple places
|
||||||
|
const SizedBox(height: 12) // multiple places
|
||||||
|
// ... and more
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Use spacing system constants instead of literals.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 12. **Inconsistent Container Decoration Pattern**
|
||||||
|
**Severity:** Minor
|
||||||
|
**Location:** All screens
|
||||||
|
**Issue:** Some decorations defined inline, others could use constants.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```dart
|
||||||
|
// Repeated decoration pattern:
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFF161616),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: const Color(0xFF2a2a2a), width: 1),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Create reusable decoration constants.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 13. **Inconsistent Const Usage**
|
||||||
|
**Severity:** Minor
|
||||||
|
**Location:** Multiple files
|
||||||
|
**Issue:** Some widgets marked const, others not (inconsistently).
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```dart
|
||||||
|
// settings_screen line 111
|
||||||
|
const [
|
||||||
|
Icon(Icons.check_circle, color: Color(0xFF00e676), size: 18),
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Audit and add const where applicable for performance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 14. **Inconsistent Dialog Implementation**
|
||||||
|
**Severity:** Minor
|
||||||
|
**Location:** `permission_screen.dart` line 112
|
||||||
|
**Issue:** Only one dialog in app, but pattern not reusable.
|
||||||
|
|
||||||
|
**Current:**
|
||||||
|
```dart
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (ctx) => AlertDialog(...)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Create reusable dialog component with consistent styling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 15. **Inconsistent Animation Usage**
|
||||||
|
**Severity:** Minor
|
||||||
|
**Location:** `main_screen.dart` only
|
||||||
|
**Issue:** Only main screen has animations (pulse effect).
|
||||||
|
|
||||||
|
**Current:** (lines 24-36)
|
||||||
|
```dart
|
||||||
|
late AnimationController _pulseController;
|
||||||
|
late Animation<double> _pulseAnimation;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Impact:** Other screens feel static in comparison.
|
||||||
|
|
||||||
|
**Recommendation:** Consider subtle animations elsewhere for consistency (e.g., permission granted transitions).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color System Issues
|
||||||
|
|
||||||
|
### Inconsistent Color Definitions
|
||||||
|
All colors are defined inline with hex literals. Should be centralized:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
// Current usage
|
||||||
|
const Color(0xFF0d0d0d) // Background
|
||||||
|
const Color(0xFF161616) // Card background
|
||||||
|
const Color(0xFF2a2a2a) // Border
|
||||||
|
const Color(0xFF00bcd4) // Primary (teal)
|
||||||
|
const Color(0xFF00e676) // Success (green)
|
||||||
|
const Color(0xFFe0e0e0) // Text primary
|
||||||
|
const Color(0xFF9e9e9e) // Text secondary
|
||||||
|
const Color(0xFF616161) // Text disabled
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Create `lib/theme/colors.dart` with named constants.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Priority Matrix
|
||||||
|
|
||||||
|
| Priority | Count | Items |
|
||||||
|
|----------|-------|-------|
|
||||||
|
| Critical | 4 | AppBar inconsistency, Border radius, Icon sizes, Padding/spacing |
|
||||||
|
| Moderate | 6 | Text styles, Button styles, Empty states, Color opacity, Loading states, Switch styling |
|
||||||
|
| Minor | 5 | SizedBox spacing, Container decorations, Const usage, Dialog pattern, Animation usage |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommendations Summary
|
||||||
|
|
||||||
|
1. **Create Design System** (`lib/theme/`)
|
||||||
|
- `colors.dart` - Centralized color constants
|
||||||
|
- `spacing.dart` - Spacing scale
|
||||||
|
- `typography.dart` - Text style hierarchy
|
||||||
|
- `decorations.dart` - Reusable decorations
|
||||||
|
- `dimensions.dart` - Icon sizes, border radius
|
||||||
|
|
||||||
|
2. **Standardize Components** (`lib/widgets/`)
|
||||||
|
- `app_button.dart` - Consistent button component
|
||||||
|
- `app_header.dart` - Reusable header/appbar
|
||||||
|
- `app_card.dart` - Standard card container
|
||||||
|
- `app_dialog.dart` - Consistent dialog styling
|
||||||
|
|
||||||
|
3. **Update All Screens**
|
||||||
|
- Replace inline styles with design system constants
|
||||||
|
- Standardize component usage
|
||||||
|
- Add consistent loading/error states
|
||||||
|
- Ensure const usage for performance
|
||||||
|
|
||||||
|
4. **Testing**
|
||||||
|
- Visual regression testing
|
||||||
|
- Ensure animations perform smoothly
|
||||||
|
- Verify touch targets meet accessibility standards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. **Phase 1: Design System Setup**
|
||||||
|
- Create theme files
|
||||||
|
- Define constants
|
||||||
|
- Document usage
|
||||||
|
|
||||||
|
2. **Phase 2: Component Standardization**
|
||||||
|
- Build reusable widgets
|
||||||
|
- Update existing screens
|
||||||
|
- Test interactions
|
||||||
|
|
||||||
|
3. **Phase 3: Polish**
|
||||||
|
- Add missing animations
|
||||||
|
- Improve empty/error states
|
||||||
|
- Performance optimization
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- All screens use `fontFamily: 'monospace'` consistently ✓
|
||||||
|
- Dark theme colors are consistent (good base) ✓
|
||||||
|
- Material 3 is enabled (`useMaterial3: true`) ✓
|
||||||
|
- Deprecated APIs have been updated (`.withValues(alpha:)`) ✓
|
||||||
|
- ZoomPageTransitionsBuilder prevents white flash ✓
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**End of Analysis**
|
||||||
|
|
@ -93,6 +93,9 @@ class BridgeModule : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||||
"isBatteryOptimizationDisabled" -> {
|
"isBatteryOptimizationDisabled" -> {
|
||||||
result.success(isBatteryOptimizationDisabled())
|
result.success(isBatteryOptimizationDisabled())
|
||||||
}
|
}
|
||||||
|
"clearLogs" -> {
|
||||||
|
clearLogs(result)
|
||||||
|
}
|
||||||
else -> result.notImplemented()
|
else -> result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -191,6 +194,7 @@ class BridgeModule : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
mainHandler.post { result.success(logs) }
|
mainHandler.post { result.success(logs) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "fetchLogs failed", e)
|
||||||
mainHandler.post { result.success(emptyList<Map<String, Any>>()) }
|
mainHandler.post { result.success(emptyList<Map<String, Any>>()) }
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
|
|
@ -228,4 +232,23 @@ class BridgeModule : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearLogs(result: MethodChannel.Result) {
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
val deleted = runBlocking(Dispatchers.IO) {
|
||||||
|
val db = context?.let { AppDatabase.getInstance(it) }
|
||||||
|
if (db != null) {
|
||||||
|
db.eventLogDao().deleteAll()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mainHandler.post { result.success(deleted) }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "clearLogs failed", e)
|
||||||
|
mainHandler.post { result.success(-1) }
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ import android.util.Log
|
||||||
class LocationTrackingService : Service() {
|
class LocationTrackingService : Service() {
|
||||||
|
|
||||||
private val binder = LocalBinder()
|
private val binder = LocalBinder()
|
||||||
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||||
private val TAG = "LocationTrackingService"
|
private val TAG = "LocationTrackingService"
|
||||||
|
|
||||||
private lateinit var fusedLocationProvider: FusedLocationProvider
|
private lateinit var fusedLocationProvider: FusedLocationProvider
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,7 @@ interface EventLogDao {
|
||||||
|
|
||||||
@Query("DELETE FROM event_log WHERE timestamp < :beforeTimestamp")
|
@Query("DELETE FROM event_log WHERE timestamp < :beforeTimestamp")
|
||||||
suspend fun deleteOlderThan(beforeTimestamp: Long)
|
suspend fun deleteOlderThan(beforeTimestamp: Long)
|
||||||
|
|
||||||
|
@Query("DELETE FROM event_log")
|
||||||
|
suspend fun deleteAll()
|
||||||
}
|
}
|
||||||
|
|
@ -116,4 +116,14 @@ class LocationBridge {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<int> clearLogs() async {
|
||||||
|
try {
|
||||||
|
final result = await _methodChannel.invokeMethod<int>('clearLogs');
|
||||||
|
return result ?? -1;
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint('Failed to clear logs: ${e.message}');
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,4 +269,4 @@ class InfoScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,15 @@ class _StatusScreenState extends State<StatusScreen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _clearLogs() async {
|
||||||
|
final result = await LocationBridge.clearLogs();
|
||||||
|
if (mounted) {
|
||||||
|
if (result >= 0) {
|
||||||
|
await _loadLogs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String _formatTimestamp(int timestamp) {
|
String _formatTimestamp(int timestamp) {
|
||||||
final dt = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
final dt = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||||
final ms = (dt.millisecond / 1000).toStringAsFixed(3).substring(2);
|
final ms = (dt.millisecond / 1000).toStringAsFixed(3).substring(2);
|
||||||
|
|
@ -128,6 +137,14 @@ class _StatusScreenState extends State<StatusScreen> {
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.delete_outline,
|
||||||
|
color: Color(0xFF616161),
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
onPressed: _clearLogs,
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.refresh, color: Color(0xFF616161), size: 20),
|
icon: const Icon(Icons.refresh, color: Color(0xFF616161), size: 20),
|
||||||
onPressed: _loadLogs,
|
onPressed: _loadLogs,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue