import 'package:flutter/material.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../constants.dart'; import '../../events/eventbus.dart'; import '../../events/events.dart'; import '../../generated/l10n.dart'; import '../../models/ticket.dart'; import '../../routes.dart'; import '../../store/actions.dart'; import '../../store/store.dart'; import '../../utils/http_util.dart'; import '../../utils/utils.dart'; import '../../widgets/general/double_back_to_close_app_wrapper.dart'; import '../../widgets/mobile/MobileBottomNav.dart'; class MobileMySupport extends StatefulWidget { final int businessId; const MobileMySupport({Key key, this.businessId}) : super(key: key); @override State createState() { return MobileMySupportState(); } } class MobileMySupportState extends State { List tickets; int _page = 1; int _pageCount = 1; bool _isLoading = false; bool _loadingFinish = false; RefreshController _refreshController = RefreshController(initialRefresh: true); void _onRefresh() { _page = 1; if (tickets != null) { tickets.clear(); } else { tickets = []; } _refreshController.resetNoData(); loadTicketes(true); } void _onLoadMore() { // if failed,use loadFailed(),if no data return,use LoadNodata() if (_pageCount > _page) { _page += 1; loadTicketes(false); } else { _refreshController.loadNoData(); } } @override Widget build(BuildContext context) { store.dispatch(UpdateContext(context)); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { if (store.state.user == null) { Utils.requireLogin(context, returnUrl: '/my-support/${widget.businessId}'); return; } }); BuildContext mainContext = context; return Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.arrow_back_ios), onPressed: () { Navigator.of(context).pop(); }, ), title: Text(S.of(context).my_support), backgroundColor: Theme.of(context).primaryColor, actions: [ IconButton( padding: EdgeInsets.only(right: 16.0), icon: Icon( Icons.add, size: 32.0, ), onPressed: () { Routes.router.navigateTo(context, '/new-ticket/${widget.businessId}'); } ), ], ), body: DoubleBackToCloseAppWrapper( child: SmartRefresher( enablePullDown: true, enablePullUp: true, header: WaterDropHeader(), footer: CustomFooter( builder: (BuildContext context, LoadStatus mode){ Widget footer; if(mode == LoadStatus.idle) { footer = Text(S.of(context).pull_up_to_load_more); } else if (mode == LoadStatus.loading) { footer = CircularProgressIndicator(); } else if (mode == LoadStatus.failed) { footer = Text(S.of(context).load_failed_retry); } else if (mode == LoadStatus.canLoading) { footer = Text(S.of(context).release_to_load_more); } else if (mode == LoadStatus.noMore) { footer = Text(S.of(context).no_more_record); } else { footer = Text('...'); } return Container( height: 55.0, child: Center(child: footer,), ); }, ), controller: _refreshController, onRefresh: _onRefresh, onLoading: _onLoadMore, child: _buildBody(), ), ), bottomNavigationBar: MobileBottomNav(currentIndex: 2,), ); } @override void dispose() { _refreshController?.dispose(); super.dispose(); } Widget _buildBody() { if (tickets == null) { return SizedBox.shrink(); } return ListView.builder( itemCount: tickets.length <= 1 ? 1 : tickets.length, itemBuilder: (BuildContext context, int i) { if (tickets.length <= 0) { return Container( padding: EdgeInsets.all(16.0), child: Center( child: Text(S.of(context).no_ticket_yet), ), ); } else { Ticket ticket = tickets[i]; return GestureDetector( onTap: () { Routes.router.navigateTo(context, '/view-ticket/${ticket.id}'); }, child: Container( padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 0.6, ) ) ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( ticket.issue.msg, style: TextStyle( fontSize: 19.0, ), overflow: TextOverflow.ellipsis, ), ), Container( child: Text( Utils.utcDatetimeStringToLocalDatetimeString(context, ticket.createdAt, withTime: true), style: TextStyle( fontSize: 13.0, color: Colors.grey, ), ), ), Container( margin: EdgeInsets.only(top: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ ticket.isClosed ? Container( padding: EdgeInsets.only(right: 10.0), child: Icon(Icons.lock, color: Colors.green, size: 16.0,), ) : SizedBox.shrink(), Text( S.of(context).followups_token(ticket.followUps.length), style: TextStyle( fontSize: 15.0, color: Colors.black87, ), ), ], ), ) ], ), ), ], ), ), ); } } ); } @override void initState() { super.initState(); eventBus.on().listen((event) { if (mounted) { setState(() { tickets = null; }); _refreshController.requestRefresh(); } }); } void loadTicketes(bool isRefresh) { _loadingFinish = false; HttpUtil.httpGet( 'v1/mysupport', businessId: widget.businessId, queryParameters: { 'page': _page.toString(), 'size': Constants.TICKET_PER_PAGE_MOBILE.toString() } ).then((value) { if (mounted) { if (isRefresh) { _refreshController.refreshCompleted(); } else { _refreshController.loadComplete(); } if (int.parse(value['_meta']['currentPage'].toString()) >= int.parse(value['_meta']['pageCount'].toString())) { _loadingFinish = true; } if (_loadingFinish) { _refreshController.loadNoData(); } _page = int.parse(value['_meta']['currentPage'].toString()); _pageCount = int.parse(value['_meta']['pageCount'].toString()); setState(() { if (tickets == null) { tickets = []; } tickets.addAll((value['tickets'] as List).map((e) => Ticket.fromJson(e)).toList()); }); } }).catchError((error) { if (mounted) { if (isRefresh) { _refreshController.refreshFailed(); } else { _refreshController.loadFailed(); } _isLoading = false; Utils.showMessageDialog(context, error, onOk: () { Navigator.of(context).pop(); Navigator.of(context).pop(); }); } }); } }