This commit is contained in:
ytc1012
2025-11-26 16:32:47 +08:00
parent 96658339e1
commit 0195cdf54b
18 changed files with 1052 additions and 240 deletions

View File

@@ -1,62 +1,135 @@
import 'package:hive_flutter/hive_flutter.dart';
import 'package:flutter/foundation.dart';
import '../models/focus_session.dart';
/// Service to manage local storage using Hive
class StorageService {
static const String _focusSessionBox = 'focus_sessions';
// Cache for today's sessions to improve performance
List<FocusSession>? _todaySessionsCache;
DateTime? _cacheDate;
/// Initialize Hive
static Future<void> init() async {
await Hive.initFlutter();
/// Initialize Hive storage service
///
/// This method initializes Hive, registers adapters, and opens the focus sessions box.
/// It should be called once during app initialization.
Future<void> init() async {
try {
await Hive.initFlutter();
// Register adapters
Hive.registerAdapter(FocusSessionAdapter());
// Register adapters
Hive.registerAdapter(FocusSessionAdapter());
// Open boxes
await Hive.openBox<FocusSession>(_focusSessionBox);
// Open boxes
await Hive.openBox<FocusSession>(_focusSessionBox);
if (kDebugMode) {
print('StorageService initialized successfully');
}
} catch (e) {
if (kDebugMode) {
print('Failed to initialize StorageService: $e');
}
rethrow;
}
}
/// Get the focus sessions box
Box<FocusSession> get _sessionsBox => Hive.box<FocusSession>(_focusSessionBox);
/// Invalidate the cache when data changes
void _invalidateCache() {
_todaySessionsCache = null;
_cacheDate = null;
}
/// Save a focus session
/// Save a focus session to local storage
///
/// [session] - The focus session to save
/// Returns a Future that completes when the session is saved
Future<void> saveFocusSession(FocusSession session) async {
await _sessionsBox.add(session);
try {
await _sessionsBox.add(session);
_invalidateCache(); // Invalidate cache when data changes
} catch (e) {
if (kDebugMode) {
print('Failed to save focus session: $e');
}
rethrow;
}
}
/// Get all focus sessions
/// Get all focus sessions from local storage
///
/// Returns a list of all focus sessions stored locally
List<FocusSession> getAllSessions() {
return _sessionsBox.values.toList();
try {
return _sessionsBox.values.toList();
} catch (e) {
if (kDebugMode) {
print('Failed to get all sessions: $e');
}
return [];
}
}
/// Get today's focus sessions
/// Get today's focus sessions with caching
///
/// Returns a list of focus sessions that occurred today
/// Uses caching to improve performance for frequent calls
List<FocusSession> getTodaySessions() {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
try {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
return _sessionsBox.values.where((session) {
final sessionDate = DateTime(
session.startTime.year,
session.startTime.month,
session.startTime.day,
);
return sessionDate == today;
}).toList();
// Check if cache is valid
if (_todaySessionsCache != null && _cacheDate == today) {
return _todaySessionsCache!;
}
// Query and cache results
final sessions = _sessionsBox.values.where((session) {
final sessionDate = DateTime(
session.startTime.year,
session.startTime.month,
session.startTime.day,
);
return sessionDate == today;
}).toList();
// Update cache
_todaySessionsCache = sessions;
_cacheDate = today;
return sessions;
} catch (e) {
if (kDebugMode) {
print('Failed to get today\'s sessions: $e');
}
return [];
}
}
/// Get total focus minutes for today
///
/// Returns the sum of actual minutes focused today
int getTodayTotalMinutes() {
return getTodaySessions()
.fold<int>(0, (sum, session) => sum + session.actualMinutes);
}
/// Get total distractions for today
///
/// Returns the total number of distractions recorded today
int getTodayDistractionCount() {
return getTodaySessions()
.fold<int>(0, (sum, session) => sum + session.distractionCount);
}
/// Get total completed sessions for today
///
/// Returns the number of focus sessions completed today
int getTodayCompletedCount() {
return getTodaySessions()
.where((session) => session.completed)
@@ -64,22 +137,54 @@ class StorageService {
}
/// Get total sessions count for today (including stopped early)
///
/// Returns the total number of focus sessions started today
int getTodaySessionsCount() {
return getTodaySessions().length;
}
/// Delete a focus session
/// Delete a focus session from local storage
///
/// [session] - The focus session to delete
/// Returns a Future that completes when the session is deleted
Future<void> deleteSession(FocusSession session) async {
await session.delete();
try {
await session.delete();
_invalidateCache(); // Invalidate cache when data changes
} catch (e) {
if (kDebugMode) {
print('Failed to delete focus session: $e');
}
rethrow;
}
}
/// Clear all sessions (for testing/debugging)
/// Clear all sessions from local storage (for testing/debugging)
///
/// Returns a Future that completes when all sessions are cleared
Future<void> clearAllSessions() async {
await _sessionsBox.clear();
try {
await _sessionsBox.clear();
_invalidateCache(); // Invalidate cache when data changes
} catch (e) {
if (kDebugMode) {
print('Failed to clear all sessions: $e');
}
rethrow;
}
}
/// Close all boxes
/// Close all Hive boxes
///
/// Should be called when the app is closing to properly clean up resources
static Future<void> close() async {
await Hive.close();
try {
await Hive.close();
} catch (e) {
if (kDebugMode) {
print('Failed to close Hive boxes: $e');
}
rethrow;
}
}
}