init cc
This commit is contained in:
137
lib/core/utils/extensions.dart
Normal file
137
lib/core/utils/extensions.dart
Normal file
@@ -0,0 +1,137 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Extensions for BuildContext
|
||||
extension BuildContextExtensions on BuildContext {
|
||||
/// Get the current theme
|
||||
ThemeData get theme => Theme.of(this);
|
||||
|
||||
/// Get the color scheme
|
||||
ColorScheme get colorScheme => theme.colorScheme;
|
||||
|
||||
/// Get text theme
|
||||
TextTheme get textTheme => theme.textTheme;
|
||||
|
||||
/// Get media query
|
||||
MediaQueryData get mediaQuery => MediaQuery.of(this);
|
||||
|
||||
/// Get screen size
|
||||
Size get screenSize => mediaQuery.size;
|
||||
|
||||
/// Get screen width
|
||||
double get screenWidth => screenSize.width;
|
||||
|
||||
/// Get screen height
|
||||
double get screenHeight => screenSize.height;
|
||||
|
||||
/// Check if device is in dark mode
|
||||
bool get isDarkMode => theme.brightness == Brightness.dark;
|
||||
|
||||
/// Show snackbar
|
||||
void showSnackBar(String message, {bool isError = false}) {
|
||||
ScaffoldMessenger.of(this).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
backgroundColor: isError ? colorScheme.error : null,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Hide keyboard
|
||||
void hideKeyboard() {
|
||||
FocusScope.of(this).unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensions for String
|
||||
extension StringExtensions on String {
|
||||
/// Check if string is email
|
||||
bool get isValidEmail {
|
||||
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
|
||||
}
|
||||
|
||||
/// Check if string is empty or null
|
||||
bool get isEmptyOrNull {
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
/// Check if string is not empty and not null
|
||||
bool get isNotEmptyAndNotNull {
|
||||
return isNotEmpty;
|
||||
}
|
||||
|
||||
/// Capitalize first letter
|
||||
String get capitalize {
|
||||
if (isEmpty) return this;
|
||||
return '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
|
||||
}
|
||||
|
||||
/// Title case
|
||||
String get titleCase {
|
||||
return split(' ').map((word) => word.capitalize).join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensions for DateTime
|
||||
extension DateTimeExtensions on DateTime {
|
||||
/// Check if date is today
|
||||
bool get isToday {
|
||||
final now = DateTime.now();
|
||||
return day == now.day && month == now.month && year == now.year;
|
||||
}
|
||||
|
||||
/// Check if date is yesterday
|
||||
bool get isYesterday {
|
||||
final yesterday = DateTime.now().subtract(const Duration(days: 1));
|
||||
return day == yesterday.day && month == yesterday.month && year == yesterday.year;
|
||||
}
|
||||
|
||||
/// Check if date is tomorrow
|
||||
bool get isTomorrow {
|
||||
final tomorrow = DateTime.now().add(const Duration(days: 1));
|
||||
return day == tomorrow.day && month == tomorrow.month && year == tomorrow.year;
|
||||
}
|
||||
|
||||
/// Get time ago string
|
||||
String get timeAgo {
|
||||
final now = DateTime.now();
|
||||
final difference = now.difference(this);
|
||||
|
||||
if (difference.inDays > 365) {
|
||||
return '${(difference.inDays / 365).floor()} year${(difference.inDays / 365).floor() == 1 ? '' : 's'} ago';
|
||||
} else if (difference.inDays > 30) {
|
||||
return '${(difference.inDays / 30).floor()} month${(difference.inDays / 30).floor() == 1 ? '' : 's'} ago';
|
||||
} else if (difference.inDays > 0) {
|
||||
return '${difference.inDays} day${difference.inDays == 1 ? '' : 's'} ago';
|
||||
} else if (difference.inHours > 0) {
|
||||
return '${difference.inHours} hour${difference.inHours == 1 ? '' : 's'} ago';
|
||||
} else if (difference.inMinutes > 0) {
|
||||
return '${difference.inMinutes} minute${difference.inMinutes == 1 ? '' : 's'} ago';
|
||||
} else {
|
||||
return 'Just now';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extensions for List
|
||||
extension ListExtensions<T> on List<T> {
|
||||
/// Check if list is empty or null
|
||||
bool get isEmptyOrNull {
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
/// Check if list is not empty and not null
|
||||
bool get isNotEmptyAndNotNull {
|
||||
return isNotEmpty;
|
||||
}
|
||||
|
||||
/// Get first element or null
|
||||
T? get firstOrNull {
|
||||
return isEmpty ? null : first;
|
||||
}
|
||||
|
||||
/// Get last element or null
|
||||
T? get lastOrNull {
|
||||
return isEmpty ? null : last;
|
||||
}
|
||||
}
|
||||
16
lib/core/utils/typedef.dart
Normal file
16
lib/core/utils/typedef.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import '../errors/failures.dart';
|
||||
|
||||
/// Common type definitions used throughout the application
|
||||
|
||||
/// Result type for operations that can fail
|
||||
typedef Result<T> = Either<Failure, T>;
|
||||
|
||||
/// Async result type
|
||||
typedef AsyncResult<T> = Future<Result<T>>;
|
||||
|
||||
/// Data map type for JSON serialization
|
||||
typedef DataMap = Map<String, dynamic>;
|
||||
|
||||
/// Data list type for JSON serialization
|
||||
typedef DataList = List<DataMap>;
|
||||
3
lib/core/utils/utils.dart
Normal file
3
lib/core/utils/utils.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
// Barrel export file for utilities
|
||||
export 'extensions.dart';
|
||||
export 'typedef.dart';
|
||||
Reference in New Issue
Block a user