98 lines
2.5 KiB
Dart
98 lines
2.5 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../domain/entities/pet_state_entity.dart';
|
|
import '../../../domain/entities/pet_type.dart';
|
|
import '../../../domain/entities/user_entity.dart';
|
|
import 'task_providers.dart';
|
|
|
|
/// Pet mood states.
|
|
enum PetMood {
|
|
happy,
|
|
neutral,
|
|
sad;
|
|
|
|
String get emoji => switch (this) {
|
|
PetMood.happy => '\u{1F60A}',
|
|
PetMood.neutral => '\u{1F610}',
|
|
PetMood.sad => '\u{1F622}',
|
|
};
|
|
}
|
|
|
|
// ── User ──
|
|
|
|
class UserNotifier extends Notifier<UserEntity> {
|
|
@override
|
|
UserEntity build() {
|
|
final currentUser = ref.watch(currentUserProvider).value;
|
|
if (currentUser != null) return currentUser;
|
|
return UserEntity(
|
|
id: '',
|
|
name: 'Friend',
|
|
petType: PetType.cat,
|
|
petName: 'Yoshi',
|
|
createdAt: DateTime.now(),
|
|
updatedAt: DateTime.now(),
|
|
);
|
|
}
|
|
|
|
void updateName(String name) {
|
|
state = state.copyWith(name: name, updatedAt: DateTime.now());
|
|
_persist();
|
|
}
|
|
|
|
void updatePetName(String petName) {
|
|
state = state.copyWith(petName: petName, updatedAt: DateTime.now());
|
|
_persist();
|
|
}
|
|
|
|
void _persist() {
|
|
if (state.id.isEmpty) return;
|
|
final repo = ref.read(userRepositoryProvider);
|
|
repo.updateUser(state);
|
|
}
|
|
}
|
|
|
|
final userProvider =
|
|
NotifierProvider<UserNotifier, UserEntity>(UserNotifier.new);
|
|
|
|
// ── Pet state ──
|
|
|
|
class PetStateNotifier extends Notifier<PetStateEntity> {
|
|
@override
|
|
PetStateEntity build() => PetStateEntity(
|
|
id: '1',
|
|
userId: '1',
|
|
energyToday: 2,
|
|
streakDays: 3,
|
|
totalTasksDone: 12,
|
|
unlockedItems: 'masle,pelisek',
|
|
updatedAt: DateTime.now(),
|
|
);
|
|
|
|
void incrementTasksDone() {
|
|
state = state.copyWith(totalTasksDone: state.totalTasksDone + 1);
|
|
}
|
|
|
|
void onTaskCompleted() => incrementTasksDone();
|
|
}
|
|
|
|
final petStateProvider =
|
|
NotifierProvider<PetStateNotifier, PetStateEntity>(PetStateNotifier.new);
|
|
|
|
// ── Derived providers ──
|
|
|
|
/// Pet mood derived from pet state.
|
|
final petMoodProvider = Provider<PetMood>((ref) {
|
|
final pet = ref.watch(petStateProvider);
|
|
if (pet.streakDays >= 3 || pet.totalTasksDone >= 5) return PetMood.happy;
|
|
if (pet.totalTasksDone == 0) return PetMood.sad;
|
|
return PetMood.neutral;
|
|
});
|
|
|
|
/// Pet level = totalTasksDone / 15 + 1, max 10.
|
|
final petLevelProvider = Provider<int>((ref) {
|
|
final pet = ref.watch(petStateProvider);
|
|
final level = pet.totalTasksDone ~/ 15 + 1;
|
|
return level.clamp(1, 10);
|
|
});
|