calendar_detail.dart 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. import 'dart:async';
  2. import 'package:fast/constants.dart';
  3. import 'package:fast/extension/relation.dart';
  4. import 'package:fast/model/model.dart';
  5. import 'package:fast/utils/api.dart';
  6. import 'package:fast/utils/global.dart';
  7. import 'package:fast/utils/http_utils.dart';
  8. import 'package:fast/utils/size_fit.dart';
  9. import 'package:fast/utils/util.dart';
  10. import 'package:fast/view/component/navi_bar.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:get/get.dart';
  13. import 'component/calendar_item.dart';
  14. import 'component/loading.dart';
  15. GlobalKey selKey = GlobalKey();
  16. // ignore: must_be_immutable
  17. class CalendarDetail extends StatefulWidget {
  18. List<dynamic> calendarList;
  19. int selDay, selMonth, selYear;
  20. CalendarDetail(
  21. {Key? key,
  22. required this.calendarList,
  23. required this.selYear,
  24. required this.selMonth,
  25. required this.selDay})
  26. : super(key: key);
  27. @override
  28. State<CalendarDetail> createState() => _CalendarDetailState();
  29. }
  30. class _CalendarDetailState extends State<CalendarDetail> {
  31. late ScrollController controller;
  32. late List<CalendarItemBean> calendars;
  33. bool isLoading = true;
  34. double top = 0.0;
  35. @override
  36. void initState() {
  37. controller = ScrollController();
  38. calendars = [];
  39. // Timer(const Duration(milliseconds: 500), () {
  40. // final RenderBox widget =
  41. // selKey.currentContext!.findRenderObject() as RenderBox;
  42. // var offset = widget.localToGlobal(Offset.zero);
  43. // controller.animateTo(offset.dy - top - 40.px,
  44. // duration: const Duration(milliseconds: 400), curve: Curves.linear);
  45. // // controller.jumpTo(offset.dy);
  46. // var size = 0;
  47. // });
  48. getRecords();
  49. super.initState();
  50. }
  51. @override
  52. void dispose() {
  53. controller.dispose();
  54. super.dispose();
  55. }
  56. DateTime serverTime() {
  57. int milliseconds = DateTime.now().millisecondsSinceEpoch;
  58. milliseconds = milliseconds + Global().timeSeconds * 1000;
  59. return DateTime.fromMillisecondsSinceEpoch(milliseconds);
  60. }
  61. Future getRecords() async {
  62. Map<String, dynamic> data = await HttpUtils.get(Api.records,
  63. params: {"day_begin": "20220101", "day_end": "20221212"});
  64. initCalendar(data);
  65. Timer(const Duration(seconds: 1), () {
  66. setState(() {
  67. isLoading = false;
  68. });
  69. });
  70. }
  71. initCalendar(data) {
  72. List<CalendarItemBean> list = [];
  73. for (int i = 0; i < widget.calendarList.length; i++) {
  74. List<CalendarItemBean> array = widget.calendarList[i];
  75. for (var e in array) {
  76. if (e.day != null) {
  77. list.add(e);
  78. }
  79. }
  80. }
  81. //贴纸
  82. for (int i = 0; i < data['records'].length; i++) {
  83. var fastObj = data['records'][i];
  84. if (fastObj['mode'] == 'CHALLENGER' &&
  85. (fastObj['status'] == 'DOING' ||
  86. fastObj['status'] == 'END' ||
  87. fastObj['status'] == 'TIMEOUT' ||
  88. fastObj['status'] == 'EXIT') &&
  89. fastObj['checkin_days'].length > 0) {
  90. int startTime = fastObj['checkin_days'][0]['start_time'];
  91. int endTime = fastObj['checkin_days']
  92. [fastObj['checkin_days'].length - 1]['end_time'];
  93. for (CalendarItemBean bean in list) {
  94. int? year = bean.year;
  95. int? month = bean.month;
  96. int? day = bean.day;
  97. int startTimeStamp =
  98. DateTime(year!, month!, day!).millisecondsSinceEpoch ~/ 1000;
  99. int endTimeStamp = startTimeStamp + 24 * 3600;
  100. double startPercent = 0.0;
  101. double widthPercent = 0.0;
  102. if ((startTimeStamp < startTime && endTimeStamp < startTime) ||
  103. (startTimeStamp > endTime && endTimeStamp > endTime)) {
  104. } else {
  105. if (startTimeStamp < startTime) {
  106. startPercent = (startTime - startTimeStamp) / (24 * 3600);
  107. if (endTimeStamp < endTime) {
  108. widthPercent = (endTimeStamp - startTime) / (24 * 3600);
  109. } else {
  110. widthPercent = (endTime - startTime) / (24 * 3600);
  111. }
  112. } else {
  113. if (endTimeStamp <= endTime) {
  114. widthPercent = 1.0;
  115. } else {
  116. widthPercent = (endTime - startTimeStamp) / (24 * 3600);
  117. }
  118. }
  119. RecordSticker sticker = RecordSticker();
  120. sticker.begin = startPercent;
  121. sticker.width = widthPercent;
  122. sticker.days = fastObj['days'];
  123. if (bean.recordItem == null) {
  124. RecordItem item = RecordItem();
  125. bean.recordItem = item;
  126. }
  127. if (bean.recordItem!.stickers == null) {
  128. List<RecordSticker> stickers = [];
  129. bean.recordItem!.stickers = stickers;
  130. }
  131. bean.recordItem!.stickers!.add(sticker);
  132. }
  133. }
  134. }
  135. }
  136. //正在进行的进度条背景
  137. if (data['records'].length > 0 &&
  138. data['records'][data['records'].length - 1]['status'] == 'DOING') {
  139. List<dynamic> array;
  140. if (data['records'][data['records'].length - 1]['mode'] == 'SINGLE') {
  141. var singleObj = data['records'][data['records'].length - 1];
  142. array = [
  143. {
  144. "day_num": singleObj['begin_day_num'],
  145. "start_time": singleObj['start_time'],
  146. "end_time": singleObj['end_time'],
  147. "cross_day": singleObj['cross_day']
  148. }
  149. ];
  150. } else {
  151. array = data['records'][data['records'].length - 1]['checkin_days'];
  152. }
  153. for (var obj in array) {
  154. int year = Util().getYearFromTimenum(obj['day_num']);
  155. int month = Util().getMonthFromTimenum(obj['day_num']);
  156. int day = Util().getDayFromTimenum(obj['day_num']);
  157. int time = DateTime(year, month, day).millisecondsSinceEpoch ~/ 1000;
  158. DateTime dateTime = DateTime(year, month, day + 1);
  159. int year1 = dateTime.year;
  160. int month1 = dateTime.month;
  161. int day1 = dateTime.day;
  162. int time1 = dateTime.millisecondsSinceEpoch ~/ 1000;
  163. double beginProgress = (obj['start_time'] - time) / (24 * 3600);
  164. double widthProgress =
  165. (obj['end_time'] - obj['start_time']) / (24 * 3600);
  166. double beginProgress2 = 0.0;
  167. double widthProgress2 = 0.0;
  168. if (obj['cross_day']) {
  169. widthProgress = 1.0 - beginProgress;
  170. widthProgress2 = (obj['end_time'] - time1) / (24 * 3600);
  171. }
  172. int now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
  173. bool foundCurrent = false;
  174. if (obj['start_time'] <= now && now <= obj['end_time']) {
  175. foundCurrent = true;
  176. }
  177. for (CalendarItemBean bean in list) {
  178. bean.recordItem ??= RecordItem();
  179. if (bean.recordItem!.progressBg == null) {
  180. bean.recordItem!.progressBg = [];
  181. }
  182. if (bean.year == year && bean.month == month && bean.day == day) {
  183. double percent = (now - obj['start_time']) /
  184. (obj['end_time'] - obj['start_time']);
  185. RecordProgress? currentProgress;
  186. if (foundCurrent &&
  187. widthProgress / (widthProgress + widthProgress2) >= percent) {
  188. currentProgress = RecordProgress();
  189. currentProgress.beginAlpha = 0.0;
  190. currentProgress.endAlpha = 1.0;
  191. currentProgress.width =
  192. percent * (widthProgress + widthProgress2) / widthProgress;
  193. currentProgress.showArrow = true;
  194. } else if (foundCurrent) {
  195. currentProgress = RecordProgress();
  196. currentProgress.beginAlpha = 0.0;
  197. currentProgress.endAlpha =
  198. widthProgress / ((widthProgress + widthProgress2) * percent);
  199. currentProgress.width = 1.0;
  200. currentProgress.showArrow = false;
  201. }
  202. RecordProgressBg recordProgressBg = RecordProgressBg();
  203. if (currentProgress != null) {
  204. recordProgressBg.progress = currentProgress;
  205. }
  206. recordProgressBg.showStart = foundCurrent;
  207. recordProgressBg.showTarget =
  208. (obj['cross_day'] || !foundCurrent) ? false : true;
  209. recordProgressBg.begin = beginProgress;
  210. recordProgressBg.width = widthProgress;
  211. bean.recordItem!.progressBg!.add(recordProgressBg);
  212. }
  213. if (obj['cross_day'] &&
  214. bean.year == year1 &&
  215. bean.month == month1 &&
  216. bean.day == day1) {
  217. double percent = (now - obj['start_time']) /
  218. (obj['end_time'] - obj['start_time']);
  219. RecordProgress? currentProgress;
  220. if (foundCurrent &&
  221. widthProgress / (widthProgress + widthProgress2) < percent) {
  222. currentProgress = RecordProgress();
  223. currentProgress.beginAlpha =
  224. widthProgress / ((widthProgress + widthProgress2) * percent);
  225. currentProgress.endAlpha = 1.0;
  226. currentProgress.width =
  227. ((widthProgress + widthProgress2) * percent - widthProgress) /
  228. widthProgress2;
  229. currentProgress.showArrow = true;
  230. }
  231. RecordProgressBg recordProgressBg = RecordProgressBg();
  232. if (currentProgress != null) {
  233. recordProgressBg.progress = currentProgress;
  234. }
  235. recordProgressBg.showStart = false;
  236. recordProgressBg.showTarget = foundCurrent ? true : false;
  237. recordProgressBg.begin = beginProgress2;
  238. recordProgressBg.width = widthProgress2;
  239. bean.recordItem!.progressBg!.add(recordProgressBg);
  240. }
  241. }
  242. }
  243. }
  244. //完成的进度
  245. for (int i = 0; i < data['records'].length; i++) {
  246. var fastObj = data['records'][i];
  247. if (fastObj['mode'] == 'SINGLE' && fastObj['status'] != 'DOING') {
  248. setProgressData(list, fastObj['cross_day'], fastObj['start_time'],
  249. fastObj['real_end_time'], fastObj['begin_day_num']);
  250. continue;
  251. }
  252. if (fastObj['mode'] == 'SINGLE') {
  253. continue;
  254. }
  255. List<dynamic> array = fastObj['checkin_days'];
  256. for (var obj in array) {
  257. if ((obj['checkout_status'] != 'SUCCESS' &&
  258. obj['checkout_status'] != 'TIMEOUT') &&
  259. fastObj['status'] == 'DOING') {
  260. continue;
  261. }
  262. setProgressData(list, obj['cross_day'], obj['start_time'],
  263. obj['end_time'], obj['day_num']);
  264. }
  265. }
  266. if (data['records'].length > 0 &&
  267. data['records'][data['records'].length - 1]['status'] == 'DOING' &&
  268. data['records'][data['records'].length - 1]['mode'] == 'SINGLE') {
  269. var singleObj = data['records'][data['records'].length - 1];
  270. int now = serverTime().millisecondsSinceEpoch ~/ 1000;
  271. num duration = now - singleObj['start_time'];
  272. int year = Util().getYearFromTimenum(singleObj['begin_day_num']);
  273. int month = Util().getMonthFromTimenum(singleObj['begin_day_num']);
  274. int day = Util().getDayFromTimenum(singleObj['begin_day_num']);
  275. DateTime beginDate = DateTime(year, month, day);
  276. int firstEndTimestamp =
  277. beginDate.millisecondsSinceEpoch ~/ 1000 + 3600 * 24;
  278. var array = [];
  279. double tempAlpha = 0.0;
  280. num width = firstEndTimestamp - singleObj['start_time'] > duration
  281. ? duration
  282. : (firstEndTimestamp - singleObj['start_time']);
  283. tempAlpha = width / duration;
  284. var obj = {
  285. 'beginAlpha': 0.0,
  286. 'endAlpha': tempAlpha,
  287. 'begin': (3600 * 24 - firstEndTimestamp + singleObj['start_time']) /
  288. (3600 * 24),
  289. 'width': width / (3600 * 24),
  290. 'date': DateTime.now(),
  291. 'showArrow': false
  292. };
  293. array.add(obj);
  294. if (firstEndTimestamp - singleObj['start_time'] < duration) {
  295. int temp = firstEndTimestamp;
  296. while (temp + 24 * 3600 <= now) {
  297. var obj2 = {
  298. 'begin': 0.0,
  299. 'width': 1.0,
  300. 'beginAlpha': tempAlpha,
  301. 'endAlpha': tempAlpha + 24 * 3600 / duration,
  302. 'showArrow': false,
  303. 'date': DateTime.now()
  304. };
  305. tempAlpha += 24 * 3600 / duration;
  306. array.add(obj2);
  307. if (temp + 24 * 3600 > now) {
  308. break;
  309. }
  310. temp = temp + 24 * 3600;
  311. }
  312. if (temp < now) {
  313. var obj3 = {
  314. 'begin': 0.0,
  315. 'width': (now - temp) / (24 * 3600),
  316. 'beginAlpha': tempAlpha,
  317. 'showArrow': false,
  318. 'date': DateTime.now()
  319. };
  320. array.add(obj3);
  321. }
  322. }
  323. array[array.length - 1]['endAlpha'] = 1.0;
  324. array[array.length - 1]['showArrow'] = true;
  325. for (int i = 0; i < array.length; i++) {
  326. array[i]['date'] =
  327. DateTime(beginDate.year, beginDate.month, beginDate.day + i);
  328. }
  329. list.forEach((monthObj) {
  330. array.forEach((obj) {
  331. DateTime dt = obj['date'];
  332. if (monthObj.year == dt.year &&
  333. monthObj.month == dt.month &&
  334. monthObj.day == dt.day) {
  335. monthObj.isHighlight = true;
  336. monthObj.singleProgress = obj;
  337. }
  338. });
  339. });
  340. // list.map((CalendarItemBean monthObj) => {
  341. // int ss = monthObj.year!
  342. // int month0 = monthObj.month!;
  343. // });
  344. }
  345. setState(() {
  346. calendars = list;
  347. });
  348. Timer(const Duration(milliseconds: 500), () {
  349. final RenderBox widget =
  350. selKey.currentContext!.findRenderObject() as RenderBox;
  351. var offset = widget.localToGlobal(Offset.zero);
  352. controller.animateTo(offset.dy - top - 40.px - 100.px,
  353. duration: const Duration(milliseconds: 400), curve: Curves.linear);
  354. // controller.jumpTo(offset.dy);
  355. // var size = 0;
  356. });
  357. }
  358. void setProgressData(List<CalendarItemBean> list, bool crossDay,
  359. int startTime, int endTime, int dayNum) {
  360. if (startTime >= endTime) {
  361. return;
  362. }
  363. int year = Util().getYearFromTimenum(dayNum);
  364. int month = Util().getMonthFromTimenum(dayNum);
  365. int day = Util().getDayFromTimenum(dayNum);
  366. int time = DateTime(year, month, day).millisecondsSinceEpoch ~/ 1000;
  367. DateTime dateTime = DateTime(year, month, day + 1);
  368. int year1 = dateTime.year;
  369. int month1 = dateTime.month;
  370. int day1 = dateTime.day;
  371. int time1 = dateTime.millisecondsSinceEpoch ~/ 1000;
  372. double beginProgress = (startTime - time) / (24 * 3600);
  373. double widthProgress = (endTime - startTime) / (24 * 3600);
  374. double beginProgress2 = 0.0;
  375. double widthProgress2 = 0.0;
  376. if (crossDay) {
  377. widthProgress = 1.0 - beginProgress;
  378. widthProgress2 = (endTime - time1) / (24 * 3600) < 0
  379. ? 0
  380. : (endTime - time1) / (24 * 3600);
  381. }
  382. for (CalendarItemBean bean in list) {
  383. bean.recordItem ??= RecordItem();
  384. if (bean.recordItem!.progress == null) {
  385. bean.recordItem!.progress = [];
  386. }
  387. if (bean.year == year && bean.month == month && bean.day == day) {
  388. RecordProgress progress = RecordProgress();
  389. progress.width = widthProgress;
  390. progress.begin = beginProgress;
  391. bean.recordItem!.progress!.add(progress);
  392. }
  393. if (crossDay &&
  394. bean.year == year1 &&
  395. bean.month == month1 &&
  396. bean.day == day1) {
  397. RecordProgress progress = RecordProgress();
  398. progress.width = widthProgress2;
  399. progress.begin = beginProgress2;
  400. bean.recordItem!.progress!.add(progress);
  401. }
  402. }
  403. }
  404. @override
  405. Widget build(BuildContext context) {
  406. EdgeInsets safePadding = MediaQuery.of(context).padding;
  407. top = safePadding.top;
  408. return Material(
  409. child: Container(
  410. color: kBgColor,
  411. child: Stack(
  412. children: [
  413. Opacity(
  414. opacity: isLoading ? 0.0 : 1.0,
  415. child: Column(
  416. crossAxisAlignment: CrossAxisAlignment.start,
  417. children: [
  418. Expanded(
  419. child: SingleChildScrollView(
  420. controller: controller,
  421. child: Container(
  422. margin: EdgeInsets.only(top: 40.px + top + 60.px),
  423. child: Column(
  424. crossAxisAlignment: CrossAxisAlignment.start,
  425. children:
  426. List<Widget>.generate(calendars.length, (i) {
  427. return Opacity(
  428. opacity: (calendars[i].isHighlight ||
  429. calendars[i].isToday)
  430. ? 1.0
  431. : 0.5,
  432. child: recordItem(calendars[i]),
  433. );
  434. })),
  435. ),
  436. ))
  437. ],
  438. ),
  439. ),
  440. // if (isLoading)
  441. // Expanded(
  442. // child: Container(
  443. // alignment: Alignment.center,
  444. // margin: EdgeInsets.only(bottom: 20.px),
  445. // color: Colors.pink,
  446. // child: SizedBox(
  447. // child: Loading(),
  448. // width: 144.px,
  449. // height: 150.px,
  450. // ))),
  451. NaviBar(
  452. title: '记录详情',
  453. closeCallback: () {
  454. Get.back();
  455. },
  456. showBar: true,
  457. ),
  458. ],
  459. ),
  460. ),
  461. );
  462. }
  463. recordItem(CalendarItemBean bean) {
  464. return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
  465. if (bean.month == 1)
  466. Container(
  467. margin: EdgeInsets.only(bottom: 8.px),
  468. child: Text(
  469. bean.year.toString(),
  470. style: TextStyle(
  471. color: const Color(0x66FFFFFF),
  472. fontSize: 24.px,
  473. fontFamily: 'Exo2',
  474. height: 1,
  475. fontWeight: FontWeight.w900),
  476. ),
  477. ),
  478. if (bean.day == 1)
  479. Container(
  480. margin: EdgeInsets.only(left: 16.px,right: 16.px,top: 16.px),
  481. child: Row(
  482. children: [
  483. Text(
  484. '${bean.month}月',
  485. style: TextStyle(
  486. fontWeight: FontWeight.bold,
  487. color: const Color(0x66C4CCDA),
  488. fontFamily: 'Exo2',
  489. height: 1.0,
  490. fontSize: 20.px),
  491. ),
  492. Expanded(
  493. child: Container(
  494. height: 1.px,
  495. margin: EdgeInsets.only(left: 12.px),
  496. // width: 297.px,
  497. color: const Color(0x1AFFFFFF),
  498. ))
  499. ],
  500. ),
  501. ),
  502. Stack(
  503. children: [
  504. Container(
  505. alignment: Alignment.centerLeft,
  506. margin: EdgeInsets.only(
  507. top: bean.isToday ? 5.px : 0,
  508. bottom: bean.isToday ? 5.px : 0,
  509. left: 17.px),
  510. child: CalendarItem(
  511. bean: bean,
  512. key: (bean.year == widget.selYear &&
  513. bean.month == widget.selMonth &&
  514. bean.day == widget.selDay)
  515. ? selKey
  516. : GlobalKey(),
  517. ),
  518. ),
  519. if (bean.recordItem != null && bean.recordItem!.progressBg != null)
  520. ...List<Widget>.generate(bean.recordItem!.progressBg!.length, (i) {
  521. return progressTargetItem(bean.recordItem!, i);
  522. })
  523. ],
  524. ),
  525. Stack(
  526. children: [
  527. Container(
  528. margin: EdgeInsets.only(left: 16.px, right: 16.px),
  529. child: ClipRRect(
  530. borderRadius: BorderRadius.all(Radius.circular(14.px)),
  531. child: Container(
  532. width: 343.px,
  533. height: 28.px,
  534. decoration: BoxDecoration(
  535. color: const Color(0x14C4CCDA),
  536. borderRadius: BorderRadius.all(Radius.circular(14.px))),
  537. child: Stack(
  538. children: [
  539. if (bean.recordItem != null &&
  540. bean.recordItem!.progressBg != null)
  541. Stack(
  542. children: List<Widget>.generate(
  543. bean.recordItem!.progressBg!.length, (i) {
  544. return progressBgItem(bean.recordItem!, i);
  545. })),
  546. if (bean.recordItem != null &&
  547. bean.recordItem!.progress != null &&
  548. bean.recordItem!.progress!.isNotEmpty)
  549. Stack(
  550. children: List<Widget>.generate(
  551. bean.recordItem!.progress!.length, (i) {
  552. return progressItem(bean.recordItem!, i);
  553. })),
  554. if (bean.singleProgress != null)
  555. Container(
  556. margin: EdgeInsets.only(
  557. left: bean.singleProgress['begin'] * 343.px),
  558. width: bean.singleProgress['width'] * 343.px,
  559. // (bean.singleProgress['width'] * 343.px < 28.px &&
  560. // bean.singleProgress['showArrow'])
  561. // ? 28.px
  562. // : bean.singleProgress['width'] * 343.px,
  563. decoration: BoxDecoration(
  564. // color: kThemeColor,
  565. gradient: LinearGradient(
  566. begin: Alignment.centerLeft,
  567. end: Alignment.centerRight,
  568. colors: [
  569. Color.fromARGB(
  570. (bean.singleProgress['beginAlpha'] * 255)
  571. .toInt(),
  572. 175,
  573. 255,
  574. 0),
  575. Color.fromARGB(
  576. (bean.singleProgress['endAlpha'] * 255)
  577. .toInt(),
  578. 175,
  579. 255,
  580. 0)
  581. ]),
  582. // borderRadius:
  583. // BorderRadius.all(Radius.circular(14.px))
  584. ),
  585. child: Row(
  586. mainAxisSize: MainAxisSize.max,
  587. mainAxisAlignment: MainAxisAlignment.end,
  588. children: [
  589. bean.singleProgress['showArrow'] &&
  590. bean.singleProgress['width'] * 343.px >=
  591. 28.px
  592. ? Image.asset(
  593. 'assets/images/arrow_foward.png',
  594. width: 28.px,
  595. height: 28.px,
  596. )
  597. : SizedBox(
  598. width: 1.px,
  599. height: 28.px,
  600. )
  601. ],
  602. ),
  603. )
  604. ],
  605. )),
  606. ),
  607. ),
  608. // Container(
  609. // margin: EdgeInsets.only(left: 16.px, right: 16.px),
  610. // width: 343.px,
  611. // height: 28.px,
  612. // child: Stack(children: [
  613. // if (bean.recordItem != null &&
  614. // bean.recordItem!.progressBg != null)
  615. // Stack(
  616. // children: List<Widget>.generate(
  617. // bean.recordItem!.progressBg!.length, (i) {
  618. // return progressTargetItem(bean.recordItem!, i);
  619. // }))
  620. // ]))
  621. ],
  622. ),
  623. // Container(
  624. // margin: EdgeInsets.only(left: 16.px, right: 16.px),
  625. // width: 343.px,
  626. // height: 28.px,
  627. // decoration: BoxDecoration(
  628. // color: const Color(0x14C4CCDA),
  629. // borderRadius: BorderRadius.all(Radius.circular(14.px))),
  630. // child: Stack(
  631. // children: [
  632. // if (bean.recordItem != null &&
  633. // bean.recordItem!.progressBg != null)
  634. // Stack(
  635. // children: List<Widget>.generate(
  636. // bean.recordItem!.progressBg!.length, (i) {
  637. // return progressBgItem(bean.recordItem!, i);
  638. // })),
  639. // if (bean.recordItem != null &&
  640. // bean.recordItem!.progress != null &&
  641. // bean.recordItem!.progress!.isNotEmpty)
  642. // Stack(
  643. // children: List<Widget>.generate(
  644. // bean.recordItem!.progress!.length, (i) {
  645. // return progressItem(bean.recordItem!, i);
  646. // })),
  647. // if (bean.singleProgress != null)
  648. // Container(
  649. // margin: EdgeInsets.only(
  650. // left: bean.singleProgress['begin'] * 343.px),
  651. // width: (bean.singleProgress['width'] * 343.px < 28.px &&
  652. // bean.singleProgress['showArrow'])
  653. // ? 28.px
  654. // : bean.singleProgress['width'] * 343.px,
  655. // decoration: BoxDecoration(
  656. // // color: kThemeColor,
  657. // gradient: LinearGradient(
  658. // begin: Alignment.centerLeft,
  659. // end: Alignment.centerRight,
  660. // colors: [
  661. // Color.fromARGB(
  662. // (bean.singleProgress['beginAlpha'] * 255)
  663. // .toInt(),
  664. // 175,
  665. // 255,
  666. // 0),
  667. // Color.fromARGB(
  668. // (bean.singleProgress['endAlpha'] * 255).toInt(),
  669. // 175,
  670. // 255,
  671. // 0)
  672. // ]),
  673. // borderRadius: BorderRadius.all(Radius.circular(14.px))),
  674. // child: Row(
  675. // mainAxisSize: MainAxisSize.max,
  676. // mainAxisAlignment: MainAxisAlignment.end,
  677. // children: [
  678. // bean.singleProgress['showArrow']
  679. // ? Image.asset(
  680. // 'assets/images/arrow_foward.png',
  681. // width: 28.px,
  682. // height: 28.px,
  683. // )
  684. // : SizedBox(
  685. // width: 1.px,
  686. // height: 28.px,
  687. // )
  688. // ],
  689. // ),
  690. // )
  691. // ],
  692. // )),
  693. SizedBox(
  694. height: 10.px,
  695. ),
  696. if (bean.recordItem != null && bean.recordItem!.stickers != null)
  697. Stack(
  698. children:
  699. List<Widget>.generate(bean.recordItem!.stickers!.length, (i) {
  700. return stickerItem(bean.recordItem!, i);
  701. }),
  702. ),
  703. ]);
  704. }
  705. progressTargetItem(RecordItem item, int i) {
  706. List<RecordProgressBg>? list = item.progressBg;
  707. RecordProgressBg progressBg = list![i];
  708. return Positioned(
  709. bottom: 0,
  710. child: SizedBox(
  711. width: 375.px,
  712. height: 50.px,
  713. child: Stack(
  714. children: [
  715. if (progressBg.showStart != null && progressBg.showStart == true)
  716. Positioned(
  717. left: progressBg.begin * 343.px,
  718. bottom: 0,
  719. child: Image.asset(
  720. 'assets/images/calendar_detail_begin.png',
  721. width: 32.px,
  722. height: 40.px,
  723. ),
  724. ),
  725. if (progressBg.showTarget != null && progressBg.showTarget == true)
  726. Positioned(
  727. left: progressBg.begin * 343.px+343.px * progressBg.width,
  728. bottom: 0,
  729. child: Image.asset(
  730. 'assets/images/calendar_detail_end.png',
  731. width: 32.px,
  732. height: 40.px,
  733. ),
  734. )
  735. ],
  736. ),
  737. ));
  738. /*
  739. return Container(
  740. margin: EdgeInsets.only(left: progressBg.begin * 343.px),
  741. width: 343.px * progressBg.width,
  742. height: 40.px,
  743. child: Stack(
  744. children: [
  745. if (progressBg.showStart != null && progressBg.showStart == true)
  746. Container(
  747. margin: EdgeInsets.zero,
  748. width: 0,
  749. height: 0,
  750. ).relationOne(
  751. -16.px,
  752. -28.px,
  753. Image.asset(
  754. 'assets/images/calendar_detail_begin.png',
  755. width: 32.px,
  756. height: 40.px,
  757. )),
  758. if (progressBg.showTarget != null && progressBg.showTarget == true)
  759. Positioned(
  760. left: 343.px * progressBg.width,
  761. child: Container(
  762. margin: EdgeInsets.zero,
  763. width: 0,
  764. height: 0,
  765. )).relationOne(
  766. 343.px * progressBg.width - 16.px,
  767. -28.px,
  768. Image.asset(
  769. 'assets/images/calendar_detail_end.png',
  770. width: 32.px,
  771. height: 40.px,
  772. )),
  773. ],
  774. ),
  775. );*/
  776. /*
  777. List<RecordProgressBg>? list = item.progressBg;
  778. RecordProgressBg progressBg = list![i];
  779. return Container(
  780. margin: EdgeInsets.only(left: progressBg.begin * 343.px),
  781. width: 343.px * progressBg.width,
  782. height: 28.px,
  783. child: Stack(
  784. children: [
  785. if (progressBg.showStart != null && progressBg.showStart == true)
  786. Container(
  787. margin: EdgeInsets.zero,
  788. width: 0,
  789. height: 0,
  790. ).relationOne(
  791. -16.px,
  792. -28.px,
  793. Image.asset(
  794. 'assets/images/calendar_detail_begin.png',
  795. width: 32.px,
  796. height: 40.px,
  797. )),
  798. if (progressBg.showTarget != null && progressBg.showTarget == true)
  799. Positioned(
  800. left: 343.px * progressBg.width,
  801. child: Container(
  802. margin: EdgeInsets.zero,
  803. width: 0,
  804. height: 0,
  805. )).relationOne(
  806. 343.px * progressBg.width - 16.px,
  807. -28.px,
  808. Image.asset(
  809. 'assets/images/calendar_detail_end.png',
  810. width: 32.px,
  811. height: 40.px,
  812. )),
  813. ],
  814. ),
  815. );*/
  816. }
  817. progressBgItem(RecordItem item, int i) {
  818. List<RecordProgressBg>? list = item.progressBg;
  819. RecordProgressBg progressBg = list![i];
  820. return Container(
  821. margin: EdgeInsets.only(left: progressBg.begin * 343.px),
  822. width: 343.px * progressBg.width,
  823. height: 28.px,
  824. decoration: const BoxDecoration(
  825. color: Color(0x26C4CCDA),
  826. // borderRadius: BorderRadius.all(Radius.circular(14.px))
  827. ),
  828. child: Stack(
  829. children: [
  830. if (progressBg.showStart != null && progressBg.showStart == true)
  831. Container(
  832. margin: EdgeInsets.zero,
  833. width: 0,
  834. height: 0,
  835. ).relationOne(
  836. -16.px,
  837. -28.px,
  838. Image.asset(
  839. 'assets/images/calendar_detail_begin.png',
  840. width: 32.px,
  841. height: 40.px,
  842. )),
  843. if (progressBg.showTarget != null && progressBg.showTarget == true)
  844. Positioned(
  845. left: 343.px * progressBg.width,
  846. child: Container(
  847. margin: EdgeInsets.zero,
  848. width: 0,
  849. height: 0,
  850. )).relationOne(
  851. 343.px * progressBg.width - 16.px,
  852. -28.px,
  853. Image.asset(
  854. 'assets/images/calendar_detail_end.png',
  855. width: 32.px,
  856. height: 40.px,
  857. )),
  858. // if (progressBg.progress != null)
  859. // Container(
  860. // width:
  861. // 343.px * progressBg.width * progressBg.progress!.width < 28.px
  862. // ? 28.px
  863. // : 343.px * progressBg.width * progressBg.progress!.width,
  864. // height: 28.px,
  865. // alignment: Alignment.centerRight,
  866. // decoration:const BoxDecoration(
  867. // image: DecorationImage(
  868. // image: AssetImage('assets/images/arrow_foward.png'),
  869. // scale: 0.8,
  870. // alignment: Alignment.centerRight)),
  871. // )
  872. ],
  873. ),
  874. );
  875. }
  876. progressItem(RecordItem item, int i) {
  877. List<RecordProgress>? list = item.progress;
  878. RecordProgress progress = list![i];
  879. if (progress.width < 0) {
  880. progress.width = 0.0;
  881. }
  882. return Container(
  883. margin: EdgeInsets.only(left: 343.px * progress.begin),
  884. width: 343.px * progress.width,
  885. height: 28.px,
  886. alignment: Alignment.centerRight,
  887. decoration: const BoxDecoration(
  888. color: kThemeColor,
  889. // borderRadius: BorderRadius.all(Radius.circular(14.px)),
  890. ));
  891. }
  892. stickerItem(RecordItem item, int i) {
  893. List<RecordSticker>? list = item.stickers;
  894. RecordSticker sticker = list![i];
  895. return Container(
  896. alignment: Alignment.centerLeft,
  897. width: 343.px * sticker.width,
  898. height: 12.px,
  899. margin: EdgeInsets.only(left: 16.px + 343.px * sticker.begin),
  900. decoration: BoxDecoration(
  901. borderRadius: BorderRadius.all(Radius.circular(6.px)),
  902. image: DecorationImage(
  903. image: AssetImage('assets/images/${sticker.days}_progress.png'),
  904. alignment: sticker.begin == 0.0
  905. ? Alignment.centerLeft
  906. : Alignment.centerRight,
  907. fit: BoxFit.cover)),
  908. );
  909. }
  910. }