tracpulse/.opencode/specs/ui-inconsistencies-analysis.md
2026-05-04 08:28:05 +07:00

13 KiB

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:

// 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:

// 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:

// 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:

// 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:

// 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)

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:

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:

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:

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:

// 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:

// 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:

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)

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:

// 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