Hibok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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