Initial commit: unionflow-mobile-apps

Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 16:30:08 +00:00
commit d094d6db9c
1790 changed files with 507435 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
/// BLoC de gestion de la messagerie
library messaging_bloc;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/usecases/get_conversations.dart';
import '../../domain/usecases/get_messages.dart';
import '../../domain/usecases/send_message.dart';
import '../../domain/usecases/send_broadcast.dart';
import 'messaging_event.dart';
import 'messaging_state.dart';
@injectable
class MessagingBloc extends Bloc<MessagingEvent, MessagingState> {
final GetConversations getConversations;
final GetMessages getMessages;
final SendMessage sendMessage;
final SendBroadcast sendBroadcast;
MessagingBloc({
required this.getConversations,
required this.getMessages,
required this.sendMessage,
required this.sendBroadcast,
}) : super(MessagingInitial()) {
on<LoadConversations>(_onLoadConversations);
on<LoadMessages>(_onLoadMessages);
on<SendMessageEvent>(_onSendMessage);
on<SendBroadcastEvent>(_onSendBroadcast);
}
Future<void> _onLoadConversations(
LoadConversations event,
Emitter<MessagingState> emit,
) async {
emit(MessagingLoading());
final result = await getConversations(
organizationId: event.organizationId,
includeArchived: event.includeArchived,
);
result.fold(
(failure) => emit(MessagingError(failure.message)),
(conversations) => emit(ConversationsLoaded(conversations: conversations)),
);
}
Future<void> _onLoadMessages(
LoadMessages event,
Emitter<MessagingState> emit,
) async {
emit(MessagingLoading());
final result = await getMessages(
conversationId: event.conversationId,
limit: event.limit,
beforeMessageId: event.beforeMessageId,
);
result.fold(
(failure) => emit(MessagingError(failure.message)),
(messages) => emit(MessagesLoaded(
conversationId: event.conversationId,
messages: messages,
hasMore: messages.length == (event.limit ?? 50),
)),
);
}
Future<void> _onSendMessage(
SendMessageEvent event,
Emitter<MessagingState> emit,
) async {
final result = await sendMessage(
conversationId: event.conversationId,
content: event.content,
attachments: event.attachments,
priority: event.priority,
);
result.fold(
(failure) => emit(MessagingError(failure.message)),
(message) => emit(MessageSent(message)),
);
}
Future<void> _onSendBroadcast(
SendBroadcastEvent event,
Emitter<MessagingState> emit,
) async {
final result = await sendBroadcast(
organizationId: event.organizationId,
subject: event.subject,
content: event.content,
priority: event.priority,
attachments: event.attachments,
);
result.fold(
(failure) => emit(MessagingError(failure.message)),
(message) => emit(BroadcastSent(message)),
);
}
}

View File

@@ -0,0 +1,118 @@
/// Événements du BLoC Messaging
library messaging_event;
import 'package:equatable/equatable.dart';
import '../../domain/entities/message.dart';
abstract class MessagingEvent extends Equatable {
const MessagingEvent();
@override
List<Object?> get props => [];
}
/// Charger les conversations
class LoadConversations extends MessagingEvent {
final String? organizationId;
final bool includeArchived;
const LoadConversations({
this.organizationId,
this.includeArchived = false,
});
@override
List<Object?> get props => [organizationId, includeArchived];
}
/// Charger les messages d'une conversation
class LoadMessages extends MessagingEvent {
final String conversationId;
final int? limit;
final String? beforeMessageId;
const LoadMessages({
required this.conversationId,
this.limit,
this.beforeMessageId,
});
@override
List<Object?> get props => [conversationId, limit, beforeMessageId];
}
/// Envoyer un message
class SendMessageEvent extends MessagingEvent {
final String conversationId;
final String content;
final List<String>? attachments;
final MessagePriority priority;
const SendMessageEvent({
required this.conversationId,
required this.content,
this.attachments,
this.priority = MessagePriority.normal,
});
@override
List<Object?> get props => [conversationId, content, attachments, priority];
}
/// Envoyer un broadcast
class SendBroadcastEvent extends MessagingEvent {
final String organizationId;
final String subject;
final String content;
final MessagePriority priority;
final List<String>? attachments;
const SendBroadcastEvent({
required this.organizationId,
required this.subject,
required this.content,
this.priority = MessagePriority.normal,
this.attachments,
});
@override
List<Object?> get props => [organizationId, subject, content, priority, attachments];
}
/// Marquer un message comme lu
class MarkMessageAsReadEvent extends MessagingEvent {
final String messageId;
const MarkMessageAsReadEvent(this.messageId);
@override
List<Object?> get props => [messageId];
}
/// Charger le nombre de messages non lus
class LoadUnreadCount extends MessagingEvent {
final String? organizationId;
const LoadUnreadCount({this.organizationId});
@override
List<Object?> get props => [organizationId];
}
/// Créer une nouvelle conversation
class CreateConversationEvent extends MessagingEvent {
final String name;
final List<String> participantIds;
final String? organizationId;
final String? description;
const CreateConversationEvent({
required this.name,
required this.participantIds,
this.organizationId,
this.description,
});
@override
List<Object?> get props => [name, participantIds, organizationId, description];
}

View File

@@ -0,0 +1,99 @@
/// États du BLoC Messaging
library messaging_state;
import 'package:equatable/equatable.dart';
import '../../domain/entities/conversation.dart';
import '../../domain/entities/message.dart';
abstract class MessagingState extends Equatable {
const MessagingState();
@override
List<Object?> get props => [];
}
/// État initial
class MessagingInitial extends MessagingState {}
/// Chargement en cours
class MessagingLoading extends MessagingState {}
/// Conversations chargées
class ConversationsLoaded extends MessagingState {
final List<Conversation> conversations;
final int unreadCount;
const ConversationsLoaded({
required this.conversations,
this.unreadCount = 0,
});
@override
List<Object?> get props => [conversations, unreadCount];
}
/// Messages d'une conversation chargés
class MessagesLoaded extends MessagingState {
final String conversationId;
final List<Message> messages;
final bool hasMore;
const MessagesLoaded({
required this.conversationId,
required this.messages,
this.hasMore = false,
});
@override
List<Object?> get props => [conversationId, messages, hasMore];
}
/// Message envoyé avec succès
class MessageSent extends MessagingState {
final Message message;
const MessageSent(this.message);
@override
List<Object?> get props => [message];
}
/// Broadcast envoyé avec succès
class BroadcastSent extends MessagingState {
final Message message;
const BroadcastSent(this.message);
@override
List<Object?> get props => [message];
}
/// Conversation créée
class ConversationCreated extends MessagingState {
final Conversation conversation;
const ConversationCreated(this.conversation);
@override
List<Object?> get props => [conversation];
}
/// Compteur de non lus chargé
class UnreadCountLoaded extends MessagingState {
final int count;
const UnreadCountLoaded(this.count);
@override
List<Object?> get props => [count];
}
/// Erreur
class MessagingError extends MessagingState {
final String message;
const MessagingError(this.message);
@override
List<Object?> get props => [message];
}