choose_mode.dart 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. import 'dart:async';
  2. import 'package:app_settings/app_settings.dart';
  3. import 'package:fast/constants.dart';
  4. import 'package:fast/extension/layout.dart';
  5. import 'package:fast/utils/global.dart';
  6. import 'package:fast/utils/util.dart';
  7. import 'package:fast/view/component/fast_btn.dart';
  8. import 'package:fast/view/component/navi_bar.dart';
  9. import 'package:fast/view/component/share.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:fast/utils/size_fit.dart';
  12. import 'package:flutter_vibrate/flutter_vibrate.dart';
  13. import 'package:get/get.dart';
  14. import '../recharge.dart';
  15. import 'alert_widget.dart';
  16. // ignore: must_be_immutable
  17. class ChooseMode extends StatefulWidget {
  18. // ignore: prefer_typing_uninitialized_variables
  19. var callback;
  20. int seconds;
  21. ChooseMode({Key? key, required this.callback, required this.seconds})
  22. : super(key: key);
  23. @override
  24. State<ChooseMode> createState() => _ChooseModeState();
  25. }
  26. class _ChooseModeState extends State<ChooseMode>
  27. with SingleTickerProviderStateMixin {
  28. late AnimationController controller;
  29. late Animation<double> scale;
  30. int selType = 0;
  31. bool enoughStone = true;
  32. @override
  33. void initState() {
  34. super.initState();
  35. controller = AnimationController(
  36. vsync: this, duration: const Duration(milliseconds: 200));
  37. controller.addStatusListener((status) {});
  38. scale = Tween(begin: 1.0, end: 1.2).animate(controller);
  39. }
  40. @override
  41. void dispose() {
  42. controller.dispose();
  43. super.dispose();
  44. }
  45. modeText(content, textAlign) {
  46. return Text(
  47. content,
  48. style: TextStyle(
  49. color: const Color(0x99C4CCDA),
  50. fontSize: 10.px,
  51. height: 1.6,
  52. fontWeight: FontWeight.normal),
  53. textAlign: textAlign,
  54. );
  55. }
  56. @override
  57. Widget build(BuildContext context) {
  58. EdgeInsets safePadding = MediaQuery.of(context).padding;
  59. var size = MediaQuery.of(context).size;
  60. var stones = [1, 3, 4, 5];
  61. var wins = [1, 3, 5, 7];
  62. if (Global().balance < stones[selType]) {
  63. enoughStone = false;
  64. } else {
  65. enoughStone = true;
  66. }
  67. return Flex(
  68. direction: Axis.vertical,
  69. children: [
  70. Expanded(
  71. child: Stack(
  72. children: [
  73. SingleChildScrollView(
  74. scrollDirection: Axis.vertical,
  75. child: Column(
  76. children: [
  77. SizedBox(
  78. height: safePadding.top + 40.px,
  79. ),
  80. Image.asset(
  81. 'assets/images/single_mode.png',
  82. width: 298.px,
  83. height: 48.px,
  84. ),
  85. modeText(
  86. '记录一次断食,适合刚接触间歇性断食的小伙伴\n· 选择适合自己的断食时长,新手可选择12h断食开始\n· 适应后延至16h或更长。单次记录将消耗1颗逆龄石',
  87. TextAlign.left),
  88. SizedBox(height: 12.px),
  89. Stack(
  90. children: [
  91. GestureDetector(
  92. onTap: () => setState(() {
  93. selType = 0;
  94. }),
  95. child: Container(
  96. width: 296.px,
  97. height: 64.px,
  98. child: Opacity(
  99. opacity: selType == 0 ? 1 : 0.8,
  100. child:
  101. Image.asset('assets/images/single_sel.png'),
  102. ),
  103. decoration: BoxDecoration(
  104. borderRadius:
  105. BorderRadius.all(Radius.circular(20.px)),
  106. border: Border.all(
  107. color: selType == 0
  108. ? kThemeColor
  109. : Colors.transparent,
  110. width: 1.px)),
  111. ),
  112. ),
  113. if (selType == 0)
  114. Image.asset(
  115. 'assets/images/mode_checked1.png',
  116. width: 39.px,
  117. height: 39.px,
  118. )
  119. ],
  120. ),
  121. // Container(
  122. // // width: 108.px,height: 152.px,
  123. // child: Image.asset('assets/images/3days_sel.png',width: 108.px,height: 152.px,),
  124. // decoration: BoxDecoration(
  125. // borderRadius: BorderRadius.all(Radius.circular(19.px)),
  126. // border: Border.all(color:Colors.red,width: 1.px)
  127. // ),
  128. // ),
  129. Image.asset(
  130. 'assets/images/challenge_mode.png',
  131. width: 298.px,
  132. height: 48.px,
  133. ),
  134. modeText(
  135. '间歇性断食挑战,激发身体内在活力,赢取傲人健康资本!\n· 期初投资3/4/5颗逆龄石,每天两次准时打卡赚取1颗\n· 挑战成功获得3/5/7颗逆龄石,分享好友还能领取更多',
  136. TextAlign.left),
  137. Callenage(
  138. selType: selType,
  139. callback: (type) {
  140. setState(() {
  141. selType = type;
  142. });
  143. },
  144. ),
  145. Column(
  146. crossAxisAlignment: CrossAxisAlignment.start,
  147. children: [
  148. Text(
  149. '挑战规则',
  150. style: TextStyle(
  151. color: const Color(0xFFC4CCDA),
  152. fontSize: 12.px,
  153. fontWeight: FontWeight.bold),
  154. textAlign: TextAlign.left,
  155. ),
  156. SizedBox(
  157. height: 8.px,
  158. ),
  159. Container(
  160. margin: EdgeInsets.only(right: 24.px),
  161. child: modeText(
  162. '预先设定每天断食时长(≥12h)并选择挑战天数。挑战期间,每晚餐后开始断食打卡、次日早餐前结束断食打卡\n\n【16/8示例】今天晚餐后🕕18:00开始断食,计划明天早餐前🕙10:00结束断食\n\n以「结束断食 打卡」为例,明天\n',
  163. TextAlign.left)),
  164. Row(
  165. children: [
  166. Image.asset(
  167. 'assets/images/green.png',
  168. width: 14.px,
  169. height: 14.px,
  170. ),
  171. SizedBox(
  172. width: 4.px,
  173. ),
  174. modeText('10:00~10:30打卡,视为准时', TextAlign.left)
  175. ],
  176. ),
  177. Row(
  178. children: [
  179. Image.asset(
  180. 'assets/images/yellow.png',
  181. width: 14.px,
  182. height: 14.px,
  183. ),
  184. SizedBox(
  185. width: 4.px,
  186. ),
  187. modeText('10:30~18:00打卡,视为超时', TextAlign.left)
  188. ],
  189. ),
  190. Row(
  191. children: [
  192. Image.asset(
  193. 'assets/images/red.png',
  194. width: 14.px,
  195. height: 14.px,
  196. ),
  197. SizedBox(
  198. width: 4.px,
  199. ),
  200. modeText('18:00后为严重超时,打卡失效', TextAlign.left)
  201. ],
  202. ),
  203. modeText('同理适用于「开始断食 打卡」\n\n当天,如果「开始断食 打卡」和「结束断食 打卡」',
  204. TextAlign.left),
  205. Row(
  206. children: [
  207. Image.asset(
  208. 'assets/images/green.png',
  209. width: 14.px,
  210. height: 14.px,
  211. ),
  212. SizedBox(
  213. width: 4.px,
  214. ),
  215. modeText('两次打卡均准时,当天视为打卡成功:', TextAlign.left)
  216. ],
  217. ),
  218. Row(
  219. children: [
  220. SizedBox(
  221. width: 18.px,
  222. ),
  223. modeText('获得+1颗逆龄石,挑战继续', TextAlign.left),
  224. Image.asset(
  225. 'assets/images/play.png',
  226. width: 14.px,
  227. height: 14.px,
  228. ),
  229. ],
  230. ),
  231. Row(
  232. children: [
  233. Image.asset(
  234. 'assets/images/yellow.png',
  235. width: 14.px,
  236. height: 14.px,
  237. ),
  238. SizedBox(
  239. width: 4.px,
  240. ),
  241. modeText('任何一次打卡超时,当天视为完成打卡:', TextAlign.left)
  242. ],
  243. ),
  244. Row(
  245. children: [
  246. SizedBox(
  247. width: 18.px,
  248. ),
  249. modeText('无法获得逆龄石,挑战继续', TextAlign.left),
  250. Image.asset(
  251. 'assets/images/play.png',
  252. width: 14.px,
  253. height: 14.px,
  254. ),
  255. ],
  256. ),
  257. Row(
  258. children: [
  259. Image.asset(
  260. 'assets/images/red.png',
  261. width: 14.px,
  262. height: 14.px,
  263. ),
  264. SizedBox(
  265. width: 4.px,
  266. ),
  267. modeText('任何一次打卡失效,当天视为打卡失败:', TextAlign.left)
  268. ],
  269. ),
  270. Row(
  271. children: [
  272. SizedBox(
  273. width: 18.px,
  274. ),
  275. modeText('无法获得逆龄石,挑战终止', TextAlign.left),
  276. Image.asset(
  277. 'assets/images/stop.png',
  278. width: 14.px,
  279. height: 14.px,
  280. ),
  281. ],
  282. ),
  283. modeText('\n如果挑战期间每天', TextAlign.left),
  284. Row(
  285. children: [
  286. Image.asset(
  287. 'assets/images/play.png',
  288. width: 14.px,
  289. height: 14.px,
  290. ),
  291. SizedBox(
  292. width: 4.px,
  293. ),
  294. modeText('连续打卡成功:视为挑战成功', TextAlign.left),
  295. ],
  296. ),
  297. Row(
  298. children: [
  299. Image.asset(
  300. 'assets/images/stop.png',
  301. width: 14.px,
  302. height: 14.px,
  303. ),
  304. SizedBox(
  305. width: 4.px,
  306. ),
  307. modeText('未连续打卡成功,但也未曾打卡失败:视为完成挑战', TextAlign.left),
  308. ],
  309. ),
  310. /*
  311. Container(
  312. margin: EdgeInsets.only(right: 12.px),
  313. child: modeText(
  314. '\n\n\n如果挑战期间每天\n➡️ 连续打卡成功:视为挑战成功\n➡️ 未连续打卡成功,但也未曾打卡失败:\n视为完成挑战',
  315. TextAlign.left),)*/
  316. ],
  317. ).width(375.px).paddingLeft(40.px).marginTop(20.px),
  318. SizedBox(
  319. height: 200.px,
  320. width: 0.px,
  321. )
  322. ],
  323. ),
  324. ),
  325. NaviBar(
  326. title: '选择模式',
  327. closeCallback: () => Navigator.of(context).pop(),
  328. showInfo: true,
  329. ),
  330. ChooseFooter(
  331. enoughStone: enoughStone,
  332. stone: stones[selType],
  333. isLock: wins[selType] > Global().userBean!.dayLevel,
  334. type: selType,
  335. callback: () {
  336. if (selType != 0 && widget.seconds < 12 * 3600) {
  337. showDialog(
  338. context: context,
  339. barrierDismissible: false,
  340. barrierColor: const Color(0xF2000D1F),
  341. builder: (BuildContext context) {
  342. return AlertWidget(
  343. title: "为获得更加显著的健康效益\n挑战者模式下的断食时长\n应大于或等于12小时",
  344. confirm: '返回重新调整',
  345. hideCancel: true,
  346. confirmCallback: () {
  347. Navigator.of(context).pop();
  348. Navigator.of(context).pop();
  349. });
  350. });
  351. return;
  352. }
  353. if (Global().allowNotification == false &&
  354. Global().pushEnable) {
  355. Util().showNotificationStatus(context);
  356. return;
  357. }
  358. Global().mainPage.getTokenId();
  359. widget.callback(selType);
  360. Navigator.of(context).pop();
  361. },
  362. )
  363. ],
  364. ),
  365. ),
  366. SizedBox(
  367. height: safePadding.bottom,
  368. )
  369. ],
  370. );
  371. }
  372. }
  373. class GetController extends GetxController {
  374. var selType = -1.obs;
  375. setType(type) {
  376. selType = type;
  377. }
  378. }
  379. // ignore: must_be_immutable
  380. class Callenage extends StatefulWidget {
  381. int selType;
  382. // ignore: prefer_typing_uninitialized_variables
  383. var callback;
  384. Callenage({Key? key, required this.selType, required this.callback})
  385. : super(key: key);
  386. @override
  387. State<Callenage> createState() => _CallenageState();
  388. }
  389. class _CallenageState extends State<Callenage> {
  390. // int selIndex = 0;
  391. void itemSel(index) {
  392. // setState(() {
  393. // selIndex = index;
  394. // });
  395. widget.selType = index;
  396. widget.callback(index);
  397. }
  398. @override
  399. Widget build(BuildContext context) {
  400. /*
  401. var widget1 = Positioned(
  402. left: 18.px,
  403. top: 0.px,
  404. width: 108.px,
  405. height: 152.px,
  406. child: CallenageItem(
  407. selIndex: selIndex,
  408. currentIndex: 1,
  409. callback: (index) => itemSel(index),
  410. ));
  411. var widget2 = Positioned(
  412. left: 135.px,
  413. top: 0.px,
  414. width: 108.px,
  415. height: 152.px,
  416. child: CallenageItem(
  417. selIndex: selIndex,
  418. currentIndex: 2,
  419. callback: (index) => itemSel(index),
  420. ));
  421. var widget3 = Positioned(
  422. left: 251.px,
  423. top: 0.px,
  424. width: 108.px,
  425. height: 152.px,
  426. child: CallenageItem(
  427. selIndex: selIndex,
  428. currentIndex: 3,
  429. callback: (index) => itemSel(index),
  430. ),
  431. );
  432. // ignore: deprecated_member_use
  433. List<Positioned> list;
  434. if (selIndex==1){
  435. list = [widget2,widget3,widget1];
  436. }
  437. else if (selIndex==2){
  438. list = [widget1,widget3,widget2];
  439. }
  440. else {
  441. list = [widget1,widget2,widget3];
  442. }
  443. return SizedBox(
  444. height: 152.px,
  445. width: 375.px,
  446. child: Stack(
  447. children: list,
  448. ),
  449. ).marginTop(20.px);*/
  450. return Row(
  451. children: [
  452. SizedBox(
  453. width: 18.px,
  454. ),
  455. CallenageItem(
  456. selIndex: widget.selType,
  457. currentIndex: 1,
  458. callback: (index) => itemSel(index),
  459. ),
  460. SizedBox(
  461. width: 8.px,
  462. ),
  463. CallenageItem(
  464. selIndex: widget.selType,
  465. currentIndex: 2,
  466. callback: (index) => itemSel(index),
  467. ),
  468. SizedBox(
  469. width: 8.px,
  470. ),
  471. CallenageItem(
  472. selIndex: widget.selType,
  473. currentIndex: 3,
  474. callback: (index) => itemSel(index),
  475. ),
  476. ],
  477. ).marginTop(20.px);
  478. }
  479. }
  480. // ignore: must_be_immutable
  481. class CallenageItem extends StatefulWidget {
  482. int selIndex, currentIndex;
  483. // ignore: prefer_typing_uninitialized_variables
  484. var callback;
  485. CallenageItem(
  486. {Key? key,
  487. required this.selIndex,
  488. required this.currentIndex,
  489. required this.callback})
  490. : super(key: key);
  491. @override
  492. State<CallenageItem> createState() => _CallenageItemState();
  493. }
  494. class _CallenageItemState extends State<CallenageItem>
  495. with SingleTickerProviderStateMixin {
  496. late AnimationController controller;
  497. late Animation<double> scale;
  498. bool expand = false;
  499. @override
  500. void initState() {
  501. super.initState();
  502. controller = AnimationController(
  503. vsync: this, duration: const Duration(milliseconds: 200));
  504. controller.addStatusListener((status) {});
  505. scale = Tween(begin: 1.0, end: 1.15).animate(controller);
  506. if (widget.selIndex == widget.currentIndex) {
  507. expand = true;
  508. controller.forward();
  509. }
  510. }
  511. @override
  512. void dispose() {
  513. controller.dispose();
  514. super.dispose();
  515. }
  516. void tapItem() {
  517. setState(() {
  518. expand = true;
  519. });
  520. widget.callback(widget.currentIndex);
  521. Timer(const Duration(milliseconds: 0), () {
  522. controller.forward();
  523. });
  524. }
  525. @override
  526. Widget build(BuildContext context) {
  527. if (expand == true && widget.selIndex != widget.currentIndex) {
  528. setState(() {
  529. expand = false;
  530. });
  531. Timer(const Duration(milliseconds: 0), () {
  532. controller.reverse();
  533. });
  534. }
  535. var stones = [1, 3, 4, 5];
  536. var wins = [1, 3, 5, 7];
  537. var path = [
  538. '',
  539. 'assets/images/3days_sel.png',
  540. 'assets/images/5days_sel.png',
  541. 'assets/images/7days_sel.png'
  542. ];
  543. return GestureDetector(
  544. onTap: () {
  545. tapItem();
  546. },
  547. child: ScaleTransition(
  548. //SizeTransition
  549. scale: scale,
  550. child: Opacity(
  551. opacity: (expand || widget.selIndex == 0) ? 1.0 : 0.6,
  552. child: Container(
  553. // width: 108.px,
  554. // height: 152.px,
  555. child: ItemContent(
  556. imgBgPath: path[widget.currentIndex],
  557. isSelected: expand,
  558. day: wins[widget.currentIndex],
  559. stone: stones[widget.currentIndex],
  560. win: wins[widget.currentIndex]),
  561. decoration: BoxDecoration(
  562. borderRadius: BorderRadius.all(Radius.circular(20.px)),
  563. border: Border.all(
  564. color: expand ? kThemeColor : Colors.transparent,
  565. width: 1.px),
  566. ),
  567. )),
  568. ),
  569. );
  570. }
  571. }
  572. // ignore: must_be_immutable
  573. class ItemContent extends StatelessWidget {
  574. String imgBgPath;
  575. int stone, win, day;
  576. bool isSelected;
  577. ItemContent(
  578. {Key? key,
  579. required this.imgBgPath,
  580. required this.isSelected,
  581. required this.stone,
  582. required this.day,
  583. required this.win})
  584. : super(key: key);
  585. Widget desc() {
  586. return Row(
  587. mainAxisAlignment: MainAxisAlignment.start,
  588. children: [
  589. SizedBox(
  590. width: 13.px,
  591. ),
  592. Text(
  593. '赚取',
  594. style: TextStyle(
  595. color: kBgColor, fontSize: 9.px, fontWeight: FontWeight.bold),
  596. ),
  597. Text(
  598. win.toString(),
  599. style: TextStyle(
  600. color: kBgColor,
  601. fontSize: 9.px,
  602. fontFamily: 'Exo2',
  603. fontWeight: FontWeight.w600),
  604. ),
  605. Image.asset(
  606. 'assets/images/stone.png',
  607. width: 9.px,
  608. height: 9.px,
  609. ),
  610. if (win == 3)
  611. Text(
  612. ',相当于免费',
  613. style: TextStyle(
  614. color: kBgColor, fontSize: 9.px, fontWeight: FontWeight.bold),
  615. ),
  616. if (win == 5 || win == 7)
  617. Text(
  618. ',净赚',
  619. style: TextStyle(
  620. color: kBgColor, fontSize: 9.px, fontWeight: FontWeight.bold),
  621. ),
  622. if (win == 5 || win == 7)
  623. Text(
  624. win == 5 ? '1' : '2',
  625. style: TextStyle(
  626. color: kBgColor,
  627. fontSize: 9.px,
  628. fontFamily: 'Exo2',
  629. fontWeight: FontWeight.w600),
  630. ),
  631. if (win == 5 || win == 7)
  632. Image.asset(
  633. 'assets/images/stone.png',
  634. width: 9.px,
  635. height: 9.px,
  636. ),
  637. ],
  638. );
  639. }
  640. @override
  641. Widget build(BuildContext context) {
  642. int level = Global().userBean!.dayLevel;
  643. print(level.toString());
  644. return Stack(
  645. children: [
  646. Container(
  647. width: 108.px,
  648. height: 152.px,
  649. decoration: BoxDecoration(
  650. color: kThemeColor,
  651. borderRadius: BorderRadius.all(Radius.circular(20.px)),
  652. image: DecorationImage(
  653. image: AssetImage(imgBgPath), fit: BoxFit.cover)),
  654. ),
  655. // Image.asset(
  656. // imgBgPath,
  657. // width: 108.px,
  658. // height: 152.px,
  659. // ),
  660. if (!isSelected)
  661. Positioned(
  662. left: 0,
  663. right: 0,
  664. bottom: 0,
  665. child: Column(
  666. children: [
  667. Container(
  668. width: 40.px,
  669. height: 1.px,
  670. color: const Color(0x66FFFFFF),
  671. ),
  672. Container(
  673. height: 47.px,
  674. alignment: Alignment.center,
  675. child: Row(
  676. mainAxisAlignment: MainAxisAlignment.center,
  677. children: [
  678. Text(
  679. '+' + win.toString(),
  680. style: TextStyle(
  681. color: Colors.white,
  682. fontWeight: FontWeight.w600,
  683. fontFamily: 'Exo2',
  684. fontSize: 16.px),
  685. ).marginBottom(4.px),
  686. Image.asset(
  687. 'assets/images/stone.png',
  688. width: 14.px,
  689. height: 14.px,
  690. ).marginLeft(3.px),
  691. Image.asset(
  692. 'assets/images/max.png',
  693. width: 30.px,
  694. height: 8.px,
  695. ).marginLeft(3.px)
  696. ]),
  697. )
  698. ],
  699. )),
  700. if (isSelected)
  701. Positioned(
  702. left: 0,
  703. right: 0,
  704. bottom: 0,
  705. child: Container(
  706. height: 42.px,
  707. alignment: Alignment.center,
  708. child: Column(
  709. mainAxisAlignment: MainAxisAlignment.center,
  710. children: [
  711. Row(
  712. mainAxisAlignment: MainAxisAlignment.start,
  713. children: [
  714. SizedBox(
  715. width: 13.px,
  716. ),
  717. Text(
  718. '投入',
  719. style: TextStyle(
  720. color: kBgColor,
  721. fontSize: 9.px,
  722. fontWeight: FontWeight.bold),
  723. ),
  724. Text(
  725. stone.toString(),
  726. style: TextStyle(
  727. color: kBgColor,
  728. fontSize: 9.px,
  729. fontFamily: 'Exo2',
  730. fontWeight: FontWeight.w600),
  731. ),
  732. Image.asset(
  733. 'assets/images/stone.png',
  734. width: 9.px,
  735. height: 9.px,
  736. ),
  737. Text(
  738. ';挑战成功',
  739. style: TextStyle(
  740. color: kBgColor,
  741. fontSize: 9.px,
  742. fontWeight: FontWeight.bold),
  743. ),
  744. ],
  745. ),
  746. desc()
  747. ],
  748. ),
  749. decoration: BoxDecoration(
  750. borderRadius: BorderRadius.only(
  751. bottomLeft: Radius.circular(18.px),
  752. bottomRight: Radius.circular(18.px)),
  753. gradient: const LinearGradient(
  754. begin: Alignment.topCenter,
  755. end: Alignment.bottomCenter,
  756. colors: [kThemeColor, Color(0x99AAFF00)])),
  757. ),
  758. ),
  759. if (isSelected)
  760. Container(
  761. width: 39.px,
  762. height: 39.px,
  763. decoration: BoxDecoration(
  764. borderRadius:
  765. BorderRadius.only(topLeft: Radius.circular(18.px)),
  766. image: DecorationImage(
  767. image: day > Global().userBean!.dayLevel
  768. ? const AssetImage('assets/images/mode_lock.png')
  769. : const AssetImage('assets/images/mode_checked.png'))),
  770. ),
  771. ],
  772. );
  773. }
  774. }
  775. // ignore: must_be_immutable
  776. class ChooseFooter extends StatelessWidget {
  777. bool enoughStone = true;
  778. bool isLock;
  779. int stone;
  780. int type;
  781. // ignore: prefer_typing_uninitialized_variables
  782. var callback;
  783. ChooseFooter(
  784. {Key? key,
  785. required this.enoughStone,
  786. required this.isLock,
  787. required this.stone,
  788. required this.type,
  789. required this.callback})
  790. : super(key: key);
  791. @override
  792. Widget build(BuildContext context) {
  793. List locks = [0, 1, 3, 5];
  794. return Positioned(
  795. child: Container(
  796. height: 160.px,
  797. padding: EdgeInsets.only(top: 38.px),
  798. decoration: const BoxDecoration(
  799. gradient: LinearGradient(
  800. begin: Alignment.topCenter,
  801. end: Alignment.bottomCenter,
  802. colors: [
  803. Color(0x33000D1F),
  804. kBgColor,
  805. kBgColor,
  806. kBgColor,
  807. kBgColor
  808. ])),
  809. child: Column(
  810. children: [
  811. if (isLock)
  812. GestureDetector(
  813. onTap: () => {Vibrate.feedback(FeedbackType.success)},
  814. child: Opacity(
  815. opacity: 0.4,
  816. child: Container(
  817. width: 248.px,
  818. height: 48.px,
  819. alignment: Alignment.center,
  820. decoration: BoxDecoration(
  821. borderRadius: BorderRadius.all(Radius.circular(24.px)),
  822. color: kThemeColor),
  823. child: Image.network(
  824. '${baseUrl}must_done_${locks[type]}.png',
  825. width: 209.px,
  826. height: 24.px,
  827. ),
  828. ),
  829. ),
  830. ).paddingBottom(17.px),
  831. if (!isLock && enoughStone)
  832. FastBtn(
  833. title: '立即开始',
  834. disable: !enoughStone,
  835. width: 248.px,
  836. height: 48.px,
  837. callback: callback,
  838. ).paddingBottom(17.px),
  839. if (!enoughStone && !isLock)
  840. GestureDetector(
  841. onTap: () {
  842. Get.to(() => const Recharge());
  843. },
  844. child: Container(
  845. width: 248.px,
  846. height: 48.px,
  847. alignment: Alignment.center,
  848. decoration: BoxDecoration(
  849. borderRadius: BorderRadius.all(Radius.circular(24.px)),
  850. border: Border.all(color: kThemeColor, width: 1.px),
  851. color: const Color(0x33C4CCDA),
  852. ),
  853. child: Text(
  854. '立即充值',
  855. style: TextStyle(
  856. color: kThemeColor,
  857. fontSize: 16.px,
  858. fontWeight: FontWeight.bold),
  859. ),
  860. ).paddingBottom(17.px),
  861. ),
  862. if (enoughStone)
  863. Row(
  864. mainAxisAlignment: MainAxisAlignment.center,
  865. children: [
  866. Text(
  867. type == 0 ? '开始将消耗 $stone' : '开始将投入 $stone',
  868. style: TextStyle(
  869. color: const Color(0x99FFFFFF),
  870. fontSize: 12.px,
  871. fontFamily: 'Exo2',
  872. fontWeight: FontWeight.w600),
  873. ),
  874. Image.asset(
  875. 'assets/images/stone.png',
  876. width: 14.px,
  877. height: 14.px,
  878. )
  879. ],
  880. )
  881. else
  882. Row(
  883. mainAxisAlignment: MainAxisAlignment.center,
  884. children: [
  885. Text(
  886. '余额 ${Global().balance}',
  887. style: TextStyle(
  888. color: const Color(0x99FFFFFF),
  889. fontSize: 12.px,
  890. fontFamily: 'Exo2',
  891. fontWeight: FontWeight.w600),
  892. ),
  893. Image.asset(
  894. 'assets/images/stone.png',
  895. width: 14.px,
  896. height: 14.px,
  897. ),
  898. Text(
  899. ',开始需要 $stone',
  900. style: TextStyle(
  901. color: const Color(0x99FFFFFF),
  902. fontSize: 12.px,
  903. fontFamily: 'Exo2',
  904. fontWeight: FontWeight.w600),
  905. ),
  906. Image.asset(
  907. 'assets/images/stone.png',
  908. width: 14.px,
  909. height: 14.px,
  910. )
  911. ],
  912. ),
  913. if (!enoughStone)
  914. Row(
  915. mainAxisAlignment: MainAxisAlignment.center,
  916. children: [
  917. GestureDetector(
  918. onTap: () {
  919. showShare(context);
  920. },
  921. child: Text('邀请好友',
  922. style: TextStyle(
  923. color: kThemeColor,
  924. fontSize: 12.px,
  925. fontFamily: 'Exo2',
  926. fontWeight: FontWeight.w600)),
  927. ),
  928. Text(
  929. ',好友加入时我和ta各得 +3',
  930. style: TextStyle(
  931. color: const Color(0x99FFFFFF),
  932. fontSize: 12.px,
  933. fontFamily: 'Exo2',
  934. fontWeight: FontWeight.w600),
  935. ),
  936. Image.asset(
  937. 'assets/images/stone.png',
  938. width: 14.px,
  939. height: 14.px,
  940. )
  941. ],
  942. ).marginTop(5.px)
  943. ],
  944. ),
  945. ),
  946. left: 0,
  947. right: 0,
  948. bottom: 0,
  949. );
  950. }
  951. showShare(BuildContext context) {
  952. showDialog(
  953. context: context,
  954. barrierDismissible: false,
  955. barrierColor: const Color(0xF2000D1F),
  956. builder: (BuildContext context) {
  957. return Share(
  958. type: 'me',
  959. );
  960. });
  961. }
  962. }