Hibok
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

742 linhas
25 KiB

  1. import 'dart:async';
  2. import 'package:cached_network_image/cached_network_image.dart';
  3. import 'package:chat/chat/ChatPage.dart';
  4. import 'package:chat/data/UserData.dart';
  5. import 'package:chat/data/chat_data_mgr.dart';
  6. import 'package:chat/data/group_data_mgr.dart';
  7. import 'package:chat/home/add_friend.dart';
  8. import 'package:chat/home/group_announcement.dart';
  9. import 'package:chat/home/group_manage_page.dart';
  10. import 'package:chat/models/group_info_model.dart';
  11. import 'package:chat/models/money_change.dart';
  12. import 'package:chat/models/ref_name_provider.dart';
  13. import 'package:chat/utils/MessageMgr.dart';
  14. import 'package:chat/utils/group_member_model.dart';
  15. import 'package:chat/utils/msgHandler.dart';
  16. import 'package:chat/utils/screen.dart';
  17. import 'package:chat/utils/sp_utils.dart';
  18. import 'package:flutter/cupertino.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:flutter/services.dart';
  21. import 'package:oktoast/oktoast.dart';
  22. import 'package:provider/provider.dart';
  23. import '../../data/constants.dart';
  24. import '../../generated/i18n.dart';
  25. import '../../r.dart';
  26. import '../../utils/CustomUI.dart';
  27. import '../../utils/FullWithButton.dart';
  28. import '../../utils/app_navigator.dart';
  29. import '../create_group_view.dart';
  30. import 'package:chat/utils/PopUpMenu.dart' as myPop;
  31. class TranslationButlerPage extends StatefulWidget {
  32. final GroupInfoModel groupInfoModel;
  33. TranslationButlerPage({Key key, this.groupInfoModel}) : super(key: key);
  34. @override
  35. State<StatefulWidget> createState() {
  36. return TranslationButlerPageState();
  37. }
  38. }
  39. class ValueModel{
  40. String name;
  41. var key;
  42. ValueModel(this.name,this.key);
  43. }
  44. class TranslationButlerPageState extends State<TranslationButlerPage> {
  45. int curToLang = 1;
  46. int curSourceLang = UserData().language;
  47. int curScenes = 0;
  48. List<ValueModel> langList;
  49. List<ValueModel> scenesList;
  50. String extraMsg;
  51. FocusNode focusNode = new FocusNode();
  52. String textLimitTips='';
  53. ScrollController _scrollController = new ScrollController();
  54. @override
  55. void initState() {
  56. super.initState();
  57. initData();
  58. WidgetsBinding.instance.addPostFrameCallback((_) {
  59. Future.delayed(Duration(seconds: 1), () {
  60. CustomUI.buildTranslationHelperOrderDialog(context,true);
  61. // Navigator.of(context).push(
  62. // new MaterialPageRoute(
  63. // builder: (context) {
  64. // return ChatPage(
  65. // key: Key('Chat'),
  66. // friendId: 100006,
  67. // isTranslateButler: true,
  68. // );
  69. // },
  70. // ),
  71. // );
  72. });
  73. });
  74. }
  75. initData() async {
  76. String time = (await SPUtils.get(Constants.TranslationHelper));
  77. if (time != null) {
  78. print('time:$time');
  79. int second = int.parse(time) ~/ 1000;
  80. if((DateTime.now().millisecondsSinceEpoch ~/ 1000 - second)>8*3600){ ///超过5小时清除缓存记录
  81. SPUtils.save(Constants.TranslationHelper,null);
  82. return;
  83. }
  84. secondsPassed =
  85. ((DateTime.now().millisecondsSinceEpoch ~/ 1000 - second));
  86. apply();
  87. } else {
  88. print('time: null');
  89. }
  90. }
  91. apply() {
  92. MsgHandler.sendCreateTranslateOrder(langList[curSourceLang].key,langList[curToLang].key,scenesList[curScenes].key,extraMsg);
  93. isApply = false;
  94. timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
  95. handleTick();
  96. });
  97. setState(() {});
  98. }
  99. @override
  100. void didChangeDependencies() {
  101. super.didChangeDependencies();
  102. textLimitTips = I18n.of(context).translation_input_limit.replaceAll('/s1', '80');
  103. langList = [
  104. ValueModel(I18n.of(context).english,1),
  105. ValueModel(I18n.of(context).Vietnamese,2),
  106. ValueModel(I18n.of(context).traditional_Chinese,4),
  107. ValueModel(I18n.of(context).Simplified_Chinese,8),
  108. ValueModel(I18n.of(context).Korean,16),
  109. ValueModel(I18n.of(context).Japanese,32),
  110. ];
  111. scenesList = [
  112. ValueModel(I18n.of(context).translation_scenes_1,0),
  113. ValueModel(I18n.of(context).translation_scenes_2,1),
  114. ValueModel(I18n.of(context).translation_scenes_3,2),
  115. ValueModel(I18n.of(context).translation_scenes_4,3),
  116. ];
  117. }
  118. @override
  119. void dispose() {
  120. timer?.cancel();
  121. if (!isApply && timeStamp != null) {
  122. print('保存时间戳$timeStamp');
  123. SPUtils.save(Constants.TranslationHelper, timeStamp.toString());
  124. }
  125. super.dispose();
  126. }
  127. _langPopMenu(bool isSource) {
  128. var curIndex = isSource ? curSourceLang : curToLang;
  129. return myPop.PopupMenuButton(
  130. child: Container(
  131. height: 37,
  132. width: double.maxFinite,
  133. decoration: BoxDecoration(
  134. color: Color(0xffD3E7FF),
  135. borderRadius: BorderRadius.circular(5)),
  136. child: Row(
  137. mainAxisAlignment: MainAxisAlignment.start,
  138. children: <Widget>[
  139. Expanded(
  140. child: Container(padding: EdgeInsets.only(left: 5),alignment: Alignment.center,child: Text(
  141. langList[curIndex].name,
  142. textAlign: TextAlign.center,
  143. overflow: TextOverflow.ellipsis,
  144. textScaleFactor: 1.0,
  145. style: TextStyle(color: Color(0xff4A5E76), fontSize: 14),
  146. ),)),
  147. Icon(IconData(0xe63b, fontFamily: Constants.IconFontFamily),
  148. size: 30, color: Color(0xff4A5E76))
  149. ],
  150. ),
  151. ),
  152. offset: Offset(0, 100),
  153. onSelected: (int index) {
  154. if (curIndex != index) {
  155. if (isSource) {
  156. curSourceLang = index;
  157. } else {
  158. curToLang = index;
  159. }
  160. print('更换翻译语言');
  161. setState(() {});
  162. }
  163. },
  164. itemBuilder: (BuildContext context) {
  165. return List<myPop.PopupMenuItem<int>>.generate(langList.length,
  166. (int i) {
  167. return myPop.PopupMenuItem(
  168. child: Container(
  169. alignment: Alignment.center,
  170. color: Colors.white,
  171. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  172. child: Text(langList[i].name,
  173. textScaleFactor: 1.0,
  174. maxLines: 1,
  175. style: TextStyle(
  176. color: i == curIndex
  177. ? Colors.blueAccent
  178. : Color(AppColors.AppBarColor),
  179. fontSize: 14)),
  180. ),
  181. value: i,
  182. );
  183. });
  184. });
  185. }
  186. _scenesPopMenu() {
  187. var curIndex = curScenes;
  188. return myPop.PopupMenuButton(
  189. child: Container(
  190. height: 40,
  191. width: double.maxFinite,
  192. decoration:BoxDecoration(
  193. borderRadius: BorderRadius.all(Radius.circular(6)),
  194. color: Colors.white,
  195. boxShadow: [
  196. BoxShadow(
  197. color: Color(0x739f9f9f),
  198. offset: Offset(0.2, 0.4),
  199. blurRadius: 1.0,
  200. spreadRadius: 0.6),
  201. // BoxShadow(
  202. // color: Color(0x9900FF00), offset: Offset(1.0, 1.0)),
  203. // BoxShadow(color: Color(0xFF0000FF))
  204. ]),
  205. child: Row(
  206. mainAxisAlignment: MainAxisAlignment.start,
  207. children: <Widget>[
  208. Expanded(
  209. child: Text(
  210. scenesList[curIndex].name,
  211. textAlign: TextAlign.center,
  212. overflow: TextOverflow.ellipsis,
  213. textScaleFactor: 1.0,
  214. style: TextStyle(color: Color(0xff3875E9), fontSize: 14),
  215. )),
  216. Icon(IconData(0xe63b, fontFamily: Constants.IconFontFamily),
  217. size: 30, color: Color(0xff4A5E76))
  218. ],
  219. ),
  220. ),
  221. offset: Offset(0, 100),
  222. onSelected: (int index) {
  223. if (curIndex != index) {
  224. curScenes = index;
  225. print('更换场景');
  226. setState(() {});
  227. }
  228. },
  229. itemBuilder: (BuildContext context) {
  230. return List<myPop.PopupMenuItem<int>>.generate(scenesList.length,
  231. (int i) {
  232. return myPop.PopupMenuItem(
  233. child: Container(
  234. width: Screen.width *0.43,
  235. alignment: Alignment.center,
  236. color: Colors.white,
  237. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  238. child: Text(scenesList[i].name,
  239. textScaleFactor: 1.0,
  240. maxLines: 1,
  241. style: TextStyle(
  242. color: i == curIndex
  243. ? Colors.blueAccent
  244. : Color(AppColors.AppBarColor),
  245. fontSize: 14)),
  246. ),
  247. value: i,
  248. );
  249. });
  250. });
  251. }
  252. @override
  253. Widget build(BuildContext context) {
  254. Widget appBar = AppBar(
  255. backgroundColor: AppColors.NewAppbarBgColor,
  256. title: Text(
  257. I18n.of(context).translation_butler,
  258. textScaleFactor: 1.0,
  259. style: TextStyle(color: AppColors.NewAppbarTextColor),
  260. ),
  261. // leading: CustomUI.buildCustomLeading(context),
  262. centerTitle: true,
  263. actions: <Widget>[
  264. Container(
  265. child: CustomUI.buildImageLabel(R.assetsImagesCoin,
  266. Provider.of<MoneyChangeProvider>(context).money,
  267. isLeft: true),
  268. decoration: BoxDecoration(borderRadius: BorderRadius.circular(15)),
  269. ),
  270. SizedBox(
  271. width: 10,
  272. )
  273. ],
  274. );
  275. return Scaffold(
  276. appBar: appBar,
  277. body: SafeArea(
  278. child: Container(
  279. color: Color(0xffE8EAF0),
  280. child: isApply ? applyPage() : waitPage(),
  281. ),
  282. ),
  283. );
  284. }
  285. Widget applyPage() {
  286. return ListView(
  287. controller: _scrollController,
  288. children: <Widget>[
  289. Padding(
  290. padding: EdgeInsets.only(left: 20, right: 10, top: 15),
  291. child: Text(
  292. I18n.of(context).translation_butler_tips,
  293. textScaleFactor: 1.0,
  294. style: TextStyle(color: Color(0xffABABAB), fontSize: 13),
  295. ),
  296. ),
  297. Container(
  298. margin: EdgeInsets.all(10),
  299. child: Card(
  300. elevation: 2, // 阴影
  301. shape: RoundedRectangleBorder(
  302. borderRadius: BorderRadius.circular(10),
  303. // side: BorderSide(color: Colors.green,width: 25),
  304. ),
  305. child: Container(
  306. padding: EdgeInsets.all(10),
  307. child: Column(
  308. crossAxisAlignment: CrossAxisAlignment.start,
  309. children: <Widget>[
  310. Padding(
  311. padding: EdgeInsets.only(bottom: 12),
  312. child: Text(
  313. I18n.of(context).choose_language,
  314. textScaleFactor: 1.0,
  315. textAlign: TextAlign.left,
  316. style: TextStyle(
  317. color: AppColors.NewAppbarTextColor, fontSize: 17),
  318. ),
  319. ),
  320. Row(
  321. children: <Widget>[
  322. SizedBox(width: 15,),
  323. Expanded(
  324. child: _langPopMenu(true),
  325. flex: 5,
  326. ),
  327. Expanded(
  328. child: InkWell(
  329. onTap: () {
  330. var temp = curSourceLang;
  331. curSourceLang = curToLang;
  332. curToLang = temp;
  333. setState(() {});
  334. },
  335. child: Container(
  336. child: Icon(
  337. IconData(
  338. 0xe669,
  339. fontFamily: Constants.IconFontFamily,
  340. ),
  341. size: 24,
  342. color: Color(0xff4A5E76),
  343. ),
  344. padding: EdgeInsets.symmetric(
  345. vertical: 5, horizontal: 5),
  346. ),
  347. ),
  348. flex: 2,
  349. ),
  350. Expanded(
  351. child: _langPopMenu(false),
  352. flex: 5,
  353. ),
  354. SizedBox(width: 15,),
  355. ],
  356. ),
  357. Row(
  358. children: <Widget>[
  359. Expanded(
  360. child: Image.asset(
  361. R.assetsImagesImgTranslationIcon,
  362. width: 195,
  363. height: 175,
  364. ),
  365. flex: 4,
  366. ),
  367. Expanded(
  368. child: Column(
  369. children: <Widget>[
  370. Text(
  371. I18n.of(context).translation_butler_scenes,
  372. textScaleFactor: 1.0,
  373. textAlign: TextAlign.left,
  374. style: TextStyle(
  375. color: AppColors.NewAppbarTextColor,
  376. fontWeight: FontWeight.w700,
  377. fontSize: 15),
  378. ),
  379. SizedBox(height: 10,),
  380. _scenesPopMenu(),
  381. ],
  382. ),
  383. flex: 6,
  384. )
  385. ],
  386. ),
  387. Stack(children: <Widget>[
  388. Container(
  389. alignment: Alignment.topLeft,
  390. height: 110.5,
  391. padding: EdgeInsets.only(bottom: 10),
  392. decoration: BoxDecoration(
  393. color: Color(0xFFE9EEF4),
  394. borderRadius: BorderRadius.all(Radius.circular(10))),
  395. child: TextField(
  396. keyboardAppearance: Brightness.light,
  397. maxLines: 10,
  398. focusNode: focusNode,
  399. textInputAction: TextInputAction.done,
  400. onSubmitted: (input) {
  401. focusNode.unfocus();
  402. },
  403. decoration: new InputDecoration(
  404. hintText: I18n.of(context).translation_more_desc,
  405. hintStyle: TextStyle(fontSize: 14),
  406. border: InputBorder.none,
  407. ),
  408. // maxLines: 1,
  409. inputFormatters: [LengthLimitingTextInputFormatter(80)],
  410. // obscureText: true,
  411. style: TextStyle(textBaseline: TextBaseline.alphabetic),
  412. onChanged: (str) {
  413. if (_scrollController != null) {
  414. ///解决键盘遮挡输入框
  415. _scrollController.position.moveTo(
  416. 200,
  417. duration: Duration(milliseconds: 100),
  418. curve: Curves.easeIn,
  419. );
  420. }
  421. extraMsg = str;
  422. textLimitTips = I18n.of(context).translation_input_limit.replaceAll('/s1', (80-str.length).toString());
  423. setState(() {});
  424. },
  425. ),
  426. ),
  427. Positioned.fill(child: Container(padding: EdgeInsets.only(bottom: 5,right: 5),alignment: Alignment.bottomRight,child: Text(
  428. textLimitTips,
  429. textScaleFactor: 1.0,
  430. style: TextStyle(color: Color(0xFF95A3B2), fontSize: 11),
  431. ),)),
  432. ],),
  433. Padding(padding: EdgeInsets.only(left: 5,right: 5,top: 5,bottom: 8),child: Text(
  434. I18n.of(context).translation_butler_scenes_tips,
  435. textScaleFactor: 1.0,
  436. style: TextStyle(color: Color(0xFFFA7B3D), fontSize: 12),
  437. ),),
  438. ],
  439. ),
  440. ),
  441. ),
  442. ),
  443. Container(
  444. margin: EdgeInsets.only(left: 70, right: 70, top: 50),
  445. height: 47,
  446. child: RaisedButton(
  447. color: Color(0xff3875E9),
  448. shape: RoundedRectangleBorder(
  449. borderRadius: BorderRadius.all(Radius.circular(10))),
  450. child: Text(
  451. I18n.of(context).translation_butler_call + ' (50h)',
  452. textScaleFactor: 1.0,
  453. style: TextStyle(color: Colors.white, fontSize: 19),
  454. ),
  455. onPressed: () {
  456. timeStamp = DateTime.now().millisecondsSinceEpoch;
  457. apply();
  458. }),
  459. ),
  460. Container(
  461. width: double.maxFinite,
  462. alignment: Alignment.center,
  463. padding: EdgeInsets.only(left: 10, right: 10, top: 15,bottom: 20),
  464. child: Text(
  465. I18n.of(context).translation_butler_rules,
  466. textScaleFactor: 1.0,
  467. style: TextStyle(color: Color(0xffABABAB), fontSize: 13),
  468. ),
  469. ),
  470. ],
  471. );
  472. }
  473. Widget waitPage() {
  474. // ~/ 取整操作
  475. int seconds = secondsPassed % 60;
  476. int minutes = secondsPassed ~/ 60;
  477. return ListView(
  478. children: <Widget>[
  479. ///当前排队人数过多。。。
  480. Container(
  481. margin: EdgeInsets.all(10),
  482. child: Card(
  483. elevation: 2, // 阴影
  484. shape: RoundedRectangleBorder(
  485. borderRadius: BorderRadius.circular(10),
  486. // side: BorderSide(color: Colors.green,width: 25),
  487. ),
  488. child: Container(
  489. // width: double.maxFinite,
  490. // color: Colors.blue,
  491. padding: EdgeInsets.fromLTRB(14, 14, 14, 22),
  492. child: Column(
  493. children: <Widget>[
  494. Padding(
  495. padding: EdgeInsets.only(bottom: 20, top: 10),
  496. child: Text(
  497. I18n.of(context).translation_butler_tips2,
  498. textScaleFactor: 1.0,
  499. textAlign: TextAlign.left,
  500. style: TextStyle(color: Color(0xff797979), fontSize: 13),
  501. ),
  502. ),
  503. Container(
  504. width: double.maxFinite,
  505. child: Row(
  506. mainAxisSize: MainAxisSize.max,
  507. mainAxisAlignment: MainAxisAlignment.spaceAround,
  508. children: <Widget>[
  509. Column(
  510. mainAxisAlignment: MainAxisAlignment.center,
  511. children: <Widget>[
  512. fixedText(
  513. I18n.of(context).translation_butler_wait_people,
  514. fontSize: 16,
  515. color: Colors.black),
  516. SizedBox(
  517. height: 10,
  518. ),
  519. RichText(
  520. maxLines: 3,
  521. textAlign: TextAlign.center,
  522. text: TextSpan(children: [
  523. TextSpan(
  524. text: '333',
  525. style: TextStyle(
  526. color: Color(0xffFF1010),
  527. fontSize: 27)),
  528. TextSpan(
  529. text: ' ' +
  530. I18n.of(context)
  531. .translation_butler_wait_people_unit,
  532. style: TextStyle(
  533. color: Colors.black, fontSize: 17)),
  534. ]))
  535. ],
  536. ),
  537. Container(
  538. width: 1,
  539. height: 65,
  540. color: Color(0xffD8D8D8),
  541. ),
  542. Column(
  543. mainAxisAlignment: MainAxisAlignment.center,
  544. children: <Widget>[
  545. fixedText(
  546. I18n.of(context).translation_butler_wait_time,
  547. fontSize: 16,
  548. color: Colors.black),
  549. SizedBox(
  550. height: 10,
  551. ),
  552. RichText(
  553. maxLines: 3,
  554. textAlign: TextAlign.center,
  555. text: TextSpan(children: [
  556. TextSpan(
  557. text: '666',
  558. style: TextStyle(
  559. color: Color(0xff3875E9),
  560. fontSize: 27)),
  561. TextSpan(
  562. text: ' ' + I18n.of(context).minute,
  563. style: TextStyle(
  564. color: Colors.black, fontSize: 17)),
  565. ]))
  566. ],
  567. ),
  568. ],
  569. ),
  570. )
  571. ],
  572. ),
  573. ),
  574. ),
  575. ),
  576. Padding(
  577. padding: EdgeInsets.only(left: 20, right: 10, top: 5, bottom: 10),
  578. child: Text(
  579. I18n.of(context).translation_butler_tips3,
  580. textScaleFactor: 1.0,
  581. style: TextStyle(color: Colors.black, fontSize: 18),
  582. ),
  583. ),
  584. Stack(
  585. alignment: Alignment.center,
  586. children: <Widget>[
  587. UnconstrainedBox(
  588. child: Container(
  589. //限制进度条的高度
  590. height: 190.0,
  591. //限制进度条的宽度
  592. width: 190.0,
  593. child: CircularProgressIndicator(
  594. //0~1的浮点数,用来表示进度多少;如果 value 为 null 或空,则显示一个动画,否则显示一个定值
  595. value: time60/60,
  596. strokeWidth: 5,
  597. //背景颜色
  598. backgroundColor: Color(0xffB2B2B2),
  599. //进度颜色
  600. valueColor:
  601. AlwaysStoppedAnimation<Color>(Color(0xff3875E9))),
  602. ),
  603. ),
  604. Column(
  605. children: <Widget>[
  606. Text(
  607. I18n.of(context).translation_butler_already_wait,
  608. textScaleFactor: 1.0,
  609. style: TextStyle(color: Colors.black, fontSize: 19),
  610. ),
  611. SizedBox(
  612. height: 10,
  613. ),
  614. Text(
  615. getFull(minutes) + ' : ' + getFull(seconds),
  616. textScaleFactor: 1.0,
  617. style: TextStyle(color: Color(0xffFF1010), fontSize: 35),
  618. )
  619. ],
  620. )
  621. ],
  622. ),
  623. Container(
  624. margin: EdgeInsets.only(left: 70, right: 70, top: 50),
  625. height: 47,
  626. child: RaisedButton(
  627. color: Color(0xff3875E9),
  628. shape: RoundedRectangleBorder(
  629. borderRadius: BorderRadius.all(Radius.circular(10))),
  630. child: Text(
  631. I18n.of(context).translation_butler_cancel,
  632. textScaleFactor: 1.0,
  633. style: TextStyle(color: Colors.white, fontSize: 19),
  634. ),
  635. onPressed: () async {
  636. await SPUtils.save(Constants.TranslationHelper, null);
  637. setState(() {
  638. isApply = true;
  639. timer?.cancel();
  640. secondsPassed = 0;
  641. });
  642. }),
  643. ),
  644. Container(
  645. margin: EdgeInsets.only(left: 70, right: 70, top: 25),
  646. height: 47,
  647. child: RaisedButton(
  648. color: Color(0xffB3B3B3),
  649. shape: RoundedRectangleBorder(
  650. borderRadius: BorderRadius.all(Radius.circular(10))),
  651. child: Text(
  652. I18n.of(context).translation_butler_wait_service,
  653. textScaleFactor: 1.0,
  654. style: TextStyle(color: Colors.white, fontSize: 19),
  655. ),
  656. onPressed: () {}),
  657. )
  658. ],
  659. );
  660. }
  661. bool isApply = true;
  662. int secondsPassed = 1;
  663. int timeStamp;
  664. Timer timer;
  665. int time60=1;
  666. void handleTick() {
  667. // if (isActive) {
  668. setState(() {
  669. secondsPassed = secondsPassed + 1; //需要更新UI
  670. time60=time60+1;
  671. if(time60==60){
  672. time60=0;
  673. }
  674. });
  675. // }
  676. }
  677. getFull(int sec) {
  678. return sec < 10 ? '0$sec' : '$sec';
  679. }
  680. }