From e855bf7b42d1e1c70cee69bbf48f0b2750ab4d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BC=A0=E6=B1=90?= <291808500@qq.com> Date: Thu, 24 Aug 2023 17:07:57 +0800 Subject: [PATCH] Merge branch 'android_1.0.1' of /Users/wangaoqing/fluttle_app/circle_app with conflicts. --- circle_app/android/app/build.gradle | 4 +- circle_app/lib/app/circle/logic.dart | 1 + circle_app/lib/app/dialog/UpdateDialog.dart | 92 ++++++++--- circle_app/lib/app/msg/view.dart | 30 ++-- circle_app/lib/app/splash/logic.dart | 23 ++- circle_app/lib/app/userinfo/logic.dart | 40 +++++ circle_app/lib/app/userinfo/view.dart | 174 +++++++++++--------- circle_app/lib/main.dart | 5 +- circle_app/lib/view/notice.dart | 170 +++++++++++++++++++ circle_app/pubspec.yaml | 2 +- 10 files changed, 403 insertions(+), 138 deletions(-) create mode 100644 circle_app/lib/view/notice.dart diff --git a/circle_app/android/app/build.gradle b/circle_app/android/app/build.gradle index 307c659..689d4d6 100644 --- a/circle_app/android/app/build.gradle +++ b/circle_app/android/app/build.gradle @@ -65,8 +65,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion - versionCode 2 - versionName "1.0.1" + versionCode 4 + versionName "1.0.3" manifestPlaceholders = [ vivo_APPID: "105669716", vivo_APPKEY:"84f750207787376b310ca5b0d5969122", diff --git a/circle_app/lib/app/circle/logic.dart b/circle_app/lib/app/circle/logic.dart index 70f8c76..ef676b0 100644 --- a/circle_app/lib/app/circle/logic.dart +++ b/circle_app/lib/app/circle/logic.dart @@ -56,6 +56,7 @@ class CircleLogic extends GetxController { if (circle.lists.length < 20) { isMore = false; } + update(); } myVip = await getVip(); diff --git a/circle_app/lib/app/dialog/UpdateDialog.dart b/circle_app/lib/app/dialog/UpdateDialog.dart index 7e0e503..8200a64 100644 --- a/circle_app/lib/app/dialog/UpdateDialog.dart +++ b/circle_app/lib/app/dialog/UpdateDialog.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -// import 'package:flutter_install_app/flutter_install_app.dart'; +import 'package:flutter_install_app/flutter_install_app.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -23,6 +23,7 @@ double myProgress = 0; class _CustomDialogState extends State { bool isDownload = false; + bool isShowWeb = false; void incrementCounter() {} @@ -111,42 +112,78 @@ class _CustomDialogState extends State { onTap: () async { //incrementCounter(); }, - child: Container( - margin: EdgeInsets.only(top: 24.sp), - child: CircularProgressIndicator( - value: myProgress, - backgroundColor: Colors.grey, - valueColor: const AlwaysStoppedAnimation( - Color(0xFF30FFD9)), - strokeWidth: 4.0.sp, - ), + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 4.sp), + child: CircularProgressIndicator( + value: myProgress, + backgroundColor: Colors.grey, + valueColor: + const AlwaysStoppedAnimation( + Color(0xFF30FFD9)), + strokeWidth: 4.0.sp, + ), + ), + GestureDetector( + onTap: () async { + final String appStoreUrl = widget.updateInfo + .downloadUrl; // App Store链接示例 + + if (await canLaunch(appStoreUrl)) { + await launch(appStoreUrl, + forceSafariVC: false); + } else { + throw 'Could not open App Store.'; + } + }, + child:isShowWeb? Container( + margin: EdgeInsets.only(top: 4.sp), + child: Text( + "下载太慢?试试游览器下载吧。", + style: TextStyle( + color: Colors.blue, // 设置蓝色颜色 + decoration: + TextDecoration.underline, // 添加下划线 + ), + ), + ): Container(), + ) + ], ), ) : GestureDetector( behavior: HitTestBehavior.opaque, onTap: () async { if (Platform.isIOS) { - final String appStoreUrl = widget.updateInfo.downloadUrl; // App Store链接示例 + final String appStoreUrl = widget + .updateInfo.downloadUrl; // App Store链接示例 if (await canLaunch(appStoreUrl)) { - await launch(appStoreUrl,forceSafariVC : false); + await launch(appStoreUrl, + forceSafariVC: false); } else { throw 'Could not open App Store.'; } } else { + final String appStoreUrl = widget + .updateInfo.downloadUrl; // App Store链接示例 - final String appStoreUrl = widget.updateInfo.downloadUrl; // App Store链接示例 - - if(appStoreUrl.contains("apk")){ + if (appStoreUrl.contains("apk")) { updataApk(appStoreUrl); setDownloadUi(); - }else{ + await Future.delayed(Duration(seconds: 10)); + setState(() { + isShowWeb = true; + }); + + } else { if (await canLaunch(appStoreUrl)) { - await launch(appStoreUrl,forceSafariVC : false); + await launch(appStoreUrl, + forceSafariVC: false); } else { throw 'Could not open App Store.'; } } - } //Navigator.pop(context); @@ -188,12 +225,17 @@ class _CustomDialogState extends State { Positioned( right: 8.sp, top: 8.sp, - child: widget.isDismiss? GestureDetector( - onTap: (){ - - Navigator.pop(context); - }, - child: Icon(Icons.close,color: Colors.white,size: 24.sp,)):Container()) + child: widget.isDismiss + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Icon( + Icons.close, + color: Colors.white, + size: 24.sp, + )) + : Container()) ], ), ), @@ -218,7 +260,7 @@ class _CustomDialogState extends State { // SmartDialog.dismiss(); print(error); }); - // await AppInstaller.installApk(filePath, actionRequired: false); + await AppInstaller.installApk(filePath, actionRequired: false); } } diff --git a/circle_app/lib/app/msg/view.dart b/circle_app/lib/app/msg/view.dart index 1ab3b78..8c4567e 100644 --- a/circle_app/lib/app/msg/view.dart +++ b/circle_app/lib/app/msg/view.dart @@ -253,22 +253,20 @@ class MsgPage extends StatelessWidget { width: Get.width, child: Row( children: [ - Container( - child: Column( - children: [ - Image.asset( - getMsgImage('msg_first'), - width: 50.sp, - ), - SizedBox( - height: 4.sp, - ), - Text( - '抢占第一', - style: TextStyle(color: Colors.white, fontSize: 12.sp), - ), - ], - ), + Column( + children: [ + Image.asset( + getMsgImage('msg_first'), + width: 50.sp, + ), + SizedBox( + height: 4.sp, + ), + Text( + '抢占第一', + style: TextStyle(color: Colors.white, fontSize: 12.sp), + ), + ], ), Expanded( child: SingleChildScrollView( diff --git a/circle_app/lib/app/splash/logic.dart b/circle_app/lib/app/splash/logic.dart index b85781f..4dca3b8 100644 --- a/circle_app/lib/app/splash/logic.dart +++ b/circle_app/lib/app/splash/logic.dart @@ -23,31 +23,26 @@ class SplashLogic extends GetxController { void onReady() async { // TODO: implement onReady super.onReady(); - - } @override void onInit() async { super.onInit(); - // await Future.delayed(Duration(seconds: 30)); + // await Future.delayed(Duration(seconds: 30)); if ((await getAuthorization()).isEmpty) { - if(Platform.isIOS){ + if (Platform.isIOS) { pushLoginPage(); return; } bool isAgreemement = await getAgreemement(); - if(!isAgreemement){ + if (!isAgreemement) { showReportDialog(); - }else{ + } else { pushLoginPage(); } - - - } else { var data = - await DioManager.instance.put(url: Api.refreshToken, params: {}); + await DioManager.instance.put(url: Api.refreshToken, params: {}); var bean = BaseResponse.fromJson( data, (data) => LoginData.fromJson(data)); if (bean.code == 200) { @@ -65,7 +60,10 @@ class SplashLogic extends GetxController { }); return; - } else if(bean.code == 5000||bean.code == 5001||bean.code == 5002||bean.code == 5003){ + } else if (bean.code == 5000 || + bean.code == 5001 || + bean.code == 5002 || + bean.code == 5003) { pushLoginPage(); return; } @@ -73,7 +71,7 @@ class SplashLogic extends GetxController { if (bean.code == 500) { await Future.delayed(Duration(seconds: 5)); onInit(); - }else { + } else { pushLoginPage(); } @@ -81,7 +79,6 @@ class SplashLogic extends GetxController { } } - void showReportDialog() { FlutterNativeSplash.remove(); showDialog( diff --git a/circle_app/lib/app/userinfo/logic.dart b/circle_app/lib/app/userinfo/logic.dart index 519d932..72c0315 100644 --- a/circle_app/lib/app/userinfo/logic.dart +++ b/circle_app/lib/app/userinfo/logic.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -15,6 +17,7 @@ import '../../util/SharedPreferencesHelper.dart'; import '../../util/eventBus.dart'; import '../../util/qiniu.dart'; import '../../util/util.dart'; +import '../../view/notice.dart'; import '../dialog/BaseDialog.dart'; import 'state.dart'; @@ -41,6 +44,12 @@ class UserinfoLogic extends GetxController { bool isDestroy = false; final startTime = DateTime.now(); SharedPreferences? sharedPreferences; + @override + void onClose() { + // TODO: implement onClose + timer?.cancel(); + super.onClose(); + } @override void onInit() async { @@ -74,6 +83,10 @@ class UserinfoLogic extends GetxController { fetchQnToken(Api.getqiniuToken); } + + + + void showBlackDialog(BuildContext context) { showDialog( context: context, @@ -98,6 +111,7 @@ class UserinfoLogic extends GetxController { if (bean.isSuccess()) { isMe = userId.isEmpty; isLike = bean.data.isFollow; + isLikeFoMsg = "${bean.data.likeMeCount}位圈友感兴趣,其中${bean.data.imageUrgeCount}位已催您更新"; userInfoBean = bean.data.user; @@ -107,6 +121,9 @@ class UserinfoLogic extends GetxController { if (isMe) { isOnline = true; } else { + if(!isLike){ + startCountdown(); + } isOnline = userInfoBean!.isOnline; isBlackBeen = bean.data.isBlock; isDestroy = bean.data.isDestroy; @@ -130,6 +147,27 @@ class UserinfoLogic extends GetxController { update(); } + int countdown = 5; + Timer? timer = null; + + startCountdown(){ + + timer = Timer.periodic(const Duration(seconds: 1), (t) { + if (countdown > 0) { + countdown--; + } else { + showFloatingButtonOverlay(Get.context!,userInfoBean!.nickname!,ageMsg,userInfoBean!.avatarThumb,(){ + setLike(); + }); + + timer?.cancel(); // 倒计时结束,取消定时器 + } + }); + } + + + + Future fetchMyAlbum(String url) async { var myAlbumData = await DioManager.instance.get(url: url); var myAlbumBean = BaseResponse.fromJson( @@ -196,6 +234,8 @@ class UserinfoLogic extends GetxController { (jsonData) => jsonData, ); if (bean.isSuccess()) { + + timer?.cancel(); isLike = !isLike; update(); } diff --git a/circle_app/lib/app/userinfo/view.dart b/circle_app/lib/app/userinfo/view.dart index 75d64cf..4895eb5 100644 --- a/circle_app/lib/app/userinfo/view.dart +++ b/circle_app/lib/app/userinfo/view.dart @@ -4,7 +4,6 @@ import 'package:circle_app/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import '../../components/my_app_bar.dart'; import '../../router/app_routers.dart'; @@ -70,26 +69,30 @@ class MyTabbedScreenState extends State fit: BoxFit.cover, ), ), - child: Scaffold( - backgroundColor: Colors.transparent, - appBar: MyAppBar( - centerTitle: logic.userInfoBean != null - ? "${logic.userInfoBean!.nickname}的主页" - : "个人主页", - ), - body: Stack( - children: [ + child: Stack( + children: [ + Scaffold( + backgroundColor: Colors.transparent, + appBar: MyAppBar( + centerTitle: logic.userInfoBean != null + ? "${logic.userInfoBean!.nickname}的主页" + : "个人主页", + ), + body: Stack( + children: [ + Container( + child: buildContent(logic), + ), + Positioned( + bottom: 27.sp, + width: Get.width, + child: _meInfoButton(logic), + ), + ], + ), + ), - Container( - child: buildContent(logic), - ), - Positioned( - bottom: 27.sp, - width: Get.width, - child: _meInfoButton(logic), - ), - ], - ), + ], ), ); } @@ -172,7 +175,7 @@ class MyTabbedScreenState extends State final chatButton = GestureDetector( onTap: () { - if(logic.isBlack||logic.isDestroy||logic.isBlackBeen){ + if (logic.isBlack || logic.isDestroy || logic.isBlackBeen) { showOKToast("私聊失败,存在拉黑关系或者该账户已注销"); return; } @@ -249,7 +252,7 @@ class MyTabbedScreenState extends State ], ), ), - Container( + Container( padding: EdgeInsets.symmetric( horizontal: 19.sp, ), @@ -267,7 +270,9 @@ class MyTabbedScreenState extends State ), ), SizedBox(width: 8.sp), - logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container(): _buildInfoRow(controller), + logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : _buildInfoRow(controller), ], ), Row( @@ -283,15 +288,17 @@ class MyTabbedScreenState extends State : const Color(0xFF787575), ), ), - logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container(): Text( - controller.onLineCity, - style: TextStyle( - fontSize: 12.sp, - color: logic.isOnline - ? const Color(0xFF00FFF4) - : const Color(0xFF787575), - ), - ), + logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : Text( + controller.onLineCity, + style: TextStyle( + fontSize: 12.sp, + color: logic.isOnline + ? const Color(0xFF00FFF4) + : const Color(0xFF787575), + ), + ), ], ), ], @@ -299,7 +306,9 @@ class MyTabbedScreenState extends State ), SizedBox( height: 59.sp, - child: logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container(): _buildInterestsListView(interests), + child: logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : _buildInterestsListView(interests), ), titleTab(controller), Expanded( @@ -309,8 +318,12 @@ class MyTabbedScreenState extends State _tabController.animateTo(index); }, children: [ - logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container():_imageAdapter(controller), - logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container(): HomeCallOutView(controller.userId), + logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : _imageAdapter(controller), + logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : HomeCallOutView(controller.userId), ], ), ), @@ -327,7 +340,7 @@ class MyTabbedScreenState extends State itemBuilder: (context, index) { final interest = interests[index]; return GestureDetector( - onTap: (){ + onTap: () { Get.toNamed(AppRoutes.Signal_circle_list, arguments: interests[index].id); }, @@ -411,49 +424,51 @@ class MyTabbedScreenState extends State ); }, ), - logic.isBlack||logic.isDestroy||logic.isBlackBeen?Container(): GestureDetector( - onTap: () { - if (controller.isMe) { - controller.isEdit = !controller.isEdit; - controller.update(); - } else { - controller.urgeChange(); - } - }, - child: Visibility( - visible: logic.isShowAlbum, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(17), - gradient: const LinearGradient( - colors: [ - Color(0xFF06F9FA), - Color(0xFFDC5BFD), - ], - begin: Alignment.centerLeft, - end: Alignment.centerRight, + logic.isBlack || logic.isDestroy || logic.isBlackBeen + ? Container() + : GestureDetector( + onTap: () { + if (controller.isMe) { + controller.isEdit = !controller.isEdit; + controller.update(); + } else { + controller.urgeChange(); + } + }, + child: Visibility( + visible: logic.isShowAlbum, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17), + gradient: const LinearGradient( + colors: [ + Color(0xFF06F9FA), + Color(0xFFDC5BFD), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.symmetric( + vertical: 2.sp, + horizontal: 12.sp, + ), + child: Text( + controller.isMe + ? controller.isEdit + ? "完成" + : "管理" + : controller.isUrgeStatus + ? "已催更" + : "催更", + style: const TextStyle( + color: Colors.white, + fontSize: 12, + ), + ), + ), ), ), - padding: EdgeInsets.symmetric( - vertical: 2.sp, - horizontal: 12.sp, - ), - child: Text( - controller.isMe - ? controller.isEdit - ? "完成" - : "管理" - : controller.isUrgeStatus - ? "已催更" - : "催更", - style: const TextStyle( - color: Colors.white, - fontSize: 12, - ), - ), - ), - ), - ), ], ), ); @@ -463,7 +478,7 @@ class MyTabbedScreenState extends State //print(controller.state.imaglist); // : - return Container( + return Container( padding: EdgeInsets.symmetric(horizontal: 19.sp), child: Stack( children: [ @@ -599,7 +614,8 @@ class MyTabbedScreenState extends State const SizedBox(width: 6), if (controller.isVip > 0) Image( - image: AssetImage(getBaseImage( controller.isVip == 1 ? "vip" : 'year_vip')), + image: AssetImage( + getBaseImage(controller.isVip == 1 ? "vip" : 'year_vip')), width: 44.sp, height: 18.sp, ), diff --git a/circle_app/lib/main.dart b/circle_app/lib/main.dart index f38dc13..0033a88 100644 --- a/circle_app/lib/main.dart +++ b/circle_app/lib/main.dart @@ -415,6 +415,8 @@ class _MyAppState extends State with WidgetsBindingObserver { listener: V2TimSDKListener(onConnectSuccess: () { print('IM登录成功'); // loginIM(); + },onUserStatusChanged:(List userStatusList){ + })); } @@ -434,8 +436,7 @@ class _MyAppState extends State with WidgetsBindingObserver { Widget build(BuildContext context) { //填入设计稿中设备的屏幕尺寸,单位dp // configureDio(); - return - ScreenUtilInit( + return ScreenUtilInit( designSize: const Size(375, 812), minTextAdapt: true, splitScreenMode: true, diff --git a/circle_app/lib/view/notice.dart b/circle_app/lib/view/notice.dart new file mode 100644 index 0000000..a2d6923 --- /dev/null +++ b/circle_app/lib/view/notice.dart @@ -0,0 +1,170 @@ +import 'dart:async'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +typedef void NoticeCallback(); + + +void showFloatingButtonOverlay( + BuildContext context, String nickname, String ageMsg, String avatar,NoticeCallback noticeCallback) { + OverlayState? overlayState = Overlay.of(context); + late OverlayEntry overlayEntry; + bool showMessage = false; + + int countdownSeconds = 5; // 倒计时秒数 + + // 创建 Timer + late Timer countdownTimer; + + // 创建 OverlayEntry + overlayEntry = OverlayEntry( + builder: (BuildContext context) { + return Positioned( + top: 30, + // right: 16, + child: AnimatedContainer( + duration: const Duration(milliseconds: 500), + curve: Curves.easeInOut, + height: showMessage ? 95 : 0, + child: Container( + width: Get.width - 16, + margin: EdgeInsets.all(10.sp), + padding: EdgeInsets.fromLTRB(16.sp, 16.sp, 16.sp, 0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: const Color(0xFF353443), + ), + child: SingleChildScrollView( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipOval( + child: CachedNetworkImage( + fit: BoxFit.cover, + placeholder: null, + imageUrl: avatar, + width: 48.sp, + height: 48.sp, + ), + ), + const SizedBox(width: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 50.sp, + child: Text( + nickname, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + color: Color.fromRGBO(247, 250, 250, 1.0), + fontSize: 14, + ), + ), + ), + SizedBox(width: 8.sp), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17), + gradient: const LinearGradient( + colors: [ + Color.fromRGBO(141, 255, 248, 1.0), + Color.fromRGBO(181, 211, 255, 1.0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.only( + top: 2.sp, + bottom: 2.sp, + left: 10.sp, + right: 10.sp, + ), + child: Text( + ageMsg, + style: const TextStyle( + color: Colors.black, + fontSize: 10, + ), + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + "看了这么久,给我点个喜欢呗~", + style: TextStyle( + color: Colors.grey, + fontSize: 12.sp, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + const Spacer(), + GestureDetector( + onTap: () { + countdownTimer.cancel(); // 取消计时器 + overlayEntry.remove(); + noticeCallback(); + + // logic.setLike(); + // logic.showMessage = false; + // logic.update(); + }, + child: Container( + margin: EdgeInsets.only(top: 6.sp), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(17), + gradient: const LinearGradient( + colors: [ + Color(0xFF06F9FA), + Color(0xFFDC5BFD), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + padding: EdgeInsets.symmetric( + horizontal: 16.sp, vertical: 6.sp), + child: Text( + "喜欢", + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + ), + ), + ), + ), + + // ), + ], + ), + ), + ), + ), + ); + }, + ); + // setState(() {}); + showMessage = true; + countdownTimer = Timer.periodic(Duration(seconds: 1), (timer) { + if (countdownSeconds > 0) { + countdownSeconds--; + // overlayEntry.markNeedsBuild(); // 刷新 OverlayEntry + } else { + timer.cancel(); // 取消计时器 + overlayEntry.remove(); // 移除 OverlayEntry + } + }); + // 将 OverlayEntry 添加到 Overlay 中 + overlayState?.insert(overlayEntry); +} diff --git a/circle_app/pubspec.yaml b/circle_app/pubspec.yaml index 590cd9a..ae0d5a9 100644 --- a/circle_app/pubspec.yaml +++ b/circle_app/pubspec.yaml @@ -93,7 +93,7 @@ dependencies: #event_bus: event_bus: ^2.0.0 #安装apk -# flutter_install_app: 1.3.0 + flutter_install_app: 1.3.0 #闪屏页 flutter_native_splash: 2.2.16 #腾讯离线推送