156 lines
5.5 KiB
Dart
156 lines
5.5 KiB
Dart
import 'dart:convert';
|
|
import 'dart:math';
|
|
import 'package:flutter/services.dart';
|
|
|
|
/// Enum representing different encouragement message types
|
|
enum EncouragementType {
|
|
general, // General encouragement messages
|
|
start, // When starting a focus session
|
|
distraction, // When user gets distracted
|
|
complete, // When completing a focus session
|
|
earlyStop, // When stopping early
|
|
}
|
|
|
|
/// Service to manage encouragement messages for different scenarios
|
|
class EncouragementService {
|
|
// Map of encouragement types to their messages
|
|
final Map<EncouragementType, List<String>> _messages = {
|
|
EncouragementType.general: [],
|
|
EncouragementType.start: [],
|
|
EncouragementType.distraction: [],
|
|
EncouragementType.complete: [],
|
|
EncouragementType.earlyStop: [],
|
|
};
|
|
|
|
final Random _random = Random();
|
|
|
|
/// Load encouragement messages from assets
|
|
Future<void> loadMessages() async {
|
|
try {
|
|
final String jsonString =
|
|
await rootBundle.loadString('assets/encouragements.json');
|
|
final dynamic jsonData = json.decode(jsonString);
|
|
|
|
// Check if the JSON is a map (new format with categories)
|
|
if (jsonData is Map<String, dynamic>) {
|
|
// Load categorized messages
|
|
_loadCategorizedMessages(jsonData);
|
|
} else if (jsonData is List<dynamic>) {
|
|
// Load legacy format (list of general messages)
|
|
_messages[EncouragementType.general] = jsonData.cast<String>();
|
|
// Initialize other categories with default messages
|
|
_initializeDefaultMessages();
|
|
} else {
|
|
// Invalid format, use defaults
|
|
_initializeDefaultMessages();
|
|
}
|
|
} catch (e) {
|
|
// Fallback to default messages if file can't be loaded
|
|
_initializeDefaultMessages();
|
|
}
|
|
}
|
|
|
|
/// Load categorized messages from JSON map
|
|
void _loadCategorizedMessages(Map<String, dynamic> jsonData) {
|
|
// Load general messages
|
|
if (jsonData.containsKey('general') && jsonData['general'] is List) {
|
|
_messages[EncouragementType.general] = (jsonData['general'] as List).cast<String>();
|
|
}
|
|
|
|
// Load start messages
|
|
if (jsonData.containsKey('start') && jsonData['start'] is List) {
|
|
_messages[EncouragementType.start] = (jsonData['start'] as List).cast<String>();
|
|
}
|
|
|
|
// Load distraction messages
|
|
if (jsonData.containsKey('distraction') && jsonData['distraction'] is List) {
|
|
_messages[EncouragementType.distraction] = (jsonData['distraction'] as List).cast<String>();
|
|
}
|
|
|
|
// Load complete messages
|
|
if (jsonData.containsKey('complete') && jsonData['complete'] is List) {
|
|
_messages[EncouragementType.complete] = (jsonData['complete'] as List).cast<String>();
|
|
}
|
|
|
|
// Load early stop messages
|
|
if (jsonData.containsKey('earlyStop') && jsonData['earlyStop'] is List) {
|
|
_messages[EncouragementType.earlyStop] = (jsonData['earlyStop'] as List).cast<String>();
|
|
}
|
|
|
|
// Ensure all categories have at least some messages
|
|
_ensureAllCategoriesHaveMessages();
|
|
}
|
|
|
|
/// Initialize default messages for all categories
|
|
void _initializeDefaultMessages() {
|
|
_messages[EncouragementType.general] = [
|
|
"Showing up is half the battle.",
|
|
"Every minute counts.",
|
|
"You're learning, not failing.",
|
|
"Gentleness is strength.",
|
|
"Progress over perfection.",
|
|
];
|
|
|
|
_messages[EncouragementType.start] = [
|
|
"You've got this! Let's begin.",
|
|
"Ready to focus? Let's do this.",
|
|
"Every moment is a fresh start.",
|
|
"Let's make this session count.",
|
|
"You're already making progress by showing up.",
|
|
];
|
|
|
|
_messages[EncouragementType.distraction] = [
|
|
"It's okay to get distracted. Let's gently come back.",
|
|
"No guilt here! Let's try again.",
|
|
"Distractions happen to everyone. Let's refocus.",
|
|
"You're doing great by noticing and coming back.",
|
|
"Gentle reminder: you can always start again.",
|
|
];
|
|
|
|
_messages[EncouragementType.complete] = [
|
|
"🎉 Congratulations! You did it!",
|
|
"Great job completing your focus session!",
|
|
"You should be proud of yourself!",
|
|
"That was amazing! Well done.",
|
|
"You're making wonderful progress!",
|
|
];
|
|
|
|
_messages[EncouragementType.earlyStop] = [
|
|
"It's okay to stop early. You tried, and that's what matters.",
|
|
"Every effort counts, even if it's shorter than planned.",
|
|
"You did your best, and that's enough.",
|
|
"Rest when you need to. We'll be here when you're ready.",
|
|
"Progress, not perfection. You're doing great.",
|
|
];
|
|
}
|
|
|
|
/// Ensure all categories have at least some messages
|
|
void _ensureAllCategoriesHaveMessages() {
|
|
// If any category is empty, use general messages as fallback
|
|
for (final type in EncouragementType.values) {
|
|
if (_messages[type]?.isEmpty ?? true) {
|
|
_messages[type] = List.from(_messages[EncouragementType.general]!);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get a random encouragement message for a specific type
|
|
String getRandomMessage([EncouragementType type = EncouragementType.general]) {
|
|
final messages = _messages[type] ?? [];
|
|
if (messages.isEmpty) {
|
|
return "You're doing great!";
|
|
}
|
|
return messages[_random.nextInt(messages.length)];
|
|
}
|
|
|
|
/// Get all messages for a specific type (for testing)
|
|
List<String> getAllMessages([EncouragementType type = EncouragementType.general]) {
|
|
return List.from(_messages[type] ?? []);
|
|
}
|
|
|
|
/// Get all messages for all types (for testing)
|
|
Map<EncouragementType, List<String>> getAllMessagesByType() {
|
|
return Map.from(_messages);
|
|
}
|
|
}
|