main_page.dart 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. import 'dart:io';
  2. import 'dart:ui';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_map/flutter_map.dart';
  6. import 'package:flutter_screenutil/flutter_screenutil.dart';
  7. import 'package:get/get.dart';
  8. import 'package:location/base/base_page.dart';
  9. import 'package:location/data/bean/user_info.dart';
  10. import 'package:location/module/main/main_controller.dart';
  11. import 'package:location/module/main/today_track_helper.dart';
  12. import 'package:location/module/main/view.dart';
  13. import 'package:location/resource/assets.gen.dart';
  14. import 'package:location/resource/colors.gen.dart';
  15. import 'package:location/resource/string.gen.dart';
  16. import 'package:location/utils/common_expand.dart';
  17. import 'package:location/widget/shimmer_effect.dart';
  18. import 'package:sliding_sheet2/sliding_sheet2.dart';
  19. import 'package:visibility_detector/visibility_detector.dart';
  20. import '../../data/consts/constants.dart';
  21. import '../../resource/fonts.gen.dart';
  22. import '../../router/app_pages.dart';
  23. import '../../utils/common_style.dart';
  24. import '../../utils/common_util.dart';
  25. import '../../widget/activity_countdown_txt_view.dart';
  26. import '../../widget/marquee_text.dart';
  27. import '../../widget/relative_time_text.dart';
  28. import 'main_common_view.dart';
  29. import 'main_friend_item.dart';
  30. class MainPage extends BasePage<MainController> {
  31. const MainPage({super.key});
  32. static start({bool? isNotClear, Map<String, dynamic>? arguments}) {
  33. if (isNotClear == null || !isNotClear) {
  34. Get.offAllNamed(RoutePath.mainTab, arguments: arguments);
  35. } else {
  36. Get.toNamed(RoutePath.mainTab, arguments: arguments);
  37. }
  38. }
  39. @override
  40. bool immersive() {
  41. return true;
  42. }
  43. @override
  44. Widget buildBody(BuildContext context) {
  45. return PopScope(
  46. canPop: false,
  47. onPopInvokedWithResult: (bool didPop, dynamic result) {
  48. controller.onAppBack();
  49. },
  50. child: Stack(
  51. children: [
  52. buildMapView(),
  53. buildMainCaringReportView(),
  54. buildMainFunView(),
  55. buildMapFunView(),
  56. buildMapLogoView(),
  57. buildMainSlidingSheetView(),
  58. ],
  59. ),
  60. );
  61. }
  62. Widget buildMainFunView() {
  63. return Positioned(
  64. right: 12.w,
  65. top: 35.w,
  66. child: SafeArea(
  67. child: Column(
  68. children: [
  69. Container(
  70. child: buildMainFunctionView(
  71. Assets.images.iconMainMine.provider(),
  72. StringName.mainTabMine,
  73. onTap: controller.onMineClick)),
  74. SizedBox(height: 20.w),
  75. Container(
  76. child: buildMainFunctionView(
  77. Assets.images.iconMainFriend.provider(),
  78. StringName.mainTabFriend,
  79. onTap: controller.onFriendClick)),
  80. SizedBox(height: 20.w),
  81. Container(
  82. child: buildMainFunctionView(
  83. Assets.images.iconMainNews.provider(),
  84. StringName.mainTabNews,
  85. onTap: controller.onNewsClick)),
  86. SizedBox(height: 20.w),
  87. ],
  88. ),
  89. ),
  90. );
  91. }
  92. Widget buildMainCaringReportView() {
  93. return Positioned(
  94. left: -8.w,
  95. top: 6.w,
  96. child: SafeArea(
  97. child: SizedBox(
  98. width: 210.w,
  99. child: AspectRatio(
  100. aspectRatio: 187 / 69,
  101. child: Assets.images.imgMainCaringReport.image(),
  102. ),
  103. )),
  104. );
  105. }
  106. Widget buildMapView() {
  107. return Padding(
  108. padding: EdgeInsets.only(bottom: 50.h),
  109. child: SizedBox(
  110. width: double.infinity,
  111. child: MapWidget(
  112. controller: controller.mapController,
  113. onMarkerTap: controller.onMarkerTap,
  114. )),
  115. );
  116. }
  117. Widget buildMainSlidingSheetView() {
  118. return Obx(() {
  119. if (controller.lastSelectedGoods == null) {
  120. return buildSlidingSheet(false);
  121. } else {
  122. return buildSlidingSheet(true);
  123. }
  124. });
  125. }
  126. SlidingSheet buildSlidingSheet(bool isShowActivity) {
  127. return SlidingSheet(
  128. listener: (SheetState state) {
  129. controller.setSheetProgress(state.progress);
  130. },
  131. key: Key(isShowActivity ? 'activity_view' : 'not_activity_view'),
  132. color: ColorName.transparent,
  133. snapSpec: SnapSpec(
  134. initialSnap: SnapSpec.headerSnap,
  135. // Enable snapping. This is true by default.
  136. snap: true,
  137. // Set custom snapping points.
  138. snappings: [SnapSpec.headerSnap, SnapSpec.expanded],
  139. // Define to what the snappings relate to. In this case,
  140. // the total available space that the sheet can expand to.
  141. positioning: SnapPositioning.relativeToAvailableSpace,
  142. ),
  143. headerBuilder: (BuildContext context, SheetState state) {
  144. return buildHeaderView(isShowActivity);
  145. },
  146. builder: buildTrackEntranceBuilder,
  147. );
  148. }
  149. Widget buildTrackEntranceBuilder(BuildContext context, SheetState state) {
  150. return VisibilityDetector(
  151. key: Key('main_today_track'),
  152. onVisibilityChanged: (VisibilityInfo info) {
  153. final visibleFraction = info.visibleFraction;
  154. controller.onFriendVisibleFraction(visibleFraction);
  155. },
  156. child: Container(
  157. color: '#EFF4FC'.color,
  158. child: AspectRatio(
  159. aspectRatio: 336 / 134,
  160. child: Container(
  161. margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 12.w),
  162. decoration: BoxDecoration(
  163. color: Colors.white,
  164. borderRadius: BorderRadius.circular(20.r)),
  165. child: Obx(() {
  166. final todayTrack = controller.selectedFriend?.id == null
  167. ? null
  168. : controller
  169. .todayTrackReportMap[controller.selectedFriend?.id];
  170. return buildTodayTrackView(todayTrack);
  171. })),
  172. ),
  173. ),
  174. );
  175. }
  176. Widget buildTodayTrackView(TodayTrackReportBean? todayTrack) {
  177. return Stack(children: [
  178. buildTodayTrackDetailView(todayTrack),
  179. Visibility(
  180. visible:
  181. todayTrack == null || todayTrack.isRequestSuccess.value == false,
  182. child: buildTodayTrackLoadingView()),
  183. Visibility(
  184. visible: controller.memberStatusInfo.value == null ||
  185. controller.memberStatusInfo.value?.expired == true,
  186. child: buildNoMemberView())
  187. ]);
  188. }
  189. Widget buildNoMemberView() {
  190. return GestureDetector(
  191. onTap: controller.onTrackNoMemberClick,
  192. child: Assets.images.imgTrackNoMemberTips
  193. .image(width: double.infinity, fit: BoxFit.fill));
  194. }
  195. Widget buildTodayTrackLoadingView() {
  196. return Container(
  197. width: double.infinity,
  198. height: double.infinity,
  199. decoration: BoxDecoration(
  200. color: Colors.white, borderRadius: BorderRadius.circular(20.r)),
  201. child: Column(
  202. mainAxisAlignment: MainAxisAlignment.center,
  203. children: [
  204. CupertinoActivityIndicator(
  205. color: '#A3A3A5'.color,
  206. radius: 16.w,
  207. ),
  208. SizedBox(height: 15.w),
  209. Text(StringName.mainTodayTrackLoading,
  210. style: TextStyle(
  211. fontSize: 14.sp, color: '#666666'.color.withOpacity(0.87)))
  212. ],
  213. ),
  214. );
  215. }
  216. Widget buildTodayTrackDetailView(TodayTrackReportBean? todayTrackReportBean) {
  217. return GestureDetector(
  218. behavior: HitTestBehavior.opaque,
  219. onTap: controller.onTodayTraceClick,
  220. child: Padding(
  221. padding:
  222. EdgeInsets.only(left: 12.w, right: 12.w, top: 12.w, bottom: 9.w),
  223. child: Column(
  224. children: [
  225. Row(
  226. children: [
  227. Text(StringName.todaySimpleTrack,
  228. style: TextStyle(
  229. fontSize: 13.sp,
  230. color: '#333333'.color,
  231. fontWeight: FontWeight.bold)),
  232. Spacer(),
  233. Assets.images.iconMainTrackArrow
  234. .image(width: 10.w, height: 10.w),
  235. ],
  236. ),
  237. SizedBox(height: 7.w),
  238. buildSelectedFriendTodayTrackDetailView(todayTrackReportBean),
  239. ],
  240. ),
  241. ),
  242. );
  243. }
  244. Widget buildSelectedFriendTodayTrackDetailView(
  245. TodayTrackReportBean? todayTrackReportBean) {
  246. final startAddr = todayTrackReportBean?.startPoint?.addr;
  247. final errorAddr = todayTrackReportBean?.exceptionPoint?.addr;
  248. MainTrackType startPointType = startAddr?.isNotEmpty == true
  249. ? MainTrackType.startPoint
  250. : MainTrackType.normalPoint;
  251. MainTrackType errorPointType = errorAddr?.isNotEmpty == true
  252. ? MainTrackType.errorPoint
  253. : MainTrackType.normalPoint;
  254. Color startPointColor;
  255. if (startPointType == MainTrackType.startPoint) {
  256. startPointColor = '#15CBA1'.color;
  257. } else if (startPointType == MainTrackType.errorPoint) {
  258. startPointColor = '#E94949'.color;
  259. } else {
  260. startPointColor = '#D6D6D6'.color;
  261. }
  262. Color errorPointColor;
  263. if (errorPointType == MainTrackType.errorPoint) {
  264. errorPointColor = '#E94949'.color;
  265. } else {
  266. errorPointColor = '#D6D6D6'.color;
  267. }
  268. return Expanded(
  269. child: Row(
  270. children: [
  271. Container(
  272. margin: EdgeInsets.only(bottom: 3.w, top: 3.w),
  273. child: AspectRatio(
  274. aspectRatio: 1,
  275. child: Stack(
  276. children: [
  277. buildTodayMapView(todayTrackReportBean),
  278. GestureDetector(
  279. behavior: HitTestBehavior.opaque,
  280. onTap: controller.onTodayTraceClick,
  281. child: SizedBox(
  282. width: double.infinity,
  283. height: double.infinity,
  284. ),
  285. )
  286. ],
  287. ),
  288. ),
  289. ),
  290. SizedBox(width: 10.w),
  291. Column(
  292. mainAxisAlignment: MainAxisAlignment.center,
  293. children: [
  294. SizedBox(height: 6.w),
  295. getMainTrackDot(startPointColor),
  296. Expanded(
  297. child: Container(
  298. margin: EdgeInsets.symmetric(vertical: 4.w),
  299. width: 1.w,
  300. height: double.infinity,
  301. decoration: BoxDecoration(
  302. color: '#F0F0F0'.color,
  303. borderRadius: BorderRadius.circular(100.r),
  304. ),
  305. ),
  306. ),
  307. getMainTrackDot(errorPointColor),
  308. SizedBox(height: 6.w),
  309. ],
  310. ),
  311. SizedBox(width: 8.w),
  312. Expanded(
  313. child: Column(
  314. crossAxisAlignment: CrossAxisAlignment.start,
  315. children: [
  316. Visibility(
  317. visible: startPointType == MainTrackType.normalPoint,
  318. child: SizedBox(height: 2.w)),
  319. buildTrackPoint(startPointType, startAddr ?? ''),
  320. Spacer(),
  321. buildTrackPoint(errorPointType, errorAddr ?? ''),
  322. Visibility(
  323. visible: errorPointType == MainTrackType.normalPoint,
  324. child: SizedBox(height: 5.w))
  325. ],
  326. ),
  327. )
  328. ],
  329. ));
  330. }
  331. Widget buildTodayMapView(TodayTrackReportBean? todayTrackReportBean) {
  332. return ClipRRect(
  333. borderRadius: BorderRadius.circular(8.r),
  334. child: MapWidget(
  335. controller: controller.todayTrackSmallMapController,
  336. isShowLogo: false,
  337. interactionIsEnabled: false,
  338. mapPadding: todayTrackReportBean?.mapPadding,
  339. markers: todayTrackReportBean?.markers,
  340. polyline: todayTrackReportBean?.polylines,
  341. ));
  342. }
  343. Widget buildMapLogoView() {
  344. return Visibility(
  345. visible: Platform.isAndroid,
  346. child: Obx(() {
  347. return Positioned(
  348. left: 12.w,
  349. bottom: 136.w +
  350. (controller.lastSelectedGoods != null ? 64.w : 0) +
  351. controller.sheetProgress * 143.w,
  352. child: Column(
  353. crossAxisAlignment: CrossAxisAlignment.start,
  354. children: [
  355. Assets.images.iconAmapLogo.image(height: 20.w),
  356. Text(StringName.locationAmapCo,
  357. style: TextStyle(
  358. fontSize: 9.sp, color: '#666666'.color, height: 1))
  359. ],
  360. ));
  361. }),
  362. );
  363. }
  364. Widget buildMapFunView() {
  365. return Obx(() {
  366. return Positioned(
  367. right: 12.w,
  368. bottom: 110.w +
  369. (controller.lastSelectedGoods != null ? 64.w : 0) +
  370. controller.sheetProgress * 143.w,
  371. child: Column(
  372. children: [
  373. GestureDetector(
  374. onTap: controller.onRefreshFriendLocationClick,
  375. child: buildMainFunctionView(
  376. Assets.images.iconMainRefresh.provider(), '',
  377. onTap: controller.onRefreshFriendLocationClick),
  378. ),
  379. SizedBox(height: 20.w),
  380. GestureDetector(
  381. onTap: controller.onCurrentLocationClick,
  382. child: buildMainFunctionView(
  383. Assets.images.iconMainLocation.provider(), '',
  384. onTap: controller.onCurrentLocationClick),
  385. ),
  386. SizedBox(height: 20.w)
  387. ],
  388. ),
  389. );
  390. });
  391. }
  392. Widget buildFunItem(ImageProvider imgProvider, String title, Function() onTap,
  393. {bool? isShowDot}) {
  394. return GestureDetector(
  395. onTap: onTap,
  396. child: IntrinsicHeight(
  397. child: Column(
  398. children: [
  399. Stack(children: [
  400. SizedBox(
  401. width: 44.w, height: 44.w, child: Image(image: imgProvider)),
  402. Visibility(
  403. visible: isShowDot ?? false,
  404. child: Positioned(
  405. top: 6.w,
  406. right: 6.w,
  407. child: Container(
  408. width: 10.w,
  409. height: 10.w,
  410. decoration: BoxDecoration(
  411. shape: BoxShape.circle,
  412. color: '#FF333D'.color, // 背景颜色
  413. ),
  414. ),
  415. ),
  416. )
  417. ]),
  418. Text(title,
  419. style: TextStyle(
  420. fontSize: 12.sp,
  421. color: ColorName.black70,
  422. fontWeight: FontWeight.bold))
  423. ],
  424. ),
  425. ),
  426. );
  427. }
  428. Widget buildHeaderBuilder(BuildContext context, SheetState state) {
  429. return buildHeaderView(false);
  430. }
  431. Widget buildHeaderView(bool isShowActivity) {
  432. return IntrinsicHeight(
  433. child: Column(
  434. children: [
  435. Visibility(visible: isShowActivity, child: buildActivityMemberView()),
  436. buildSelectFriendPlateView()
  437. ],
  438. ));
  439. }
  440. Widget buildSelectFriendPlateView() {
  441. return Container(
  442. width: double.infinity,
  443. padding: EdgeInsets.only(left: 1.5.w, top: 1.5.w, right: 1.5.w),
  444. decoration: BoxDecoration(
  445. borderRadius: BorderRadius.only(
  446. topLeft: Radius.circular(12.r), topRight: Radius.circular(12.r)),
  447. gradient: LinearGradient(
  448. begin: Alignment.topCenter,
  449. end: Alignment.bottomCenter,
  450. colors: [
  451. Colors.white,
  452. '#EFF4FC'.color,
  453. ])),
  454. child: Container(
  455. width: double.infinity,
  456. decoration: BoxDecoration(
  457. color: '#EFF4FC'.color,
  458. borderRadius: BorderRadius.only(
  459. topLeft: Radius.circular(12.w),
  460. topRight: Radius.circular(12.w))),
  461. child: Column(
  462. children: [
  463. SizedBox(height: 7.h),
  464. Container(
  465. width: 24.w,
  466. height: 3.h,
  467. decoration: BoxDecoration(
  468. color: '#CDE0FF'.color,
  469. borderRadius: BorderRadius.all(Radius.circular(49.w))),
  470. ),
  471. SizedBox(height: 5.h),
  472. buildFriendPlateListView(),
  473. SizedBox(height: 12.h)
  474. ],
  475. )),
  476. );
  477. }
  478. Widget buildFriendPlateListView() {
  479. return SizedBox(
  480. width: double.infinity,
  481. height: 68.h,
  482. child: Row(
  483. children: [
  484. Expanded(child: Obx(() {
  485. return PageView.builder(
  486. controller: controller.pageController,
  487. onPageChanged: controller.onFriendPageChanged,
  488. physics: const BouncingScrollPhysics(),
  489. itemBuilder: (ctx, index) =>
  490. _buildFriendListItem(controller.integrateList[index]),
  491. itemCount: controller.integrateList.length);
  492. })),
  493. Obx(() {
  494. return Visibility(
  495. visible: controller.friendsList.isNotEmpty,
  496. child: Container(
  497. padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 6.w),
  498. decoration: BoxDecoration(
  499. color: Colors.white,
  500. borderRadius: BorderRadius.only(
  501. topLeft: Radius.circular(10.r),
  502. bottomLeft: Radius.circular(10.r)),
  503. ),
  504. child: IntrinsicHeight(
  505. child: Column(
  506. children: [
  507. Text(StringName.mainLeftSlipSwitch,
  508. style: TextStyle(
  509. fontSize: 8.sp,
  510. color: ColorName.colorPrimary,
  511. fontWeight: FontWeight.bold)),
  512. SizedBox(height: 2.w),
  513. Assets.images.iconMainLeftSlipArrow
  514. .image(width: 5.w, height: 5.w)
  515. ],
  516. ),
  517. ),
  518. ),
  519. );
  520. })
  521. ],
  522. ),
  523. );
  524. }
  525. Widget _buildFriendListItem(UserInfo userInfo) {
  526. return Obx(() {
  527. return Padding(
  528. padding: EdgeInsets.only(
  529. left: 12.w, right: controller.friendsList.isNotEmpty ? 8.w : 12.w),
  530. child: buildSelectFriendInfoView(userInfo, controller.memberStatusInfo,
  531. onTraceClick: controller.onViewTraceClick),
  532. );
  533. });
  534. }
  535. Widget buildActivityMemberView() {
  536. return GestureDetector(
  537. behavior: HitTestBehavior.opaque,
  538. onTap: controller.onBuyMemberActivityClick,
  539. child: Container(
  540. height: 56.w,
  541. margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 8.w),
  542. decoration: BoxDecoration(
  543. borderRadius: BorderRadius.all(Radius.circular(12.r)),
  544. gradient: LinearGradient(
  545. colors: [
  546. '#FFEEE9'.color,
  547. Colors.white,
  548. ],
  549. stops: [0.0, 0.8],
  550. begin: Alignment.topCenter,
  551. end: Alignment.bottomCenter,
  552. )),
  553. child: ShimmerEffect(
  554. image: Assets.images.imgMemberBtnShadow.provider(),
  555. child: Stack(
  556. children: [
  557. Row(
  558. children: [
  559. SizedBox(width: 12.w),
  560. Assets.images.iconMemberActivityCoupon
  561. .image(width: 40.w, height: 40.w),
  562. SizedBox(width: 8.w),
  563. Column(
  564. crossAxisAlignment: CrossAxisAlignment.start,
  565. children: [
  566. Spacer(flex: 1),
  567. Row(
  568. children: [
  569. Text('您有一订单未支付专属优惠券',
  570. style: TextStyle(
  571. fontSize: 10.sp,
  572. color: '#202020'.color,
  573. fontWeight: FontWeight.bold)),
  574. Obx(() {
  575. return Text(
  576. ' -¥${(((controller.lastSelectedGoods?.originalAmount ?? 0) - (controller.lastSelectedGoods?.amount ?? 0)) / 100).toInt()}',
  577. style: TextStyle(
  578. fontSize: 20.sp,
  579. color: '#E74E4E'.color,
  580. fontWeight: FontWeight.bold));
  581. })
  582. ],
  583. ),
  584. Row(
  585. crossAxisAlignment: CrossAxisAlignment.start,
  586. children: [
  587. Obx(() {
  588. return ActivityCountdownTextView(
  589. timeItemHeight: 15.w,
  590. contentPadding:
  591. EdgeInsets.symmetric(horizontal: 2.w),
  592. textStyle: TextStyle(
  593. fontSize: 11.sp,
  594. color: '#E74F4F'.color,
  595. fontWeight: FontWeight.w500,
  596. ),
  597. duration: controller.activityDuration ??
  598. Duration(seconds: 0),
  599. separator: buildCountdownSeparator(),
  600. timeBgBoxDecoration: BoxDecoration(
  601. gradient: LinearGradient(colors: [
  602. '#FFEFEF'.color,
  603. '#FFEFEF'.color,
  604. ]),
  605. borderRadius: BorderRadius.circular(3.w),
  606. ));
  607. }),
  608. SizedBox(width: 4.w),
  609. Text(
  610. StringName.memberActivitySpeciallyPreferential,
  611. style: TextStyle(
  612. fontSize: 10.sp,
  613. color: '#202020'.color,
  614. ),
  615. )
  616. ],
  617. ),
  618. Spacer(flex: 4),
  619. ],
  620. ),
  621. ],
  622. ),
  623. Positioned(
  624. top: 15.w,
  625. bottom: 14.w,
  626. right: 10.w,
  627. child: Container(
  628. decoration: BoxDecoration(
  629. borderRadius: BorderRadius.circular(8.w),
  630. gradient: LinearGradient(
  631. colors: [
  632. '#FA6565'.color,
  633. '#D565FA'.color,
  634. ],
  635. ),
  636. ),
  637. padding:
  638. EdgeInsets.symmetric(horizontal: 14.w, vertical: 7.w),
  639. child: Center(
  640. child: Text(StringName.memberActivityToBuy,
  641. style: TextStyle(
  642. fontSize: 12.sp,
  643. color: Colors.white,
  644. height: 1,
  645. fontWeight: FontWeight.bold)),
  646. )),
  647. )
  648. ],
  649. )),
  650. ),
  651. );
  652. }
  653. Widget buildCountdownSeparator() {
  654. return Container(
  655. margin: EdgeInsets.symmetric(horizontal: 2.w),
  656. child: IntrinsicHeight(
  657. child: Column(
  658. children: [
  659. Container(
  660. width: 2.w,
  661. height: 2.w,
  662. decoration: BoxDecoration(
  663. color: '#E74F4F'.color,
  664. shape: BoxShape.circle,
  665. ),
  666. ),
  667. SizedBox(height: 3.w),
  668. Container(
  669. width: 2.w,
  670. height: 2.w,
  671. decoration: BoxDecoration(
  672. color: '#E74F4F'.color,
  673. shape: BoxShape.circle,
  674. ),
  675. )
  676. ],
  677. ),
  678. ),
  679. );
  680. }
  681. }