diff --git a/lib/i10n/localization_intl.dart b/lib/i10n/localization_intl.dart index 652d02c..4a5c8b6 100644 --- a/lib/i10n/localization_intl.dart +++ b/lib/i10n/localization_intl.dart @@ -356,6 +356,7 @@ class DemoLocalizations { String get loadingError => Intl.message('loading error', name: 'loadingError', desc: '加载出错了',); String get loading => Intl.message('loading...', name: 'loading', desc: '加载中...',); String get waiting => Intl.message('waiting...', name: 'waiting', desc: '请稍后...',); + String get timeOut => Intl.message('timeout error', name: 'timeOut', desc: '超时错误',); String get pullUpToLoadMore => Intl.message('pull up load more', name: 'pullUpToLoadMore', desc: '上拉加载更多',); String get pullDownToRefresh => Intl.message('pull down to refresh', name: 'pullDownToRefresh', desc: '下拉刷新',); String get reLoading => Intl.message('click to reload', name: 'reLoading', desc: '点击重新加载',); diff --git a/lib/i10n/messages_en_US.dart b/lib/i10n/messages_en_US.dart index 9876fc0..2ee4b0e 100644 --- a/lib/i10n/messages_en_US.dart +++ b/lib/i10n/messages_en_US.dart @@ -175,6 +175,7 @@ class MessageLookup extends MessageLookupByLibrary { "taskNum" : MessageLookupByLibrary.simpleMessage("Task Number"), "thanksForFeedback" : MessageLookupByLibrary.simpleMessage("Thanks for your feedback"), "thePassword" : MessageLookupByLibrary.simpleMessage("password"), + "timeOut" : MessageLookupByLibrary.simpleMessage("timeout error"), "toFinishTask" : MessageLookupByLibrary.simpleMessage("Try to complete a task!"), "travel" : MessageLookupByLibrary.simpleMessage("Travel"), "tryToSearch" : MessageLookupByLibrary.simpleMessage("Try searching for the title or content"), diff --git a/lib/i10n/messages_zh_CN.dart b/lib/i10n/messages_zh_CN.dart index e9a9011..c8e2ef0 100644 --- a/lib/i10n/messages_zh_CN.dart +++ b/lib/i10n/messages_zh_CN.dart @@ -175,6 +175,7 @@ class MessageLookup extends MessageLookupByLibrary { "taskNum" : MessageLookupByLibrary.simpleMessage("任务数"), "thanksForFeedback" : MessageLookupByLibrary.simpleMessage("感谢你的反馈"), "thePassword" : MessageLookupByLibrary.simpleMessage("密码"), + "timeOut" : MessageLookupByLibrary.simpleMessage("超时错误"), "toFinishTask" : MessageLookupByLibrary.simpleMessage("努力去完成一项任务吧"), "travel" : MessageLookupByLibrary.simpleMessage("旅行"), "tryToSearch" : MessageLookupByLibrary.simpleMessage("试试搜一下标题、内容吧"), diff --git a/lib/pages/about_page.dart b/lib/pages/about_page.dart index 6f0aaa5..8e3fa0a 100644 --- a/lib/pages/about_page.dart +++ b/lib/pages/about_page.dart @@ -245,14 +245,14 @@ class _AboutPageState extends State { final packageInfo = await PackageInfo.fromPlatform(); bool needUpdate = UpdateInfoBean.needUpdate( packageInfo.version, updateInfo.appVersion); - if (needUpdate) { + if (!needUpdate) { Navigator.of(context).pop(); showDialog( context: context, builder: (ctx2) { return UpdateDialog( version: updateInfo.appVersion, - updateUrl: updateInfo.downloadUrl, + updateUrl: "https://github.com/asjqkkkk/flutter-todos/releases/download/1.0.4/todo-list.apk", updateInfo: updateInfo.updateInfo, updateInfoColor: globalModel.logic.getBgInDark(), backgroundColor: diff --git a/lib/widgets/synchronize_widget.dart b/lib/widgets/synchronize_widget.dart index 9e48b80..9e16fad 100644 --- a/lib/widgets/synchronize_widget.dart +++ b/lib/widgets/synchronize_widget.dart @@ -171,6 +171,7 @@ class _SynchronizeWidgetState extends State< SynchronizeWidget> { void uploadTask(TaskBean taskBean, String token) async{ if(synFlag == SynFlag.failSynced) return; ApiService.instance.postCreateTask( + taskBean: taskBean, success: (UploadTaskBean bean){ syncedList.add(bean.uniqueId); taskBean.uniqueId = bean.uniqueId; diff --git a/lib/widgets/update_dialog.dart b/lib/widgets/update_dialog.dart index 94d6f29..37d6c55 100644 --- a/lib/widgets/update_dialog.dart +++ b/lib/widgets/update_dialog.dart @@ -22,7 +22,9 @@ class UpdateDialog extends StatefulWidget { this.version = "1.0.0", this.updateInfo = "", this.updateUrl = "", - this.isForce = false, this.backgroundColor, this.updateInfoColor, + this.isForce = false, + this.backgroundColor, + this.updateInfoColor, }); @override @@ -32,26 +34,21 @@ class UpdateDialog extends StatefulWidget { class UpdateDialogState extends State { int _downloadProgress = 0; CancelToken token; - bool isUpdating = false; + UploadingFlag uploadingFlag = UploadingFlag.idle; @override Widget build(BuildContext context) { - final bgColor = widget.backgroundColor ?? Theme - .of(context) - .primaryColor; - final size = MediaQuery - .of(context) - .size; + final bgColor = widget.backgroundColor ?? Theme.of(context).primaryColor; + final size = MediaQuery.of(context).size; final isVertical = size.height > size.width; final marginLeft = isVertical ? size.width / 8 : size.width / 4; final marginTop = isVertical ? size.height / 4 : size.height / 8; - return WillPopScope( onWillPop: () async => false, child: Container( - margin: EdgeInsets.fromLTRB( - marginLeft, marginTop, marginLeft, marginTop), + margin: + EdgeInsets.fromLTRB(marginLeft, marginTop, marginLeft, marginTop), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(10), @@ -65,10 +62,10 @@ class UpdateDialogState extends State { margin: EdgeInsets.fromLTRB(5, 30, 5, 5), child: Material( child: Text( - DemoLocalizations - .of(context) - .newVersionIsComing, - style: TextStyle(color:widget.updateInfoColor ?? Colors.white, fontSize: 20), + DemoLocalizations.of(context).newVersionIsComing, + style: TextStyle( + color: widget.updateInfoColor ?? Colors.white, + fontSize: 20), ), color: Colors.transparent, )), @@ -84,23 +81,12 @@ class UpdateDialogState extends State { scrollDirection: Axis.vertical, child: Text( widget.updateInfo ?? "", - style: TextStyle(color: widget.updateInfoColor ?? Colors.white), + style: TextStyle( + color: widget.updateInfoColor ?? Colors.white), ), ), ))), - _downloadProgress != 0 - ? Expanded( - child: Container( - child: LinearProgressIndicator( - valueColor: - new AlwaysStoppedAnimation(Theme.of(context).primaryColorLight), - backgroundColor: Colors.grey[300], - value: _downloadProgress / 100, - ), - ), - flex: 1, - ) - : SizedBox(), + getLoadingWidget(), Expanded( flex: 2, child: Container( @@ -109,37 +95,38 @@ class UpdateDialogState extends State { borderRadius: BorderRadius.only( bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), - color: Colors.white, + color: widget.updateInfoColor ?? Colors.white, ), child: Row( children: [ !widget.isForce ? Expanded( - flex: 1, - child: FlatButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text( - DemoLocalizations - .of(context) - .cancel, - style: TextStyle(color: Colors.grey, fontSize: 16), - )), - ) + flex: 1, + child: FlatButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + DemoLocalizations.of(context).cancel, + style: TextStyle( + color: Colors.grey, fontSize: 16), + )), + ) : SizedBox(), !widget.isForce ? Container( - width: 1, - color: Colors.grey[100], - ) + width: 1, + color: Colors.grey[100], + ) : SizedBox(), Expanded( flex: 1, child: FlatButton( onPressed: () async { - if(isUpdating) return; - isUpdating = true; + if (uploadingFlag == UploadingFlag.uploading) + return; + uploadingFlag = UploadingFlag.uploading; + if (mounted) setState(() {}); if (Platform.isAndroid) { _androidUpdate(); } else if (Platform.isIOS) { @@ -147,9 +134,7 @@ class UpdateDialogState extends State { } }, child: Text( - DemoLocalizations - .of(context) - .update, + DemoLocalizations.of(context).update, style: TextStyle(color: Colors.black, fontSize: 16), )), ), @@ -165,14 +150,19 @@ class UpdateDialogState extends State { void _androidUpdate() async { final apkPath = await FileUtil.getInstance().getSavePath("/Download/"); - ApiStrategy - .getInstance() - .client - .download(widget.updateUrl, apkPath + "todo-list.apk", - cancelToken: token, onReceiveProgress: (int count, int total) { + try { + await ApiStrategy.getInstance().client.download( + widget.updateUrl, apkPath + "todo-list.apk", cancelToken: token, + onReceiveProgress: (int count, int total) { + if (mounted) { setState(() { _downloadProgress = ((count / total) * 100).toInt(); if (_downloadProgress == 100) { + if (mounted) { + setState(() { + uploadingFlag = UploadingFlag.uploaded; + }); + } debugPrint("读取的目录:${apkPath}"); try { OpenFile.open(apkPath + "todo-list.apk"); @@ -180,24 +170,101 @@ class UpdateDialogState extends State { Navigator.of(context).pop(); } }); + } + }); + } catch (e) { + if (mounted) { + setState(() { + uploadingFlag = UploadingFlag.uploadingFailed; }); + } + } + } + + Widget getLoadingWidget() { + if (_downloadProgress != 0 && uploadingFlag == UploadingFlag.uploading) { + return Expanded( + child: Container( + child: LinearProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Theme.of(context).primaryColor), + backgroundColor: Colors.grey[300], + value: _downloadProgress / 100, + ), + ), + flex: 1, + ); + } + if (uploadingFlag == UploadingFlag.uploading && _downloadProgress == 0) { + return Container( + alignment: Alignment.center, + height: 40, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(widget.updateInfoColor ?? Colors.white), + ), + SizedBox( + width: 5, + ), + Material( + child: Text( + DemoLocalizations.of(context).waiting, + style: TextStyle(color: widget.updateInfoColor ?? Colors.white), + ), + color: Colors.transparent, + ) + ], + ), + ); + } + if (uploadingFlag == UploadingFlag.uploadingFailed) { + return Container( + alignment: Alignment.center, + height: 40, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.clear, + color: Colors.redAccent, + ), + SizedBox( + width: 5, + ), + Material( + child: Text( + DemoLocalizations.of(context).timeOut, + style: + TextStyle(color: widget.updateInfoColor ?? Colors.white), + ), + color: Colors.transparent, + ) + ], + )); + } + return Container(); } void _iosUpdate() { launch(widget.updateUrl); } - @override void initState() { - super.initState(); token = new CancelToken(); + super.initState(); } @override void dispose() { + if (!token.isCancelled) token?.cancel(); super.dispose(); - token?.cancel(); debugPrint("升级销毁"); } } + +enum UploadingFlag { uploading, idle, uploaded, uploadingFailed } diff --git a/res/intl_en_US.arb b/res/intl_en_US.arb index fae0a2b..80db60c 100644 --- a/res/intl_en_US.arb +++ b/res/intl_en_US.arb @@ -995,6 +995,12 @@ "type": "text", "placeholders": {} }, + "timeOut": "timeout error", + "@timeOut": { + "description": "超时错误", + "type": "text", + "placeholders": {} + }, "pullUpToLoadMore": "pull up load more", "@pullUpToLoadMore": { "description": "上拉加载更多", diff --git a/res/intl_messages.arb b/res/intl_messages.arb index dce9c76..e865a34 100644 --- a/res/intl_messages.arb +++ b/res/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2019-08-26T16:23:12.738549", + "@@last_modified": "2019-08-26T23:04:59.147083", "appName": "One Day List", "@appName": { "description": "app的名字", @@ -994,6 +994,12 @@ "type": "text", "placeholders": {} }, + "timeOut": "timeout error", + "@timeOut": { + "description": "超时错误", + "type": "text", + "placeholders": {} + }, "pullUpToLoadMore": "pull up load more", "@pullUpToLoadMore": { "description": "上拉加载更多", diff --git a/res/intl_zh_CN.arb b/res/intl_zh_CN.arb index d7c4119..a2dcb0a 100644 --- a/res/intl_zh_CN.arb +++ b/res/intl_zh_CN.arb @@ -994,6 +994,12 @@ "type": "text", "placeholders": {} }, + "timeOut": "超时错误", + "@timeOut": { + "description": "超时错误", + "type": "text", + "placeholders": {} + }, "pullUpToLoadMore": "上拉加载更多", "@pullUpToLoadMore": { "description": "上拉加载更多",