191 lines
5.9 KiB
Dart
191 lines
5.9 KiB
Dart
/// Achievement types for tracking progress
|
|
enum AchievementType {
|
|
sessionCount, // Total number of completed sessions
|
|
distractionCount, // Total number of recorded distractions
|
|
totalMinutes, // Total minutes of focus time
|
|
consecutiveDays, // Consecutive check-in days
|
|
}
|
|
|
|
/// Configuration for a single achievement
|
|
class AchievementConfig {
|
|
final String id;
|
|
final String nameKey; // Localization key for name
|
|
final String descKey; // Localization key for description
|
|
final String icon; // Emoji icon
|
|
final AchievementType type;
|
|
final int requiredValue;
|
|
final int bonusPoints; // Points awarded when unlocked
|
|
|
|
const AchievementConfig({
|
|
required this.id,
|
|
required this.nameKey,
|
|
required this.descKey,
|
|
required this.icon,
|
|
required this.type,
|
|
required this.requiredValue,
|
|
required this.bonusPoints,
|
|
});
|
|
|
|
/// All available achievements in the app
|
|
static List<AchievementConfig> get all => [
|
|
// First session
|
|
const AchievementConfig(
|
|
id: 'first_session',
|
|
nameKey: 'achievement_first_session_name',
|
|
descKey: 'achievement_first_session_desc',
|
|
icon: '🎖️',
|
|
type: AchievementType.sessionCount,
|
|
requiredValue: 1,
|
|
bonusPoints: 10,
|
|
),
|
|
|
|
// Session milestones
|
|
const AchievementConfig(
|
|
id: 'sessions_10',
|
|
nameKey: 'achievement_sessions_10_name',
|
|
descKey: 'achievement_sessions_10_desc',
|
|
icon: '⭐',
|
|
type: AchievementType.sessionCount,
|
|
requiredValue: 10,
|
|
bonusPoints: 50,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'sessions_50',
|
|
nameKey: 'achievement_sessions_50_name',
|
|
descKey: 'achievement_sessions_50_desc',
|
|
icon: '🌟',
|
|
type: AchievementType.sessionCount,
|
|
requiredValue: 50,
|
|
bonusPoints: 200,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'sessions_100',
|
|
nameKey: 'achievement_sessions_100_name',
|
|
descKey: 'achievement_sessions_100_desc',
|
|
icon: '💫',
|
|
type: AchievementType.sessionCount,
|
|
requiredValue: 100,
|
|
bonusPoints: 500,
|
|
),
|
|
|
|
// Honesty tracking series (KEY INNOVATION)
|
|
const AchievementConfig(
|
|
id: 'honest_bronze',
|
|
nameKey: 'achievement_honest_bronze_name',
|
|
descKey: 'achievement_honest_bronze_desc',
|
|
icon: '🧠',
|
|
type: AchievementType.distractionCount,
|
|
requiredValue: 50,
|
|
bonusPoints: 50,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'honest_silver',
|
|
nameKey: 'achievement_honest_silver_name',
|
|
descKey: 'achievement_honest_silver_desc',
|
|
icon: '🧠',
|
|
type: AchievementType.distractionCount,
|
|
requiredValue: 200,
|
|
bonusPoints: 100,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'honest_gold',
|
|
nameKey: 'achievement_honest_gold_name',
|
|
descKey: 'achievement_honest_gold_desc',
|
|
icon: '🧠',
|
|
type: AchievementType.distractionCount,
|
|
requiredValue: 500,
|
|
bonusPoints: 300,
|
|
),
|
|
|
|
// Focus time milestones
|
|
const AchievementConfig(
|
|
id: 'focus_5h',
|
|
nameKey: 'achievement_focus_5h_name',
|
|
descKey: 'achievement_focus_5h_desc',
|
|
icon: '⏱️',
|
|
type: AchievementType.totalMinutes,
|
|
requiredValue: 300, // 5 hours
|
|
bonusPoints: 100,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'focus_25h',
|
|
nameKey: 'achievement_focus_25h_name',
|
|
descKey: 'achievement_focus_25h_desc',
|
|
icon: '⏰',
|
|
type: AchievementType.totalMinutes,
|
|
requiredValue: 1500, // 25 hours
|
|
bonusPoints: 300,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'focus_100h',
|
|
nameKey: 'achievement_focus_100h_name',
|
|
descKey: 'achievement_focus_100h_desc',
|
|
icon: '👑',
|
|
type: AchievementType.totalMinutes,
|
|
requiredValue: 6000, // 100 hours
|
|
bonusPoints: 1000,
|
|
),
|
|
|
|
// Check-in streaks
|
|
const AchievementConfig(
|
|
id: 'streak_3',
|
|
nameKey: 'achievement_streak_3_name',
|
|
descKey: 'achievement_streak_3_desc',
|
|
icon: '🔥',
|
|
type: AchievementType.consecutiveDays,
|
|
requiredValue: 3,
|
|
bonusPoints: 20,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'streak_7',
|
|
nameKey: 'achievement_streak_7_name',
|
|
descKey: 'achievement_streak_7_desc',
|
|
icon: '🔥',
|
|
type: AchievementType.consecutiveDays,
|
|
requiredValue: 7,
|
|
bonusPoints: 50,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'streak_30',
|
|
nameKey: 'achievement_streak_30_name',
|
|
descKey: 'achievement_streak_30_desc',
|
|
icon: '🔥',
|
|
type: AchievementType.consecutiveDays,
|
|
requiredValue: 30,
|
|
bonusPoints: 200,
|
|
),
|
|
|
|
const AchievementConfig(
|
|
id: 'streak_100',
|
|
nameKey: 'achievement_streak_100_name',
|
|
descKey: 'achievement_streak_100_desc',
|
|
icon: '🔥',
|
|
type: AchievementType.consecutiveDays,
|
|
requiredValue: 100,
|
|
bonusPoints: 1000,
|
|
),
|
|
];
|
|
|
|
/// Get achievement by ID
|
|
static AchievementConfig? getById(String id) {
|
|
try {
|
|
return all.firstWhere((achievement) => achievement.id == id);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// Get all achievements of a specific type
|
|
static List<AchievementConfig> getByType(AchievementType type) {
|
|
return all.where((achievement) => achievement.type == type).toList();
|
|
}
|
|
}
|