feat: add message feature

This commit is contained in:
2026-06-25 01:11:34 +03:30
parent e8cde8e1f7
commit fa45ef0737
6 changed files with 274 additions and 8 deletions
@@ -17,6 +17,7 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
Map<String, dynamic> _joinAction = const {};
bool _joined = false;
int _bubbleSeq = 0; // شناسه‌ی یکتا برای هر حبابِ پیام (انقضای دقیق)
GameBloc(this.repository) : super(const GameUiState()) {
_msgSub =
@@ -45,6 +46,18 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
on<PlayCardEvent>(
(event, emit) => repository.send({'type': 'play_card', 'card': event.card}));
on<ReshuffleEvent>((event, emit) => repository.send({'type': 'reshuffle'}));
on<SendChatEvent>((event, emit) => repository.send({
'type': 'chat',
if (event.text != null) 'text': event.text,
if (event.emoji != null) 'emoji': event.emoji,
}));
on<ExpireChatEvent>((event, emit) {
final cur = state.chatBubbles[event.seat];
if (cur == null || cur.id != event.id) return; // حبابِ جدیدتر است ⇒ نگه‌دار
final next = Map<int, ChatBubble>.from(state.chatBubbles)
..remove(event.seat);
emit(state.copyWith(chatBubbles: next));
});
on<LeaveGameEvent>((event, emit) => repository.send({'type': 'leave'}));
on<StartTableEvent>((event, emit) =>
repository.send({'type': 'start_table', 'hands': event.hands}));
@@ -75,6 +88,19 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
emit(state.copyWith(notice: 'یک بازیکن قطع شد'));
case 'player_reconnected':
emit(state.copyWith(notice: 'بازیکن بازگشت'));
case 'chat':
final seat = (msg['seat'] ?? 0) as int;
final id = ++_bubbleSeq;
final bubble = ChatBubble(
text: msg['text'] as String?,
emoji: msg['emoji'] as String?,
id: id,
);
final next = Map<int, ChatBubble>.from(state.chatBubbles)
..[seat] = bubble;
emit(state.copyWith(chatBubbles: next));
// انقضای خودکار پس از ۴ ثانیه (مگر حبابِ جدیدتری روی همان جایگاه بنشیند).
Timer(const Duration(seconds: 4), () => add(ExpireChatEvent(seat, id)));
case 'player_left':
emit(state.copyWith(notice: 'یک بازیکن میز را ترک کرد'));
case 'error':
@@ -85,6 +111,8 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
// --- متدهای کمکی برای موتور Flame و صفحه‌ها ---
void chooseTrump(String suit) => add(ChooseTrumpEvent(suit));
void reshuffle() => add(ReshuffleEvent());
void sendChatText(String text) => add(SendChatEvent(text: text));
void sendChatEmoji(String emoji) => add(SendChatEvent(emoji: emoji));
void playCard(String card) => add(PlayCardEvent(card));
void leave() => add(LeaveGameEvent());
void startTable(int hands) => add(StartTableEvent(hands));