Hibok
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

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