Utilities Layer
Overview
The Utilities layer in the MS-dTMT application provides essential supporting functionality organized into distinct categories. These utilities handle device detection, UI helpers, storage, networking, and various application-wide services that support the core features of the application.
Key Components
Services
LocalStorageServices
A centralized persistent storage system using Flutter’s SharedPreferences package that handles:
Pending TMT Test Results * Saves test results when offline using
savePendingResultList(List<String>)* Retrieves pending results withgetPendingResultList()* Clears completed results withclearPendingResultList()Theme Settings Management * Stores user theme preferences (dark/light) with
saveThemeSettings(bool, ThemeMode)* Implements system theme following withisFollowSystemflag * Retrieves theme settings with type-safe returns vialoadThemeSettings()User Profile Persistence * Manages current active user with
setCurrentProfileId(String)andgetCurrentProfileId()* Handles user switching and deletion with appropriate cleanup * Provides profile context across app restartsApplication Configuration * Stores TMT test configuration like circle count using
saveCircleNumber(int)* Retrieves configuration with defaults viagetCircleNumber()* Maintains consistent user experience across sessionsStorage Keys * Uses standardized key constants (
_pendingResultsKey,_themeKey, etc.) * Implements safe type conversion and null handling * Ensures data integrity with appropriate storage patterns
The LocalStorageServices class is implemented as a singleton to provide application-wide access while preventing multiple instances:
static final LocalStorageServices _localStorageServices = LocalStorageServices._internal();
factory LocalStorageServices() {
return _localStorageServices;
}
LocalStorageServices._internal();
AppLogger
A centralized logging system that provides:
Named logger instances to categorize logs by component
Multiple logging levels (fine, info, warning, severe, debug)
Debug-mode specific logging functionality
Stack trace and error recording for troubleshooting
Initialization with environment-specific settings
Database Services
Database-related utilities including:
UserDataBaseHelper for managing user profiles and test results
Database migration utilities to handle schema changes
Transaction management for data integrity
Native API Services
Bridges functionality to native platform APIs for device-specific features.
WorkManagerHandler
Manages background tasks for offline operation with:
Task scheduling for pending test results with
scheduleResultsSending()Initialization of the worker system via
initializeWorkManager()Background task management for network operations
Cancellation of pending tasks with
cancelWorkTask()Callback handling through the
callbackDispatcher()function
Network Services
API Error Handling
Implements robust error handling for network requests with:
Error categorization (server, client, authentication, network)
Status code interpretation
Standardized error messages
Error data extraction from various response formats
API Constants
Defines API endpoints, headers, and request configurations.
Result Data
Provides standardized response wrappers for network operations to ensure consistent handling of:
Success responses with proper typing
Error cases with contextual information
Loading/progress states
UI Utilities
AppSnackbar
Implements a custom snackbar with:
Responsive sizing based on device type
Consistent styling and animation
Prevention of multiple overlapping instances
Automatic dismissal with configurable duration
UI Extensions
Provides extensions for UI components to maintain consistent styling.
Bottom Sheet
Implements standardized bottom sheets for consistent presentation of modal content.
Mixins
NavigationMixin
Centralizes navigation logic with methods for:
Screen transitions between TMT test components
User registration and profile flow navigation
Result history access
Practice and test mode selection
Consistent navigation patterns throughout the app
ValidationInputMixin
Provides standardized form validation logic for input components.
App Mixins
Organizes all application mixins for easy access.
Helpers
DeviceHelper
Provides device detection and responsive design support with:
Device type categorization (largeTablet, mediumTablet, smallTablet, largePhone, mediumPhone, smallPhone)
Screen metrics for adaptive layouts
Device orientation handling
Initialization and recalculation functions for screen changes
WidgetMaxWidthCalculator
Calculates optimal component widths based on:
Device type
Screen orientation (portrait/landscape)
Different scaling factors for each device category
This ensures proper content display across the wide range of devices supported by the application.
String and Double Helpers
Simple utilities for common string and numeric operations:
Text formatting and manipulation
Numeric precision control
Type conversion
Type Utilities
Utilities for type checking and conversion operations.
App Helpers
General application utility functions used across different features.
Organization Structure
The utils package is organized into a clear directory structure:
- /services/
Contains utilities for backend and system services like logging, storage, and API access.
- /ui/
Holds UI-related utilities including custom UI components and extensions.
- /mixins/
Contains reusable behavior mixins that can be incorporated into various controllers and widgets.
- /helpers/
Provides utility functions focused on specific tasks like device detection and component sizing.
Persistence Strategy
The application implements a multi-layered persistence strategy:
Transient Settings (SharedPreferences) * Handled by LocalStorageServices for app preferences, theme settings, and active user * Provides quick access to lightweight configuration data * Used for cross-session persistence of UI state and user selections
Structured Data (SQLite) * Managed through UserDatabaseHelper for user profiles and test results * Provides relational data storage with transactions and queries * Supports complex data relationships and integrity constraints
Pending Data Handling * Combines SharedPreferences and WorkManager for offline operation * Stores test results when offline and schedules background sync * Implements automatic retry with exponential backoff
The shared preference implementation ensures critical application state persists across sessions while maintaining a responsive user experience.
Benefits of the Utilities Layer
Cross-Cutting Concerns: Handles functionality that spans multiple features
Consistency: Ensures consistent behavior and appearance throughout the application
Code Reuse: Prevents duplication of common functionality
Maintainability: Centralizes core utilities for easier updates and bug fixes
Abstraction: Shields application features from low-level implementation details
The Utilities layer provides the foundation that enables the application’s features to focus on their core functionality while relying on standardized utilities for common operations. This separation of concerns leads to a more maintainable and scalable codebase.