feat: add coin private table
This commit is contained in:
@@ -59,8 +59,10 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
|
|||||||
emit(state.copyWith(chatBubbles: next));
|
emit(state.copyWith(chatBubbles: next));
|
||||||
});
|
});
|
||||||
on<LeaveGameEvent>((event, emit) => repository.send({'type': 'leave'}));
|
on<LeaveGameEvent>((event, emit) => repository.send({'type': 'leave'}));
|
||||||
on<StartTableEvent>((event, emit) =>
|
on<StartTableEvent>((event, emit) => repository.send(
|
||||||
repository.send({'type': 'start_table', 'hands': event.hands}));
|
{'type': 'start_table', 'hands': event.hands, 'stake': event.stake}));
|
||||||
|
on<SetStakeEvent>((event, emit) =>
|
||||||
|
repository.send({'type': 'set_stake', 'stake': event.stake}));
|
||||||
on<RotateTableEvent>((event, emit) =>
|
on<RotateTableEvent>((event, emit) =>
|
||||||
repository.send({'type': 'rotate_table', 'dir': event.dir}));
|
repository.send({'type': 'rotate_table', 'dir': event.dir}));
|
||||||
on<LeaveTableEvent>((event, emit) => repository.send({'type': 'leave_table'}));
|
on<LeaveTableEvent>((event, emit) => repository.send({'type': 'leave_table'}));
|
||||||
@@ -115,7 +117,9 @@ class GameBloc extends Bloc<GameEvent, GameUiState> {
|
|||||||
void sendChatEmoji(String emoji) => add(SendChatEvent(emoji: emoji));
|
void sendChatEmoji(String emoji) => add(SendChatEvent(emoji: emoji));
|
||||||
void playCard(String card) => add(PlayCardEvent(card));
|
void playCard(String card) => add(PlayCardEvent(card));
|
||||||
void leave() => add(LeaveGameEvent());
|
void leave() => add(LeaveGameEvent());
|
||||||
void startTable(int hands) => add(StartTableEvent(hands));
|
void startTable(int hands, {int stake = 0}) =>
|
||||||
|
add(StartTableEvent(hands, stake: stake));
|
||||||
|
void setStake(int stake) => add(SetStakeEvent(stake));
|
||||||
void rotateTable(int dir) => add(RotateTableEvent(dir));
|
void rotateTable(int dir) => add(RotateTableEvent(dir));
|
||||||
void leaveTable() => add(LeaveTableEvent());
|
void leaveTable() => add(LeaveTableEvent());
|
||||||
void clearNotice() => add(ClearNoticeEvent());
|
void clearNotice() => add(ClearNoticeEvent());
|
||||||
|
|||||||
@@ -50,7 +50,13 @@ class LeaveGameEvent extends GameEvent {}
|
|||||||
|
|
||||||
class StartTableEvent extends GameEvent {
|
class StartTableEvent extends GameEvent {
|
||||||
final int hands; // تعداد دستِ انتخابی (۳/۵/۷)
|
final int hands; // تعداد دستِ انتخابی (۳/۵/۷)
|
||||||
StartTableEvent(this.hands);
|
final int stake; // شرطِ سکهایِ هر بازیکن
|
||||||
|
StartTableEvent(this.hands, {this.stake = 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetStakeEvent extends GameEvent {
|
||||||
|
final int stake; // شرطِ سکهایِ میز (تنظیمِ زندهی میزبان)
|
||||||
|
SetStakeEvent(this.stake);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RotateTableEvent extends GameEvent {
|
class RotateTableEvent extends GameEvent {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class TableLobby {
|
|||||||
final int youSeat; // جایگاهِ مطلقِ خودِ کاربر (برای چیدمانِ صحنه)
|
final int youSeat; // جایگاهِ مطلقِ خودِ کاربر (برای چیدمانِ صحنه)
|
||||||
final int remaining;
|
final int remaining;
|
||||||
final bool unlimited;
|
final bool unlimited;
|
||||||
|
final int stake; // شرطِ سکهایِ هر بازیکن (۰ یعنی رایگان)
|
||||||
const TableLobby({
|
const TableLobby({
|
||||||
required this.code,
|
required this.code,
|
||||||
required this.players,
|
required this.players,
|
||||||
@@ -26,6 +27,7 @@ class TableLobby {
|
|||||||
required this.youSeat,
|
required this.youSeat,
|
||||||
required this.remaining,
|
required this.remaining,
|
||||||
required this.unlimited,
|
required this.unlimited,
|
||||||
|
required this.stake,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory TableLobby.fromJson(Map<String, dynamic> j) => TableLobby(
|
factory TableLobby.fromJson(Map<String, dynamic> j) => TableLobby(
|
||||||
@@ -41,9 +43,10 @@ class TableLobby {
|
|||||||
youSeat: (j['you_seat'] ?? 0) as int,
|
youSeat: (j['you_seat'] ?? 0) as int,
|
||||||
remaining: (j['remaining'] ?? 0) as int,
|
remaining: (j['remaining'] ?? 0) as int,
|
||||||
unlimited: (j['unlimited'] ?? false) as bool,
|
unlimited: (j['unlimited'] ?? false) as bool,
|
||||||
|
stake: (j['stake'] ?? 0) as int,
|
||||||
);
|
);
|
||||||
|
|
||||||
String get sig => '$code|$isHost|$youSeat|$remaining|$unlimited|'
|
String get sig => '$code|$isHost|$youSeat|$remaining|$unlimited|$stake|'
|
||||||
'${players.map((p) => '${p.name}${p.host ? '*' : ''}@${p.seat}').join(',')}';
|
'${players.map((p) => '${p.name}${p.host ? '*' : ''}@${p.seat}').join(',')}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -230,14 +230,30 @@ class _LobbyViewState extends State<_LobbyView> {
|
|||||||
for (final h in [3, 5, 7]) _handChip(h, lobby.isHost),
|
for (final h in [3, 5, 7]) _handChip(h, lobby.isHost),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 14),
|
||||||
|
const Text('ورودی (سکه) — برنده کل را میبرد',
|
||||||
|
style: TextStyle(color: Colors.white70)),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
|
children: [
|
||||||
|
for (final v in const [0, 500, 1000, 5000, 20000])
|
||||||
|
_stakeChip(v, lobby.isHost, lobby.stake),
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (lobby.isHost)
|
if (lobby.isHost)
|
||||||
GameButton(
|
GameButton(
|
||||||
label: 'شروع بازی',
|
label: lobby.stake > 0
|
||||||
|
? 'شروع بازی (${lobby.stake} سکه)'
|
||||||
|
: 'شروع بازی',
|
||||||
icon: Icons.play_arrow,
|
icon: Icons.play_arrow,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
colors: const [AppColors.success, AppColors.successDark],
|
colors: const [AppColors.success, AppColors.successDark],
|
||||||
onTap: () => context.read<GameBloc>().startTable(_hands),
|
onTap: () =>
|
||||||
|
context.read<GameBloc>().startTable(_hands, stake: lobby.stake),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
const Text(
|
const Text(
|
||||||
@@ -374,6 +390,45 @@ class _LobbyViewState extends State<_LobbyView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// چیپِ شرطِ سکه؛ میزبان با انتخاب، setStake را زنده برای همه پخش میکند.
|
||||||
|
Widget _stakeChip(int value, bool editable, int current) {
|
||||||
|
final selected = current == value;
|
||||||
|
final label = value == 0 ? 'رایگان' : '$value';
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: editable ? () => context.read<GameBloc>().setStake(value) : null,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
gradient: selected
|
||||||
|
? const LinearGradient(colors: [AppColors.gold, AppColors.goldDark])
|
||||||
|
: null,
|
||||||
|
color: selected ? null : AppColors.panel,
|
||||||
|
border: Border.all(
|
||||||
|
color: selected ? AppColors.gold : AppColors.goldDark,
|
||||||
|
width: 1.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (value > 0)
|
||||||
|
Icon(Icons.monetization_on,
|
||||||
|
size: 16, color: selected ? AppColors.bg : AppColors.gold),
|
||||||
|
if (value > 0) const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: TextStyle(
|
||||||
|
color: selected ? AppColors.bg : Colors.white,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// اوورلی شمارش معکوس ۳، ۲، ۱ پیش از شروع بازی.
|
/// اوورلی شمارش معکوس ۳، ۲، ۱ پیش از شروع بازی.
|
||||||
|
|||||||
Reference in New Issue
Block a user