3.5 KiB
3.5 KiB
Code Style and Conventions
Linting
- Uses
package:flutter_lints/flutter.yaml- Flutter's recommended lint rules - Configuration in
analysis_options.yaml - Run linter:
flutter analyze - All lints must pass before committing
Dart/Flutter Conventions
Naming
- Classes/Enums/Typedefs: PascalCase (e.g.,
OPDSFeed,DatabaseHelper) - Variables/Functions/Parameters: camelCase (e.g.,
fetchFeed,serverId) - Private members: Prefix with underscore (e.g.,
_database,_authService) - Constants: lowerCamelCase for const variables (e.g.,
const defaultTimeout) - Files: snake_case (e.g.,
opds_service.dart,server_list_screen.dart)
Widget Construction
- Use
constconstructors wherever possible for performance - Use
super.keyfor widget keys - Mark widget fields as
final - Prefer
StatelessWidgetoverStatefulWidgetwhen no state is needed - Use trailing commas for better formatting (especially in widget trees)
State Management - Riverpod
- Use riverpod_annotation with code generation for providers
- Provider files should have corresponding
.g.dartfiles - Use
@riverpodannotation for provider functions - Run
flutter pub run build_runner buildto generate provider code - Consume providers using
ref.watch()in widgets (via ConsumerWidget or Consumer) - Use
ref.read()for one-time reads in callbacks
Data Models - Freezed
- All data models use Freezed for immutability
- Include both
.freezed.dartand.g.dartparts - Use
@freezedannotation for models - Define
fromJsonfactory for JSON deserialization - Private constructor pattern:
const ModelName._(); - Run
flutter pub run build_runner buildto generate model code
Database Patterns
- Singleton pattern for DatabaseHelper (
DatabaseHelper.instance) - Table definitions as static constants in table classes
- Use foreign key constraints
- Repository pattern for data access
- All database operations should be async
Service Layer
- Services are injectable via constructor parameters
- Default implementations provided with null coalescing
- Use Dio for HTTP operations with proper error handling
- Parser services are separate from network services
Code Structure
- Imports: Organize as package imports, relative imports, then part files
- Theme: Uses Material 3 (
useMaterial3: true) - Documentation: Use
///for public API documentation comments - Regular comments: Use
//for implementation comments - Debug output: Use
debugPrint()instead ofprint()
Type Annotations
- Prefer explicit types for public APIs and class fields
- Type inference acceptable for local variables when obvious
- Always specify return types for functions and methods
Error Handling
- Use try-catch for async operations that may fail
- Provide meaningful error messages
- Handle HTTP errors appropriately
- Log errors with
debugPrint()for debugging
Authentication
- Credentials stored encrypted in SQLite
- Authentication handled via AuthService
- Dio clients created per-server with auth configuration
File Organization
- Group related functionality in directories (screens, services, models, etc.)
- Keep widget files focused on single widgets or screens
- Extract reusable widgets to
lib/widgets/ - Screen-specific widgets can go in
screens/<feature>/widgets/
Code Generation
Run code generation after modifying:
- Models with
@freezedannotation - Providers with
@riverpodannotation - Models with
@JsonSerializableannotation
Command: flutter pub run build_runner build --delete-conflicting-outputs