import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.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/address.dart'; import '../../models/blog.dart'; import '../../models/ticket.dart'; import '../../pages/edit_address.dart'; import '../../routes.dart'; import '../../store/actions.dart'; import '../../store/store.dart'; import '../../utils/http_util.dart'; import '../../utils/utils.dart'; import '../../widgets/general/bottom_nav.dart'; import '../../widgets/general/breadcrumbs.dart'; import '../../widgets/general/navigationbar.dart'; import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart'; class DesktopBlog extends StatefulWidget { final int businessId; const DesktopBlog({Key key, this.businessId}) : super(key: key); @override State createState() { return DesktopBlogState(); } } class DesktopBlogState extends State { List blogs; double division = 2; int _page = 1; int _pageCount = 1; bool _isLoading = false; bool _loadingFinish = false; RefreshController _refreshController = RefreshController(initialRefresh: true); void _onRefresh() { _page = 1; if (blogs != null) { blogs.clear(); } else { blogs = []; } _refreshController.resetNoData(); loadBlogs(true); } void _onLoadMore() { // if failed,use loadFailed(),if no data return,use LoadNodata() if (_pageCount > _page) { _page += 1; loadBlogs(false); } else { _refreshController.loadNoData(); } } double sideSpace = 0; double mainSpace = 1200; @override Widget build(BuildContext context) { store.dispatch(UpdateContext(context)); if (MediaQuery.of(context).size.width <= 1200) { mainSpace = MediaQuery.of(context).size.width; sideSpace = 0; } else { mainSpace = 1200; sideSpace = (MediaQuery.of(context).size.width - 1200) / 2; } BuildContext mainContext = context; return Scaffold( appBar: MiniNavigationBar( title: S.of(context).blog, back: true, breadCrumbs: [ BreadCrumb(S.of(context).blog, null), ], breadCrumbHeight: Constants.BREADCRUMB_HEIGHT, ), body: 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: BottomNav(), ); } Widget _buildBody() { if (blogs == null) { return SizedBox.shrink(); } Row row = Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: sideSpace, ), Container( width: mainSpace, padding: EdgeInsets.only( top: 12.0, bottom: 16.0, left: 8.0, right: 8.0, ), child: blogs == null ? Text('') : (blogs.length > 0 ? Wrap( children: blogs.map((a) => GestureDetector( child: _getBlog(a), onTap: () { Routes.router.navigateTo(context, '/view-blog/${a.id}'); }, )).toList(), ) : Center( child: Text(S.of(context).no_blog_yet), )), ), Container( width: sideSpace, ), ], ); return SingleChildScrollView( child: row, ); } Widget _getBlog(Blog blog) { return Container( width: (mainSpace - 16.0) / division, padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0), child: Container( padding: EdgeInsets.only(top: 20.0, bottom: 20.0, left: 16.0, right: 16.0,), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 0.6, ), top: BorderSide( color: Colors.black12, width: 0.6, ), left: BorderSide( color: Colors.black12, width: 0.6, ), right: BorderSide( color: Colors.black12, width: 0.6, ), ), borderRadius: BorderRadius.all(Radius.circular(10.0)), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ (blog.thumbUrl != null) ? Container( padding: EdgeInsets.only(right: 10.0), child: Util.showImage( 'https:${blog.thumbUrl}', width: 80, height: 80, ), ) : SizedBox.shrink(), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( blog.title, style: TextStyle( fontSize: 19.0, ), overflow: TextOverflow.ellipsis, ), ), Container( child: Text( Utils.utcDatetimeStringToLocalDatetimeString(context, blog.createdAt,), style: TextStyle( fontSize: 13.0, color: Colors.grey, ), ), ), ], ), ), ], ), ), ); } @override void dispose() { _refreshController?.dispose(); super.dispose(); } @override void initState() { super.initState(); eventBus.on().listen((event) { if (mounted) { setState(() { blogs = null; }); } _refreshController.requestRefresh(); }); } void loadBlogs(bool isRefresh) { _loadingFinish = false; HttpUtil.httpGet( 'v1/blogs', businessId: widget.businessId, queryParameters: { 'page': _page.toString(), 'size': Constants.BLOG_PER_PAGE_DESKTOP.toString() } ).then((value) { print('value: $value'); if (mounted) { if (isRefresh) { _refreshController.refreshCompleted(); } else { _refreshController.loadComplete(); } if (int.parse(value['currentPage'].toString()) >= int.parse(value['pageCount'].toString())) { _loadingFinish = true; } if (_loadingFinish) { _refreshController.loadNoData(); } _page = int.parse(value['currentPage'].toString()); _pageCount = int.parse(value['pageCount'].toString()); setState(() { if (blogs == null) { blogs = []; } blogs.addAll((value['blogs'] as List).map((e) => Blog.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(); }); } }); } }