148 lines
5.7 KiB
Dart
148 lines
5.7 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:auto_route/auto_route.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:mnemo_cards/features/packs/images_holder.dart';
|
|
import 'package:mnemo_cards/utils/color_helper.dart';
|
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
|
import 'package:rxdart/rxdart.dart';
|
|
|
|
import '../../features/card_flipper/flip_card_controllers.dart';
|
|
import '../../features/card_swiper/src/allowed_swipe_direction.dart';
|
|
import '../../features/card_swiper/src/card_swiper.dart';
|
|
import '../../features/card_swiper/src/card_swiper_controller.dart';
|
|
import '../../features/card_swiper/src/enums.dart';
|
|
import '../../main.dart';
|
|
import '../game_card_widget.dart';
|
|
|
|
class CardGameMainWidget extends StatelessWidget {
|
|
final List<GameCardDto> cards;
|
|
final Color? color;
|
|
final int? startCardId;
|
|
final CardSwiperController cardSwiperController;
|
|
final FlipCardController flipCardController;
|
|
final int length;
|
|
|
|
const CardGameMainWidget(
|
|
this.cards,
|
|
this.color,
|
|
this.startCardId,
|
|
this.cardSwiperController,
|
|
this.flipCardController,
|
|
this.length,
|
|
);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final numberOfCardsDisplayed = min(2, cards.length);
|
|
final initialScale = 0.9;
|
|
|
|
GameCardDto? activeCard() => cardSwiperController.currentIndex >= 0
|
|
? cards[cardSwiperController.currentIndex % cards.length]
|
|
: null;
|
|
|
|
return PopScope(
|
|
canPop: false,
|
|
onPopInvoked: (v) {
|
|
if (!v) {
|
|
appRouter.popForced(activeCard()?.id);
|
|
}
|
|
},
|
|
child: Material(
|
|
type: MaterialType.transparency,
|
|
child: LayoutBuilder(builder: (context, constraints) {
|
|
final cardWidth = constraints.maxWidth;
|
|
final cardHeight = cardWidth;
|
|
bool enabled = true;
|
|
return StatefulBuilder(builder: (context, setState) {
|
|
return Stack(
|
|
children: [
|
|
_EndWidget(),
|
|
if (enabled)
|
|
Hero(
|
|
tag: activeCard()?.id ?? 'empty',
|
|
child: StreamBuilder<bool>(
|
|
stream: cardSwiperController.asStream
|
|
.map((index) => /*cards[index].isAd*/ false)
|
|
.pairwise()
|
|
.asyncMap((pair) async {
|
|
if (pair.first) {
|
|
await Future.delayed(Duration(seconds: 5));
|
|
return false;
|
|
}
|
|
return pair.last;
|
|
}).timeout(Duration(seconds: 5),
|
|
onTimeout: (_) => false),
|
|
builder: (context, snapshot) {
|
|
return AbsorbPointer(
|
|
absorbing: snapshot.data ?? false,
|
|
child: CardSwiper(
|
|
controller: cardSwiperController,
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 0.0,
|
|
horizontal: 0.0,
|
|
),
|
|
cardsCount: length,
|
|
numberOfCardsDisplayed: numberOfCardsDisplayed,
|
|
allowedSwipeDirection:
|
|
AllowedSwipeDirection.all(),
|
|
scale: initialScale,
|
|
backCardOffset: Offset(0, cardHeight * 0.1 / 2),
|
|
isLoop: false,
|
|
cardBuilder: (
|
|
context,
|
|
cardIndex,
|
|
percentThresholdX,
|
|
percentThresholdY,
|
|
scale,
|
|
) {
|
|
final index = cardIndex % cards.length;
|
|
final isFirstCard =
|
|
(cardSwiperController.currentIndex ==
|
|
cardIndex);
|
|
if (cardSwiperController.currentIndex ==
|
|
index) {
|
|
// lastThreshold = percentThresholdX;
|
|
}
|
|
print('${cards[index].translation} $scale');
|
|
final cardWidget = Center(
|
|
child: GameCardWidget(
|
|
cards[index],
|
|
cards[index].memoryImage,
|
|
flipCardController,
|
|
flipCardController.state
|
|
// || cards[index].isAd
|
|
,
|
|
isFirstCard,
|
|
isFirstCard
|
|
? color
|
|
: color?.darken(
|
|
(scale - 1) /
|
|
(initialScale - 1) *
|
|
0.075,
|
|
),
|
|
),
|
|
);
|
|
return cardWidget;
|
|
},
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
],
|
|
);
|
|
});
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _EndWidget extends StatelessWidget {
|
|
_EndWidget();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container();
|
|
}
|
|
}
|