openRoom.dart 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_picker/flutter_picker.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:file_picker/file_picker.dart';
  5. import '../styles/colors.dart';
  6. import 'dart:io';
  7. import 'dart:async';
  8. import 'dart:convert';
  9. import 'dart:ui';
  10. import '../styles/totast.dart';
  11. import '../pages/roomInfo.dart';
  12. import 'package:flutter_redux/flutter_redux.dart';
  13. import '../redux/AppState.dart';
  14. import '../net/HttpManager.dart';
  15. import '../net/Result.dart';
  16. import 'package:dio/dio.dart';
  17. import '../model/GameInfo.dart';
  18. import '../model/HouseLevel.dart';
  19. import '../plugins/ScreenStramPlugin.dart';
  20. class OpenRoom extends StatefulWidget {
  21. OpenRoom({Key key, this.roomFlag}) : super(key: key);
  22. final String roomFlag; // 用来储存传递过来的值
  23. @override
  24. OpenRoomState createState() => OpenRoomState();
  25. }
  26. class OpenRoomState extends State<OpenRoom> {
  27. TextStyle titleStyle = TextStyle(color: Colors.white, fontSize: 14);
  28. TextStyle valStyle =
  29. TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500);
  30. Map<String, dynamic> editRoomInfo = {
  31. "gameId": 1,
  32. "houseLevel": 1,
  33. "maxNumber": 10
  34. };
  35. List<GameInfo> gameList = [];
  36. List<HouseLevel> levelList = [];
  37. void getFilePath() async {
  38. String filePath = await FilePicker.getFilePath(type: FileType.ANY);
  39. File _file = File(filePath);
  40. Toast.show(context, '加载中', -1, 'loading');
  41. Result res = await HttpManager.post("assets/uploadFile", data: {
  42. "file": UploadFileInfo(_file, filePath),
  43. });
  44. Toast.hide();
  45. if (res.success) {
  46. setState(() {
  47. editRoomInfo['video'] = res.data[0];
  48. });
  49. } else {}
  50. }
  51. void saveInfo() async {
  52. if (!editRoomInfo.containsKey('gameId')) {
  53. Toast.show(context, '请选择游戏', 1500, 'info');
  54. return;
  55. }
  56. if (editRoomInfo['houseName'] == null || editRoomInfo['houseName'] == '') {
  57. Toast.show(context, '请输入房间标题', 1500, 'info');
  58. return;
  59. }
  60. if (!editRoomInfo.containsKey('houseLevel')) {
  61. Toast.show(context, '请选择房间等级', 1500, 'info');
  62. return;
  63. }
  64. if (editRoomInfo['houseType'] == '1' &&
  65. (editRoomInfo['gameHouseId'] == null ||
  66. editRoomInfo['gameHouseId'] == '')) {
  67. Toast.show(context, '请录入游戏房间号', 1500, 'info');
  68. return;
  69. }
  70. if (editRoomInfo['houseType'] == '1' &&
  71. (editRoomInfo['gameHousePassword'] == null ||
  72. editRoomInfo['gameHousePassword'] == '')) {
  73. Toast.show(context, '请录入游戏房间密码', 1500, 'info');
  74. return;
  75. }
  76. if (StoreProvider.of<AppState>(context).state.userInfo.moneyCoin != null) {
  77. HouseLevel chooseLevelInfo = HouseLevel.empty();
  78. for (var item in levelList) {
  79. if (item.id.toString() == editRoomInfo['houseLevel'].toString()) {
  80. chooseLevelInfo = item;
  81. }
  82. }
  83. if (StoreProvider.of<AppState>(context).state.userInfo.moneyCoin <
  84. chooseLevelInfo.entryCoin) {
  85. return;
  86. }
  87. } else {
  88. return;
  89. }
  90. bool hasPermission = await ScreenStreamPlugin.checkPermission();
  91. if (!hasPermission) {
  92. showDialog(
  93. context: context,
  94. builder: (context) => AlertDialog(
  95. title: Text('需要悬浮窗权限'),
  96. contentTextStyle: TextStyle(color: Colors.black87),
  97. content: Text('请在点击确定后,勾选"允许显示在其他应用的上层"'),
  98. actions: <Widget>[
  99. FlatButton(
  100. child: Text('确定'),
  101. onPressed: () {
  102. Navigator.of(context).pop();
  103. ScreenStreamPlugin.requestPermission();
  104. },
  105. ),
  106. ],
  107. ),
  108. );
  109. return;
  110. }
  111. editRoomInfo['createUser'] =
  112. StoreProvider.of<AppState>(context).state.userInfo.id;
  113. Toast.show(context, '加载中', -1, 'loading');
  114. Result res = await HttpManager.post("houseInfo/save", data: editRoomInfo);
  115. Toast.hide();
  116. if (res.success) {
  117. HttpManager.post("houseInfo/join", data: {
  118. "houseId": res.data,
  119. "userId": StoreProvider.of<AppState>(context).state.userInfo.id
  120. });
  121. Toast.show(context, '创建成功', 1500, 'success');
  122. Future.delayed(Duration(milliseconds: 1500), () {
  123. Navigator.pushReplacement(
  124. context,
  125. new CupertinoPageRoute(
  126. builder: (context) =>
  127. new RoomInfo(roomId: res.data.toString())));
  128. });
  129. } else {}
  130. }
  131. void getInfo() async {
  132. Toast.show(context, '加载中', -1, 'loading');
  133. Result res = await HttpManager.get("gameInfo/all");
  134. if (res.success) {
  135. List<GameInfo> _list = [];
  136. for (var item in res.data) {
  137. _list.add(GameInfo.fromJson(item));
  138. }
  139. setState(() {
  140. gameList = _list;
  141. if (res.data.length > 0) {
  142. editRoomInfo['gameId'] = res.data[0]['id'];
  143. editRoomInfo['houseName'] =
  144. StoreProvider.of<AppState>(context).state.userInfo.nickname +
  145. '的' +
  146. res.data[0]['shortName'] +
  147. '房间';
  148. editRoomInfo['houseAbstract'] = res.data[0]['profile'] ?? '';
  149. }
  150. });
  151. } else {}
  152. Result res2 = await HttpManager.get("houseLevel/all");
  153. Toast.hide();
  154. if (res2.success) {
  155. List<HouseLevel> _list = [];
  156. for (var item in res2.data) {
  157. _list.add(HouseLevel.fromJson(item));
  158. }
  159. setState(() {
  160. levelList = _list;
  161. if (levelList.length > 0) {
  162. editRoomInfo['houseLevel'] = res2.data[0]['id'];
  163. }
  164. });
  165. } else {}
  166. }
  167. @override
  168. void initState() {
  169. super.initState();
  170. editRoomInfo['houseType'] = widget.roomFlag;
  171. Future.delayed(Duration.zero, () {
  172. getInfo();
  173. });
  174. }
  175. @override
  176. Widget build(BuildContext context) {
  177. GameInfo chooseGameInfo = GameInfo.empty();
  178. for (var item in gameList) {
  179. if (item.id.toString() == editRoomInfo['gameId'].toString()) {
  180. chooseGameInfo = item;
  181. }
  182. }
  183. HouseLevel chooseLevelInfo = HouseLevel.empty();
  184. for (var item in levelList) {
  185. if (item.id.toString() == editRoomInfo['houseLevel'].toString()) {
  186. chooseLevelInfo = item;
  187. }
  188. }
  189. return WillPopScope(
  190. child: Scaffold(
  191. appBar: AppBar(
  192. backgroundColor: PRIMARY_COLOR,
  193. title: Text('创建' + (widget.roomFlag == '0' ? '普通' : '官方') + '房间'),
  194. centerTitle: true,
  195. elevation: 0,
  196. actions: <Widget>[
  197. Container(
  198. width: 60,
  199. child: FlatButton(
  200. highlightColor: PRIMARY_COLOR,
  201. padding: EdgeInsets.only(right: 0),
  202. child: Text('规则',
  203. style: TextStyle(color: Colors.white, fontSize: 13)),
  204. onPressed: () {},
  205. ),
  206. )
  207. ],
  208. ),
  209. body: Container(
  210. color: BG_COLOR,
  211. width: double.infinity,
  212. height: double.infinity,
  213. child: SingleChildScrollView(
  214. child: Container(
  215. color: BG_COLOR,
  216. child: Column(
  217. children: <Widget>[
  218. ChooseContent(
  219. title: '选择游戏',
  220. val: chooseGameInfo.gameName,
  221. onTapHomeMenu: () {
  222. showPicker(context);
  223. },
  224. ),
  225. Container(
  226. width: double.infinity,
  227. color: BG_SUB_COLOR,
  228. height: 210,
  229. child: Column(
  230. mainAxisAlignment: MainAxisAlignment.center,
  231. children: <Widget>[
  232. FlatButton(
  233. padding: EdgeInsets.all(0),
  234. color: Color(0xFF464B6A),
  235. highlightColor: Color(0xFF333557),
  236. child: Container(
  237. height: 38,
  238. width: 160,
  239. decoration: BoxDecoration(
  240. gradient: LinearGradient(
  241. begin: Alignment.topRight,
  242. colors: [Colors.black12, Colors.black38],
  243. )),
  244. child: Row(
  245. mainAxisAlignment: MainAxisAlignment.center,
  246. children: <Widget>[
  247. Padding(
  248. padding: EdgeInsets.only(right: 8),
  249. child: Image.asset(
  250. 'images/icon_shipin.png',
  251. width: 20,
  252. )),
  253. Text('上传图片或视频', style: titleStyle)
  254. ],
  255. ),
  256. ),
  257. onPressed: () {
  258. getFilePath();
  259. },
  260. ),
  261. Padding(
  262. padding: EdgeInsets.only(top: 12),
  263. child: Text(
  264. editRoomInfo.containsKey('video')
  265. ? '已选择'
  266. : '不上传则自动使用官方默认视频',
  267. style: TextStyle(
  268. color: Color(0xFF9BA0AE), fontSize: 13),
  269. ),
  270. )
  271. ],
  272. ),
  273. ),
  274. //房间标题
  275. // Container(
  276. // height: 60,
  277. // color: BG_COLOR,
  278. // padding:
  279. // EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  280. // child: TextField(
  281. // textAlign: TextAlign.end,
  282. // style: valStyle,
  283. // maxLength: 10,
  284. // decoration: InputDecoration(
  285. // hintText: "请输入房间标题",
  286. // hintStyle: TextStyle(
  287. // color: Color(0xFF727785), fontSize: 13),
  288. // prefixIcon: Padding(
  289. // padding: EdgeInsets.symmetric(vertical: 12),
  290. // child: Text('房间标题', style: titleStyle),
  291. // ),
  292. // border: InputBorder.none,
  293. // counterStyle: TextStyle(fontSize: 0)),
  294. // onChanged: (value) {
  295. // editRoomInfo['houseName'] = value;
  296. // },
  297. // ),
  298. // ),
  299. InputContent(
  300. title: '房间标题',
  301. value: editRoomInfo['houseName'],
  302. onTextChange: (value) {
  303. editRoomInfo['houseName'] = value;
  304. }),
  305. Container(
  306. height: 1,
  307. color: BG_SUB_COLOR,
  308. ),
  309. //房间简介
  310. InputContent(
  311. title: '房间简介',
  312. value: editRoomInfo['houseAbstract'],
  313. onTextChange: (value) {
  314. editRoomInfo['houseAbstract'] = value;
  315. }),
  316. // Container(
  317. // height: 60,
  318. // color: BG_COLOR,
  319. // padding:
  320. // EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  321. // child: TextField(
  322. // textAlign: TextAlign.end,
  323. // style: valStyle,
  324. // maxLength: 15,
  325. // decoration: InputDecoration(
  326. // hintText: "请输入房间简介",
  327. // hintStyle: TextStyle(
  328. // color: Color(0xFF727785), fontSize: 13),
  329. // prefixIcon: Padding(
  330. // padding: EdgeInsets.symmetric(vertical: 12),
  331. // child: Text('房间简介', style: titleStyle),
  332. // ),
  333. // border: InputBorder.none,
  334. // counterStyle: TextStyle(fontSize: 0)),
  335. // onChanged: (value) {
  336. // editRoomInfo['houseAbstract'] = value;
  337. // },
  338. // ),
  339. // ),
  340. Container(
  341. height: 1,
  342. color: BG_SUB_COLOR,
  343. ),
  344. //房间等级
  345. ChooseContent(
  346. title: '房间等级',
  347. chooseLevelInfo: chooseLevelInfo,
  348. isLevel: true,
  349. onTapHomeMenu: () {
  350. showLevelPicker(context);
  351. },
  352. ),
  353. Container(
  354. height: 1,
  355. color: BG_SUB_COLOR,
  356. ),
  357. //房间人数
  358. ChooseContent(
  359. title: '房间人数',
  360. val: editRoomInfo['maxNumber'].toString(),
  361. onTapHomeMenu: () {
  362. showNumPicker(context);
  363. },
  364. ),
  365. _bottomWidget(),
  366. //创建房间
  367. Container(
  368. padding: EdgeInsets.fromLTRB(15, 39, 15, 28),
  369. height: 109,
  370. color: BG_COLOR,
  371. child: FlatButton(
  372. color: PRIMARY_COLOR,
  373. child: Row(
  374. mainAxisAlignment: MainAxisAlignment.center,
  375. children: <Widget>[
  376. Padding(
  377. padding: EdgeInsets.only(right: 6),
  378. child: Image.asset('images/icon_jinbi_da_bai.png',
  379. width: 20),
  380. ),
  381. Text(
  382. '×' + (chooseLevelInfo.entryCoin ?? 0).toString(),
  383. style: TextStyle(
  384. color: Colors.white,
  385. fontSize: 16,
  386. fontWeight: FontWeight.w500),
  387. ),
  388. Padding(
  389. padding: EdgeInsets.only(left: 20),
  390. child: Text(
  391. '创建房间',
  392. style: TextStyle(
  393. color: Colors.white,
  394. fontSize: 16,
  395. fontWeight: FontWeight.w500),
  396. ),
  397. )
  398. ],
  399. ),
  400. onPressed: () {
  401. saveInfo();
  402. },
  403. ),
  404. )
  405. ],
  406. ),
  407. ),
  408. ),
  409. )),
  410. onWillPop: () {
  411. Toast.hide();
  412. Navigator.pop(context);
  413. return Future.value(false);
  414. },
  415. );
  416. }
  417. Widget _bottomWidget() {
  418. if (widget.roomFlag == '1')
  419. return Column(
  420. children: <Widget>[
  421. Container(
  422. height: 10,
  423. color: BG_SUB_COLOR,
  424. ),
  425. //游戏房间号
  426. Container(
  427. height: 60,
  428. color: BG_COLOR,
  429. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  430. child: TextField(
  431. textAlign: TextAlign.end,
  432. style: valStyle,
  433. maxLength: 15,
  434. decoration: InputDecoration(
  435. hintText: "请输入游戏房间号",
  436. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  437. prefixIcon: Padding(
  438. padding: EdgeInsets.symmetric(vertical: 12),
  439. child: Text('游戏房间号', style: titleStyle),
  440. ),
  441. border: InputBorder.none,
  442. counterStyle: TextStyle(fontSize: 0)),
  443. onChanged: (value) {
  444. editRoomInfo['gameHouseId'] = value;
  445. },
  446. ),
  447. ),
  448. Container(
  449. height: 1,
  450. color: BG_SUB_COLOR,
  451. ),
  452. //游戏中房间密��
  453. Container(
  454. height: 60,
  455. color: BG_COLOR,
  456. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  457. child: TextField(
  458. textAlign: TextAlign.end,
  459. style: valStyle,
  460. maxLength: 10,
  461. decoration: InputDecoration(
  462. hintText: "请输入密码",
  463. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  464. prefixIcon: Padding(
  465. padding: EdgeInsets.symmetric(vertical: 12),
  466. child: Text('游戏中房间密码', style: titleStyle),
  467. ),
  468. border: InputBorder.none,
  469. counterStyle: TextStyle(fontSize: 0)),
  470. onChanged: (value) {
  471. editRoomInfo['gameHousePassword'] = value;
  472. },
  473. ),
  474. ),
  475. ],
  476. );
  477. else {
  478. return Container();
  479. }
  480. }
  481. showPicker(BuildContext context) {
  482. List<String> _list = [];
  483. for (var item in gameList) {
  484. _list.add(item.gameName);
  485. }
  486. String PickerData = json.encode(_list);
  487. new Picker(
  488. confirmText: '确定',
  489. cancelText: "取消",
  490. adapter: PickerDataAdapter<String>(
  491. pickerdata: new JsonDecoder().convert(PickerData)),
  492. changeToFirst: true,
  493. textAlign: TextAlign.left,
  494. columnPadding: const EdgeInsets.all(8.0),
  495. onConfirm: (Picker picker, List value) {
  496. setState(() {
  497. editRoomInfo['gameId'] = gameList[value[0]].id;
  498. editRoomInfo['houseName'] =
  499. StoreProvider.of<AppState>(context).state.userInfo.nickname +
  500. '的' +
  501. gameList[value[0]].shortName +
  502. '房间';
  503. editRoomInfo['houseAbstract'] = gameList[value[0]].profile ?? '';
  504. });
  505. }).showModal(this.context);
  506. }
  507. showNumPicker(BuildContext context) {
  508. List _list = [];
  509. for (var i = 10; i <= 100; i = i + 10) {
  510. _list.add(i);
  511. }
  512. String PickerData = json.encode(_list);
  513. new Picker(
  514. confirmText: '确定',
  515. cancelText: "取消",
  516. adapter: PickerDataAdapter<String>(
  517. pickerdata: new JsonDecoder().convert(PickerData)),
  518. changeToFirst: true,
  519. textAlign: TextAlign.left,
  520. columnPadding: const EdgeInsets.all(8.0),
  521. onConfirm: (Picker picker, List value) {
  522. setState(() {
  523. editRoomInfo['maxNumber'] = _list[value[0]];
  524. });
  525. }).showModal(this.context);
  526. }
  527. showLevelPicker(BuildContext context) {
  528. List<String> _list = [];
  529. for (var item in levelList) {
  530. _list.add(item.levelName);
  531. }
  532. String PickerData = json.encode(_list);
  533. new Picker(
  534. confirmText: '确定',
  535. cancelText: "取消",
  536. adapter: PickerDataAdapter<String>(
  537. pickerdata: new JsonDecoder().convert(PickerData)),
  538. changeToFirst: true,
  539. textAlign: TextAlign.left,
  540. columnPadding: const EdgeInsets.all(8.0),
  541. onConfirm: (Picker picker, List value) {
  542. setState(() {
  543. editRoomInfo['houseLevel'] = levelList[value[0]].id;
  544. });
  545. }).showModal(this.context);
  546. }
  547. }
  548. typedef int OnTapHomeMenu();
  549. typedef ValueChanged<T> = void Function(T value);
  550. class ChooseContent extends StatelessWidget {
  551. ChooseContent(
  552. {Key key,
  553. this.title,
  554. this.val,
  555. this.chooseLevelInfo,
  556. this.isLevel = false,
  557. this.onTapHomeMenu})
  558. : super(key: key);
  559. final String title;
  560. final String val;
  561. final OnTapHomeMenu onTapHomeMenu;
  562. final HouseLevel chooseLevelInfo;
  563. final bool isLevel;
  564. @override
  565. Widget build(BuildContext context) {
  566. return Container(
  567. child: InkWell(
  568. child: Container(
  569. height: 60,
  570. padding: EdgeInsets.symmetric(horizontal: 15),
  571. child: Row(
  572. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  573. children: <Widget>[
  574. Text(title, style: TextStyle(fontSize: 14, color: Colors.white)),
  575. Expanded(
  576. flex: 1,
  577. child: isLevel
  578. ? Row(
  579. mainAxisAlignment: MainAxisAlignment.end,
  580. children: <Widget>[
  581. chooseLevelInfo.icon != null
  582. ? Image.network(
  583. chooseLevelInfo.icon,
  584. width: 22,
  585. )
  586. : Container(),
  587. Text(
  588. chooseLevelInfo.levelName ?? '',
  589. style: TextStyle(color: Color(0xFFF9D881)),
  590. ),
  591. Padding(
  592. padding: EdgeInsets.only(left: 20, right: 2),
  593. child: Image.asset('images/icon_jinbi_da_bai.png',
  594. width: 20),
  595. ),
  596. Text(
  597. '×' + (chooseLevelInfo.entryCoin ?? 0).toString(),
  598. style: TextStyle(
  599. color: Colors.white,
  600. fontSize: 15,
  601. fontWeight: FontWeight.w500),
  602. )
  603. ],
  604. )
  605. : Text(val ?? '',
  606. style: TextStyle(
  607. fontSize: 15,
  608. color: Colors.white,
  609. fontWeight: FontWeight.w500),
  610. textAlign: TextAlign.right),
  611. ),
  612. Image.asset('images/icon_inter.png', width: 24)
  613. ],
  614. ),
  615. ),
  616. onTap: onTapHomeMenu,
  617. ));
  618. }
  619. }
  620. class InputContent extends StatefulWidget {
  621. InputContent({Key key, this.title, this.value, this.onTextChange})
  622. : super(key: key);
  623. final String title;
  624. final String value;
  625. final ValueChanged onTextChange;
  626. @override
  627. InputContentState createState() => InputContentState();
  628. }
  629. class InputContentState extends State<InputContent> {
  630. TextEditingController _controller;
  631. @override
  632. void initState() {
  633. super.initState();
  634. _controller = new TextEditingController();
  635. }
  636. @override
  637. void didUpdateWidget(InputContent oldWidget) {
  638. // TODO: implement didUpdateWidget
  639. super.didUpdateWidget(oldWidget);
  640. _controller.text = widget.value ?? '';
  641. }
  642. @override
  643. Widget build(BuildContext context) {
  644. return Container(
  645. height: 60,
  646. color: BG_COLOR,
  647. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
  648. child: TextField(
  649. controller: _controller,
  650. textAlign: TextAlign.end,
  651. style: TextStyle(
  652. fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500),
  653. maxLength: 10,
  654. decoration: InputDecoration(
  655. hintText: "请输入" + widget.title,
  656. hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13),
  657. prefixIcon: Padding(
  658. padding: EdgeInsets.symmetric(vertical: 12),
  659. child: Text(widget.title,
  660. style: TextStyle(fontSize: 14, color: Colors.white)),
  661. ),
  662. border: InputBorder.none,
  663. counterStyle: TextStyle(fontSize: 0)),
  664. onChanged: widget.onTextChange,
  665. ),
  666. );
  667. }
  668. }