cards order
This commit is contained in:
parent
578eb0ec2f
commit
e19be0b015
4 changed files with 152 additions and 117 deletions
|
|
@ -8,6 +8,7 @@ import 'package:mnemo_cards/admin/admin_api.dart';
|
||||||
import 'package:mnemo_cards/di/injector.dart';
|
import 'package:mnemo_cards/di/injector.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/api.dart';
|
import 'package:mnemo_cards/managers/repository/api.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
import 'package:mnemo_cards/managers/repository/dio_provider.dart';
|
||||||
|
import 'package:mnemo_cards/utils/iterable_helper.dart';
|
||||||
import 'package:mnemo_cards/utils/string_helper.dart';
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||||||
import 'package:mnemo_cards/widgets/header.dart';
|
import 'package:mnemo_cards/widgets/header.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
|
@ -268,6 +269,18 @@ class AddPackage with Api {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
_TextParam(
|
||||||
|
'Cards order (ids)',
|
||||||
|
cardPackDto.cardsOrder?.join(','),
|
||||||
|
(v) {
|
||||||
|
final ids = v
|
||||||
|
.split(',')
|
||||||
|
.map((s) => int.tryParse(s.trim()))
|
||||||
|
.whereNotNull()
|
||||||
|
.toList();
|
||||||
|
cardPackDto = cardPackDto.copyWith(cardsOrder: ids);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'dart:io';
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:google_sign_in/google_sign_in.dart';
|
import 'package:google_sign_in/google_sign_in.dart';
|
||||||
|
import 'package:mnemo_cards/di/locator.dart';
|
||||||
import 'package:mnemo_cards/main.dart';
|
import 'package:mnemo_cards/main.dart';
|
||||||
import 'package:mnemo_cards/managers/repository/http_repository.dart';
|
import 'package:mnemo_cards/managers/repository/http_repository.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
|
|
@ -118,10 +119,18 @@ class UserManager {
|
||||||
await _createUser(token!, ExternalIdType.google, name);
|
await _createUser(token!, ExternalIdType.google, name);
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
..add(Stream.periodic(Duration(seconds: 10)).listen((_) async {
|
..add(userStateHolder.asNullableStream.listen((user) async {
|
||||||
try {
|
try {
|
||||||
if (userStateHolder.user == null) {
|
if (user == null) {
|
||||||
await _updateUser();
|
await _updateUser();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await locator.previewPackPoller.poll();
|
||||||
|
await locator.packManager.clearCache();
|
||||||
|
await locator.packUpdater.updateAvailablePacks();
|
||||||
|
} catch (err) {
|
||||||
|
log(err.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e.toString());
|
log(e.toString());
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,15 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/animation.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:mnemo_cards/features/packs/images_holder.dart';
|
|
||||||
import 'package:mnemo_cards/main.dart';
|
|
||||||
import 'package:mnemo_cards/widgets/fade_in_widget.dart';
|
import 'package:mnemo_cards/widgets/fade_in_widget.dart';
|
||||||
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||||||
import 'package:yandex_mobileads/mobile_ads.dart';
|
import 'package:yandex_mobileads/mobile_ads.dart';
|
||||||
import '../../domain/router/app_router.gr.dart';
|
import '../../domain/router/app_router.gr.dart';
|
||||||
import '../../features/analytics/analytics.dart';
|
import '../../features/analytics/analytics.dart';
|
||||||
import '../../features/yandex_ads/yandex_ads.dart';
|
import '../../features/yandex_ads/yandex_ads.dart';
|
||||||
import '../game_card_widget.dart';
|
|
||||||
|
|
||||||
import '../../di/locator.dart';
|
import '../../di/locator.dart';
|
||||||
import '../../theme/themes.dart';
|
import '../../theme/themes.dart';
|
||||||
|
|
@ -40,119 +33,139 @@ class AvailablePack extends StatelessWidget {
|
||||||
Analytics.availablePackOpened(cardPack);
|
Analytics.availablePackOpened(cardPack);
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
CardPackHeader.fromDto(cardPack),
|
CardPackHeader(
|
||||||
|
cardPack.title,
|
||||||
|
cardPack.subtitle,
|
||||||
|
Colors.transparent,
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: RefreshIndicator(
|
||||||
controller: _mainScrollController,
|
onRefresh: () =>
|
||||||
children: [
|
locator.packUpdater.updatePackAndSaveImages(cardPack.id),
|
||||||
StatefulBuilder(builder: (context, setState) {
|
backgroundColor: Colors.white,
|
||||||
return Column(
|
color: cardPack.color?.asColor ?? Colors.black,
|
||||||
children: [
|
child: ListView(
|
||||||
Container(
|
physics: BouncingScrollPhysics(
|
||||||
decoration: BoxDecoration(
|
decelerationRate: ScrollDecelerationRate.fast,
|
||||||
color: cardPack.color?.asColor?.withOpacity(0.1),
|
parent: AlwaysScrollableScrollPhysics()),
|
||||||
|
controller: _mainScrollController,
|
||||||
|
children: [
|
||||||
|
StatefulBuilder(builder: (context, setState) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 1,
|
||||||
|
color: cardPack.color?.asColor ??
|
||||||
|
Colors.grey.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
Container(
|
||||||
clipBehavior: Clip.antiAlias,
|
decoration: BoxDecoration(
|
||||||
child: CardsView(_cardsViewController, cardPack),
|
color: cardPack.color?.asColor?.withOpacity(0.1),
|
||||||
),
|
),
|
||||||
Container(
|
alignment: Alignment.center,
|
||||||
height: 1,
|
clipBehavior: Clip.antiAlias,
|
||||||
color: cardPack.color?.asColor ??
|
child: CardsView(_cardsViewController, cardPack),
|
||||||
Colors.grey.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 10.w,
|
|
||||||
),
|
),
|
||||||
child: Row(
|
Container(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
height: 1,
|
||||||
children: [
|
color: cardPack.color?.asColor ??
|
||||||
StreamBuilder(
|
Colors.grey.withOpacity(0.5),
|
||||||
stream: _cardsViewController.asStream,
|
),
|
||||||
builder: (context, snapshot) {
|
SizedBox(
|
||||||
return AnimatedRotation(
|
height: 10.h,
|
||||||
duration: Duration(milliseconds: 300),
|
),
|
||||||
turns: (snapshot.data?.expanded ?? false)
|
Padding(
|
||||||
? 0.5
|
padding: EdgeInsets.symmetric(
|
||||||
: 0.0,
|
horizontal: 10.w,
|
||||||
child: _Button(
|
),
|
||||||
'down.png',
|
child: Row(
|
||||||
() async {
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
if (snapshot.hasData) {
|
children: [
|
||||||
_cardsViewController.setExpanded(
|
StreamBuilder(
|
||||||
!snapshot.requireData.expanded,
|
stream: _cardsViewController.asStream,
|
||||||
);
|
builder: (context, snapshot) {
|
||||||
}
|
return AnimatedRotation(
|
||||||
},
|
duration: Duration(milliseconds: 300),
|
||||||
|
turns: (snapshot.data?.expanded ?? false)
|
||||||
|
? 0.5
|
||||||
|
: 0.0,
|
||||||
|
child: _Button(
|
||||||
|
'down.png',
|
||||||
|
() async {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
_cardsViewController.setExpanded(
|
||||||
|
!snapshot.requireData.expanded,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
_Button('shuffle.png', () async {
|
||||||
|
final cards =
|
||||||
|
_cardsViewController.state.packCards;
|
||||||
|
if (cards.isEmpty) return;
|
||||||
|
final index = (_cardsViewController.offsetCards +
|
||||||
|
Random().nextInt(
|
||||||
|
(cards.length / 2).ceil(),
|
||||||
|
) +
|
||||||
|
3) %
|
||||||
|
cards.length;
|
||||||
|
await _cardsViewController.animateTo(index);
|
||||||
|
AutoRouter.of(context).push(
|
||||||
|
PageRouteInfo(
|
||||||
|
CardGamePage.name,
|
||||||
|
args: CardGamePageArgs(
|
||||||
|
cards: cards,
|
||||||
|
color: cardPack.color?.asColor,
|
||||||
|
startCardId: cards[index].id,
|
||||||
|
infinite: true,
|
||||||
|
shuffle: true,
|
||||||
|
// id: cardPack.dto.id.toString(),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
}),
|
|
||||||
_Button('shuffle.png', () async {
|
|
||||||
final cards = _cardsViewController.state.packCards;
|
|
||||||
if (cards.isEmpty) return;
|
|
||||||
final index = (_cardsViewController.offsetCards +
|
|
||||||
Random().nextInt(
|
|
||||||
(cards.length / 2).ceil(),
|
|
||||||
) +
|
|
||||||
3) %
|
|
||||||
cards.length;
|
|
||||||
await _cardsViewController.animateTo(index);
|
|
||||||
AutoRouter.of(context).push(
|
|
||||||
PageRouteInfo(
|
|
||||||
CardGamePage.name,
|
|
||||||
args: CardGamePageArgs(
|
|
||||||
cards: cards,
|
|
||||||
color: cardPack.color?.asColor,
|
|
||||||
startCardId: cards[index].id,
|
|
||||||
infinite: true,
|
|
||||||
shuffle: true,
|
|
||||||
// id: cardPack.dto.id.toString(),
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}),
|
||||||
}),
|
// _Button('chat.png', () {}),
|
||||||
// _Button('chat.png', () {}),
|
StreamBuilder(
|
||||||
StreamBuilder(
|
stream: _cardsViewController.asStream,
|
||||||
stream: _cardsViewController.asStream,
|
builder: (context, snapshot) {
|
||||||
builder: (context, snapshot) {
|
return _Button(
|
||||||
return _Button(
|
(snapshot.data?.favorite ?? false)
|
||||||
(snapshot.data?.favorite ?? false)
|
? 'heart_fill.png'
|
||||||
? 'heart_fill.png'
|
: 'heart.png', () {
|
||||||
: 'heart.png', () {
|
if (snapshot.hasData) {
|
||||||
if (snapshot.hasData) {
|
_cardsViewController.setFavorite(
|
||||||
_cardsViewController.setFavorite(
|
!snapshot.requireData.favorite,
|
||||||
!snapshot.requireData.favorite,
|
);
|
||||||
);
|
}
|
||||||
}
|
});
|
||||||
});
|
}),
|
||||||
}),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
);
|
||||||
);
|
}),
|
||||||
}),
|
_AdTile(),
|
||||||
_AdTile(),
|
_TestsSection(cardPack.id.toString()),
|
||||||
_TestsSection(cardPack.id.toString()),
|
// _TestButton(
|
||||||
// _TestButton(
|
// title: 'Быстрый тест',
|
||||||
// title: 'Быстрый тест',
|
// subtitle: 'Лучший результат: 99 / 100',
|
||||||
// subtitle: 'Лучший результат: 99 / 100',
|
// time: '3',
|
||||||
// time: '3',
|
// timeSubtitle: 'мин',
|
||||||
// timeSubtitle: 'мин',
|
// onTap: () {},
|
||||||
// onTap: () {},
|
// ),
|
||||||
// ),
|
// _TestButton(
|
||||||
// _TestButton(
|
// title: 'Полный тест',
|
||||||
// title: 'Полный тест',
|
// subtitle: 'Лучший результат: 99 / 100',
|
||||||
// subtitle: 'Лучший результат: 99 / 100',
|
// time: '10',
|
||||||
// time: '10',
|
// timeSubtitle: 'мин',
|
||||||
// timeSubtitle: 'мин',
|
// onTap: () {},
|
||||||
// onTap: () {},
|
// ),
|
||||||
// ),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Hero(
|
Hero(
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class GameCardDecoration extends StatelessWidget {
|
||||||
margin: EdgeInsets.only(
|
margin: EdgeInsets.only(
|
||||||
left: 10.0 * alpha,
|
left: 10.0 * alpha,
|
||||||
right: 10.0 * alpha,
|
right: 10.0 * alpha,
|
||||||
bottom: 10.0 * alpha,
|
bottom: 2.0 * alpha,
|
||||||
top: 0.0 * alpha,
|
top: 0.0 * alpha,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue