setings and gen filter

This commit is contained in:
2026-06-23 10:54:16 +02:00
parent d54e517ca6
commit 71f5122e74
8 changed files with 515 additions and 10 deletions
@@ -6,6 +6,7 @@ import '../../core/config/app_constants.dart';
import '../../domain/game/game_engine.dart';
import '../../domain/game/game_state.dart';
import '../../core/logger.dart';
import 'gen_filter_provider.dart';
import 'pokedex_provider.dart';
import 'repository_provider.dart';
@@ -34,7 +35,7 @@ class GameNotifier extends Notifier<GameState> {
final repo = ref.read(pokemonRepositoryProvider);
final isShiny = _random.nextInt(AppConstants.shinyOdds) == 0;
final id = _random.nextInt(AppConstants.totalPokemon) + 1;
final id = ref.read(genFilterProvider.notifier).randomId(_random);
try {
final pokemon = await repo.getById(id);
if (pokemon == null) {
@@ -0,0 +1,54 @@
import 'dart:math';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../core/config/app_constants.dart';
class GenFilterNotifier extends Notifier<Set<int>> {
@override
Set<int> build() {
_load();
// Default: all gens enabled
return Set.from(List.generate(AppConstants.genRanges.length, (i) => i));
}
Future<void> _load() async {
final prefs = await SharedPreferences.getInstance();
final saved = prefs.getStringList(AppConstants.prefsGenFilter);
if (saved != null && saved.isNotEmpty) {
state = saved.map(int.parse).toSet();
}
}
Future<void> toggle(int genIndex) async {
final next = Set<int>.from(state);
if (next.contains(genIndex)) {
// Prevent deselecting the last gen
if (next.length == 1) return;
next.remove(genIndex);
} else {
next.add(genIndex);
}
state = next;
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList(
AppConstants.prefsGenFilter,
state.map((i) => i.toString()).toList(),
);
}
/// Returns a random Pokémon ID within the currently enabled gens.
int randomId(Random random) {
final ranges = state.map((i) => AppConstants.genRanges[i]).toList();
final totalPool = ranges.fold(0, (sum, r) => sum + (r.$2 - r.$1 + 1));
var pick = random.nextInt(totalPool);
for (final r in ranges) {
final size = r.$2 - r.$1 + 1;
if (pick < size) return r.$1 + pick;
pick -= size;
}
return 1;
}
}
final genFilterProvider =
NotifierProvider<GenFilterNotifier, Set<int>>(GenFilterNotifier.new);
@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AppPalette {
final String name;
final Color primary;
final Color surface;
const AppPalette({
required this.name,
required this.primary,
required this.surface,
});
}
const List<AppPalette> appPalettes = [
AppPalette(name: 'Pokédex Rouge', primary: Color(0xFFD32F2F), surface: Color(0xFF1B2333)),
AppPalette(name: 'Océan Bleu', primary: Color(0xFF1565C0), surface: Color(0xFF0D1B2A)),
AppPalette(name: 'Forêt Verte', primary: Color(0xFF2E7D32), surface: Color(0xFF1A2B1A)),
AppPalette(name: 'Foudre Jaune', primary: Color(0xFFF9A825), surface: Color(0xFF1C1A00)),
AppPalette(name: 'Ombre Violette',primary: Color(0xFF6A1B9A), surface: Color(0xFF1A0A2B)),
];
const String _prefsPaletteIndex = 'palette_index';
class ThemeNotifier extends Notifier<int> {
@override
int build() {
_loadSaved();
return 0;
}
Future<void> _loadSaved() async {
final prefs = await SharedPreferences.getInstance();
final idx = prefs.getInt(_prefsPaletteIndex) ?? 0;
state = idx.clamp(0, appPalettes.length - 1);
}
Future<void> setPalette(int index) async {
state = index.clamp(0, appPalettes.length - 1);
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(_prefsPaletteIndex, state);
}
AppPalette get current => appPalettes[state];
}
final themeProvider = NotifierProvider<ThemeNotifier, int>(ThemeNotifier.new);