- Replace flutter_appauth with custom WebView implementation to resolve deep link issues - Add KeycloakWebViewAuthService with integrated WebView for seamless authentication - Configure Android manifest for HTTP cleartext traffic support - Add network security config for development environment (192.168.1.11) - Update Keycloak client to use HTTP callback endpoint (http://192.168.1.11:8080/auth/callback) - Remove obsolete keycloak_auth_service.dart and temporary scripts - Clean up dependencies and regenerate injection configuration - Tested successfully on multiple Android devices (Xiaomi 2201116TG, SM A725F) BREAKING CHANGE: Authentication flow now uses WebView instead of external browser - Users will see Keycloak login page within the app instead of browser redirect - Resolves ERR_CLEARTEXT_NOT_PERMITTED and deep link state management issues - Maintains full OIDC compliance with PKCE flow and secure token storage Technical improvements: - WebView with custom navigation delegate for callback handling - Automatic token extraction and user info parsing from JWT - Proper error handling and user feedback - Consistent authentication state management across app lifecycle
161 lines
3.3 KiB
Dart
161 lines
3.3 KiB
Dart
import 'package:equatable/equatable.dart';
|
|
import '../../../../core/models/evenement_model.dart';
|
|
|
|
/// Événements du BLoC Evenement
|
|
abstract class EvenementEvent extends Equatable {
|
|
const EvenementEvent();
|
|
|
|
@override
|
|
List<Object?> get props => [];
|
|
}
|
|
|
|
/// Charge les événements à venir
|
|
class LoadEvenementsAVenir extends EvenementEvent {
|
|
final int page;
|
|
final int size;
|
|
final bool refresh;
|
|
|
|
const LoadEvenementsAVenir({
|
|
this.page = 0,
|
|
this.size = 10,
|
|
this.refresh = false,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [page, size, refresh];
|
|
}
|
|
|
|
/// Charge les événements publics
|
|
class LoadEvenementsPublics extends EvenementEvent {
|
|
final int page;
|
|
final int size;
|
|
final bool refresh;
|
|
|
|
const LoadEvenementsPublics({
|
|
this.page = 0,
|
|
this.size = 20,
|
|
this.refresh = false,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [page, size, refresh];
|
|
}
|
|
|
|
/// Charge tous les événements
|
|
class LoadEvenements extends EvenementEvent {
|
|
final int page;
|
|
final int size;
|
|
final String sortField;
|
|
final String sortDirection;
|
|
final bool refresh;
|
|
|
|
const LoadEvenements({
|
|
this.page = 0,
|
|
this.size = 20,
|
|
this.sortField = 'dateDebut',
|
|
this.sortDirection = 'asc',
|
|
this.refresh = false,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [page, size, sortField, sortDirection, refresh];
|
|
}
|
|
|
|
/// Charge un événement par ID
|
|
class LoadEvenementById extends EvenementEvent {
|
|
final String id;
|
|
|
|
const LoadEvenementById(this.id);
|
|
|
|
@override
|
|
List<Object?> get props => [id];
|
|
}
|
|
|
|
/// Recherche d'événements
|
|
class SearchEvenements extends EvenementEvent {
|
|
final String terme;
|
|
final int page;
|
|
final int size;
|
|
final bool refresh;
|
|
|
|
const SearchEvenements({
|
|
required this.terme,
|
|
this.page = 0,
|
|
this.size = 20,
|
|
this.refresh = false,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [terme, page, size, refresh];
|
|
}
|
|
|
|
/// Filtre par type d'événement
|
|
class FilterEvenementsByType extends EvenementEvent {
|
|
final TypeEvenement type;
|
|
final int page;
|
|
final int size;
|
|
final bool refresh;
|
|
|
|
const FilterEvenementsByType({
|
|
required this.type,
|
|
this.page = 0,
|
|
this.size = 20,
|
|
this.refresh = false,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [type, page, size, refresh];
|
|
}
|
|
|
|
/// Crée un nouvel événement
|
|
class CreateEvenement extends EvenementEvent {
|
|
final EvenementModel evenement;
|
|
|
|
const CreateEvenement(this.evenement);
|
|
|
|
@override
|
|
List<Object?> get props => [evenement];
|
|
}
|
|
|
|
/// Met à jour un événement
|
|
class UpdateEvenement extends EvenementEvent {
|
|
final String id;
|
|
final EvenementModel evenement;
|
|
|
|
const UpdateEvenement(this.id, this.evenement);
|
|
|
|
@override
|
|
List<Object?> get props => [id, evenement];
|
|
}
|
|
|
|
/// Supprime un événement
|
|
class DeleteEvenement extends EvenementEvent {
|
|
final String id;
|
|
|
|
const DeleteEvenement(this.id);
|
|
|
|
@override
|
|
List<Object?> get props => [id];
|
|
}
|
|
|
|
/// Change le statut d'un événement
|
|
class ChangeStatutEvenement extends EvenementEvent {
|
|
final String id;
|
|
final StatutEvenement nouveauStatut;
|
|
|
|
const ChangeStatutEvenement(this.id, this.nouveauStatut);
|
|
|
|
@override
|
|
List<Object?> get props => [id, nouveauStatut];
|
|
}
|
|
|
|
/// Charge les statistiques
|
|
class LoadStatistiquesEvenements extends EvenementEvent {
|
|
const LoadStatistiquesEvenements();
|
|
}
|
|
|
|
/// Réinitialise l'état
|
|
class ResetEvenementState extends EvenementEvent {
|
|
const ResetEvenementState();
|
|
}
|