view.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import 'package:electronic_assistant/base/base_page.dart';
  2. import 'package:electronic_assistant/module/record/constants.dart';
  3. import 'package:electronic_assistant/module/record/controller.dart';
  4. import 'package:electronic_assistant/resource/colors.gen.dart';
  5. import 'package:electronic_assistant/utils/expand.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:flutter/services.dart';
  8. import 'package:flutter_screenutil/flutter_screenutil.dart';
  9. import 'package:get/get.dart';
  10. import 'package:lottie/lottie.dart';
  11. import '../../resource/assets.gen.dart';
  12. class RecordPage extends BasePage<RecordController> {
  13. const RecordPage({super.key});
  14. @override
  15. bool immersive() {
  16. return true;
  17. }
  18. @override
  19. bool statusBarDarkFont() {
  20. return false;
  21. }
  22. @override
  23. Color backgroundColor() {
  24. return ColorName.recordBackgroundColor;
  25. }
  26. @override
  27. Color navigationBarColor() {
  28. return "#4A4F67".color;
  29. }
  30. @override
  31. Widget buildBody(BuildContext context) {
  32. return Stack(alignment: Alignment.bottomCenter, children: [
  33. _buildBottomGradient(),
  34. Scaffold(
  35. appBar: AppBar(
  36. leading: IconButton(
  37. icon: const Icon(Icons.arrow_back_ios_new_rounded),
  38. color: ColorName.white,
  39. onPressed: () {
  40. controller.onBackClick();
  41. },
  42. ),
  43. scrolledUnderElevation: 0,
  44. backgroundColor: ColorName.transparent,
  45. systemOverlayStyle: SystemUiOverlayStyle.light,
  46. actions: [
  47. _buildAddShortcut(true),
  48. ],
  49. ),
  50. backgroundColor: ColorName.transparent,
  51. body: Flex(
  52. direction: Axis.vertical,
  53. children: [
  54. _buildRecordStatus(),
  55. const Spacer(flex: 271),
  56. _buildRecordAnim(),
  57. const Spacer(flex: 407),
  58. _buildRecordControl(),
  59. ],
  60. ),
  61. ),
  62. _buildAvailableTimeRemind(),
  63. ]);
  64. }
  65. Widget _buildAvailableTimeRemind() {
  66. return Obx(() {
  67. int? electric = controller.userInfo?.memberInfo?.electric;
  68. return Visibility(
  69. visible: electric != null &&
  70. electric < 12 &&
  71. !controller.isHideIntegrationInsufficient.value,
  72. child: IntrinsicHeight(
  73. child: Align(
  74. alignment: Alignment.bottomCenter,
  75. child: Container(
  76. margin: EdgeInsets.only(
  77. left: 16.w,
  78. right: 16.w,
  79. bottom: 200.h,
  80. ),
  81. child: Stack(
  82. children: [
  83. Align(
  84. alignment: Alignment.bottomCenter,
  85. child: Container(
  86. width: double.infinity,
  87. height: 48.w,
  88. decoration: BoxDecoration(
  89. borderRadius: BorderRadius.circular(10.w),
  90. gradient: LinearGradient(colors: [
  91. '#8671FF'.color,
  92. '#3E55FF'.color,
  93. '#7E80FE'.color,
  94. ], stops: const [
  95. 0.0,
  96. 0.7,
  97. 1
  98. ]),
  99. ),
  100. child: Stack(
  101. children: [
  102. Align(
  103. alignment: const Alignment(-0.05, -0.15),
  104. child: Assets
  105. .images.iconRecordIntegrationInsufficient
  106. .image(width: 153.w, height: 20.w),
  107. ),
  108. Align(
  109. alignment: Alignment.centerRight,
  110. child: GestureDetector(
  111. onTap: () =>
  112. controller.onAvailableTimeClick(),
  113. child: Container(
  114. padding: EdgeInsets.symmetric(
  115. horizontal: 10.w, vertical: 4.w),
  116. decoration: BoxDecoration(
  117. gradient: RadialGradient(
  118. center: Alignment.centerRight,
  119. colors: [
  120. "#E7F2FF".toColor(),
  121. "#FFFFFF".toColor(),
  122. "#F9E8FF".toColor()
  123. ],
  124. radius: 2),
  125. borderRadius:
  126. BorderRadius.circular(100.w),
  127. ),
  128. margin: EdgeInsets.only(right: 12.w),
  129. child: Assets.images.iconRecordRecharge
  130. .image(width: 39.w, height: 19.w)),
  131. ))
  132. ],
  133. ),
  134. ),
  135. ),
  136. Assets.images.iconRecordAvailableTime
  137. .image(width: 88.w, height: 77.w),
  138. Align(
  139. alignment: Alignment.topRight,
  140. child: GestureDetector(
  141. onTap: () {
  142. controller.onCloseAvailableTimeClick();
  143. },
  144. child: Assets
  145. .images.iconRecordIntegrationInsufficientClose
  146. .image(width: 18.w, height: 18.w),
  147. ),
  148. )
  149. ],
  150. ))),
  151. ),
  152. );
  153. });
  154. }
  155. Widget _buildAddShortcut(bool visible) {
  156. return GestureDetector(
  157. onTap: () {
  158. controller.addShortcut();
  159. },
  160. child: Visibility(
  161. visible: visible,
  162. child: Row(
  163. children: [
  164. Image(
  165. image: Assets.images.iconRecordAddShortcut.provider(),
  166. width: 24.w,
  167. height: 24.w),
  168. Padding(
  169. padding: EdgeInsets.only(left: 8.w, right: 16.w),
  170. child: Text(
  171. '添加到桌面',
  172. style: TextStyle(color: ColorName.white, fontSize: 14.w),
  173. ),
  174. )
  175. ],
  176. ),
  177. ),
  178. );
  179. }
  180. Widget _buildRecordStatus() {
  181. return Container(
  182. padding: EdgeInsets.symmetric(horizontal: 16.w),
  183. margin: EdgeInsets.only(top: 20.w),
  184. child: Row(
  185. children: [
  186. Container(
  187. margin: EdgeInsets.only(right: 8.w),
  188. child: Image(
  189. image: Assets.images.iconRecordLogo.provider(),
  190. width: 45.w,
  191. height: 48.w),
  192. ),
  193. Obx(() {
  194. return Text(
  195. controller.currentStatus.value.desc,
  196. style: TextStyle(color: ColorName.white, fontSize: 17.w),
  197. );
  198. }),
  199. ],
  200. ),
  201. );
  202. }
  203. Widget _buildRecordAnim() {
  204. return Obx(() {
  205. return AnimatedOpacity(
  206. opacity:
  207. controller.currentStatus.value == RecordStatus.recording ? 1 : 0,
  208. duration: const Duration(milliseconds: 520),
  209. child: SizedBox(
  210. width: 360.w,
  211. height: 180.w,
  212. child: Lottie.asset(Assets.anim.animRecordingLottie)),
  213. );
  214. });
  215. }
  216. Widget _buildRecordControl() {
  217. return Stack(
  218. alignment: Alignment.bottomCenter,
  219. children: [
  220. Container(
  221. padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 30.w),
  222. decoration: BoxDecoration(
  223. color: "#4A4F67".color,
  224. borderRadius: BorderRadius.only(
  225. topLeft: Radius.circular(40.w),
  226. topRight: Radius.circular(40.w)),
  227. ),
  228. child: Row(
  229. children: [
  230. GestureDetector(
  231. onTap: controller.onCancelClick,
  232. child: Obx(() {
  233. return Image(
  234. image: controller.currentStatus.value.cancelButtonImage,
  235. width: 56.w,
  236. height: 56.w);
  237. }),
  238. ),
  239. const Spacer(),
  240. GestureDetector(
  241. onTap: controller.onSaveClick,
  242. child: Obx(() {
  243. return Image(
  244. image: controller.currentStatus.value.saveButtonImage,
  245. width: 56.w,
  246. height: 56.w);
  247. }),
  248. ),
  249. ],
  250. ),
  251. ),
  252. Column(
  253. children: [
  254. GestureDetector(
  255. onTap: () {
  256. controller.onActionClick();
  257. },
  258. child: Obx(
  259. () => Image(
  260. image: controller.currentStatus.value.actionButtonImage,
  261. width: 92.w,
  262. height: 92.w),
  263. )),
  264. Padding(
  265. padding: EdgeInsets.only(top: 10.w, bottom: 35.w),
  266. child: Obx(() => Text(
  267. formatDuration(controller.currentDuration.value),
  268. style: TextStyle(
  269. color: ColorName.white,
  270. fontSize: 16.w,
  271. ),
  272. )),
  273. )
  274. ],
  275. )
  276. ],
  277. );
  278. }
  279. Widget _buildBottomGradient() {
  280. return Container(
  281. height: 0.38.sh,
  282. decoration: BoxDecoration(
  283. gradient: LinearGradient(
  284. begin: Alignment.topCenter,
  285. end: Alignment.bottomCenter,
  286. colors: [
  287. "#006177F2".color,
  288. "#806177F2".color,
  289. ],
  290. ),
  291. ),
  292. );
  293. }
  294. String formatDuration(double value) {
  295. int hour = (value / 3600).floor();
  296. int minute = ((value - hour * 3600) / 60).floor();
  297. int second = (value - hour * 3600 - minute * 60).floor();
  298. return '${hour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}:${second.toString().padLeft(2, '0')}';
  299. }
  300. }