diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs index 0e90bae..f89ba04 100644 --- a/android/.settings/org.eclipse.buildship.core.prefs +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -5,7 +5,7 @@ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 gradle.user.home= -java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.15.jdk/Contents/Home +java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home jvm.arguments= offline.mode=false override.workspace.settings=true diff --git a/android/app/build.gradle b/android/app/build.gradle index c6e0f89..75a556c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -34,7 +34,7 @@ android { } defaultConfig { - applicationId "com.hgmj.manju" + applicationId "com.wydj.manju" minSdk = 24 targetSdk = 36 versionCode = 1 @@ -84,7 +84,7 @@ android { println "outputFileDir= ${outputFileDir}" def abi = filters.find { it.filterType.toString() == "ABI" }?.identifier def abiSuffix = (variant.outputs.size() > 1 && abi) ? "_${abi}" : "" - def path = "hgmj" + '_release' + "_" + variant.versionName + abiSuffix + "_" + createTime + ".apk" + def path = "wydj" + '_release' + "_" + variant.versionName + abiSuffix + "_" + createTime + ".apk" println("path= " + path) outputFileName = path } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 509dbb4..095d54d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index d55974f..2a7385a 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_splash_bg.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_splash_bg.webp index 46dbd3d..9a6085e 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_splash_bg.webp and b/android/app/src/main/res/mipmap-xxhdpi/ic_splash_bg.webp differ diff --git a/assets/images/common/ic_launcher.webp b/assets/images/common/ic_launcher.webp index 7e39d85..a2f81ea 100644 Binary files a/assets/images/common/ic_launcher.webp and b/assets/images/common/ic_launcher.webp differ diff --git a/assets/images/common/place_holder_logo.webp b/assets/images/common/place_holder_logo.webp index 6627f74..2bf2b9a 100644 Binary files a/assets/images/common/place_holder_logo.webp and b/assets/images/common/place_holder_logo.webp differ diff --git a/assets/images/home/nav_logo.webp b/assets/images/home/nav_logo.webp index 4452e13..1af9ba9 100644 Binary files a/assets/images/home/nav_logo.webp and b/assets/images/home/nav_logo.webp differ diff --git a/assets/images/launch/ic_splash_bg.webp b/assets/images/launch/ic_splash_bg.webp index 46dbd3d..9a6085e 100644 Binary files a/assets/images/launch/ic_splash_bg.webp and b/assets/images/launch/ic_splash_bg.webp differ diff --git a/build_apk.sh b/build_apk.sh index b88c5e2..15b146d 100755 --- a/build_apk.sh +++ b/build_apk.sh @@ -14,7 +14,7 @@ fi # 参数说明 if [ $# -lt 1 ]; then - printf -- "Build hgmj release package.\n\n" + printf -- "Build wydj release package.\n\n" printf -- "Usage: $0 [mode] [export_method] [export_options_plist] [sign_mode]\n" printf -- " target : a(android) | i(ios) | all\n" printf -- " mode : release(默认) | debug | profile\n" @@ -83,7 +83,7 @@ SAFE_VERSION=${RAW_VERSION//+/_} TIME_TAG=$(date +"%m%d-%H%M") # 读取应用内 Config.isDebug(lib/config/config.dart),决定产物命名标识: -# isDebug=true → 命名标识固定为 debug(如 hgmj_debug_xxxx),方便区分内测包 +# isDebug=true → 命名标识固定为 debug(如 wydj_debug_xxxx),方便区分内测包 # isDebug=false → 正式环境,命名沿用构建模式(release/profile),保持不变 CONFIG_FILE="lib/config/config.dart" CONFIG_DEBUG=$(grep -E 'static[[:space:]]+const[[:space:]]+isDebug[[:space:]]*=' "$CONFIG_FILE" 2>/dev/null | grep -oE 'true|false' | head -1) diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh index 870c537..3f569d4 100755 --- a/ios/Flutter/flutter_export_environment.sh +++ b/ios/Flutter/flutter_export_environment.sh @@ -1,12 +1,12 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=/Users/mac/fvm/versions/3.38.3" -export "FLUTTER_APPLICATION_PATH=/Users/mac/weiming/黄果短剧/hgmj_android" +export "FLUTTER_APPLICATION_PATH=/Users/mac/weiming/黄果短剧/51dj_android" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" -export "FLUTTER_BUILD_NAME=2.0.4" -export "FLUTTER_BUILD_NUMBER=2.0.4" +export "FLUTTER_BUILD_NAME=2.0.0" +export "FLUTTER_BUILD_NUMBER=2.0.0" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=true" export "TREE_SHAKE_ICONS=false" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0ab2d6d..0bd02b7 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -493,7 +493,7 @@ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = NWP977LR25; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "黄果漫剧"; + INFOPLIST_KEY_CFBundleDisplayName = "51短剧"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -681,7 +681,7 @@ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = NWP977LR25; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "黄果漫剧"; + INFOPLIST_KEY_CFBundleDisplayName = "51短剧"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -711,7 +711,7 @@ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = NWP977LR25; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "黄果漫剧"; + INFOPLIST_KEY_CFBundleDisplayName = "51短剧"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 1.png index d019588..e8651fd 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 1.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 2.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 2.png index d019588..e8651fd 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 2.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x 2.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png index d019588..e8651fd 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/AppIcon20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png index 852b828..684e125 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20-ipad.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png index 35d8651..d52cdff 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29 1.png index e32e3e6..3f99fcd 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29 1.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png index e32e3e6..3f99fcd 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x 1.png index 0101a6e..cf35bda 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x 1.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png index 0101a6e..cf35bda 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png index eee653a..afdfd7c 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png index 51d325b..48c0980 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x 1.png index 807878e..a585e5e 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x 1.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png index 807878e..a585e5e 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x 1.png index 87328d9..b069218 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x 1.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png index 87328d9..b069218 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png index 0be8576..5effcf5 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png index d4311c3..b00afbc 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png index bee9664..2882187 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/logo.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/logo.png index 6cb716d..045c0a0 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/logo.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/logo.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 1.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 1.png index 43dae44..ff66b56 100644 Binary files a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 1.png and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 1.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 2.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 2.png index e19fec3..3882383 100644 Binary files a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 2.png and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg 2.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg.png index c4892c7..de5d646 100644 Binary files a/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg.png and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/ic_splash_bg.png differ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index adcf083..c943dcf 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -7,7 +7,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - 黄果漫剧 + 51短剧 CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - 黄果漫剧 + 51短剧 CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/alert/aw_permission_alert.dart b/lib/alert/aw_permission_alert.dart index 1b1097f..8ac785b 100644 --- a/lib/alert/aw_permission_alert.dart +++ b/lib/alert/aw_permission_alert.dart @@ -2,9 +2,9 @@ import 'dart:ui'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/routers/jump_router.dart'; import '../hj_utils/screen.dart'; import '../tools_base/widget/net_image_widget.dart'; @@ -19,7 +19,9 @@ class AwPermissionAlert extends StatelessWidget { color: Colors.black.withValues(alpha: .4), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: Config.darkWebImg?.isNotEmpty == true ? _imageView() : _normalView(), + child: Config.darkWebImg?.isNotEmpty == true + ? _imageView() + : _normalView(), ), ); } @@ -60,20 +62,25 @@ class AwPermissionAlert extends StatelessWidget { '乌/中东战争,血腥缅北,呦呦破处,变态\n' '恐怖,暗网交易,等稀缺资源!', textAlign: TextAlign.center, - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), ), 18.sizeBoxH, //会员卡名标红 EasyRichText( '马上开通\n$vipName\n进入世界的黑暗面!', textAlign: TextAlign.center, - defaultStyle: const TextStyle(color: Colors.white, fontSize: 14, height: 1.5), + defaultStyle: const TextStyle( + color: Colors.white, fontSize: 14, height: 1.5), patternList: [ if (vipName.isNotEmpty) EasyRichTextPattern( targetString: vipName, matchWordBoundaries: false, // 纯中文无 \b 词边界,关掉才能匹配上 - hasSpecialCharacters: true, // 卡名是服务端下发的,带 ()+ 等正则符会构造出非法正则崩掉 + hasSpecialCharacters: + true, // 卡名是服务端下发的,带 ()+ 等正则符会构造出非法正则崩掉 style: const TextStyle(color: Color(0xffC40F0B)), ), ], @@ -88,7 +95,8 @@ class AwPermissionAlert extends StatelessWidget { '此板块为黑客破解内容,真实稀缺资源,\n' '可能会引起极度不适,请谨慎进入!\n', textAlign: TextAlign.center, - style: TextStyle(color: Colors.white.withValues(alpha: .6), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: .6), fontSize: 12), ), ], ), diff --git a/lib/alert/mine/vip_level_dialog.dart b/lib/alert/mine/vip_level_dialog.dart index 2d29dd0..04b5ee0 100644 --- a/lib/alert/mine/vip_level_dialog.dart +++ b/lib/alert/mine/vip_level_dialog.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; import '../../routers/jump_router.dart'; @@ -36,7 +36,8 @@ Future showVipLevelDialog( child: Text( content, textAlign: TextAlign.center, - style: TextStyle(fontSize: 16, color: Color(0x73FFFFFF), height: 1.5), + style: TextStyle( + fontSize: 16, color: Color(0x73FFFFFF), height: 1.5), ), ), if (desc != null && desc.isNotEmpty) @@ -49,7 +50,8 @@ Future showVipLevelDialog( ), ), 24.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { if (vipEvent != null) { vipEvent.call(); diff --git a/lib/alert/splash/app_center_dialog.dart b/lib/alert/splash/app_center_dialog.dart index 44e2cc3..56e8f8e 100644 --- a/lib/alert/splash/app_center_dialog.dart +++ b/lib/alert/splash/app_center_dialog.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; import '../../hj_model/splash/ads_model.dart'; import '../../hj_utils/screen.dart'; @@ -70,7 +70,8 @@ class _AppCenterDialogState extends State { shrinkWrap: true, //不足 4 行时按内容收,不留空 physics: const ClampingScrollPhysics(), itemCount: _appList.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, crossAxisSpacing: 12, mainAxisSpacing: 16, @@ -93,7 +94,8 @@ class _AppCenterDialogState extends State { ignoring: !_showClose, child: GestureDetector( onTap: () => Get.back(), - child: Image.asset("close_button.png".commonImgPath, width: 32, height: 32), + child: Image.asset("close_button.png".commonImgPath, + width: 32, height: 32), ), ), ), diff --git a/lib/alert/splash/line_error_dialog.dart b/lib/alert/splash/line_error_dialog.dart index fb294af..34e88b5 100644 --- a/lib/alert/splash/line_error_dialog.dart +++ b/lib/alert/splash/line_error_dialog.dart @@ -2,11 +2,11 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; class LineErrorDialog extends StatelessWidget { static Future show({Function? callback}) { @@ -58,7 +58,10 @@ class LineErrorDialog extends StatelessWidget { alignment: Alignment.centerLeft, child: const Text( "解决方案:", - style: TextStyle(color: Color(0xff656565), fontSize: 12, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xff656565), + fontSize: 12, + fontWeight: FontWeight.w500), ), ), 12.sizeBoxH, @@ -67,7 +70,8 @@ class LineErrorDialog extends StatelessWidget { 2.前往官网地址 $officialUrl下载最新版。 3.前往Telegram${Config.appName}官方交流群 ''', - defaultStyle: TextStyle(fontSize: 12, color: Color(0xff656565), height: 1.8), + defaultStyle: + TextStyle(fontSize: 12, color: Color(0xff656565), height: 1.8), patternList: [ EasyRichTextPattern( targetString: officialUrl, diff --git a/lib/alert/splash/notice_image_dialog.dart b/lib/alert/splash/notice_image_dialog.dart index 9c27848..05dc5f5 100644 --- a/lib/alert/splash/notice_image_dialog.dart +++ b/lib/alert/splash/notice_image_dialog.dart @@ -3,9 +3,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../tools_base/banner/ads_item.dart'; @@ -31,7 +31,8 @@ class NoticeImageDialog extends StatelessWidget { aspectRatio: 6 / 8, ), 20.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.back(result: false), child: Image.asset("close_button.png".commonImgPath, width: 32), ) @@ -76,7 +77,8 @@ class SystemImagesDialog extends StatelessWidget { itemCount: ads?.length ?? 0, ), 20.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.back(result: false), child: Image.asset("close_button.png".commonImgPath, width: 32), ) diff --git a/lib/alert/splash/notice_text_dialog.dart b/lib/alert/splash/notice_text_dialog.dart index 8f3aefe..7798379 100644 --- a/lib/alert/splash/notice_text_dialog.dart +++ b/lib/alert/splash/notice_text_dialog.dart @@ -3,9 +3,9 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; import '../../hj_model/splash/ads_model.dart'; @@ -43,7 +43,8 @@ class NoticeTextDialog extends StatelessWidget { child: SingleChildScrollView( child: EasyRichText( content ?? "", - defaultStyle: TextStyle(color: Color(0xff656565), fontSize: 12, height: 25 / 12), + defaultStyle: TextStyle( + color: Color(0xff656565), fontSize: 12, height: 25 / 12), patternList: [ EasyRichTextPattern( targetString: @@ -59,15 +60,21 @@ class NoticeTextDialog extends StatelessWidget { ), ), 12.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.back(), child: Container( alignment: Alignment.center, height: 44, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: AppColors.actionRed), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + color: AppColors.actionRed), child: Text( "我知道了", - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/alert/splash/update_dialog.dart b/lib/alert/splash/update_dialog.dart index 97e38b3..21f53bf 100644 --- a/lib/alert/splash/update_dialog.dart +++ b/lib/alert/splash/update_dialog.dart @@ -5,11 +5,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/install_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/install_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -118,7 +118,9 @@ class _UpdateDialog extends State { //Row 不给约束,Text 会按自然宽度排版撑出去,必须 Expanded 收回可用宽度才会换行 Expanded( child: Text( - widget.updateInfo.description?.replaceAll("|", "\n") ?? "", + widget.updateInfo.description + ?.replaceAll("|", "\n") ?? + "", style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 12, @@ -240,8 +242,10 @@ class _UpdateDialog extends State { ///下载 apk(仅 Android,iOS 走商店) Future _downloadApk(String url) async { - final saveDirectory = path.join((await getExternalStorageDirectory())?.path ?? "", "apk"); - DioSliceRetryDownloader(DioCli(), url, null, saveDirectory, "paofu.apk", onReceiveProgress: (count, total) { + final saveDirectory = + path.join((await getExternalStorageDirectory())?.path ?? "", "apk"); + DioSliceRetryDownloader(DioCli(), url, null, saveDirectory, "paofu.apk", + onReceiveProgress: (count, total) { progress = (count / total); setState(() {}); }, onRetry: (int retryCount) { diff --git a/lib/alert/video/buy_vip_alert.dart b/lib/alert/video/buy_vip_alert.dart index a3a7eae..d259c35 100644 --- a/lib/alert/video/buy_vip_alert.dart +++ b/lib/alert/video/buy_vip_alert.dart @@ -5,9 +5,9 @@ import 'dart:math' as math; import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:provider/provider.dart'; import '../../hj_model/splash/domain_source_model.dart'; @@ -26,10 +26,12 @@ import 'buy_vip_alert_logic.dart'; class BuyVipAlert extends StatefulWidget { final String? vipId; //外部指定卡ID(可选),不传走分层卡/升级卡兜底 final String? videoId; //在看的那条内容 id,下单时透传给服务端做归因 - final PayOrderTrackInfo? orderTrack; //整份下单上下文,短剧付费墙要带 mediaId/contentId/checkoutContextId + final PayOrderTrackInfo? + orderTrack; //整份下单上下文,短剧付费墙要带 mediaId/contentId/checkoutContextId const BuyVipAlert({super.key, this.vipId, this.videoId, this.orderTrack}); - static Future show({String? vipId, String? videoId, PayOrderTrackInfo? orderTrack}) { + static Future show( + {String? vipId, String? videoId, PayOrderTrackInfo? orderTrack}) { return Get.bottomSheet( BuyVipAlert(vipId: vipId, videoId: videoId, orderTrack: orderTrack), isScrollControlled: true, @@ -42,7 +44,10 @@ class BuyVipAlert extends StatefulWidget { // 可叠弹(试看结束/超时长等多处触发),用 per-实例唯一 tag 隔离 controller class _BuyVipAlertState extends State with UniqueTagMixin { - late final logic = BuyVipAlertLogic(vId: widget.vipId, videoId: widget.videoId, orderTrack: widget.orderTrack); + late final logic = BuyVipAlertLogic( + vId: widget.vipId, + videoId: widget.videoId, + orderTrack: widget.orderTrack); static const _sheetRadius = 26.0; @@ -109,14 +114,18 @@ class _BuyVipAlertState extends State with UniqueTagMixin { _selectionBuilder( (_) => Text( _title, - style: const TextStyle(color: Color(0xE5FFFFFF), fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 16, + fontWeight: FontWeight.w500), ), ), _buildCountdown(), ], ), 14.sizeBoxH, - _selectionBuilder((_) => _buildPriceInfo()), //原价 / 限时特价 / 优惠 + _selectionBuilder( + (_) => _buildPriceInfo()), //原价 / 限时特价 / 优惠 16.sizeBoxH, Expanded( child: _buildContent(), @@ -169,7 +178,8 @@ class _BuyVipAlertState extends State with UniqueTagMixin { child: CarouselSlider.builder( carouselController: logic.pageCtr, itemCount: mgr.vipCards.length + 2, - itemBuilder: (_, index, __) => _selectionBuilder((l) => l.instanceChildItem(index)), + itemBuilder: (_, index, __) => _selectionBuilder( + (l) => l.instanceChildItem(index)), options: CarouselOptions( height: logic.cardHeight, viewportFraction: logic.itemRatio, @@ -180,7 +190,8 @@ class _BuyVipAlertState extends State with UniqueTagMixin { enlargeCenterPage: false, padEnds: false, clipBehavior: Clip.none, - onPageChanged: (index, __) => logic.onPageChanged(index), + onPageChanged: (index, __) => + logic.onPageChanged(index), scrollDirection: Axis.horizontal, ), ), @@ -230,7 +241,8 @@ class _BuyVipAlertState extends State with UniqueTagMixin { decoration: TextDecoration.lineThrough, decorationColor: Color(0x8cFFFFFF), ); - const normal = TextStyle(color: Color(0x8cFFFFFF), fontSize: 14, fontWeight: FontWeight.w500); + const normal = TextStyle( + color: Color(0x8cFFFFFF), fontSize: 14, fontWeight: FontWeight.w500); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -238,16 +250,20 @@ class _BuyVipAlertState extends State with UniqueTagMixin { 24.sizeBoxW, _priceItem("限时特价", "¥$discounted", normal), 24.sizeBoxW, - _priceItem("优惠", "¥${(original - discounted).clamp(0, original)}", normal), + _priceItem( + "优惠", "¥${(original - discounted).clamp(0, original)}", normal), ], ); } - Widget _priceItem(String title, String value, TextStyle valueStyle, {TextStyle? titleStyle}) { + Widget _priceItem(String title, String value, TextStyle valueStyle, + {TextStyle? titleStyle}) { return Row( mainAxisSize: MainAxisSize.min, children: [ - Text(title, style: titleStyle ?? const TextStyle(color: Color(0x99FFFFFF), fontSize: 14)), + Text(title, + style: titleStyle ?? + const TextStyle(color: Color(0x99FFFFFF), fontSize: 14)), 4.sizeBoxW, Text(value, style: valueStyle), ], @@ -260,7 +276,8 @@ class _BuyVipAlertState extends State with UniqueTagMixin { valueListenable: MineMsgProvider().tick, builder: (_, __, ___) { final c = MineMsgProvider().payTier?.config; - if (c == null || !c.hasDiscountCountdown) return const SizedBox.shrink(); + if (c == null || !c.hasDiscountCountdown) + return const SizedBox.shrink(); return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -281,27 +298,35 @@ class _BuyVipAlertState extends State with UniqueTagMixin { width: 24, height: 24, alignment: Alignment.center, - decoration: BoxDecoration(color: const Color(0xffE1351F), borderRadius: BorderRadius.circular(3)), - child: Text(value, style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500)), + decoration: BoxDecoration( + color: const Color(0xffE1351F), + borderRadius: BorderRadius.circular(3)), + child: Text(value, + style: const TextStyle( + color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500)), ); } Widget _colon() => const Padding( padding: EdgeInsets.symmetric(horizontal: 2), - child: Text(":", style: TextStyle(color: Color(0xffDD001B), fontSize: 20)), + child: + Text(":", style: TextStyle(color: Color(0xffDD001B), fontSize: 20)), ); /// 权益区:与会员中心同实验分支 —— classic=A/DISABLED,改版=ACTIVE+B Widget _buildPrivilegeSections({required bool classic}) { return _selectionBuilder((l) { final privileges = l.currentProductModel?.newPrivilege ?? []; - // final coreList = privileges.where((p) => p.isCore == true).toList(); - final moreList = privileges; // privileges.where((p) => p.isCore != true).toList(); + // final coreList = privileges.where((p) => p.isCore == true).toList(); + final moreList = + privileges; // privileges.where((p) => p.isCore != true).toList(); return Column( mainAxisSize: MainAxisSize.min, children: [ - // classic ? _buildClassicCorePrivileges(coreList) : _buildCorePrivileges(coreList), - classic ? _buildClassicMorePrivileges(moreList) : _buildMorePrivileges(moreList), + // classic ? _buildClassicCorePrivileges(coreList) : _buildCorePrivileges(coreList), + classic + ? _buildClassicMorePrivileges(moreList) + : _buildMorePrivileges(moreList), ], ); }); @@ -358,7 +383,8 @@ class _BuyVipAlertState extends State with UniqueTagMixin { childAspectRatio: 63 / 100, ), itemCount: list.length, - itemBuilder: (_, i) => VipProductPrivilegeItem(list[i], classic: true), + itemBuilder: (_, i) => + VipProductPrivilegeItem(list[i], classic: true), ), ], ); @@ -410,6 +436,8 @@ class _BuyVipTopBorderPainter extends CustomPainter { @override bool shouldRepaint(covariant _BuyVipTopBorderPainter oldDelegate) { - return oldDelegate.gradient != gradient || oldDelegate.strokeWidth != strokeWidth || oldDelegate.topRadius != topRadius; + return oldDelegate.gradient != gradient || + oldDelegate.strokeWidth != strokeWidth || + oldDelegate.topRadius != topRadius; } } diff --git a/lib/alert/video/comic_buy_alert.dart b/lib/alert/video/comic_buy_alert.dart index a6a69ab..a856d73 100644 --- a/lib/alert/video/comic_buy_alert.dart +++ b/lib/alert/video/comic_buy_alert.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:provider/provider.dart'; import '../../assets_tool/app_colors.dart'; @@ -75,34 +75,48 @@ class _ComicBuyAlertState extends State { 18.sizeBoxH, const Text( '购买作品', - style: TextStyle(color: Color(0xE5ffffff), fontSize: 20, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xE5ffffff), + fontSize: 20, + fontWeight: FontWeight.w500), ), 36.sizeBoxH, //作品解锁价 Row( children: [ - const Text('作品解锁', style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), + const Text('作品解锁', + style: + TextStyle(color: Color(0xE5ffffff), fontSize: 14)), const Spacer(), GestureDetector( onTap: () => pushToWalletPage(tabPosition: 1), child: Text( '$_price 金币', - style: const TextStyle(color: Color(0xffFF9000), fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xffFF9000), + fontSize: 14, + fontWeight: FontWeight.w500), ), ), ], ), 18.sizeBoxH, - Divider(height: 0.5, color: Colors.white.withValues(alpha: .05)), + Divider( + height: 0.5, color: Colors.white.withValues(alpha: .05)), 18.sizeBoxH, //我的金币余额 + 充值入口 Row( children: [ - const Text('我的金币', style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), + const Text('我的金币', + style: + TextStyle(color: Color(0xE5ffffff), fontSize: 14)), const Spacer(), Text( '${store.wallet?.amount?.toDouble().fixed(2) ?? 0}', - style: const TextStyle(color: Color(0xE5ffffff), fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xE5ffffff), + fontSize: 14, + fontWeight: FontWeight.w500), ), 12.sizeBoxW, InkWell( @@ -125,15 +139,22 @@ class _ComicBuyAlertState extends State { //支付按钮:余额不足直接去充值 GestureDetector( behavior: HitTestBehavior.translucent, - onTap: () => enough ? _buyProduct(true) : pushToWalletPage(tabPosition: 1), + onTap: () => enough + ? _buyProduct(true) + : pushToWalletPage(tabPosition: 1), child: Container( width: double.infinity, height: 47, - decoration: BoxDecoration(color: const Color(0xffFFC000), borderRadius: BorderRadius.circular(30)), + decoration: BoxDecoration( + color: const Color(0xffFFC000), + borderRadius: BorderRadius.circular(30)), alignment: Alignment.center, child: Text( enough ? '$_price金币/立即支付' : '余额不足,前往充值', - style: const TextStyle(color: Color(0xff1F2029), fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xff1F2029), + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), @@ -150,7 +171,9 @@ class _ComicBuyAlertState extends State { if (_isBuying) return; //纯防重入,build 不依赖它,改了不用 setState _isBuying = true; final productType = isAll ? ProductType.mediaAll : ProductType.mediaChapter; - final productID = isAll ? (widget.mediaInfo?.id ?? widget.curModel?.mediaId) : widget.curModel?.id; + final productID = isAll + ? (widget.mediaInfo?.id ?? widget.curModel?.mediaId) + : widget.curModel?.id; await PayManager().buy( productID, productType, diff --git a/lib/alert/video/share_media_dialog.dart b/lib/alert/video/share_media_dialog.dart index 95deb64..973829f 100644 --- a/lib/alert/video/share_media_dialog.dart +++ b/lib/alert/video/share_media_dialog.dart @@ -2,14 +2,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/user/user_info_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/user/user_info_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:qr_flutter/qr_flutter.dart'; import '../../config/address.dart'; @@ -72,7 +72,8 @@ class _ShareMediaDialogState extends State { //app 图标 + 名称 + 标语 Row( children: [ - Image.asset('ic_launcher.webp'.commonImgPath, width: 48.w, height: 48.w), + Image.asset('ic_launcher.webp'.commonImgPath, + width: 48.w, height: 48.w), 10.w.sizeBoxW, Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -80,10 +81,16 @@ class _ShareMediaDialogState extends State { children: [ Text( Config.appName, - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontWeight: FontWeight.w500, fontSize: 14), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontWeight: FontWeight.w500, + fontSize: 14), ), 4.sizeBoxH, - Text("百万大神短剧原创", style: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 10)), + Text("百万大神短剧原创", + style: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 10)), ], ), ], @@ -110,7 +117,8 @@ class _ShareMediaDialogState extends State { height: 94, padding: const EdgeInsets.all(2), color: Colors.white, - child: QrImageView(data: _shareUrl, padding: EdgeInsets.zero), + child: QrImageView( + data: _shareUrl, padding: EdgeInsets.zero), ), 16.sizeBoxW, Expanded( @@ -120,13 +128,18 @@ class _ShareMediaDialogState extends State { children: [ Text( "邀请码${_me?.promotionCode ?? ""}", - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.white.withValues(alpha: .9)), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.white.withValues(alpha: .9)), ), 20.sizeBoxH, Text( '每邀请 1人 送 1天 会员 ${Address.groundUrl}', maxLines: 2, - style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .55)), + style: TextStyle( + fontSize: 12, + color: Colors.white.withValues(alpha: .55)), ), ], ), @@ -164,7 +177,10 @@ class _ShareMediaDialogState extends State { ); } - Widget _button(String text, {required Color bgColor, required Color textColor, required VoidCallback onTap}) { + Widget _button(String text, + {required Color bgColor, + required Color textColor, + required VoidCallback onTap}) { return InkWell( enableFeedback: false, onTap: onTap, @@ -177,7 +193,8 @@ class _ShareMediaDialogState extends State { ), child: Text( text, - style: TextStyle(fontSize: 16, color: textColor, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, color: textColor, fontWeight: FontWeight.w500), ), ), ); diff --git a/lib/alert/video/video_buy_bottom_sheet.dart b/lib/alert/video/video_buy_bottom_sheet.dart index 7d7a2fd..477df07 100644 --- a/lib/alert/video/video_buy_bottom_sheet.dart +++ b/lib/alert/video/video_buy_bottom_sheet.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/mine/widgets/gradient_text.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart'; -import 'package:hgmj/hj_utils/pay/pay_manager.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/mine/widgets/gradient_text.dart'; +import 'package:wydj/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart'; +import 'package:wydj/hj_utils/pay/pay_manager.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:provider/provider.dart'; ///金币购买作品面板 @@ -33,7 +33,8 @@ class _VideoBuyBottomSheetState extends State { bool get _noDiscount => _video.newsType == "PIC" || _isSeedLink; //实际售价:无折扣品类按原价,其余按折后价 - String get _priceText => '${(_noDiscount ? _video.originCoins : _video.coins) ?? 0} 金币'; + String get _priceText => + '${(_noDiscount ? _video.originCoins : _video.coins) ?? 0} 金币'; @override void initState() { @@ -61,19 +62,26 @@ class _VideoBuyBottomSheetState extends State { 18.sizeBoxH, const Text( '购买作品', - style: TextStyle(color: Color(0xE5ffffff), fontSize: 20, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xE5ffffff), + fontSize: 20, + fontWeight: FontWeight.w500), ), 18.sizeBoxH, //作品解锁价 Row( children: [ - const Text('作品解锁', style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), + const Text('作品解锁', + style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), const Spacer(), GestureDetector( onTap: () => CoinPayBottomSheet.show(), child: Text( _priceText, - style: const TextStyle(color: Color(0xffFF9000), fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xffFF9000), + fontSize: 14, + fontWeight: FontWeight.w500), ), ), ], @@ -86,11 +94,15 @@ class _VideoBuyBottomSheetState extends State { //我的金币余额 + 充值入口 Row( children: [ - const Text('我的金币', style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), + const Text('我的金币', + style: TextStyle(color: Color(0xE5ffffff), fontSize: 14)), const Spacer(), Text( '${store.wallet?.amount?.toDouble().fixed(2) ?? 0}', - style: const TextStyle(color: Color(0xE5ffffff), fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xE5ffffff), + fontSize: 14, + fontWeight: FontWeight.w500), ), 12.sizeBoxW, InkWell( @@ -164,7 +176,8 @@ class _VideoBuyBottomSheetState extends State { return [ Row( children: [ - const Text('作品原价', style: TextStyle(color: Color(0xE5FFFFFF), fontSize: 14)), + const Text('作品原价', + style: TextStyle(color: Color(0xE5FFFFFF), fontSize: 14)), const Spacer(), Text( '${_video.originCoins ?? 0} 金币', @@ -183,14 +196,16 @@ class _VideoBuyBottomSheetState extends State { GradientText( discountText, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), - gradient: const LinearGradient(colors: [Color(0xffAC7E6E), Color(0xffA4634D)]), + gradient: const LinearGradient( + colors: [Color(0xffAC7E6E), Color(0xffA4634D)]), ), const Spacer(), GestureDetector( onTap: () => pushToWalletPage(), child: GradientText( isVip ? '升级会员免费看' : '购买VIP免费看', - gradient: const LinearGradient(colors: [Color(0xffAC7E6E), Color(0xffA4634D)]), + gradient: const LinearGradient( + colors: [Color(0xffAC7E6E), Color(0xffA4634D)]), style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, @@ -205,7 +220,10 @@ class _VideoBuyBottomSheetState extends State { ]; } - Widget _button(String text, {required Color textColor, required BoxDecoration decoration, required VoidCallback onTap}) { + Widget _button(String text, + {required Color textColor, + required BoxDecoration decoration, + required VoidCallback onTap}) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: onTap, @@ -215,7 +233,8 @@ class _VideoBuyBottomSheetState extends State { decoration: decoration, child: Text( text, - style: TextStyle(color: textColor, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: textColor, fontSize: 16, fontWeight: FontWeight.w500), ), ), ); @@ -227,7 +246,8 @@ class _VideoBuyBottomSheetState extends State { return; } //黄游(SEED_LINK)和普通视频都按单片算,动漫按整部算 - final type = (!_isSeedLink && _isCartoon) ? ProductType.mediaAll : ProductType.media; + final type = + (!_isSeedLink && _isCartoon) ? ProductType.mediaAll : ProductType.media; await PayManager().buy( _video.id, type, diff --git a/lib/alert/video/video_line_menu_alert.dart b/lib/alert/video/video_line_menu_alert.dart index bc1a69d..7096638 100644 --- a/lib/alert/video/video_line_menu_alert.dart +++ b/lib/alert/video/video_line_menu_alert.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../config/address.dart'; import '../../hj_model/splash/domain_source_model.dart'; @@ -70,7 +70,9 @@ class VideoLineMenuAlert extends StatelessWidget { domain.desc ?? "", style: TextStyle( fontSize: 14, - color: isSelected ? Color(0xffFFC000) : Colors.white.withValues(alpha: 0.45), + color: isSelected + ? Color(0xffFFC000) + : Colors.white.withValues(alpha: 0.45), fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400, ), ), diff --git a/lib/alert/video/vip_acg_dialog.dart b/lib/alert/video/vip_acg_dialog.dart index 9a92aa0..8e4f3da 100644 --- a/lib/alert/video/vip_acg_dialog.dart +++ b/lib/alert/video/vip_acg_dialog.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; /// 动漫/图集的 VIP 门槛提示弹窗:只有文案和一个开通按钮 class VipACGDialog extends StatelessWidget { @@ -16,13 +16,19 @@ class VipACGDialog extends StatelessWidget { children: [ Text( "温馨提示", - style: TextStyle(fontSize: 20, color: Colors.white.withValues(alpha: .9), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 20, + color: Colors.white.withValues(alpha: .9), + fontWeight: FontWeight.w500), ), 24.sizeBoxH, Text( "本内容需要开通VIP会员\n开通会员 即可解锁查看完整版", textAlign: TextAlign.center, - style: TextStyle(fontSize: 16, color: Colors.white.withValues(alpha: .45), height: 2), + style: TextStyle( + fontSize: 16, + color: Colors.white.withValues(alpha: .45), + height: 2), ), 24.sizeBoxH, //开通按钮。margin 留在 InkWell 外,否则左右各 12 的空白会被算进点击热区 @@ -34,10 +40,15 @@ class VipACGDialog extends StatelessWidget { child: Container( height: 44, alignment: Alignment.center, - decoration: BoxDecoration(color: AppColors.actionRed, borderRadius: BorderRadius.circular(30)), + decoration: BoxDecoration( + color: AppColors.actionRed, + borderRadius: BorderRadius.circular(30)), child: const Text( "立即开通", - style: TextStyle(fontSize: 16, color: Color(0xff1F2029), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, + color: Color(0xff1F2029), + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/alert/vip_guide/guide_bottom_sheet.dart b/lib/alert/vip_guide/guide_bottom_sheet.dart index 1604add..4e4fef8 100644 --- a/lib/alert/vip_guide/guide_bottom_sheet.dart +++ b/lib/alert/vip_guide/guide_bottom_sheet.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../hj_page/mine/mine_vip/pay_order_source.dart'; import '../../hj_page/mine/mine_vip/vip_support_model.dart'; @@ -66,14 +66,21 @@ class GuideBottomSheet extends StatelessWidget { return show( scene: GuideScene.videoPreviewEnd, title: Text( - config?.title?.isNotEmpty == true ? config!.title! : '该视频为VIP内容\n只能观看试看内容哦~', + config?.title?.isNotEmpty == true + ? config!.title! + : '该视频为VIP内容\n只能观看试看内容哦~', textAlign: TextAlign.center, - style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Colors.white, fontSize: 17, fontWeight: FontWeight.w600), ), subtitle: GradientText( - config?.description?.isNotEmpty == true ? config!.description! : '想要查看完整内容,需要开通会员', - gradient: const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]), - style: const TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), + config?.description?.isNotEmpty == true + ? config!.description! + : '想要查看完整内容,需要开通会员', + gradient: + const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]), + style: const TextStyle( + color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), ), buttonText: buttonText, ); @@ -87,8 +94,13 @@ class GuideBottomSheet extends StatelessWidget { width: double.infinity, padding: EdgeInsets.fromLTRB(16, 18, 16, 18 + screen.paddingBottom), decoration: const BoxDecoration( - gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xff0F0F0F), Colors.black]), - border: Border(top: BorderSide(color: Color(0x4DE4BB6D))), // rgba(228,187,109,0.3) + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0xff0F0F0F), Colors.black]), + border: Border( + top: BorderSide( + color: Color(0x4DE4BB6D))), // rgba(228,187,109,0.3) borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), child: Column( @@ -103,7 +115,8 @@ class GuideBottomSheet extends StatelessWidget { SizedBox( width: 270, height: 122, - child: NetworkImageLoader(imageUrl: cover, fit: BoxFit.fill, borderRadius: 8), + child: NetworkImageLoader( + imageUrl: cover, fit: BoxFit.fill, borderRadius: 8), ), 18.sizeBoxH, subtitle, @@ -116,11 +129,21 @@ class GuideBottomSheet extends StatelessWidget { height: 52, alignment: Alignment.center, decoration: BoxDecoration( - gradient: const LinearGradient(colors: [Color(0xffFFB03F), Color(0xffF2680C)]), + gradient: const LinearGradient( + colors: [Color(0xffFFB03F), Color(0xffF2680C)]), borderRadius: BorderRadius.circular(26), - boxShadow: [BoxShadow(color: const Color(0x73F2680C), blurRadius: 18, offset: const Offset(0, 6))], // rgba(242,104,12,0.45) + boxShadow: [ + BoxShadow( + color: const Color(0x73F2680C), + blurRadius: 18, + offset: const Offset(0, 6)) + ], // rgba(242,104,12,0.45) ), - child: Text(buttonText, style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w700)), + child: Text(buttonText, + style: const TextStyle( + color: Colors.white, + fontSize: 17, + fontWeight: FontWeight.w700)), ), ), ], diff --git a/lib/alert/vip_guide/guide_common.dart b/lib/alert/vip_guide/guide_common.dart index 97018a9..b9be4d0 100644 --- a/lib/alert/vip_guide/guide_common.dart +++ b/lib/alert/vip_guide/guide_common.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../hj_page/main_page/provider/msg_provider.dart'; import '../../hj_page/mine/mine_vip/mine_charge_vip_page.dart'; @@ -19,13 +19,18 @@ import 'guide_manager.dart'; Future loadGuideCard(GuideScene scene) async { final config = GuideManager().configOf(scene); if (config == null) return null; // 开关关着 - if (config.productId?.isNotEmpty != true || config.cover?.isNotEmpty != true) { + if (config.productId?.isNotEmpty != true || + config.cover?.isNotEmpty != true) { debugLog('paymentGuide', '${scene.value} 缺 productId 或 cover,配置有误不弹'); return null; } - if (vipProductManager.vipCards.isEmpty) await vipProductManager.loadVipCards(); - final card = vipProductManager.vipCards.firstWhereOrNull((e) => e.productID == config.productId); - if (card == null) debugLog('paymentGuide', '${scene.value} 配置的会员卡不在列表里,不弹: ${config.productId}'); + if (vipProductManager.vipCards.isEmpty) + await vipProductManager.loadVipCards(); + final card = vipProductManager.vipCards + .firstWhereOrNull((e) => e.productID == config.productId); + if (card == null) + debugLog( + 'paymentGuide', '${scene.value} 配置的会员卡不在列表里,不弹: ${config.productId}'); return card; } @@ -38,7 +43,9 @@ bool isUnpayGuideUser() { /// 场景 → 下单来源页(透传 /mine/topay 的 sourcePage) PaySourcePage guideSourcePage(GuideScene scene) => switch (scene) { - GuideScene.homeNewUser || GuideScene.homeOldUser || GuideScene.homeNewUserFreeTrial => + GuideScene.homeNewUser || + GuideScene.homeOldUser || + GuideScene.homeNewUserFreeTrial => PaySourcePage.homeUserSegment, GuideScene.vipCenter => PaySourcePage.vipCenter, _ => PaySourcePage.videoBottomSheet, //播放页起播引导 / 返回挽留 @@ -47,5 +54,6 @@ PaySourcePage guideSourcePage(GuideScene scene) => switch (scene) { /// 开通 → 关弹窗 + 进会员页并选中该卡(落地页 VIP_CENTER 开着还会再弹一次,不去重) void goVipDetail(VipProductModel card, {required PaySourcePage sourcePage}) { Get.back(result: true); // 带回"去开通了",调用方据此不恢复播放 - Get.to(() => MineChargeVipPage(vipID: card.productID, sourcePage: sourcePage)); + Get.to( + () => MineChargeVipPage(vipID: card.productID, sourcePage: sourcePage)); } diff --git a/lib/alert/vip_guide/guide_countdown_dialog.dart b/lib/alert/vip_guide/guide_countdown_dialog.dart index 63e9b83..ec31e6f 100644 --- a/lib/alert/vip_guide/guide_countdown_dialog.dart +++ b/lib/alert/vip_guide/guide_countdown_dialog.dart @@ -2,8 +2,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../assets_tool/images.dart'; import '../../hj_page/mine/mine_vip/pay_order_source.dart'; @@ -34,7 +34,8 @@ class PromoCountdown { /// 长视频返回挽留 / 进会员页时触发 class GuideCountdownDialog extends StatelessWidget { final VipProductModel card; - final ValueChanged? onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡) + final ValueChanged? + onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡) final PaySourcePage sourcePage; final String cover; // 场景下发的主图,相对路径由 ImageCacheManager 拼域名 const GuideCountdownDialog({ @@ -47,7 +48,9 @@ class GuideCountdownDialog extends StatelessWidget { /// [scene] 决定主图/卡/下单来源,调用方须先用开关判过能弹 /// 返回 true = 点了「立即开通」(点X/点蒙层/没弹成都是 false),返回挽留场景据此决定要不要放行返回 - static Future show({required GuideScene scene, ValueChanged? onConfirm}) async { + static Future show( + {required GuideScene scene, + ValueChanged? onConfirm}) async { final card = await loadGuideCard(scene); if (card == null) return false; // 配置有误不弹 final confirmed = await Get.dialog( @@ -92,15 +95,29 @@ class GuideCountdownDialog extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ - const Text('现在下单获得', style: TextStyle(color: Colors.white, fontSize: 19, fontWeight: FontWeight.w800)), + const Text('现在下单获得', + style: TextStyle( + color: Colors.white, + fontSize: 19, + fontWeight: FontWeight.w800)), 2.sizeBoxW, const GradientText( '优惠', - gradient: LinearGradient(colors: [Color(0xffFFE3A0), Color(0xffF0A93C)]), - style: TextStyle(color: Colors.white, fontSize: 26, fontWeight: FontWeight.w800), + gradient: LinearGradient(colors: [ + Color(0xffFFE3A0), + Color(0xffF0A93C) + ]), + style: TextStyle( + color: Colors.white, + fontSize: 26, + fontWeight: FontWeight.w800), ), 2.sizeBoxW, - const Text('福利', style: TextStyle(color: Colors.white, fontSize: 19, fontWeight: FontWeight.w800)), + const Text('福利', + style: TextStyle( + color: Colors.white, + fontSize: 19, + fontWeight: FontWeight.w800)), ], ), 15.sizeBoxH, @@ -119,15 +136,24 @@ class GuideCountdownDialog extends StatelessWidget { height: 52, alignment: Alignment.center, decoration: BoxDecoration( - gradient: const LinearGradient(colors: [Color(0xffFFB03F), Color(0xffF2680C)]), + gradient: const LinearGradient(colors: [ + Color(0xffFFB03F), + Color(0xffF2680C) + ]), borderRadius: BorderRadius.circular(26), boxShadow: [ - BoxShadow(color: const Color(0x73F2680C), blurRadius: 18, offset: const Offset(0, 6)) + BoxShadow( + color: const Color(0x73F2680C), + blurRadius: 18, + offset: const Offset(0, 6)) ], // rgba(242,104,12,0.45) ), child: Text( '立即开通 · 仅需¥${card.discountedPriceUI}', - style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w700), + style: const TextStyle( + color: Colors.white, + fontSize: 17, + fontWeight: FontWeight.w700), ), ), ), @@ -140,7 +166,8 @@ class GuideCountdownDialog extends StatelessWidget { child: SizedBox( width: 270, height: 122, - child: NetworkImageLoader(imageUrl: cover, fit: BoxFit.fill, borderRadius: 8), + child: NetworkImageLoader( + imageUrl: cover, fit: BoxFit.fill, borderRadius: 8), ), ), ], @@ -193,7 +220,11 @@ class _CountdownRowState extends State<_CountdownRow> { return Row( mainAxisSize: MainAxisSize.min, children: [ - const Text('距优惠结束', style: TextStyle(color: Color(0xffB8AE9C), fontSize: 12, fontWeight: FontWeight.w500)), + const Text('距优惠结束', + style: TextStyle( + color: Color(0xffB8AE9C), + fontSize: 12, + fontWeight: FontWeight.w500)), 8.sizeBoxW, ValueListenableBuilder( valueListenable: _remain, @@ -215,15 +246,22 @@ class _CountdownRowState extends State<_CountdownRow> { // 时/分/秒块 Widget _timeCell(int v) => Container( padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 4), - decoration: BoxDecoration(color: const Color(0xffE23B2E), borderRadius: BorderRadius.circular(6)), + decoration: BoxDecoration( + color: const Color(0xffE23B2E), + borderRadius: BorderRadius.circular(6)), child: Text( v.toString().padLeft(2, '0'), - style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700), + style: const TextStyle( + color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700), ), ); Widget get _colon => const Padding( padding: EdgeInsets.symmetric(horizontal: 3), - child: Text(':', style: TextStyle(color: Color(0xffE85B4F), fontSize: 14, fontWeight: FontWeight.w700)), + child: Text(':', + style: TextStyle( + color: Color(0xffE85B4F), + fontSize: 14, + fontWeight: FontWeight.w700)), ); } diff --git a/lib/alert/vip_guide/guide_home_dialog.dart b/lib/alert/vip_guide/guide_home_dialog.dart index d59dc02..9eaefaa 100644 --- a/lib/alert/vip_guide/guide_home_dialog.dart +++ b/lib/alert/vip_guide/guide_home_dialog.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_page/home/activity_float/home_activity_float.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/fly_to_overlay.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_page/home/activity_float/home_activity_float.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/fly_to_overlay.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// 支付分层首页弹窗:展示后端 homePage 图,点击跳会员页并选中 config.vipCard。 /// 倒计时读 config.lastDiscountTime,秒级刷新由 MineMsgProvider().tick 驱动,过期自动停 @@ -60,7 +60,8 @@ class _GuideHomeDialogState extends State { if (box == null || !box.hasSize) return null; final origin = box.localToGlobal(Offset.zero); const w = 60.0, h = 66.0; // 与 _LayeredFloatView 的尺寸一致 - return Rect.fromLTWH(origin.dx + box.size.width - w, origin.dy + box.size.height - h, w, h); + return Rect.fromLTWH( + origin.dx + box.size.width - w, origin.dy + box.size.height - h, w, h); } @override @@ -104,7 +105,8 @@ class _GuideHomeDialogState extends State { imageUrl: config.homePage ?? "", fit: BoxFit.fill, borderRadius: 0, - placeHolderWidget: Container(color: const Color(0x00000000)), + placeHolderWidget: + Container(color: const Color(0x00000000)), ), // 倒计时胶囊:海报右上角,听 tick 每秒刷新,过期自动收起 Positioned( @@ -112,7 +114,10 @@ class _GuideHomeDialogState extends State { right: 0, child: ValueListenableBuilder( valueListenable: MineMsgProvider().tick, - builder: (_, __, ___) => config.hasDiscountCountdown ? _buildCountdownPill() : const SizedBox.shrink(), + builder: (_, __, ___) => + config.hasDiscountCountdown + ? _buildCountdownPill() + : const SizedBox.shrink(), ), ), ], @@ -123,7 +128,8 @@ class _GuideHomeDialogState extends State { 20.sizeBoxH, GestureDetector( onTap: _close, - child: Image.asset("close_button.png".commonImgPath, width: 32), + child: Image.asset("close_button.png".commonImgPath, + width: 32), ) ], ), @@ -149,7 +155,10 @@ class _GuideHomeDialogState extends State { ), child: Text( '${config.discountHour}:${config.discountMin}:${config.discountSec}', - style: const TextStyle(color: Color(0xffFFF0D1), fontSize: 20, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Color(0xffFFF0D1), + fontSize: 20, + fontWeight: FontWeight.w600), ), ); } diff --git a/lib/alert/vip_guide/guide_manager.dart b/lib/alert/vip_guide/guide_manager.dart index 0220dd0..3f045da 100644 --- a/lib/alert/vip_guide/guide_manager.dart +++ b/lib/alert/vip_guide/guide_manager.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; import '../../hj_page/main_page/provider/msg_provider.dart'; import 'guide_config.dart'; @@ -45,8 +45,12 @@ class GuideManager { /// 请求还没回来,硬判成老用户会让新用户永远错过新人引导,且 _adShown 保证不会再有第二次 GuideScene? get homeScene { final tier = MineMsgProvider().payTier?.status; - if (tier == null) return [GuideScene.homeNewUser, GuideScene.homeOldUser].firstWhereOrNull(canShow); - final scene = tier == PayTier.newUnpay ? GuideScene.homeNewUser : GuideScene.homeOldUser; + if (tier == null) + return [GuideScene.homeNewUser, GuideScene.homeOldUser] + .firstWhereOrNull(canShow); + final scene = tier == PayTier.newUnpay + ? GuideScene.homeNewUser + : GuideScene.homeOldUser; return canShow(scene) ? scene : null; } } diff --git a/lib/config/config.dart b/lib/config/config.dart index 17d69ad..357505f 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -4,7 +4,7 @@ import '../hj_model/splash/domain_source_model.dart'; /// 全局配置:常量 + 启动时由 /ping/domain 下发并缓存的运营配置 class Config { // ===== 应用标识 ===== - static const appName = '黄果漫剧'; + static const appName = '51短剧'; static const appId = 'JHAc-214'; // 埋点app id static const innerVersion = '2.0.0'; static const isDebug = false; @@ -21,7 +21,7 @@ class Config { static const signKey = 'kaFtkDJRcchRMTI9'; // ===== 域名 / 线路 ===== - static String dns = 'hgmj.mfcg.it.com'; // 运维提供,返回配置域名(TXT 查询,只填域名不带 https://) + static String dns = 'wydj.mfcg.it.com'; // 运维提供,返回配置域名(TXT 查询,只填域名不带 https://) /// 本地兜底线路(无本地缓存线路时用) static const lineList = isDebug @@ -43,11 +43,12 @@ class Config { // ===== 首页模块数据 ===== static HomePlateModel? plateModule; // 亚模块数据 static List? jgArea; // 金刚区 - static List? marquees; // 新版跑马灯数据 + static List? marquees; // 新版跑马灯数据 static List? get marqueesActive { // 新版跑马灯数据 激活的 return marquees?.where((e) => e.active == true).toList(); } + static List bannerJumps = []; static BannerJump? proxyBanner; @@ -66,7 +67,8 @@ class Config { // ===== 短剧 ===== static String? shortDramaCardId; // 短剧卡 id,付费墙拉起会员弹窗时默认选中它 static bool entryPopupEnabled = true; // 「AI爽剧来袭」引导气泡开关,后台置 false 即永久不出现 - static bool isDramaEntry = false; // ping 的 defaultEntryPage==drama:启动直接落在短剧 tab + static bool isDramaEntry = + false; // ping 的 defaultEntryPage==drama:启动直接落在短剧 tab // ===== 开关 / 展示配置 ===== static bool isStoreOpen = false; // 商店模块开关 diff --git a/lib/hj_model/acg/cartoon_more_list.dart b/lib/hj_model/acg/cartoon_more_list.dart index 32633f7..1a9479f 100644 --- a/lib/hj_model/acg/cartoon_more_list.dart +++ b/lib/hj_model/acg/cartoon_more_list.dart @@ -1,8 +1,8 @@ -import 'package:hgmj/hj_model/actress_info.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/hj_model/actress_info.dart'; +import 'package:wydj/hj_model/video_model.dart'; import '../cartoon_media_info.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/text_util.dart'; class AllMediaInfo { List? contents; @@ -21,11 +21,15 @@ class AllMediaInfo { List? allActress; String? get coverH { - return (horizontalCover?.isNotEmpty == true) ? horizontalCover : verticalCover; + return (horizontalCover?.isNotEmpty == true) + ? horizontalCover + : verticalCover; } String? get coverV { - return (verticalCover?.isNotEmpty == true) ? verticalCover : horizontalCover; + return (verticalCover?.isNotEmpty == true) + ? verticalCover + : horizontalCover; } String? id; @@ -117,7 +121,9 @@ class AllMediaInfo { } AllMediaInfo.fromJson(Map json) { - contents = json["contents"] == null ? [] : List.from(json["contents"]!.map((x) => Content.fromJson(x))); + contents = json["contents"] == null + ? [] + : List.from(json["contents"]!.map((x) => Content.fromJson(x))); countBrowse = json["countBrowse"]; countCollect = json["countCollect"]; countComment = json["countComment"]; @@ -130,11 +136,16 @@ class AllMediaInfo { freeTime = json["freeTime"]; hasFollow = json["hasFollow"]; horizontalCover = json["horizontalCover"]; - allActress = json["actresses"] == null ? [] : List.from(json["actresses"]!.map((x) => ActressInfo.fromJson(x))); + allActress = json["actresses"] == null + ? [] + : List.from( + json["actresses"]!.map((x) => ActressInfo.fromJson(x))); id = json["id"]; kind = json["kind"]; mId = json["mId"]; - mediaStatus = json["mediaStatus"] == null ? null : VidStatus.fromMap(json["mediaStatus"]); + mediaStatus = json["mediaStatus"] == null + ? null + : VidStatus.fromMap(json["mediaStatus"]); mediaType = json["mediaType"]; moduleName = json["moduleName"]; number = json["number"]; @@ -148,7 +159,10 @@ class AllMediaInfo { sortCode = json["sortCode"]; status = json["status"]; summary = json["summary"]; - tagDetails = json["tagDetails"] == null ? [] : List.from(json["tagDetails"]!.map((x) => TagsBean.fromMap(x))); + tagDetails = json["tagDetails"] == null + ? [] + : List.from( + json["tagDetails"]!.map((x) => TagsBean.fromMap(x))); tags = parseStringList(json["tags"]); title = json["title"]; totalEpisode = json["totalEpisode"]; @@ -230,7 +244,9 @@ class Content { md5 = json["md5"]; mediaId = json["mediaId"]; mediaSize = json["mediaSize"]; - mediaStatus = json["mediaStatus"] == null ? null : VidStatus.fromMap(json["mediaStatus"]); + mediaStatus = json["mediaStatus"] == null + ? null + : VidStatus.fromMap(json["mediaStatus"]); name = json["name"]; playTime = json["playTime"]; price = json["price"]; @@ -265,7 +281,8 @@ class Content { "ratio": ratio, "text": text, "updateTime": updateTime, - "urlSet": urlSet == null ? [] : List.from(urlSet!.map((x) => x)), + "urlSet": + urlSet == null ? [] : List.from(urlSet!.map((x) => x)), "videoUrl": videoUrl, "weight": weight, }; @@ -282,8 +299,12 @@ class MediaSearchListModel { MediaSearchListModel.fromJson(dynamic json) { hasNext = json['hasNext']; - list = (json['list'] as List?)?.map((v) => CartoonMediaInfo.fromJson(v)).toList(); - tagMedia = (json['tagMedia'] as List?)?.map((v) => CartoonMediaInfo.fromJson(v)).toList(); + list = (json['list'] as List?) + ?.map((v) => CartoonMediaInfo.fromJson(v)) + .toList(); + tagMedia = (json['tagMedia'] as List?) + ?.map((v) => CartoonMediaInfo.fromJson(v)) + .toList(); tagId = json['tagId']; total = json['total']; } @@ -298,4 +319,3 @@ class MediaSearchListModel { return map; } } - diff --git a/lib/hj_model/acg/comic_chapters_model.dart b/lib/hj_model/acg/comic_chapters_model.dart index 5dcc5a8..92b55a7 100644 --- a/lib/hj_model/acg/comic_chapters_model.dart +++ b/lib/hj_model/acg/comic_chapters_model.dart @@ -1,5 +1,5 @@ //漫画章节 -import 'package:hgmj/config/address.dart' as address; +import 'package:wydj/config/address.dart' as address; import 'package:path/path.dart' as path; import '../media_content.dart'; diff --git a/lib/hj_model/actress_info.dart b/lib/hj_model/actress_info.dart index e3769ad..2c8345e 100644 --- a/lib/hj_model/actress_info.dart +++ b/lib/hj_model/actress_info.dart @@ -1,5 +1,4 @@ -import 'package:hgmj/hj_utils/text_util.dart'; - +import 'package:wydj/hj_utils/text_util.dart'; class ActressInfo { String? age; diff --git a/lib/hj_model/actress_model.dart b/lib/hj_model/actress_model.dart index d510436..cf636cf 100644 --- a/lib/hj_model/actress_model.dart +++ b/lib/hj_model/actress_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_model/actress_info.dart'; +import 'package:wydj/hj_model/actress_info.dart'; class ActressModel { ActressModel({ diff --git a/lib/hj_model/cartoon_media_info.dart b/lib/hj_model/cartoon_media_info.dart index 4d35713..b248be8 100644 --- a/lib/hj_model/cartoon_media_info.dart +++ b/lib/hj_model/cartoon_media_info.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import 'acg/comic_chapters_model.dart'; import 'actress_info.dart'; @@ -30,7 +30,8 @@ class CartoonMediaInfo { int? totalEpisode; //总集数 int? currentEpisode; //当前集数 int? freeEpisode; //免费集数 - bool isCartoonFreeEpisode = false; //当前播放集是否属于免费集(前 freeEpisode 集):运行时按当前集号计算,命中则不拦播、进度可全程拖 + bool isCartoonFreeEpisode = + false; //当前播放集是否属于免费集(前 freeEpisode 集):运行时按当前集号计算,命中则不拦播、进度可全程拖 int? updateStatus; //更新状态 0 默认 1、更新中 2、已完结 String? updateTime; //文档更新时间 String? createdAt; //文档创建时间 @@ -86,16 +87,19 @@ class CartoonMediaInfo { bool isSelected = false; // 是否选中 String? heroTag; //本地字段,用于传递hero动画tag 随机数 - String? get coverH => horizontalCover?.isNotEmpty == true ? horizontalCover : verticalCover; + String? get coverH => + horizontalCover?.isNotEmpty == true ? horizontalCover : verticalCover; - String? get coverV => verticalCover?.isNotEmpty == true ? verticalCover : horizontalCover; + String? get coverV => + verticalCover?.isNotEmpty == true ? verticalCover : horizontalCover; String get unit => mediaType == 'image' ? '话' : '章'; //更新状态 String get updateDesc => updateStatus == 1 ? '连载中' : '已完结'; String get tagIds => tagDetails?.map((e) => e.id).toList().join(',') ?? ''; - String get tagNames => tagDetails?.map((e) => e.name).toList().join(',') ?? ''; + String get tagNames => + tagDetails?.map((e) => e.name).toList().join(',') ?? ''; //更新状态 String get getDetailUpdateString { @@ -237,50 +241,51 @@ class CartoonMediaInfo { globalStore.isSuperUp; } - CartoonMediaInfo( - {this.contents, - this.choiceSort, - this.countBrowse, - this.countCollect, - this.countComment, - this.countLike, - this.countPurchases, - this.countPurchasesRate, - this.countView, - this.createdAt, - this.direction, - this.freeTime, - this.horizontalCover, - this.id, - this.isDelete, - this.kind, - this.mId, - this.mediaType, - this.moduleName, - this.permission, - this.permissionIconHide, - this.price, - this.sId, - this.discountPrice, - this.sectionName, - this.sectionSort, - this.sortCode, - this.status, - this.summary, - this.tagDetails, - this.title, - this.totalEpisode, - this.currentEpisode, - this.updateStatus, - this.updateTime, - this.updatedAct, - this.verticalCover, - this.author, - this.freeEpisode, - this.contentsPrice, - this.mediaSubType, - this.actress, - this.hot,}); + CartoonMediaInfo({ + this.contents, + this.choiceSort, + this.countBrowse, + this.countCollect, + this.countComment, + this.countLike, + this.countPurchases, + this.countPurchasesRate, + this.countView, + this.createdAt, + this.direction, + this.freeTime, + this.horizontalCover, + this.id, + this.isDelete, + this.kind, + this.mId, + this.mediaType, + this.moduleName, + this.permission, + this.permissionIconHide, + this.price, + this.sId, + this.discountPrice, + this.sectionName, + this.sectionSort, + this.sortCode, + this.status, + this.summary, + this.tagDetails, + this.title, + this.totalEpisode, + this.currentEpisode, + this.updateStatus, + this.updateTime, + this.updatedAct, + this.verticalCover, + this.author, + this.freeEpisode, + this.contentsPrice, + this.mediaSubType, + this.actress, + this.hot, + }); CartoonMediaInfo.fromJson(dynamic json) { freeEpisode = json['freeEpisode']; @@ -321,11 +326,15 @@ class CartoonMediaInfo { status = json['status']; summary = json['summary']; lsjId = json['lsjId']; - actress = json["actress"] == null ? null : ActressInfo.fromJson(json["actress"]); - allActress = json["actresses"] == null ? [] : List.from(json["actresses"]!.map((x) => ActressInfo.fromJson(x))); + actress = + json["actress"] == null ? null : ActressInfo.fromJson(json["actress"]); + allActress = json["actresses"] == null + ? [] + : List.from( + json["actresses"]!.map((x) => ActressInfo.fromJson(x))); hasFollow = json['hasFollow']; final hot = json['hot']; - if(hot is int) { + if (hot is int) { this.hot = hot; } if (json['tagDetails'] != null) { diff --git a/lib/hj_model/comment/comment_list_res.dart b/lib/hj_model/comment/comment_list_res.dart index db2b7b1..fd3c565 100644 --- a/lib/hj_model/comment/comment_list_res.dart +++ b/lib/hj_model/comment/comment_list_res.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_model/comment/comment_model.dart'; +import 'package:wydj/hj_model/comment/comment_model.dart'; ///评论列表返回信息 class CommentListRes { diff --git a/lib/hj_model/comment/comment_model.dart b/lib/hj_model/comment/comment_model.dart index 2061740..625e624 100644 --- a/lib/hj_model/comment/comment_model.dart +++ b/lib/hj_model/comment/comment_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_model/comment/reply_model.dart'; +import 'package:wydj/hj_model/comment/reply_model.dart'; class CommentModel { String? id; diff --git a/lib/hj_model/drama/drama_models.dart b/lib/hj_model/drama/drama_models.dart index 8705580..48f5723 100644 --- a/lib/hj_model/drama/drama_models.dart +++ b/lib/hj_model/drama/drama_models.dart @@ -1,5 +1,5 @@ -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/media_content.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/media_content.dart'; /// 一条短剧观看记录:续播位置 + 列表展示用的剧信息快照。本地记录,不走后端,见 [DramaResumeStore]。 /// 落库时整条存成 model_data,所以 [mediaId] 必须写进 json—— @@ -29,7 +29,9 @@ class DramaResume { : mediaId = json?['mediaId'] ?? '', contentId = json?['contentId'] ?? '', progressSeconds = json?['progressSeconds'] ?? 0, - drama = json?['drama'] == null ? null : DramaMediaInfo.fromJson(json['drama']), + drama = json?['drama'] == null + ? null + : DramaMediaInfo.fromJson(json['drama']), watchedAt = json?['watchedAt'] ?? 0; Map toJson() => { @@ -62,9 +64,12 @@ class DramaPaywall { String get titleUI => title?.isNotEmpty == true ? title! : '更多精彩解锁即享'; - String get coinButtonUI => coinButtonText?.isNotEmpty == true ? coinButtonText! : '${unlockCoin ?? 0}金币解锁'; + String get coinButtonUI => coinButtonText?.isNotEmpty == true + ? coinButtonText! + : '${unlockCoin ?? 0}金币解锁'; - String get cardButtonUI => cardButtonText?.isNotEmpty == true ? cardButtonText! : '开通短剧卡免费看'; + String get cardButtonUI => + cardButtonText?.isNotEmpty == true ? cardButtonText! : '开通短剧卡免费看'; } /// AI短剧 Feed 的一条:某部剧 + 该剧第一集。整页走 ListBaseModel @@ -76,7 +81,8 @@ class DramaFeedItem { json ??= {}; //缺 media 就不造空模型,上层按 null 过滤掉这条,别让信息流多出一个没剧名没地址的空位 if (json['media'] != null) media = DramaMediaInfo.fromJson(json['media']); - if (json['content'] != null) content = MediaContent.fromJson(json['content']); + if (json['content'] != null) + content = MediaContent.fromJson(json['content']); } } @@ -104,9 +110,12 @@ class DramaTopic { name = json['name']?.toString(); topicType = json['topicType']?.toString(); systemKey = json['systemKey']?.toString(); - sort = json['sort'] is int ? json['sort'] as int : int.tryParse('${json['sort'] ?? ''}'); - workCount = - json['workCount'] is int ? json['workCount'] as int : int.tryParse('${json['workCount'] ?? ''}'); + sort = json['sort'] is int + ? json['sort'] as int + : int.tryParse('${json['sort'] ?? ''}'); + workCount = json['workCount'] is int + ? json['workCount'] as int + : int.tryParse('${json['workCount'] ?? ''}'); } } @@ -121,9 +130,14 @@ class DramaSearchResult { json ??= {}; hasNext = json['hasNext'] == true; tagID = json['tagID']?.toString(); - list = (json['list'] as List?)?.map((e) => DramaMediaInfo.fromJson(e)).toList() ?? []; - tagMediaList = - (json['tagMediaList'] as List?)?.map((e) => DramaMediaInfo.fromJson(e)).toList() ?? []; + list = (json['list'] as List?) + ?.map((e) => DramaMediaInfo.fromJson(e)) + .toList() ?? + []; + tagMediaList = (json['tagMediaList'] as List?) + ?.map((e) => DramaMediaInfo.fromJson(e)) + .toList() ?? + []; } } diff --git a/lib/hj_model/drama_media_info.dart b/lib/hj_model/drama_media_info.dart index 1a192f3..bbd0236 100644 --- a/lib/hj_model/drama_media_info.dart +++ b/lib/hj_model/drama_media_info.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_model/video_model.dart'; /// 短剧作品信息(接口 DramaInfo:一部剧 + 一堆分集) /// 单集播放数据用 [toVideoModel] 转成 VideoModel 交给短视频播放器 @@ -72,9 +72,11 @@ class DramaMediaInfo { bool haxNextEpisode = true; //是否还有下一页 bool isSelected = false; //是否选中 - String? get coverH => horizontalCover?.isNotEmpty == true ? horizontalCover : verticalCover; + String? get coverH => + horizontalCover?.isNotEmpty == true ? horizontalCover : verticalCover; - String? get coverV => verticalCover?.isNotEmpty == true ? verticalCover : horizontalCover; + String? get coverV => + verticalCover?.isNotEmpty == true ? verticalCover : horizontalCover; String get unit => '集'; @@ -83,9 +85,11 @@ class DramaMediaInfo { String get tagIds => tagDetails?.map((e) => e.id).toList().join(',') ?? ''; - String get tagNames => tagDetails?.map((e) => e.name).toList().join(',') ?? ''; + String get tagNames => + tagDetails?.map((e) => e.name).toList().join(',') ?? ''; - Color get updateDescColor => updateStatus == 1 ? AppColors.actionRed : const Color(0xff989898); + Color get updateDescColor => + updateStatus == 1 ? AppColors.actionRed : const Color(0xff989898); //集数状态描述 String get episodeNumberStatus { @@ -172,13 +176,14 @@ class DramaMediaInfo { countView = json['countView']; hasFollow = json['hasFollow']; final hot = json['hot']; - if(hot is int) { + if (hot is int) { this.hot = hot; } direction = json['direction']; freeTime = json['freeTime']; mediaStatus = VidStatus.fromMap(json['mediaStatus']); - tagDetails = (json['tagDetails'] as List?)?.map((e) => TagsBean.fromMap(e)).toList(); + tagDetails = + (json['tagDetails'] as List?)?.map((e) => TagsBean.fromMap(e)).toList(); } /// 落本地观看记录用(见 [DramaResume.drama])。只序列化后端字段, diff --git a/lib/hj_model/home/plate_model.dart b/lib/hj_model/home/plate_model.dart index 0c02c67..509d2b9 100644 --- a/lib/hj_model/home/plate_model.dart +++ b/lib/hj_model/home/plate_model.dart @@ -1,5 +1,5 @@ import 'package:collection/collection.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/const.dart'; //亚模块模型 class ModuleData { @@ -41,6 +41,7 @@ class ModuleData { bool get isACG => type == 4 || type == 5 || type == 6; //短剧 bool get isDrama => type == 12; + /// 展示用的排序项:top=true 的置顶,最多 4 个。 /// 标题、sort 值、随机刷新配置一律从这份派生——分头各排一次,遇到同名/同值 remove 会删错元素,两边就对不上了。 /// haiJiaoStyle 解析完就不再变,算一次存起来,别每个 getter 各构造一遍 @@ -53,10 +54,13 @@ class ModuleData { /// 排序 tab(标题 + sort 值),为空返回 null 让调用方退回默认值。 /// 标题和 sort 值必须一起产出:拆成两个并行数组时,后端只下发其中一个就会静默错位 - List>? get sortTabs => _sortedRules.isEmpty ? null : _sortedRules.map((e) => SortTab(e.name ?? '', e.val ?? -1)).toList(); + List>? get sortTabs => _sortedRules.isEmpty + ? null + : _sortedRules.map((e) => SortTab(e.name ?? '', e.val ?? -1)).toList(); /// 按 sort 值取对应的排序规则(用于判断该排序项是否走随机刷新接口) - SortRuleModel? sortRuleOf(int? val) => _sortedRules.firstWhereOrNull((e) => e.val == val); + SortRuleModel? sortRuleOf(int? val) => + _sortedRules.firstWhereOrNull((e) => e.val == val); } class HaiJiaoStyle { @@ -73,7 +77,8 @@ class HaiJiaoStyle { showChosenVideo = json['showChosenVideo']; sortShow = json['sortShow']; final rules = json['sortRules']; - if (rules is List) sortRules = rules.map((e) => SortRuleModel.fromJson(e)).toList(); + if (rules is List) + sortRules = rules.map((e) => SortRuleModel.fromJson(e)).toList(); } } @@ -129,5 +134,8 @@ class HomePlateModel { } //字段缺失或类型不对(后端偶发下发非数组)都退化成空列表,别让首页解析整个抛掉 - static List _modules(dynamic list) => (list is List ? list : const []).map((e) => ModuleData.fromJson(e)).toList(); + static List _modules(dynamic list) => + (list is List ? list : const []) + .map((e) => ModuleData.fromJson(e)) + .toList(); } diff --git a/lib/hj_model/home/video_list_model.dart b/lib/hj_model/home/video_list_model.dart index e49b7d9..f34faee 100644 --- a/lib/hj_model/home/video_list_model.dart +++ b/lib/hj_model/home/video_list_model.dart @@ -1,5 +1,5 @@ -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; //注意⚠️ VideoListResp 只用于兼容不同业务服务端返回的视频列表 key 不一致的情况 //注意⚠️ 请勿添加其他类型的数据list,如需添加请单独另外创建新的类 @@ -15,14 +15,24 @@ class VideoListResp { json ??= {}; hasNext = json['hasNext']; //各业务的视频列表 key 不一样,逐个匹配(后命中的覆盖先命中的) - for (final key in ['videos', 'vInfos', 'searchVideo', 'list', 'data', 'searchTag']) { + for (final key in [ + 'videos', + 'vInfos', + 'searchVideo', + 'list', + 'data', + 'searchTag' + ]) { if (json[key] is List) { - videos = (json[key] as List).map((e) => VideoModel.fromJson(e)).toList(); + videos = + (json[key] as List).map((e) => VideoModel.fromJson(e)).toList(); } } tagID = json['tagID'] ?? json['libraryTag']?['id']; if (json['tagVidList'] is List) { - tagVidList = (json['tagVidList'] as List).map((e) => VideoModel.fromJson(e)).toList(); + tagVidList = (json['tagVidList'] as List) + .map((e) => VideoModel.fromJson(e)) + .toList(); } } } @@ -41,4 +51,3 @@ class SectionListResp { } } } - diff --git a/lib/hj_model/list_base_model.dart b/lib/hj_model/list_base_model.dart index 4e81151..cc16fab 100644 --- a/lib/hj_model/list_base_model.dart +++ b/lib/hj_model/list_base_model.dart @@ -1,17 +1,17 @@ -import 'package:hgmj/hj_model/acg/comic_chapters_model.dart'; -import 'package:hgmj/hj_model/actress_model.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/comment/reply_model.dart'; -import 'package:hgmj/hj_model/comment/user_comment_res.dart'; -import 'package:hgmj/hj_model/home/collection_model.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_model/message/message_dynamic_list.dart'; -import 'package:hgmj/hj_model/mine/exchange/bill_item_model.dart'; -import 'package:hgmj/hj_model/mine/follow_user_list_model.dart'; -import 'package:hgmj/hj_model/mine/promotion_record.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/hj_model/acg/comic_chapters_model.dart'; +import 'package:wydj/hj_model/actress_model.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/comment/reply_model.dart'; +import 'package:wydj/hj_model/comment/user_comment_res.dart'; +import 'package:wydj/hj_model/home/collection_model.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_model/message/message_dynamic_list.dart'; +import 'package:wydj/hj_model/mine/exchange/bill_item_model.dart'; +import 'package:wydj/hj_model/mine/follow_user_list_model.dart'; +import 'package:wydj/hj_model/mine/promotion_record.dart'; +import 'package:wydj/hj_model/video_model.dart'; import '../hj_page/ai/models/ai_change_face_video_model.dart'; import '../hj_page/ai/models/ai_record_model.dart'; diff --git a/lib/hj_model/media_content.dart b/lib/hj_model/media_content.dart index 2e23221..610faa4 100644 --- a/lib/hj_model/media_content.dart +++ b/lib/hj_model/media_content.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/config/address.dart' as address; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/config/address.dart' as address; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/video_model.dart'; import 'package:path/path.dart' as path; /// 作品的「一集」:漫画一话 / 小说一章 / 有声一集 / 短剧一集 共用这一个模型, @@ -73,7 +73,8 @@ class MediaContent { audioUrl = json['audioUrl']; //用 is List 判而不是 as List:下发 null 或非数组时硬 cast 会抛,整条分集就解析不出来 final rawUrlSet = json['urlSet']; - urlSet = rawUrlSet is List ? rawUrlSet.map((e) => e.toString()).toList() : []; + urlSet = + rawUrlSet is List ? rawUrlSet.map((e) => e.toString()).toList() : []; text = json['text']; md5 = json['md5']; playTime = json['playTime']; @@ -82,7 +83,9 @@ class MediaContent { weight = json['weight']; //数字直接转;后端也可能下发字符串("1.5"),那时才走 parse,脏值落 null final rawRatio = json['ratio']; - ratio = rawRatio is num ? rawRatio.toDouble() : double.tryParse(rawRatio?.toString() ?? ''); + ratio = rawRatio is num + ? rawRatio.toDouble() + : double.tryParse(rawRatio?.toString() ?? ''); listenPermission = json['listenPermission']; price = json['price']; @@ -90,7 +93,8 @@ class MediaContent { isFree = json['isFree']; canPlay = json['canPlay']; accessType = json['accessType']; - paywall = json['paywall'] != null ? DramaPaywall.fromJson(json['paywall']) : null; + paywall = + json['paywall'] != null ? DramaPaywall.fromJson(json['paywall']) : null; isActive = json['isActive']; previewEnabled = json['previewEnabled']; @@ -105,7 +109,9 @@ class MediaContent { countDisLike = json['countDisLike']; countLike = json['countLike']; countPurchases = json['countPurchases']; - mediaStatus = json['mediaStatus'] != null ? VidStatus.fromMap(json['mediaStatus']) : null; + mediaStatus = json['mediaStatus'] != null + ? VidStatus.fromMap(json['mediaStatus']) + : null; createdAt = json['createdAt']; updateTime = json['updateTime']; diff --git a/lib/hj_model/mine/exchange/recharge_list_model.dart b/lib/hj_model/mine/exchange/recharge_list_model.dart index 574a638..b8ad1fd 100644 --- a/lib/hj_model/mine/exchange/recharge_list_model.dart +++ b/lib/hj_model/mine/exchange/recharge_list_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_model/mine/exchange/recharge_type_list_model.dart'; +import 'package:wydj/hj_model/mine/exchange/recharge_type_list_model.dart'; import 'dc_model.dart'; @@ -11,6 +11,8 @@ class RechargeListModel { json ??= {}; daichong = DCModel.fromJson(json['daichong']); //代充数据挂在上级,逐条塞给档位,档位内部才能拼出代充支付方式 - list = (json['list'] as List?)?.map((e) => RechargeTypeModel.fromJson(e)..daichong = daichong).toList(); + list = (json['list'] as List?) + ?.map((e) => RechargeTypeModel.fromJson(e)..daichong = daichong) + .toList(); } } diff --git a/lib/hj_model/mine/happy/happy_model.dart b/lib/hj_model/mine/happy/happy_model.dart index 0a52c1d..77330b0 100644 --- a/lib/hj_model/mine/happy/happy_model.dart +++ b/lib/hj_model/mine/happy/happy_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; class AdGroup { final List? items; diff --git a/lib/hj_model/splash/domain_source_model.dart b/lib/hj_model/splash/domain_source_model.dart index 4f49898..e726742 100644 --- a/lib/hj_model/splash/domain_source_model.dart +++ b/lib/hj_model/splash/domain_source_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; import '../../alert/vip_guide/guide_manager.dart'; import '../../config/config.dart'; @@ -20,7 +20,9 @@ class AdvanceStatus { balancePayment = json['balancePayment']; activityPopUp = json['activityPopUp']; oid = json['oid']; - privilegeLimit = json['privilegeLimit'] != null ? PrivilegeLimit.fromJson(json['privilegeLimit']) : null; + privilegeLimit = json['privilegeLimit'] != null + ? PrivilegeLimit.fromJson(json['privilegeLimit']) + : null; } } @@ -43,7 +45,10 @@ class Remain { int? todayCoinVideoCount; //今日剩余金币视频观看次数 int? todayDownloadCount; //今日剩余下载次数 - Remain({this.todayAiUndressCount, this.todayCoinVideoCount, this.todayDownloadCount}); + Remain( + {this.todayAiUndressCount, + this.todayCoinVideoCount, + this.todayDownloadCount}); Remain.fromJson(Map json) { todayAiUndressCount = json['todayAiUndressCount']; @@ -63,7 +68,8 @@ class BannerJump { BannerJump({this.additionalProp}); BannerJump.fromJson(Map json, {String key = '1'}) { - additionalProp = json[key] != null ? AdditionalProp.fromJson(json[key]) : null; + additionalProp = + json[key] != null ? AdditionalProp.fromJson(json[key]) : null; } } @@ -77,7 +83,15 @@ class AdditionalProp { String? endAt; //结束时间 int? countdownType; - AdditionalProp({this.id, this.banner, this.endAt, this.position, this.startAt, this.title, this.url, this.countdownType}); + AdditionalProp( + {this.id, + this.banner, + this.endAt, + this.position, + this.startAt, + this.title, + this.url, + this.countdownType}); AdditionalProp.fromJson(Map json) { id = json['id']; @@ -159,15 +173,23 @@ class DomainSourceModel { Config.darkWebIcon = map['darkWebIcon']; Config.darkWebIconName = map['darkWebIconName']; Config.mineBg = map['personalCenterBackground']; - Config.entryPopupEnabled = map['shortDramaEntryPopupEnabled'] ?? true; //短剧引导气泡,字段缺失当开启 - Config.isDramaEntry = map['defaultEntryPage'] == 'drama'; //默认进哪个 tab,缺字段/其它值都按主页 - MineMsgProvider().payTier = PayTierModel.fromJson(map); //支付状态分层(各展示位图片/卡ID/倒计时) + Config.entryPopupEnabled = + map['shortDramaEntryPopupEnabled'] ?? true; //短剧引导气泡,字段缺失当开启 + Config.isDramaEntry = + map['defaultEntryPage'] == 'drama'; //默认进哪个 tab,缺字段/其它值都按主页 + MineMsgProvider().payTier = + PayTierModel.fromJson(map); //支付状态分层(各展示位图片/卡ID/倒计时) GuideManager().update(map['paymentGuide']); //付费引导各场景开关(弹窗一律读缓存,不再临时查接口) if (map['aiSwitchConf'] is List) { - Config.aiTypes = (map['aiSwitchConf'] as List).map((e) => AISwitchConf.fromJson(e)).toList(); + Config.aiTypes = (map['aiSwitchConf'] as List) + .map((e) => AISwitchConf.fromJson(e)) + .toList(); } if (map.containsKey('bannerJumpList')) { - Config.bannerJumps = (map['bannerJumpList'] as List?)?.map((o) => BannerJumpEntity.fromJson(o)).toList() ?? []; + Config.bannerJumps = (map['bannerJumpList'] as List?) + ?.map((o) => BannerJumpEntity.fromJson(o)) + .toList() ?? + []; } // 域名 / 线路 / 版本 @@ -175,10 +197,14 @@ class DomainSourceModel { info.domain = (map['domain'] as List?)?.map((o) => o.toString()).toList(); } if (map.containsKey('sourceList')) { - info.sourceList = (map['sourceList'] as List?)?.map((o) => Sourcelist.fromJson(o)).toList(); + info.sourceList = (map['sourceList'] as List?) + ?.map((o) => Sourcelist.fromJson(o)) + .toList(); } if (map.containsKey('ver')) { - info.ver = (map['ver'] as List?)?.map((o) => CheckVersionInfo.fromMap(o)).toList(); + info.ver = (map['ver'] as List?) + ?.map((o) => CheckVersionInfo.fromMap(o)) + .toList(); } // 广告 @@ -199,8 +225,12 @@ class DomainSourceModel { if (map.containsKey('advanceStatus')) { info.advanceStatus = AdvanceStatus.fromJson(map['advanceStatus']); } - info.bannerJump = map['bannerJump'] != null ? BannerJump.fromJson(map['bannerJump']) : null; - info.proxyBannerJump = map['bannerJump'] != null ? BannerJump.fromJson(map['bannerJump'], key: '2') : null; + info.bannerJump = map['bannerJump'] != null + ? BannerJump.fromJson(map['bannerJump']) + : null; + info.proxyBannerJump = map['bannerJump'] != null + ? BannerJump.fromJson(map['bannerJump'], key: '2') + : null; info.festivalUi = map['festivalUi']; if (info.festivalUi?.isNotEmpty != true) info.festivalUi = '默认'; @@ -210,10 +240,12 @@ class DomainSourceModel { // 搜索 if (map['hotSearchTerms'] is List) { - info.hotSearchTerms = (map['hotSearchTerms'] as List).map((e) => e.toString()).toList(); + info.hotSearchTerms = + (map['hotSearchTerms'] as List).map((e) => e.toString()).toList(); } if (map['searchHintWord'] is List) { - info.searchHintWord = (map['searchHintWord'] as List).map((e) => e.toString()).toList(); + info.searchHintWord = + (map['searchHintWord'] as List).map((e) => e.toString()).toList(); } // 暗网 VIP @@ -221,7 +253,8 @@ class DomainSourceModel { info.darkWebVipName = map['darkWebVipName']; info.shortDramaCardId = map['shortDramaCardId']; if (map['recommendVipIds'] is List) { - info.recommendVipIds = (map['recommendVipIds'] as List).map((e) => e.toString()).toList(); + info.recommendVipIds = + (map['recommendVipIds'] as List).map((e) => e.toString()).toList(); } // 其他 @@ -229,7 +262,9 @@ class DomainSourceModel { info.broadcast = map['broadcast'] ?? false; info.storeIsOpen = map['storeIsOpen']; if (map['jgArea'] is List) { - info.jgArea = (map['jgArea'] as List?)?.map((e) => JGAreaModel.fromJson(e)).toList(); + info.jgArea = (map['jgArea'] as List?) + ?.map((e) => JGAreaModel.fromJson(e)) + .toList(); } return info; } @@ -292,9 +327,15 @@ class AdsBean { static AdsBean fromMap(Map? map) { map ??= {}; return AdsBean() - ..announInfo = (map['announInfo'] as List?)?.map((o) => AnnounceInfoBean.fromJson(o)).toList() - ..announList = (map['announList'] as List?)?.map((o) => AnnounceInfoBean.fromJson(o)).toList() - ..adsInfoList = (map['adsInfoList'] as List?)?.map((o) => AdsInfoModel.fromMap(o)).toList(); + ..announInfo = (map['announInfo'] as List?) + ?.map((o) => AnnounceInfoBean.fromJson(o)) + .toList() + ..announList = (map['announList'] as List?) + ?.map((o) => AnnounceInfoBean.fromJson(o)) + .toList() + ..adsInfoList = (map['adsInfoList'] as List?) + ?.map((o) => AdsInfoModel.fromMap(o)) + .toList(); } Map toJson() => { @@ -313,7 +354,15 @@ class JGAreaModel { String? linkUrl; String? mid; - JGAreaModel({this.id, this.name, this.img, this.desc, this.linkType, this.linkUrl, this.type, this.mid}); + JGAreaModel( + {this.id, + this.name, + this.img, + this.desc, + this.linkType, + this.linkUrl, + this.type, + this.mid}); factory JGAreaModel.fromJson(Map json) => JGAreaModel( id: json["id"], @@ -348,7 +397,8 @@ class Sourcelist { factory Sourcelist.fromJson(Map json) => Sourcelist( id: json["id"], - domain: List.from(json["domain"].map((x) => Domain.fromJson(x))), + domain: + List.from(json["domain"].map((x) => Domain.fromJson(x))), isActive: json["isActive"], type: json["type"], ); @@ -436,7 +486,15 @@ class BannerJumpEntity { String? endAt; int? countdownType; - BannerJumpEntity({this.title, this.id, this.position, this.url, this.startAt, this.banner, this.endAt, this.countdownType}); + BannerJumpEntity( + {this.title, + this.id, + this.position, + this.url, + this.startAt, + this.banner, + this.endAt, + this.countdownType}); BannerJumpEntity.fromJson(dynamic json) { id = json['id']; @@ -455,7 +513,8 @@ enum PayTier { newUnpay('new_unpay'), //新用户:注册≤1天且从未付费 → 推新人200卡(新人价+首购引导+紧迫感) under7DayUnpay('under_7_day_unpay'), //未付费·注册1~7天 → 推300卡(限时优惠+紧迫感) over7DayUnpay('over_7_day_unpay'), //未付费·注册>7天 → 推300卡(永久卡唤醒需求+信任背书) - over7DayNeedUpgrade('over_7_day_need_upgrade'), //低级会员需续费:注册>7天且已付费、未达最高等级(<5) → 推500至尊卡 + over7DayNeedUpgrade( + 'over_7_day_need_upgrade'), //低级会员需续费:注册>7天且已付费、未达最高等级(<5) → 推500至尊卡 normal('normal'), //正常用户:无特殊弹窗 unregistered('unregistered'); //未注册(未登录) @@ -496,7 +555,13 @@ class PayTierConfig { String? vipCard; //点击跳转的会员卡 ID int? lastDiscountTime; //优惠截止 Unix 时间戳(秒),早于当前则不展示倒计时 - PayTierConfig({this.homePage, this.homePageFlot, this.playPage, this.meTab, this.vipCard, this.lastDiscountTime}); + PayTierConfig( + {this.homePage, + this.homePageFlot, + this.playPage, + this.meTab, + this.vipCard, + this.lastDiscountTime}); PayTierConfig.fromJson(Map? json) { json ??= {}; @@ -508,7 +573,8 @@ class PayTierConfig { lastDiscountTime = _parseEpochSec(json['lastDiscountTime']); } - static const _minValidEpochSec = 946684800; //2000-01-01,用于挡掉后端零值时间 0001-01-01T00:00:00Z + static const _minValidEpochSec = + 946684800; //2000-01-01,用于挡掉后端零值时间 0001-01-01T00:00:00Z //兼容 Unix 秒(int) / 数字字符串 / ISO 字符串(带 Z 或 +08:00 时区);零值哨兵一律归 null,避免负 epoch 流入业务 static int? _parseEpochSec(dynamic v) { @@ -519,7 +585,8 @@ class PayTierConfig { } else if (v is String) { final s = v.trim(); if (s.isEmpty) return null; - sec = int.tryParse(s) ?? (DateTime.tryParse(s)?.millisecondsSinceEpoch ?? 0) ~/ 1000; + sec = int.tryParse(s) ?? + (DateTime.tryParse(s)?.millisecondsSinceEpoch ?? 0) ~/ 1000; } return (sec != null && sec >= _minValidEpochSec) ? sec : null; } @@ -535,9 +602,11 @@ class PayTierConfig { bool get hasDiscountCountdown => discountRemainSec > 0; - String get discountHour => (discountRemainSec ~/ 3600).toString().padLeft(2, '0'); + String get discountHour => + (discountRemainSec ~/ 3600).toString().padLeft(2, '0'); - String get discountMin => ((discountRemainSec ~/ 60) % 60).toString().padLeft(2, '0'); + String get discountMin => + ((discountRemainSec ~/ 60) % 60).toString().padLeft(2, '0'); String get discountSec => (discountRemainSec % 60).toString().padLeft(2, '0'); } diff --git a/lib/hj_model/user/user_info_model.dart b/lib/hj_model/user/user_info_model.dart index 9f6f8af..3f65271 100644 --- a/lib/hj_model/user/user_info_model.dart +++ b/lib/hj_model/user/user_info_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; /// 用户信息 class UserInfoModel { @@ -54,7 +54,8 @@ class UserInfoModel { // ============ 计算属性 ============ /// 观影券总数量 - int get couponCount => (goldVideoCoupon ?? []).fold(0, (sum, e) => sum + (e.count ?? 0)); + int get couponCount => + (goldVideoCoupon ?? []).fold(0, (sum, e) => sum + (e.count ?? 0)); /// 可解锁该金币视频的观影券面额:券面额需 >= 视频金币,都不够就退回第一张 int? couponGold(int? originCoins) { @@ -66,7 +67,8 @@ class UserInfoModel { } /// 作品总数(视频上传 + 封面上传) - int get totalWorkCount => totalWorks ?? 0 ; //(vidUploadCount ?? 0) + (coverUploadCount ?? 0); + int get totalWorkCount => + totalWorks ?? 0; //(vidUploadCount ?? 0) + (coverUploadCount ?? 0); /// 会员等级对应的角标图片;等级 1~4,0 级(含推广会员)无角标 String get vipImageName { @@ -111,7 +113,9 @@ class UserInfoModel { allGoldVideoFree = map['allGoldVideoFree'] ?? false; goldVideoFreeExpire = map['goldVideoFreeExpire']; - goldVideoCoupon = (map['goldVideoCoupon'] as List?)?.map((o) => MyCoupon.fromJson(o)).toList(); + goldVideoCoupon = (map['goldVideoCoupon'] as List?) + ?.map((o) => MyCoupon.fromJson(o)) + .toList(); broadcastExpire = map['broadcastExpire']; dramaExpire = map['dramaExpire']; payVidDiscount = map['payVidDiscount']; diff --git a/lib/hj_model/video_model.dart b/lib/hj_model/video_model.dart index 0661e71..91aa101 100644 --- a/lib/hj_model/video_model.dart +++ b/lib/hj_model/video_model.dart @@ -1,5 +1,5 @@ -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; import '../config/address.dart'; import '../tools_base/global_store/store.dart'; @@ -186,10 +186,12 @@ class VideoModel { .toList(); title = map['title']; via = map['via']; - comment = map.containsKey("comment") ? CommentBean.fromMap(map['comment']) : null; + comment = + map.containsKey("comment") ? CommentBean.fromMap(map['comment']) : null; vidStatus = VidStatus.fromMap(map['vidStatus']); if (map['seriesCover'] is List) { - seriesCover = (map['seriesCover'] as List).map((e) => e.toString()).toList(); + seriesCover = + (map['seriesCover'] as List).map((e) => e.toString()).toList(); } newsType = map['newsType']; reason = map['reason']; @@ -302,7 +304,9 @@ class VideoModel { /// 拼 m3u8 完整播放链接:各播放源共用同一套 host / token / cdn 参数。 /// 后端偶尔直接下发完整链接(265、短剧下载授权地址),那种别再往前面拼一遍 host String _m3u8(String? path) { - if (path != null && (path.startsWith('http://') || path.startsWith('https://'))) return path; + if (path != null && + (path.startsWith('http://') || path.startsWith('https://'))) + return path; return "${Address.baseApiPath}/vid/h5/m3u8/$path?token=${Address.token}&c=${Address.cdnAddress}"; } @@ -332,8 +336,10 @@ class VideoModel { /// - 普通源:[useH265] 且有 265 地址 → 265(省带宽),否则 264(兜底) /// [useH265] 由调用方算好传入(设备硬解能力 + 本条是否已运行时回退),model 不依赖 CodecSupport String realPlayUrl({required bool canPlayPreview, required bool useH265}) { - if (playContentStyle == 2 && chineseLink?.isNotEmpty == true) return realChineseUrl; - if (playContentStyle == 3 && codelessLink?.isNotEmpty == true) return realUncodeUrl; + if (playContentStyle == 2 && chineseLink?.isNotEmpty == true) + return realChineseUrl; + if (playContentStyle == 3 && codelessLink?.isNotEmpty == true) + return realUncodeUrl; if (canPlayPreview) return realPreviewUrl; if (useH265 && realH265Url.isNotEmpty) return realH265Url; return realVideoUrl; @@ -343,7 +349,8 @@ class VideoModel { /// 展示用创建时间:createdAt 为空或后端占位值时退回审核通过时间 String? get realCreateAt { - if (createdAt?.contains("0001-01-01") == true || createdAt?.isNotEmpty != true) { + if (createdAt?.contains("0001-01-01") == true || + createdAt?.isNotEmpty != true) { return reviewAt; } return createdAt; @@ -356,7 +363,8 @@ class VideoModel { return sec >= start && sec < end; } - bool get isDarkTag => tags?.any((e) => e.name?.contains("暗网") == true) ?? false; + bool get isDarkTag => + tags?.any((e) => e.name?.contains("暗网") == true) ?? false; String get allTags => tags?.map((e) => e.name).join(' ') ?? ''; @@ -448,14 +456,19 @@ extension LockType on VideoModel { /// 帖子流相关的判断与封面取值扩展(社区/个人主页等场景使用) extension Post on VideoModel { bool isVideo() { - return newsType == 'SP' || newsType == 'MOVIE' || newsType == 'SHORT' || newsType == 'COVER'; + return newsType == 'SP' || + newsType == 'MOVIE' || + newsType == 'SHORT' || + newsType == 'COVER'; } //埋点专用 String get contentType => newsType == 'SP' ? 'video' : 'short_video'; bool isSeedPost() { - return newsType == 'ADULT_GAME' || (seedLink?.isNotEmpty ?? false) || newsType == 'SEED_LINK'; + return newsType == 'ADULT_GAME' || + (seedLink?.isNotEmpty ?? false) || + newsType == 'SEED_LINK'; } } diff --git a/lib/hj_page/ai/ai_change_face_logic.dart b/lib/hj_page/ai/ai_change_face_logic.dart index 1608d05..680f2a4 100644 --- a/lib/hj_page/ai/ai_change_face_logic.dart +++ b/lib/hj_page/ai/ai_change_face_logic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import 'ai_sub_type/ai_function_logic.dart'; import 'models/ai_mod_list_model.dart'; diff --git a/lib/hj_page/ai/ai_change_face_page.dart b/lib/hj_page/ai/ai_change_face_page.dart index 30deadc..e980926 100644 --- a/lib/hj_page/ai/ai_change_face_page.dart +++ b/lib/hj_page/ai/ai_change_face_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../assets_tool/app_colors.dart'; import '../../tools_base/indicator/custom_tab_indicator.dart'; diff --git a/lib/hj_page/ai/ai_draw/ai_paint_logic.dart b/lib/hj_page/ai/ai_draw/ai_paint_logic.dart index 6569db7..6b9f61a 100644 --- a/lib/hj_page/ai/ai_draw/ai_paint_logic.dart +++ b/lib/hj_page/ai/ai_draw/ai_paint_logic.dart @@ -4,7 +4,7 @@ import 'package:get/get.dart'; import '../../../alert/mine/vip_level_dialog.dart'; import '../../../config/config.dart'; import '../../../hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../tools_base/global_store/store.dart'; import '../../../tools_base/loading/loading_helper.dart'; import '../ai_sub_type/ai_function_logic.dart'; @@ -37,7 +37,8 @@ class AiPaintLogic extends AiFunctionBaseLogic { @override Future submit() async { - if ((globalStore.wallet?.amount ?? 0) < (int.tryParse(Config.aiDrawPrice) ?? 0)) { + if ((globalStore.wallet?.amount ?? 0) < + (int.tryParse(Config.aiDrawPrice) ?? 0)) { showVipLevelDialog( "当前金币不足", buttonTitle: '我知道了', diff --git a/lib/hj_page/ai/ai_draw/ai_paint_page.dart b/lib/hj_page/ai/ai_draw/ai_paint_page.dart index 44a68f9..41de663 100644 --- a/lib/hj_page/ai/ai_draw/ai_paint_page.dart +++ b/lib/hj_page/ai/ai_draw/ai_paint_page.dart @@ -2,10 +2,10 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../tools_base/widget/net_image_widget.dart'; import '../models/ai_mod_list_model.dart'; @@ -30,7 +30,8 @@ class AiPaintPage extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -86,31 +87,45 @@ class AiPaintPage extends StatelessWidget { logic.aspectRatios.length, (index) => Padding( padding: EdgeInsets.only(right: 12), - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () { logic.selectIndex = index; logic.update(); }, child: Container( - padding: EdgeInsets.symmetric(horizontal: 8), + padding: + EdgeInsets.symmetric(horizontal: 8), alignment: Alignment.center, decoration: BoxDecoration( gradient: LinearGradient( colors: logic.selectIndex == index - ? [AppColors.actionRed, AppColors.actionRed] + ? [ + AppColors.actionRed, + AppColors.actionRed + ] : [ - Colors.white.withValues(alpha: .05), - Colors.white.withValues(alpha: .05), + Colors.white + .withValues(alpha: .05), + Colors.white + .withValues(alpha: .05), ]), borderRadius: BorderRadius.circular(4), - color: logic.selectIndex == index ? null : Color(0xFF7C7C7C), + color: logic.selectIndex == index + ? null + : Color(0xFF7C7C7C), ), height: 28, child: Text( logic.aspectRatios[index], style: TextStyle( - color: logic.selectIndex == index ? Colors.white : Colors.white.withValues(alpha: .5), - fontSize: logic.selectIndex == index ? 14 : 12, + color: logic.selectIndex == index + ? Colors.white + : Colors.white + .withValues(alpha: .5), + fontSize: logic.selectIndex == index + ? 14 + : 12, fontWeight: FontWeight.w400, ), ), @@ -160,7 +175,8 @@ class AiPaintPage extends StatelessWidget { ) ], ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.submit(), child: Container( height: 44, @@ -193,19 +209,23 @@ class AiPaintPage extends StatelessWidget { Widget _getStyleView(AiPaintLogic logic) { return logic.isFold - ? InkWell(enableFeedback: false, + ? InkWell( + enableFeedback: false, onTap: () { logic.isFold = !logic.isFold; logic.update(); }, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10), + padding: + const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10), child: Row( children: [ _buildStyleTitle(), Spacer(), NetworkImageLoader( - imageUrl: logic.models.length > 1 ? logic.models[logic.chooseItemIndex].cover ?? "" : '', + imageUrl: logic.models.length > 1 + ? logic.models[logic.chooseItemIndex].cover ?? "" + : '', width: 32, height: 32, ), @@ -220,13 +240,15 @@ class AiPaintPage extends StatelessWidget { ) : Column( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { logic.isFold = !logic.isFold; logic.update(); }, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10), + padding: const EdgeInsets.symmetric( + horizontal: 10.0, vertical: 10), child: Row( children: [ _buildStyleTitle(), diff --git a/lib/hj_page/ai/ai_face_sub_logic.dart b/lib/hj_page/ai/ai_face_sub_logic.dart index 4c94177..0feea27 100644 --- a/lib/hj_page/ai/ai_face_sub_logic.dart +++ b/lib/hj_page/ai/ai_face_sub_logic.dart @@ -1,5 +1,5 @@ -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import 'ai_sub_type/ai_function_logic.dart'; import 'models/ai_mod_list_model.dart'; @@ -28,7 +28,8 @@ class AIFaceTemplateLogic extends ListBaseLogic { void loadData() async { dataList ??= []; - final resp = await AIService.getModelListV2(type: type, categoryId: mod?.id ?? ''); + final resp = + await AIService.getModelListV2(type: type, categoryId: mod?.id ?? ''); if (resp != null) { dataList?.addAll(resp.templateList ?? []); //默认上架时间降序 @@ -49,18 +50,21 @@ class AIFaceTemplateLogic extends ListBaseLogic { switch (sortIndex) { case 0: dataList?.sort( - (obj1, obj2) => ascending ? obj2.timestamp.compareTo(obj1.timestamp) : obj1.timestamp.compareTo(obj2.timestamp), + (obj1, obj2) => ascending + ? obj2.timestamp.compareTo(obj1.timestamp) + : obj1.timestamp.compareTo(obj2.timestamp), ); case 1: dataList?.sort( (obj1, obj2) => ascending - ? (obj2.usedCount ?? 0).compareTo(obj1.usedCount ?? 0) : - (obj1.usedCount ?? 0).compareTo(obj2.usedCount ?? 0), + ? (obj2.usedCount ?? 0).compareTo(obj1.usedCount ?? 0) + : (obj1.usedCount ?? 0).compareTo(obj2.usedCount ?? 0), ); case 2: dataList?.sort( - (obj1, obj2) => - ascending ? (obj2.coin ?? 0).compareTo(obj1.coin ?? 0) : (obj1.coin ?? 0).compareTo(obj2.coin ?? 0), + (obj1, obj2) => ascending + ? (obj2.coin ?? 0).compareTo(obj1.coin ?? 0) + : (obj1.coin ?? 0).compareTo(obj2.coin ?? 0), ); default: } diff --git a/lib/hj_page/ai/ai_face_sub_page.dart b/lib/hj_page/ai/ai_face_sub_page.dart index ced0260..e14657e 100644 --- a/lib/hj_page/ai/ai_face_sub_page.dart +++ b/lib/hj_page/ai/ai_face_sub_page.dart @@ -2,10 +2,10 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../assets_tool/app_colors.dart'; import 'ai_face_sub_logic.dart'; @@ -17,7 +17,8 @@ import 'models/ai_mod_list_model.dart'; class AIFaceChangeSubPage extends StatelessWidget { final AICategoryMod? mod; final AiType type; //图片换脸 / 视频换脸 - const AIFaceChangeSubPage({super.key, this.mod, this.type = AiType.imageChangeFace}); + const AIFaceChangeSubPage( + {super.key, this.mod, this.type = AiType.imageChangeFace}); // 多分类子页作为 TabBarView 的 keepAlive children 并存,用 type+分类id 隔离各自 logic 实例 String get _tag => 'ai_face_sub_${type.name}_${mod?.id}'; @@ -51,7 +52,8 @@ class AIFaceChangeSubPage extends StatelessWidget { itemCount: logic.dataList?.length ?? 0, itemBuilder: (context, index) { TemplateModel? model = logic.dataList?[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => Get.to(AIModDetailPage(model!)), child: NetworkImageLoader(imageUrl: model?.cover ?? ''), ); @@ -78,9 +80,11 @@ class AIFaceChangeSubPage extends StatelessWidget { ); } - Widget _buildSortItem(String title, bool ascending, int sortIndex, AIFaceTemplateLogic logic) { + Widget _buildSortItem( + String title, bool ascending, int sortIndex, AIFaceTemplateLogic logic) { final bool sel = logic.sortIndex == sortIndex; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => logic.changeSortAction(sortIndex), child: Container( padding: EdgeInsets.symmetric(horizontal: 12, vertical: 3), @@ -92,7 +96,11 @@ class AIFaceChangeSubPage extends StatelessWidget { children: [ Text( title, - style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500, height: 1.5), + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w500, + height: 1.5), ), 5.sizeBoxW, Column( @@ -100,7 +108,8 @@ class AIFaceChangeSubPage extends StatelessWidget { children: [ _buildArrow(active: sel && ascending), 4.sizeBoxH, - Transform.rotate(angle: -pi, child: _buildArrow(active: sel && !ascending)), + Transform.rotate( + angle: -pi, child: _buildArrow(active: sel && !ascending)), ], ), ], diff --git a/lib/hj_page/ai/ai_girl/ai_girl_friend_logic.dart b/lib/hj_page/ai/ai_girl/ai_girl_friend_logic.dart index 32c28ae..ee51785 100644 --- a/lib/hj_page/ai/ai_girl/ai_girl_friend_logic.dart +++ b/lib/hj_page/ai/ai_girl/ai_girl_friend_logic.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../models/ai_girl_resp_model.dart'; import '../widgets/ai_girl_sheet.dart'; @@ -54,7 +54,8 @@ class AIGrilFriendLogic extends GetxController { //充值操作 onRechargeBottomSheet() async { if (currencys != null && currencys?.list?.isNotEmpty == true) { - Get.bottomSheet(AIGirlSheet(list: currencys?.list), isScrollControlled: true); + Get.bottomSheet(AIGirlSheet(list: currencys?.list), + isScrollControlled: true); } else { await onFetchChargeList(); if (currencys?.list?.isNotEmpty != true) { diff --git a/lib/hj_page/ai/ai_girl/ai_girl_friend_page.dart b/lib/hj_page/ai/ai_girl/ai_girl_friend_page.dart index 148b5b5..8af5476 100644 --- a/lib/hj_page/ai/ai_girl/ai_girl_friend_page.dart +++ b/lib/hj_page/ai/ai_girl/ai_girl_friend_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; import '../../../hj_utils/widget_util.dart'; import '../../../tools_base/unique_tag_mixin.dart'; @@ -15,7 +15,8 @@ class AIGrilFriendPage extends StatefulWidget { State createState() => _AIGrilFriendPageState(); } -class _AIGrilFriendPageState extends State with UniqueTagMixin { +class _AIGrilFriendPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -67,7 +68,8 @@ class _AIGrilFriendPageState extends State with UniqueTagMixin child: Obx( () => Text( logic.tips.value, - style: textStyle(17, Colors.white, FontWeight.w500), + style: + textStyle(17, Colors.white, FontWeight.w500), ), )), ), @@ -77,7 +79,8 @@ class _AIGrilFriendPageState extends State with UniqueTagMixin child: GestureDetector( child: GestureDetector( onTap: () => Get.back(), - child: const Icon(Icons.arrow_back_ios, size: 24, color: Colors.white), + child: const Icon(Icons.arrow_back_ios, + size: 24, color: Colors.white), ), ), ) @@ -101,7 +104,8 @@ class _AIGrilFriendPageState extends State with UniqueTagMixin GestureDetector( child: GestureDetector( onTap: () => Get.back(), - child: const Icon(Icons.arrow_back_ios, size: 24, color: Colors.white), + child: const Icon(Icons.arrow_back_ios, + size: 24, color: Colors.white), ), ), Container( diff --git a/lib/hj_page/ai/ai_girl/ai_h5_page.dart b/lib/hj_page/ai/ai_girl/ai_h5_page.dart index 96a62ee..599cbbb 100644 --- a/lib/hj_page/ai/ai_girl/ai_h5_page.dart +++ b/lib/hj_page/ai/ai_girl/ai_h5_page.dart @@ -3,7 +3,7 @@ import 'dart:collection'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; import '../../../hj_utils/widget_util.dart'; import '../../web_page/h5_webview_settings.dart'; @@ -27,7 +27,8 @@ class _YHYSH5ViewState extends State { fit: StackFit.expand, children: [ InAppWebView( - initialUrlRequest: URLRequest(url: WebUri(widget.webUrl ?? "")), //h5的url + initialUrlRequest: + URLRequest(url: WebUri(widget.webUrl ?? "")), //h5的url initialSettings: h5WebViewSettings, initialUserScripts: UnmodifiableListView([]), ), diff --git a/lib/hj_page/ai/ai_home_logic.dart b/lib/hj_page/ai/ai_home_logic.dart index 4d6e965..9c2436e 100644 --- a/lib/hj_page/ai/ai_home_logic.dart +++ b/lib/hj_page/ai/ai_home_logic.dart @@ -2,10 +2,10 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../config/config.dart'; import '../../hj_model/splash/domain_source_model.dart'; @@ -18,7 +18,8 @@ import './ai_sub_type/ai_strip_sub_page.dart'; import './models/ai_mod_list_model.dart'; import 'ai_square/ai_square_page.dart'; -class AiHomeLogic extends GetxController with GetSingleTickerProviderStateMixin { +class AiHomeLogic extends GetxController + with GetSingleTickerProviderStateMixin { bool isShowLoading = true; final AiType? aiType; // int tabIndex; @@ -50,7 +51,8 @@ class AiHomeLogic extends GetxController with GetSingleTickerProviderStateMixin //3.获取到默认进来的排序 int? initialIndex = aiTypes?.indexWhere((model) => model.aiType == aiType); initialIndex = max(0, initialIndex ?? 0); - tabCtr = TabController(initialIndex: initialIndex, length: menus.length, vsync: this) + tabCtr = TabController( + initialIndex: initialIndex, length: menus.length, vsync: this) ..addListener(() { if (!tabCtr.indexIsChanging) { update(['tab']); diff --git a/lib/hj_page/ai/ai_home_page.dart b/lib/hj_page/ai/ai_home_page.dart index 25447b7..99975ae 100644 --- a/lib/hj_page/ai/ai_home_page.dart +++ b/lib/hj_page/ai/ai_home_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../hj_utils/widget_util.dart'; import 'ai_home_logic.dart'; @@ -36,7 +36,10 @@ class AiHomePage extends StatelessWidget { ), child: Text( '记录', - style: textStyle(14, Colors.white.withValues(alpha: 0.55), FontWeight.w400), + style: textStyle( + 14, + Colors.white.withValues(alpha: 0.55), + FontWeight.w400), ), ), ), @@ -61,7 +64,9 @@ class AiHomePage extends StatelessWidget { Expanded( child: TabBarView( controller: logic.tabCtr, - children: logic.menus.map((e) => logic.subPage(e).keepAlive).toList(), + children: logic.menus + .map((e) => logic.subPage(e).keepAlive) + .toList(), ), ) ], @@ -100,8 +105,13 @@ class AiHomePage extends StatelessWidget { alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), - color: isSelected ? Color(0xffFFC000) : Colors.white.withValues(alpha: .1), - border: isSelected ? null : Border.all(width: 1, color: Colors.white.withValues(alpha: .35)), + color: isSelected + ? Color(0xffFFC000) + : Colors.white.withValues(alpha: .1), + border: isSelected + ? null + : Border.all( + width: 1, color: Colors.white.withValues(alpha: .35)), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -114,7 +124,10 @@ class AiHomePage extends StatelessWidget { 4.sizeBoxW, Text( menu.aiTypeName ?? '', - style: textStyle(12, isSelected ? Colors.black : Colors.white, FontWeight.w400), + style: textStyle( + 12, + isSelected ? Colors.black : Colors.white, + FontWeight.w400), ), ], ), diff --git a/lib/hj_page/ai/ai_image_to_video/ai_itv_logic.dart b/lib/hj_page/ai/ai_image_to_video/ai_itv_logic.dart index 14d226e..bf9a024 100644 --- a/lib/hj_page/ai/ai_image_to_video/ai_itv_logic.dart +++ b/lib/hj_page/ai/ai_image_to_video/ai_itv_logic.dart @@ -2,13 +2,13 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/file_upload/file_upload_tool.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/file_upload/file_upload_tool.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../../alert/mine/vip_level_dialog.dart'; import '../../../hj_model/splash/ads_model.dart'; @@ -26,7 +26,8 @@ class AiItvLogic extends GetxController { AiItvLogic({this.model}); Future submit() async { - if ((globalStore.wallet?.amount ?? 0) < (int.tryParse(Config.aiVideoPrice) ?? 0)) { + if ((globalStore.wallet?.amount ?? 0) < + (int.tryParse(Config.aiVideoPrice) ?? 0)) { showVipLevelDialog( "当前金币不足", buttonTitle: '我知道了', diff --git a/lib/hj_page/ai/ai_image_to_video/ai_itv_page.dart b/lib/hj_page/ai/ai_image_to_video/ai_itv_page.dart index 05148eb..78bd148 100644 --- a/lib/hj_page/ai/ai_image_to_video/ai_itv_page.dart +++ b/lib/hj_page/ai/ai_image_to_video/ai_itv_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; import '../../../hj_model/splash/ads_model.dart'; import '../widgets/pic_picker.dart'; @@ -20,7 +20,8 @@ class AiItvPage extends StatelessWidget { appBar: AppBar( title: Text( model?.title ?? '图生视频', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600), ), centerTitle: false, titleSpacing: -20, @@ -78,7 +79,10 @@ class AiItvPage extends StatelessWidget { 18.sizeBoxH, Text( "案列鉴赏", - style: TextStyle(fontSize: 18, color: Colors.white, fontWeight: FontWeight.w600), + style: TextStyle( + fontSize: 18, + color: Colors.white, + fontWeight: FontWeight.w600), ), 12.sizeBoxH, ClipRRect( @@ -100,7 +104,9 @@ class AiItvPage extends StatelessWidget { children: [ Text( "处理一张照片的费用是 ", - style: TextStyle(color: Colors.white.withValues(alpha: .6), fontSize: 14), + style: TextStyle( + color: Colors.white.withValues(alpha: .6), + fontSize: 14), ), Text( "${Config.aiVideoPrice}金币", @@ -112,7 +118,8 @@ class AiItvPage extends StatelessWidget { ], ), 18.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.submit(), child: Container( height: 44, diff --git a/lib/hj_page/ai/ai_mod_detail_page.dart b/lib/hj_page/ai/ai_mod_detail_page.dart index 31f8099..45366b1 100644 --- a/lib/hj_page/ai/ai_mod_detail_page.dart +++ b/lib/hj_page/ai/ai_mod_detail_page.dart @@ -1,12 +1,12 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../hj_model/video_model.dart'; @@ -45,7 +45,8 @@ class AIModDetailPage extends StatelessWidget { bottom: 0, left: 0, right: 0, - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () => logic.submit(), child: Container( height: 44, @@ -91,9 +92,11 @@ class AIModDetailPage extends StatelessWidget { ), //视频换脸 if (logic.isChangeVideo) - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { - VideoModel videoModel = VideoModel()..sourceURL = logic.mod.m3u8Url; + VideoModel videoModel = VideoModel() + ..sourceURL = logic.mod.m3u8Url; Get.to( SimpleVideoPlayerPage( videoUrl: videoModel.realVideoUrl, @@ -205,7 +208,10 @@ class AIModDetailPage extends StatelessWidget { 12.sizeBoxH, EasyRichText( '处理一张照片的费用是 ${logic.price}金币', - defaultStyle: TextStyle(color: Color(0xff989898), fontSize: 14, fontWeight: FontWeight.w400), + defaultStyle: TextStyle( + color: Color(0xff989898), + fontSize: 14, + fontWeight: FontWeight.w400), patternList: [ EasyRichTextPattern( targetString: '${logic.price}金币', @@ -218,7 +224,10 @@ class AIModDetailPage extends StatelessWidget { 12.sizeBoxH, EasyRichText( '已抵扣 ${logic.coupon?.goodsValue ?? 0}金币', - defaultStyle: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 14, fontWeight: FontWeight.w400), + defaultStyle: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 14, + fontWeight: FontWeight.w400), patternList: [ EasyRichTextPattern( targetString: '${logic.coupon?.goodsValue ?? 0}金币', @@ -230,7 +239,8 @@ class AIModDetailPage extends StatelessWidget { 12.sizeBoxH, Row( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.showCoupon(), child: GradientText( logic.coupon == null ? '使用抵扣券' : '更换抵扣券', @@ -245,7 +255,8 @@ class AIModDetailPage extends StatelessWidget { ), if (logic.coupon != null) ...[ 12.sizeBoxW, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { //取消优惠券 logic.coupon = null; @@ -253,7 +264,8 @@ class AIModDetailPage extends StatelessWidget { }, child: Text( '取消', - style: textStyle(14, Colors.white.withValues(alpha: .55), FontWeight.w400), + style: textStyle(14, Colors.white.withValues(alpha: .55), + FontWeight.w400), ), ) ] diff --git a/lib/hj_page/ai/ai_novel/ai_novel_logic.dart b/lib/hj_page/ai/ai_novel/ai_novel_logic.dart index 2d300ef..bedd4a6 100644 --- a/lib/hj_page/ai/ai_novel/ai_novel_logic.dart +++ b/lib/hj_page/ai/ai_novel/ai_novel_logic.dart @@ -1,9 +1,9 @@ //ai小说 import 'package:flutter/material.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; import '../../../../hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../ai_sub_type/ai_function_logic.dart'; class AINovelLogic extends AiFunctionBaseLogic { diff --git a/lib/hj_page/ai/ai_novel/ai_novel_page.dart b/lib/hj_page/ai/ai_novel/ai_novel_page.dart index 7014fd7..8323254 100644 --- a/lib/hj_page/ai/ai_novel/ai_novel_page.dart +++ b/lib/hj_page/ai/ai_novel/ai_novel_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../widgets/ai_draw_text_field.dart'; import 'ai_novel_logic.dart'; @@ -22,7 +22,8 @@ class AINovelSubPage extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, padding: EdgeInsets.symmetric(horizontal: 6).copyWith(top: 12), child: Column( children: [ @@ -70,7 +71,8 @@ class AINovelSubPage extends StatelessWidget { logic.mods.length, (index) => Padding( padding: EdgeInsets.only(right: 12), - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () { logic.selectIndex = index; logic.update(); @@ -81,19 +83,28 @@ class AINovelSubPage extends StatelessWidget { decoration: BoxDecoration( gradient: LinearGradient( colors: logic.selectIndex == index - ? [AppColors.actionRed, AppColors.actionRed] + ? [ + AppColors.actionRed, + AppColors.actionRed + ] : [ - Colors.white.withValues(alpha: .05), - Colors.white.withValues(alpha: .05), + Colors.white + .withValues(alpha: .05), + Colors.white + .withValues(alpha: .05), ]), borderRadius: BorderRadius.circular(4), - color: logic.selectIndex == index ? null : Color(0xFF7C7C7C), + color: logic.selectIndex == index + ? null + : Color(0xFF7C7C7C), ), height: 28, child: Text( logic.mods[index], style: TextStyle( - color: logic.selectIndex == index ? Colors.black : Colors.white.withValues(alpha: .5), + color: logic.selectIndex == index + ? Colors.black + : Colors.white.withValues(alpha: .5), fontSize: 14, fontWeight: FontWeight.w400, ), @@ -125,7 +136,8 @@ class AINovelSubPage extends StatelessWidget { ) ], ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.submit(), child: Container( height: 44, diff --git a/lib/hj_page/ai/ai_record/ai_main_record_page.dart b/lib/hj_page/ai/ai_record/ai_main_record_page.dart index 084cd9f..7fa05d9 100644 --- a/lib/hj_page/ai/ai_record/ai_main_record_page.dart +++ b/lib/hj_page/ai/ai_record/ai_main_record_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../hj_model/splash/domain_source_model.dart'; import '../ai_sub_type/ai_function_logic.dart'; @@ -65,7 +65,8 @@ class AIMainRecordPage extends StatelessWidget { fontWeight: FontWeight.w500, ), unselectedLabelColor: Colors.white.withValues(alpha: .35), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), indicator: CustomIndicator( isGradient: true, width: 13, diff --git a/lib/hj_page/ai/ai_record/ai_record_logic.dart b/lib/hj_page/ai/ai_record/ai_record_logic.dart index cdae3e5..a2bf579 100644 --- a/lib/hj_page/ai/ai_record/ai_record_logic.dart +++ b/lib/hj_page/ai/ai_record/ai_record_logic.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../ai_sub_type/ai_function_logic.dart'; import '../models/ai_record_model.dart'; @@ -41,7 +41,9 @@ class AIRecordLogic extends GetxController { refreshCtr?.refreshCompleted(); } dataSource.addAll(res?.list ?? []); - (res?.hasNext ?? false) ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); + (res?.hasNext ?? false) + ? refreshCtr?.loadComplete() + : refreshCtr?.loadNoData(); page += 1; } catch (e) { isLoading = false; @@ -73,13 +75,17 @@ class AIRecordLogic extends GetxController { final model = dataSource[index]; switch (aiType) { case AiType.aiNovel: - return AINovelRecord(model, onDeleteCallback: () => deleteRecord(index)); + return AINovelRecord(model, + onDeleteCallback: () => deleteRecord(index)); case AiType.imageToVideo: - return AIVideoRecord(model, status: sort, onDeleteCallback: () => deleteRecord(index)); + return AIVideoRecord(model, + status: sort, onDeleteCallback: () => deleteRecord(index)); case AiType.aiPaint: - return AIPaintRecord(model, status: sort, onDeleteCallback: () => deleteRecord(index)); + return AIPaintRecord(model, + status: sort, onDeleteCallback: () => deleteRecord(index)); default: //脱衣 / 视频换脸 / 图片换脸 - return AIImageRecord(model, aiType: aiType, onDeleteCallback: () => deleteRecord(index)); + return AIImageRecord(model, + aiType: aiType, onDeleteCallback: () => deleteRecord(index)); } } diff --git a/lib/hj_page/ai/ai_record/ai_record_page.dart b/lib/hj_page/ai/ai_record/ai_record_page.dart index b74ec04..866c92f 100644 --- a/lib/hj_page/ai/ai_record/ai_record_page.dart +++ b/lib/hj_page/ai/ai_record/ai_record_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../ai_sub_type/ai_function_logic.dart'; import 'ai_record_logic.dart'; @@ -20,8 +20,10 @@ class AiRecordPage extends StatefulWidget { State createState() => _AiRecordPageState(); } -class _AiRecordPageState extends State with SingleTickerProviderStateMixin { - late final TabController _tabCtr = TabController(length: _subTypes.length, vsync: this); +class _AiRecordPageState extends State + with SingleTickerProviderStateMixin { + late final TabController _tabCtr = + TabController(length: _subTypes.length, vsync: this); @override void dispose() { @@ -39,7 +41,9 @@ class _AiRecordPageState extends State with SingleTickerProviderSt controller: _tabCtr, children: List.generate( _subTypes.length, - (index) => _AiRecordStatusList(aiType: widget.aiType, status: index + 1).keepAlive, + (index) => + _AiRecordStatusList(aiType: widget.aiType, status: index + 1) + .keepAlive, ), ), ) @@ -58,7 +62,8 @@ class _AiRecordPageState extends State with SingleTickerProviderSt decoration: BoxDecoration( border: index != 2 ? Border( - right: BorderSide(width: .5, color: Colors.white.withValues(alpha: .1)), + right: BorderSide( + width: .5, color: Colors.white.withValues(alpha: .1)), ) : null, ), @@ -69,8 +74,10 @@ class _AiRecordPageState extends State with SingleTickerProviderSt padding: EdgeInsets.only(top: 10, left: 7), labelPadding: EdgeInsets.zero, tabAlignment: TabAlignment.start, - unselectedLabelStyle: TextStyle(color: Colors.white.withValues(alpha: .35), fontSize: 14), - labelStyle: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 14), + unselectedLabelStyle: + TextStyle(color: Colors.white.withValues(alpha: .35), fontSize: 14), + labelStyle: + TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 14), indicator: const BoxDecoration(), ); } @@ -108,7 +115,8 @@ class _AiRecordStatusList extends StatelessWidget { padding: EdgeInsets.only(left: 16, right: 16, top: 18), separatorBuilder: (_, index) => 12.sizeBoxH, itemCount: logic.dataSource.length, - itemBuilder: (BuildContext context, int index) => logic.instanceChild(index), + itemBuilder: (BuildContext context, int index) => + logic.instanceChild(index), ); } } diff --git a/lib/hj_page/ai/ai_square/ai_square_logic.dart b/lib/hj_page/ai/ai_square/ai_square_logic.dart index 2a6d4cd..27be92e 100644 --- a/lib/hj_page/ai/ai_square/ai_square_logic.dart +++ b/lib/hj_page/ai/ai_square/ai_square_logic.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../ai_mod_detail_page.dart'; import '../ai_home_logic.dart'; @@ -15,7 +15,8 @@ class AiSquareLogic extends ListBaseLogic { } //isRefresh=true 下拉刷新 / false 上拉加载更多 - void loadData({bool isRefresh = true}) => fetchData(isRefresh: isRefresh, fetch: _fetch); + void loadData({bool isRefresh = true}) => + fetchData(isRefresh: isRefresh, fetch: _fetch); Future<(List?, bool)> _fetch(int page) async { final resp = await AIService.getPlazaList(page); @@ -44,7 +45,8 @@ class AiSquareLogic extends ListBaseLogic { Get.to(() => AIModDetailPage(mod)); return; } - final isImageFace = AiTypeCode.fromServerCode(model.type) == AiType.imageChangeFace; + final isImageFace = + AiTypeCode.fromServerCode(model.type) == AiType.imageChangeFace; Get.find().jumpSubModule(isImageFace ? 5 : 4); } } diff --git a/lib/hj_page/ai/ai_square/ai_square_page.dart b/lib/hj_page/ai/ai_square/ai_square_page.dart index 77bb372..9f5567d 100644 --- a/lib/hj_page/ai/ai_square/ai_square_page.dart +++ b/lib/hj_page/ai/ai_square/ai_square_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../widgets/ai_square_cell.dart'; import 'ai_square_logic.dart'; diff --git a/lib/hj_page/ai/ai_sub_type/ai_function_logic.dart b/lib/hj_page/ai/ai_sub_type/ai_function_logic.dart index 518e5ed..fe51bea 100644 --- a/lib/hj_page/ai/ai_sub_type/ai_function_logic.dart +++ b/lib/hj_page/ai/ai_sub_type/ai_function_logic.dart @@ -1,14 +1,14 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/tools_base/file_upload/file_upload_tool.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/tools_base/file_upload/file_upload_tool.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../../alert/mine/vip_level_dialog.dart'; import '../../../routers/jump_router.dart'; @@ -68,7 +68,8 @@ abstract class AiFunctionBaseLogic extends GetxController { //免费次数或金币够不够本次消费 bool canPay(int price) { - final freeCount = (globalStore.wallet?.todayAiFreeTimes ?? 0) + (presaleProvider.remain?.todayAiUndressCount ?? 0); + final freeCount = (globalStore.wallet?.todayAiFreeTimes ?? 0) + + (presaleProvider.remain?.todayAiUndressCount ?? 0); if ((globalStore.wallet?.amount ?? 0) < price && freeCount <= 0) { showVipLevelDialog("当前免费次数不足或金币余额不足", buttonTitle: '去充值', vipEvent: () { Get.back(); @@ -142,13 +143,19 @@ class AiStripLogic extends AiFunctionBaseLogic { Future submit() async { if (!checkPic()) return; //预售期有免费次数先走免费,否则查金币 - if (presaleProvider.isOpen && presaleProvider.hasLimit && (presaleProvider.remain?.todayAiUndressCount ?? 0) > 0) { - presaleProvider.remain?.todayAiUndressCount = (presaleProvider.remain?.todayAiUndressCount ?? 0) - 1; + if (presaleProvider.isOpen && + presaleProvider.hasLimit && + (presaleProvider.remain?.todayAiUndressCount ?? 0) > 0) { + presaleProvider.remain?.todayAiUndressCount = + (presaleProvider.remain?.todayAiUndressCount ?? 0) - 1; } else { if (!canPay(int.tryParse(Config.aiUndressPrice) ?? 0)) return; } //传副本:提交成功回调里会清空 localPicList - await upload([...localPicList], (urls) => AIService.generateUndress(urls, shareToAiSquare, editingCtr.text)); + await upload( + [...localPicList], + (urls) => + AIService.generateUndress(urls, shareToAiSquare, editingCtr.text)); } } @@ -171,16 +178,22 @@ class AiFaceDetailLogic extends AiFunctionBaseLogic { Future submit() async { if (!checkPic()) return; //预售期图片换脸有免费次数先走免费,否则查金币 - if (presaleProvider.isOpen && presaleProvider.hasLimit && (presaleProvider.remain?.todayAiUndressCount ?? 0) > 0 && !isChangeVideo) { - presaleProvider.remain?.todayAiUndressCount = (presaleProvider.remain?.todayAiUndressCount ?? 0) - 1; + if (presaleProvider.isOpen && + presaleProvider.hasLimit && + (presaleProvider.remain?.todayAiUndressCount ?? 0) > 0 && + !isChangeVideo) { + presaleProvider.remain?.todayAiUndressCount = + (presaleProvider.remain?.todayAiUndressCount ?? 0) - 1; } else { if (!canPay(price)) return; } await upload( localPicList, (urls) => isChangeVideo - ? AIService.generateChangeFace(urls, mod.id, coupon?.id, shareToAiSquare, editingCtr.text) //视频换脸 - : AIService.generateImg(urls.firstOrNull ?? '', mod.id ?? '', shareToAiSquare, editingCtr.text), //图片换脸 + ? AIService.generateChangeFace( + urls, mod.id, coupon?.id, shareToAiSquare, editingCtr.text) //视频换脸 + : AIService.generateImg(urls.firstOrNull ?? '', mod.id ?? '', + shareToAiSquare, editingCtr.text), //图片换脸 onDone: () => coupon = null, ); } diff --git a/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart b/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart index 256cde0..b7dd01c 100644 --- a/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart +++ b/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; import '../widgets/pic_picker.dart'; diff --git a/lib/hj_page/ai/models/ai_mod_list_model.dart b/lib/hj_page/ai/models/ai_mod_list_model.dart index 2540c9b..b55b982 100644 --- a/lib/hj_page/ai/models/ai_mod_list_model.dart +++ b/lib/hj_page/ai/models/ai_mod_list_model.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/text_util.dart'; import '../../../hj_model/splash/ads_model.dart'; import 'ai_change_face_video_model.dart'; @@ -18,9 +18,15 @@ class AiModList { AiModList.fromJson(dynamic json) { json ??= {}; - aiUndressMod = (json['aiUndressMod'] as List?)?.map((e) => AdsInfoModel.fromJson(e)).toList(); - aiImgToVideoMod = (json['aiImgToVideoMod'] as List?)?.map((e) => AdsInfoModel.fromJson(e)).toList(); - aiTextToImgMod = (json['aiTextToImgMod'] as List?)?.map((e) => AiChangeFaceVideoMod.fromJson(e)).toList(); + aiUndressMod = (json['aiUndressMod'] as List?) + ?.map((e) => AdsInfoModel.fromJson(e)) + .toList(); + aiImgToVideoMod = (json['aiImgToVideoMod'] as List?) + ?.map((e) => AdsInfoModel.fromJson(e)) + .toList(); + aiTextToImgMod = (json['aiTextToImgMod'] as List?) + ?.map((e) => AiChangeFaceVideoMod.fromJson(e)) + .toList(); } } @@ -33,8 +39,12 @@ class AiChangeModList { AiChangeModList.fromJson(dynamic json) { json ??= {}; categoryId = json['categoryId']; - categoryList = (json['categoryList'] as List?)?.map((e) => AICategoryMod.fromJson(e)).toList(); - templateList = (json['templateList'] as List?)?.map((e) => TemplateModel.fromJson(e)).toList(); + categoryList = (json['categoryList'] as List?) + ?.map((e) => AICategoryMod.fromJson(e)) + .toList(); + templateList = (json['templateList'] as List?) + ?.map((e) => TemplateModel.fromJson(e)) + .toList(); } } @@ -77,7 +87,8 @@ class TemplateModel { int? vipCoin; /// 上架时间戳,模版列表按它排序;时间解析不了按 0 排最前 - int get timestamp => DateTime.tryParse(createdAt ?? '')?.millisecondsSinceEpoch ?? 0; + int get timestamp => + DateTime.tryParse(createdAt ?? '')?.millisecondsSinceEpoch ?? 0; TemplateModel.fromJson(dynamic json) { json ??= {}; diff --git a/lib/hj_page/ai/models/ai_record_model.dart b/lib/hj_page/ai/models/ai_record_model.dart index f09321c..5c24880 100644 --- a/lib/hj_page/ai/models/ai_record_model.dart +++ b/lib/hj_page/ai/models/ai_record_model.dart @@ -7,7 +7,7 @@ cover换脸后封面大图 url换脸后视频地址 */ -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/text_util.dart'; import '../../../config/address.dart'; @@ -41,7 +41,8 @@ class AiRecordModel { String? locationScene; //地点场景 /// 换脸结果视频地址。query 用 cdn= 而不是 VideoModel 的 c=,两边接口不同,别顺手统一 - String get realVideoUrl => "${Address.baseApiPath}/vid/h5/m3u8/$url?token=${Address.token}&cdn=${Address.cdnAddress}"; + String get realVideoUrl => + "${Address.baseApiPath}/vid/h5/m3u8/$url?token=${Address.token}&cdn=${Address.cdnAddress}"; AiRecordModel.fromJson(dynamic json) { json ??= {}; diff --git a/lib/hj_page/ai/widgets/ai_coupon_sheet.dart b/lib/hj_page/ai/widgets/ai_coupon_sheet.dart index d696dc7..fe98d77 100644 --- a/lib/hj_page/ai/widgets/ai_coupon_sheet.dart +++ b/lib/hj_page/ai/widgets/ai_coupon_sheet.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../../hj_utils/widget_util.dart'; import '../../mine/mine_vip/coupon_model.dart'; @@ -42,7 +42,9 @@ class _AICouponSheetState extends State { dataList ??= []; //首屏失败也要退出 loading,否则永远转圈 setState(() {}); if (page == 1) refreshCtr?.refreshCompleted(); - (res?.length ?? 0) < size ? refreshCtr?.loadNoData() : refreshCtr?.loadComplete(); + (res?.length ?? 0) < size + ? refreshCtr?.loadNoData() + : refreshCtr?.loadComplete(); } Future loadMore() => loadData(page: curPage + 1); @@ -59,7 +61,9 @@ class _AICouponSheetState extends State { children: [ const SheetHandleBar(), 18.sizeBoxH, - Text('使用抵扣券', style: textStyle(18, Colors.white.withValues(alpha: .9), FontWeight.w600)), + Text('使用抵扣券', + style: textStyle( + 18, Colors.white.withValues(alpha: .9), FontWeight.w600)), 18.sizeBoxH, Expanded(child: _list()), ], @@ -92,12 +96,14 @@ class _AICouponSheetState extends State { alignment: Alignment.center, height: 68, decoration: BoxDecoration( - image: DecorationImage(image: AssetImage('ai_coupon_bg.webp'.aiPath), fit: BoxFit.fill), + image: DecorationImage( + image: AssetImage('ai_coupon_bg.webp'.aiPath), fit: BoxFit.fill), ), child: Row( children: [ 18.sizeBoxW, - Text('${model.goodsName}', style: textStyle(18, couponText, FontWeight.w600)), + Text('${model.goodsName}', + style: textStyle(18, couponText, FontWeight.w600)), 12.sizeBoxW, Expanded( child: Text( @@ -116,7 +122,8 @@ class _AICouponSheetState extends State { color: const Color(0xffFFDCB3), borderRadius: BorderRadius.circular(22), ), - child: Text('立即使用', style: textStyle(12, Color(0xFF7F0000), FontWeight.w400)), + child: Text('立即使用', + style: textStyle(12, Color(0xFF7F0000), FontWeight.w400)), ), 18.sizeBoxW, ], diff --git a/lib/hj_page/ai/widgets/ai_girl_sheet.dart b/lib/hj_page/ai/widgets/ai_girl_sheet.dart index 4e6e9e3..7e4ab46 100644 --- a/lib/hj_page/ai/widgets/ai_girl_sheet.dart +++ b/lib/hj_page/ai/widgets/ai_girl_sheet.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/ai_service.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/hj_utils/api_service/ai_service.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../../hj_utils/widget_util.dart'; import '../models/ai_girl_resp_model.dart'; @@ -26,7 +26,8 @@ class _AIGirlSheetState extends State { List get _items => widget.list ?? []; //列表可能为空,取不到就没得选 - AIGirlFriendCurrency? get _selected => selectIndex < _items.length ? _items[selectIndex] : null; + AIGirlFriendCurrency? get _selected => + selectIndex < _items.length ? _items[selectIndex] : null; @override Widget build(BuildContext context) { @@ -44,9 +45,12 @@ class _AIGirlSheetState extends State { const SheetHandleBar(color: Color(0x1AFFFFFF)), Padding( padding: const EdgeInsets.only(top: 18, bottom: 12), - child: Text('AI女友', style: textStyle(20, Colors.white, FontWeight.w600)), + child: Text('AI女友', + style: textStyle(20, Colors.white, FontWeight.w600)), ), - Text('充值积分', style: textStyle(14, Colors.white.withValues(alpha: .8), FontWeight.w400)), + Text('充值积分', + style: textStyle( + 14, Colors.white.withValues(alpha: .8), FontWeight.w400)), GridView.builder( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18), shrinkWrap: true, @@ -65,11 +69,13 @@ class _AIGirlSheetState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('支付小贴士:', style: textStyle(14, Colors.white, FontWeight.w500)), + Text('支付小贴士:', + style: textStyle(14, Colors.white, FontWeight.w500)), const SizedBox(height: 6), Text( '1.因超时支付无法到账,请重新发起。\n2.连续发起且未支付,账号可能被加入黑名单\n3.充值成功后会在1~5分钟内到账,可重新刷新进入当前页面', - style: textStyle(12, Colors.white.withValues(alpha: .6), FontWeight.w400), + style: textStyle(12, Colors.white.withValues(alpha: .6), + FontWeight.w400), ), ], ), @@ -83,7 +89,12 @@ class _AIGirlSheetState extends State { alignment: Alignment.center, decoration: BoxDecoration( gradient: const LinearGradient( - colors: [Color(0xff1E3C72), Color(0xff5F40B6), Color(0xff1E3C72), Color(0xff2A5298)], + colors: [ + Color(0xff1E3C72), + Color(0xff5F40B6), + Color(0xff1E3C72), + Color(0xff2A5298) + ], begin: Alignment.centerLeft, end: Alignment.centerRight, ), @@ -109,10 +120,14 @@ class _AIGirlSheetState extends State { onTap: () => setState(() => selectIndex = index), child: Container( decoration: BoxDecoration( - color: isSelected ? const Color(0xff4039A1) : Colors.white.withValues(alpha: .05), + color: isSelected + ? const Color(0xff4039A1) + : Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(6), border: Border.all( - color: isSelected ? const Color(0xff30509C) : Colors.white.withValues(alpha: .1), + color: isSelected + ? const Color(0xff30509C) + : Colors.white.withValues(alpha: .1), ), ), child: Column( @@ -120,14 +135,21 @@ class _AIGirlSheetState extends State { children: [ Text( '${item.coins ?? 0}积分', - style: textStyle(16, isSelected ? const Color(0xffAFABFF) : const Color(0xff7D95D5), FontWeight.w400), + style: textStyle( + 16, + isSelected + ? const Color(0xffAFABFF) + : const Color(0xff7D95D5), + FontWeight.w400), ), const SizedBox(height: 4), Text( '${(item.price ?? 0).truncate()}金币', style: textStyle( 12, - isSelected ? const Color(0x4DF3F5FF) : Colors.white.withValues(alpha: .3), + isSelected + ? const Color(0x4DF3F5FF) + : Colors.white.withValues(alpha: .3), FontWeight.w400, ), ), diff --git a/lib/hj_page/ai/widgets/ai_image_record.dart b/lib/hj_page/ai/widgets/ai_image_record.dart index 8820b96..d359f1e 100644 --- a/lib/hj_page/ai/widgets/ai_image_record.dart +++ b/lib/hj_page/ai/widgets/ai_image_record.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/video_download/video_cache_store.dart'; -import 'package:hgmj/tools_base/video_download/video_download_manager.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/video_download/video_cache_store.dart'; +import 'package:wydj/tools_base/video_download/video_download_manager.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../video/simple_video_player_page.dart'; import '../ai_sub_type/ai_function_logic.dart'; @@ -39,7 +39,8 @@ class AIImageRecord extends StatelessWidget { final AiType aiType; final VoidCallback? onDeleteCallback; - const AIImageRecord(this.model, {super.key, this.aiType = AiType.autoStrip, this.onDeleteCallback}); + const AIImageRecord(this.model, + {super.key, this.aiType = AiType.autoStrip, this.onDeleteCallback}); bool get isVideoFace => aiType.isVideoFace; @@ -110,7 +111,8 @@ class AIImageRecord extends StatelessWidget { String get _resultCover { if (_state == AIRecordState.success) { //视频换脸有的成功订单后端不回 cover,退回素材封面,别让结果位空着露占位图 - if (isVideoFace) return model.cover?.isNotEmpty == true ? model.cover! : _sourceCover; + if (isVideoFace) + return model.cover?.isNotEmpty == true ? model.cover! : _sourceCover; return model.newPic?.firstOrNull ?? ''; } if (isVideoFace) return model.picture?.firstOrNull ?? ''; @@ -124,14 +126,17 @@ class AIImageRecord extends StatelessWidget { ImageBrowserPage.open([images.first], showSaveButton: true); return; } - final isCached = await VideoCacheStore.instance.isExistLoadVideoByUrl(MediaStyle.Video, model.url ?? ''); + final isCached = await VideoCacheStore.instance + .isExistLoadVideoByUrl(MediaStyle.Video, model.url ?? ''); if (isCached) { showToast('你已经添加过缓存了'); return; } + /// VideoDownloadManager下载到了 应用的外部私有目录中,无需动态权限 /// if (!await _checkPermission()) return; - final result = await VideoDownloadManager.instance.download(url: model.url ?? ''); + final result = + await VideoDownloadManager.instance.download(url: model.url ?? ''); if (result != null) return; final viewModel = VideoModel() ..sourceURL = model.url @@ -147,7 +152,8 @@ class AIImageRecord extends StatelessWidget { //视频换脸的结果位单独接播放器,链接由 VideoModel 拼(和 AiRecordModel.realVideoUrl 的 query 不一样) void _playResultVideo() { final videoModel = VideoModel()..sourceURL = model.url; - Get.to(SimpleVideoPlayerPage(videoUrl: videoModel.realVideoUrl, title: 'AI生成视频')); + Get.to(SimpleVideoPlayerPage( + videoUrl: videoModel.realVideoUrl, title: 'AI生成视频')); } //三张图:模版 + 素材 = 结果 @@ -164,7 +170,10 @@ class AIImageRecord extends StatelessWidget { ), const AIRecordJoin(gap: 3.5), ], - AIRecordThumb(imageUrl: _sourceCover, badge: const AISourceBadge(isTemplate: false), width: 90.w), + AIRecordThumb( + imageUrl: _sourceCover, + badge: const AISourceBadge(isTemplate: false), + width: 90.w), const AIRecordJoin(isEquals: true, gap: 3.5), AIResultThumb( imageUrl: _resultCover, diff --git a/lib/hj_page/ai/widgets/ai_mod_cell.dart b/lib/hj_page/ai/widgets/ai_mod_cell.dart index 7622fe4..d3f6dea 100644 --- a/lib/hj_page/ai/widgets/ai_mod_cell.dart +++ b/lib/hj_page/ai/widgets/ai_mod_cell.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../models/ai_change_face_video_model.dart'; @@ -10,7 +10,8 @@ class AIModCell extends StatelessWidget { final bool isSelected; final VoidCallback? onTap; - const AIModCell({super.key, required this.mod, this.isSelected = false, this.onTap}); + const AIModCell( + {super.key, required this.mod, this.isSelected = false, this.onTap}); @override Widget build(BuildContext context) { @@ -28,7 +29,9 @@ class AIModCell extends StatelessWidget { right: 8, top: 8, child: Image.asset( - isSelected ? 'radio_select.png'.commonImgPath : 'ai_draw_unselected.png'.aiPath, + isSelected + ? 'radio_select.png'.commonImgPath + : 'ai_draw_unselected.png'.aiPath, width: 20, ), ), @@ -38,7 +41,10 @@ class AIModCell extends StatelessWidget { const Spacer(), Text( mod.title ?? '', - style: TextStyle(color: Colors.white.withValues(alpha: .8), fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: .8), + fontSize: 14, + fontWeight: FontWeight.w500), ), ], ), diff --git a/lib/hj_page/ai/widgets/ai_paint_record.dart b/lib/hj_page/ai/widgets/ai_paint_record.dart index 6207973..a75345e 100644 --- a/lib/hj_page/ai/widgets/ai_paint_record.dart +++ b/lib/hj_page/ai/widgets/ai_paint_record.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../models/ai_record_model.dart'; import 'ai_record_parts.dart'; @@ -11,7 +11,8 @@ class AIPaintRecord extends StatelessWidget { final int status; // 1 排队 2 成功 3 失败 final VoidCallback? onDeleteCallback; - const AIPaintRecord(this.model, {super.key, required this.status, this.onDeleteCallback}); + const AIPaintRecord(this.model, + {super.key, required this.status, this.onDeleteCallback}); AIRecordState get _state => switch (status) { 2 => AIRecordState.success, @@ -22,10 +23,13 @@ class AIPaintRecord extends StatelessWidget { /// 排队/失败没有结果图,退回模版封面占位。 /// 后端在这个接口里放模版封面的字段不固定(styleUrl 常为空),挨个兜一遍,别露占位图 String get _templateCover => - [model.styleUrl, model.cover, model.modCover, model.modPic].firstWhere((e) => e?.isNotEmpty == true, orElse: () => '') ?? ''; + [model.styleUrl, model.cover, model.modCover, model.modPic] + .firstWhere((e) => e?.isNotEmpty == true, orElse: () => '') ?? + ''; //只有成功才是真结果图;未知 status 按排队处理,与 _state 的口径保持一致 - String get _resultCover => status == 2 ? (model.newImgUrl ?? '') : _templateCover; + String get _resultCover => + status == 2 ? (model.newImgUrl ?? '') : _templateCover; @override Widget build(BuildContext context) { @@ -71,7 +75,10 @@ class AIPaintRecord extends StatelessWidget { AIResultThumb( imageUrl: _resultCover, state: _state, - onTap: _resultCover.isEmpty ? null : () => ImageBrowserPage.open([_resultCover], showSaveButton: true), + onTap: _resultCover.isEmpty + ? null + : () => + ImageBrowserPage.open([_resultCover], showSaveButton: true), ), ], ), diff --git a/lib/hj_page/ai/widgets/ai_record_parts.dart b/lib/hj_page/ai/widgets/ai_record_parts.dart index 1d82289..d2990b2 100644 --- a/lib/hj_page/ai/widgets/ai_record_parts.dart +++ b/lib/hj_page/ai/widgets/ai_record_parts.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_utils/widget_util.dart'; @@ -13,7 +13,8 @@ import '../../../hj_utils/widget_util.dart'; enum AIRecordState { queuing, success, failed } /// 失败原因:接口没给就退回通用文案。底部文案和失败弹窗共用,改一处即可 -String _failedText(String? remark) => remark?.isNotEmpty == true ? remark! : '生成失败'; +String _failedText(String? remark) => + remark?.isNotEmpty == true ? remark! : '生成失败'; /// 记录卡:白 5% 底 + 12 圆角,版式固定为 /// 创建时间/删除 → 内容 → 细线 → 状态胶囊/下载或失败原因。 @@ -60,7 +61,11 @@ class AIRecordCard extends StatelessWidget { 12.sizeBoxH, 0.5.line, 12.sizeBoxH, - AIRecordFooter(state: state, remark: remark, onDownload: onDownload, onStatusTap: onStatusTap), + AIRecordFooter( + state: state, + remark: remark, + onDownload: onDownload, + onStatusTap: onStatusTap), ], ), ); @@ -68,7 +73,8 @@ class AIRecordCard extends StatelessWidget { //失败原因底部只放得下两行,点卡片看全文。四类记录都走这里,别再各自实现 return GestureDetector( behavior: HitTestBehavior.opaque, //卡片内的空白也要能点 - onTap: () => CommonAlert.show(title: '失败原因', content: _failedText(remark), showCancel: false), + onTap: () => CommonAlert.show( + title: '失败原因', content: _failedText(remark), showCancel: false), child: card, ); } @@ -108,7 +114,12 @@ class AIRecordFooter extends StatelessWidget { final VoidCallback? onDownload; final VoidCallback? onStatusTap; - const AIRecordFooter({super.key, required this.state, this.remark, this.onDownload, this.onStatusTap}); + const AIRecordFooter( + {super.key, + required this.state, + this.remark, + this.onDownload, + this.onStatusTap}); @override Widget build(BuildContext context) { @@ -117,7 +128,8 @@ class AIRecordFooter extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AIStatusPill(state, onTap: state == AIRecordState.success ? onStatusTap : null), + AIStatusPill(state, + onTap: state == AIRecordState.success ? onStatusTap : null), if (state == AIRecordState.success && onDownload != null) AIDownloadBtn(onTap: onDownload) else if (state == AIRecordState.failed) @@ -154,13 +166,18 @@ class AIStatusPill extends StatelessWidget { onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), - decoration: - isFailed ? null : BoxDecoration(color: const Color(0x1AFFDB9E), borderRadius: BorderRadius.circular(3)), + decoration: isFailed + ? null + : BoxDecoration( + color: const Color(0x1AFFDB9E), + borderRadius: BorderRadius.circular(3)), child: Text( text, style: textStyle( 13, - isFailed ? Colors.white.withValues(alpha: .55) : const Color(0xffFFDB9E), + isFailed + ? Colors.white.withValues(alpha: .55) + : const Color(0xffFFDB9E), FontWeight.w400, ), ), @@ -183,14 +200,16 @@ class AIDownloadBtn extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4), decoration: BoxDecoration( - border: Border.all(width: 0.5, color: Colors.white.withValues(alpha: .15)), + border: Border.all( + width: 0.5, color: Colors.white.withValues(alpha: .15)), borderRadius: BorderRadius.circular(6), ), child: Row( children: [ Image.asset('icon_ai_download.png'.aiPath, width: 18), 2.5.sizeBoxW, - const Text('一键下载', style: TextStyle(color: Colors.white, fontSize: 12)), + const Text('一键下载', + style: TextStyle(color: Colors.white, fontSize: 12)), ], ), ), @@ -206,7 +225,8 @@ class AIRecordThumb extends StatelessWidget { final VoidCallback? onTap; final double width; - const AIRecordThumb({super.key, this.imageUrl, this.badge, this.onTap, this.width = 90}); + const AIRecordThumb( + {super.key, this.imageUrl, this.badge, this.onTap, this.width = 90}); @override Widget build(BuildContext context) { @@ -222,7 +242,11 @@ class AIRecordThumb extends StatelessWidget { color: Color(0xff262626), borderRadius: BorderRadius.all(Radius.circular(8)), ), - child: NetworkImageLoader(imageUrl: imageUrl, width: width, height: 90, borderRadius: 8), + child: NetworkImageLoader( + imageUrl: imageUrl, + width: width, + height: 90, + borderRadius: 8), ), if (badge != null) badge!, ], @@ -239,7 +263,12 @@ class AIResultThumb extends StatelessWidget { final VoidCallback? onTap; final double width; - const AIResultThumb({super.key, this.imageUrl, required this.state, this.onTap, this.width = 90}); + const AIResultThumb( + {super.key, + this.imageUrl, + required this.state, + this.onTap, + this.width = 90}); @override Widget build(BuildContext context) { @@ -260,7 +289,10 @@ class AIResultThumb extends StatelessWidget { ), ), if (state == AIRecordState.failed) - Positioned.fill(child: Center(child: Image.asset('ai_record_failed.webp'.aiPath, width: 20))), + Positioned.fill( + child: Center( + child: + Image.asset('ai_record_failed.webp'.aiPath, width: 20))), ], ); } diff --git a/lib/hj_page/ai/widgets/ai_square_cell.dart b/lib/hj_page/ai/widgets/ai_square_cell.dart index 53d17f8..7602972 100644 --- a/lib/hj_page/ai/widgets/ai_square_cell.dart +++ b/lib/hj_page/ai/widgets/ai_square_cell.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/video/simple_video_player_page.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/header_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/video/simple_video_player_page.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/header_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_utils/widget_util.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../ai_sub_type/ai_function_logic.dart'; import '../models/ai_square_model.dart'; @@ -39,7 +39,9 @@ class AISquareCell extends StatelessWidget { Widget _imgView() { return switch (AiTypeCode.fromServerCode(model.type)) { - AiType.imageChangeFace || AiType.autoStrip => _twoImgsView(model.originalImage, model.generateImage), + AiType.imageChangeFace || + AiType.autoStrip => + _twoImgsView(model.originalImage, model.generateImage), AiType.videoChangeFace => _videoChangeFace(), AiType.imageToVideo => _imgToVideo(), AiType.aiPaint => _aiDraw(), @@ -53,20 +55,24 @@ class AISquareCell extends StatelessWidget { Expanded( child: InkWell( enableFeedback: false, - onTap: () => ImageBrowserPage.open([left ?? ''], showSaveButton: true), + onTap: () => + ImageBrowserPage.open([left ?? ''], showSaveButton: true), child: NetworkImageLoader( imageUrl: left, - imgBorderRadius: const BorderRadius.horizontal(left: Radius.circular(9)), + imgBorderRadius: + const BorderRadius.horizontal(left: Radius.circular(9)), ), ), ), Expanded( child: InkWell( enableFeedback: false, - onTap: () => ImageBrowserPage.open([right ?? ''], showSaveButton: true), + onTap: () => + ImageBrowserPage.open([right ?? ''], showSaveButton: true), child: NetworkImageLoader( imageUrl: right, - imgBorderRadius: const BorderRadius.horizontal(right: Radius.circular(9)), + imgBorderRadius: + const BorderRadius.horizontal(right: Radius.circular(9)), ), ), ), @@ -80,7 +86,10 @@ class AISquareCell extends StatelessWidget { children: [ Text( '“${model.originContent ?? ''}”', - style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xff03FCEB)), + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Color(0xff03FCEB)), ), 12.sizeBoxH, Row( @@ -88,7 +97,8 @@ class AISquareCell extends StatelessWidget { Expanded( child: InkWell( enableFeedback: false, - onTap: () => ImageBrowserPage.open([model.generateImage ?? ''], showSaveButton: true), + onTap: () => ImageBrowserPage.open([model.generateImage ?? ''], + showSaveButton: true), child: NetworkImageLoader(imageUrl: model.generateImage), ), ), @@ -113,7 +123,9 @@ class AISquareCell extends StatelessWidget { Widget _videoChangeFace() { return Row( children: [ - Expanded(child: _videoItem(model.generateVideoCover, model.realGenerateVideoUrl)), + Expanded( + child: _videoItem( + model.generateVideoCover, model.realGenerateVideoUrl)), 10.sizeBoxW, const Expanded(child: SizedBox.shrink()), ], @@ -141,7 +153,10 @@ class AISquareCell extends StatelessWidget { style: textStyle(10, Colors.white, FontWeight.w500), ), )), - TextSpan(text: model.title, style: textStyle(14, Colors.white.withValues(alpha: .9), FontWeight.w500)) + TextSpan( + text: model.title, + style: textStyle( + 14, Colors.white.withValues(alpha: .9), FontWeight.w500)) ])); } @@ -175,7 +190,8 @@ class AISquareCell extends StatelessWidget { 10.sizeBoxW, Text( DateTimeUtil.utcTurnYear(model.reviewAt), - style: textStyle(12, Colors.white.withValues(alpha: 0.55), FontWeight.w400), + style: textStyle(12, Colors.white.withValues(alpha: 0.55), + FontWeight.w400), ) ], ) @@ -189,7 +205,9 @@ class AISquareCell extends StatelessWidget { width: 70, height: 24, alignment: Alignment.center, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: AppColors.actionRed), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + color: AppColors.actionRed), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -218,7 +236,8 @@ class AISquareCell extends StatelessWidget { Widget _videoItem(String? img, String url) { return InkWell( enableFeedback: false, - onTap: () => Get.to(() => SimpleVideoPlayerPage(videoUrl: url, title: model.title ?? '')), + onTap: () => Get.to( + () => SimpleVideoPlayerPage(videoUrl: url, title: model.title ?? '')), child: Stack( alignment: Alignment.center, children: [ diff --git a/lib/hj_page/ai/widgets/ai_video_record.dart b/lib/hj_page/ai/widgets/ai_video_record.dart index 3e3bd8e..1fcfc18 100644 --- a/lib/hj_page/ai/widgets/ai_video_record.dart +++ b/lib/hj_page/ai/widgets/ai_video_record.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../models/ai_record_model.dart'; import 'ai_record_parts.dart'; @@ -12,7 +12,8 @@ class AIVideoRecord extends StatelessWidget { final int status; // 1 排队 2 成功 3 失败 final VoidCallback? onDeleteCallback; - const AIVideoRecord(this.model, {super.key, required this.status, this.onDeleteCallback}); + const AIVideoRecord(this.model, + {super.key, required this.status, this.onDeleteCallback}); AIRecordState get _state => switch (status) { 2 => AIRecordState.success, @@ -20,7 +21,8 @@ class AIVideoRecord extends StatelessWidget { _ => AIRecordState.queuing, }; - String get _resultCover => model.status == 3 ? (model.newImgUrl ?? '') : (model.imgUrl ?? ''); + String get _resultCover => + model.status == 3 ? (model.newImgUrl ?? '') : (model.imgUrl ?? ''); @override Widget build(BuildContext context) { @@ -51,13 +53,17 @@ class AIVideoRecord extends StatelessWidget { children: [ AIRecordThumb( imageUrl: model.imgUrl, - badge: Image.asset('ai_record_org.png'.aiPath, width: 36, height: 18), + badge: + Image.asset('ai_record_org.png'.aiPath, width: 36, height: 18), ), const AIRecordJoin(isEquals: true), AIResultThumb( imageUrl: _resultCover, state: _state, - onTap: _resultCover.isEmpty ? null : () => ImageBrowserPage.open([_resultCover], showSaveButton: true), + onTap: _resultCover.isEmpty + ? null + : () => + ImageBrowserPage.open([_resultCover], showSaveButton: true), ), ], ), diff --git a/lib/hj_page/ai/widgets/pic_picker.dart b/lib/hj_page/ai/widgets/pic_picker.dart index 007ccde..d22fe69 100644 --- a/lib/hj_page/ai/widgets/pic_picker.dart +++ b/lib/hj_page/ai/widgets/pic_picker.dart @@ -2,10 +2,10 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:mobkit_dashed_border/mobkit_dashed_border.dart'; /// AI 功能的单图选择器:未选时是虚线占位框,选后是缩略图 + 右上角删除 @@ -54,7 +54,8 @@ class _PicPickerState extends State { selectCount: 1, showCamera: true, ); - final paths = medias.map((e) => e.path ?? "").where((e) => e.isNotEmpty).toList(); + final paths = + medias.map((e) => e.path ?? "").where((e) => e.isNotEmpty).toList(); if (paths.length < medias.length) showToast("添加图片失败"); return paths; } @@ -92,7 +93,8 @@ class _PicPickerState extends State { onTap: _delPic, child: Padding( padding: const EdgeInsets.all(6), - child: Image.asset("close_grey.png".commonImgPath, width: 14, height: 14), + child: Image.asset("close_grey.png".commonImgPath, + width: 14, height: 14), ), ), ), @@ -120,7 +122,8 @@ class _PicPickerState extends State { children: [ Image.asset('add_grey.png'.communityPath, width: 24), 10.sizeBoxH, - const Text("添加图片", style: TextStyle(fontSize: 12, color: Color(0xff999999))), + const Text("添加图片", + style: TextStyle(fontSize: 12, color: Color(0xff999999))), ], ), ), diff --git a/lib/hj_page/cartoon/acg_widget_item.dart b/lib/hj_page/cartoon/acg_widget_item.dart index d975668..491ee35 100644 --- a/lib/hj_page/cartoon/acg_widget_item.dart +++ b/lib/hj_page/cartoon/acg_widget_item.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../config/config.dart'; import '../../hj_model/cartoon_media_info.dart'; @@ -83,7 +83,10 @@ class AcgItemWidget extends StatelessWidget { child: Text( '${info?.episodeNumberStatus ?? ''} · ${info?.updateDesc}', textAlign: TextAlign.left, - style: TextStyle(fontSize: 11, color: _statusColor, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 11, + color: _statusColor, + fontWeight: FontWeight.w400), maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -96,8 +99,12 @@ class AcgItemWidget extends StatelessWidget { } Widget _buildLevelIcon() { - if (info?.permission == 1 && Config.coinMark) return _levelTag('金币', const Color(0xFF1F2029), bgColor: [const Color(0xFFFFE580), const Color(0xFFFACC15)]); - if (info?.permission == 0 && Config.vipMark) return _levelTag('VIP', Colors.white, bgColor: [ const Color(0xFFFF8000), const Color(0xFFFF7A01)]); + if (info?.permission == 1 && Config.coinMark) + return _levelTag('金币', const Color(0xFF1F2029), + bgColor: [const Color(0xFFFFE580), const Color(0xFFFACC15)]); + if (info?.permission == 0 && Config.vipMark) + return _levelTag('VIP', Colors.white, + bgColor: [const Color(0xFFFF8000), const Color(0xFFFF7A01)]); return const SizedBox.shrink(); } @@ -107,7 +114,8 @@ class AcgItemWidget extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 6), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(2)), - gradient: LinearGradient(colors: bgColor ?? [Color(0xffFFC000), Color(0xffFFC000)]), + gradient: LinearGradient( + colors: bgColor ?? [Color(0xffFFC000), Color(0xffFFC000)]), ), child: Text( text, @@ -117,6 +125,8 @@ class AcgItemWidget extends StatelessWidget { } Color get _statusColor { - return info?.updateStatus == 1 ? const Color(0xffFFC000) : Colors.white.withValues(alpha: .45); + return info?.updateStatus == 1 + ? const Color(0xffFFC000) + : Colors.white.withValues(alpha: .45); } } diff --git a/lib/hj_page/cartoon/audio_player_bottomsheet.dart b/lib/hj_page/cartoon/audio_player_bottomsheet.dart index ff155c1..079fb63 100644 --- a/lib/hj_page/cartoon/audio_player_bottomsheet.dart +++ b/lib/hj_page/cartoon/audio_player_bottomsheet.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/acg/comic_chapters_model.dart'; -import 'package:hgmj/hj_page/live/live_widget.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/acg/comic_chapters_model.dart'; +import 'package:wydj/hj_page/live/live_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../assets_tool/app_colors.dart'; import '../../hj_utils/widget_util.dart'; import 'widget/free_badge.dart'; -import 'package:hgmj/tools_base/widget/stagger_in_item.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/tools_base/widget/stagger_in_item.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; //有声小说 选择子集 class AudioPlayerBottomSheet extends StatefulWidget { @@ -62,7 +62,8 @@ class _AudioPlayerBottomSheetState extends State { ), ), Spacer(), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => setState(() => sortType = sortType == 1 ? 0 : 1), child: Row( children: [ @@ -70,12 +71,14 @@ class _AudioPlayerBottomSheetState extends State { turns: sortType == 1 ? 0 : 0.5, duration: const Duration(milliseconds: 250), curve: Curves.easeOutCubic, - child: Image.asset('text_play_sort.png'.acgImgPath, width: 18), + child: Image.asset('text_play_sort.png'.acgImgPath, + width: 18), ), 4.sizeBoxW, Text( sortType == 1 ? '正序' : '倒序', - style: textStyle(12, Colors.white.withValues(alpha: .45), FontWeight.w400), + style: textStyle(12, Colors.white.withValues(alpha: .45), + FontWeight.w400), ), ], ), @@ -96,52 +99,57 @@ class _AudioPlayerBottomSheetState extends State { final model = widget.allAudiobooks[realIndex]; final select = widget.currentPlayIndex == realIndex; return StaggerInItem( - index: index, - child: InkWell(enableFeedback: false, - onTap: () { - Get.back(result: realIndex); - widget.indexHandler?.call(realIndex); - }, - child: Container( - padding: const EdgeInsets.only(bottom: 6), - child: Column( - children: [ - 16.sizeBoxH, - Row( + index: index, + child: InkWell( + enableFeedback: false, + onTap: () { + Get.back(result: realIndex); + widget.indexHandler?.call(realIndex); + }, + child: Container( + padding: const EdgeInsets.only(bottom: 6), + child: Column( children: [ - if (select) ...[ - AudioWaveView(), - 8.sizeBoxW, - ], - Expanded( - child: Text( - //与详情/抽屉子集 title 格式一致:第X章 - '第${model.episodeNumber ?? 1}${widget.unit ?? ''}', - style: TextStyle( - color: select ? AppColors.actionRed : Colors.white.withValues(alpha: .9), - fontSize: 14, + 16.sizeBoxH, + Row( + children: [ + if (select) ...[ + AudioWaveView(), + 8.sizeBoxW, + ], + Expanded( + child: Text( + //与详情/抽屉子集 title 格式一致:第X章 + '第${model.episodeNumber ?? 1}${widget.unit ?? ''}', + style: TextStyle( + color: select + ? AppColors.actionRed + : Colors.white + .withValues(alpha: .9), + fontSize: 14, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + //无任何权限时,前 N 集免费展示「免费」角标 + if (widget.hasPermission == false && + model.inFreeEpisode) ...[ + 8.sizeBoxW, + const FreeBadge(), + ], + 8.sizeBoxW, + const Icon( + Icons.navigate_next, + size: 18, + color: Color(0xffDCDCDC), + ) + ], ), - //无任何权限时,前 N 集免费展示「免费」角标 - if (widget.hasPermission == false && model.inFreeEpisode) ...[ - 8.sizeBoxW, - const FreeBadge(), - ], - 8.sizeBoxW, - const Icon( - Icons.navigate_next, - size: 18, - color: Color(0xffDCDCDC), - ) + 16.sizeBoxH, ], - ), - 16.sizeBoxH, - ], - )), - )); + )), + )); }, ), ) diff --git a/lib/hj_page/cartoon/audio_player_content.dart b/lib/hj_page/cartoon/audio_player_content.dart index 612f21b..0a559f3 100644 --- a/lib/hj_page/cartoon/audio_player_content.dart +++ b/lib/hj_page/cartoon/audio_player_content.dart @@ -2,11 +2,11 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'audio_player_bottomsheet.dart'; import 'widget/acg_source_manager.dart'; @@ -16,7 +16,8 @@ class AudioPlayerContent extends StatefulWidget { final int index; final AudioPlayerManager manager; final ACGSourceManager sourceManager; - const AudioPlayerContent(this.sourceManager, {super.key, required this.manager, this.index = 0}); + const AudioPlayerContent(this.sourceManager, + {super.key, required this.manager, this.index = 0}); @override State createState() => _AudioPlayerContentState(); @@ -33,7 +34,8 @@ class _AudioPlayerContentState extends State { // - onInit 已 initPlayer // - onClose 已 dispose // 此处不要再调 initPlayer,否则 4 个 stream listener 重复注册导致旧 sub 泄漏 - manager.play(widget.sourceManager.allEpisodes[widget.index].getRealAudioUrl); + manager + .play(widget.sourceManager.allEpisodes[widget.index].getRealAudioUrl); } @override @@ -60,7 +62,10 @@ class _AudioPlayerContentState extends State { children: [ Text( '正在播放:第${(audioValue.onPlayIndex ?? 0) + 1}集', - style: TextStyle(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500), ), ], ), @@ -76,7 +81,8 @@ class _AudioPlayerContentState extends State { } // 进度条行:左右 ±10s 快进退、中间滑块、两侧时间 - Widget _progressRow(AudioPlayerValue audioValue, double progress, double max) { + Widget _progressRow( + AudioPlayerValue audioValue, double progress, double max) { return Row( children: [ Column( @@ -96,7 +102,10 @@ class _AudioPlayerContentState extends State { buildMMSS(audioValue.position?.inSeconds ?? 0), maxLines: 1, softWrap: false, - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 12, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 12, + fontWeight: FontWeight.w500), ), ), ], @@ -115,7 +124,8 @@ class _AudioPlayerContentState extends State { InkWell( enableFeedback: false, onTap: () => manager.seekTenMinsWithDirection(1), - child: Image.asset('noval_time_forword.png'.acgImgPath, width: 24), + child: + Image.asset('noval_time_forword.png'.acgImgPath, width: 24), ), 8.sizeBoxH, SizedBox( @@ -158,9 +168,12 @@ class _AudioPlayerContentState extends State { children: [ AnimatedSwitcher( duration: const Duration(milliseconds: 150), - transitionBuilder: (child, anim) => ScaleTransition(scale: anim, child: child), + transitionBuilder: (child, anim) => + ScaleTransition(scale: anim, child: child), child: Image.asset( - isLoop ? 'single_cycle.png'.acgImgPath : 'list_cycle.png'.acgImgPath, + isLoop + ? 'single_cycle.png'.acgImgPath + : 'list_cycle.png'.acgImgPath, // key 必须按状态区分,AnimatedSwitcher 才会把它当成新 child 触发动画 key: ValueKey(isLoop ? 'loop' : 'loop_list'), width: 24, @@ -169,7 +182,10 @@ class _AudioPlayerContentState extends State { 2.sizeBoxH, Text( isLoop ? '单曲循环' : '多集循环', - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 12, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 12, + fontWeight: FontWeight.w400), ), ], ), @@ -188,7 +204,8 @@ class _AudioPlayerContentState extends State { onTap: () => isPlaying ? manager.pause() : manager.resume(), child: AnimatedSwitcher( duration: const Duration(milliseconds: 150), - transitionBuilder: (child, anim) => ScaleTransition(scale: anim, child: child), + transitionBuilder: (child, anim) => + ScaleTransition(scale: anim, child: child), child: Image.asset( isPlaying ? 'pause.png'.acgImgPath : 'play.png'.acgImgPath, key: ValueKey(isPlaying ? 'pause' : 'play'), @@ -214,7 +231,10 @@ class _AudioPlayerContentState extends State { 2.sizeBoxH, Text( '播放列表', - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 12, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 12, + fontWeight: FontWeight.w400), ), ], ), @@ -278,7 +298,8 @@ class GradientTrackShape extends SliderTrackShape { }) { final trackHeight = sliderTheme.trackHeight ?? 2; final trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2; - return Rect.fromLTWH(offset.dx, trackTop, parentBox.size.width, trackHeight); + return Rect.fromLTWH( + offset.dx, trackTop, parentBox.size.width, trackHeight); } @override @@ -303,12 +324,14 @@ class GradientTrackShape extends SliderTrackShape { final inactivePaint = Paint()..color = const Color(0xff3D3D3D); // 左侧已播放 context.canvas.drawRect( - Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom), + Rect.fromLTRB( + trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom), activePaint, ); // 右侧未播放 context.canvas.drawRect( - Rect.fromLTRB(thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom), + Rect.fromLTRB( + thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom), inactivePaint, ); } @@ -321,7 +344,8 @@ class GradientThumbShape extends SliderComponentShape { const GradientThumbShape({this.radius = 8}); @override - Size getPreferredSize(bool isEnabled, bool isDiscrete) => Size.fromRadius(radius); + Size getPreferredSize(bool isEnabled, bool isDiscrete) => + Size.fromRadius(radius); @override void paint( @@ -339,7 +363,8 @@ class GradientThumbShape extends SliderComponentShape { required double value, }) { final canvas = context.canvas; - final outerPaint = Paint()..color = AppColors.actionRed.withValues(alpha: 0.7); + final outerPaint = Paint() + ..color = AppColors.actionRed.withValues(alpha: 0.7); final innerPaint = Paint()..color = Colors.white; canvas.drawCircle(center, radius, outerPaint); canvas.drawCircle(center, radius - 3, innerPaint); diff --git a/lib/hj_page/cartoon/cartoon_detail_logic.dart b/lib/hj_page/cartoon/cartoon_detail_logic.dart index 8bb6cb0..92d2ffe 100644 --- a/lib/hj_page/cartoon/cartoon_detail_logic.dart +++ b/lib/hj_page/cartoon/cartoon_detail_logic.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import '../../../hj_model/acg/comic_chapters_model.dart'; import '../../../hj_model/cartoon_media_info.dart'; @@ -15,7 +15,8 @@ import 'cartoon_read_page.dart'; import 'widget/acg_source_manager.dart'; import 'widget/cartoon_subset_alert.dart'; -class CartoonDetailLogic extends GetxController with GetTickerProviderStateMixin { +class CartoonDetailLogic extends GetxController + with GetTickerProviderStateMixin { String? id; CartoonMediaInfo? mediaInfo; @@ -39,7 +40,8 @@ class CartoonDetailLogic extends GetxController with GetTickerProviderStateMixin late ACGSourceManager manager; late StreamSubscription subscription; - CartoonDetailLogic({this.id}) : manager = ACGSourceManager(id ?? ''); //初始化,加载子集 + CartoonDetailLogic({this.id}) + : manager = ACGSourceManager(id ?? ''); //初始化,加载子集 @override void onReady() async { @@ -88,7 +90,8 @@ class CartoonDetailLogic extends GetxController with GetTickerProviderStateMixin play() async { //判断权限 - ComicChapterInfo? info = await manager.getEpisodeHasPermisson(manager.index); + ComicChapterInfo? info = + await manager.getEpisodeHasPermisson(manager.index); if (info == null) return; Get.to(() => CartoonReadPage(manager: manager..index = manager.index)); } diff --git a/lib/hj_page/cartoon/cartoon_detail_page.dart b/lib/hj_page/cartoon/cartoon_detail_page.dart index 2989068..4a59cd3 100644 --- a/lib/hj_page/cartoon/cartoon_detail_page.dart +++ b/lib/hj_page/cartoon/cartoon_detail_page.dart @@ -3,15 +3,15 @@ import 'dart:math'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/follow_button.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/follow_button.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../hj_utils/const.dart'; @@ -38,7 +38,8 @@ class CartoonDetailPage extends StatefulWidget { } // 详情页可经「推荐页 → 再开详情页」成环并存,用 UniqueTagMixin 给每个实例唯一 tag -class _CartoonDetailPageState extends State with UniqueTagMixin { +class _CartoonDetailPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return Scaffold( @@ -65,7 +66,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix } // 当前内容对应的推荐类型(小说等无对应 tab 时为 null) - MediaStyle? _selfStyle(CartoonDetailLogic logic) => switch (logic.mediaInfo?.mediaType) { + MediaStyle? _selfStyle(CartoonDetailLogic logic) => + switch (logic.mediaInfo?.mediaType) { 'video' => MediaStyle.Cartoon, 'image' => MediaStyle.Comics, _ => null, @@ -111,7 +113,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix return [ SliverToBoxAdapter(child: _buildImgHeader(logic)), //header SliverToBoxAdapter(child: _buildMenu(logic)), //目录 - SliverToBoxAdapter(child: _buildTabbar(logic, styles)) //推荐 tabbar + SliverToBoxAdapter( + child: _buildTabbar(logic, styles)) //推荐 tabbar ]; }, //推荐 @@ -137,8 +140,10 @@ class _CartoonDetailPageState extends State with UniqueTagMix if (logic.isCartoonType) ...[ Consumer( builder: (context, manager, child) { - bool liked = manager.mediaInfo?.mediaStatus?.hasLiked == true; - return InkWell(enableFeedback: false, + bool liked = + manager.mediaInfo?.mediaStatus?.hasLiked == true; + return InkWell( + enableFeedback: false, onTap: () => manager.onLikeAction(), child: Container( width: 108, @@ -152,13 +157,16 @@ class _CartoonDetailPageState extends State with UniqueTagMix mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - liked ? 'acg_like_sel.png'.acgImgPath : 'acg_like_nor.png'.acgImgPath, + liked + ? 'acg_like_sel.png'.acgImgPath + : 'acg_like_nor.png'.acgImgPath, width: 16, ), 10.sizeBoxW, Text( '喜欢', - style: textStyle(16, Color(0xff989898), FontWeight.w500), + style: textStyle( + 16, Color(0xff989898), FontWeight.w500), ), ], )), @@ -168,7 +176,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix 12.sizeBoxW, ], Expanded( - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () => logic.play(), child: Container( decoration: BoxDecoration( @@ -268,12 +277,14 @@ class _CartoonDetailPageState extends State with UniqueTagMix if (logic.mediaInfo?.permission == 0) ...[ Text( 'VIP', - style: textStyle(12, Color(0xff989898), FontWeight.w400), + style: + textStyle(12, Color(0xff989898), FontWeight.w400), ), ] else if (logic.mediaInfo?.permission == 1) ...[ Text( '${logic.mediaInfo?.price ?? 0}金币', - style: textStyle(12, Color(0xff989898), FontWeight.w400), + style: + textStyle(12, Color(0xff989898), FontWeight.w400), ), ], ], @@ -300,7 +311,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix scrollDirection: Axis.horizontal, itemBuilder: (context, index) { TagsBean? tag = logic.mediaInfo?.tagDetails?[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { Get.to(CartoonTagPage( title: tag?.name ?? '', @@ -310,8 +322,9 @@ class _CartoonDetailPageState extends State with UniqueTagMix child: Container( padding: EdgeInsets.symmetric(horizontal: 8), alignment: Alignment.center, - decoration: - BoxDecoration(color: Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(3)), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .05), + borderRadius: BorderRadius.circular(3)), height: 26, child: Text( tag?.name ?? '', @@ -375,7 +388,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), labelColor: Colors.white.withValues(alpha: 0.9), unselectedLabelColor: Colors.white.withValues(alpha: .55), - unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + TextStyle(fontSize: 14, fontWeight: FontWeight.w400), indicator: CustomIndicator( isGradient: true, width: 13, @@ -397,7 +411,9 @@ class _CartoonDetailPageState extends State with UniqueTagMix Row( children: [ Text( - logic.isCartoonType ? '选集' : '共${logic.mediaInfo?.totalEpisode ?? 0}${logic.mediaInfo?.unit}', + logic.isCartoonType + ? '选集' + : '共${logic.mediaInfo?.totalEpisode ?? 0}${logic.mediaInfo?.unit}', style: TextStyle( color: Colors.white, fontSize: 18, @@ -407,10 +423,13 @@ class _CartoonDetailPageState extends State with UniqueTagMix Spacer(), Row( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: logic.onMenuAction, child: Text( - logic.isCartoonType ? '全${logic.mediaInfo?.totalEpisode ?? 0}${logic.mediaInfo?.unit}' : '目录', + logic.isCartoonType + ? '全${logic.mediaInfo?.totalEpisode ?? 0}${logic.mediaInfo?.unit}' + : '目录', style: TextStyle( color: Color(0xFFA7A7A7), fontSize: 14, @@ -437,10 +456,12 @@ class _CartoonDetailPageState extends State with UniqueTagMix shrinkWrap: true, itemBuilder: (context, index) { final epm = provider.allEpisodes[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => logic.changeEpisode(index, false), child: Container( - padding: EdgeInsets.symmetric(vertical: logic.isCartoonType ? 6 : 12), + padding: EdgeInsets.symmetric( + vertical: logic.isCartoonType ? 6 : 12), child: Row( children: [ Flexible( @@ -450,13 +471,18 @@ class _CartoonDetailPageState extends State with UniqueTagMix overflow: TextOverflow.ellipsis, style: textStyle( 16, - provider.index == index ? Colors.white.withValues(alpha: .9) : Colors.white.withValues(alpha: .45), - provider.index == index ? FontWeight.w500 : FontWeight.w400, + provider.index == index + ? Colors.white.withValues(alpha: .9) + : Colors.white.withValues(alpha: .45), + provider.index == index + ? FontWeight.w500 + : FontWeight.w400, ), ), ), //无任何权限时,前 N 集免费展示「免费」角标 - if (provider.mediaInfo?.hasPermission == false && epm.inFreeEpisode) ...[ + if (provider.mediaInfo?.hasPermission == false && + epm.inFreeEpisode) ...[ 8.sizeBoxW, const FreeBadge(), ], @@ -478,7 +504,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix } Widget _buildBackView() { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, child: Image.asset( 'back_circle_grey.png'.commonImgPath, width: 24, @@ -488,7 +515,8 @@ class _CartoonDetailPageState extends State with UniqueTagMix } Widget _buildShareView(CartoonDetailLogic logic) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { Get.dialog( ShareMediaDialog( @@ -510,20 +538,25 @@ class _CartoonDetailPageState extends State with UniqueTagMix return Offstage( offstage: logic.showHeader, child: Container( - padding: EdgeInsets.only(left: 16, right: 16, top: screen.paddingTop), + padding: + EdgeInsets.only(left: 16, right: 16, top: screen.paddingTop), height: 44 + screen.paddingTop, color: Color(0xff05000E), child: Row( children: [ GestureDetector( onTap: () => Get.back(), - child: Icon(Icons.arrow_back_ios, size: 24, color: Colors.white), + child: + Icon(Icons.arrow_back_ios, size: 24, color: Colors.white), ), 8.sizeBoxW, Expanded( child: Text( logic.mediaInfo?.title ?? '', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.white), textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, ), diff --git a/lib/hj_page/cartoon/cartoon_read_logic.dart b/lib/hj_page/cartoon/cartoon_read_logic.dart index b02b182..63f31c4 100644 --- a/lib/hj_page/cartoon/cartoon_read_logic.dart +++ b/lib/hj_page/cartoon/cartoon_read_logic.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import 'widget/acg_source_manager.dart'; @@ -156,9 +156,11 @@ class CartoonReadLogic extends GetxController { /// [isFirstLoad] 失败时才进错误页 Future _openEpisode(int index, {bool isFirstLoad = false}) async { // 首次进入页面已有全屏 loading,不再叠遮罩 - final model = await manager.getComicsMediaContent(index: index, showLoading: !isFirstLoad); + final model = await manager.getComicsMediaContent( + index: index, showLoading: !isFirstLoad); if (model == null) { - if (isFirstLoad) detailInfo = MediaContent(); // 空 model → id 为 null → 页面走错误态 + if (isFirstLoad) + detailInfo = MediaContent(); // 空 model → id 为 null → 页面走错误态 update(); return; } @@ -196,7 +198,8 @@ class CartoonReadLogic extends GetxController { void _startTimer() { _timer?.cancel(); // 防重入:先停旧的再建新的,避免重复开启时旧定时器泄漏 _timer = Timer.periodic(const Duration(milliseconds: 500), (_) { - scrollOffsetCtr.animateScroll(offset: 50, duration: const Duration(milliseconds: 500)); + scrollOffsetCtr.animateScroll( + offset: 50, duration: const Duration(milliseconds: 500)); }); } diff --git a/lib/hj_page/cartoon/cartoon_read_page.dart b/lib/hj_page/cartoon/cartoon_read_page.dart index dc6f47c..b83d4d6 100644 --- a/lib/hj_page/cartoon/cartoon_read_page.dart +++ b/lib/hj_page/cartoon/cartoon_read_page.dart @@ -3,23 +3,23 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/comment_alert.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/follow_button.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/comment_alert.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/follow_button.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import 'package:provider/provider.dart'; import '../../alert/video/share_media_dialog.dart'; import '../../hj_utils/widget_util.dart'; import 'cartoon_read_logic.dart'; import 'widget/acg_source_manager.dart'; -import 'package:hgmj/tools_base/widget/stagger_in_item.dart'; +import 'package:wydj/tools_base/widget/stagger_in_item.dart'; // 漫画阅读页面 class CartoonReadPage extends StatelessWidget { @@ -42,11 +42,13 @@ class CartoonReadPage extends StatelessWidget { Widget _buildBody(BuildContext context, CartoonReadLogic logic) { if (logic.detailInfo == null) return const LoadingCenterWidget(); - if (logic.detailInfo?.id == null) return CErrorWidget(retryOnTap: logic.loadData); + if (logic.detailInfo?.id == null) + return CErrorWidget(retryOnTap: logic.loadData); return Stack( alignment: Alignment.center, children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: logic.changeShowMenu, child: ScrollablePositionedList.builder( scrollAction: logic.onScrollAction, @@ -85,21 +87,27 @@ class CartoonReadPage extends StatelessWidget { padding: EdgeInsets.fromLTRB(10, screen.paddingTop + 8, 10, 8), child: Row( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.back(), - child: const Icon(Icons.arrow_back_ios_new, size: 24, color: Colors.white), + child: const Icon(Icons.arrow_back_ios_new, + size: 24, color: Colors.white), ), 10.sizeBoxW, Expanded( child: Text( logic.detailInfo?.name ?? '', - style: TextStyle(fontSize: 18.sp, color: Colors.white, fontWeight: FontWeight.w600), + style: TextStyle( + fontSize: 18.sp, + color: Colors.white, + fontWeight: FontWeight.w600), ), ), 21.sizeBoxW, Consumer( builder: (ctx, manager, _) { - final col = manager.mediaInfo?.mediaStatus?.hasCollected ?? false; + final col = + manager.mediaInfo?.mediaStatus?.hasCollected ?? false; return FollowButton( mediaId: manager.mediaInfo?.id ?? '', isFollow: col, @@ -112,7 +120,8 @@ class CartoonReadPage extends StatelessWidget { }, ), 12.sizeBoxW, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.dialog( ShareMediaDialog( videoModel: VideoModel() @@ -196,8 +205,10 @@ class CartoonReadPage extends StatelessWidget { ); } - Widget _buildActionItem({String? title, String? icon, VoidCallback? action, Color? color}) { - return InkWell(enableFeedback: false, + Widget _buildActionItem( + {String? title, String? icon, VoidCallback? action, Color? color}) { + return InkWell( + enableFeedback: false, onTap: action, child: Column( children: [ @@ -223,13 +234,15 @@ class CartoonReadPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.loadOtherEpisode(false), child: Column( children: [ Image.asset('common_back_new.png'.commonImgPath, width: 24), 4.sizeBoxH, - Text('上一篇', style: textStyle(12, Colors.white, FontWeight.w400)), + Text('上一篇', + style: textStyle(12, Colors.white, FontWeight.w400)), ], ), ), @@ -238,9 +251,12 @@ class CartoonReadPage extends StatelessWidget { child: SliderTheme( data: SliderTheme.of(context).copyWith( trackHeight: 4, - thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 8.0), - overlayShape: const RoundSliderOverlayShape(overlayRadius: 12.0), - tickMarkShape: const RoundSliderTickMarkShape(tickMarkRadius: 10.0), + thumbShape: + const RoundSliderThumbShape(enabledThumbRadius: 8.0), + overlayShape: + const RoundSliderOverlayShape(overlayRadius: 12.0), + tickMarkShape: + const RoundSliderTickMarkShape(tickMarkRadius: 10.0), trackShape: const RoundedRectSliderTrackShape(), overlayColor: Colors.white.withValues(alpha: .3), activeTrackColor: const Color(0xffFFD460), @@ -261,16 +277,19 @@ class CartoonReadPage extends StatelessWidget { ), ), 13.sizeBoxW, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.loadOtherEpisode(true), child: Column( children: [ Transform.rotate( angle: pi, - child: Image.asset('common_back_new.png'.commonImgPath, width: 24), + child: Image.asset('common_back_new.png'.commonImgPath, + width: 24), ), 4.sizeBoxH, - Text('下一篇', style: textStyle(12, Colors.white, FontWeight.w400)), + Text('下一篇', + style: textStyle(12, Colors.white, FontWeight.w400)), ], ), ), @@ -290,10 +309,12 @@ class CartoonReadPage extends StatelessWidget { child: Consumer( builder: (_, manager, __) { final liked = manager.mediaInfo?.mediaStatus?.hasLiked == true; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: manager.onLikeAction, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.black.withValues(alpha: .5), borderRadius: const BorderRadius.only( @@ -306,12 +327,15 @@ class CartoonReadPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - liked ? 'acg_like_sel.png'.acgImgPath : 'acg_like_nor.png'.acgImgPath, + liked + ? 'acg_like_sel.png'.acgImgPath + : 'acg_like_nor.png'.acgImgPath, width: 24, color: liked ? null : Colors.white, ), 5.sizeBoxW, - Text('喜欢', style: textStyle(12, Colors.white, FontWeight.w400)), + Text('喜欢', + style: textStyle(12, Colors.white, FontWeight.w400)), ], ), ), @@ -344,7 +368,8 @@ class CartoonReadPage extends StatelessWidget { color: Colors.white, ), child: Center( - child: Image.asset('cartoon_auto_play.gif'.acgImgPath, width: 24), + child: Image.asset('cartoon_auto_play.gif'.acgImgPath, + width: 24), ), ), ), @@ -390,9 +415,13 @@ class CartoonReadPage extends StatelessWidget { children: [ Text( '共${logic.manager.mediaInfo?.totalEpisode}话 ${logic.manager.mediaInfo?.getDetailUpdateString ?? ''}', - style: const TextStyle(fontSize: 14, color: Color(0xff141414), fontWeight: FontWeight.w400), + style: const TextStyle( + fontSize: 14, + color: Color(0xff141414), + fontWeight: FontWeight.w400), ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: logic.toggleSort, child: Row( children: [ @@ -400,12 +429,18 @@ class CartoonReadPage extends StatelessWidget { turns: logic.sortType ? 0 : 0.5, duration: const Duration(milliseconds: 250), curve: Curves.easeOutCubic, - child: Image.asset('text_play_sort.png'.acgImgPath, color: const Color(0xff141414), width: 16, height: 16), + child: Image.asset('text_play_sort.png'.acgImgPath, + color: const Color(0xff141414), + width: 16, + height: 16), ), 4.sizeBoxW, Text( logic.sortType ? '正序' : '倒序', - style: const TextStyle(fontSize: 14, color: Color(0xff141414), fontWeight: FontWeight.w400), + style: const TextStyle( + fontSize: 14, + color: Color(0xff141414), + fontWeight: FontWeight.w400), ), ], ), @@ -422,13 +457,15 @@ class CartoonReadPage extends StatelessWidget { // 不使用 list.reverse(items 不够会从底部排),采用数据倒序方法 final info = logic.sortType ? logic.manager.allEpisodes[index] - : logic.manager.allEpisodes[logic.manager.allEpisodes.length - index - 1]; + : logic.manager.allEpisodes[ + logic.manager.allEpisodes.length - index - 1]; return StaggerInItem( index: index, child: GestureDetector( onTap: () { Get.back(); - if (logic.detailInfo?.id == info.id) return; //点的就是当前章,不重复加载 + if (logic.detailInfo?.id == info.id) + return; //点的就是当前章,不重复加载 logic.loadDataWithIndex(info.id ?? ''); }, child: Container( @@ -461,7 +498,9 @@ class CartoonReadPage extends StatelessWidget { title, style: TextStyle( fontSize: 16.sp, - color: select ? AppColors.actionRed : Colors.white.withValues(alpha: 0.55), + color: select + ? AppColors.actionRed + : Colors.white.withValues(alpha: 0.55), fontWeight: select ? FontWeight.w500 : FontWeight.w400, ), maxLines: 1, diff --git a/lib/hj_page/cartoon/cartoon_recommend_logic.dart b/lib/hj_page/cartoon/cartoon_recommend_logic.dart index 5d440e9..9c00189 100644 --- a/lib/hj_page/cartoon/cartoon_recommend_logic.dart +++ b/lib/hj_page/cartoon/cartoon_recommend_logic.dart @@ -1,7 +1,7 @@ //小说/视频推荐 -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../../hj_utils/api_service/common_service.dart'; @@ -10,7 +10,8 @@ class CartoonRecommendLogic extends ListBaseLogic { final MediaStyle mediaStyle; //推荐类型:Video(真人视频) / Cartoon(动漫) / Comics(漫画) final String? videoTagId; //视频(SP)推荐的 tagId,按当前视频 tag 拉同类 - CartoonRecommendLogic({this.mediaId, this.mediaStyle = MediaStyle.Comics, this.videoTagId}); + CartoonRecommendLogic( + {this.mediaId, this.mediaStyle = MediaStyle.Comics, this.videoTagId}); @override void onReady() { @@ -30,10 +31,15 @@ class CartoonRecommendLogic extends ListBaseLogic { //按类型分流:视频走 getRecommendList,漫画/动漫走 comicsRecommendList Future<(List?, bool)> _fetch(int page) async { if (mediaStyle == MediaStyle.Video) { - final resp = await CommonService.getRecommendList(pageNumber: page, pageSize: 12, tagId: videoTagId, newsType: mediaStyle.rankParam); + final resp = await CommonService.getRecommendList( + pageNumber: page, + pageSize: 12, + tagId: videoTagId, + newsType: mediaStyle.rankParam); return (resp?.videos, resp?.hasNext == true); } - final model = await ACGService.comicsRecommendList(page, 12, tagId: mediaId, mediaType: mediaStyle.rankParam); + final model = await ACGService.comicsRecommendList(page, 12, + tagId: mediaId, mediaType: mediaStyle.rankParam); return (model?.list, model?.hasNext == true); } } diff --git a/lib/hj_page/cartoon/cartoon_recommend_page.dart b/lib/hj_page/cartoon/cartoon_recommend_page.dart index 3c0eaa2..81dd1db 100644 --- a/lib/hj_page/cartoon/cartoon_recommend_page.dart +++ b/lib/hj_page/cartoon/cartoon_recommend_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../hj_model/video_model.dart'; import '../home/home_cell_style/video_simple_cell.dart'; @@ -40,7 +40,8 @@ class CartoonRecommendPage extends StatefulWidget { State createState() => _CartoonRecommendPageState(); } -class _CartoonRecommendPageState extends State with UniqueTagMixin { +class _CartoonRecommendPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -52,7 +53,8 @@ class _CartoonRecommendPageState extends State with Unique ), builder: (logic) { if (logic.isLoading) return LoadingCenterWidget(); - if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData()); + if (logic.isEmptyData) + return CErrorWidget(retryOnTap: () => logic.loadData()); final list = logic.dataList!; return pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, @@ -68,7 +70,9 @@ class _CartoonRecommendPageState extends State with Unique childAspectRatio: widget.childAspectRatio, ), itemCount: list.length, - itemBuilder: (_, index) => widget.mediaStyle == MediaStyle.Video ? _videoCell(list[index]) : _acgCell(list[index]), + itemBuilder: (_, index) => widget.mediaStyle == MediaStyle.Video + ? _videoCell(list[index]) + : _acgCell(list[index]), ), ); }, diff --git a/lib/hj_page/cartoon/cartoon_sectionlist_page.dart b/lib/hj_page/cartoon/cartoon_sectionlist_page.dart index a9c6c96..e5aba20 100644 --- a/lib/hj_page/cartoon/cartoon_sectionlist_page.dart +++ b/lib/hj_page/cartoon/cartoon_sectionlist_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'cartoon_sectionlist_sub_page.dart'; @@ -26,8 +26,10 @@ class CartoonSectionListPage extends StatefulWidget { State createState() => _CartoonSectionListPageState(); } -class _CartoonSectionListPageState extends State with SingleTickerProviderStateMixin { - late final TabController tabCtr = TabController(length: _sortTabs.length, vsync: this); +class _CartoonSectionListPageState extends State + with SingleTickerProviderStateMixin { + late final TabController tabCtr = + TabController(length: _sortTabs.length, vsync: this); @override void dispose() { @@ -73,7 +75,8 @@ class _CartoonSectionListPageState extends State with Si decoration: BoxDecoration( border: index != _sortTabs.length - 1 ? Border( - right: BorderSide(width: .5, color: Colors.white.withValues(alpha: .1)), + right: BorderSide( + width: .5, color: Colors.white.withValues(alpha: .1)), ) : null, ), @@ -84,7 +87,8 @@ class _CartoonSectionListPageState extends State with Si labelPadding: EdgeInsets.zero, labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), unselectedLabelColor: Colors.white.withValues(alpha: 0.5), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), indicator: const BoxDecoration(), ), ); diff --git a/lib/hj_page/cartoon/cartoon_sectionlist_sub_logic.dart b/lib/hj_page/cartoon/cartoon_sectionlist_sub_logic.dart index 17ca254..475a557 100644 --- a/lib/hj_page/cartoon/cartoon_sectionlist_sub_logic.dart +++ b/lib/hj_page/cartoon/cartoon_sectionlist_sub_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class CartoonSectionSubLogic extends ListBaseLogic { final int? sortType; @@ -8,13 +8,13 @@ class CartoonSectionSubLogic extends ListBaseLogic { CartoonSectionSubLogic({this.sortType, this.sectionID}); - bool get isCartoon { - if(dataList?.isNotEmpty == true){ + if (dataList?.isNotEmpty == true) { return dataList!.first.mediaType == "video"; } return false; } + @override void onReady() { super.onReady(); @@ -25,7 +25,6 @@ class CartoonSectionSubLogic extends ListBaseLogic { void loadMoreData() => fetchData(isRefresh: false, fetch: _fetch); - Future<(List?, bool)> _fetch(int page) async { final resp = await ACGService.getPreferences( page, diff --git a/lib/hj_page/cartoon/cartoon_sectionlist_sub_page.dart b/lib/hj_page/cartoon/cartoon_sectionlist_sub_page.dart index 7396619..384b168 100644 --- a/lib/hj_page/cartoon/cartoon_sectionlist_sub_page.dart +++ b/lib/hj_page/cartoon/cartoon_sectionlist_sub_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'acg_widget_item.dart'; import 'cartoon_sectionlist_sub_logic.dart'; @@ -35,14 +35,15 @@ class CartoonSectionSubPage extends StatelessWidget { Widget _buildGrid(CartoonSectionSubLogic logic) { return GridView.builder( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: logic.isCartoon ? 2 : 3, mainAxisSpacing: 12, crossAxisSpacing: 5, - childAspectRatio: logic.isCartoon ? 174 /138 : 111 / 190, + childAspectRatio: logic.isCartoon ? 174 / 138 : 111 / 190, ), itemCount: logic.dataList?.length ?? 0, - itemBuilder: (context, index) => AcgItemWidget(info: logic.dataList?[index]), + itemBuilder: (context, index) => + AcgItemWidget(info: logic.dataList?[index]), ); } } diff --git a/lib/hj_page/cartoon/cartoon_sub_detail_page.dart b/lib/hj_page/cartoon/cartoon_sub_detail_page.dart index 0d78486..065b52f 100644 --- a/lib/hj_page/cartoon/cartoon_sub_detail_page.dart +++ b/lib/hj_page/cartoon/cartoon_sub_detail_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'cartoon_sub_grid_page.dart'; @@ -21,6 +21,7 @@ class CartoonSubDetailPage extends StatelessWidget { @override Widget build(BuildContext context) { - return CartoonSubGridPage(tagData: tagData, type: type, scrollCtr: scroll).keepAlive; + return CartoonSubGridPage(tagData: tagData, type: type, scrollCtr: scroll) + .keepAlive; } } diff --git a/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart b/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart index 116aaeb..5e7f6f4 100644 --- a/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart +++ b/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class CartoonSubGridLogic extends ListBaseLogic { final MediaStyle type; //-1:动漫和漫画 0:图集 1:黄游 2:小说 @@ -30,11 +30,13 @@ class CartoonSubGridLogic extends ListBaseLogic { String get newsType { if (tagData?.moduleName == '热门推荐' && tagData?.type == -100) return 'PIC'; - if (tagData?.moduleName == '热门推荐' && tagData?.type == -101) return 'SEED_LINK'; + if (tagData?.moduleName == '热门推荐' && tagData?.type == -101) + return 'SEED_LINK'; return ''; } - bool get isAcg => type == MediaStyle.Novel || type == MediaStyle.Cartoon; //是否是acg模块 + bool get isAcg => + type == MediaStyle.Novel || type == MediaStyle.Cartoon; //是否是acg模块 CartoonSubGridLogic({this.tagData, this.type = MediaStyle.Pic}); @@ -57,7 +59,11 @@ class CartoonSubGridLogic extends ListBaseLogic { SortTab('最多收藏', 7), ]; } else if (type == MediaStyle.Pic || type == MediaStyle.Novel) { - sortTabs = const [SortTab('最多观看', 3), SortTab('最新发布', 1), SortTab('最多收藏', 7)]; + sortTabs = const [ + SortTab('最多观看', 3), + SortTab('最新发布', 1), + SortTab('最多收藏', 7) + ]; } else { sortTabs = const [SortTab('最新', 1), SortTab('最热', 2), SortTab('畅销', 8)]; } @@ -74,7 +80,8 @@ class CartoonSubGridLogic extends ListBaseLogic { loadData({int pageNum = 1}) async { dataList ??= []; ModuleDetailModel? retModel; - if (tagData?.moduleName == '热门推荐' && (tagData?.type == -100 || tagData?.type == -101)) { + if (tagData?.moduleName == '热门推荐' && + (tagData?.type == -100 || tagData?.type == -101)) { //图集 retModel = await VidService.communityRecommend( pageNum, @@ -111,7 +118,9 @@ class CartoonSubGridLogic extends ListBaseLogic { } update(); refreshCtr?.refreshCompleted(); - retModel?.hasNext == true ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); + retModel?.hasNext == true + ? refreshCtr?.loadComplete() + : refreshCtr?.loadNoData(); } loadMoreData() => loadData(pageNum: currentPage + 1); diff --git a/lib/hj_page/cartoon/cartoon_sub_grid_page.dart b/lib/hj_page/cartoon/cartoon_sub_grid_page.dart index 08a7f30..1b32c52 100644 --- a/lib/hj_page/cartoon/cartoon_sub_grid_page.dart +++ b/lib/hj_page/cartoon/cartoon_sub_grid_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/sliver_delegate.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/sliver_delegate.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../home/home_cell_style/quick_entry_row.dart'; import '../home/home_cell_style/video_simple_cell.dart'; @@ -89,7 +89,8 @@ class CartoonSubGridPage extends StatelessWidget { controller: logic.tabCtr, isScrollable: true, //选中/未选中只差颜色,unselectedLabelStyle 不传会 fallback 到 labelStyle - labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + labelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), labelColor: Colors.white.withValues(alpha: .9), unselectedLabelColor: Colors.white.withValues(alpha: .55), indicator: const BoxDecoration(), //去掉默认下划线 @@ -110,11 +111,13 @@ class CartoonSubGridPage extends StatelessWidget { final list = logic.dataList; //null 是还没拉过,空 list 才是真没数据 if (list == null) { - return const SliverToBoxAdapter(child: SizedBox(height: 400, child: LoadingCenterWidget())); + return const SliverToBoxAdapter( + child: SizedBox(height: 400, child: LoadingCenterWidget())); } if (list.isEmpty) { return SliverToBoxAdapter( - child: SizedBox(height: 400, child: CErrorWidget(retryOnTap: logic.loadData)), + child: SizedBox( + height: 400, child: CErrorWidget(retryOnTap: logic.loadData)), ); } return SliverPadding( @@ -129,8 +132,11 @@ class CartoonSubGridPage extends StatelessWidget { delegate: SliverChildBuilderDelegate( //-1动漫/漫画 0-图集 1-黄游 2-小说 (_, index) => switch (type) { - MediaStyle.Cartoon || MediaStyle.Novel => AcgItemWidget(info: list[index], coverV: true), - MediaStyle.Pic => PhotoGalleryItem(videoModel: list[index], textline: 1), + MediaStyle.Cartoon || + MediaStyle.Novel => + AcgItemWidget(info: list[index], coverV: true), + MediaStyle.Pic => + PhotoGalleryItem(videoModel: list[index], textline: 1), MediaStyle.Game => VideoSimpleCell( videoModel: list[index], isFromHY: true, diff --git a/lib/hj_page/cartoon/cartoon_sub_module_logic.dart b/lib/hj_page/cartoon/cartoon_sub_module_logic.dart index 5de1dfa..bbe603c 100644 --- a/lib/hj_page/cartoon/cartoon_sub_module_logic.dart +++ b/lib/hj_page/cartoon/cartoon_sub_module_logic.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/bottom_bar_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_page/main_page/provider/bottom_bar_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; -class CartoonSubModuleLogic extends GetxController with GetTickerProviderStateMixin { +class CartoonSubModuleLogic extends GetxController + with GetTickerProviderStateMixin { final int tabIndex; // 未初始化时,内链跳转需要 final MediaStyle type; //-1:动漫和漫画 0:图集 1:黄游 2:小说 List tabs = []; //漫画 @@ -39,7 +40,8 @@ class CartoonSubModuleLogic extends GetxController with GetTickerProviderStateMi @override void onClose() { - tabController.dispose(); // 自建 TabController,随 logic 释放(含内部 AnimationController + 匿名监听) + tabController + .dispose(); // 自建 TabController,随 logic 释放(含内部 AnimationController + 匿名监听) super.onClose(); } diff --git a/lib/hj_page/cartoon/cartoon_sub_module_page.dart b/lib/hj_page/cartoon/cartoon_sub_module_page.dart index 277181e..6922093 100644 --- a/lib/hj_page/cartoon/cartoon_sub_module_page.dart +++ b/lib/hj_page/cartoon/cartoon_sub_module_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/main_page/provider/bottom_bar_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/hj_page/main_page/provider/bottom_bar_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; import 'cartoon_sub_detail_page.dart'; import 'cartoon_sub_module_logic.dart'; @@ -12,7 +12,8 @@ class CartoonSubModulePage extends StatelessWidget { final MediaStyle type; //-1:动漫和漫画 0:图集 1:黄游 2:小说 final int tabIndex; - const CartoonSubModulePage({super.key, this.type = MediaStyle.Pic, this.tabIndex = 0}); + const CartoonSubModulePage( + {super.key, this.type = MediaStyle.Pic, this.tabIndex = 0}); @override Widget build(BuildContext context) { @@ -31,8 +32,11 @@ class CartoonSubModulePage extends StatelessWidget { tagData: logic.tabs[index], type: type, index: index, - scroll: CommunityBottomProvider() - .scrollCtr(type == MediaStyle.Pic ? MediaStyle.Pic : MediaStyle.Novel, index), + scroll: CommunityBottomProvider().scrollCtr( + type == MediaStyle.Pic + ? MediaStyle.Pic + : MediaStyle.Novel, + index), ), ), ), @@ -59,8 +63,10 @@ class CartoonSubModulePage extends StatelessWidget { labelColor: Colors.white.withValues(alpha: .9), labelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), unselectedLabelColor: Colors.white.withValues(alpha: .55), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), - indicator: CustomIndicator(width: 16, height: 2, offsetY: 6, color: Color(0xFFFFC000)), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + indicator: CustomIndicator( + width: 16, height: 2, offsetY: 6, color: Color(0xFFFFC000)), ); } } diff --git a/lib/hj_page/cartoon/novel_detail_logic.dart b/lib/hj_page/cartoon/novel_detail_logic.dart index 09c215f..00c9392 100644 --- a/lib/hj_page/cartoon/novel_detail_logic.dart +++ b/lib/hj_page/cartoon/novel_detail_logic.dart @@ -4,9 +4,9 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../hj_model/cartoon_media_info.dart'; import '../../hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../hj_utils/history_util.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/const.dart'; import '../../routers/jump_router.dart'; import 'audio_player_bottomsheet.dart'; import 'text_novel_read_page.dart'; @@ -71,12 +71,15 @@ class NovelDetailLogic extends GetxController { // 获取相关推荐 Future fetchRecommendData() async { - final result = await ACGService.comicsRecommendList(page, 12, tagId: model?.tagDetails?.firstOrNull?.id ?? '', mediaType: 'text'); + final result = await ACGService.comicsRecommendList(page, 12, + tagId: model?.tagDetails?.firstOrNull?.id ?? '', mediaType: 'text'); if (result != null) { page += 1; recommends.addAll(result.list ?? []); } - result?.hasNext ?? false ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); + result?.hasNext ?? false + ? refreshCtr?.loadComplete() + : refreshCtr?.loadNoData(); update(); } @@ -96,11 +99,13 @@ class NovelDetailLogic extends GetxController { gotoPlay({int index = 0}) async { final mediaSubType = model?.mediaSubType ?? -1; - final opm = await manager.getEpisodeHasPermisson(index); //通过时内部已切集,不必再 changeEpisodesIndex + final opm = await manager + .getEpisodeHasPermisson(index); //通过时内部已切集,不必再 changeEpisodesIndex if (opm != null) { //0-默认文本小说 1-有声小说 if (mediaSubType == 0) { - Get.to(() => TextNovelReadPage(manager: manager), preventDuplicates: false); + Get.to(() => TextNovelReadPage(manager: manager), + preventDuplicates: false); } else if (mediaSubType == 1) { Get.to( () => VoiceNovelReadPage( @@ -123,5 +128,4 @@ class NovelDetailLogic extends GetxController { } pushToCartoonPage(info); } - } diff --git a/lib/hj_page/cartoon/novel_detail_page.dart b/lib/hj_page/cartoon/novel_detail_page.dart index 4a7a9c4..d5f92a9 100644 --- a/lib/hj_page/cartoon/novel_detail_page.dart +++ b/lib/hj_page/cartoon/novel_detail_page.dart @@ -2,12 +2,12 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/follow_button.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/follow_button.dart'; import 'package:provider/provider.dart'; import '../../hj_utils/widget_util.dart'; @@ -87,7 +87,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { padding: EdgeInsets.only(bottom: 80), sliver: SliverGrid.builder( itemCount: _.recommends.length, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 12, crossAxisSpacing: 6, @@ -112,7 +113,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { ), ), ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, child: Container( margin: EdgeInsets.symmetric(horizontal: 16, vertical: 10), height: 44, @@ -124,7 +126,10 @@ class _NovelDetailPageState extends State with UniqueTagMixin { child: Consumer( builder: (context, value, child) => Text( _.manager.actionTitle(), - style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w500), ), )), onTap: () => _.gotoPlay(index: _.manager.index), @@ -152,7 +157,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { color: !_.showHeader ? Color(0xff0E141E) : Colors.transparent, child: Row( children: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, child: Image.asset('acg_noval_back.png'.acgImgPath, width: 24), onTap: () => Get.back(), ), @@ -165,7 +171,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { Spacer(), Consumer( builder: (context, manager, child) { - bool col = manager.mediaInfo?.mediaStatus?.hasCollected ?? false; + bool col = + manager.mediaInfo?.mediaStatus?.hasCollected ?? false; return FollowButton( mediaId: manager.mediaInfo?.id ?? '', isFollow: col, @@ -207,7 +214,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { ), ), Spacer(), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => _.episodesBottomSheet(), child: Row( children: [ @@ -241,7 +249,8 @@ class _NovelDetailPageState extends State with UniqueTagMixin { ), itemBuilder: (BuildContext context, int index) { final epm = manager.allEpisodes[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => _.gotoPlay(index: index), child: Column( children: [ @@ -251,18 +260,22 @@ class _NovelDetailPageState extends State with UniqueTagMixin { Text( '第${epm.episodeNumber ?? 1}${_.model?.unit}', style: TextStyle( - color: manager.index == index ? AppColors.actionRed : Color(0xff989898), + color: manager.index == index + ? AppColors.actionRed + : Color(0xff989898), fontSize: 12, fontWeight: FontWeight.w400, ), ), //无任何权限时,前 N 集免费展示「免费」角标 - if (manager.mediaInfo?.hasPermission == false && epm.inFreeEpisode) ...[ + if (manager.mediaInfo?.hasPermission == false && + epm.inFreeEpisode) ...[ 6.sizeBoxW, const FreeBadge(), ], Spacer(), - Icon(Icons.navigate_next_sharp, size: 20, color: Colors.white) + Icon(Icons.navigate_next_sharp, + size: 20, color: Colors.white) ], ), 12.sizeBoxH, diff --git a/lib/hj_page/cartoon/novel_header.dart b/lib/hj_page/cartoon/novel_header.dart index a5a1c34..d5de1a2 100644 --- a/lib/hj_page/cartoon/novel_header.dart +++ b/lib/hj_page/cartoon/novel_header.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../hj_model/cartoon_media_info.dart'; import '../../hj_model/video_model.dart'; @@ -87,17 +87,20 @@ class NovelHeader extends StatelessWidget { children: [ Text( '共${info?.totalEpisode ?? 0}${info?.unit}', - style: textStyle(12, const Color(0xff999999), FontWeight.w400), + style: + textStyle(12, const Color(0xff999999), FontWeight.w400), ), 8.sizeBoxW, Text( '/', - style: textStyle(12, const Color(0xff999999), FontWeight.w400), + style: + textStyle(12, const Color(0xff999999), FontWeight.w400), ), 8.sizeBoxW, Text( info?.updateDesc ?? '', - style: textStyle(12, info!.getDetailUpdateColor, FontWeight.w400), + style: textStyle( + 12, info!.getDetailUpdateColor, FontWeight.w400), ), ], ), @@ -118,10 +121,13 @@ class NovelHeader extends StatelessWidget { runSpacing: 10, maxLines: 1, children: tags - .map((tag) => InkWell(enableFeedback: false, - onTap: () => Get.to(CartoonTagPage(title: tag.name ?? '', sId: tag.id ?? '')), + .map((tag) => InkWell( + enableFeedback: false, + onTap: () => Get.to( + CartoonTagPage(title: tag.name ?? '', sId: tag.id ?? '')), child: Container( - padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12), + padding: + const EdgeInsets.symmetric(vertical: 6, horizontal: 12), decoration: BoxDecoration( color: const Color(0xff22252D), borderRadius: BorderRadius.circular(4), @@ -129,7 +135,8 @@ class NovelHeader extends StatelessWidget { child: Text( '#${tag.name ?? ''}', maxLines: 1, - style: const TextStyle(color: Color(0xFF999999), fontSize: 12), + style: + const TextStyle(color: Color(0xFF999999), fontSize: 12), ), ), )) diff --git a/lib/hj_page/cartoon/photo_gallery_item.dart b/lib/hj_page/cartoon/photo_gallery_item.dart index 51621ae..ffba906 100644 --- a/lib/hj_page/cartoon/photo_gallery_item.dart +++ b/lib/hj_page/cartoon/photo_gallery_item.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/find/pic_collect/pics_detail_page.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/find/pic_collect/pics_detail_page.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/extension/extensions.dart'; //图集item class PhotoGalleryItem extends StatelessWidget { @@ -13,7 +13,8 @@ class PhotoGalleryItem extends StatelessWidget { final Function? callback; final int textline; - const PhotoGalleryItem({super.key, + const PhotoGalleryItem({ + super.key, this.videoModel, this.callback, this.textline = 1, @@ -21,7 +22,8 @@ class PhotoGalleryItem extends StatelessWidget { @override Widget build(BuildContext context) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { if (callback != null) { callback?.call(); diff --git a/lib/hj_page/cartoon/text_novel_read_logic.dart b/lib/hj_page/cartoon/text_novel_read_logic.dart index 4e7bdcb..a04971f 100644 --- a/lib/hj_page/cartoon/text_novel_read_logic.dart +++ b/lib/hj_page/cartoon/text_novel_read_logic.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../hj_model/acg/comic_chapters_model.dart'; import '../../hj_model/cartoon_media_info.dart'; @@ -49,7 +49,8 @@ class TextNovelReadLogic extends GetxController { // ========== 公开方法 ========== // 获取文字小说。返回 Future 不是可有可无:CErrorWidget 靠它做重试 loading 和防连点 - Future loadData({bool showLoading = false, bool needToTop = false}) async { + Future loadData( + {bool showLoading = false, bool needToTop = false}) async { if (showLoading) LoadingHelper.showLoading(); final model = await manager.getComicsMediaContent(index: currentEpisode); if (showLoading) LoadingHelper.dismissLoading(); @@ -89,7 +90,8 @@ class TextNovelReadLogic extends GetxController { final epm = await manager.getEpisodeHasPermisson(realIndex); if (epm == null) return; LoadingHelper.showLoading(); - final model = await ACGService.getMediaDetail(mediaId: manager.mediaInfo?.id, id: id); + final model = + await ACGService.getMediaDetail(mediaId: manager.mediaInfo?.id, id: id); LoadingHelper.dismissLoading(); if (model != null) { currentEpisode = realIndex; diff --git a/lib/hj_page/cartoon/text_novel_read_page.dart b/lib/hj_page/cartoon/text_novel_read_page.dart index abc863f..51c3ec3 100644 --- a/lib/hj_page/cartoon/text_novel_read_page.dart +++ b/lib/hj_page/cartoon/text_novel_read_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/stagger_in_item.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/stagger_in_item.dart'; import '../../tools_base/loading/loading_center_widget.dart'; import 'text_novel_read_logic.dart'; @@ -65,7 +65,8 @@ class TextNovelReadPage extends StatelessWidget { Expanded( child: SingleChildScrollView( controller: logic.scrollCtr, - padding: const EdgeInsets.only(bottom: 60), //给底部菜单栏留位,别被挡住最后几行 + padding: + const EdgeInsets.only(bottom: 60), //给底部菜单栏留位,别被挡住最后几行 child: Align( //正文不足一行时居中(长文自然撑满,看不出差别),与旧版 Column 默认的 center 保持一致 alignment: Alignment.topCenter, @@ -73,7 +74,8 @@ class TextNovelReadPage extends StatelessWidget { logic.detailInfo?.text ?? '', style: TextStyle( fontSize: 16, - color: (logic.isDark ? Colors.white : Colors.black).withValues(alpha: .9), + color: (logic.isDark ? Colors.white : Colors.black) + .withValues(alpha: .9), ), ), ), @@ -98,7 +100,8 @@ class TextNovelReadPage extends StatelessWidget { child: Container( height: height, color: logic.isDark ? Colors.black : Colors.white, - padding: EdgeInsets.only(top: screen.paddingTop + 5, left: 16, right: 16), + padding: + EdgeInsets.only(top: screen.paddingTop + 5, left: 16, right: 16), alignment: Alignment.topCenter, //按钮贴状态栏下沿,余量留在底部 child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -111,7 +114,8 @@ class TextNovelReadPage extends StatelessWidget { Expanded( child: Text( logic.detailInfo?.name ?? '', - style: TextStyle(fontSize: 18, color: fg, fontWeight: FontWeight.w600), + style: TextStyle( + fontSize: 18, color: fg, fontWeight: FontWeight.w600), maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -124,9 +128,12 @@ class TextNovelReadPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 7), child: AnimatedSwitcher( duration: const Duration(milliseconds: 200), - transitionBuilder: (child, anim) => ScaleTransition(scale: anim, child: child), + transitionBuilder: (child, anim) => + ScaleTransition(scale: anim, child: child), child: Image.asset( - logic.isDark ? 'text_sun.png'.acgImgPath : 'text_moon.png'.acgImgPath, + logic.isDark + ? 'text_sun.png'.acgImgPath + : 'text_moon.png'.acgImgPath, // key 按状态区分,AnimatedSwitcher 才会把它当成新 child 触发动画 key: ValueKey(logic.isDark), width: 24, @@ -140,7 +147,8 @@ class TextNovelReadPage extends StatelessWidget { onTap: () => Scaffold.of(ctx).openEndDrawer(), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 7), - child: Image.asset('text_play_menu.png'.acgImgPath, width: 24, color: fg), + child: Image.asset('text_play_menu.png'.acgImgPath, + width: 24, color: fg), ), ), ], @@ -151,7 +159,8 @@ class TextNovelReadPage extends StatelessWidget { // 底部翻章栏,收起时整条移出屏幕下方 Widget _buildFooter(TextNovelReadLogic logic) { - final style = TextStyle(fontSize: 14, color: logic.isDark ? Colors.white : Colors.black); + final style = TextStyle( + fontSize: 14, color: logic.isDark ? Colors.white : Colors.black); return AnimatedPositioned( duration: Duration(milliseconds: logic.durationTime), bottom: logic.showMenu ? 0 : -60, @@ -170,7 +179,8 @@ class TextNovelReadPage extends StatelessWidget { onTap: () => logic.loadOtherEpisode(false, showLoading: true), child: Row( children: [ - Image.asset('text_last.png'.acgImgPath, color: AppColors.actionRed, width: 20, height: 20), + Image.asset('text_last.png'.acgImgPath, + color: AppColors.actionRed, width: 20, height: 20), 12.sizeBoxW, Text('上一章', style: style), ], @@ -183,7 +193,8 @@ class TextNovelReadPage extends StatelessWidget { children: [ Text('下一章', style: style), 12.sizeBoxW, - Image.asset('text_next.png'.acgImgPath, color: AppColors.actionRed, width: 20, height: 20), + Image.asset('text_next.png'.acgImgPath, + color: AppColors.actionRed, width: 20, height: 20), ], ), ), @@ -207,7 +218,10 @@ class TextNovelReadPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( logic.mediaInfo?.title ?? '', - style: TextStyle(fontSize: 16, color: fg.withValues(alpha: .9), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, + color: fg.withValues(alpha: .9), + fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis, ), ), @@ -221,7 +235,10 @@ class TextNovelReadPage extends StatelessWidget { children: [ Text( '共${logic.mediaInfo?.totalEpisode ?? 0}话 ${logic.mediaInfo?.updateDesc ?? ''}', - style: const TextStyle(fontSize: 14, color: Color(0xFF1F2029), fontWeight: FontWeight.w500), + style: const TextStyle( + fontSize: 14, + color: Color(0xFF1F2029), + fontWeight: FontWeight.w500), ), InkWell( enableFeedback: false, @@ -234,12 +251,19 @@ class TextNovelReadPage extends StatelessWidget { turns: logic.isAscend ? 0 : 0.5, duration: const Duration(milliseconds: 250), curve: Curves.easeOutCubic, - child: Image.asset('text_play_sort.png'.acgImgPath, width: 20, color: Color(0xFF1F2029),), + child: Image.asset( + 'text_play_sort.png'.acgImgPath, + width: 20, + color: Color(0xFF1F2029), + ), ), 4.sizeBoxW, Text( logic.isAscend ? '正序' : '倒序', - style: const TextStyle(fontSize: 14, color: Color(0xFF1F2029), fontWeight: FontWeight.w500), + style: const TextStyle( + fontSize: 14, + color: Color(0xFF1F2029), + fontWeight: FontWeight.w500), ), ], ), @@ -252,7 +276,8 @@ class TextNovelReadPage extends StatelessWidget { child: GetBuilder( id: 'list', builder: (_) => ListView.builder( - key: ValueKey(logic.isAscend), // 切换正/倒序时 key 变化→列表重建→item 重新错峰入场 + key: + ValueKey(logic.isAscend), // 切换正/倒序时 key 变化→列表重建→item 重新错峰入场 itemCount: logic.allEpisodes.length, padding: const EdgeInsets.only(top: 6), itemBuilder: (_, index) { @@ -261,7 +286,8 @@ class TextNovelReadPage extends StatelessWidget { return StaggerInItem( index: index, child: InkWell( - enableFeedback: false, //换掉裸 GestureDetector:整行可点,不再只有文字那一小块 + enableFeedback: + false, //换掉裸 GestureDetector:整行可点,不再只有文字那一小块 onTap: () { Get.back(); logic.loadDataWithIndex(info.id ?? ''); @@ -275,8 +301,11 @@ class TextNovelReadPage extends StatelessWidget { '第${info.episodeNumber ?? 1}${logic.mediaInfo?.unit ?? ''}', style: TextStyle( fontSize: 16, - color: select ? AppColors.actionRed : fg.withValues(alpha: .55), - fontWeight: select ? FontWeight.w500 : FontWeight.w400, + color: select + ? AppColors.actionRed + : fg.withValues(alpha: .55), + fontWeight: + select ? FontWeight.w500 : FontWeight.w400, ), maxLines: 1, overflow: TextOverflow.ellipsis, diff --git a/lib/hj_page/cartoon/voice_novel_read_logic.dart b/lib/hj_page/cartoon/voice_novel_read_logic.dart index d33cc8b..516423c 100644 --- a/lib/hj_page/cartoon/voice_novel_read_logic.dart +++ b/lib/hj_page/cartoon/voice_novel_read_logic.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; import 'widget/acg_source_manager.dart'; diff --git a/lib/hj_page/cartoon/voice_novel_read_page.dart b/lib/hj_page/cartoon/voice_novel_read_page.dart index 6630b89..6e6a90a 100644 --- a/lib/hj_page/cartoon/voice_novel_read_page.dart +++ b/lib/hj_page/cartoon/voice_novel_read_page.dart @@ -2,10 +2,10 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/widget_util.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/widget_util.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import 'package:provider/provider.dart'; import 'audio_player_content.dart'; @@ -34,7 +34,8 @@ class VoiceNovelReadPage extends StatefulWidget { // 可重复 push(preventDuplicates: false)+ 间接环 NovelDetail→VoiceNovelRead 可能多实例并存, // 用 UniqueTagMixin 给每个实例分独立 tag 隔离 -class _VoiceNovelReadPageState extends State with UniqueTagMixin { +class _VoiceNovelReadPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -49,9 +50,11 @@ class _VoiceNovelReadPageState extends State with UniqueTagM value: logic.sourceManager, child: Scaffold( appBar: AppBar( - leading: InkWell(enableFeedback: false, + leading: InkWell( + enableFeedback: false, onTap: () => Get.back(), - child: const Icon(Icons.arrow_back_ios, size: 24, color: Colors.white), + child: const Icon(Icons.arrow_back_ios, + size: 24, color: Colors.white), ), centerTitle: false, titleSpacing: -10, @@ -91,17 +94,18 @@ class _VoiceNovelReadPageState extends State with UniqueTagM padding: const EdgeInsets.fromLTRB(16, 18, 16, 12), child: Text( '相关推荐', - style: textStyle(18, Colors.white.withValues(alpha: .9), FontWeight.w600), + style: textStyle( + 18, Colors.white.withValues(alpha: .9), FontWeight.w600), ), ), ), ], body: CartoonRecommendPage( - mediaId: logic.sourceManager.mediaInfo?.tagDetails?.firstOrNull?.id ?? '', + mediaId: + logic.sourceManager.mediaInfo?.tagDetails?.firstOrNull?.id ?? '', padding: const EdgeInsets.only(top: 10), tapAction: () => logic.audioManager.pause(), ), ); } - } diff --git a/lib/hj_page/cartoon/widget/acg_expand_text.dart b/lib/hj_page/cartoon/widget/acg_expand_text.dart index c1b6287..4bcf316 100644 --- a/lib/hj_page/cartoon/widget/acg_expand_text.dart +++ b/lib/hj_page/cartoon/widget/acg_expand_text.dart @@ -1,8 +1,8 @@ //查看更多 import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_utils/widget_util.dart'; @@ -33,7 +33,9 @@ class _AcgShowMoreTextWidgetState extends State { Widget build(BuildContext context) { //用 LayoutBuilder 拿真实约束宽度测量,避免传入的 maxWidth 与实际渲染宽度不符导致"该展开却没按钮" return LayoutBuilder(builder: (context, cons) { - final maxWidth = cons.maxWidth.isFinite ? cons.maxWidth : (widget.maxWidth ?? Get.width); + final maxWidth = cons.maxWidth.isFinite + ? cons.maxWidth + : (widget.maxWidth ?? Get.width); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -41,7 +43,9 @@ class _AcgShowMoreTextWidgetState extends State { SizedBox( width: double.infinity, child: Text( - widget.summary?.isNotEmpty == true ? widget.summary ?? '' : '暂无简介', + widget.summary?.isNotEmpty == true + ? widget.summary ?? '' + : '暂无简介', textAlign: TextAlign.left, style: textStyle(12, widget.txColor, FontWeight.w400), maxLines: _isFold ? widget.maxLine : null, @@ -59,7 +63,8 @@ class _AcgShowMoreTextWidgetState extends State { children: [ Text( _isFold ? '更多简介' : '收起简介', - style: textStyle(12, const Color(0xffEFEFEF), FontWeight.w400), + style: textStyle( + 12, const Color(0xffEFEFEF), FontWeight.w400), ), 2.sizeBoxW, AnimatedRotation( @@ -93,7 +98,8 @@ class _AcgShowMoreTextWidgetState extends State { ); } - bool _textExceedMaxLines(String text, TextStyle style, int maxLine, double maxWidth) { + bool _textExceedMaxLines( + String text, TextStyle style, int maxLine, double maxWidth) { //与 Text 组件保持一致:合并 DefaultTextStyle(letterSpacing/字体等差异会导致测量行数偏少) final effectiveStyle = DefaultTextStyle.of(context).style.merge(style); final painter = TextPainter( diff --git a/lib/hj_page/cartoon/widget/acg_source_manager.dart b/lib/hj_page/cartoon/widget/acg_source_manager.dart index 9de4233..597a75c 100644 --- a/lib/hj_page/cartoon/widget/acg_source_manager.dart +++ b/lib/hj_page/cartoon/widget/acg_source_manager.dart @@ -3,13 +3,13 @@ import 'dart:async'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../alert/video/comic_buy_alert.dart'; import '../../../alert/video/vip_acg_dialog.dart'; @@ -44,7 +44,9 @@ class ACGSourceManager extends ChangeNotifier { final liked = mediaInfo?.mediaStatus?.hasLiked ?? false; final mid = mediaInfo?.id ?? ''; final type = mediaInfo?.mediaType ?? ''; - final suc = liked ? await CommonService.cancelLike(mid, type) : await CommonService.sendLike(mid, type); + final suc = liked + ? await CommonService.cancelLike(mid, type) + : await CommonService.sendLike(mid, type); LoadingHelper.dismissLoading(); if (suc) { mediaInfo?.mediaStatus?.hasLiked = !liked; @@ -94,7 +96,8 @@ class ACGSourceManager extends ChangeNotifier { final list = result.list ?? []; // 每页拉到就按集号标免费集(与播放放行/角标同一口径),避免全部拉完才标导致角标迟到 for (final e in list) { - e.inFreeEpisode = mediaInfo?.isFreeEpisodeNumber(e.episodeNumber) ?? false; + e.inFreeEpisode = + mediaInfo?.isFreeEpisodeNumber(e.episodeNumber) ?? false; } allEpisodes.addAll(list); notifyListeners(); @@ -146,7 +149,8 @@ class ACGSourceManager extends ChangeNotifier { } /// 拉漫画章节详情(带缓存 + 权限校验) - Future getComicsMediaContent({int index = 0, bool showLoading = false}) async { + Future getComicsMediaContent( + {int index = 0, bool showLoading = false}) async { final cached = mediaContentCache[index]; if (cached != null) { changeEpisodesIndex(index); // 命中缓存也要同步当前章,否则退回详情页「续看」还停在旧章 @@ -244,9 +248,11 @@ class AudioPlayerManager { double playSpeed = 1; void initPlayer() { - if (_audioPlayer != null) return; // 防重入:已初始化则跳过,避免 5 个 stream 监听重复注册、旧 sub 泄漏 + if (_audioPlayer != null) + return; // 防重入:已初始化则跳过,避免 5 个 stream 监听重复注册、旧 sub 泄漏 _audioPlayer = AudioPlayer(); - _audioPlayer?.setReleaseMode(playMod == AudioPlayMod.loop ? ReleaseMode.loop : ReleaseMode.stop); + _audioPlayer?.setReleaseMode( + playMod == AudioPlayMod.loop ? ReleaseMode.loop : ReleaseMode.stop); _audioDurationSub = _audioPlayer?.onDurationChanged.listen((event) { audioValue.value = AudioPlayerValue.copyWith(value..duration = event); @@ -270,7 +276,8 @@ class AudioPlayerManager { audioValue.value = AudioPlayerValue.copyWith(value..isPlaying = true); break; case PlayerState.paused: - audioValue.value = AudioPlayerValue.copyWith(value..isPlaying = false); + audioValue.value = + AudioPlayerValue.copyWith(value..isPlaying = false); break; default: break; @@ -292,7 +299,8 @@ class AudioPlayerManager { audioValue.value = AudioPlayerValue.copyWith(value..isPlaying = true); }); - audioValue.value = AudioPlayerValue.copyWith(value..isInitialized = _audioPlayer != null); + audioValue.value = + AudioPlayerValue.copyWith(value..isInitialized = _audioPlayer != null); } void setPlaySpeed(double speed) { @@ -355,9 +363,11 @@ class AudioPlayerManager { } void setPlayMod(AudioPlayMod mod) { - _audioPlayer?.setReleaseMode(mod == AudioPlayMod.loop ? ReleaseMode.loop : ReleaseMode.stop); + _audioPlayer?.setReleaseMode( + mod == AudioPlayMod.loop ? ReleaseMode.loop : ReleaseMode.stop); playMod = mod; - audioValue.value = AudioPlayerValue.copyWith(value..isLooping = mod == AudioPlayMod.loop); + audioValue.value = + AudioPlayerValue.copyWith(value..isLooping = mod == AudioPlayMod.loop); } Future playWithIndex(int index) async { diff --git a/lib/hj_page/cartoon/widget/cartoon_subset_alert.dart b/lib/hj_page/cartoon/widget/cartoon_subset_alert.dart index 7b48b80..1b05378 100644 --- a/lib/hj_page/cartoon/widget/cartoon_subset_alert.dart +++ b/lib/hj_page/cartoon/widget/cartoon_subset_alert.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/acg/comic_chapters_model.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; -import 'package:hgmj/tools_base/widget/stagger_in_item.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/acg/comic_chapters_model.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/tools_base/widget/stagger_in_item.dart'; import 'acg_source_manager.dart'; import 'free_badge.dart'; @@ -63,7 +63,8 @@ class _CartoonSubSetAlertState extends State { 16.sizeBoxW, const Text( '漫画列表', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), ), 10.sizeBoxW, const Spacer(), @@ -117,13 +118,16 @@ class _CartoonSubSetAlertState extends State { //与详情/阅读抽屉子集 title 一致:第X话(CartoonDetailPage 只处理 image,恒为漫画) '第${info.episodeNumber ?? ''}${mediaInfo?.unit ?? ''}', style: TextStyle( - color: sel ? Colors.white.withValues(alpha: .9) : Colors.white.withValues(alpha: .45), + color: sel + ? Colors.white.withValues(alpha: .9) + : Colors.white.withValues(alpha: .45), fontSize: 16, fontWeight: FontWeight.w400, ), ), //无任何权限时,前 N 集免费展示「免费」角标 - if (mediaInfo?.hasPermission == false && info.inFreeEpisode) ...[ + if (mediaInfo?.hasPermission == false && + info.inFreeEpisode) ...[ 8.sizeBoxW, const FreeBadge(), ], diff --git a/lib/hj_page/comment/cell/comment_item.dart b/lib/hj_page/comment/cell/comment_item.dart index 5747ff4..8774860 100644 --- a/lib/hj_page/comment/cell/comment_item.dart +++ b/lib/hj_page/comment/cell/comment_item.dart @@ -2,26 +2,26 @@ import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/comment/comment_model.dart'; -import 'package:hgmj/hj_model/comment/reply_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/cell/reply_comment_item.dart'; -import 'package:hgmj/hj_utils/api_service/comment_service.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/comment/comment_model.dart'; +import 'package:wydj/hj_model/comment/reply_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/cell/reply_comment_item.dart'; +import 'package:wydj/hj_utils/api_service/comment_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:like_button/like_button.dart'; import '../../../tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../home/widget/user_avatar.dart'; import '../../home/widget/user_name_view.dart'; import '../widget/comment_rich_text.dart'; import '../widget/comment_top_banner.dart'; -import 'package:hgmj/hj_model/banner/comment_top_banner_model.dart'; +import 'package:wydj/hj_model/banner/comment_top_banner_model.dart'; /// 一条评论:头像 + 昵称 + 正文(可带图) + 时间/点赞/回复 + 折叠的回复列表 class CommentItem extends StatefulWidget { @@ -93,7 +93,8 @@ class _CommentItemState extends State { ), if ((comment.vipLevel ?? 0) > 0) ...[ 4.sizeBoxW, - Image.asset("vip_v.webp".commentPath, width: 16), + Image.asset("vip_v.webp".commentPath, + width: 16), ] ], ), @@ -108,11 +109,13 @@ class _CommentItemState extends State { margin: EdgeInsets.only(top: 6), alignment: Alignment.centerLeft, constraints: BoxConstraints(maxWidth: 150), - child: NetworkImageLoader(imageUrl: comment.image ?? ""), + child: NetworkImageLoader( + imageUrl: comment.image ?? ""), ), ), // 置顶评论配置 Banner(多图轮播,支持 GIF / 内外链) - if (widget.topBanners?.isNotEmpty == true) CommentTopBanner(banners: widget.topBanners!), + if (widget.topBanners?.isNotEmpty == true) + CommentTopBanner(banners: widget.topBanners!), 8.sizeBoxH, Row( children: [ @@ -124,7 +127,8 @@ class _CommentItemState extends State { ), ), const Spacer(), - if (!comment.isOfficial && !comment.isHideLikeOrComment) ...[ + if (!comment.isOfficial && + !comment.isHideLikeOrComment) ...[ ValueListenableBuilder( valueListenable: isLikedNof, builder: (context, value, child) => Row( @@ -134,7 +138,9 @@ class _CommentItemState extends State { onTap: (_) => _toggleLike(), size: 20, likeBuilder: (isLiked) { - return Image.asset(isLiked ? 'like_red.webp'.commentPath : 'like_white.webp'.commentPath); + return Image.asset(isLiked + ? 'like_red.webp'.commentPath + : 'like_white.webp'.commentPath); }, ), Text( @@ -149,15 +155,18 @@ class _CommentItemState extends State { ), 12.sizeBoxW, GestureDetector( - onTap: () => widget.replyHandler?.call(comment), - child: Image.asset('msg_icon.png'.commentPath, width: 20), + onTap: () => + widget.replyHandler?.call(comment), + child: Image.asset('msg_icon.png'.commentPath, + width: 20), ), ], ], ), _replyList(), // 展开更多评论 - if ((comment.replies?.length ?? 0) > 0) _moreReplyBar(), + if ((comment.replies?.length ?? 0) > 0) + _moreReplyBar(), ], ), ), @@ -192,7 +201,11 @@ class _CommentItemState extends State { children: [ Container(width: 20, height: 1, color: const Color(0xff989898)), 4.sizeBoxW, - Text(text, style: const TextStyle(fontSize: 12, color: Color(0xff989898), fontWeight: FontWeight.w500)), + Text(text, + style: const TextStyle( + fontSize: 12, + color: Color(0xff989898), + fontWeight: FontWeight.w500)), 2.sizeBoxW, isUp ? Transform.rotate(angle: pi, child: chevron) : chevron, ], @@ -250,8 +263,8 @@ class _CommentItemState extends State { if (comment.hasMoreReply ?? false) { final curTime = DateTimeUtil.format2utc(DateTime.now()); final fastId = comment.replies!.first.id ?? ''; - final result = - await CommentService.getReplyList(widget.objId, comment.id ?? '', curTime, comment.replyPage ?? _page, 5, fastId); + final result = await CommentService.getReplyList(widget.objId, + comment.id ?? '', curTime, comment.replyPage ?? _page, 5, fastId); comment.hasMoreReply = result?.hasNext ?? false; comment.replies?.addAll(result?.list ?? []); if (result?.hasNext == true) { @@ -296,7 +309,8 @@ class _CommentItemState extends State { length, (i) => ReplyCommentItem( replies[i], - replyHandler: (reply) => widget.replyHandler?.call(comment, reply: reply), + replyHandler: (reply) => + widget.replyHandler?.call(comment, reply: reply), ), ), ); diff --git a/lib/hj_page/comment/cell/reply_comment_item.dart b/lib/hj_page/comment/cell/reply_comment_item.dart index d4478ce..6a53770 100644 --- a/lib/hj_page/comment/cell/reply_comment_item.dart +++ b/lib/hj_page/comment/cell/reply_comment_item.dart @@ -1,15 +1,15 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:like_button/like_button.dart'; import '../../../hj_model/comment/reply_model.dart'; import '../../../hj_utils/api_service/common_service.dart'; import '../../../tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../user_center_page/user_center_page.dart'; /// 评论下的一条回复:小头像 + 「A ▸ B」 + 正文(可带图) + 时间/点赞/回复 @@ -81,7 +81,8 @@ class _ReplyCommentItemState extends State { 3.sizeBoxW, Text( reply.toUserName ?? '', - style: TextStyle(color: Color(0x73FFFFFF), fontSize: 14), + style: + TextStyle(color: Color(0x73FFFFFF), fontSize: 14), ), ] ], @@ -111,7 +112,8 @@ class _ReplyCommentItemState extends State { children: [ Text( reply.createdAt?.utcToAgo() ?? "", - style: const TextStyle(color: Color(0x73FFFFFF), fontSize: 12), + style: const TextStyle( + color: Color(0x73FFFFFF), fontSize: 12), ), const Spacer(), ValueListenableBuilder( @@ -123,7 +125,9 @@ class _ReplyCommentItemState extends State { onTap: (_) => _toggleLike(), size: 20, likeBuilder: (isLiked) { - return Image.asset(isLiked ? 'like_red.webp'.commentPath : 'like_white.webp'.commentPath); + return Image.asset(isLiked + ? 'like_red.webp'.commentPath + : 'like_white.webp'.commentPath); }, ), Text( @@ -139,7 +143,8 @@ class _ReplyCommentItemState extends State { 12.sizeBoxW, GestureDetector( onTap: () => widget.replyHandler?.call(reply), - child: Image.asset('msg_icon.png'.commentPath, width: 20), + child: + Image.asset('msg_icon.png'.commentPath, width: 20), ), ], ), diff --git a/lib/hj_page/comment/comment_alert.dart b/lib/hj_page/comment/comment_alert.dart index 0b17488..283078d 100644 --- a/lib/hj_page/comment/comment_alert.dart +++ b/lib/hj_page/comment/comment_alert.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'comment_views.dart'; @@ -35,7 +35,10 @@ Future showCommentDialog( padding: const EdgeInsets.only(left: 16, bottom: 16), child: Text( "${commentCount ?? 0}条评论", - style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 14), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 14), ), ), Expanded( diff --git a/lib/hj_page/comment/comment_input_view.dart b/lib/hj_page/comment/comment_input_view.dart index 18c4691..d7a0367 100644 --- a/lib/hj_page/comment/comment_input_view.dart +++ b/lib/hj_page/comment/comment_input_view.dart @@ -3,10 +3,10 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/group_text_filed.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/group_text_filed.dart'; /// 评论输入弹层:点空白关闭,自动聚焦拉起键盘 class CommentInputView extends StatefulWidget { @@ -125,19 +125,24 @@ class _CommentInputViewState extends State { controller: textCtr, height: 32, padding: EdgeInsets.symmetric(horizontal: 16), - textStyle: TextStyle(color: Colors.white, fontSize: 14), + textStyle: + TextStyle(color: Colors.white, fontSize: 14), onSubmitted: (value) { Get.back(result: true); }, placeholder: widget.hint ?? '请在此输入评论...', - placeholderTextStyle: TextStyle(color: Color(0xff4D4D4D), fontSize: 14), - decoration: BoxDecoration(color: Color(0xff1A1A1A), borderRadius: BorderRadius.circular(40)), + placeholderTextStyle: TextStyle( + color: Color(0xff4D4D4D), fontSize: 14), + decoration: BoxDecoration( + color: Color(0xff1A1A1A), + borderRadius: BorderRadius.circular(40)), ), ), ), 12.sizeBoxW, Padding( - padding: const EdgeInsets.only(right: 12, top: 4, bottom: 4), + padding: const EdgeInsets.only( + right: 12, top: 4, bottom: 4), child: GestureDetector( onTap: _pickImage, child: Image.asset( diff --git a/lib/hj_page/comment/comment_mixin.dart b/lib/hj_page/comment/comment_mixin.dart index 608f98c..b7c5f3c 100644 --- a/lib/hj_page/comment/comment_mixin.dart +++ b/lib/hj_page/comment/comment_mixin.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/comment/comment_model.dart'; -import 'package:hgmj/hj_model/comment/reply_model.dart'; -import 'package:hgmj/hj_page/comment/comment_input_view.dart'; -import 'package:hgmj/hj_utils/api_service/comment_service.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/comment/comment_model.dart'; +import 'package:wydj/hj_model/comment/reply_model.dart'; +import 'package:wydj/hj_page/comment/comment_input_view.dart'; +import 'package:wydj/hj_utils/api_service/comment_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../hj_model/banner/comment_top_banner_model.dart'; @@ -49,7 +49,8 @@ mixin CommentMixin on GetxController { String? sendImagePath; if (selectedImagePath.value?.isNotEmpty == true) { try { - ImageUploadResultModel? imgResult = await FileUploadTool().uploadImage(selectedImagePath.value!); + ImageUploadResultModel? imgResult = + await FileUploadTool().uploadImage(selectedImagePath.value!); sendImagePath = imgResult?.coverImg ?? ""; if (sendImagePath.isEmpty) { isSendingMsg.value = false; @@ -102,8 +103,10 @@ mixin CommentMixin on GetxController { showToast('已提交,审核通过后将展示'); hintText = null; //插在第一条普通评论前面,置顶那几条不动 - final insertIndex = comments.indexWhere((e) => !e.isHideLikeOrComment); - comments.insert(insertIndex == -1 ? comments.length : insertIndex, res); + final insertIndex = + comments.indexWhere((e) => !e.isHideLikeOrComment); + comments.insert( + insertIndex == -1 ? comments.length : insertIndex, res); } update(); } @@ -116,7 +119,8 @@ mixin CommentMixin on GetxController { } // isSend: true 点击了发送按钮, 如果没有发送内容弹键盘, 有内容直接发送 - readyReplyComment(CommentModel? comment, {ReplyModel? replyModel, bool? isSend}) async { + readyReplyComment(CommentModel? comment, + {ReplyModel? replyModel, bool? isSend}) async { replyComment = comment; replyCommentModel = replyModel; if (replyModel != null) { @@ -156,7 +160,8 @@ mixin CommentMixin on GetxController { page = 1; } final currentT = DateTimeUtil.format2utc(DateTime.now()) ?? ""; - final result = await CommentService.getCommentList(id, currentT, page, 20); + final result = + await CommentService.getCommentList(id, currentT, page, 20); totalCallback?.call(result?.total ?? 0); refreshCtr?.refreshCompleted(); refreshCtr?.loadComplete(); diff --git a/lib/hj_page/comment/comment_views.dart b/lib/hj_page/comment/comment_views.dart index e8dac13..06abb5f 100644 --- a/lib/hj_page/comment/comment_views.dart +++ b/lib/hj_page/comment/comment_views.dart @@ -1,11 +1,11 @@ import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/cell/comment_item.dart'; -import 'package:hgmj/hj_page/comment/comment_mixin.dart'; -import 'package:hgmj/hj_page/comment/widget/comment_foot_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/cell/comment_item.dart'; +import 'package:wydj/hj_page/comment/comment_mixin.dart'; +import 'package:wydj/hj_page/comment/widget/comment_foot_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../home/widget/quick_search_view.dart'; @@ -41,7 +41,6 @@ class CommentLogic extends GetxController with CommentMixin { isLoading = false; fetchComments(objId); } - } class CommentView extends StatelessWidget { @@ -63,7 +62,10 @@ class CommentView extends StatelessWidget { @override Widget build(BuildContext context) { return GetBuilder( - init: CommentLogic(objId, commentType: objType, totalCallback: totalCallback, vModel: videoModel), + init: CommentLogic(objId, + commentType: objType, + totalCallback: totalCallback, + vModel: videoModel), tag: objId, builder: (logic) => LayoutBuilder(builder: (_, cons) { if (cons.maxHeight < 58) return SizedBox.shrink(); @@ -84,7 +86,10 @@ class CommentView extends StatelessWidget { child: Container( padding: EdgeInsets.only(bottom: 12), margin: EdgeInsets.fromLTRB(12, 0, 12, 12), - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Color(0x08ffffff)))), + decoration: BoxDecoration( + border: Border( + bottom: + BorderSide(color: Color(0x08ffffff)))), child: QuickSearchView(logic.quickSearchList), ), ), @@ -92,15 +97,19 @@ class CommentView extends StatelessWidget { itemCount: logic.comments.length, itemBuilder: (BuildContext context, int index) { final topIndex = logic.topPinnedCommentIndex; - final showBanner = index == topIndex && logic.commentTopBanners.isNotEmpty; + final showBanner = index == topIndex && + logic.commentTopBanners.isNotEmpty; return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: CommentItem( key: ValueKey(logic.comments[index].id), logic.comments[index], objId: objId, - topBanners: showBanner ? logic.commentTopBanners : null, - replyHandler: (comment, {reply}) => logic.readyReplyComment(comment, replyModel: reply), + topBanners: + showBanner ? logic.commentTopBanners : null, + replyHandler: (comment, {reply}) => + logic.readyReplyComment(comment, + replyModel: reply), ), ); }, @@ -114,7 +123,8 @@ class CommentView extends StatelessWidget { Obx( () => CommentFootView( isSending: logic.isSendingMsg.value, - onComment: (isSend) => logic.readyReplyComment(null, isSend: isSend), + onComment: (isSend) => + logic.readyReplyComment(null, isSend: isSend), textCtr: logic.commentController, imgPath: logic.selectedImagePath.value, onImgChange: (value) => logic.selectedImagePath.value = value, diff --git a/lib/hj_page/comment/widget/comment_foot_view.dart b/lib/hj_page/comment/widget/comment_foot_view.dart index 94c578c..cce9f32 100644 --- a/lib/hj_page/comment/widget/comment_foot_view.dart +++ b/lib/hj_page/comment/widget/comment_foot_view.dart @@ -4,14 +4,14 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/group_text_filed.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/group_text_filed.dart'; import '../../../hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../mine/collec_history_buy/col_his_buy_sub_page.dart'; /// 底部评论条:假输入框 + 选图 + 收藏 + 发送 @@ -50,7 +50,8 @@ class _CommentFootViewState extends State { selectCount: 1, showCamera: false, ); - if (listMedia.isNotEmpty) widget.onImgChange?.call(listMedia.first.path ?? ''); + if (listMedia.isNotEmpty) + widget.onImgChange?.call(listMedia.first.path ?? ''); if (mounted) setState(() {}); } @@ -60,7 +61,8 @@ class _CommentFootViewState extends State { try { final preCollect = isCollect; - await MineService.postCollect(widget.video?.id, LoadDataType.post.apiType, !isCollect); + await MineService.postCollect( + widget.video?.id, LoadDataType.post.apiType, !isCollect); if (!preCollect) { widget.video?.collectCount = (widget.video?.collectCount ?? 0) + 1; @@ -82,100 +84,106 @@ class _CommentFootViewState extends State { Widget build(BuildContext context) { return Container( color: Colors.black, - padding: EdgeInsets.only(left: 18.w, right: 18.w, bottom: screen.paddingBottom), + padding: EdgeInsets.only( + left: 18.w, right: 18.w, bottom: screen.paddingBottom), alignment: Alignment.centerLeft, child: SizedBox( height: 58, child: Row( - children: [ - Expanded( - child: GestureDetector( - onTap: () => widget.onComment(false), - child: Container( - padding: EdgeInsets.symmetric(vertical: 2), - child: GroupTextFiled( - controller: widget.textCtr, - height: 32, - enabled: false, - padding: EdgeInsets.symmetric(horizontal: 16), - textStyle: TextStyle(color: Colors.white, fontSize: 14), - placeholder: '请在此输入评论...', - placeholderTextStyle: TextStyle(color: Color(0xff525252), fontSize: 14), - decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1), borderRadius: BorderRadius.circular(16)), + children: [ + Expanded( + child: GestureDetector( + onTap: () => widget.onComment(false), + child: Container( + padding: EdgeInsets.symmetric(vertical: 2), + child: GroupTextFiled( + controller: widget.textCtr, + height: 32, + enabled: false, + padding: EdgeInsets.symmetric(horizontal: 16), + textStyle: TextStyle(color: Colors.white, fontSize: 14), + placeholder: '请在此输入评论...', + placeholderTextStyle: + TextStyle(color: Color(0xff525252), fontSize: 14), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .1), + borderRadius: BorderRadius.circular(16)), + ), ), ), ), - ), - 12.sizeBoxW, - Stack( - children: [ + 12.sizeBoxW, + Stack( + children: [ + Container( + margin: EdgeInsets.fromLTRB(0, 4, 4, 4), + width: 30, + height: 30, + alignment: Alignment.center, + child: GestureDetector( + onTap: _pickImage, + child: widget.imgPath?.isNotEmpty == true + ? Image.file( + File(widget.imgPath!), + width: 30, + height: 30, + fit: BoxFit.cover, + ) + : Image.asset( + 'icon_pic.webp'.commentPath, + width: 24, + height: 24, + ), + ), + ), + if (widget.imgPath?.isNotEmpty == true) + Positioned( + top: 0, + right: 0, + child: GestureDetector( + onTap: () { + widget.onImgChange?.call(null); + setState(() {}); + }, + child: Image.asset( + "close_grey.png".commonImgPath, + width: 12, + height: 12, + ), + ), + ), + ], + ), + if (widget.showCollect) Container( - margin: EdgeInsets.fromLTRB(0, 4, 4, 4), width: 30, height: 30, alignment: Alignment.center, - child: GestureDetector( - onTap: _pickImage, - child: widget.imgPath?.isNotEmpty == true - ? Image.file( - File(widget.imgPath!), - width: 30, - height: 30, - fit: BoxFit.cover, - ) - : Image.asset( - 'icon_pic.webp'.commentPath, - width: 24, - height: 24, - ), - ), - ), - if (widget.imgPath?.isNotEmpty == true) - Positioned( - top: 0, - right: 0, - child: GestureDetector( - onTap: () { - widget.onImgChange?.call(null); - setState(() {}); - }, - child: Image.asset( - "close_grey.png".commonImgPath, - width: 12, - height: 12, - ), + child: InkWell( + enableFeedback: false, + onTap: _onCollect, + child: Image.asset( + isCollect + ? "collect_red.png".commonImgPath + : "collect_path.png".commonImgPath, + width: 24, ), ), - ], - ), - if (widget.showCollect) - Container( + ), + SizedBox( width: 30, height: 30, - alignment: Alignment.center, - child: InkWell( - enableFeedback: false, - onTap: _onCollect, - child: Image.asset( - isCollect ? "collect_red.png".commonImgPath : "collect_path.png".commonImgPath, - width: 24, - ), + child: GestureDetector( + onTap: () => widget.onComment(true), + child: widget.isSending + ? CupertinoActivityIndicator( + color: AppColors.actionRed, + radius: 12, + ) + : Image.asset('ic_send.webp'.commentPath), ), - ), - SizedBox( - width: 30, - height: 30, - child: GestureDetector( - onTap: () => widget.onComment(true), - child: widget.isSending - ? CupertinoActivityIndicator( - color: AppColors.actionRed, - radius: 12, - ) - : Image.asset('ic_send.webp'.commentPath), - ), - ) - ], + ) + ], ), ), ); diff --git a/lib/hj_page/comment/widget/comment_rich_text.dart b/lib/hj_page/comment/widget/comment_rich_text.dart index d51cf4e..d540dca 100644 --- a/lib/hj_page/comment/widget/comment_rich_text.dart +++ b/lib/hj_page/comment/widget/comment_rich_text.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/comment/comment_model.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/hj_model/comment/comment_model.dart'; +import 'package:wydj/routers/jump_router.dart'; /// 评论正文:命中搜索词时把该词渲染成可点的橙色链接,其余按纯文本 class CommentRichText extends StatelessWidget { @@ -13,8 +13,11 @@ class CommentRichText extends StatelessWidget { const style = TextStyle(color: Color(0xE5FFFFFF), fontSize: 14); final keyword = model?.searchKeyword ?? ""; //按关键词切开,段与段之间插链接;切不出两段就当纯文本 - final parts = keyword.isEmpty ? [] : (model?.content?.split(keyword) ?? []); - if (model?.linkStr?.isNotEmpty != true || keyword.isEmpty || parts.length <= 1) { + final parts = + keyword.isEmpty ? [] : (model?.content?.split(keyword) ?? []); + if (model?.linkStr?.isNotEmpty != true || + keyword.isEmpty || + parts.length <= 1) { return Text(model?.content ?? '', style: style); } return Text.rich( @@ -29,7 +32,8 @@ class CommentRichText extends StatelessWidget { onTap: () => pushToPageByLink(model?.linkStr), child: Text( keyword, - style: const TextStyle(color: Color(0xffF68804), fontSize: 14, height: 1.2), + style: const TextStyle( + color: Color(0xffF68804), fontSize: 14, height: 1.2), ), ), ), diff --git a/lib/hj_page/comment/widget/comment_top_banner.dart b/lib/hj_page/comment/widget/comment_top_banner.dart index 2853ef2..627c703 100644 --- a/lib/hj_page/comment/widget/comment_top_banner.dart +++ b/lib/hj_page/comment/widget/comment_top_banner.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/banner/comment_top_banner_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; -import 'package:hgmj/tools_base/widget/card_swiper/src/swiper.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/banner/comment_top_banner_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/tools_base/widget/card_swiper/src/swiper.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// 评论区置顶评论下方 Banner:支持多图轮播(含 GIF),按 linkType 跳转内外链 class CommentTopBanner extends StatefulWidget { final List banners; final double borderRadius; + /// 宽高比,默认对齐站内 Banner 素材 720×150;勿用固定高度,窄/宽屏 cover 会裁切 final double aspectRatio; diff --git a/lib/hj_page/community/community/community_module_logic.dart b/lib/hj_page/community/community/community_module_logic.dart index 5b6ca5c..d2b79b4 100644 --- a/lib/hj_page/community/community/community_module_logic.dart +++ b/lib/hj_page/community/community/community_module_logic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; +import 'package:wydj/config/config.dart'; import '../../main_page/provider/bottom_bar_provider.dart'; class CommunityMainModuleLogic extends GetxController diff --git a/lib/hj_page/community/community/community_module_page.dart b/lib/hj_page/community/community/community_module_page.dart index 70e3099..fd6d574 100644 --- a/lib/hj_page/community/community/community_module_page.dart +++ b/lib/hj_page/community/community/community_module_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../tools_base/indicator/custom_tab_indicator.dart'; import '../../../tools_base/loading/loading_center_widget.dart'; @@ -28,15 +28,24 @@ class CommunityModulePage extends StatelessWidget { labelPadding: EdgeInsets.zero, padding: EdgeInsets.zero, tabAlignment: TabAlignment.start, - indicator: CustomIndicator(width: 16, height: 2, offsetY: 6, color: Color(0xFFFFC000)), + indicator: CustomIndicator( + width: 16, + height: 2, + offsetY: 6, + color: Color(0xFFFFC000)), indicatorWeight: 1, - unselectedLabelStyle: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 16), - labelStyle: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 16, fontWeight: FontWeight.w500), + unselectedLabelStyle: TextStyle( + color: Colors.white.withValues(alpha: .9), fontSize: 16), + labelStyle: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 16, + fontWeight: FontWeight.w500), isScrollable: true, tabs: logic.modules .map( (e) => Padding( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 13.h), + padding: EdgeInsets.symmetric( + horizontal: 16.w, vertical: 13.h), child: Text(e.moduleName ?? ''), ), ) @@ -55,7 +64,8 @@ class CommunityModulePage extends StatelessWidget { model: value, index: key, cancelCallBack: () { - logic.tabController.index = logic.tabController.previousIndex; + logic.tabController.index = + logic.tabController.previousIndex; }, ).keepAlive, ), diff --git a/lib/hj_page/community/community/community_tab_logic.dart b/lib/hj_page/community/community/community_tab_logic.dart index 15b4970..f85fcec 100644 --- a/lib/hj_page/community/community/community_tab_logic.dart +++ b/lib/hj_page/community/community/community_tab_logic.dart @@ -2,12 +2,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_model/home/plate_model.dart'; @@ -21,7 +21,8 @@ class CommunityTabLogic extends GetxController { CommunityTabLogic(this.model, {this.index = 0}); RefreshController? refreshController; - late ScrollController sctrl = CommunityBottomProvider().scrollCtr(MediaStyle.Community, index); + late ScrollController sctrl = + CommunityBottomProvider().scrollCtr(MediaStyle.Community, index); int page = 1; bool isLoading = true; @@ -60,7 +61,8 @@ class CommunityTabLogic extends GetxController { @override void onInit() { super.onInit(); - _collectStatusSub = eventBus.on(_onCollectStatusChanged); + _collectStatusSub = + eventBus.on(_onCollectStatusChanged); } @override @@ -91,7 +93,8 @@ class CommunityTabLogic extends GetxController { sctrl.jumpTo(0); } - Future fetchPagedata({bool isRefresh = true, bool needLoading = false}) async { + Future fetchPagedata( + {bool isRefresh = true, bool needLoading = false}) async { if (isRefresh) { page = 1; } @@ -110,19 +113,24 @@ class CommunityTabLogic extends GetxController { dataSource.clear(); refreshController?.refreshCompleted(); } - (res?.hasNext ?? false) ? refreshController?.loadComplete() : refreshController?.loadNoData(); + (res?.hasNext ?? false) + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.allVideoInfo ?? []); if ((res?.allSection?.isNotEmpty ?? false) && specials.isEmpty) { specials.addAll(res!.allSection?.firstOrNull?.allTags ?? []); if (model?.defaultTagId?.isNotEmpty == true) { - tagIndex = specials.indexWhere((element) => element.id == model?.defaultTagId); + tagIndex = specials + .indexWhere((element) => element.id == model?.defaultTagId); } } page += 1; } catch (e) { // 接口异常兜底:结束刷新/加载态,避免 loading、下拉/上拉指示器卡死 debugLog(e); - isRefresh ? refreshController?.refreshCompleted() : refreshController?.loadComplete(); + isRefresh + ? refreshController?.refreshCompleted() + : refreshController?.loadComplete(); } finally { isLoading = false; update(); diff --git a/lib/hj_page/community/community/community_tab_page.dart b/lib/hj_page/community/community/community_tab_page.dart index 3e96a42..26ec107 100644 --- a/lib/hj_page/community/community/community_tab_page.dart +++ b/lib/hj_page/community/community/community_tab_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../../hj_model/home/plate_model.dart'; import '../../../hj_model/video_model.dart'; @@ -14,7 +14,7 @@ import '../../../tools_base/widget/net_image_widget.dart'; import '../widget/community_middle_header.dart'; import '../widget/community_post_widget.dart'; import 'community_tab_logic.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; class CommunityTabPage extends StatelessWidget { final ModuleData model; @@ -36,40 +36,40 @@ class CommunityTabPage extends StatelessWidget { builder: (logic) { return pullYsRefresh( onInit: (ctr) => logic.refreshController = ctr, - onRefresh: (_) => logic.fetchPagedata(), - onLoading: (_) => logic.fetchPagedata(isRefresh: false), - child: CustomScrollView( - controller: logic.sctrl, - slivers: [ - if (model.pureVersion != true) - SliverToBoxAdapter( - child: AdsGridView( - 7, - autoStyle: true, - padding: EdgeInsets.fromLTRB(16.w, 0, 16.w, 10.h), - ), - ), + onRefresh: (_) => logic.fetchPagedata(), + onLoading: (_) => logic.fetchPagedata(isRefresh: false), + child: CustomScrollView( + controller: logic.sctrl, + slivers: [ + if (model.pureVersion != true) SliverToBoxAdapter( - child: _buildSpecialView(logic), - ), - SliverPersistentHeader( - pinned: true, - floating: true, - delegate: MySliverDelegate( - maxHeight: 34, - minHeight: 34, - child: CommunityMiddleHeader( - sortOnTap: (sort) { - logic.sort = sort; - logic.fetchPagedata(needLoading: true); - }, - ), + child: AdsGridView( + 7, + autoStyle: true, + padding: EdgeInsets.fromLTRB(16.w, 0, 16.w, 10.h), ), ), - _buildTableView(logic), - ], - ), - ); + SliverToBoxAdapter( + child: _buildSpecialView(logic), + ), + SliverPersistentHeader( + pinned: true, + floating: true, + delegate: MySliverDelegate( + maxHeight: 34, + minHeight: 34, + child: CommunityMiddleHeader( + sortOnTap: (sort) { + logic.sort = sort; + logic.fetchPagedata(needLoading: true); + }, + ), + ), + ), + _buildTableView(logic), + ], + ), + ); }, ); } @@ -88,7 +88,8 @@ class CommunityTabPage extends StatelessWidget { itemCount: logic.specials.length, shrinkWrap: true, itemBuilder: (BuildContext context, int index) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => logic.changeSpecialsIndex(index), child: _buildSpecialTagCell(logic, index), ); @@ -124,7 +125,9 @@ class CommunityTabPage extends StatelessWidget { height: double.infinity, ), Container( - decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: Colors.black.withValues(alpha: .6)), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: Colors.black.withValues(alpha: .6)), ), if (model.hotMark?.isNotEmpty == true) Positioned( @@ -162,12 +165,20 @@ class CommunityTabPage extends StatelessWidget { Text( "${model.tagName}", style: TextStyle( - color: logic.tagIndex == index ? AppColors.actionRed : Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + color: logic.tagIndex == index + ? AppColors.actionRed + : Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), ), 2.sizeBoxH, Text( "${model.videoCount?.countStr}个帖子", - style: TextStyle(color: logic.tagIndex == index ? AppColors.actionRed : Colors.white, fontSize: 12), + style: TextStyle( + color: logic.tagIndex == index + ? AppColors.actionRed + : Colors.white, + fontSize: 12), ), ], ), diff --git a/lib/hj_page/community/community_main_page_page/community_main_logic.dart b/lib/hj_page/community/community_main_page_page/community_main_logic.dart index 10009e4..17dd455 100644 --- a/lib/hj_page/community/community_main_page_page/community_main_logic.dart +++ b/lib/hj_page/community/community_main_page_page/community_main_logic.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/const.dart'; import '../../main_page/main_logic.dart'; import '../../main_page/provider/bottom_bar_provider.dart'; -class CommunityMainLogic extends GetxController with GetTickerProviderStateMixin { +class CommunityMainLogic extends GetxController + with GetTickerProviderStateMixin { final int index; CommunityMainLogic({this.index = 0}); @@ -30,13 +31,18 @@ class CommunityMainLogic extends GetxController with GetTickerProviderStateMixin ]; // tab 顺序对应的媒体类型:社区/色图/小说 - static const List _tabTypes = [MediaStyle.Community, MediaStyle.Pic, MediaStyle.Novel]; + static const List _tabTypes = [ + MediaStyle.Community, + MediaStyle.Pic, + MediaStyle.Novel + ]; late TabController tabCtr; @override void onInit() { - tabCtr = TabController(length: tabs.length, vsync: this, initialIndex: index); + tabCtr = + TabController(length: tabs.length, vsync: this, initialIndex: index); tabCtr.addListener(() { if (tabCtr.indexIsChanging) return; CommunityBottomProvider().communityType = _tabTypes[tabCtr.index]; diff --git a/lib/hj_page/community/community_main_page_page/community_main_page.dart b/lib/hj_page/community/community_main_page_page/community_main_page.dart index a7288cd..93763c1 100644 --- a/lib/hj_page/community/community_main_page_page/community_main_page.dart +++ b/lib/hj_page/community/community_main_page_page/community_main_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../config/config.dart'; import '../../cartoon/cartoon_sub_module_page.dart'; @@ -25,7 +25,8 @@ class CommunityMainPage extends StatefulWidget { } } -class CommunityMainPageState extends State with SingleTickerProviderStateMixin { +class CommunityMainPageState extends State + with SingleTickerProviderStateMixin { @override void initState() { super.initState(); @@ -37,7 +38,8 @@ class CommunityMainPageState extends State with SingleTickerP //提前加载图片资源 precacheImage(AssetImage('community_main_sel.png'.communityPath), context); precacheImage(AssetImage('community_pic_sel.png'.communityPath), context); - precacheImage(AssetImage('community_chatgroup_sel.png'.communityPath), context); + precacheImage( + AssetImage('community_chatgroup_sel.png'.communityPath), context); precacheImage(AssetImage('community_noval_sel.png'.communityPath), context); } @@ -56,7 +58,8 @@ class CommunityMainPageState extends State with SingleTickerP Row( children: [ Expanded(child: _buildTabbar(_)), - if (Config.signIcon != null && Config.signIcon!.isNotEmpty) ...[ + if (Config.signIcon != null && + Config.signIcon!.isNotEmpty) ...[ InkWell( enableFeedback: false, onTap: () => Get.to(SignDailyPage()), @@ -85,7 +88,8 @@ class CommunityMainPageState extends State with SingleTickerP children: [ //社区 CommunityModulePage( - defaultIndex: widget.index == 0 ? widget.subTabIndex : 0, + defaultIndex: + widget.index == 0 ? widget.subTabIndex : 0, ).keepAlive, //图集 CartoonSubModulePage( diff --git a/lib/hj_page/community/community_tag_page/community_tag_logic.dart b/lib/hj_page/community/community_tag_page/community_tag_logic.dart index b8f98ce..6f3d144 100644 --- a/lib/hj_page/community/community_tag_page/community_tag_logic.dart +++ b/lib/hj_page/community/community_tag_page/community_tag_logic.dart @@ -2,16 +2,18 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/tag_service.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/tag_service.dart'; -class CommunityTagLogic extends GetxController with GetTickerProviderStateMixin { +class CommunityTagLogic extends GetxController + with GetTickerProviderStateMixin { final scrollCtr = ScrollController(); double? offset; bool isPinned = false; TagsBean model; StreamController showAppCtr = StreamController.broadcast(); - late final TabController mainTabCtr = TabController(length: sorts.length, vsync: this); + late final TabController mainTabCtr = + TabController(length: sorts.length, vsync: this); RxBool isLoadingFollow = false.obs; final sorts = [2, 1, 5]; //排序类型 1:最新上架 2:最多收藏 3:本月最热 4:最多观看 diff --git a/lib/hj_page/community/community_tag_page/community_tag_page.dart b/lib/hj_page/community/community_tag_page/community_tag_page.dart index d1bea78..60fba5b 100644 --- a/lib/hj_page/community/community_tag_page/community_tag_page.dart +++ b/lib/hj_page/community/community_tag_page/community_tag_page.dart @@ -2,12 +2,12 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../tools_base/widget/follow_button.dart'; @@ -23,7 +23,6 @@ class UserCenterSortTypeEvent { } class CommunityTagDetailPage extends StatefulWidget { - final TagsBean model; const CommunityTagDetailPage({super.key, required this.model}); @@ -32,7 +31,8 @@ class CommunityTagDetailPage extends StatefulWidget { State createState() => _CommunityTagDetailPageState(); } -class _CommunityTagDetailPageState extends State with UniqueTagMixin { +class _CommunityTagDetailPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -44,7 +44,8 @@ class _CommunityTagDetailPageState extends State with Un children: [ ExtendedNestedScrollView( controller: controller.scrollCtr, - pinnedHeaderSliverHeightBuilder: () => AppBar().preferredSize.height + screen.paddingTop, + pinnedHeaderSliverHeightBuilder: () => + AppBar().preferredSize.height + screen.paddingTop, headerSliverBuilder: (_, istop) { return [ SliverAppBar( @@ -73,7 +74,9 @@ class _CommunityTagDetailPageState extends State with Un controller: controller.mainTabCtr, children: controller.sorts .map( - (e) => TagDetailSubView(tag: controller.model, postSort: e).keepAlive, + (e) => TagDetailSubView( + tag: controller.model, postSort: e) + .keepAlive, ) .toList(), ), @@ -98,7 +101,9 @@ class _CommunityTagDetailPageState extends State with Un GestureDetector( onTap: () => Get.back(), child: Image.asset( - isTop ? 'common_back.png'.commonImgPath : 'back_circle.png'.commonImgPath, + isTop + ? 'common_back.png'.commonImgPath + : 'back_circle.png'.commonImgPath, width: 24, height: 24, ), @@ -127,7 +132,8 @@ class _CommunityTagDetailPageState extends State with Un mediaId: controller.model.id, isFollow: controller.model.hasCollected ?? false, followType: FollowEnum.tag, - onSuccess: (success) => controller.model.hasCollected = success, + onSuccess: (success) => + controller.model.hasCollected = success, ), ), ] else ...[ diff --git a/lib/hj_page/community/community_tag_page/subviews/tag_detail_sub_controller.dart b/lib/hj_page/community/community_tag_page/subviews/tag_detail_sub_controller.dart index 5acca03..bfca41a 100644 --- a/lib/hj_page/community/community_tag_page/subviews/tag_detail_sub_controller.dart +++ b/lib/hj_page/community/community_tag_page/subviews/tag_detail_sub_controller.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/tag_service.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/tag_service.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../home/widget/collect_status_wrapper.dart'; @@ -42,7 +42,8 @@ abstract class TagDetailSubController extends GetxController { @override void onInit() { super.onInit(); - _collectStatusSub = eventBus.on(_onCollectStatusChanged); + _collectStatusSub = + eventBus.on(_onCollectStatusChanged); } @override @@ -81,7 +82,9 @@ abstract class TagDetailSubController extends GetxController { page += 1; isLoading = false; update(); - res?.hasNext ?? false ? controller?.loadComplete() : controller?.loadNoData(); + res?.hasNext ?? false + ? controller?.loadComplete() + : controller?.loadNoData(); } } @@ -119,7 +122,8 @@ class TagCOVERController extends TagDetailSubController { T instanceController(TagsBean tag, {int? postSort}) { // Type 对象比较,避免 release 混淆下类名字符串匹配失败导致 throw→灰屏 - if (T == TagCOVERController) return TagCOVERController(tag, postSort: postSort) as T; + if (T == TagCOVERController) + return TagCOVERController(tag, postSort: postSort) as T; if (T == TagSPController) return TagSPController(tag) as T; if (T == TagVideoController) return TagVideoController(tag) as T; throw '$T 没有对应类型'; diff --git a/lib/hj_page/community/community_tag_page/subviews/tag_detail_subview.dart b/lib/hj_page/community/community_tag_page/subviews/tag_detail_subview.dart index 986fc79..ccc1985 100644 --- a/lib/hj_page/community/community_tag_page/subviews/tag_detail_subview.dart +++ b/lib/hj_page/community/community_tag_page/subviews/tag_detail_subview.dart @@ -1,16 +1,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../../home/home_cell_style/video_simple_cell.dart'; import '../../widget/community_post_widget.dart'; import 'tag_detail_sub_controller.dart'; -class TagDetailSubView extends StatelessWidget { +class TagDetailSubView + extends StatelessWidget { final TagsBean tag; final int? postSort; @@ -25,7 +26,8 @@ class TagDetailSubView extends StatelessWidget builder: (controller) { if (controller.isLoading) return LoadingCenterWidget(); return pullYsRefresh( - onLoading: (refreshController) => controller.fetchPageData(isRefresh: false), + onLoading: (refreshController) => + controller.fetchPageData(isRefresh: false), onRefresh: (refreshController) => controller.fetchPageData(), child: () { if (controller.dataSource.isEmpty) return CErrorWidget(); diff --git a/lib/hj_page/community/group_chat/alert/group_buy_bottom_sheet.dart b/lib/hj_page/community/group_chat/alert/group_buy_bottom_sheet.dart index 4c1d100..8c8bbf5 100644 --- a/lib/hj_page/community/group_chat/alert/group_buy_bottom_sheet.dart +++ b/lib/hj_page/community/group_chat/alert/group_buy_bottom_sheet.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/pay/pay_manager.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/pay/pay_manager.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:provider/provider.dart'; import '../model/im_group_list_model.dart'; @@ -32,7 +32,8 @@ class _GroupBuyBottomSheetState extends State { Widget build(BuildContext context) { return Consumer( builder: (_, store, __) { - final enough = (store.wallet?.amount ?? 0) >= (widget.groupModel.price ?? 0); + final enough = + (store.wallet?.amount ?? 0) >= (widget.groupModel.price ?? 0); return _buildNormal(enough, store); }, ); @@ -76,7 +77,8 @@ class _GroupBuyBottomSheetState extends State { children: [ Text( '${widget.groupModel.price ?? 0} 金币', - style: TextStyle(color: AppColors.actionRed, fontSize: 14), + style: + TextStyle(color: AppColors.actionRed, fontSize: 14), ), ], ), @@ -107,7 +109,8 @@ class _GroupBuyBottomSheetState extends State { ), ), 12.sizeBoxW, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => pushToWalletPage(tabPosition: 1), child: Text( '充值', @@ -137,8 +140,13 @@ class _GroupBuyBottomSheetState extends State { ), alignment: Alignment.center, child: Text( - enough ? '${widget.groupModel.price ?? 0} 金币/立即支付' : '余额不足,前往充值', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + enough + ? '${widget.groupModel.price ?? 0} 金币/立即支付' + : '余额不足,前往充值', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/hj_page/community/group_chat/detail/soul_group_detail_logic.dart b/lib/hj_page/community/group_chat/detail/soul_group_detail_logic.dart index 99a2a68..515f3c7 100644 --- a/lib/hj_page/community/group_chat/detail/soul_group_detail_logic.dart +++ b/lib/hj_page/community/group_chat/detail/soul_group_detail_logic.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../../hj_utils/api_service/group_service.dart'; @@ -47,7 +47,9 @@ class GroupChatDetailLogic extends GetxController { msgList?.clear(); } msgList?.addAll(retResp.list ?? []); - retResp.hasNext == true ? refreshController?.loadComplete() : refreshController?.loadNoData(); + retResp.hasNext == true + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); } catch (e) { debugLog(e); refreshController?.loadComplete(); @@ -57,7 +59,9 @@ class GroupChatDetailLogic extends GetxController { } Future readySendMsg({bool? isSend}) async { - if (isSend == true && (textEditController.text.isNotEmpty || selectedImagePath.value?.isNotEmpty == true)) { + if (isSend == true && + (textEditController.text.isNotEmpty || + selectedImagePath.value?.isNotEmpty == true)) { // 点击发送按钮有内容,直接发送内容, 否则弹出输入框 sendMsgEvent(); } else { @@ -82,7 +86,8 @@ class GroupChatDetailLogic extends GetxController { } Future sendMsgEvent() async { - if (textEditController.text.isEmpty && selectedImagePath.value?.isNotEmpty != true) { + if (textEditController.text.isEmpty && + selectedImagePath.value?.isNotEmpty != true) { showToast("请输入消息内容"); return; } @@ -91,7 +96,8 @@ class GroupChatDetailLogic extends GetxController { String? sendImagePath; if (selectedImagePath.value?.isNotEmpty == true) { try { - ImageUploadResultModel? imgResult = await FileUploadTool().uploadImage(selectedImagePath.value!); + ImageUploadResultModel? imgResult = + await FileUploadTool().uploadImage(selectedImagePath.value!); sendImagePath = imgResult?.coverImg ?? ""; if (sendImagePath.isEmpty) { isSendingMsg.value = false; @@ -106,13 +112,15 @@ class GroupChatDetailLogic extends GetxController { } } try { - var ret = await GroupService.sendMessage(model.groupId, textEditController.text, sendImagePath); + var ret = await GroupService.sendMessage( + model.groupId, textEditController.text, sendImagePath); if (ret.isSuccess) { textEditController.text = ""; selectedImagePath.value = null; showToast("消息已发送"); if (ret.data is Map && (ret.data['message'] is Map)) { - IMMessageModel sendModel = IMMessageModel.fromJson(ret.data['message']); + IMMessageModel sendModel = + IMMessageModel.fromJson(ret.data['message']); sendModel.portrait = globalStore.meInfo?.portrait; sendModel.name = globalStore.meInfo?.name; msgList?.insert(0, sendModel); diff --git a/lib/hj_page/community/group_chat/detail/soul_group_detail_page.dart b/lib/hj_page/community/group_chat/detail/soul_group_detail_page.dart index 5717ba8..5dc68df 100644 --- a/lib/hj_page/community/group_chat/detail/soul_group_detail_page.dart +++ b/lib/hj_page/community/group_chat/detail/soul_group_detail_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/comment/widget/comment_foot_view.dart'; +import 'package:wydj/hj_page/comment/widget/comment_foot_view.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../model/im_group_list_model.dart'; import 'soul_group_detail_logic.dart'; diff --git a/lib/hj_page/community/group_chat/detail/widget/chat_item_cell.dart b/lib/hj_page/community/group_chat/detail/widget/chat_item_cell.dart index 5d76563..cd4731d 100644 --- a/lib/hj_page/community/group_chat/detail/widget/chat_item_cell.dart +++ b/lib/hj_page/community/group_chat/detail/widget/chat_item_cell.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../../../tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../model/im_message_resp.dart'; class ChatItemCell extends StatefulWidget { @@ -87,7 +87,8 @@ class _ChatItemCellState extends State { SizedBox(height: 10), if (widget.model?.content?.isNotEmpty == true) Container( - padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + padding: EdgeInsets.symmetric( + horizontal: 20, vertical: 10), margin: EdgeInsets.only(top: 5), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.05), @@ -106,7 +107,8 @@ class _ChatItemCellState extends State { ), ), if (isImg) - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { _showImageScan(widget.model?.image ?? ""); }, @@ -155,7 +157,8 @@ class _ChatItemCellState extends State { SizedBox(height: 10), if (widget.model?.content?.isNotEmpty == true) Container( - padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), + padding: EdgeInsets.symmetric( + horizontal: 20, vertical: 10), margin: EdgeInsets.only(top: 5), decoration: BoxDecoration( color: Color(0xff1DC194), @@ -174,7 +177,8 @@ class _ChatItemCellState extends State { ), ), if (isImg) - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { _showImageScan(widget.model?.image ?? ""); }, diff --git a/lib/hj_page/community/group_chat/group_chat_logic.dart b/lib/hj_page/community/group_chat/group_chat_logic.dart index 1e340f7..061af90 100644 --- a/lib/hj_page/community/group_chat/group_chat_logic.dart +++ b/lib/hj_page/community/group_chat/group_chat_logic.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_utils/api_service/group_service.dart'; @@ -33,7 +33,9 @@ class GroupChatLogic extends GetxController { groupList?.clear(); } groupList?.addAll(retResp?.list ?? []); - retResp?.hasNext == true ? refreshController?.loadComplete() : refreshController?.loadNoData(); + retResp?.hasNext == true + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); } catch (e) { debugLog(e); refreshController?.loadComplete(); diff --git a/lib/hj_page/community/group_chat/group_chat_page.dart b/lib/hj_page/community/group_chat/group_chat_page.dart index 2cd31d7..0100f5a 100644 --- a/lib/hj_page/community/group_chat/group_chat_page.dart +++ b/lib/hj_page/community/group_chat/group_chat_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/main_page/provider/bottom_bar_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_page/main_page/provider/bottom_bar_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'group_chat_logic.dart'; import 'widget/chat_group_cell.dart'; @@ -23,7 +23,8 @@ class GroupChatPage extends StatelessWidget { onRefresh: (ctr) => logic.refreshData(), onLoading: (ctr) => logic.loadMoreData(), child: CustomScrollView( - controller: CommunityBottomProvider().scrollCtr(MediaStyle.GroupChat, 0), + controller: + CommunityBottomProvider().scrollCtr(MediaStyle.GroupChat, 0), slivers: [ SliverToBoxAdapter( child: AdsGridView( @@ -45,7 +46,8 @@ class GroupChatPage extends StatelessWidget { ) else SliverList.builder( - itemBuilder: (ctx, index) => ChatGroupCell(logic.groupList![index]), + itemBuilder: (ctx, index) => + ChatGroupCell(logic.groupList![index]), itemCount: logic.groupList!.length, ), ], diff --git a/lib/hj_page/community/group_chat/widget/chat_group_cell.dart b/lib/hj_page/community/group_chat/widget/chat_group_cell.dart index 48217c8..c44299d 100644 --- a/lib/hj_page/community/group_chat/widget/chat_group_cell.dart +++ b/lib/hj_page/community/group_chat/widget/chat_group_cell.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; import '../../../../alert/mine/vip_level_dialog.dart'; import '../../../../assets_tool/app_colors.dart'; @@ -13,7 +13,7 @@ import '../../../../tools_base/widget/header_widget.dart'; import '../alert/group_buy_bottom_sheet.dart'; import '../detail/soul_group_detail_page.dart'; import '../model/im_group_list_model.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; class ChatGroupCell extends StatefulWidget { final IMGroupItemModel model; @@ -45,7 +45,8 @@ class _ChatGroupCellState extends State { } else if (status == 1) { Get.to(GroupChatDetailPage(model)); } else if (status == 2) { - var ret = await Get.bottomSheet(GroupBuyBottomSheet(groupModel: widget.model)); + var ret = await Get.bottomSheet( + GroupBuyBottomSheet(groupModel: widget.model)); if (ret == true) { Get.to(GroupChatDetailPage(model)); } @@ -69,7 +70,8 @@ class _ChatGroupCellState extends State { color: Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(6), ), - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: _addGroupEvent, child: Row( children: [ @@ -88,7 +90,10 @@ class _ChatGroupCellState extends State { children: [ Text( model.name ?? '', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500), ), 2.sizeBoxH, Text( @@ -116,7 +121,9 @@ class _ChatGroupCellState extends State { width: 52, height: 24, alignment: Alignment.center, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: AppColors.actionRed), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + color: AppColors.actionRed), child: Text( '加入群聊', style: TextStyle( diff --git a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_cover_content.dart b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_cover_content.dart index aab4a5d..cbdad57 100644 --- a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_cover_content.dart +++ b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_cover_content.dart @@ -3,16 +3,16 @@ import 'dart:ui'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/video/video_player_alert.dart'; -import 'package:hgmj/hj_utils/pay/pay_manager.dart'; -import 'package:hgmj/hj_utils/buy_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/widget_util.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/video/video_player_alert.dart'; +import 'package:wydj/hj_utils/pay/pay_manager.dart'; +import 'package:wydj/hj_utils/buy_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/widget_util.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../../../alert/video/vip_acg_dialog.dart'; import '../../../../assets_tool/app_colors.dart'; @@ -34,7 +34,8 @@ class _PostDetailVideoContentState extends State { @override Widget build(BuildContext context) { final isPlayable = model.isVideo() || model.isSeedPost(); - if (!isPlayable || model.sourceURL?.isNotEmpty != true) return const SizedBox.shrink(); + if (!isPlayable || model.sourceURL?.isNotEmpty != true) + return const SizedBox.shrink(); final isLocked = needPostCoin(model); //非免费区的金币帖走金币解锁,其余走 VIP 解锁 @@ -54,8 +55,12 @@ class _PostDetailVideoContentState extends State { child: Stack( alignment: Alignment.center, children: [ - NetworkImageLoader(imageUrl: model.cover ?? '', width: double.infinity, height: double.infinity), - Image.asset('circle_play.webp'.videoPath, width: 30, height: 30), + NetworkImageLoader( + imageUrl: model.cover ?? '', + width: double.infinity, + height: double.infinity), + Image.asset('circle_play.webp'.videoPath, + width: 30, height: 30), //未解锁蒙层 if (isLocked) Positioned.fill( @@ -89,11 +94,17 @@ class _PostDetailVideoContentState extends State { '你只需花费 $coins 金币', defaultStyle: textStyle(16, Colors.white, FontWeight.w400), patternList: [ - EasyRichTextPattern(targetString: '$coins', style: textStyle(16, AppColors.actionRed, FontWeight.w400)), + EasyRichTextPattern( + targetString: '$coins', + style: textStyle(16, AppColors.actionRed, FontWeight.w400)), ], ), 16.sizeBoxH, - const Text('即可解锁继续查看', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w400)), + const Text('即可解锁继续查看', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w400)), 16.sizeBoxH, _btn( '立即解锁', @@ -120,7 +131,11 @@ class _PostDetailVideoContentState extends State { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text('本视频需开通VIP免费观看', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w400)), + const Text('本视频需开通VIP免费观看', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w400)), 16.sizeBoxH, Row( mainAxisAlignment: MainAxisAlignment.center, @@ -160,7 +175,9 @@ class _PostDetailVideoContentState extends State { width: width, height: 30, alignment: Alignment.center, - decoration: BoxDecoration(gradient: LinearGradient(colors: colors), borderRadius: BorderRadius.circular(15)), + decoration: BoxDecoration( + gradient: LinearGradient(colors: colors), + borderRadius: BorderRadius.circular(15)), child: Text(text, style: textStyle(12, textColor, FontWeight.w400)), ), ); @@ -192,7 +209,8 @@ class PostDetailCoverContent extends StatelessWidget { @override Widget build(BuildContext context) { //有视频源时封面已在视频区展示,这里剔除避免重复 - if (model.sourceURL?.isNotEmpty == true) model.seriesCover?.remove(model.cover); + if (model.sourceURL?.isNotEmpty == true) + model.seriesCover?.remove(model.cover); final covers = model.seriesCover ?? []; return Column( children: [ @@ -206,7 +224,11 @@ class PostDetailCoverContent extends StatelessWidget { onTap: () => ImageBrowserPage.open(covers, index: index), child: ClipRRect( borderRadius: _radius(index, covers.length), - child: NetworkImageLoader(imageUrl: url, width: double.infinity, fit: BoxFit.fill, borderRadius: 0), + child: NetworkImageLoader( + imageUrl: url, + width: double.infinity, + fit: BoxFit.fill, + borderRadius: 0), ), ), ], @@ -219,8 +241,10 @@ class PostDetailCoverContent extends StatelessWidget { BorderRadius _radius(int index, int total) { const radius = Radius.circular(12); if (total == 1) return const BorderRadius.all(radius); - if (index == 0) return const BorderRadius.only(topLeft: radius, topRight: radius); - if (index == total - 1) return const BorderRadius.only(bottomLeft: radius, bottomRight: radius); + if (index == 0) + return const BorderRadius.only(topLeft: radius, topRight: radius); + if (index == total - 1) + return const BorderRadius.only(bottomLeft: radius, bottomRight: radius); return BorderRadius.zero; } } diff --git a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_operation_view.dart b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_operation_view.dart index 45b34fb..e1cd3ab 100644 --- a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_operation_view.dart +++ b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_operation_view.dart @@ -3,14 +3,14 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../../alert/video/share_media_dialog.dart'; import '../../../mine/collec_history_buy/col_his_buy_sub_page.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; /// 帖子详情操作栏:浏览量 / 点赞 / 评论 / 分享 class PostDetailOperationView extends StatefulWidget { @@ -19,7 +19,8 @@ class PostDetailOperationView extends StatefulWidget { const PostDetailOperationView({super.key, required this.model}); @override - State createState() => _PostDetailOperationViewState(); + State createState() => + _PostDetailOperationViewState(); } class _PostDetailOperationViewState extends State { @@ -46,7 +47,9 @@ class _PostDetailOperationViewState extends State { behavior: HitTestBehavior.translucent, onTap: _toggleLike, child: _iconLabel( - icon: model.vidStatus?.hasLiked == true ? "like_red.png".commonImgPath : "like_empty_gray.png".communityPath, + icon: model.vidStatus?.hasLiked == true + ? "like_red.png".commonImgPath + : "like_empty_gray.png".communityPath, gap: 5.w, text: model.likeCount?.countOr("喜欢") ?? '', fontSize: 12.sp, @@ -103,8 +106,10 @@ class _PostDetailOperationViewState extends State { final wasLiked = model.vidStatus?.hasLiked ?? false; final count = model.likeCount ?? 0; final res = wasLiked - ? await CommonService.cancelLike(model.id ?? '', LoadDataType.post.apiType) - : await CommonService.sendLike(model.id ?? '', LoadDataType.post.apiType); + ? await CommonService.cancelLike( + model.id ?? '', LoadDataType.post.apiType) + : await CommonService.sendLike( + model.id ?? '', LoadDataType.post.apiType); if (!res || !mounted) return; model.vidStatus?.hasLiked = !wasLiked; model.likeCount = max(0, count + (wasLiked ? -1 : 1)); diff --git a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_unlock_dialog.dart b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_unlock_dialog.dart index 58a7fdd..254bbb8 100644 --- a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_unlock_dialog.dart +++ b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_unlock_dialog.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/pay/pay_manager.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/pay/pay_manager.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; /// 帖子金币解锁弹窗:解锁成功回传 true,点空白关闭交给 barrier class PostDetailUnlockDialog extends StatelessWidget { @@ -32,7 +32,10 @@ class PostDetailUnlockDialog extends StatelessWidget { decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(30)), gradient: LinearGradient( - colors: [Color.fromRGBO(255, 238, 220, 1), Color.fromRGBO(249, 219, 191, 1)], + colors: [ + Color.fromRGBO(255, 238, 220, 1), + Color.fromRGBO(249, 219, 191, 1) + ], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), @@ -40,10 +43,14 @@ class PostDetailUnlockDialog extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Image.asset('post_detail_coin.png'.communityPath, width: 30, height: 30), + Image.asset('post_detail_coin.png'.communityPath, + width: 30, height: 30), Text( '${model.videoCoin()}金币解锁继续', - style: const TextStyle(color: Color(0xff370000), fontSize: 14, fontWeight: FontWeight.w400), + style: const TextStyle( + color: Color(0xff370000), + fontSize: 14, + fontWeight: FontWeight.w400), ), ], ), diff --git a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_word_content.dart b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_word_content.dart index 94dcc31..ec5c31a 100644 --- a/lib/hj_page/community/post_detail_page/detail_widget/post_detail_word_content.dart +++ b/lib/hj_page/community/post_detail_page/detail_widget/post_detail_word_content.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; import '../../../../tools_base/richTextParsing/html_parser.dart'; import '../../../../tools_base/widget/shrink_wrap.dart'; @@ -24,7 +24,8 @@ class GameDetailWordContent extends StatelessWidget { children: [ const Text('游戏介绍', style: TextStyle(color: Colors.white, fontSize: 16)), 18.sizeBoxH, - Text(model.content ?? '', style: const TextStyle(color: Colors.white, fontSize: 16)), + Text(model.content ?? '', + style: const TextStyle(color: Colors.white, fontSize: 16)), ], ); } @@ -39,14 +40,17 @@ class PostDetailWordContent extends StatelessWidget { @override Widget build(BuildContext context) { if (model.newsType == 'ADULT_GAME') return const SizedBox.shrink(); - final contentStyle = TextStyle(color: const Color(0xFFDCDCDC), fontSize: 14.sp); + final contentStyle = + TextStyle(color: const Color(0xFFDCDCDC), fontSize: 14.sp); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 14.sizeBoxH, //标题 if (model.title?.isNotEmpty == true) - Padding(padding: EdgeInsets.only(bottom: 1.h), child: Text(model.title ?? '', style: contentStyle)), + Padding( + padding: EdgeInsets.only(bottom: 1.h), + child: Text(model.title ?? '', style: contentStyle)), //标签 _tags(), 12.h.sizeBoxH, @@ -56,7 +60,9 @@ class PostDetailWordContent extends StatelessWidget { if (model.richText?.isNotEmpty == true) _richText() else if (model.content?.isNotEmpty == true) - Padding(padding: EdgeInsets.only(bottom: 18.h), child: Text(model.content ?? '', style: contentStyle)), + Padding( + padding: EdgeInsets.only(bottom: 18.h), + child: Text(model.content ?? '', style: contentStyle)), ], ); } @@ -91,8 +97,12 @@ class PostDetailWordContent extends StatelessWidget { child: Container( padding: const EdgeInsets.fromLTRB(8, 3, 8, 3), margin: const EdgeInsets.only(right: 6), - decoration: BoxDecoration(color: const Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(3)), - child: Text('#${e.name}', style: const TextStyle(color: Color(0x8CFFFFFF), fontSize: 12)), + decoration: BoxDecoration( + color: const Color(0x0DFFFFFF), + borderRadius: BorderRadius.circular(3)), + child: Text('#${e.name}', + style: const TextStyle( + color: Color(0x8CFFFFFF), fontSize: 12)), ), )) .toList(), diff --git a/lib/hj_page/community/post_detail_page/detail_widget/post_resource_info_widget.dart b/lib/hj_page/community/post_detail_page/detail_widget/post_resource_info_widget.dart index 5d8c7f6..238f88e 100644 --- a/lib/hj_page/community/post_detail_page/detail_widget/post_resource_info_widget.dart +++ b/lib/hj_page/community/post_detail_page/detail_widget/post_resource_info_widget.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../../hj_model/video_model.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'post_detail_unlock_dialog.dart'; /// 种子帖 / 黄游帖的资源信息与下载入口 @@ -31,28 +31,36 @@ class _PostResourceInfoWidgetState extends State { final me = globalStore.meInfo; //金币视频限免期内:全场免费 或 50 金币以内免费 final isFreeTime = DateTimeUtil.calTime3(me?.goldVideoFreeExpire) > 0; - if (isFreeTime && (me?.allGoldVideoFree == true || (model.coins ?? 0) < 50)) return false; - return model.isCoinVideo() && !globalStore.isMe(model.publisher?.uid) && !(model.vidStatus?.hasPaid ?? false); + if (isFreeTime && (me?.allGoldVideoFree == true || (model.coins ?? 0) < 50)) + return false; + return model.isCoinVideo() && + !globalStore.isMe(model.publisher?.uid) && + !(model.vidStatus?.hasPaid ?? false); } - String get _buyDesc => _needLock ? '${model.realCoins ?? 0}金币解锁 即可下载种子' : '开通VIP 即可下载种子'; + String get _buyDesc => + _needLock ? '${model.realCoins ?? 0}金币解锁 即可下载种子' : '开通VIP 即可下载种子'; @override Widget build(BuildContext context) { final isSeed = model.newsType == 'SEED_LINK'; if (!isSeed && model.newsType != 'ADULT_GAME') return const SizedBox(); - const descStyle = TextStyle(color: Color(0xff999999), fontSize: 14, height: 1.5); + const descStyle = + TextStyle(color: Color(0xff999999), fontSize: 14, height: 1.5); //未解锁、或非 VIP 的非免费区内容,都只能看解锁入口 - final isLocked = _needLock || (!globalStore.isVIP && model.freeArea != true); + final isLocked = + _needLock || (!globalStore.isVIP && model.freeArea != true); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ //种子帖的影片信息与下载说明 if (isSeed) ...[ - if ((model.seedSize ?? 0) > 0) Text('[影片大小]:${model.seedSizeDesc}', style: descStyle), - if ((model.seedPlayTime ?? 0) > 0) Text('[影片时长]:${model.seedPlayTimeDesc}', style: descStyle), + if ((model.seedSize ?? 0) > 0) + Text('[影片大小]:${model.seedSizeDesc}', style: descStyle), + if ((model.seedPlayTime ?? 0) > 0) + Text('[影片时长]:${model.seedPlayTimeDesc}', style: descStyle), const Text( '[下载说明]:解锁后请复制种子的下载链接到手机自带浏览器(谷歌/UC/夸克/火狐 等)打开!或使用BT软件(迅雷/Vuze/uTorrent/BitTorrent 等)进行下载.', style: descStyle, @@ -68,13 +76,17 @@ class _PostResourceInfoWidgetState extends State { onTap: _showUnlock, child: Text( _buyDesc, - style: const TextStyle(fontSize: 16, color: AppColors.primaryHighColor, fontWeight: FontWeight.w500), + style: const TextStyle( + fontSize: 16, + color: AppColors.primaryHighColor, + fontWeight: FontWeight.w500), ), ) : InkWell( enableFeedback: false, onTap: _copyLink, - child: Image.asset('link_copy_icon.webp'.communityPath, width: 180, height: 32), + child: Image.asset('link_copy_icon.webp'.communityPath, + width: 180, height: 32), ), ), ], diff --git a/lib/hj_page/community/post_detail_page/post_detail_logic.dart b/lib/hj_page/community/post_detail_page/post_detail_logic.dart index 15e5e4f..2c91e2d 100644 --- a/lib/hj_page/community/post_detail_page/post_detail_logic.dart +++ b/lib/hj_page/community/post_detail_page/post_detail_logic.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/comment_mixin.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/comment_mixin.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; import '../../../hj_utils/history_util.dart'; import 'post_detail_page.dart'; diff --git a/lib/hj_page/community/post_detail_page/post_detail_page.dart b/lib/hj_page/community/post_detail_page/post_detail_page.dart index 1211ce5..f14cb91 100644 --- a/lib/hj_page/community/post_detail_page/post_detail_page.dart +++ b/lib/hj_page/community/post_detail_page/post_detail_page.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/cell/comment_item.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/cell/comment_item.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../comment/widget/comment_foot_view.dart'; import '../../home/widget/quick_search_view.dart'; @@ -21,18 +21,20 @@ import 'post_detail_logic.dart'; /// 过滤掉广告位,只留真实帖子 List? _filters(List? videoModel) { - return (videoModel ?? []).where((e) => !e.isRandomAd() && !e.isAdsArr()).toList(); + return (videoModel ?? []) + .where((e) => !e.isRandomAd() && !e.isAdsArr()) + .toList(); } class PostDetailPageArgument { final List? videoModels; String? id; - PostDetailPageArgument({List? models, this.id}) : videoModels = _filters(models); + PostDetailPageArgument({List? models, this.id}) + : videoModels = _filters(models); } class PostDetailPage extends StatefulWidget { - final PostDetailPageArgument argument; const PostDetailPage({super.key, required this.argument}); @@ -55,7 +57,10 @@ class _PostDetailPageState extends State with UniqueTagMixin { final topIndex = logic.topPinnedCommentIndex; return Scaffold( resizeToAvoidBottomInset: false, - appBar: AppBar(titleSpacing: 18.w, automaticallyImplyLeading: false, title: _titleView(logic)), + appBar: AppBar( + titleSpacing: 18.w, + automaticallyImplyLeading: false, + title: _titleView(logic)), body: logic.isLoading || model == null ? SizedBox(height: 300, child: LoadingCenterWidget()) : Column( @@ -66,24 +71,35 @@ class _PostDetailPageState extends State with UniqueTagMixin { child: pullYsRefresh( enablePullDown: false, onInit: (refreshCtr) => logic.refreshCtr = refreshCtr, - onLoading: (_) => logic.fetchComments(logic.args.id ?? ''), + onLoading: (_) => + logic.fetchComments(logic.args.id ?? ''), child: CustomScrollView( controller: logic.scrollCtr, slivers: [ SliverToBoxAdapter(child: 14.h.sizeBoxH), //发帖人信息 - SliverToBoxAdapter(child: PostUserInfoView(model: model, isDetailStyle: true)), + SliverToBoxAdapter( + child: PostUserInfoView( + model: model, isDetailStyle: true)), //正文 - SliverToBoxAdapter(child: PostDetailWordContent(model: model)), + SliverToBoxAdapter( + child: PostDetailWordContent(model: model)), //富文本帖自带图,不再单独铺封面 if (model.richText?.isNotEmpty != true) - SliverToBoxAdapter(child: PostDetailCoverContent(model: model)), - SliverToBoxAdapter(child: GameDetailWordContent(model: model)), - SliverToBoxAdapter(child: PostDetailVideoContent(model: model)), - SliverToBoxAdapter(child: PostResourceInfoWidget(videoModel: model)), + SliverToBoxAdapter( + child: + PostDetailCoverContent(model: model)), + SliverToBoxAdapter( + child: GameDetailWordContent(model: model)), + SliverToBoxAdapter( + child: PostDetailVideoContent(model: model)), + SliverToBoxAdapter( + child: PostResourceInfoWidget( + videoModel: model)), SliverToBoxAdapter(child: 16.sizeBoxH), //点赞/收藏/分享 - SliverToBoxAdapter(child: PostDetailOperationView(model: model)), + SliverToBoxAdapter( + child: PostDetailOperationView(model: model)), SliverToBoxAdapter( child: AdsGridView( 7, @@ -98,15 +114,23 @@ class _PostDetailPageState extends State with UniqueTagMixin { Text( '${model.commentCount?.countStr}条评论', style: TextStyle( - fontSize: 14, fontWeight: FontWeight.w400, color: Colors.white.withValues(alpha: 0.9)), + fontSize: 14, + fontWeight: FontWeight.w400, + color: Colors.white + .withValues(alpha: 0.9)), ), - if (logic.quickSearchList.isNotEmpty) ...[18.sizeBoxH, QuickSearchView(logic.quickSearchList)] + if (logic.quickSearchList.isNotEmpty) ...[ + 18.sizeBoxH, + QuickSearchView(logic.quickSearchList) + ] ], ).paddingOnly(bottom: 14), ), //评论列表 if (logic.comments.isEmpty) - SliverToBoxAdapter(child: SizedBox(height: 220, child: CErrorWidget())) + SliverToBoxAdapter( + child: SizedBox( + height: 220, child: CErrorWidget())) else SliverList.builder( itemCount: logic.comments.length, @@ -114,8 +138,13 @@ class _PostDetailPageState extends State with UniqueTagMixin { logic.comments[index], objId: model.id ?? '', //置顶那条上方插一组 Banner - topBanners: index == topIndex && logic.commentTopBanners.isNotEmpty ? logic.commentTopBanners : null, - replyHandler: (comment, {reply}) => logic.readyReplyComment(comment, replyModel: reply), + topBanners: index == topIndex && + logic.commentTopBanners.isNotEmpty + ? logic.commentTopBanners + : null, + replyHandler: (comment, {reply}) => + logic.readyReplyComment(comment, + replyModel: reply), ), ) ], @@ -128,11 +157,13 @@ class _PostDetailPageState extends State with UniqueTagMixin { () => CommentFootView( video: model, showCollect: true, - onComment: (isSend) => logic.readyReplyComment(null, isSend: isSend), + onComment: (isSend) => + logic.readyReplyComment(null, isSend: isSend), isSending: logic.isSendingMsg.value, textCtr: logic.commentController, imgPath: logic.selectedImagePath.value, - onImgChange: (value) => logic.selectedImagePath.value = value, + onImgChange: (value) => + logic.selectedImagePath.value = value, ), ) ], @@ -168,7 +199,9 @@ class _PostDetailPageState extends State with UniqueTagMixin { children: [ _backBtn(), 4.sizeBoxW, - Expanded(child: PostUserInfoView(model: logic.model!, isDetailStyle: true, avatarSize: 30)), + Expanded( + child: PostUserInfoView( + model: logic.model!, isDetailStyle: true, avatarSize: 30)), ], ); }, diff --git a/lib/hj_page/community/publish_page/chose_tag_logic.dart b/lib/hj_page/community/publish_page/chose_tag_logic.dart index 4221758..df19dd9 100644 --- a/lib/hj_page/community/publish_page/chose_tag_logic.dart +++ b/lib/hj_page/community/publish_page/chose_tag_logic.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/search_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/search_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'chose_tag_page.dart'; diff --git a/lib/hj_page/community/publish_page/chose_tag_page.dart b/lib/hj_page/community/publish_page/chose_tag_page.dart index faaba22..4f40da6 100644 --- a/lib/hj_page/community/publish_page/chose_tag_page.dart +++ b/lib/hj_page/community/publish_page/chose_tag_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/community/publish_page/chose_tag_logic.dart'; -import 'package:hgmj/hj_page/home/search_page/widget/topic_item.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/community/publish_page/chose_tag_logic.dart'; +import 'package:wydj/hj_page/home/search_page/widget/topic_item.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; enum ChoseTopicEntry { home('选择标签'), @@ -48,7 +48,8 @@ class ChoseTopicPage extends StatelessWidget { Widget _buildBody(ChoseTopicLogic logic) { if (logic.isLoading) return LoadingCenterWidget(); - if (logic.dataSource.isEmpty) return CErrorWidget(retryOnTap: logic.loadTags); + if (logic.dataSource.isEmpty) + return CErrorWidget(retryOnTap: logic.loadTags); return _buildList(logic); } @@ -60,7 +61,8 @@ class ChoseTopicPage extends StatelessWidget { itemCount: logic.dataSource.length, itemBuilder: (_, index) { final model = logic.dataSource[index]; - final selected = logic.selectTags.indexWhere((e) => e.id == model.id) != -1; + final selected = + logic.selectTags.indexWhere((e) => e.id == model.id) != -1; return TopicItem( model: model, isSelect: selected, diff --git a/lib/hj_page/community/publish_page/publish_logic.dart b/lib/hj_page/community/publish_page/publish_logic.dart index 24bce0f..38566f2 100644 --- a/lib/hj_page/community/publish_page/publish_logic.dart +++ b/lib/hj_page/community/publish_page/publish_logic.dart @@ -4,16 +4,16 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/file_util.dart'; -import 'package:hgmj/hj_utils/media_info.dart'; -import 'package:hgmj/tools_base/file_upload/file_upload_tool.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/file_util.dart'; +import 'package:wydj/hj_utils/media_info.dart'; +import 'package:wydj/tools_base/file_upload/file_upload_tool.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_thumbnail/video_thumbnail.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import 'publish_page.dart'; @@ -221,7 +221,8 @@ class PublishLogic extends GetxController { } /// 提交发布([mediaInfo] 仅视频帖有) - Future _submitPost(List seriesCover, MediaInfo? mediaInfo) async { + Future _submitPost( + List seriesCover, MediaInfo? mediaInfo) async { final result = await VidService.submit( title: titleController.text, newsType: _generateNewsType(), @@ -373,7 +374,9 @@ class PublishLogic extends GetxController { } String _generateNewsType() { - if (type == PublishType.homeImg || type == PublishType.homeImgText || type == PublishType.squireImgText) return 'COVER'; + if (type == PublishType.homeImg || + type == PublishType.homeImgText || + type == PublishType.squireImgText) return 'COVER'; final duration = video.value.playTime ?? 0; if (duration <= 300) return 'SP'; return 'SP'; diff --git a/lib/hj_page/community/publish_page/publish_page.dart b/lib/hj_page/community/publish_page/publish_page.dart index 89b854f..5fefa6e 100644 --- a/lib/hj_page/community/publish_page/publish_page.dart +++ b/lib/hj_page/community/publish_page/publish_page.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_page/community/publish_page/chose_tag_page.dart'; -import 'package:hgmj/hj_page/community/publish_page/publish_logic.dart'; -import 'package:hgmj/hj_page/community/publish_page/publish_rule_page.dart'; -import 'package:hgmj/hj_page/community/publish_page/widget/publish_widget.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_page/community/publish_page/chose_tag_page.dart'; +import 'package:wydj/hj_page/community/publish_page/publish_logic.dart'; +import 'package:wydj/hj_page/community/publish_page/publish_rule_page.dart'; +import 'package:wydj/hj_page/community/publish_page/widget/publish_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; enum PublishType { homeImg(RuleType.home, ChoseTopicEntry.home, '发布图片'), @@ -69,7 +69,6 @@ extension PublishMore on PublishType { } class PublishPage extends StatelessWidget { - final PublishType type; const PublishPage({super.key, this.type = PublishType.homeImgText}); @@ -94,7 +93,8 @@ class PublishPage extends StatelessWidget { showCancel: false, confirmText: '我知道了', ), - child: const Text('规则', style: TextStyle(color: Color(0x8CFFFFFF))), + child: + const Text('规则', style: TextStyle(color: Color(0x8CFFFFFF))), ), 18.w.sizeBoxW, ], @@ -132,7 +132,11 @@ class PublishPage extends StatelessWidget { ), child: const Text( '确定发布', - style: TextStyle(color: Colors.black, fontSize: 16, height: 27 / 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 16, + height: 27 / 14, + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/hj_page/community/publish_page/widget/publish_widget.dart b/lib/hj_page/community/publish_page/widget/publish_widget.dart index 7c8c1ad..86adc28 100644 --- a/lib/hj_page/community/publish_page/widget/publish_widget.dart +++ b/lib/hj_page/community/publish_page/widget/publish_widget.dart @@ -4,12 +4,12 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/widget/add_media_source_button.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/widget/add_media_source_button.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../home/widget/support_up_alert.dart'; import '../chose_tag_page.dart'; @@ -40,9 +40,14 @@ class ChoseVideoWidget extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Text('添加视频', style: TextStyle(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500)), + Text('添加视频', + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500)), 10.sizeBoxW, - Text('最大300M以内', style: TextStyle(color: Color(0xff666666), fontSize: 12.sp)), + Text('最大300M以内', + style: TextStyle(color: Color(0xff666666), fontSize: 12.sp)), ], ), 14.h.sizeBoxH, @@ -51,7 +56,11 @@ class ChoseVideoWidget extends StatelessWidget { return Row(children: [ 6.h.sizeBoxW, if (controller.video.value.localPath == null) - AddMediaSourceButton(width: cellW, height: cellW, onTap: controller.choseVideo, isVideo: true) + AddMediaSourceButton( + width: cellW, + height: cellW, + onTap: controller.choseVideo, + isVideo: true) else _cover(cellW), ]); @@ -67,7 +76,8 @@ class ChoseVideoWidget extends StatelessWidget { constraints: const BoxConstraints(maxWidth: 230, maxHeight: 219), child: Stack( children: [ - VideoCoverWidget(controller.video.value.localCover ?? '', width: size, height: size, isLocal: true), + VideoCoverWidget(controller.video.value.localCover ?? '', + width: size, height: size, isLocal: true), Positioned( right: 6, top: 6, @@ -75,8 +85,11 @@ class ChoseVideoWidget extends StatelessWidget { onTap: () => controller.deleteSelectVideo(), child: Container( padding: const EdgeInsets.all(4), - decoration: BoxDecoration(color: Colors.white.withValues(alpha: .8), borderRadius: BorderRadius.circular(10)), - child: const Icon(Icons.close, size: 12, color: Color(0xff333333)), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .8), + borderRadius: BorderRadius.circular(10)), + child: + const Icon(Icons.close, size: 12, color: Color(0xff333333)), ), ), ) @@ -97,7 +110,8 @@ class TopicWidget extends StatelessWidget { return Obx( () => GestureDetector( onTap: () async { - final model = await Get.to(ChoseTopicPage(entry: controller.type.tag, selectTags: controller.topics)); + final model = await Get.to(ChoseTopicPage( + entry: controller.type.tag, selectTags: controller.topics)); if (model is TagsBean) { controller.topics ..clear() @@ -120,9 +134,17 @@ class TopicWidget extends StatelessWidget { Widget _emptyTip() { return Row( children: [ - Text("#", style: TextStyle(color: Color(0xff989898), fontSize: 24.sp, fontWeight: FontWeight.bold)), + Text("#", + style: TextStyle( + color: Color(0xff989898), + fontSize: 24.sp, + fontWeight: FontWeight.bold)), 10.sizeBoxW, - Text('选择标签', style: TextStyle(color: Color(0xff989898), fontSize: 12.sp, fontWeight: FontWeight.w500)), + Text('选择标签', + style: TextStyle( + color: Color(0xff989898), + fontSize: 12.sp, + fontWeight: FontWeight.w500)), const Spacer(), Icon(Icons.arrow_forward_ios, size: 16.sp, color: Color(0xffDCDCDC)), ], @@ -135,12 +157,20 @@ class TopicWidget extends StatelessWidget { children: [ ClipRRect( borderRadius: BorderRadius.circular(5), - child: NetworkImageLoader(imageUrl: controller.topics.first.coverImg ?? '', width: 38, height: 38), + child: NetworkImageLoader( + imageUrl: controller.topics.first.coverImg ?? '', + width: 38, + height: 38), ), 5.sizeBoxW, Text( - controller.topics.firstOrNull?.name != null ? '#${controller.topics.firstOrNull?.name}' : '', - style: TextStyle(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500), + controller.topics.firstOrNull?.name != null + ? '#${controller.topics.firstOrNull?.name}' + : '', + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500), ), Spacer(), Icon(Icons.arrow_forward_ios, size: 16.sp, color: Color(0xffDCDCDC)), @@ -176,7 +206,8 @@ class InputTitleWidget extends StatelessWidget { decoration: InputDecoration( border: InputBorder.none, hintText: '请填写标题', - hintStyle: TextStyle(color: Color(0xff525252), fontSize: 12.sp, height: 22 / 15), + hintStyle: TextStyle( + color: Color(0xff525252), fontSize: 12.sp, height: 22 / 15), contentPadding: EdgeInsets.zero, isDense: true, ), @@ -246,7 +277,13 @@ class ChoseImageWidget extends StatelessWidget { final Color? highlightTextColor; final double? highlightTextSize; - ChoseImageWidget({super.key, this.title, this.hint, this.highlightText, this.highlightTextColor, this.highlightTextSize}); + ChoseImageWidget( + {super.key, + this.title, + this.hint, + this.highlightText, + this.highlightTextColor, + this.highlightTextSize}); final controller = Get.find(); @@ -259,15 +296,22 @@ class ChoseImageWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, spacing: 10, children: [ - Text(title ?? '添加图片', style: TextStyle(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500)), + Text(title ?? '添加图片', + style: TextStyle( + color: Colors.white, + fontSize: 16.sp, + fontWeight: FontWeight.w500)), EasyRichText( hint ?? '添加图集 图片数量最多上传9张哦~', - defaultStyle: TextStyle(color: Color(0xff666666), fontSize: 12.sp), + defaultStyle: + TextStyle(color: Color(0xff666666), fontSize: 12.sp), patternList: [ EasyRichTextPattern( targetString: highlightText ?? '', style: TextStyle( - color: highlightTextColor ?? Colors.white, fontSize: highlightTextSize ?? 16.sp, fontWeight: FontWeight.w500), + color: highlightTextColor ?? Colors.white, + fontSize: highlightTextSize ?? 16.sp, + fontWeight: FontWeight.w500), ) ], ), @@ -310,7 +354,8 @@ class ChoseImageWidget extends StatelessWidget { height: size, child: Stack( children: [ - Image.file(File(path), width: size, height: size, fit: BoxFit.cover), + Image.file(File(path), + width: size, height: size, fit: BoxFit.cover), Positioned( right: 6, top: 6, @@ -319,7 +364,9 @@ class ChoseImageWidget extends StatelessWidget { child: Container( width: 20, height: 20, - decoration: BoxDecoration(color: Colors.white.withValues(alpha: .8), borderRadius: BorderRadius.circular(10)), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .8), + borderRadius: BorderRadius.circular(10)), alignment: Alignment.center, child: const Icon(Icons.close, size: 14), ), @@ -344,7 +391,9 @@ class SettingGoldWidget extends StatelessWidget { behavior: HitTestBehavior.translucent, onTap: () async { final res = await Get.bottomSheet( - SupportUPAlert(isPublish: true, selectCoin: int.tryParse(controller.gold.value ?? '')), + SupportUPAlert( + isPublish: true, + selectCoin: int.tryParse(controller.gold.value ?? '')), ); controller.gold.value = res?.toString(); }, @@ -354,22 +403,32 @@ class SettingGoldWidget extends StatelessWidget { decoration: publishDecoration, child: Row( children: [ - Image.asset('community_coin.webp'.communityPath, width: 20, height: 20), + Image.asset('community_coin.webp'.communityPath, + width: 20, height: 20), 10.sizeBoxW, - const Text('设置价格', style: TextStyle(color: Color(0xFF989898), fontSize: 12, fontWeight: FontWeight.w600)), + const Text('设置价格', + style: TextStyle( + color: Color(0xFF989898), + fontSize: 12, + fontWeight: FontWeight.w600)), const Spacer(), Obx( () => Text( - controller.gold.value == null ? '免费' : '${controller.gold.value} 金币', + controller.gold.value == null + ? '免费' + : '${controller.gold.value} 金币', style: TextStyle( - color: controller.gold.value == null ? Color(0xFF989898) : AppColors.actionRed, + color: controller.gold.value == null + ? Color(0xFF989898) + : AppColors.actionRed, // color: Color(0xffF68216), fontSize: 12, fontWeight: FontWeight.w400), ), ), 5.sizeBoxW, - const Icon(Icons.arrow_forward_ios, color: Color(0xffDCDCDC), size: 12) + const Icon(Icons.arrow_forward_ios, + color: Color(0xffDCDCDC), size: 12) ], ), ), diff --git a/lib/hj_page/community/publish_page/widget/video_cover_widget.dart b/lib/hj_page/community/publish_page/widget/video_cover_widget.dart index 64a8636..f7d66f3 100644 --- a/lib/hj_page/community/publish_page/widget/video_cover_widget.dart +++ b/lib/hj_page/community/publish_page/widget/video_cover_widget.dart @@ -1,8 +1,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// 视频封面:本地/网络图 + 可选暗色遮罩 + 居中播放按钮 /// [ratio] 传了就按比例撑开,不传则由外部约束决定尺寸 @@ -34,16 +34,24 @@ class VideoCoverWidget extends StatelessWidget { alignment: Alignment.center, children: [ if (isLocal) - Image.file(File(cover), width: width, height: height, fit: BoxFit.cover) + Image.file(File(cover), + width: width, height: height, fit: BoxFit.cover) else - NetworkImageLoader(imageUrl: cover, width: maskW, height: maskH, borderRadius: 0), - if (showMask) Container(width: maskW, height: maskH, color: Colors.black.withValues(alpha: 0.4)), + NetworkImageLoader( + imageUrl: cover, width: maskW, height: maskH, borderRadius: 0), + if (showMask) + Container( + width: maskW, + height: maskH, + color: Colors.black.withValues(alpha: 0.4)), Image.asset('circle_play.webp'.videoPath, width: 30, height: 30), ], ); return ClipRRect( borderRadius: BorderRadius.circular(borderRadius), - child: ratio == null ? child : AspectRatio(aspectRatio: ratio! > 0 ? ratio! : 1, child: child), + child: ratio == null + ? child + : AspectRatio(aspectRatio: ratio! > 0 ? ratio! : 1, child: child), ); } } diff --git a/lib/hj_page/community/widget/community_middle_header.dart b/lib/hj_page/community/widget/community_middle_header.dart index 912a57b..78cbf24 100644 --- a/lib/hj_page/community/widget/community_middle_header.dart +++ b/lib/hj_page/community/widget/community_middle_header.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; import '../community/community_tab_logic.dart'; /// 社区首页的排序 tab 条,标题取自 CommunityTabLogic.sortTabs @@ -12,7 +12,8 @@ class CommunityMiddleHeader extends StatefulWidget { State createState() => _CommunityMiddleHeaderState(); } -class _CommunityMiddleHeaderState extends State with SingleTickerProviderStateMixin { +class _CommunityMiddleHeaderState extends State + with SingleTickerProviderStateMixin { //别在这里另写一份标题 final sorts = CommunityTabLogic.sortTabs.map((e) => e.name).toList(); late final TabController _controller; @@ -47,8 +48,15 @@ class _CommunityMiddleHeaderState extends State with Sing )) .toList(), indicatorWeight: 1, - unselectedLabelStyle: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 16.sp, height: 1), - labelStyle: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 16.sp, height: 1, fontWeight: FontWeight.w600), + unselectedLabelStyle: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 16.sp, + height: 1), + labelStyle: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 16.sp, + height: 1, + fontWeight: FontWeight.w600), indicator: const BoxDecoration(), controller: _controller, ), diff --git a/lib/hj_page/community/widget/community_post_widget.dart b/lib/hj_page/community/widget/community_post_widget.dart index 45e214c..f8c4e93 100644 --- a/lib/hj_page/community/widget/community_post_widget.dart +++ b/lib/hj_page/community/widget/community_post_widget.dart @@ -4,10 +4,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_model/video_model.dart'; import '../../find/rank_module/rank_badge.dart'; @@ -16,10 +16,11 @@ import '../community_tag_page/community_tag_page.dart'; import '../post_detail_page/post_detail_page.dart'; import 'post_user_info_view.dart'; import 'post_word_rich_text.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; -typedef OnItemCheckCallback = void Function(VideoModel videoModel, bool isChecked); +typedef OnItemCheckCallback = void Function( + VideoModel videoModel, bool isChecked); /// 社区帖子卡片,社区/搜索/个人主页/我的发布/收藏历史多处复用 class CommunityPostWidget extends StatelessWidget { @@ -66,7 +67,9 @@ class CommunityPostWidget extends StatelessWidget { _ => '未知状态', //含 5 }; - Color get _statusColor => videoModel.status == 2 ? const Color(0xffFD0563) : const Color(0xff3476FF); + Color get _statusColor => videoModel.status == 2 + ? const Color(0xffFD0563) + : const Color(0xff3476FF); bool get _showStatus => videoModel.status != 1 && !showCheck; @@ -81,7 +84,8 @@ class CommunityPostWidget extends StatelessWidget { onTap: clickCallback ?? () { //在点击时算好:PostDetailPageArgument 内部要过滤整个列表,别丢进 page builder 里重复跑 - final argument = PostDetailPageArgument(id: videoModel.id, models: videoModels); + final argument = + PostDetailPageArgument(id: videoModel.id, models: videoModels); Get.to(() => PostDetailPage(argument: argument)); }, child: Padding( @@ -107,7 +111,8 @@ class CommunityPostWidget extends StatelessWidget { '$_statusPrefix于${formatTimeTwo(videoModel.realCreateAt)}', maxLines: 2, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Color(0x8CFFFFFF), fontSize: 14), + style: + const TextStyle(color: Color(0x8CFFFFFF), fontSize: 14), ), const Spacer(), if (showCheck) @@ -121,13 +126,18 @@ class CommunityPostWidget extends StatelessWidget { width: 18, height: 18, decoration: BoxDecoration( - color: isChecked ? Colors.white : Colors.transparent, + color: + isChecked ? Colors.white : Colors.transparent, shape: BoxShape.circle, ), ), Icon( - isChecked ? CupertinoIcons.checkmark_circle_fill : CupertinoIcons.circle, - color: isChecked ? const Color(0xffFFC000) : const Color(0xff999999), + isChecked + ? CupertinoIcons.checkmark_circle_fill + : CupertinoIcons.circle, + color: isChecked + ? const Color(0xffFFC000) + : const Color(0xff999999), ), ], ), @@ -145,7 +155,9 @@ class CommunityPostWidget extends StatelessWidget { ); } }, - child: Text(_statusDesc, style: TextStyle(color: _statusColor, fontSize: 14.sp)), + child: Text(_statusDesc, + style: + TextStyle(color: _statusColor, fontSize: 14.sp)), ), ], ), @@ -163,15 +175,19 @@ class CommunityPostWidget extends StatelessWidget { //底部:浏览、评论、点赞 + 右侧话题 Row( children: [ - _countItem(videoModel.pageViewCount?.countStr, "eye_grey.webp".commonImgPath), + _countItem(videoModel.pageViewCount?.countStr, + "eye_grey.webp".commonImgPath), 12.sizeBoxW, - _countItem(videoModel.commentCount?.countStr, "count_msg_gray.png".communityPath), + _countItem(videoModel.commentCount?.countStr, + "count_msg_gray.png".communityPath), 12.sizeBoxW, CollectStatusWrapper( videoModel: videoModel, builder: () => _countItem( videoModel.likeCount?.countStr, - videoModel.vidStatus?.hasLiked == true ? "like_red.png".commonImgPath : "like_empty_gray.png".communityPath, + videoModel.vidStatus?.hasLiked == true + ? "like_red.png".commonImgPath + : "like_empty_gray.png".communityPath, ), ), const Spacer(), @@ -201,8 +217,11 @@ class CommunityPostWidget extends StatelessWidget { child: Stack( fit: StackFit.expand, children: [ - NetworkImageLoader(imageUrl: videoModel.cover ?? '', borderRadius: 6), - Center(child: Image.asset("play_icon.png".communityPath, width: 32, height: 32)), + NetworkImageLoader( + imageUrl: videoModel.cover ?? '', borderRadius: 6), + Center( + child: Image.asset("play_icon.png".communityPath, + width: 32, height: 32)), Positioned(right: 0, top: 0, child: _coinBadge()), ], ), @@ -232,27 +251,36 @@ class CommunityPostWidget extends StatelessWidget { itemBuilder: (context, index) { final isLast = index == 2 || coverCount == index + 1; //视频帖把视频封面排在最后一格,其余格按图集顺序取 - final imgPath = (isLast && isVideo) || index >= covers.length ? (videoModel.cover ?? "") : covers[index]; + final imgPath = (isLast && isVideo) || index >= covers.length + ? (videoModel.cover ?? "") + : covers[index]; return Stack( fit: StackFit.expand, children: [ - NetworkImageLoader(imageUrl: imgPath, imgBorderRadius: BorderRadius.circular(6)), + NetworkImageLoader( + imageUrl: imgPath, imgBorderRadius: BorderRadius.circular(6)), if (isLast) Positioned(right: 0, top: 0, child: _coinBadge()), if (isLast && isVideo) - Center(child: Image.asset("play_icon.png".communityPath, width: 30)) + Center( + child: Image.asset("play_icon.png".communityPath, width: 30)) else if (isLast && coverCount > 3) Positioned( bottom: 6, right: 6, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 1), + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 1), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(30), ), child: Text( "+${coverCount - 3}", - style: const TextStyle(fontSize: 10, color: Color(0xff141414), fontWeight: FontWeight.w400, height: 1.6), + style: const TextStyle( + fontSize: 10, + color: Color(0xff141414), + fontWeight: FontWeight.w400, + height: 1.6), ), ), ), @@ -268,7 +296,8 @@ class CommunityPostWidget extends StatelessWidget { return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), decoration: const BoxDecoration( - borderRadius: BorderRadius.only(topRight: Radius.circular(6), bottomLeft: Radius.circular(6)), + borderRadius: BorderRadius.only( + topRight: Radius.circular(6), bottomLeft: Radius.circular(6)), color: Color(0xffDB361F), ), child: Image.asset("coin.webp".commonImgPath, width: 14, height: 14), @@ -281,7 +310,8 @@ class CommunityPostWidget extends StatelessWidget { children: [ Image.asset(icon, width: 20, height: 20), const SizedBox(width: 4), - Text(title ?? "", style: const TextStyle(color: Color(0xff999999), fontSize: 12)), + Text(title ?? "", + style: const TextStyle(color: Color(0xff999999), fontSize: 12)), ], ); } @@ -295,7 +325,9 @@ class CommunityPostWidget extends StatelessWidget { onTap: () => Get.to(() => CommunityTagDetailPage(model: tagsBean)), child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(3), color: const Color(0x0DFFFFFF)), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + color: const Color(0x0DFFFFFF)), child: Text( '#${tagsBean.name ?? ''}', style: TextStyle(color: tagsColor ?? Color(0x8CFFFFFF), fontSize: 12), diff --git a/lib/hj_page/community/widget/community_sort_header.dart b/lib/hj_page/community/widget/community_sort_header.dart index 41bd22c..5a25387 100644 --- a/lib/hj_page/community/widget/community_sort_header.dart +++ b/lib/hj_page/community/widget/community_sort_header.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; class CommunitySortHeader extends StatefulWidget { final Function(int sort) sortOnTap; @@ -15,7 +15,8 @@ class CommunitySortHeader extends StatefulWidget { State createState() => _CommunitySortHeaderState(); } -class _CommunitySortHeaderState extends State with SingleTickerProviderStateMixin { +class _CommunitySortHeaderState extends State + with SingleTickerProviderStateMixin { final sorts = ['最多收藏', '最新上架', '最新热评']; late TabController _controller; @@ -27,7 +28,8 @@ class _CommunitySortHeaderState extends State with SingleTi super.initState(); //在 initState 定死归属,别用 late 惰性求值——那时读到的可能是 rebuild 后的新 widget _isMine = widget.controller == null; - _controller = widget.controller ?? TabController(length: sorts.length, vsync: this); + _controller = + widget.controller ?? TabController(length: sorts.length, vsync: this); } @override @@ -50,13 +52,21 @@ class _CommunitySortHeaderState extends State with SingleTi tabAlignment: TabAlignment.center, tabs: sorts .map((e) => Padding( - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 4.h), + padding: + EdgeInsets.symmetric(horizontal: 12.w, vertical: 4.h), child: Text(e), )) .toList(), indicatorWeight: 1, - unselectedLabelStyle: TextStyle(color: Colors.white.withValues(alpha: .6), fontSize: 16.sp, height: 1), - labelStyle: TextStyle(color: Colors.white, fontSize: 16.sp, height: 1, fontWeight: FontWeight.w600), + unselectedLabelStyle: TextStyle( + color: Colors.white.withValues(alpha: .6), + fontSize: 16.sp, + height: 1), + labelStyle: TextStyle( + color: Colors.white, + fontSize: 16.sp, + height: 1, + fontWeight: FontWeight.w600), // 无指示器:原 ContainerTabIndicator 为全透明,选中态仅靠文字加粗变白 indicator: const BoxDecoration(), controller: _controller, diff --git a/lib/hj_page/community/widget/follow_loading_button.dart b/lib/hj_page/community/widget/follow_loading_button.dart index 6e4545a..fa35c92 100644 --- a/lib/hj_page/community/widget/follow_loading_button.dart +++ b/lib/hj_page/community/widget/follow_loading_button.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; /// 关注 / 收藏按钮,加载中转菊花 class FollowLoadingButton extends StatelessWidget { diff --git a/lib/hj_page/community/widget/pic_simple_cell.dart b/lib/hj_page/community/widget/pic_simple_cell.dart index 9f7fc95..2fe4884 100644 --- a/lib/hj_page/community/widget/pic_simple_cell.dart +++ b/lib/hj_page/community/widget/pic_simple_cell.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_model/video_model.dart'; import '../../find/pic_collect/pics_detail_page.dart'; @@ -17,7 +17,8 @@ class PicSimpleCell extends StatelessWidget { @override Widget build(BuildContext context) { return GestureDetector( - onTap: () => Get.to(PicsDetailPage(id: videoModel?.id), preventDuplicates: false), + onTap: () => + Get.to(PicsDetailPage(id: videoModel?.id), preventDuplicates: false), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -58,13 +59,16 @@ class PicSimpleCell extends StatelessWidget { ), Spacer(), Container( - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 1), + padding: + EdgeInsets.symmetric(horizontal: 4, vertical: 1), child: Row( children: [ - Image.asset("icon_pic.png".communityPath, width: 16), + Image.asset("icon_pic.png".communityPath, + width: 16), 2.sizeBoxW, Text( - videoModel?.seriesCover?.length.toString() ?? "", + videoModel?.seriesCover?.length.toString() ?? + "", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( diff --git a/lib/hj_page/community/widget/post_user_info_view.dart b/lib/hj_page/community/widget/post_user_info_view.dart index af70e1a..1bdb9bb 100644 --- a/lib/hj_page/community/widget/post_user_info_view.dart +++ b/lib/hj_page/community/widget/post_user_info_view.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/community/widget/follow_loading_button.dart'; -import 'package:hgmj/hj_page/home/widget/collect_status_wrapper.dart'; -import 'package:hgmj/hj_page/home/widget/user_name_view.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/community/widget/follow_loading_button.dart'; +import 'package:wydj/hj_page/home/widget/collect_status_wrapper.dart'; +import 'package:wydj/hj_page/home/widget/user_name_view.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; //帖子发布者信息:头像 + 昵称 + 发布时间,详情模式额外带关注按钮 class PostUserInfoView extends StatefulWidget { @@ -64,7 +64,9 @@ class _PostUserInfoViewState extends State { builder: () => InkWell( enableFeedback: false, onTap: _toggleFollow, - child: FollowLoadingButton(isFollow: publisher?.hasFollowed ?? false, isLoading: _isLoading), + child: FollowLoadingButton( + isFollow: publisher?.hasFollowed ?? false, + isLoading: _isLoading), ), ), ], diff --git a/lib/hj_page/community/widget/post_word_rich_text.dart b/lib/hj_page/community/widget/post_word_rich_text.dart index fe25ee1..b48012a 100644 --- a/lib/hj_page/community/widget/post_word_rich_text.dart +++ b/lib/hj_page/community/widget/post_word_rich_text.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/widget_util.dart'; +import 'package:wydj/hj_utils/widget_util.dart'; import '../../../hj_model/video_model.dart'; @@ -18,7 +18,10 @@ class PostWordRichText extends StatelessWidget { if (videoModel?.chosen ?? false) _badge('精华'), TextSpan( text: videoModel?.title ?? '', - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 14, + fontWeight: FontWeight.w500), ), ], ), @@ -33,8 +36,11 @@ class PostWordRichText extends StatelessWidget { height: 18, alignment: Alignment.topCenter, margin: const EdgeInsets.only(right: 4), - decoration: BoxDecoration(color: const Color(0xffF52C56), borderRadius: BorderRadius.circular(2)), - child: Text(text, style: textStyle(12, Colors.white, FontWeight.w500)), + decoration: BoxDecoration( + color: const Color(0xffF52C56), + borderRadius: BorderRadius.circular(2)), + child: + Text(text, style: textStyle(12, Colors.white, FontWeight.w500)), ), ); } diff --git a/lib/hj_page/drama/drama_detail_logic.dart b/lib/hj_page/drama/drama_detail_logic.dart index f4b2183..6d367a3 100644 --- a/lib/hj_page/drama/drama_detail_logic.dart +++ b/lib/hj_page/drama/drama_detail_logic.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/cache/history/drama_resume_store.dart'; -import 'package:hgmj/hj_page/drama/view/drama_episode_sheet.dart'; -import 'package:hgmj/hj_page/drama/view/drama_speed_sheet.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/cache/history/drama_resume_store.dart'; +import 'package:wydj/hj_page/drama/view/drama_episode_sheet.dart'; +import 'package:wydj/hj_page/drama/view/drama_speed_sheet.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; /// 短剧二级页:同一部剧连播,退出本页就回到 Feed 的逐剧模式 class DramaDetailLogic extends GetxController { @@ -83,7 +83,8 @@ class DramaDetailLogic extends GetxController { final resumeTask = dramaResume.load(); // 读本地盘,内部已兜住异常 final resp = await Future.wait([ DramaService.fetchDetail(drama?.id), - DramaService.fetchEpisodeList(drama?.id ?? '', 1, drama?.episodePageSize ?? 30), + DramaService.fetchEpisodeList( + drama?.id ?? '', 1, drama?.episodePageSize ?? 30), ]); await resumeTask; _detail = resp[0] as DramaMediaInfo? ?? drama; @@ -113,7 +114,8 @@ class DramaDetailLogic extends GetxController { final list = episodes; dramaResume.markWatched( mediaId: info?.id, - contentId: list.isEmpty ? null : list[pageIndex.clamp(0, list.length - 1)].id, + contentId: + list.isEmpty ? null : list[pageIndex.clamp(0, list.length - 1)].id, drama: info, ); } @@ -144,7 +146,8 @@ class DramaDetailLogic extends GetxController { } //置空而不是改成 bought:开了卡就是不该再挂付费标,真实状态以分集详情为准 for (final episode in info?.episodeList ?? []) { - if (episode.accessType == 'coin' || episode.accessType == 'card') episode.accessType = null; + if (episode.accessType == 'coin' || episode.accessType == 'card') + episode.accessType = null; } update([idFeed]); } @@ -157,7 +160,8 @@ class DramaDetailLogic extends GetxController { if (media == null || _isLoading || media.haxNextEpisode != true) return; _isLoading = true; final page = (media.episodeCurPage ?? 1) + 1; - final res = await DramaService.fetchEpisodeList(media.id ?? '', page, media.episodePageSize); + final res = await DramaService.fetchEpisodeList( + media.id ?? '', page, media.episodePageSize); _isLoading = false; if (isClosed) return; //拉空/失败都要落 haxNextEpisode,否则 _resumeIndex 的补页循环会一直转 diff --git a/lib/hj_page/drama/drama_detail_page.dart b/lib/hj_page/drama/drama_detail_page.dart index 57b3c2f..03ad71d 100644 --- a/lib/hj_page/drama/drama_detail_page.dart +++ b/lib/hj_page/drama/drama_detail_page.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_page/drama/drama_detail_logic.dart'; -import 'package:hgmj/hj_page/drama/view/drama_bottom_bar.dart'; -import 'package:hgmj/hj_page/drama/view/drama_video_player.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_page/drama/drama_detail_logic.dart'; +import 'package:wydj/hj_page/drama/view/drama_bottom_bar.dart'; +import 'package:wydj/hj_page/drama/view/drama_video_player.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; /// 短剧二级页:竖划切集 + 底部剧集条(选集/自动续播) class DramaDetailPage extends StatefulWidget { @@ -55,7 +55,8 @@ class _DramaDetailPageState extends State with UniqueTagMixin { ), builder: (logic) { if (!logic.isFirstLoaded) return const LoadingCenterWidget(); - if (logic.episodeVideos.isEmpty) return CErrorWidget(retryOnTap: logic.loadDetail); + if (logic.episodeVideos.isEmpty) + return CErrorWidget(retryOnTap: logic.loadDetail); return Stack( fit: StackFit.expand, children: [ @@ -121,7 +122,9 @@ class _DramaDetailPageState extends State with UniqueTagMixin { final seconds = logic.nextSeconds; return DramaBottomBar( highlight: seconds > 0 ? '${seconds}s后' : null, - text: seconds > 0 ? '播放下一集' : '观看完整剧集·全${logic.info?.totalEpisode ?? logic.episodes.length}集', + text: seconds > 0 + ? '播放下一集' + : '观看完整剧集·全${logic.info?.totalEpisode ?? logic.episodes.length}集', onTap: logic.openEpisodeSheet, ); }, @@ -150,13 +153,17 @@ class _DramaDetailPageState extends State with UniqueTagMixin { 'stopwatch.svg'.videoPath, width: 18, height: 18, - colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), + colorFilter: + const ColorFilter.mode(Colors.white, BlendMode.srcIn), ), 4.sizeBoxW, Text( '${logic.speed}x', - style: - const TextStyle(color: Colors.white, fontSize: 12, height: 18 / 12, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + height: 18 / 12, + fontWeight: FontWeight.w500), ), ], ), @@ -175,7 +182,9 @@ class _DramaDetailPageState extends State with UniqueTagMixin { icon: const Icon( Icons.arrow_back_ios, color: Colors.white, - shadows: [Shadow(color: Colors.black, offset: Offset(1, 1), blurRadius: 1)], + shadows: [ + Shadow(color: Colors.black, offset: Offset(1, 1), blurRadius: 1) + ], ), onPressed: Get.back, ), diff --git a/lib/hj_page/drama/drama_feed_logic.dart b/lib/hj_page/drama/drama_feed_logic.dart index 2789cff..fa5c567 100644 --- a/lib/hj_page/drama/drama_feed_logic.dart +++ b/lib/hj_page/drama/drama_feed_logic.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/cache/history/drama_resume_store.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/cache/history/drama_resume_store.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:uuid/uuid.dart'; /// AI短剧信息流:一条 = 一部剧的第 1 集,竖划换下一部剧。 @@ -68,7 +68,8 @@ class DramaFeedLogic extends GetxController { if (!isRefresh && !hasNext) return; isLoading = true; try { - final resp = await DramaService.fetchFeed(size: 20, requestId: _requestId ??= const Uuid().v4()); + final resp = await DramaService.fetchFeed( + size: 20, requestId: _requestId ??= const Uuid().v4()); if (resp != null) _requestId = null; // 成功才作废;失败重试沿用同一个 id,避免服务端当成两批 //拿到什么收什么,不按剧 id 去重:服务端反复下发同一部剧时,去重会让列表不增长, //用户停在最后一条划不动、onPageChanged 也不再触发,就彻底卡死了。 diff --git a/lib/hj_page/drama/drama_feed_page.dart b/lib/hj_page/drama/drama_feed_page.dart index 7f31314..4690cdf 100644 --- a/lib/hj_page/drama/drama_feed_page.dart +++ b/lib/hj_page/drama/drama_feed_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/drama/drama_feed_logic.dart'; -import 'package:hgmj/hj_page/drama/view/drama_video_player.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_page/drama/drama_feed_logic.dart'; +import 'package:wydj/hj_page/drama/view/drama_video_player.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; /// AI短剧信息流页:竖划一部换一部,每条播该剧第 1 集 class DramaFeedPage extends StatefulWidget { @@ -21,7 +21,8 @@ class _DramaFeedPageState extends State with UniqueTagMixin { Widget build(BuildContext context) { return GetBuilder( tag: uniqueTag, // 多 tab 并存,按实例隔离 - init: DramaFeedLogic(superTabCtr: widget.superTabCtr, tabIndex: widget.tabIndex), + init: DramaFeedLogic( + superTabCtr: widget.superTabCtr, tabIndex: widget.tabIndex), builder: (logic) { final Widget content; if (!logic.isFirstLoaded) { diff --git a/lib/hj_page/drama/drama_list_logic.dart b/lib/hj_page/drama/drama_list_logic.dart index be5110e..47303e4 100644 --- a/lib/hj_page/drama/drama_list_logic.dart +++ b/lib/hj_page/drama/drama_list_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../../hj_model/drama_media_info.dart'; @@ -36,7 +36,8 @@ class DramaListLogic extends ListBaseLogic { List topics = []; bool topicsReady = false; - List get sortTitles => topics.map((e) => e.name ?? '').where((e) => e.isNotEmpty).toList(); + List get sortTitles => + topics.map((e) => e.name ?? '').where((e) => e.isNotEmpty).toList(); String? get _currentTopicId { if (topics.isEmpty) return null; @@ -79,7 +80,8 @@ class DramaListLogic extends ListBaseLogic { Future<(List?, bool)> _fetch(int page) async { final topicId = _currentTopicId; if (topicId == null) return ([], false); - final res = await DramaService.fetchTopicWorks(topicId, page: page, size: 20); + final res = + await DramaService.fetchTopicWorks(topicId, page: page, size: 20); return (res?.list ?? [], res?.hasNext ?? false); } diff --git a/lib/hj_page/drama/drama_list_page.dart b/lib/hj_page/drama/drama_list_page.dart index 6b86b9e..c6d3210 100644 --- a/lib/hj_page/drama/drama_list_page.dart +++ b/lib/hj_page/drama/drama_list_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/drama/drama_list_logic.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/drama/drama_list_logic.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../home/home_cell_style/drama_cover_card.dart'; @@ -57,9 +57,13 @@ class _DramaListPageState extends State with UniqueTagMixin { children: [ for (var r = 0; r < rows.length; r++) ...[ if (r > 0) const SizedBox(height: 8), - _buildSortRow(logic, titles, rows[r], hasToggle: _rowHasToggle(needToggle, rows, r)), + _buildSortRow(logic, titles, rows[r], + hasToggle: _rowHasToggle(needToggle, rows, r)), ], - if (needToggle && _sortExpanded && rows.isNotEmpty && rows.last.length == 4) ...[ + if (needToggle && + _sortExpanded && + rows.isNotEmpty && + rows.last.length == 4) ...[ const SizedBox(height: 8), Row(children: [_buildExpandToggle()]), ], @@ -84,7 +88,8 @@ class _DramaListPageState extends State with UniqueTagMixin { children: [ for (var k = 0; k < indexes.length; k++) ...[ if (k > 0) const SizedBox(width: 8), - _buildSortTab(logic, indexes[k], titles[indexes[k]], expand: !hasToggle), + _buildSortTab(logic, indexes[k], titles[indexes[k]], + expand: !hasToggle), ], if (hasToggle) ...[ const SizedBox(width: 8), @@ -94,7 +99,8 @@ class _DramaListPageState extends State with UniqueTagMixin { ); } - Widget _buildSortTab(DramaListLogic logic, int index, String title, {bool expand = false}) { + Widget _buildSortTab(DramaListLogic logic, int index, String title, + {bool expand = false}) { final selected = index == logic.sortIndex; final tab = GestureDetector( onTap: () => logic.changeSort(index), @@ -135,7 +141,8 @@ class _DramaListPageState extends State with UniqueTagMixin { child: AnimatedRotation( turns: _sortExpanded ? 0.5 : 0, duration: const Duration(milliseconds: 200), - child: Image.asset('chevron_down.webp'.commonImgPath, width: 16, height: 16), + child: Image.asset('chevron_down.webp'.commonImgPath, + width: 16, height: 16), ), ), ); @@ -143,7 +150,8 @@ class _DramaListPageState extends State with UniqueTagMixin { Widget _buildBody(DramaListLogic logic) { if (logic.isLoading) return const LoadingCenterWidget(); - if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData()); + if (logic.isEmptyData) + return CErrorWidget(retryOnTap: () => logic.loadData()); final list = logic.dataList!; return pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, @@ -159,7 +167,7 @@ class _DramaListPageState extends State with UniqueTagMixin { ), itemCount: list.length, itemBuilder: (context, index) { - final model = list[index]; + final model = list[index]; return DramaCoverCard(mediaInfo: model); }, ), diff --git a/lib/hj_page/drama/drama_tag_detail_logic.dart b/lib/hj_page/drama/drama_tag_detail_logic.dart index f6ceb60..59daf68 100644 --- a/lib/hj_page/drama/drama_tag_detail_logic.dart +++ b/lib/hj_page/drama/drama_tag_detail_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../../hj_model/drama_media_info.dart'; diff --git a/lib/hj_page/drama/drama_tag_detail_page.dart b/lib/hj_page/drama/drama_tag_detail_page.dart index 1c12be0..83d0dc0 100644 --- a/lib/hj_page/drama/drama_tag_detail_page.dart +++ b/lib/hj_page/drama/drama_tag_detail_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/drama/drama_tag_detail_logic.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/drama/drama_tag_detail_logic.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../home/home_cell_style/drama_cover_card.dart'; @@ -20,13 +20,15 @@ class DramaTagDetailPage extends StatefulWidget { /// 进短剧标签页。跳转一律走它,别在调用方自己写 Get.to——不显式传 routeName 时 /// GetX 会用闭包的 runtimeType 拼出 `/DramaTagDetailPage Function()`,埋点反查不到 static Future? to(TagsBean tag) => - Get.to(() => DramaTagDetailPage(tag: tag), routeName: routeName, preventDuplicates: true); + Get.to(() => DramaTagDetailPage(tag: tag), + routeName: routeName, preventDuplicates: true); @override State createState() => _DramaTagDetailPageState(); } -class _DramaTagDetailPageState extends State with UniqueTagMixin { +class _DramaTagDetailPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -71,7 +73,9 @@ class _DramaTagDetailPageState extends State with UniqueTagM titles[i], style: TextStyle( fontSize: 14, - color: i == logic.sortIndex ? Colors.white : const Color(0x59FFFFFF), + color: i == logic.sortIndex + ? Colors.white + : const Color(0x59FFFFFF), ), ), ), @@ -83,7 +87,8 @@ class _DramaTagDetailPageState extends State with UniqueTagM Widget _buildBody(DramaTagDetailLogic logic) { if (logic.isLoading) return const LoadingCenterWidget(); - if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData()); + if (logic.isEmptyData) + return CErrorWidget(retryOnTap: () => logic.loadData()); final list = logic.dataList!; return pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, @@ -99,7 +104,7 @@ class _DramaTagDetailPageState extends State with UniqueTagM ), itemCount: list.length, itemBuilder: (context, index) { - final model = list[index]; + final model = list[index]; return DramaCoverCard(mediaInfo: model); }, ), diff --git a/lib/hj_page/drama/view/drama_bottom_bar.dart b/lib/hj_page/drama/view/drama_bottom_bar.dart index 6f1188c..99aac5e 100644 --- a/lib/hj_page/drama/view/drama_bottom_bar.dart +++ b/lib/hj_page/drama/view/drama_bottom_bar.dart @@ -2,9 +2,9 @@ import 'dart:ui'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// 短剧底部条:信息流「查看完整短剧」入口 / 二级页「观看完整剧集」选集入口 + 自动播放倒计时。 /// 不跟左右菜单一起收:纯净模式(眼睛按钮)下也常驻,这是进整部剧的唯一入口 @@ -55,7 +55,8 @@ class DramaBottomBar extends StatelessWidget { '${highlight ?? ''}$text', maxLines: 1, overflow: TextOverflow.ellipsis, - defaultStyle: const TextStyle(color: Colors.white, fontSize: 13), + defaultStyle: + const TextStyle(color: Colors.white, fontSize: 13), patternList: [ //highlight 是「5s后」这种自己拼的倒计时,不会有正则元字符 if (highlight?.isNotEmpty == true) diff --git a/lib/hj_page/drama/view/drama_episode_sheet.dart b/lib/hj_page/drama/view/drama_episode_sheet.dart index edbe7f3..fcf29d8 100644 --- a/lib/hj_page/drama/view/drama_episode_sheet.dart +++ b/lib/hj_page/drama/view/drama_episode_sheet.dart @@ -2,12 +2,12 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/cupertino.dart' show CupertinoActivityIndicator; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_page/live/live_widget.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_page/live/live_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; /// 短剧选集面板:剧名 + 连载状态 + 分段(1-30/31-60…) + 集数宫格 /// 选中某集后 Get.back(result: 该集下标) @@ -92,13 +92,19 @@ class _DramaEpisodeSheetState extends State { widget.drama?.title ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 16, + fontWeight: FontWeight.w500), ), 18.sizeBoxH, // 连载中·全x集 EasyRichText( '$_updateDesc·共$_total集', - defaultStyle: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 12, height: 1.5), + defaultStyle: TextStyle( + color: Colors.white.withValues(alpha: 0.35), + fontSize: 12, + height: 1.5), patternList: [ //updateDesc 是后端下发的、可能带正则元字符,必须开 hasSpecialCharacters 转义; //空串更要拦住——空 targetString 会编译成 (),在每个位置都命中 @@ -139,7 +145,8 @@ class _DramaEpisodeSheetState extends State { child: Text( '$from-$to', style: TextStyle( - color: Colors.white.withValues(alpha: isSelected ? 0.9 : 0.35), + color: + Colors.white.withValues(alpha: isSelected ? 0.9 : 0.35), fontSize: 14, height: 1.43, ), @@ -171,7 +178,8 @@ class _DramaEpisodeSheetState extends State { Widget? _badgeOf(MediaContent model) { switch (model.accessType) { case 'coin': - return _corner('金币', color: Color(0xffFFCC14),textColor: Color(0xff1F2029)); + return _corner('金币', + color: Color(0xffFFCC14), textColor: Color(0xff1F2029)); case 'bought': return _corner('已购'); default: // free / card 及未知类型不挂角标 @@ -195,7 +203,9 @@ class _DramaEpisodeSheetState extends State { ), borderRadius: BorderRadius.circular(3), ), - child: Text(text, style: TextStyle(color: textColor ?? Colors.white, fontSize: 10, height: 1.6)), + child: Text(text, + style: TextStyle( + color: textColor ?? Colors.white, fontSize: 10, height: 1.6)), ); } @@ -205,8 +215,11 @@ class _DramaEpisodeSheetState extends State { if (count <= 0) { return Center( child: _isLoading - ? const CupertinoActivityIndicator(color: AppColors.actionRed, radius: 10) - : Text('暂无剧集', style: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 12)), + ? const CupertinoActivityIndicator( + color: AppColors.actionRed, radius: 10) + : Text('暂无剧集', + style: TextStyle( + color: Colors.white.withValues(alpha: 0.35), fontSize: 12)), ); } return GridView.builder( @@ -238,7 +251,10 @@ class _DramaEpisodeSheetState extends State { decoration: BoxDecoration( color: isSelected ? const Color(0x0DF68804) : Colors.transparent, borderRadius: BorderRadius.circular(6), - border: Border.all(color: isSelected ? AppColors.actionRed : Colors.white.withValues(alpha: 0.1)), + border: Border.all( + color: isSelected + ? AppColors.actionRed + : Colors.white.withValues(alpha: 0.1)), ), child: Stack( alignment: Alignment.center, @@ -252,7 +268,9 @@ class _DramaEpisodeSheetState extends State { Text( '${model.episodeNumber ?? index + 1}', style: TextStyle( - color: isSelected ? AppColors.actionRed : Colors.white.withValues(alpha: 0.9), + color: isSelected + ? AppColors.actionRed + : Colors.white.withValues(alpha: 0.9), fontSize: isSelected ? 14 : 16, fontWeight: FontWeight.w500, ), diff --git a/lib/hj_page/drama/view/drama_menu.dart b/lib/hj_page/drama/view/drama_menu.dart index d0069f7..94b4320 100644 --- a/lib/hj_page/drama/view/drama_menu.dart +++ b/lib/hj_page/drama/view/drama_menu.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/drama/drama_detail_page.dart'; -import 'package:hgmj/hj_page/drama/drama_tag_detail_page.dart'; -import 'package:hgmj/hj_page/short_video/view/media_action_menu.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/drama/drama_detail_page.dart'; +import 'package:wydj/hj_page/drama/drama_tag_detail_page.dart'; +import 'package:wydj/hj_page/short_video/view/media_action_menu.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:video_player/video_player.dart'; import '../../../tools_base/widget/shrink_wrap.dart'; @@ -94,7 +94,8 @@ class _DramaMenuState extends State { ], ), ), - if (widget.playerCtr != null) CenterPlayPause(controller: widget.playerCtr!), + if (widget.playerCtr != null) + CenterPlayPause(controller: widget.playerCtr!), ], ), ); @@ -129,25 +130,31 @@ class _DramaMenuState extends State { title, maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), ), ), - if (widget.showEntry) Image.asset('chevron_right.webp'.videoPath, width: 20, height: 20), + if (widget.showEntry) + Image.asset('chevron_right.webp'.videoPath, width: 20, height: 20), ], ); return Container( padding: EdgeInsets.only(top: gapValue), - child: widget.showEntry ? InkWell(enableFeedback: false, onTap: _openDrama, child: content) : content, + child: widget.showEntry + ? InkWell(enableFeedback: false, onTap: _openDrama, child: content) + : content, ); } Widget _buildTagItem() { final episodeText = Text( "第${_video?.episodeNo ?? 1}集", - style: const TextStyle(color: Colors.white, fontSize: 13, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, fontSize: 13, fontWeight: FontWeight.w500), ); if (_video?.tags?.isNotEmpty != true) { - return Container(padding: EdgeInsets.only(top: gapValue), child: episodeText); + return Container( + padding: EdgeInsets.only(top: gapValue), child: episodeText); } return Container( padding: EdgeInsets.only(top: gapValue), @@ -181,7 +188,9 @@ class _DramaMenuState extends State { color: const Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(3), ), - child: Text(e.name ?? '', style: const TextStyle(color: Color(0xffffffff), fontSize: 11)), + child: Text(e.name ?? '', + style: const TextStyle( + color: Color(0xffffffff), fontSize: 11)), ), )) .toList() ?? diff --git a/lib/hj_page/drama/view/drama_paywall_view.dart b/lib/hj_page/drama/view/drama_paywall_view.dart index a9e10f7..66a6be9 100644 --- a/lib/hj_page/drama/view/drama_paywall_view.dart +++ b/lib/hj_page/drama/view/drama_paywall_view.dart @@ -1,18 +1,18 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/cupertino.dart' show CupertinoActivityIndicator; import 'package:flutter/material.dart'; -import 'package:hgmj/alert/video/buy_vip_alert.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/pay_order_source.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart'; -import 'package:hgmj/hj_utils/pay/pay_manager.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/net_code.dart'; +import 'package:wydj/alert/video/buy_vip_alert.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/mine/mine_vip/pay_order_source.dart'; +import 'package:wydj/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart'; +import 'package:wydj/hj_utils/pay/pay_manager.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/net_code.dart'; import 'package:uuid/uuid.dart'; /// 短剧付费墙:只有「金币解锁」和「开通短剧卡」两个按钮,没有第三种选择。 @@ -103,7 +103,8 @@ class _DramaPaywallViewState extends State { if (!mounted) return; } if (_balance < need) { - await CoinPayBottomSheet.show(sourcePage: PaySourcePage.dramaPaywall, orderTrack: _orderTrack); + await CoinPayBottomSheet.show( + sourcePage: PaySourcePage.dramaPaywall, orderTrack: _orderTrack); await globalStore.refreshWallet(); if (!mounted || _balance < need) return; // 没充成功,停在付费墙 } @@ -149,9 +150,11 @@ class _DramaPaywallViewState extends State { } /// 解锁失败:只处理余额不足,其余保留 _requestId,重试复用同一个键别重复扣费 - Future _onUnlockFailed(BaseRespBean? resp, {required bool allowRetry}) async { + Future _onUnlockFailed(BaseRespBean? resp, + {required bool allowRetry}) async { if (resp?.code != Code.NOT_ENOUGH_MONEY) return; - await CoinPayBottomSheet.show(sourcePage: PaySourcePage.dramaPaywall, orderTrack: _orderTrack); + await CoinPayBottomSheet.show( + sourcePage: PaySourcePage.dramaPaywall, orderTrack: _orderTrack); _requestId = null; // 充值后是新的一次解锁,换新键;沿用旧键会拿回刚才那次「余额不足」 await globalStore.refreshWallet(); if (!mounted) return; @@ -167,7 +170,8 @@ class _DramaPaywallViewState extends State { if (_busy) return; _busy = true; try { - await BuyVipAlert.show(vipId: Config.shortDramaCardId, orderTrack: _orderTrack); + await BuyVipAlert.show( + vipId: Config.shortDramaCardId, orderTrack: _orderTrack); if (!mounted) return; setState(() => _unlocking = true); await widget.onUnlocked(byCard: true).whenComplete(_stopUnlocking); @@ -190,48 +194,53 @@ class _DramaPaywallViewState extends State { color: const Color.fromRGBO(0, 7, 18, 0.8), //已经付过钱了,别再让人对着解锁按钮干等:这层遮罩留着盖住还没建好的播放器 child: _unlocking - ? const CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15) + ? const CupertinoActivityIndicator( + color: AppColors.actionRed, radius: 15) : Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - paywall?.titleUI ?? '更多精彩解锁即享', - style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600), - ), - 18.sizeBoxH, - EasyRichText( - '剩余金币数:$_coin', - defaultStyle: const TextStyle(color: Colors.white, fontSize: 14), - patternList: [ - //纯数字,前缀里没有数字所以不会误命中 - EasyRichTextPattern( - targetString: _coin, - matchOption: 'first', - style: const TextStyle(color: AppColors.actionRed), - ), - ], - ), - 18.sizeBoxH, - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _btn( - title: paywall?.coinButtonUI ?? '金币解锁', - colors: const [Color(0xffFFE8BE), Color(0xffE6B764)], - textColor: const Color(0xff694923), - onTap: _onCoinUnlock, - ), - 18.sizeBoxW, - _btn( - title: paywall?.cardButtonUI ?? '开通短剧卡免费看', - colors: const [Color(0xffFF6E6E), Color(0xffFF4D4D)], - textColor: Colors.white, - onTap: _onCardTap, - ), - ], - ), - ], - ), + mainAxisSize: MainAxisSize.min, + children: [ + Text( + paywall?.titleUI ?? '更多精彩解锁即享', + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600), + ), + 18.sizeBoxH, + EasyRichText( + '剩余金币数:$_coin', + defaultStyle: + const TextStyle(color: Colors.white, fontSize: 14), + patternList: [ + //纯数字,前缀里没有数字所以不会误命中 + EasyRichTextPattern( + targetString: _coin, + matchOption: 'first', + style: const TextStyle(color: AppColors.actionRed), + ), + ], + ), + 18.sizeBoxH, + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _btn( + title: paywall?.coinButtonUI ?? '金币解锁', + colors: const [Color(0xffFFE8BE), Color(0xffE6B764)], + textColor: const Color(0xff694923), + onTap: _onCoinUnlock, + ), + 18.sizeBoxW, + _btn( + title: paywall?.cardButtonUI ?? '开通短剧卡免费看', + colors: const [Color(0xffFF6E6E), Color(0xffFF4D4D)], + textColor: Colors.white, + onTap: _onCardTap, + ), + ], + ), + ], + ), ); } diff --git a/lib/hj_page/drama/view/drama_speed_sheet.dart b/lib/hj_page/drama/view/drama_speed_sheet.dart index d6f4084..fc656e8 100644 --- a/lib/hj_page/drama/view/drama_speed_sheet.dart +++ b/lib/hj_page/drama/view/drama_speed_sheet.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// 短剧倍速弹窗:选中档主题色 + 右侧对勾,点击直接 Get.back(倍速) class DramaSpeedSheet extends StatelessWidget { @@ -16,7 +16,8 @@ class DramaSpeedSheet extends StatelessWidget { const DramaSpeedSheet({super.key, this.speed = normalSpeed}); - static Future show({double speed = normalSpeed}) => Get.bottomSheet( + static Future show({double speed = normalSpeed}) => + Get.bottomSheet( DramaSpeedSheet(speed: speed), backgroundColor: Colors.transparent, // 圆角由内部 Container 画,别让默认底色露出直角 ); @@ -28,14 +29,16 @@ class DramaSpeedSheet extends StatelessWidget { child: Container( width: double.infinity, //底部 6 + 末档自带的 12 = 设计稿的 18 - padding: EdgeInsets.fromLTRB(16, 18, 16, 6 + Get.mediaQuery.padding.bottom), + padding: + EdgeInsets.fromLTRB(16, 18, 16, 6 + Get.mediaQuery.padding.bottom), decoration: const BoxDecoration( color: AppColors.primaryColor, borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, // 分割线要全宽,默认 center 会把它挤成 0 + crossAxisAlignment: + CrossAxisAlignment.stretch, // 分割线要全宽,默认 center 会把它挤成 0 children: [ //标题行:左侧收起箭头 + 标题在剩余空间居中 SizedBox( @@ -44,7 +47,8 @@ class DramaSpeedSheet extends StatelessWidget { children: [ GestureDetector( onTap: () => Get.back(), - child: Image.asset('chevron_down.webp'.commonImgPath, width: 24, height: 24), + child: Image.asset('chevron_down.webp'.commonImgPath, + width: 24, height: 24), ), Expanded( child: Text( @@ -89,12 +93,15 @@ class DramaSpeedSheet extends StatelessWidget { style: TextStyle( fontSize: 16, height: 22 / 16, - color: isSelected ? AppColors.actionRed : Colors.white.withValues(alpha: .9), + color: isSelected + ? AppColors.actionRed + : Colors.white.withValues(alpha: .9), fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400, ), ), ), - if (isSelected) Image.asset('check.webp'.commonImgPath, width: 24, height: 24), + if (isSelected) + Image.asset('check.webp'.commonImgPath, width: 24, height: 24), ], ), ), diff --git a/lib/hj_page/drama/view/drama_video_player.dart b/lib/hj_page/drama/view/drama_video_player.dart index b5c357c..e1f05f1 100644 --- a/lib/hj_page/drama/view/drama_video_player.dart +++ b/lib/hj_page/drama/view/drama_video_player.dart @@ -1,18 +1,18 @@ import 'package:flutter/cupertino.dart' show CupertinoActivityIndicator; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/drama/drama_detail_page.dart'; -import 'package:hgmj/hj_page/drama/view/drama_bottom_bar.dart'; -import 'package:hgmj/hj_page/drama/view/drama_menu.dart'; -import 'package:hgmj/hj_page/drama/view/drama_paywall_view.dart'; -import 'package:hgmj/hj_page/drama/view/drama_video_player_logic.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_page/short_video/view/video_progress_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/like_burst_view.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/drama/drama_detail_page.dart'; +import 'package:wydj/hj_page/drama/view/drama_bottom_bar.dart'; +import 'package:wydj/hj_page/drama/view/drama_menu.dart'; +import 'package:wydj/hj_page/drama/view/drama_paywall_view.dart'; +import 'package:wydj/hj_page/drama/view/drama_video_player_logic.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_page/short_video/view/video_progress_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/like_burst_view.dart'; import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -51,7 +51,8 @@ class DramaVideoPlayer extends StatefulWidget { } // PageView 里 2~3 条同时存活,用 per-实例唯一 tag 隔离各自的播放器 logic -class _DramaVideoPlayerState extends State with UniqueTagMixin { +class _DramaVideoPlayerState extends State + with UniqueTagMixin { //进度条压暗档位:滑动中 / 挂着付费墙都用这一档 static const _dimOpacity = 0.4; @@ -69,7 +70,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin startSeconds: widget.startSeconds, onCardUnlocked: widget.onCardUnlocked, //Feed 里这一集播完 = 进入连播,直接把用户带进二级页;二级页自己传 onCompleted 切下一集 - onCompleted: widget.onCompleted ?? (widget.showEntry ? _onFeedCompleted : null), + onCompleted: + widget.onCompleted ?? (widget.showEntry ? _onFeedCompleted : null), onRemaining: widget.onRemaining, ); @@ -78,7 +80,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin //信息栏要让开下方这一摞,再留设计稿的 18: //进度条本体 28 + 进度条自己往下让的距离(二级页= 剧集条48 + 底部安全区) + Feed 才有的剧集条 48 - double get _menuBottom => 28 + (widget.progressBottom ?? 0) + (widget.showEntry ? 48 : 0) + 18; + double get _menuBottom => + 28 + (widget.progressBottom ?? 0) + (widget.showEntry ? 48 : 0) + 18; @override void didUpdateWidget(covariant DramaVideoPlayer oldWidget) { @@ -156,7 +159,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin Positioned.fill( child: Visibility( visible: logic.showPaywall, - child: DramaPaywallView(video: logic.video, onUnlocked: logic.onUnlocked), + child: DramaPaywallView( + video: logic.video, onUnlocked: logic.onUnlocked), ), ), LikeBurstView(controller: _likeBurst), @@ -172,7 +176,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin if (widget.showEntry) DramaBottomBar( leadingIcon: 'full_drama.webp', - text: '查看完整短剧·全${logic.video?.dramaInfo?.totalEpisode ?? 0}集', + text: + '查看完整短剧·全${logic.video?.dramaInfo?.totalEpisode ?? 0}集', tailIcon: 'chevron_right.webp', onTap: _openDrama, ), @@ -205,7 +210,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin () => DramaDetailPage( drama: widget.videoInfo?.dramaInfo, initialIndex: index < 0 ? 0 : index, - initialSeconds: startNext ? 0 : (_logic.playerCtr?.value.position.inSeconds ?? 0), + initialSeconds: + startNext ? 0 : (_logic.playerCtr?.value.position.inSeconds ?? 0), ), ); } @@ -223,7 +229,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin final (minSeek, maxSeek) = logic.previewRange; final Widget bar = VideoProgressWidget( controller: logic.playerCtr, - padding: EdgeInsets.only(left: 12, right: 12, bottom: widget.progressBottom ?? 0), + padding: EdgeInsets.only( + left: 12, right: 12, bottom: widget.progressBottom ?? 0), //试看放的是完整视频,可拖区间夹在 [previewStart, previewStart+previewSeconds];挂墙后整条禁拖。 //与长视频页同一套(VideoMenuView 的 minSeek/maxSeek + enableSeek) minSeekDuration: minSeek, @@ -231,7 +238,8 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin enableSeek: !logic.showPaywall, ); final scrolling = widget.isScrolling; - if (scrolling == null) return Opacity(opacity: logic.showPaywall ? _dimOpacity : 1, child: bar); + if (scrolling == null) + return Opacity(opacity: logic.showPaywall ? _dimOpacity : 1, child: bar); return ValueListenableBuilder( valueListenable: scrolling, //只做透明+屏蔽点击,不能用 Visibility——它会卸载 child,重建时 initState 会拿旧 controller 挂监听。 @@ -251,12 +259,16 @@ class _DramaVideoPlayerState extends State with UniqueTagMixin /// 未就绪/缓冲中的居中转圈。挂着付费墙时不转——那不是在加载,是没权限 Widget _bufferLoading(DramaVideoPlayerLogic logic) { if (logic.showPaywall) return const SizedBox(); - const indicator = Center(child: CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15)); + const indicator = Center( + child: + CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15)); final ctr = logic.playerCtr; if (ctr == null) return indicator; // 控制器还没建好,同样转圈 return ValueListenableBuilder( valueListenable: ctr, - builder: (_, value, __) => !value.isInitialized || value.isBuffering ? indicator : const SizedBox(), + builder: (_, value, __) => !value.isInitialized || value.isBuffering + ? indicator + : const SizedBox(), ); } } diff --git a/lib/hj_page/drama/view/drama_video_player_logic.dart b/lib/hj_page/drama/view/drama_video_player_logic.dart index 63faa9f..468cc28 100644 --- a/lib/hj_page/drama/view/drama_video_player_logic.dart +++ b/lib/hj_page/drama/view/drama_video_player_logic.dart @@ -1,17 +1,18 @@ import 'package:flutter/widgets.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/cache/history/drama_resume_store.dart'; -import 'package:hgmj/hj_page/short_video/view/video_player_base_logic.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/cache/history/drama_resume_store.dart'; +import 'package:wydj/hj_page/short_video/view/video_player_base_logic.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:visibility_detector/visibility_detector.dart'; /// 单集短剧的播放逻辑,PageView 每项一个实例。 /// 能不能播只认服务端 canPlay,拦不住就挂付费墙;续播位置纯本地记 -class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObserver { +class DramaVideoPlayerLogic extends VideoPlayerBaseLogic + with WidgetsBindingObserver { /// 开卡放行广播:PageView 预建的上下两条已各自问过 canPlay,不叫醒就还挂着买卡前那道墙 static final ValueNotifier unlockRevision = ValueNotifier(0); @@ -128,7 +129,8 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse showPaywall = false; notify(); } - playerCtr?.seekTo(Duration(seconds: _isPreview ? _previewStart : 0)); //试看重看要回到起播点,不是 0 + playerCtr?.seekTo( + Duration(seconds: _isPreview ? _previewStart : 0)); //试看重看要回到起播点,不是 0 syncPlay(); _markWatched(); // 滑到这条才算看过:onInit 预建时 isCurrent 还是 false } @@ -165,11 +167,13 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse int get _previewStart => videoInfo?.dramaEpisode?.previewStart ?? 0; //试看看到第几秒为止:起播点 + 时长,previewSeconds 是时长不是绝对位置 - int get _previewEnd => _previewStart + (videoInfo?.dramaEpisode?.previewSeconds ?? 0); + int get _previewEnd => + _previewStart + (videoInfo?.dramaEpisode?.previewSeconds ?? 0); /// 试看可拖区间 [起, 止],不在试看态时 (null, null)。同长视频页 VideoMenuView._calcSeekRange - (Duration?, Duration?) get previewRange => - _isPreview ? (Duration(seconds: _previewStart), Duration(seconds: _previewEnd)) : (null, null); + (Duration?, Duration?) get previewRange => _isPreview + ? (Duration(seconds: _previewStart), Duration(seconds: _previewEnd)) + : (null, null); /// 没解锁 + 开关开 + 有地址 + 有时长,刷剧和连播两个页面一视同仁。 /// 秒数必须 >0:试看地址给的是完整视频、后端不裁片,配成 0 就是整集免费送 @@ -218,8 +222,10 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse episode.previewEnabled ??= prev?.previewEnabled; episode.previewStart ??= prev?.previewStart; episode.previewSeconds ??= prev?.previewSeconds; - if (episode.previewVideoUrl?.isNotEmpty != true) episode.previewVideoUrl = prev?.previewVideoUrl; - if (episode.previewH265Url?.isNotEmpty != true) episode.previewH265Url = prev?.previewH265Url; + if (episode.previewVideoUrl?.isNotEmpty != true) + episode.previewVideoUrl = prev?.previewVideoUrl; + if (episode.previewH265Url?.isNotEmpty != true) + episode.previewH265Url = prev?.previewH265Url; final usePreview = _canPreview(episode); target ?..dramaEpisode = episode @@ -246,10 +252,13 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse //从刷剧页点进来要接着那边的秒数往下放,试看片同样接着放。 //试看不认本地续播记录(记的是正片进度,一跳就越过试看区间),没带位置就从后端给的 previewStart 起 final last = isSerial && !usePreview ? dramaResume.of(_mediaId) : null; - final resume = startSeconds > 0 ? startSeconds : (last?.contentId == episode.id ? last!.progressSeconds : 0); + final resume = startSeconds > 0 + ? startSeconds + : (last?.contentId == episode.id ? last!.progressSeconds : 0); final seconds = usePreview && resume <= 0 ? _previewStart : resume; startSeconds = 0; - if (seconds > 0 && !isClosed) await playerCtr?.seekTo(Duration(seconds: seconds)); + if (seconds > 0 && !isClosed) + await playerCtr?.seekTo(Duration(seconds: seconds)); if (isSerial) _resumeDone = !usePreview; // 试看那段不落进度,正片才从这一刻起作数 if (isClosed) return; //位置定好才撤墙,中间不露转圈。播放器建失败也照撤—— @@ -268,7 +277,8 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse } void _applySpeed() { - if (playerCtr?.value.isInitialized == true) playerCtr?.setPlaybackSpeed(speed); + if (playerCtr?.value.isInitialized == true) + playerCtr?.setPlaybackSpeed(speed); } /// 长按 2 倍抬手后回到用户选的档位,不是基类写死的 1.0 @@ -357,7 +367,9 @@ class DramaVideoPlayerLogic extends VideoPlayerBaseLogic with WidgetsBindingObse final ctr = playerCtr; if (seconds == null && ctr?.value.isInitialized != true) return; final now = DateTime.now(); - if (throttle && _savedAt != null && now.difference(_savedAt!).inSeconds < 10) return; + if (throttle && + _savedAt != null && + now.difference(_savedAt!).inSeconds < 10) return; _savedAt = now; dramaResume.record( mediaId: _mediaId, diff --git a/lib/hj_page/find/acg_game_detail_logic.dart b/lib/hj_page/find/acg_game_detail_logic.dart index fa94686..62b88cc 100644 --- a/lib/hj_page/find/acg_game_detail_logic.dart +++ b/lib/hj_page/find/acg_game_detail_logic.dart @@ -3,17 +3,18 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/history_util.dart'; +import 'package:wydj/hj_utils/const.dart'; import '../../alert/video/video_buy_bottom_sheet.dart'; -class AcgGameDetailLogic extends GetxController with GetTickerProviderStateMixin { +class AcgGameDetailLogic extends GetxController + with GetTickerProviderStateMixin { // 外部传入:游戏(资源) ID final String gameId; AcgGameDetailLogic({this.gameId = ''}); diff --git a/lib/hj_page/find/acg_game_detail_page.dart b/lib/hj_page/find/acg_game_detail_page.dart index dd1c424..bcd0c8d 100644 --- a/lib/hj_page/find/acg_game_detail_page.dart +++ b/lib/hj_page/find/acg_game_detail_page.dart @@ -2,20 +2,20 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/comment_views.dart'; -import 'package:hgmj/hj_page/find/acg_game_detail_logic.dart'; -import 'package:hgmj/hj_page/find/acg_game_recommend_page.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/sliver_delegate.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/comment_views.dart'; +import 'package:wydj/hj_page/find/acg_game_detail_logic.dart'; +import 'package:wydj/hj_page/find/acg_game_recommend_page.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/sliver_delegate.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:mobkit_dashed_border/mobkit_dashed_border.dart'; import '../../hj_utils/widget_util.dart'; @@ -30,7 +30,8 @@ class AcgGameDetailPage extends StatefulWidget { State createState() => _AcgGameDetailPageState(); } -class _AcgGameDetailPageState extends State with UniqueTagMixin { +class _AcgGameDetailPageState extends State + with UniqueTagMixin { // 详情可自我堆叠(相关推荐→再开详情),uniqueTag 由 UniqueTagMixin 提供,隔离多实例 logic late final AcgGameDetailLogic logic = AcgGameDetailLogic(gameId: widget.id); @@ -108,7 +109,8 @@ class _AcgGameDetailPageState extends State with UniqueTagMix labelColor: Colors.white, labelStyle: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), unselectedLabelColor: Color(0xffE0E0E0), - unselectedLabelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 16, fontWeight: FontWeight.w400), indicator: CustomIndicator( width: 16, height: 4, @@ -133,7 +135,8 @@ class _AcgGameDetailPageState extends State with UniqueTagMix padding: EdgeInsets.only(left: 2), child: Text( '${logic.totalCtCount.value == 0 ? '' : logic.totalCtCount.value}', - style: textStyle(12, AppColors.actionRed, FontWeight.w500), + style: + textStyle(12, AppColors.actionRed, FontWeight.w500), ), ), ), @@ -173,12 +176,14 @@ class _AcgGameDetailPageState extends State with UniqueTagMix ), 18.sizeBoxH, _buildRightWidget(), - if (logic.detailInfo?.tags != null && logic.detailInfo?.tags?.isNotEmpty == true) ...[ + if (logic.detailInfo?.tags != null && + logic.detailInfo?.tags?.isNotEmpty == true) ...[ 20.sizeBoxH, Wrap( spacing: 10, runSpacing: 0, - children: List.generate(logic.detailInfo?.tags?.length ?? 0, (index) { + children: + List.generate(logic.detailInfo?.tags?.length ?? 0, (index) { final tag = logic.detailInfo?.tags?[index]; return Container( decoration: BoxDecoration( @@ -220,7 +225,8 @@ class _AcgGameDetailPageState extends State with UniqueTagMix Row( children: [ Spacer(), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.onLinkClickAction(), child: Container( padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), @@ -236,7 +242,10 @@ class _AcgGameDetailPageState extends State with UniqueTagMix ), child: EasyRichText( '点击复制「种子资源」', - defaultStyle: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), + defaultStyle: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), patternList: [ EasyRichTextPattern( targetString: '「种子资源」', @@ -251,7 +260,8 @@ class _AcgGameDetailPageState extends State with UniqueTagMix ) ] else ...[ //金币解锁 - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.showAlert(), child: Container( height: 124, @@ -282,7 +292,8 @@ class _AcgGameDetailPageState extends State with UniqueTagMix ), ), 18.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.showAlert(), child: Container( height: 44, @@ -312,16 +323,20 @@ class _AcgGameDetailPageState extends State with UniqueTagMix return Row( children: [ //观看 - _buildStatusItem('eye_white.webp'.commonImgPath, logic.detailInfo?.playCount.countStr ?? '', false), + _buildStatusItem('eye_white.webp'.commonImgPath, + logic.detailInfo?.playCount.countStr ?? '', false), 30.sizeBoxW, //收藏 GetBuilder( tag: uniqueTag, id: 'collect', - builder: (_) => InkWell(enableFeedback: false, + builder: (_) => InkWell( + enableFeedback: false, onTap: logic.onCollectionAction, child: _buildStatusItem( - logic.detailInfo?.hasCollected == true ? 'collect_red.png'.commonImgPath : 'collect_path.png'.commonImgPath, + logic.detailInfo?.hasCollected == true + ? 'collect_red.png'.commonImgPath + : 'collect_path.png'.commonImgPath, logic.detailInfo?.collectCount?.countOr("0") ?? '', logic.detailInfo?.hasCollected == true, ), @@ -332,10 +347,13 @@ class _AcgGameDetailPageState extends State with UniqueTagMix GetBuilder( tag: uniqueTag, id: 'like', - builder: (_) => InkWell(enableFeedback: false, + builder: (_) => InkWell( + enableFeedback: false, onTap: logic.onLikeAction, child: _buildStatusItem( - logic.detailInfo?.hasLiked == true ? 'like_red.png'.commonImgPath : 'like_empty.png'.communityPath, + logic.detailInfo?.hasLiked == true + ? 'like_red.png'.commonImgPath + : 'like_empty.png'.communityPath, logic.detailInfo?.likeCount?.countOr("0") ?? '', logic.detailInfo?.hasLiked == true, ), diff --git a/lib/hj_page/find/acg_game_recommend_logic.dart b/lib/hj_page/find/acg_game_recommend_logic.dart index dbe8b73..542677b 100644 --- a/lib/hj_page/find/acg_game_recommend_logic.dart +++ b/lib/hj_page/find/acg_game_recommend_logic.dart @@ -1,7 +1,7 @@ -import 'package:hgmj/hj_model/home/video_list_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/home/video_list_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class AcgGameRecommendLogic extends ListBaseLogic { VideoModel? mediaModel; @@ -16,7 +16,8 @@ class AcgGameRecommendLogic extends ListBaseLogic { loadData({int pageNum = 1, bool showLoading = false, int size = 10}) async { dataList ??= []; - VideoListResp? resp = await CommonService.getRecommendList(pageNumber: pageNum, pageSize: 10, tagId: mediaModel?.tags?.first.id); + VideoListResp? resp = await CommonService.getRecommendList( + pageNumber: pageNum, pageSize: 10, tagId: mediaModel?.tags?.first.id); if (resp != null) { currentPage = pageNum; @@ -24,7 +25,9 @@ class AcgGameRecommendLogic extends ListBaseLogic { dataList?.addAll(resp.videos ?? []); } update(); - resp?.hasNext == true ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); + resp?.hasNext == true + ? refreshCtr?.loadComplete() + : refreshCtr?.loadNoData(); refreshCtr?.refreshCompleted(); } diff --git a/lib/hj_page/find/acg_game_recommend_page.dart b/lib/hj_page/find/acg_game_recommend_page.dart index 7b023a1..1a0ae79 100644 --- a/lib/hj_page/find/acg_game_recommend_page.dart +++ b/lib/hj_page/find/acg_game_recommend_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/find/acg_game_recommend_logic.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/find/acg_game_recommend_logic.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../home/home_cell_style/video_simple_cell.dart'; diff --git a/lib/hj_page/find/pic_collect/album_action_widget.dart b/lib/hj_page/find/pic_collect/album_action_widget.dart index ed7aeb2..625241a 100644 --- a/lib/hj_page/find/pic_collect/album_action_widget.dart +++ b/lib/hj_page/find/pic_collect/album_action_widget.dart @@ -2,17 +2,17 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/alert/video/share_media_dialog.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/comment/comment_alert.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/alert/video/share_media_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/comment/comment_alert.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:like_button/like_button.dart'; ///图集底部操作按钮组 @@ -21,7 +21,8 @@ class AlbumActionWidget extends StatefulWidget { final int currentIndex; //当前顶部那张的下标,0 基 final int? total; //显示的总张数,未传则取 seriesCover.length - const AlbumActionWidget({super.key, this.videoModel, this.currentIndex = 0, this.total}); + const AlbumActionWidget( + {super.key, this.videoModel, this.currentIndex = 0, this.total}); @override State createState() => _AlbumActionWidgetState(); @@ -49,19 +50,23 @@ class _AlbumActionWidgetState extends State { _actionItem( 'share_grey_pic.png'.commonImgPath, '分享', - onTap: () => Get.dialog(ShareMediaDialog(videoModel: model), useSafeArea: false), + onTap: () => Get.dialog(ShareMediaDialog(videoModel: model), + useSafeArea: false), ), //页码 1/3 Container( padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 2), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(20)), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text('${widget.currentIndex + 1}', - style: const TextStyle(color: AppColors.actionRed, fontSize: 12)), + style: const TextStyle( + color: AppColors.actionRed, fontSize: 12)), Text('/${widget.total ?? model?.seriesCover?.length ?? 0}', - style: const TextStyle(color: Color(0xff3D3D3D), fontSize: 12)), + style: const TextStyle( + color: Color(0xff3D3D3D), fontSize: 12)), ], ), ), @@ -75,13 +80,16 @@ class _AlbumActionWidgetState extends State { return LikeButton( size: 20, isLiked: model?.vidStatus?.hasLiked ?? false, - circleColor: CircleColor(start: AppColors.actionRed, end: AppColors.actionRed), + circleColor: + CircleColor(start: AppColors.actionRed, end: AppColors.actionRed), bubblesColor: BubblesColor( dotPrimaryColor: AppColors.actionRed, dotSecondaryColor: AppColors.actionRed, ), likeBuilder: (isLiked) => Image.asset( - isLiked ? 'like_red.png'.commonImgPath : 'video_like_border.png'.videoPath, + isLiked + ? 'like_red.png'.commonImgPath + : 'video_like_border.png'.videoPath, width: 20, height: 20, color: isLiked ? AppColors.actionRed : const Color(0xff989898), @@ -89,7 +97,9 @@ class _AlbumActionWidgetState extends State { likeCount: model?.likeCount ?? 0, countBuilder: (count, isLiked, text) => Text( count.countOr('点赞'), - style: TextStyle(color: isLiked ? AppColors.actionRed : const Color(0xff989898), fontSize: 12), + style: TextStyle( + color: isLiked ? AppColors.actionRed : const Color(0xff989898), + fontSize: 12), ), onTap: (isLiked) async { final hasLiked = model?.vidStatus?.hasLiked ?? false; @@ -118,25 +128,31 @@ class _AlbumActionWidgetState extends State { return LikeButton( size: 20, isLiked: model?.vidStatus?.hasCollected ?? false, - circleColor: CircleColor(start: AppColors.actionRed, end: AppColors.actionRed), + circleColor: + CircleColor(start: AppColors.actionRed, end: AppColors.actionRed), bubblesColor: BubblesColor( dotPrimaryColor: AppColors.actionRed, dotSecondaryColor: AppColors.actionRed, ), likeBuilder: (isLiked) => Image.asset( - isLiked ? 'collect_red.png'.commonImgPath : 'collect_empty.png'.commonImgPath, + isLiked + ? 'collect_red.png'.commonImgPath + : 'collect_empty.png'.commonImgPath, width: 20, color: isLiked ? AppColors.actionRed : const Color(0xff989898), ), likeCount: model?.collectCount ?? 0, countBuilder: (count, isLiked, text) => Text( count.countOr('收藏'), - style: TextStyle(color: isLiked ? AppColors.actionRed : const Color(0xff989898), fontSize: 12), + style: TextStyle( + color: isLiked ? AppColors.actionRed : const Color(0xff989898), + fontSize: 12), ), onTap: (isLiked) async { final hasCollected = model?.vidStatus?.hasCollected ?? false; final count = model?.collectCount ?? 0; - final isOk = await MineService.postCollect(model?.id, 'PIC', !hasCollected); + final isOk = + await MineService.postCollect(model?.id, 'PIC', !hasCollected); //失败不动本地状态,返回原值让按钮回弹 if (!isOk) return hasCollected; model?.collectCount = max(0, count + (hasCollected ? -1 : 1)); @@ -149,7 +165,8 @@ class _AlbumActionWidgetState extends State { } //图标 + 文字按钮(评论、分享共用) - Widget _actionItem(String imagePath, String title, {GestureTapCallback? onTap}) { + Widget _actionItem(String imagePath, String title, + {GestureTapCallback? onTap}) { return InkWell( enableFeedback: false, onTap: onTap, @@ -160,7 +177,8 @@ class _AlbumActionWidgetState extends State { children: [ Image.asset(imagePath, width: 20, color: const Color(0xff989898)), 3.sizeBoxW, - Text(title, style: const TextStyle(color: Color(0xff989898), fontSize: 12)), + Text(title, + style: const TextStyle(color: Color(0xff989898), fontSize: 12)), ], ), ), diff --git a/lib/hj_page/find/pic_collect/pics_detail_logic.dart b/lib/hj_page/find/pic_collect/pics_detail_logic.dart index f36d706..315ce64 100644 --- a/lib/hj_page/find/pic_collect/pics_detail_logic.dart +++ b/lib/hj_page/find/pic_collect/pics_detail_logic.dart @@ -1,13 +1,13 @@ import 'dart:math'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/pay_order_source.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/mine/mine_vip/pay_order_source.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/history_util.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import '../../../alert/video/video_buy_bottom_sheet.dart'; import '../../mine/mine_vip/mine_charge_vip_page.dart'; @@ -36,7 +36,9 @@ class PicsDetailLogic extends GetxController { //未解锁时放出几张:freeTime 为 0(后端没配)兜底 8 张,否则按 freeTime,都不超过总张数 //freeTime 为 null 走后半段算 0 张,与原逻辑一致 - int get lockCount => videoModel?.freeTime == 0 ? min(8, covers.length) : min(videoModel?.freeTime ?? 0, covers.length); + int get lockCount => videoModel?.freeTime == 0 + ? min(8, covers.length) + : min(videoModel?.freeTime ?? 0, covers.length); @override void onReady() { @@ -56,14 +58,20 @@ class PicsDetailLogic extends GetxController { //解锁:金币走购买弹窗,会员走开通弹窗 void showBuy() async { if (isCoinLock) { - final res = await Get.bottomSheet(VideoBuyBottomSheet(video: videoModel!)); + final res = + await Get.bottomSheet(VideoBuyBottomSheet(video: videoModel!)); if (res == true) { videoModel?.vidStatus?.hasPaid = true; update(); } } else if (videoModel?.lockType == 2) { //Get.dialog(VipACGDialog()); - Get.to(MineChargeVipPage(sourcePage: PaySourcePage.vipCenter,), preventDuplicates: false,); + Get.to( + MineChargeVipPage( + sourcePage: PaySourcePage.vipCenter, + ), + preventDuplicates: false, + ); } } } diff --git a/lib/hj_page/find/pic_collect/pics_detail_page.dart b/lib/hj_page/find/pic_collect/pics_detail_page.dart index d57f6d2..5d197bd 100644 --- a/lib/hj_page/find/pic_collect/pics_detail_page.dart +++ b/lib/hj_page/find/pic_collect/pics_detail_page.dart @@ -3,16 +3,16 @@ import 'dart:ui'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/widget_util.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/widget_util.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import '../../mine/mine_share/mine_share_page.dart'; import 'album_action_widget.dart'; @@ -40,7 +40,8 @@ class _PicsDetailPageState extends State with UniqueTagMixin { builder: (logic) { if (logic.videoModel == null) return LoadingCenterWidget(); //拉失败后 videoModel 是空壳,靠 id 判断 - if (logic.videoModel?.id == null) return CErrorWidget(retryOnTap: () => logic.loadData()); + if (logic.videoModel?.id == null) + return CErrorWidget(retryOnTap: () => logic.loadData()); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -49,13 +50,15 @@ class _PicsDetailPageState extends State with UniqueTagMixin { InkWell( enableFeedback: false, onTap: () => Get.back(), - child: Icon(Icons.arrow_back_ios_new, color: Colors.white, size: 24), + child: Icon(Icons.arrow_back_ios_new, + color: Colors.white, size: 24), ), 4.sizeBoxW, Expanded( child: Text( logic.videoModel?.title ?? '', - style: textStyle(16, Colors.white.withValues(alpha: .9), FontWeight.w800), + style: textStyle(16, Colors.white.withValues(alpha: .9), + FontWeight.w800), maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -68,7 +71,9 @@ class _PicsDetailPageState extends State with UniqueTagMixin { builder: (_, positions, __) => AlbumActionWidget( videoModel: logic.videoModel, currentIndex: positions.isEmpty ? 0 : positions.first.index, - total: logic.isUnlocked ? logic.covers.length : logic.lockCount, + total: logic.isUnlocked + ? logic.covers.length + : logic.lockCount, ), ), ], @@ -89,13 +94,19 @@ class _PicsDetailPageState extends State with UniqueTagMixin { itemScrollController: logic.itemScrollCtr, itemCount: count, itemBuilder: (_, index) { - final image = NetworkImageLoader(imageUrl: covers[index], borderRadius: 0); + final image = + NetworkImageLoader(imageUrl: covers[index], borderRadius: 0); if (isUnlocked) { - return GestureDetector(onTap: () => ImageBrowserPage.open(covers, index: index), child: image); + return GestureDetector( + onTap: () => ImageBrowserPage.open(covers, index: index), + child: image); } return Stack( children: [ - InkWell(enableFeedback: false, onTap: () => showToast('解锁后可查看图片详情'), child: image), + InkWell( + enableFeedback: false, + onTap: () => showToast('解锁后可查看图片详情'), + child: image), if (index == count - 1) Positioned.fill(child: _unlockMask(logic)), ], ); @@ -113,27 +124,41 @@ class _PicsDetailPageState extends State with UniqueTagMixin { '你只需花费 $coins 金币', defaultStyle: textStyle(16, Colors.white, FontWeight.w400), patternList: [ - EasyRichTextPattern(targetString: '$coins', style: textStyle(16, AppColors.actionRed, FontWeight.w400)), + EasyRichTextPattern( + targetString: '$coins', + style: textStyle(16, AppColors.actionRed, FontWeight.w400)), ], ), 16.sizeBoxH, - Text('即可解锁继续查看', style: textStyle(12, Colors.white, FontWeight.w400)), + Text('即可解锁继续查看', + style: textStyle(12, Colors.white, FontWeight.w400)), 16.sizeBoxH, - _maskBtn('立即解锁', 84, [Color(0xffFF6E6E), Color(0xffFF4D4D)], Colors.white, logic.showBuy), + _maskBtn('立即解锁', 84, [Color(0xffFF6E6E), Color(0xffFF4D4D)], + Colors.white, logic.showBuy), ] : [ //会员解锁 Text('试看结束', style: textStyle(16, Colors.white, FontWeight.w400)), 16.sizeBoxH, - Text('本内容需开通VIP免费观看', style: textStyle(16, Colors.white, FontWeight.w400)), + Text('本内容需开通VIP免费观看', + style: textStyle(16, Colors.white, FontWeight.w400)), 16.sizeBoxH, Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - _maskBtn('邀请得3日VIP', 110, [Color(0xffFFE8BE), Color(0xffE6B764)], Color(0xff694923), + _maskBtn( + '邀请得3日VIP', + 110, + [Color(0xffFFE8BE), Color(0xffE6B764)], + Color(0xff694923), () => Get.to(() => MineSharePage())), 18.sizeBoxW, - _maskBtn('开通VIP免费看', 115, [Color(0xffFF6E6E), Color(0xffFF4D4D)], Colors.white, logic.showBuy), + _maskBtn( + '开通VIP免费看', + 115, + [Color(0xffFF6E6E), Color(0xffFF4D4D)], + Colors.white, + logic.showBuy), ], ), ]; @@ -146,7 +171,9 @@ class _PicsDetailPageState extends State with UniqueTagMixin { fit: BoxFit.scaleDown, child: SizedBox( width: screen.screenWidth, - child: Column(mainAxisAlignment: MainAxisAlignment.center, children: content), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: content), ), ), ), @@ -155,7 +182,8 @@ class _PicsDetailPageState extends State with UniqueTagMixin { } //蒙层里的胶囊按钮,三处只差宽度/渐变/文字色/回调 - Widget _maskBtn(String text, double width, List colors, Color textColor, VoidCallback onTap) { + Widget _maskBtn(String text, double width, List colors, + Color textColor, VoidCallback onTap) { return InkWell( enableFeedback: false, onTap: onTap, @@ -163,7 +191,9 @@ class _PicsDetailPageState extends State with UniqueTagMixin { width: width, height: 30, alignment: Alignment.center, - decoration: BoxDecoration(gradient: LinearGradient(colors: colors), borderRadius: BorderRadius.circular(15)), + decoration: BoxDecoration( + gradient: LinearGradient(colors: colors), + borderRadius: BorderRadius.circular(15)), child: Text(text, style: textStyle(12, textColor, FontWeight.w400)), ), ); diff --git a/lib/hj_page/find/rank_module/acg_rank_item.dart b/lib/hj_page/find/rank_module/acg_rank_item.dart index d61cb06..dede8c3 100644 --- a/lib/hj_page/find/rank_module/acg_rank_item.dart +++ b/lib/hj_page/find/rank_module/acg_rank_item.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_page/find/rank_module/rank_badge.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_page/find/rank_module/rank_badge.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; //动漫/漫画排行榜item class ACGRankItem extends StatelessWidget { @@ -69,6 +69,7 @@ class ACGRankItem extends StatelessWidget { } //连载中金色,已完结半透明白 - Color get _statusColor => - movie?.updateStatus == 1 ? const Color(0xffFFC000) : Colors.white.withValues(alpha: .45); + Color get _statusColor => movie?.updateStatus == 1 + ? const Color(0xffFFC000) + : Colors.white.withValues(alpha: .45); } diff --git a/lib/hj_page/find/rank_module/image_rank_item.dart b/lib/hj_page/find/rank_module/image_rank_item.dart index 6078a70..e422f1e 100644 --- a/lib/hj_page/find/rank_module/image_rank_item.dart +++ b/lib/hj_page/find/rank_module/image_rank_item.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/find/pic_collect/pics_detail_page.dart'; -import 'package:hgmj/hj_page/find/rank_module/rank_badge.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/find/pic_collect/pics_detail_page.dart'; +import 'package:wydj/hj_page/find/rank_module/rank_badge.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; //图集排行榜item class ImageRankItem extends StatelessWidget { @@ -19,7 +19,8 @@ class ImageRankItem extends StatelessWidget { Widget build(BuildContext context) { return InkWell( enableFeedback: false, - onTap: () => Get.to(PicsDetailPage(id: movie?.id), preventDuplicates: false), + onTap: () => + Get.to(PicsDetailPage(id: movie?.id), preventDuplicates: false), child: SizedBox( height: 108, child: Row( @@ -54,18 +55,21 @@ class ImageRankItem extends StatelessWidget { //浏览量 + 收藏量 Row( children: [ - Image.asset("eye_grey.webp".commonImgPath, width: 14, height: 14), + Image.asset("eye_grey.webp".commonImgPath, + width: 14, height: 14), 5.sizeBoxW, Text( movie?.playCount?.countStr ?? "0", - style: const TextStyle(color: Color(0xff989898), fontSize: 12), + style: const TextStyle( + color: Color(0xff989898), fontSize: 12), ), 8.sizeBoxW, Image.asset("collect_start.webp".homePath, width: 14), 5.sizeBoxW, Text( movie?.collectCount?.countStr ?? "0", - style: const TextStyle(color: Color(0xff989898), fontSize: 12), + style: const TextStyle( + color: Color(0xff989898), fontSize: 12), ), ], ), diff --git a/lib/hj_page/find/rank_module/rank_badge.dart b/lib/hj_page/find/rank_module/rank_badge.dart index b09ce5f..9bacc8a 100644 --- a/lib/hj_page/find/rank_module/rank_badge.dart +++ b/lib/hj_page/find/rank_module/rank_badge.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// 榜单名次徽标「皇冠 + NO.1」:影视 / 图集 / 动漫 / 帖子四种 item 共用,改样式只改这一处 Widget rankBadge(int index) { diff --git a/lib/hj_page/find/rank_module/rank_main_logic.dart b/lib/hj_page/find/rank_module/rank_main_logic.dart index 755567d..cf458ce 100644 --- a/lib/hj_page/find/rank_module/rank_main_logic.dart +++ b/lib/hj_page/find/rank_module/rank_main_logic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/const.dart'; class RankMainLogic extends GetxController with GetTickerProviderStateMixin { RankMainLogic({int initIndex = 0}) : _initIndex = initIndex; @@ -10,7 +10,8 @@ class RankMainLogic extends GetxController with GetTickerProviderStateMixin { //榜单类型,顺序即 tab 顺序 static const tabs = [MediaStyle.Video, MediaStyle.Community, MediaStyle.Pic]; - late final TabController tabCtr = TabController(initialIndex: _initIndex, length: tabs.length, vsync: this); + late final TabController tabCtr = + TabController(initialIndex: _initIndex, length: tabs.length, vsync: this); @override void onClose() { diff --git a/lib/hj_page/find/rank_module/rank_main_page.dart b/lib/hj_page/find/rank_module/rank_main_page.dart index 2763c17..8949ec1 100644 --- a/lib/hj_page/find/rank_module/rank_main_page.dart +++ b/lib/hj_page/find/rank_module/rank_main_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/find/rank_module/rank_type_tab_view.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_page/find/rank_module/rank_type_tab_view.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'rank_main_logic.dart'; @@ -37,13 +37,17 @@ class _RankMainPageState extends State with UniqueTagMixin { controller: logic.tabCtr, padding: const EdgeInsets.symmetric(horizontal: 30), tabs: RankMainLogic.tabs - .map((e) => Padding(padding: const EdgeInsets.only(bottom: 5), child: Text(e.rankTitle))) + .map((e) => Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Text(e.rankTitle))) .toList(), labelPadding: const EdgeInsets.symmetric(horizontal: 3), unselectedLabelColor: const Color(0x8CFFFFFF), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), labelColor: const Color(0xE5FFFFFF), - labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + labelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), indicator: CustomIndicator( height: 3, width: 13, @@ -57,7 +61,9 @@ class _RankMainPageState extends State with UniqueTagMixin { Expanded( child: TabBarView( controller: logic.tabCtr, - children: RankMainLogic.tabs.map((e) => RankTypeTabView(e).keepAlive).toList(), + children: RankMainLogic.tabs + .map((e) => RankTypeTabView(e).keepAlive) + .toList(), ), ), ], diff --git a/lib/hj_page/find/rank_module/rank_sort_tab_bar.dart b/lib/hj_page/find/rank_module/rank_sort_tab_bar.dart index 80d0dbb..5ef73a5 100644 --- a/lib/hj_page/find/rank_module/rank_sort_tab_bar.dart +++ b/lib/hj_page/find/rank_module/rank_sort_tab_bar.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// 榜单周期 Tab:周榜 / 月榜 / 年榜 / 总榜,项间用一条竖线分隔、无下划线指示器。 /// 不用自己监听 controller 重绘——TabBar 内部就挂着 animation 监听 @@ -19,7 +19,8 @@ class RankSortTabBar extends StatelessWidget { .map((e) => Row( children: [ Container( - padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 3), + padding: + const EdgeInsets.symmetric(horizontal: 18, vertical: 3), child: Text(e.value), ), if (e.key != titles.length - 1) 12.lineV, diff --git a/lib/hj_page/find/rank_module/rank_sub_logic.dart b/lib/hj_page/find/rank_module/rank_sub_logic.dart index 5741a86..0dd3533 100644 --- a/lib/hj_page/find/rank_module/rank_sub_logic.dart +++ b/lib/hj_page/find/rank_module/rank_sub_logic.dart @@ -1,7 +1,7 @@ -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class RankSubPageLogic extends ListBaseLogic { final MediaStyle pageType; // 榜单媒体类型:影片/帖子/图集/漫画等 @@ -9,7 +9,8 @@ class RankSubPageLogic extends ListBaseLogic { RankSubPageLogic({required this.pageType, this.sortType = 2}); - bool get isACG => pageType == MediaStyle.Comics || pageType == MediaStyle.Cartoon; + bool get isACG => + pageType == MediaStyle.Comics || pageType == MediaStyle.Cartoon; // onInit(挂载即同步触发,比 onReady 的帧后回调在嵌套 keepAlive 下可靠) @override @@ -31,10 +32,12 @@ class RankSubPageLogic extends ListBaseLogic { // 拉取榜单:ACG 走 getRanking,其余走 vidRanking;返回 (列表, 是否还有更多) Future<(List?, bool)> _fetch(int page) async { if (isACG) { - final resp = await ACGService.getRanking(page, 10, mediaType: pageType.rankParam, type: sortType); + final resp = await ACGService.getRanking(page, 10, + mediaType: pageType.rankParam, type: sortType); return (resp?.list, resp?.hasNext == true); } - final res = await VidService.vidRanking(page, 10, newsType: pageType.rankParam, type: sortType); + final res = await VidService.vidRanking(page, 10, + newsType: pageType.rankParam, type: sortType); return (res?.videos, res?.hasNext == true); } } diff --git a/lib/hj_page/find/rank_module/rank_sub_page.dart b/lib/hj_page/find/rank_module/rank_sub_page.dart index 191a3f0..42500a6 100644 --- a/lib/hj_page/find/rank_module/rank_sub_page.dart +++ b/lib/hj_page/find/rank_module/rank_sub_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/find/rank_module/video_rank_item.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/find/rank_module/video_rank_item.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../community/widget/community_post_widget.dart'; import 'acg_rank_item.dart'; @@ -47,7 +47,8 @@ class _RankSubPageState extends State with UniqueTagMixin { Widget _buildContent() { if (logic.isLoading) return LoadingCenterWidget(); //retryOnTap 要拿到 Future 才有 loading + 防连点 - if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData(showLoading: true)); + if (logic.isEmptyData) + return CErrorWidget(retryOnTap: () => logic.loadData(showLoading: true)); final list = logic.dataList ?? const []; return ListView.separated( keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, @@ -64,7 +65,9 @@ class _RankSubPageState extends State with UniqueTagMixin { videoModels: list.cast(), rankIndex: index, ), - MediaStyle.Cartoon || MediaStyle.Comics => ACGRankItem(index, list[index]), + MediaStyle.Cartoon || + MediaStyle.Comics => + ACGRankItem(index, list[index]), _ => const SizedBox.shrink(), }, ); diff --git a/lib/hj_page/find/rank_module/rank_type_tab_view.dart b/lib/hj_page/find/rank_module/rank_type_tab_view.dart index 0e435fb..8a21b74 100644 --- a/lib/hj_page/find/rank_module/rank_type_tab_view.dart +++ b/lib/hj_page/find/rank_module/rank_type_tab_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_page/find/rank_module/rank_sort_tab_bar.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_page/find/rank_module/rank_sort_tab_bar.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'rank_sub_page.dart'; @@ -15,7 +15,8 @@ class RankTypeTabView extends StatefulWidget { State createState() => _RankTypeTabViewState(); } -class _RankTypeTabViewState extends State with SingleTickerProviderStateMixin { +class _RankTypeTabViewState extends State + with SingleTickerProviderStateMixin { //标题与后端 sortType 绑在一起,避免两个数组分家后漏改一处就错位 static const _tabs = [ SortTab('周榜', 2), @@ -24,7 +25,8 @@ class _RankTypeTabViewState extends State with SingleTickerProv SortTab('总榜', 4), ]; - late final TabController tabCtr = TabController(length: _tabs.length, vsync: this); + late final TabController tabCtr = + TabController(length: _tabs.length, vsync: this); @override void dispose() { @@ -35,16 +37,21 @@ class _RankTypeTabViewState extends State with SingleTickerProv @override Widget build(BuildContext context) { return Container( - color: Color(0xff0f0f0f), + color: Color(0xff0f0f0f), child: Column( children: [ - RankSortTabBar(titles: _tabs.map((e) => e.name).toList(), tabCtr: tabCtr), + RankSortTabBar( + titles: _tabs.map((e) => e.name).toList(), tabCtr: tabCtr), Expanded( child: Container( padding: EdgeInsets.only(top: 8), child: TabBarView( controller: tabCtr, - children: _tabs.map((e) => RankSubPage(pageType: widget.pageType, sortType: e.sort).keepAlive).toList(), + children: _tabs + .map((e) => + RankSubPage(pageType: widget.pageType, sortType: e.sort) + .keepAlive) + .toList(), ), ), ), diff --git a/lib/hj_page/find/rank_module/video_rank_item.dart b/lib/hj_page/find/rank_module/video_rank_item.dart index 033da88..fa7567b 100644 --- a/lib/hj_page/find/rank_module/video_rank_item.dart +++ b/lib/hj_page/find/rank_module/video_rank_item.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/find/rank_module/rank_badge.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/find/rank_module/rank_badge.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; //影视排行榜item class VideoRankItem extends StatelessWidget { @@ -30,7 +30,8 @@ class VideoRankItem extends StatelessWidget { child: Stack( fit: StackFit.expand, children: [ - NetworkImageLoader(imageUrl: movie?.cover ?? '', borderRadius: 8), + NetworkImageLoader( + imageUrl: movie?.cover ?? '', borderRadius: 8), Container( alignment: Alignment.bottomCenter, padding: const EdgeInsets.fromLTRB(5, 0, 5, 5), @@ -39,12 +40,14 @@ class VideoRankItem extends StatelessWidget { Image.asset('circle_play.webp'.videoPath, width: 16), Text( movie?.playCount?.countStr ?? '0', - style: const TextStyle(color: Colors.white, fontSize: 10, height: 1.6), + style: const TextStyle( + color: Colors.white, fontSize: 10, height: 1.6), ), const Spacer(), Text( movie?.playTime?.hmsStr ?? "", - style: const TextStyle(color: Colors.white, fontSize: 10, height: 1.6), + style: const TextStyle( + color: Colors.white, fontSize: 10, height: 1.6), ), ], ), @@ -64,7 +67,8 @@ class VideoRankItem extends StatelessWidget { "${movie?.title ?? ''}\n", maxLines: 2, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Color(0xE5FFFFFF), fontSize: 12, height: 1.5), + style: const TextStyle( + color: Color(0xE5FFFFFF), fontSize: 12, height: 1.5), ), //收藏量 Row( @@ -73,7 +77,8 @@ class VideoRankItem extends StatelessWidget { 5.sizeBoxW, Text( movie?.collectCount?.countStr ?? "0", - style: const TextStyle(color: Color(0xff989898), fontSize: 12), + style: const TextStyle( + color: Color(0xff989898), fontSize: 12), ), ], ), diff --git a/lib/hj_page/home/activity_float/home_activity_float.dart b/lib/hj_page/home/activity_float/home_activity_float.dart index faf19dc..8782e05 100644 --- a/lib/hj_page/home/activity_float/home_activity_float.dart +++ b/lib/hj_page/home/activity_float/home_activity_float.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/mine_charge_vip_page.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/pay_order_source.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_page/mine/mine_vip/mine_charge_vip_page.dart'; +import 'package:wydj/hj_page/mine/mine_vip/pay_order_source.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../tools_base/widget/card_swiper/src/swiper.dart'; @@ -31,14 +31,17 @@ class HomeActivityFloat extends StatelessWidget { //预售浮窗:展示判断走项目统一的 canShowEnter,点击进预售页(入口图/动画由 PreSaleEntry 内部处理) if (presale.canShowEnter) const PreSaleEntry(), //支付分层浮窗:有 homePageFlot 图就展示 - if ((tier?.homePageFlot ?? '').isNotEmpty) _LayeredFloatView(config: tier!), + if ((tier?.homePageFlot ?? '').isNotEmpty) + _LayeredFloatView(config: tier!), ]; if (floats.isEmpty) return const SizedBox(); // 单个直接贴右下角;预售 + 分层并存则轮播 return KeyedSubtree( key: homeFloatKey, - child: floats.length == 1 ? Align(alignment: Alignment.bottomRight, child: floats.first) : _FloatCarousel(items: floats), + child: floats.length == 1 + ? Align(alignment: Alignment.bottomRight, child: floats.first) + : _FloatCarousel(items: floats), ); }, ); @@ -57,7 +60,8 @@ class _LayeredFloatView extends StatelessWidget { return InkWell( enableFeedback: false, //点击跳会员中心,vipID 让其自动选中对应卡 - onTap: () => Get.to(() => MineChargeVipPage(vipID: config.vipCard, sourcePage: PaySourcePage.homeFloatWindow)), + onTap: () => Get.to(() => MineChargeVipPage( + vipID: config.vipCard, sourcePage: PaySourcePage.homeFloatWindow)), child: SizedBox( width: 60, height: 66, @@ -65,7 +69,10 @@ class _LayeredFloatView extends StatelessWidget { fit: StackFit.expand, children: [ //分层海报图(后端加密图) - NetworkImageLoader(imageUrl: config.homePageFlot ?? '', fit: BoxFit.fill, borderRadius: 0), + NetworkImageLoader( + imageUrl: config.homePageFlot ?? '', + fit: BoxFit.fill, + borderRadius: 0), //倒计时文字:监听 tick 每秒刷新(过期自动收起),框由后端图自带,位置不对就调 bottom Positioned( left: 0, @@ -77,7 +84,10 @@ class _LayeredFloatView extends StatelessWidget { ? Center( child: Text( '${config.discountHour}:${config.discountMin}:${config.discountSec}', - style: const TextStyle(color: Colors.white, fontSize: 8.5, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Colors.white, + fontSize: 8.5, + fontWeight: FontWeight.w600), ), ) : const SizedBox.shrink(), @@ -108,7 +118,8 @@ class _FloatCarousel extends StatelessWidget { autoplayDelay: 4000, loop: true, itemCount: items.length, - itemBuilder: (_, index) => Align(alignment: Alignment.bottomRight, child: items[index]), + itemBuilder: (_, index) => + Align(alignment: Alignment.bottomRight, child: items[index]), ), ); } diff --git a/lib/hj_page/home/activity_float/home_float_banner.dart b/lib/hj_page/home/activity_float/home_float_banner.dart index 9af324b..d299a0f 100644 --- a/lib/hj_page/home/activity_float/home_float_banner.dart +++ b/lib/hj_page/home/activity_float/home_float_banner.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; import '../../../config/config.dart'; import '../../../hj_model/splash/domain_source_model.dart'; @@ -82,7 +82,8 @@ class _HomeFloatBannerState extends State { _timer?.cancel(); _timer = null; if (_isCountdownActivity) { - _timer = Timer.periodic(const Duration(seconds: 1), (_) => _onTimerTick()); + _timer = + Timer.periodic(const Duration(seconds: 1), (_) => _onTimerTick()); } } @@ -106,7 +107,8 @@ class _HomeFloatBannerState extends State { final start = _parseDate(_banner.startAt); _bottomText.value = switch (_activityStatus()) { _ActStatus.inProgress => '立即参与', - _ActStatus.beforeStart => start == null ? '' : _formatCountdown(start.difference(DateTime.now())), + _ActStatus.beforeStart => + start == null ? '' : _formatCountdown(start.difference(DateTime.now())), _ActStatus.ended => '', }; } @@ -139,7 +141,8 @@ class _HomeFloatBannerState extends State { // 用新 banner 替换 Config.bannerJumps 里同位置同 id 的旧数据 void _updateConfigBanner(BannerJumpEntity banner) { - final index = Config.bannerJumps.indexWhere((e) => e.position == _banner.position && e.id == _banner.id); + final index = Config.bannerJumps.indexWhere( + (e) => e.position == _banner.position && e.id == _banner.id); if (index >= 0) { Config.bannerJumps[index] = banner; } @@ -147,12 +150,14 @@ class _HomeFloatBannerState extends State { // 活动结束且无下一场:从 Config.bannerJumps 移除当前 banner void _removeConfigBanner() { - Config.bannerJumps.removeWhere((e) => e.position == _banner.position && e.id == _banner.id); + Config.bannerJumps.removeWhere( + (e) => e.position == _banner.position && e.id == _banner.id); } // 解析后端时间字符串为本地时间;空值/占位(0001-01-01)/非法格式返回 null DateTime? _parseDate(String? date) { - if (date == null || date.isEmpty || date.contains('0001-01-01')) return null; + if (date == null || date.isEmpty || date.contains('0001-01-01')) + return null; try { return DateTime.parse(date).toLocal(); } catch (_) { @@ -174,7 +179,8 @@ class _HomeFloatBannerState extends State { String _formatCountdown(Duration duration) { final seconds = duration.inSeconds < 0 ? 0 : duration.inSeconds; final days = seconds ~/ 86400; - final time = DateTimeUtil.formatHMS(seconds % 86400, alwaysHour: true); // 当天内 HH:MM:SS + final time = DateTimeUtil.formatHMS(seconds % 86400, + alwaysHour: true); // 当天内 HH:MM:SS return days > 0 ? '$days天$time' : time; } @@ -183,7 +189,8 @@ class _HomeFloatBannerState extends State { return InkWell( enableFeedback: false, // 内链可配到会员/金币页,来源统一记首页浮窗 - onTap: () => pushToPageByLink(_banner.url, sourcePage: PaySourcePage.homeFloatWindow), + onTap: () => pushToPageByLink(_banner.url, + sourcePage: PaySourcePage.homeFloatWindow), child: SizedBox( width: widget.width, height: widget.height, diff --git a/lib/hj_page/home/dark_home_page.dart b/lib/hj_page/home/dark_home_page.dart index 6d700c0..fea738c 100644 --- a/lib/hj_page/home/dark_home_page.dart +++ b/lib/hj_page/home/dark_home_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; import '../../alert/aw_permission_alert.dart'; @@ -20,7 +20,8 @@ class DarkHomePage extends StatefulWidget { } class _DarkHomePageState extends State { - late final logic = HomeMainLogic(isDarkStyle: true, darkDefaultId: widget.defaultId); + late final logic = + HomeMainLogic(isDarkStyle: true, darkDefaultId: widget.defaultId); @override Widget build(BuildContext context) { diff --git a/lib/hj_page/home/home_cell_style/drama_banner.dart b/lib/hj_page/home/home_cell_style/drama_banner.dart index aaa27d4..6e5c2bc 100644 --- a/lib/hj_page/home/home_cell_style/drama_banner.dart +++ b/lib/hj_page/home/home_cell_style/drama_banner.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_page/drama/drama_detail_page.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; -import 'package:hgmj/tools_base/widget/card_swiper/card_swiper.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_page/drama/drama_detail_page.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/tools_base/widget/card_swiper/card_swiper.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// AI 短剧专题 banner:轮播 + 右下角指示器,点击跳短剧详情。 class DramaBanner extends StatefulWidget { @@ -31,7 +31,7 @@ class _DramaBannerState extends State { @override Widget build(BuildContext context) { - if(widget.banners.isEmpty) return SizedBox(); + if (widget.banners.isEmpty) return SizedBox(); return Padding( padding: const EdgeInsets.fromLTRB(16, 12, 16, 0), child: ClipRRect( @@ -84,4 +84,4 @@ class _DramaBannerState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/hj_page/home/home_cell_style/drama_cover_card.dart b/lib/hj_page/home/home_cell_style/drama_cover_card.dart index 1fcb752..eb9447f 100644 --- a/lib/hj_page/home/home_cell_style/drama_cover_card.dart +++ b/lib/hj_page/home/home_cell_style/drama_cover_card.dart @@ -3,13 +3,13 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_page/drama/drama_detail_page.dart'; -import 'package:hgmj/hj_page/drama/drama_tag_detail_page.dart'; -import 'package:hgmj/hj_utils/free_play_manager.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_page/drama/drama_detail_page.dart'; +import 'package:wydj/hj_page/drama/drama_tag_detail_page.dart'; +import 'package:wydj/hj_utils/free_play_manager.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// AI 短剧封面卡:按 Figma「短片封面展示样式」独立绘制。 class DramaCoverCard extends StatelessWidget { @@ -137,7 +137,8 @@ class DramaCoverCard extends StatelessWidget { ? () { final t = mediaInfo.tagDetails!.first; DramaTagDetailPage.to(t); - } : null, + } + : null, child: _chip(tag), ), ), @@ -194,19 +195,22 @@ class DramaCoverCard extends StatelessWidget { Widget? get _badge { if (mediaInfo.permissionIconHide == true) return null; + /// 免费 /// Config.freeMark 后端下发是否展示免费角标 /// mediaInfo.permission == 2视频为免费 /// FreePlayManager().canShowFreeBadge() 免费观看次数是否可看, 相等于 需要金币或者vip观看的,只要免费观看次数有,都为免费 - if(Config.freeMark && (mediaInfo.permission == 2 || FreePlayManager().canShowFreeBadge())) { + if (Config.freeMark && + (mediaInfo.permission == 2 || FreePlayManager().canShowFreeBadge())) { return _cornerBadge( '免费', const Color(0xFF1CD302), Colors.white, ); } + /// Vip - if(Config.vipMark && mediaInfo.permission == 0) { + if (Config.vipMark && mediaInfo.permission == 0) { return _cornerBadge( 'VIP', null, @@ -218,8 +222,9 @@ class DramaCoverCard extends StatelessWidget { ), ); } + /// 金币 - if(Config.coinMark && mediaInfo.permission == 1) { + if (Config.coinMark && mediaInfo.permission == 1) { return _cornerBadge( '金币', const Color(0xFFFFCC14), @@ -229,7 +234,8 @@ class DramaCoverCard extends StatelessWidget { return null; } - Widget _cornerBadge(String text, Color? color, Color textColor, {Gradient? gradient}) { + Widget _cornerBadge(String text, Color? color, Color textColor, + {Gradient? gradient}) { return Container( padding: const EdgeInsets.symmetric(horizontal: 6), decoration: BoxDecoration( diff --git a/lib/hj_page/home/home_cell_style/guess_like_sliver.dart b/lib/hj_page/home/home_cell_style/guess_like_sliver.dart index 1afbaef..64acb1b 100644 --- a/lib/hj_page/home/home_cell_style/guess_like_sliver.dart +++ b/lib/hj_page/home/home_cell_style/guess_like_sliver.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../hj_utils/sliver_delegate.dart'; @@ -41,7 +41,8 @@ class GuessLikeSliver extends StatelessWidget { minHeight: 42, childBuildHandler: (_, offset, overlaps, child) { return Container( - color: (offset >= 0) ? AppColors.primaryColor : Colors.transparent, + color: + (offset >= 0) ? AppColors.primaryColor : Colors.transparent, child: child, ); }, @@ -80,7 +81,8 @@ class GuessLikeSliver extends StatelessWidget { childAspectRatio: 168 / 154, ), delegate: SliverChildBuilderDelegate( - (context, index) => VideoSimpleCell(videoModel: model.allVideoInfo![index]), + (context, index) => + VideoSimpleCell(videoModel: model.allVideoInfo![index]), childCount: model.allVideoInfo!.length, ), ), diff --git a/lib/hj_page/home/home_cell_style/home_section_cell.dart b/lib/hj_page/home/home_cell_style/home_section_cell.dart index 9ac8700..7a21ed3 100644 --- a/lib/hj_page/home/home_cell_style/home_section_cell.dart +++ b/lib/hj_page/home/home_cell_style/home_section_cell.dart @@ -3,8 +3,8 @@ import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../hj_utils/api_service/vid_service.dart'; @@ -79,7 +79,8 @@ class _HomeSectionCellState extends State { _body(style), //101/102/103 底部挂「更多片源 / 更换一批」,其余样式只留间距 if (style?.canExchange == true) - Padding(padding: const EdgeInsets.only(bottom: 24), child: _exchangeBar()) + Padding( + padding: const EdgeInsets.only(bottom: 24), child: _exchangeBar()) else 12.sizeBoxH, //section 间的分割线跟着 cell 走,外面只管往列表里塞 @@ -148,12 +149,14 @@ class _HomeSectionCellState extends State { Expanded( child: _ExchangeButton( title: '更多片源', - onTap: () => Get.to(SpecialTopicsDetailPage(section), preventDuplicates: false), + onTap: () => Get.to(SpecialTopicsDetailPage(section), + preventDuplicates: false), ), ), 16.sizeBoxW, Expanded( - child: _ExchangeButton(title: '更换一批', loading: _exchanging, onTap: _exchange), + child: _ExchangeButton( + title: '更换一批', loading: _exchanging, onTap: _exchange), ), ], ), @@ -168,7 +171,8 @@ class _HomeSectionCellState extends State { try { final resp = await VidService.sectionVideoExchange(id); //请求飞行中列表可能被刷新,cell 按 index 复用后 section 已换人,结果不能再往回写 - if (resp.videos?.isNotEmpty == true && section.sectionID == id) section.allVideoInfo = resp.videos; + if (resp.videos?.isNotEmpty == true && section.sectionID == id) + section.allVideoInfo = resp.videos; } catch (e) { debugLog(e); } @@ -182,7 +186,8 @@ class _ExchangeButton extends StatelessWidget { final bool loading; final VoidCallback onTap; - const _ExchangeButton({required this.title, required this.onTap, this.loading = false}); + const _ExchangeButton( + {required this.title, required this.onTap, this.loading = false}); @override Widget build(BuildContext context) { @@ -199,13 +204,20 @@ class _ExchangeButton extends StatelessWidget { children: [ //转圈占位 16、常态 4,保持文字位置不跳 if (loading) - const SizedBox(width: 16, height: 16, child: CupertinoActivityIndicator(radius: 8, color: Colors.white)) + const SizedBox( + width: 16, + height: 16, + child: CupertinoActivityIndicator( + radius: 8, color: Colors.white)) else const SizedBox(width: 4), Text( title, textAlign: TextAlign.center, - style: const TextStyle(color: Color(0xE5FFFFFF), fontSize: 14, fontWeight: FontWeight.w400), + style: const TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 14, + fontWeight: FontWeight.w400), ), ], ), @@ -214,7 +226,6 @@ class _ExchangeButton extends StatelessWidget { } } - //一大四小 class SectionOneBigFourSmall extends StatelessWidget { final AllSection section; @@ -223,7 +234,8 @@ class SectionOneBigFourSmall extends StatelessWidget { @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -267,7 +279,8 @@ class SectionOneHalfFiveHor extends StatelessWidget { @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -300,11 +313,13 @@ class SectionOneHalfFiveHor extends StatelessWidget { class SectionTwoHalfFiveHV extends StatelessWidget { final AllSection section; final bool isVertical; // true 竖, false 横 - const SectionTwoHalfFiveHV(this.section, {super.key, this.isVertical = false}); + const SectionTwoHalfFiveHV(this.section, + {super.key, this.isVertical = false}); @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -363,7 +378,8 @@ class SectionGridViewHV extends StatelessWidget { @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -398,7 +414,8 @@ class SectionListView extends StatelessWidget { @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -438,7 +455,8 @@ class SectionGridViewSmall extends StatelessWidget { @override Widget build(BuildContext context) { - if (section.allVideoInfo?.isNotEmpty != true) return const SizedBox.shrink(); + if (section.allVideoInfo?.isNotEmpty != true) + return const SizedBox.shrink(); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/hj_page/home/home_cell_style/home_section_title.dart b/lib/hj_page/home/home_cell_style/home_section_title.dart index 28c74cf..d47778e 100644 --- a/lib/hj_page/home/home_cell_style/home_section_title.dart +++ b/lib/hj_page/home/home_cell_style/home_section_title.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../special_topic_detail/special_topics_detail_page.dart'; @@ -17,7 +17,8 @@ class HomeSectionTitle extends StatelessWidget { return Container( padding: EdgeInsets.fromLTRB(12, 0, 12, 12), child: GestureDetector( - onTap: () => Get.to(SpecialTopicsDetailPage(section), preventDuplicates: false), + onTap: () => + Get.to(SpecialTopicsDetailPage(section), preventDuplicates: false), child: Row( children: [ Expanded( diff --git a/lib/hj_page/home/home_cell_style/quick_entry_row.dart b/lib/hj_page/home/home_cell_style/quick_entry_row.dart index 685faa8..32bdfeb 100644 --- a/lib/hj_page/home/home_cell_style/quick_entry_row.dart +++ b/lib/hj_page/home/home_cell_style/quick_entry_row.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_model/home/plate_model.dart'; import '../../../hj_model/splash/domain_source_model.dart'; @@ -15,7 +15,8 @@ class QuickEntryRow extends StatelessWidget { @override Widget build(BuildContext context) { - final dataArr = (Config.jgArea ?? []).where((e) => e.mid == tabModel?.id).toList(); + final dataArr = + (Config.jgArea ?? []).where((e) => e.mid == tabModel?.id).toList(); if (dataArr.isEmpty) return const SizedBox.shrink(); return Container( height: 62, @@ -30,7 +31,8 @@ class QuickEntryRow extends StatelessWidget { itemCount: dataArr.length, padding: EdgeInsets.zero, scrollDirection: Axis.horizontal, - itemBuilder: (context, index) => _buildItem(dataArr[index], width), + itemBuilder: (context, index) => + _buildItem(dataArr[index], width), ), ); }, diff --git a/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart b/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart index ed759c8..2628f90 100644 --- a/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart +++ b/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; import '../../../hj_model/video_model.dart'; import '../../../tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; /// 抖音样式的视频 item:封面 + 底部角标 + 标题 +(可选)标签/评论数。 /// 封面占满父级剩余高度,外层必须给约束(网格 / 固定高容器) @@ -40,7 +40,8 @@ class TiktokSimpleCell extends StatelessWidget { "${videoModel?.title ?? ""}\n", maxLines: textLines, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), fontSize: 12), ), ), if (isShowBottom) _buildBottom(), @@ -72,11 +73,15 @@ class TiktokSimpleCell extends StatelessWidget { height: 30, padding: const EdgeInsets.symmetric(horizontal: 6), decoration: BoxDecoration( - borderRadius: const BorderRadius.vertical(bottom: Radius.circular(4)), + borderRadius: + const BorderRadius.vertical(bottom: Radius.circular(4)), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, - colors: [Colors.black.withValues(alpha: 0), Colors.black.withValues(alpha: 0.6)], + colors: [ + Colors.black.withValues(alpha: 0), + Colors.black.withValues(alpha: 0.6) + ], ), ), child: _buildCoverBadge(), @@ -96,7 +101,8 @@ class TiktokSimpleCell extends StatelessWidget { videoModel?.playCount?.countStr ?? "0", maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Colors.white, fontSize: 10, height: 1.6), + style: + const TextStyle(color: Colors.white, fontSize: 10, height: 1.6), ), const Spacer(), if (isShowTime) @@ -133,7 +139,8 @@ class TiktokSimpleCell extends StatelessWidget { child: tagName.isEmpty ? const SizedBox.shrink() : Container( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 1), decoration: BoxDecoration( color: const Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(3), @@ -142,7 +149,8 @@ class TiktokSimpleCell extends StatelessWidget { tagName, maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Color(0x73FFFFFF), fontSize: 10), + style: const TextStyle( + color: Color(0x73FFFFFF), fontSize: 10), ), ), ), diff --git a/lib/hj_page/home/home_cell_style/video_hor_cell.dart b/lib/hj_page/home/home_cell_style/video_hor_cell.dart index d28d1b8..4073a1c 100644 --- a/lib/hj_page/home/home_cell_style/video_hor_cell.dart +++ b/lib/hj_page/home/home_cell_style/video_hor_cell.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_model/video_model.dart'; import '../../../hj_utils/free_play_manager.dart'; import '../../../routers/jump_router.dart'; import '../../../tools_base/widget/net_image_widget.dart'; import 'level_mark_chip.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; /// 横版视频 item:左封面(带售卖角标) + 右标题/收藏数,用在专题的小列表样式 class VideoHorCell extends StatelessWidget { diff --git a/lib/hj_page/home/home_cell_style/video_simple_cell.dart b/lib/hj_page/home/home_cell_style/video_simple_cell.dart index 9c576b8..4179c3f 100644 --- a/lib/hj_page/home/home_cell_style/video_simple_cell.dart +++ b/lib/hj_page/home/home_cell_style/video_simple_cell.dart @@ -1,13 +1,13 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/banner/ads_item.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/banner/ads_item.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../hj_model/splash/ads_model.dart'; import '../../../hj_model/video_model.dart'; @@ -95,7 +95,9 @@ class VideoSimpleCell extends StatelessWidget { "${videoModel?.title ?? ""}\n", maxLines: textLines, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: titleFontSize), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: titleFontSize), ), ), if (isShowBottom) _buildBottomWidget(), @@ -177,7 +179,8 @@ class VideoSimpleCell extends StatelessWidget { videoModel?.playCount?.countStr ?? "0", maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Colors.white, fontSize: coverFontSize, height: 1.6), + style: TextStyle( + color: Colors.white, fontSize: coverFontSize, height: 1.6), ), Spacer(), Text( @@ -211,7 +214,8 @@ class VideoSimpleCell extends StatelessWidget { Widget _buildBottomWidget() { if (isFromHY) { - final tagDesc = videoModel?.tags?.map((e) => e.name ?? "").join("·") ?? ""; + final tagDesc = + videoModel?.tags?.map((e) => e.name ?? "").join("·") ?? ""; return Container( padding: EdgeInsets.only(top: 3), child: Text( @@ -234,9 +238,12 @@ class VideoSimpleCell extends StatelessWidget { Flexible( child: videoModel?.tags?.isNotEmpty == true ? GestureDetector( - onTap: onTagTap == null ? null : () => onTagTap!(videoModel!.tags!.first), + onTap: onTagTap == null + ? null + : () => onTagTap!(videoModel!.tags!.first), child: Container( - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 1), + padding: + EdgeInsets.symmetric(horizontal: 4, vertical: 1), decoration: BoxDecoration( color: Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(3), @@ -295,7 +302,8 @@ class _VideoSimpleAdsCellState extends State { int adIndex = 0; - List? get adsInfoArr => videoModel?.adsInfoArr; //?? mediaInfo?.adsInfoArr; + List? get adsInfoArr => + videoModel?.adsInfoArr; //?? mediaInfo?.adsInfoArr; AdsInfoModel? get adsModel => videoModel?.randomAdsInfo; @@ -356,7 +364,9 @@ class _VideoSimpleAdsCellState extends State { child: child, ), child: Text( - isHor ? adsInfoArr![adIndex].title?.trim() ?? "" : "${adsInfoArr![adIndex].title?.trim() ?? ""}\n", + isHor + ? adsInfoArr![adIndex].title?.trim() ?? "" + : "${adsInfoArr![adIndex].title?.trim() ?? ""}\n", key: ValueKey(adIndex), // adIndex 变化触发切换动画 maxLines: widget.textLines, overflow: TextOverflow.ellipsis, @@ -436,7 +446,9 @@ class _VideoSimpleAdsCellState extends State { Container( padding: const EdgeInsets.only(top: 4), child: Text( - isHor ? videoModel?.title ?? "" : "${videoModel?.title ?? ""}\n", + isHor + ? videoModel?.title ?? "" + : "${videoModel?.title ?? ""}\n", maxLines: widget.textLines, overflow: TextOverflow.ellipsis, style: TextStyle( diff --git a/lib/hj_page/home/home_main_logic.dart b/lib/hj_page/home/home_main_logic.dart index b7c157b..6bce2d8 100644 --- a/lib/hj_page/home/home_main_logic.dart +++ b/lib/hj_page/home/home_main_logic.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/alert/vip_guide/guide_manager.dart'; -import 'package:hgmj/alert/vip_guide/timed_popup_manager.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/alert/vip_guide/guide_manager.dart'; +import 'package:wydj/alert/vip_guide/timed_popup_manager.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import '../../alert/splash/app_center_dialog.dart'; import '../../alert/splash/notice_image_dialog.dart'; @@ -144,7 +144,8 @@ class HomeMainLogic extends GetxController { if (config == null || (config.homePage ?? '').isEmpty) return; final goVip = await Get.dialog(GuideHomeDialog(config: config)); if (goVip != true) return; - await Get.to(() => MineChargeVipPage(vipID: config.vipCard, sourcePage: PaySourcePage.homeUserSegment)); + await Get.to(() => MineChargeVipPage( + vipID: config.vipCard, sourcePage: PaySourcePage.homeUserSegment)); } /// 首页吸底 VIP 引导:开屏弹窗链末尾弹(全链最低优先级),能不能弹由 HOME_NEW_USER / HOME_OLD_USER @@ -160,12 +161,17 @@ class HomeMainLogic extends GetxController { scene: scene, title: Text( config?.title?.isNotEmpty == true ? config!.title! : 'VIP影片免费试看', - style: const TextStyle(color: Colors.white, fontSize: 19, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Colors.white, fontSize: 19, fontWeight: FontWeight.w600), ), subtitle: GradientText( - config?.description?.isNotEmpty == true ? config!.description! : '开通会员 查看完整影片', - gradient: const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]), - style: const TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), + config?.description?.isNotEmpty == true + ? config!.description! + : '开通会员 查看完整影片', + gradient: + const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]), + style: const TextStyle( + color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), ), ), ); @@ -182,7 +188,8 @@ class HomeMainLogic extends GetxController { Future _showImageDialog() async { final adsList = AdManager().adsByType(46); for (int i = 0; i < adsList.length; i += 2) { - await Get.dialog(SystemImagesDialog(ads: adsList.skip(i).take(2).toList())); + await Get.dialog( + SystemImagesDialog(ads: adsList.skip(i).take(2).toList())); } } @@ -191,8 +198,11 @@ class HomeMainLogic extends GetxController { for (final wordBean in AdManager().announceList) { await Get.dialog( wordBean.type == 0 - ? NoticeTextDialog(content: wordBean.content.toString(), wordBean: wordBean) - : NoticeImageDialog(model: AdsInfoModel(cover: wordBean.cover, href: wordBean.href)), + ? NoticeTextDialog( + content: wordBean.content.toString(), wordBean: wordBean) + : NoticeImageDialog( + model: + AdsInfoModel(cover: wordBean.cover, href: wordBean.href)), ); } } diff --git a/lib/hj_page/home/home_main_page.dart b/lib/hj_page/home/home_main_page.dart index c20f8ce..ee55589 100644 --- a/lib/hj_page/home/home_main_page.dart +++ b/lib/hj_page/home/home_main_page.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/home/provider/home_update_marker_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/home/provider/home_update_marker_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:provider/provider.dart'; import '../cartoon/cartoon_sub_detail_page.dart'; @@ -39,7 +39,8 @@ class HomeMainPage extends StatelessWidget { fit: StackFit.expand, children: [ _body(logic), - const Positioned(right: 12, bottom: 40, child: HomeFloatWidget()), + const Positioned( + right: 12, bottom: 40, child: HomeFloatWidget()), ], ), ); @@ -60,7 +61,8 @@ class HomeMainPage extends StatelessWidget { child: CommonSearchBarView(logic: logic), ), //排序变化时 tabViewKey 变,整个 TabView 连 TabController 一起重建 - Expanded(child: HomeTabView(key: ValueKey(logic.tabViewKey), logic: logic)), + Expanded( + child: HomeTabView(key: ValueKey(logic.tabViewKey), logic: logic)), ], ); } @@ -80,7 +82,8 @@ class HomeTabView extends StatefulWidget { State createState() => _HomeTabViewState(); } -class _HomeTabViewState extends State with SingleTickerProviderStateMixin { +class _HomeTabViewState extends State + with SingleTickerProviderStateMixin { HomeMainLogic get logic => widget.logic; bool get isDarkStyle => widget.isDarkStyle; @@ -148,19 +151,31 @@ class _HomeTabViewState extends State with SingleTickerProviderStat //1首页(原首页视频) 3暗网 //showType==2 走分区聚合页,其余走排序列表页 if (module.showType == 2) { - return HomeTabSectionPage(index, module, isDarkStyle: isDarkStyle).keepAlive; + return HomeTabSectionPage(index, module, + isDarkStyle: isDarkStyle) + .keepAlive; } else { - return HomeTabSortPage(index, module, isDarkStyle: isDarkStyle).keepAlive; + return HomeTabSortPage(index, module, + isDarkStyle: isDarkStyle) + .keepAlive; } } else if (module.isACG) { /// 动漫/漫画/小说 - return CartoonSubDetailPage(tagData: module, type: MediaStyle.Cartoon, index: index).keepAlive; + return CartoonSubDetailPage( + tagData: module, + type: MediaStyle.Cartoon, + index: index) + .keepAlive; } else if (module.isDrama) { /// 短剧 - return HomeTabDramaPage(index, module, isDarkStyle: isDarkStyle).keepAlive; + return HomeTabDramaPage(index, module, + isDarkStyle: isDarkStyle) + .keepAlive; } else { //兜底 - return HomeTabSortPage(index, module, isDarkStyle: isDarkStyle).keepAlive; + return HomeTabSortPage(index, module, + isDarkStyle: isDarkStyle) + .keepAlive; } }), ), @@ -181,7 +196,9 @@ class _HomeTabViewState extends State with SingleTickerProviderStat tabAlignment: TabAlignment.start, tabs: logic.tabs.map((e) { //「最新」有更新时右上角挂红点 - final showDot = !isDarkStyle && e.id == '-110' && marker.showHomeLatestDot; + final showDot = !isDarkStyle && + e.id == '-110' && + marker.showHomeLatestDot; return Container( padding: EdgeInsets.symmetric(horizontal: 14.w), alignment: Alignment.center, @@ -204,8 +221,11 @@ class _HomeTabViewState extends State with SingleTickerProviderStat labelPadding: EdgeInsets.zero, unselectedLabelStyle: const TextStyle(fontSize: 14), unselectedLabelColor: const Color(0x80FFFFFF), - labelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), - labelColor: isDarkStyle ? const Color(0xffFFC000) : const Color(0xffFFC000), + labelStyle: + const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + labelColor: isDarkStyle + ? const Color(0xffFFC000) + : const Color(0xffFFC000), indicator: CustomIndicator( height: 2, width: 16.w, @@ -230,7 +250,8 @@ class _HomeTabViewState extends State with SingleTickerProviderStat onTap: () => widget.logic.openEndDrawer(), child: Container( padding: EdgeInsets.only(bottom: 4), - child: Image.asset('acg_menu.png'.acgImgPath, width: 24, color: const Color(0xff989898)), + child: Image.asset('acg_menu.png'.acgImgPath, + width: 24, color: const Color(0xff989898)), ), ); } diff --git a/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart b/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart index 2be8ba3..b6186c2 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../hj_utils/api_service/vid_service.dart'; @@ -9,16 +9,15 @@ import 'home_tab_base_logic.dart'; /// AI 短剧子 tab:拉 [VidService.getModuleDetail];专题样式(5)按选中专题拉 /// [ACGService.getPreferences],否则直接用模块 allMediaInfo。 class HomeTabDramaLogic extends HomeTabBaseLogic { - HomeTabDramaLogic(super.index, super.tabModel, {super.isDarkStyle}); - /// 专题样式(5)才走「专题 tab + fetchTopicWorks」;否则直接用 allMediaInfo 无 tab。 bool get hasSectionTabs => tabModel.haiJiaoStyle?.sectionStyle == 5; bool get isShowMenuTab => hasSectionTabs && allSection.isNotEmpty; - List get banners => isShowMenuTab ? (allSection[selectedSection].banners ?? []) : []; + List get banners => + isShowMenuTab ? (allSection[selectedSection].banners ?? []) : []; /// 当前选中专题下标 int selectedSection = 0; @@ -38,7 +37,8 @@ class HomeTabDramaLogic extends HomeTabBaseLogic { try { isInitData = true; update(); - dataSource = await VidService.getModuleDetail(tabModel.id ?? '', pageNumber: 1, pageSize: 10, moduleSort: 0); + dataSource = await VidService.getModuleDetail(tabModel.id ?? '', + pageNumber: 1, pageSize: 10, moduleSort: 0); _loadData(selectedSection); } catch (e) { debugLog(e); @@ -47,7 +47,6 @@ class HomeTabDramaLogic extends HomeTabBaseLogic { update(); } - void onInitListData() { videoList = null; update(); @@ -76,23 +75,30 @@ class HomeTabDramaLogic extends HomeTabBaseLogic { } /// 第一步:拉模块详情;完成后按样式进入第二步。 - Future _loadData(int selectedIndex, {int page = 1, int pageSize = 10}) async { + Future _loadData(int selectedIndex, + {int page = 1, int pageSize = 10}) async { try { bool hasNext = false; List retArr = []; if (hasSectionTabs) { final sectionId = _selectedSectionId; - final res = await ACGService.getPreferences(page, pageSize, sId: sectionId, type: null); - if(sectionId != _selectedSectionId){ + final res = await ACGService.getPreferences(page, pageSize, + sId: sectionId, type: null); + if (sectionId != _selectedSectionId) { //切换菜单了,数据直接丢弃 return; } retArr = res?.list?.map((e) => e.toDramaMediaInfo()).toList() ?? []; hasNext = res?.hasNext ?? false; } else { - ModuleDetailModel? detail = - await VidService.getModuleDetail(tabModel.id ?? '', pageNumber: page, pageSize: pageSize, moduleSort: 0); - retArr = detail?.allMediaInfo?.map((e) => e.toDramaMediaInfo()).toList() ?? []; + ModuleDetailModel? detail = await VidService.getModuleDetail( + tabModel.id ?? '', + pageNumber: page, + pageSize: pageSize, + moduleSort: 0); + retArr = + detail?.allMediaInfo?.map((e) => e.toDramaMediaInfo()).toList() ?? + []; hasNext = detail?.hasNext ?? false; } videoList ??= []; @@ -114,5 +120,4 @@ class HomeTabDramaLogic extends HomeTabBaseLogic { } update(); } - } diff --git a/lib/hj_page/home/home_sub_module/home_tab_drama_page.dart b/lib/hj_page/home/home_sub_module/home_tab_drama_page.dart index 1cd8174..d53b1ea 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_drama_page.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_drama_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_page/home/home_cell_style/drama_banner.dart'; -import 'package:hgmj/hj_page/home/home_cell_style/drama_cover_card.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_page/home/home_cell_style/drama_banner.dart'; +import 'package:wydj/hj_page/home/home_cell_style/drama_cover_card.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import 'home_tab_drama_logic.dart'; @@ -26,11 +26,13 @@ class HomeTabDramaPage extends StatefulWidget { State createState() => _HomeTabDramaPageState(); } -class _HomeTabDramaPageState extends State with UniqueTagMixin { +class _HomeTabDramaPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( - init: HomeTabDramaLogic(widget.tabIndex, widget.tabModel, isDarkStyle: widget.isDarkStyle), + init: HomeTabDramaLogic(widget.tabIndex, widget.tabModel, + isDarkStyle: widget.isDarkStyle), tag: uniqueTag, builder: (logic) { if (logic.isInitData) { @@ -99,10 +101,13 @@ class _HomeTabDramaPageState extends State with UniqueTagMixin return GestureDetector( onTap: () => logic.selectSection(i), child: Container( - padding: EdgeInsets.symmetric(horizontal: selected ? 12 : 8, vertical: 4), + padding: EdgeInsets.symmetric( + horizontal: selected ? 12 : 8, vertical: 4), alignment: Alignment.center, decoration: BoxDecoration( - color: selected ? const Color(0xFFFFC000) : const Color(0x0DFFFFFF), + color: selected + ? const Color(0xFFFFC000) + : const Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(20), ), child: Text( @@ -111,7 +116,9 @@ class _HomeTabDramaPageState extends State with UniqueTagMixin fontSize: 12, height: 18 / 12, fontWeight: selected ? FontWeight.w500 : FontWeight.w400, - color: selected ? const Color(0xFF292929) : const Color(0x8CFFFFFF), + color: selected + ? const Color(0xFF292929) + : const Color(0x8CFFFFFF), ), ), ), diff --git a/lib/hj_page/home/home_sub_module/home_tab_section_logic.dart b/lib/hj_page/home/home_sub_module/home_tab_section_logic.dart index e2f4227..5d635a1 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_section_logic.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_section_logic.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../hj_utils/api_service/vid_service.dart'; @@ -57,10 +57,14 @@ class HomeTabSectionLogic extends HomeTabBaseLogic { void _loadData({int page = 1, int size = 5}) async { try { - ModuleDetailModel? retResp = await VidService.getModuleDetail(tabModel.id ?? '', pageNumber: page, pageSize: size); + ModuleDetailModel? retResp = await VidService.getModuleDetail( + tabModel.id ?? '', + pageNumber: page, + pageSize: size); currentPage = page; - retResp?.allSection?.removeWhere((element) => element.allVideoInfo?.isEmpty ?? true); + retResp?.allSection + ?.removeWhere((element) => element.allVideoInfo?.isEmpty ?? true); if (currentPage == 1) { dataSource = retResp; } else { @@ -109,7 +113,8 @@ class HomeTabSectionLogic extends HomeTabBaseLogic { try { AllSection lastSection = allSection.last; int sortValue = gLikeSortParam[sortType]; - AllSection? retModel = await VidService.getGuessLike(page, size, tabModel.id ?? "", sortValue); + AllSection? retModel = await VidService.getGuessLike( + page, size, tabModel.id ?? "", sortValue); if (sortType != guessLikeSortType) { return; } @@ -119,7 +124,9 @@ class HomeTabSectionLogic extends HomeTabBaseLogic { lastSection.allVideoInfo?.clear(); } lastSection.allVideoInfo?.addAll(retModel?.allVideoInfo ?? []); - retModel?.hasNext == false ? refreshCtr?.loadNoData() : refreshCtr?.loadComplete(); + retModel?.hasNext == false + ? refreshCtr?.loadNoData() + : refreshCtr?.loadComplete(); } catch (e) { refreshCtr?.loadComplete(); } diff --git a/lib/hj_page/home/home_sub_module/home_tab_section_page.dart b/lib/hj_page/home/home_sub_module/home_tab_section_page.dart index 1d4e934..aaacf4f 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_section_page.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_section_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import '../../../hj_model/home/plate_model.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../tools_base/banner/ads_grid_view.dart'; import '../../../tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../home_cell_style/guess_like_sliver.dart'; import '../home_cell_style/quick_entry_row.dart'; import '../home_cell_style/home_section_cell.dart'; @@ -29,11 +29,13 @@ class HomeTabSectionPage extends StatefulWidget { State createState() => _HomeTabSectionPageState(); } -class _HomeTabSectionPageState extends State with UniqueTagMixin { +class _HomeTabSectionPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( - init: HomeTabSectionLogic(widget.tabIndex, widget.tabModel, isDarkStyle: widget.isDarkStyle), + init: HomeTabSectionLogic(widget.tabIndex, widget.tabModel, + isDarkStyle: widget.isDarkStyle), tag: uniqueTag, builder: (logic) { return Container( @@ -91,7 +93,8 @@ class _HomeTabSectionPageState extends State with UniqueTagM ads: section.adsInfoArr ?? [], padding: EdgeInsets.fromLTRB(12, 0, 12, 16), ); - } else if (logic.lastIsGuessLike && index == logic.allSection.length - 1) { + } else if (logic.lastIsGuessLike && + index == logic.allSection.length - 1) { return SizedBox(); // 最后一个猜你喜欢列表单独处理 } else if (section.allVideoInfo?.isNotEmpty == true) { //换一批、间距、分割线都在 HomeSectionCell 里 diff --git a/lib/hj_page/home/home_sub_module/home_tab_sort_logic.dart b/lib/hj_page/home/home_sub_module/home_tab_sort_logic.dart index 0e3d1db..2d4b795 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_sort_logic.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_sort_logic.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/home/video_list_model.dart'; -import 'package:hgmj/hj_page/home/provider/home_update_marker_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_model/home/video_list_model.dart'; +import 'package:wydj/hj_page/home/provider/home_update_marker_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; import 'package:uuid/uuid.dart'; import '../../../hj_model/home/module_detail_model.dart'; @@ -37,7 +37,8 @@ class HomeTabSortLogic extends HomeTabBaseLogic { SortTab('本月最热', 4), SortTab('年度最热', 5), ]; - List get lastestSortTitles => _lastestSortTabs.map((e) => e.name).toList(); + List get lastestSortTitles => + _lastestSortTabs.map((e) => e.name).toList(); int lastestModuleSort = 1; // 一排几个:haiJiaoStyle.defaultShow 0-一排两个(网格) 1-一排一个(单列),缺省按网格 @@ -99,12 +100,18 @@ class HomeTabSortLogic extends HomeTabBaseLogic { } void loadMoreData() { - _loadData(page: currentPage + 1, sortValue: isNewestStyle ? lastestModuleSort : moduleSort); + _loadData( + page: currentPage + 1, + sortValue: isNewestStyle ? lastestModuleSort : moduleSort); } // 每页固定 30:随机刷新接口也传同一个 size,分页偏移才对齐不重叠 // [refreshToken] 非空 = 走热门随机刷新接口,只换视频列表 - void _loadData({int page = 1, int size = 30, int sortValue = 0, String? refreshToken}) async { + void _loadData( + {int page = 1, + int size = 30, + int sortValue = 0, + String? refreshToken}) async { final seq = ++_reqSeq; try { bool hasNext = false; @@ -142,8 +149,11 @@ class HomeTabSortLogic extends HomeTabBaseLogic { currentPage = 1; // 刷新成功才重置页码,下次上拉从 pageNumber=2 开始 } } else { - ModuleDetailModel? retResp = - await VidService.getModuleDetail(tabModel.id ?? '', moduleSort: sortValue, pageNumber: page, pageSize: size); + ModuleDetailModel? retResp = await VidService.getModuleDetail( + tabModel.id ?? '', + moduleSort: sortValue, + pageNumber: page, + pageSize: size); if (seq != _reqSeq) return; // 已被更新的请求取代,本次结果作废 currentPage = page; @@ -159,7 +169,9 @@ class HomeTabSortLogic extends HomeTabBaseLogic { globalStore.filterShowType(dataSource?.allVideoInfo ?? []); dataSource?.allVideoInfo?.removeWhere((element) => element.isRandomAd()); if (isShowAd) { - AdManager().insertGroupAds(dataSource?.allVideoInfo ?? [], AdManager().adsByType(11), adGap: 6); + AdManager().insertGroupAds( + dataSource?.allVideoInfo ?? [], AdManager().adsByType(11), + adGap: 6); } hasNext ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); } catch (e) { diff --git a/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart b/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart index 89615ba..20c39fd 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../../hj_model/cartoon_media_info.dart'; import '../../../hj_model/home/plate_model.dart'; @@ -40,7 +40,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( - init: HomeTabSortLogic(widget.tabIndex, widget.tabModel, isDarkStyle: widget.isDarkStyle), + init: HomeTabSortLogic(widget.tabIndex, widget.tabModel, + isDarkStyle: widget.isDarkStyle), tag: uniqueTag, builder: (logic) { return Stack( @@ -71,7 +72,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { isDarkStyle: widget.isDarkStyle, ), ), - if (widget.tabModel.haiJiaoStyle?.sortShow == 1 || logic.isNewestStyle) + if (widget.tabModel.haiJiaoStyle?.sortShow == 1 || + logic.isNewestStyle) SliverPersistentHeader( pinned: true, delegate: MySliverDelegate( @@ -79,12 +81,14 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { minHeight: 42, callTop: (shrinkOffset) { if (shrinkOffset > 0) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance + .addPostFrameCallback((timeStamp) { logic.isSortMenuInTop.value = false; }); } if (shrinkOffset <= 0) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + WidgetsBinding.instance + .addPostFrameCallback((timeStamp) { logic.isSortMenuInTop.value = true; }); } @@ -103,11 +107,16 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { } return HomeSortHeader( isLatest: logic.isNewestStyle, - labelPadding: const EdgeInsets.symmetric(horizontal: 10), - tabs: logic.isNewestStyle ? logic.lastestSortTitles : logic.sortTitles, + labelPadding: + const EdgeInsets.symmetric(horizontal: 10), + tabs: logic.isNewestStyle + ? logic.lastestSortTitles + : logic.sortTitles, bgColor: bgColor, onSort: logic.sortMenuEvent, - rightWidget: logic.isNewestStyle ? null : _buildSortStyleMenu(logic), + rightWidget: logic.isNewestStyle + ? null + : _buildSortStyleMenu(logic), ); }, ), @@ -143,9 +152,12 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { 2.sizeBoxW, AnimatedSwitcher( duration: const Duration(milliseconds: 300), - transitionBuilder: (child, anim) => ScaleTransition(scale: anim, child: child), + transitionBuilder: (child, anim) => + ScaleTransition(scale: anim, child: child), child: Image.asset( - logic.isGridStyle.value ? 'list_style.webp'.homePath : 'grid_style.webp'.homePath, + logic.isGridStyle.value + ? 'list_style.webp'.homePath + : 'grid_style.webp'.homePath, key: ValueKey(logic.isGridStyle.value), width: 18, ), @@ -206,7 +218,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { crossAxisCount: logic.isGridStyle.value ? 2 : 1, mainAxisSpacing: logic.isGridStyle.value ? 12 : 14, crossAxisSpacing: 7, - childAspectRatio: logic.isGridStyle.value ? 168 / 134 : 340 / 215, //子控件宽高比 + childAspectRatio: + logic.isGridStyle.value ? 168 / 134 : 340 / 215, //子控件宽高比 ), delegate: SliverChildBuilderDelegate( (context, index) { @@ -237,7 +250,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { int leftCount = logic.allVideo.length % gapValue; int insertIndex = 0; for (int i = 0; i < allIndex; i++) { - List subList = logic.allVideo.sublist(i * gapValue, i * gapValue + gapValue); + List subList = + logic.allVideo.sublist(i * gapValue, i * gapValue + gapValue); slivers.add(SliverPadding( padding: EdgeInsets.only(bottom: 12), sliver: SliverGrid( @@ -245,7 +259,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { crossAxisCount: logic.isGridStyle.value ? 2 : 1, mainAxisSpacing: logic.isGridStyle.value ? 10 : 12, crossAxisSpacing: 7, - childAspectRatio: logic.isGridStyle.value ? 168 / 134 : 343 / 215, //子控件宽高比 + childAspectRatio: + logic.isGridStyle.value ? 168 / 134 : 343 / 215, //子控件宽高比 ), delegate: SliverChildBuilderDelegate( (context, index) { @@ -281,7 +296,8 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { crossAxisCount: logic.isGridStyle.value ? 2 : 1, mainAxisSpacing: logic.isGridStyle.value ? 10 : 12, crossAxisSpacing: 7, - childAspectRatio: logic.isGridStyle.value ? 168 / 134 : 343 / 215, //子控件宽高比 + childAspectRatio: + logic.isGridStyle.value ? 168 / 134 : 343 / 215, //子控件宽高比 ), delegate: SliverChildBuilderDelegate( (context, index) { diff --git a/lib/hj_page/home/home_sub_module/widget/sort_header.dart b/lib/hj_page/home/home_sub_module/widget/sort_header.dart index 1918082..e21eab4 100644 --- a/lib/hj_page/home/home_sub_module/widget/sort_header.dart +++ b/lib/hj_page/home/home_sub_module/widget/sort_header.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_page/home/provider/home_update_marker_provider.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_page/home/provider/home_update_marker_provider.dart'; import 'package:provider/provider.dart'; /// 首页模块的排序切换栏(热门推荐 / 最新上架 / ...) @@ -27,9 +27,12 @@ class HomeSortHeader extends StatefulWidget { State createState() => _HomeSortHeaderState(); } -class _HomeSortHeaderState extends State with SingleTickerProviderStateMixin { - late final List tabs = widget.tabs ?? const ['热门推荐', '最新上架', '最新热评', '最多收藏']; - late final TabController tabCtr = TabController(length: tabs.length, vsync: this); +class _HomeSortHeaderState extends State + with SingleTickerProviderStateMixin { + late final List tabs = + widget.tabs ?? const ['热门推荐', '最新上架', '最新热评', '最多收藏']; + late final TabController tabCtr = + TabController(length: tabs.length, vsync: this); @override void dispose() { @@ -41,7 +44,7 @@ class _HomeSortHeaderState extends State with SingleTickerProvid Widget build(BuildContext context) { if (widget.isLatest) { return _buildNewsetsStyle(); - }else { + } else { return Container( height: 38, color: widget.bgColor ?? Theme.of(context).scaffoldBackgroundColor, @@ -60,13 +63,15 @@ class _HomeSortHeaderState extends State with SingleTickerProvid onTap: widget.onSort, indicatorWeight: 0, indicator: const BoxDecoration(), - labelPadding: widget.labelPadding ?? const EdgeInsets.symmetric(horizontal: 8), + labelPadding: + widget.labelPadding ?? const EdgeInsets.symmetric(horizontal: 8), labelStyle: const TextStyle( color: Color(0xE5FFFFFF), fontSize: 14, fontWeight: FontWeight.w600, ), - unselectedLabelStyle: const TextStyle(color: Color(0x8CFFFFFF), fontSize: 14), + unselectedLabelStyle: + const TextStyle(color: Color(0x8CFFFFFF), fontSize: 14), tabs: List.generate(tabs.length, (i) => Text(tabs[i])), ); } @@ -82,20 +87,21 @@ class _HomeSortHeaderState extends State with SingleTickerProvid tabAlignment: TabAlignment.center, onTap: widget.onSort, indicatorWeight: 0, - indicator: BoxDecoration(color: AppColors.actionRed, borderRadius: BorderRadius.circular(3)), + indicator: BoxDecoration( + color: AppColors.actionRed, borderRadius: BorderRadius.circular(3)), labelPadding: const EdgeInsets.symmetric(horizontal: 6), labelStyle: const TextStyle( color: Color(0xff1F2029), fontSize: 12, fontWeight: FontWeight.w500, ), - unselectedLabelStyle: const TextStyle(color: Color(0x8CFFFFFF), fontSize: 12), + unselectedLabelStyle: + const TextStyle(color: Color(0x8CFFFFFF), fontSize: 12), tabs: List.generate(tabs.length, (i) => _latestTab(i, tabs[i])), ), ); } - /// 红点只落在「最新」页首个 tab,只让它订阅 provider Widget _latestTab(int index, String label) { final text = Padding( @@ -109,7 +115,10 @@ class _HomeSortHeaderState extends State with SingleTickerProvid children: [ text, if (marker.showTodayLatestDot) - Positioned(right: 4, top: 0, child: HomeUpdateMarkerProvider.buildRedDot()), + Positioned( + right: 4, + top: 0, + child: HomeUpdateMarkerProvider.buildRedDot()), ], ), ); diff --git a/lib/hj_page/home/home_sub_module/widget/special_topics_view.dart b/lib/hj_page/home/home_sub_module/widget/special_topics_view.dart index 852a31b..aa535f4 100644 --- a/lib/hj_page/home/home_sub_module/widget/special_topics_view.dart +++ b/lib/hj_page/home/home_sub_module/widget/special_topics_view.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/refresh/horizontal_load_more.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/refresh/horizontal_load_more.dart'; import '../../../../tools_base/widget/net_image_widget.dart'; import '../../../cartoon/cartoon_sectionlist_page.dart'; @@ -55,7 +55,8 @@ class SpecialTopicsView extends StatelessWidget { /// 注:原创达人区不走这里,它固定进专题详情(见 [_actressSection]) void _onTap(AllSection model) { if (module?.isACG == true) { - Get.to(CartoonSectionListPage(sectionID: model.sectionID, tagName: model.sectionName)); + Get.to(CartoonSectionListPage( + sectionID: model.sectionID, tagName: model.sectionName)); } else { Get.to(SpecialTopicsDetailPage(model), preventDuplicates: false); } @@ -63,7 +64,8 @@ class SpecialTopicsView extends StatelessWidget { // ========== 样式 1 / 5:圆头像横滑 ========== - Widget _avatarRow(List list, {required double height, required double imgSize}) { + Widget _avatarRow(List list, + {required double height, required double imgSize}) { return Container( margin: padding, height: height, @@ -111,7 +113,10 @@ class SpecialTopicsView extends StatelessWidget { Text( list.first.sectionName ?? "", maxLines: 1, - style: const TextStyle(color: Color(0xE5FFFFFF), fontSize: 18, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 18, + fontWeight: FontWeight.w500), ), _avatarRow(list, height: 84, imgSize: 55), ], @@ -143,21 +148,31 @@ class SpecialTopicsView extends StatelessWidget { width: double.infinity, height: double.infinity, decoration: BoxDecoration( - color: isDarkStyle ? const Color(0x4D810906) : const Color(0x0DFFFFFF), + color: + isDarkStyle ? const Color(0x4D810906) : const Color(0x0DFFFFFF), borderRadius: const BorderRadius.all(Radius.circular(2)), ), child: Stack( alignment: Alignment.center, children: [ - if (isDarkStyle) Positioned(top: 0, child: Image.asset("aw_tag.webp".homePath, height: 13)), + if (isDarkStyle) + Positioned( + top: 0, + child: Image.asset("aw_tag.webp".homePath, height: 13)), Text( "${model.sectionName}", - style: const TextStyle(color: Color(0xE5FFFFFF), fontSize: 12, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 12, + fontWeight: FontWeight.w500), maxLines: 1, overflow: TextOverflow.ellipsis, ), if (model.hot == true) - Positioned(top: 0, right: 0, child: Image.asset("home_hot.webp".homePath, height: 20)), + Positioned( + top: 0, + right: 0, + child: Image.asset("home_hot.webp".homePath, height: 20)), ], ), ), @@ -182,11 +197,16 @@ class SpecialTopicsView extends StatelessWidget { child: Text( '原创达人', maxLines: 1, - style: TextStyle(color: Color(0xE5FFFFFF), fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 18, + fontWeight: FontWeight.w600), ), ), 10.sizeBoxW, - const Text('更多', maxLines: 1, style: TextStyle(color: Color(0x59FFFFFF), fontSize: 12)), + const Text('更多', + maxLines: 1, + style: TextStyle(color: Color(0x59FFFFFF), fontSize: 12)), Image.asset("arrow_right_grey.webp".commonImgPath, width: 18), ], ), @@ -221,7 +241,8 @@ class SpecialTopicsView extends StatelessWidget { Widget _actressItem(AllSection model, double itemW) { return GestureDetector( //达人固定进专题详情,不走 _onTap 的漫画分支 - onTap: () => Get.to(SpecialTopicsDetailPage(model), preventDuplicates: false), + onTap: () => + Get.to(SpecialTopicsDetailPage(model), preventDuplicates: false), child: SizedBox( height: double.infinity, width: itemW, diff --git a/lib/hj_page/home/provider/home_update_marker_provider.dart b/lib/hj_page/home/provider/home_update_marker_provider.dart index e7f0f72..03c9690 100644 --- a/lib/hj_page/home/provider/home_update_marker_provider.dart +++ b/lib/hj_page/home/provider/home_update_marker_provider.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/home/update_marker_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/home/update_marker_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; /// 首页「最新 / 今日最新」等内容更新红点 class HomeUpdateMarkerProvider with ChangeNotifier { - static final HomeUpdateMarkerProvider _instance = HomeUpdateMarkerProvider._(); + static final HomeUpdateMarkerProvider _instance = + HomeUpdateMarkerProvider._(); HomeUpdateMarkerProvider._(); factory HomeUpdateMarkerProvider() => _instance; @@ -18,9 +19,11 @@ class HomeUpdateMarkerProvider with ChangeNotifier { String? _lastViewTodayLatestAt; final Map _lastViewModuleAt = {}; - bool get showHomeLatestDot => _isNewer(_markers?.homeLatestAt, _lastViewHomeLatestAt); + bool get showHomeLatestDot => + _isNewer(_markers?.homeLatestAt, _lastViewHomeLatestAt); - bool get showTodayLatestDot => _isNewer(_markers?.todayLatestAt, _lastViewTodayLatestAt); + bool get showTodayLatestDot => + _isNewer(_markers?.todayLatestAt, _lastViewTodayLatestAt); bool showModuleDot(String? moduleId) { if (moduleId == null || moduleId.isEmpty) return false; @@ -101,8 +104,10 @@ class HomeUpdateMarkerProvider with ChangeNotifier { } Future _loadLocalLastViewed() async { - _lastViewHomeLatestAt = await lightKV.getString(StoreKeys.HOME_LATEST_LAST_VIEW_AT); - _lastViewTodayLatestAt = await lightKV.getString(StoreKeys.HOME_TODAY_LATEST_LAST_VIEW_AT); + _lastViewHomeLatestAt = + await lightKV.getString(StoreKeys.HOME_LATEST_LAST_VIEW_AT); + _lastViewTodayLatestAt = + await lightKV.getString(StoreKeys.HOME_TODAY_LATEST_LAST_VIEW_AT); _lastViewModuleAt.clear(); for (final m in _markers?.modules ?? const []) { final id = m.moduleId; diff --git a/lib/hj_page/home/search_page/search_main_logic.dart b/lib/hj_page/home/search_page/search_main_logic.dart index 428f16b..7cc602a 100644 --- a/lib/hj_page/home/search_page/search_main_logic.dart +++ b/lib/hj_page/home/search_page/search_main_logic.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/history_util.dart'; import 'search_result_page/search_result_main_page.dart'; @@ -51,7 +51,8 @@ class SearchMainLogic extends GetxController { Future onSubmitted(String text) async { searchTextCtr.text = text; HistoryUtil.addSearch(text); //不 await:落盘不该挡住跳转,返回时早已写完 - await Get.to(() => SearchResultMainPage(text, initialType: initialResultType)); + await Get.to( + () => SearchResultMainPage(text, initialType: initialResultType)); loadHistories(); } } diff --git a/lib/hj_page/home/search_page/search_main_page.dart b/lib/hj_page/home/search_page/search_main_page.dart index dd355d0..8abc51a 100644 --- a/lib/hj_page/home/search_page/search_main_page.dart +++ b/lib/hj_page/home/search_page/search_main_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; import '../../find/rank_module/rank_main_page.dart'; import '../../find/rank_module/rank_sub_page.dart'; @@ -39,7 +39,8 @@ class SearchMainPage extends StatelessWidget { Expanded( child: NestedScrollView( headerSliverBuilder: (_, __) => _headerSlivers(logic), - body: const RankSubPage(pageType: MediaStyle.Video, sortType: 2), // 2 = 周榜 + body: const RankSubPage( + pageType: MediaStyle.Video, sortType: 2), // 2 = 周榜 ), ), ], @@ -71,7 +72,8 @@ class SearchMainPage extends StatelessWidget { ), ), //热搜词 - SliverToBoxAdapter(child: SearchHotTagView(onTagClick: logic.onSubmitted)), + SliverToBoxAdapter( + child: SearchHotTagView(onTagClick: logic.onSubmitted)), //「热门排行」标题行,右侧跳完整排行榜页 SliverToBoxAdapter( child: Padding( @@ -80,12 +82,16 @@ class SearchMainPage extends StatelessWidget { children: [ const Text( '热门排行', - style: TextStyle(color: Color(0xE5FFFFFF), fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + color: Color(0xE5FFFFFF), + fontSize: 18, + fontWeight: FontWeight.w600), ), const Spacer(), InkWell( enableFeedback: false, - onTap: () => Get.to(() => const RankMainPage(), preventDuplicates: false), + onTap: () => Get.to(() => const RankMainPage(), + preventDuplicates: false), child: Container( width: 54, height: 18, @@ -93,8 +99,13 @@ class SearchMainPage extends StatelessWidget { margin: const EdgeInsets.only(left: 8), child: Row( children: [ - Text('更多', style: TextStyle(color: Colors.white.withValues(alpha: 0.55), fontSize: 14)), - Icon(Icons.navigate_next, size: 22, color: Colors.white.withValues(alpha: 0.55)), + Text('更多', + style: TextStyle( + color: Colors.white.withValues(alpha: 0.55), + fontSize: 14)), + Icon(Icons.navigate_next, + size: 22, + color: Colors.white.withValues(alpha: 0.55)), ], ), ), diff --git a/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart b/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart index 7ebe334..4561453 100644 --- a/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart +++ b/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../../hj_model/acg/cartoon_more_list.dart'; @@ -40,15 +40,20 @@ class _SearchACGResultPageState extends State { _loadData({int page = 1, int size = 12}) async { try { - MediaSearchListModel? retResp = - await ACGService.mediaSearch(keyword: widget.keywords, page: page, size: size, kind: widget.type.searchKind); + MediaSearchListModel? retResp = await ACGService.mediaSearch( + keyword: widget.keywords, + page: page, + size: size, + kind: widget.type.searchKind); pageNumber = page; videoList ??= []; if (page == 1) { videoList?.clear(); } videoList?.addAll(retResp?.list ?? []); - retResp?.hasNext == false ? refreshController?.loadNoData() : refreshController?.loadComplete(); + retResp?.hasNext == false + ? refreshController?.loadNoData() + : refreshController?.loadComplete(); } catch (e) { refreshController?.loadComplete(); debugLog(e); diff --git a/lib/hj_page/home/search_page/search_result_page/search_result_main_page.dart b/lib/hj_page/home/search_page/search_result_page/search_result_main_page.dart index 5d381d3..a979a1d 100644 --- a/lib/hj_page/home/search_page/search_result_page/search_result_main_page.dart +++ b/lib/hj_page/home/search_page/search_result_page/search_result_main_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/history_util.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../../tools_base/indicator/custom_tab_indicator.dart'; import '../widget/search_app_bar.dart'; @@ -22,7 +22,8 @@ class SearchResultMainPage extends StatefulWidget { } } -class _SearchResultMainPageState extends State with SingleTickerProviderStateMixin { +class _SearchResultMainPageState extends State + with SingleTickerProviderStateMixin { final typeList = ['影片', '短剧', '抖音', '漫画', '动漫', '帖子', '图集']; late final TabController tabCtr; @@ -86,20 +87,49 @@ class _SearchResultMainPageState extends State with Single padding: EdgeInsets.zero, isScrollable: false, labelPadding: EdgeInsets.zero, - indicator: const CustomIndicator(height: 4, width: 16, isGradient: true, offsetY: 4), + indicator: const CustomIndicator( + height: 4, width: 16, isGradient: true, offsetY: 4), ), ), Expanded( child: TabBarView( controller: tabCtr, children: [ - SearchVideoResultPage(key: ValueKey("0$keywords"), keywords: keywords, type: MediaStyle.Video).keepAlive, - SearchVideoResultPage(key: ValueKey("1$keywords"), keywords: keywords, type: MediaStyle.Drama).keepAlive, - SearchVideoResultPage(key: ValueKey("2$keywords"), keywords: keywords, type: MediaStyle.ShortVideo).keepAlive, - SearchACGResultPage(key: ValueKey("3$keywords"), keywords: keywords, type: MediaStyle.Comics).keepAlive, - SearchACGResultPage(key: ValueKey("4$keywords"), keywords: keywords, type: MediaStyle.Cartoon).keepAlive, - SearchVideoResultPage(key: ValueKey("5$keywords"), keywords: keywords, type: MediaStyle.Community).keepAlive, - SearchVideoResultPage(key: ValueKey("6$keywords"), keywords: keywords, type: MediaStyle.Pic).keepAlive, + SearchVideoResultPage( + key: ValueKey("0$keywords"), + keywords: keywords, + type: MediaStyle.Video) + .keepAlive, + SearchVideoResultPage( + key: ValueKey("1$keywords"), + keywords: keywords, + type: MediaStyle.Drama) + .keepAlive, + SearchVideoResultPage( + key: ValueKey("2$keywords"), + keywords: keywords, + type: MediaStyle.ShortVideo) + .keepAlive, + SearchACGResultPage( + key: ValueKey("3$keywords"), + keywords: keywords, + type: MediaStyle.Comics) + .keepAlive, + SearchACGResultPage( + key: ValueKey("4$keywords"), + keywords: keywords, + type: MediaStyle.Cartoon) + .keepAlive, + SearchVideoResultPage( + key: ValueKey("5$keywords"), + keywords: keywords, + type: MediaStyle.Community) + .keepAlive, + SearchVideoResultPage( + key: ValueKey("6$keywords"), + keywords: keywords, + type: MediaStyle.Pic) + .keepAlive, ], ), ), diff --git a/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart b/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart index 9a7b2d4..1e72be7 100644 --- a/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart +++ b/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart @@ -2,14 +2,14 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/drama/drama_tag_detail_page.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/api_service/search_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/drama/drama_tag_detail_page.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/api_service/search_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../../hj_model/home/video_list_model.dart'; @@ -73,18 +73,26 @@ class _SearchVideoResultPageState extends State { pageNumber = page; if (page == 1) { videoList = []; - tagVidList = retResp?.tagMediaList.map((e) => e.toVideoModel(null)).toList() ?? []; + tagVidList = + retResp?.tagMediaList.map((e) => e.toVideoModel(null)).toList() ?? + []; tagID = retResp?.tagID; } videoList ??= []; videoList?.addAll(retResp?.list.map((e) => e.toVideoModel(null)) ?? []); - retResp?.hasNext != true ? refreshController?.loadNoData() : refreshController?.loadComplete(); + retResp?.hasNext != true + ? refreshController?.loadNoData() + : refreshController?.loadComplete(); } else { - VideoListResp? retResp = await SearchService.searchMedia(widget.keywords, - pageNumber: page, pageSize: size, realm: widget.type.searchRealm, sortType: sortValue); + VideoListResp? retResp = await SearchService.searchMedia( + widget.keywords, + pageNumber: page, + pageSize: size, + realm: widget.type.searchRealm, + sortType: sortValue); pageNumber = page; videoList ??= []; - if(page == 1) { + if (page == 1) { videoList?.clear(); } videoList?.addAll(retResp?.videos ?? []); @@ -92,7 +100,9 @@ class _SearchVideoResultPageState extends State { tagVidList = retResp?.tagVidList ?? []; tagID = retResp?.tagID; } - retResp?.hasNext == false ? refreshController?.loadNoData() : refreshController?.loadComplete(); + retResp?.hasNext == false + ? refreshController?.loadNoData() + : refreshController?.loadComplete(); } } catch (e) { refreshController?.loadComplete(); @@ -128,7 +138,8 @@ class _SearchVideoResultPageState extends State { }, body: Column( children: [ - if (widget.type == MediaStyle.Video || widget.type == MediaStyle.ShortVideo) + if (widget.type == MediaStyle.Video || + widget.type == MediaStyle.ShortVideo) DividerTabBar( _sortTabs.map((e) => e.name).toList(), selectIndex: sortIndex, @@ -187,7 +198,8 @@ class _SearchVideoResultPageState extends State { }, ); } - if (widget.type == MediaStyle.Video || widget.type == MediaStyle.ShortVideo) { + if (widget.type == MediaStyle.Video || + widget.type == MediaStyle.ShortVideo) { bool isShort = widget.type == MediaStyle.ShortVideo; return GridView.builder( padding: EdgeInsets.only(left: 12, right: 12), @@ -267,7 +279,8 @@ class _SearchVideoResultPageState extends State { if (tagID?.isNotEmpty == true) ...[ const SizedBox(height: 12), GestureDetector( - onTap: () => DramaTagDetailPage.to(TagsBean(id: tagID, name: widget.keywords)), + onTap: () => DramaTagDetailPage.to( + TagsBean(id: tagID, name: widget.keywords)), child: Container( height: 40, alignment: Alignment.center, @@ -278,9 +291,12 @@ class _SearchVideoResultPageState extends State { child: const Row( mainAxisSize: MainAxisSize.min, children: [ - Text('查看更多', style: TextStyle(color: Color(0xffFFFFFF), fontSize: 14)), + Text('查看更多', + style: TextStyle( + color: Color(0xffFFFFFF), fontSize: 14)), SizedBox(width: 6), - Icon(Icons.keyboard_arrow_right, color: Color(0xffFFFFFF), size: 18), + Icon(Icons.keyboard_arrow_right, + color: Color(0xffFFFFFF), size: 18), ], ), ), @@ -291,7 +307,8 @@ class _SearchVideoResultPageState extends State { ), ); } - if (widget.type == MediaStyle.Video || widget.type == MediaStyle.ShortVideo) { + if (widget.type == MediaStyle.Video || + widget.type == MediaStyle.ShortVideo) { bool isShort = widget.type == MediaStyle.ShortVideo; return Container( padding: EdgeInsets.fromLTRB(12, 12, 12, 0), diff --git a/lib/hj_page/home/search_page/video_all_type_page.dart b/lib/hj_page/home/search_page/video_all_type_page.dart index be4e153..1e39f7c 100644 --- a/lib/hj_page/home/search_page/video_all_type_page.dart +++ b/lib/hj_page/home/search_page/video_all_type_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; import 'package:waterfall_flow/waterfall_flow.dart'; import '../../../hj_model/home/video_library_model.dart'; @@ -73,8 +73,12 @@ class _VideoAllTypePageState extends State { SliverToBoxAdapter( child: Column( children: [ - _buildItemMenuWidget("分类", logic.homeVideoLibrary?.canvas, logic.firstSelectedType, (data) { - if (logic.firstSelectedType?.isACG != data.isACG) { + _buildItemMenuWidget( + "分类", + logic.homeVideoLibrary?.canvas, + logic.firstSelectedType, (data) { + if (logic.firstSelectedType?.isACG != + data.isACG) { logic.thirdSelectedType = null; } if (logic.firstSelectedType != data) { @@ -85,7 +89,10 @@ class _VideoAllTypePageState extends State { logic.searchVideoList?.clear(); logic.menuExchangeEvent(); }), - _buildItemMenuWidget("排序", logic.homeVideoLibrary?.orderBy, logic.secondSelectedType, (data) { + _buildItemMenuWidget( + "排序", + logic.homeVideoLibrary?.orderBy, + logic.secondSelectedType, (data) { if (logic.secondSelectedType != data) { logic.secondSelectedType = data; } else { @@ -93,7 +100,9 @@ class _VideoAllTypePageState extends State { } logic.menuExchangeEvent(); }), - _buildTagMenuWidget("标签", logic.tags, logic.thirdSelectedType, (data) { + _buildTagMenuWidget( + "标签", logic.tags, logic.thirdSelectedType, + (data) { if (logic.thirdSelectedType != data) { logic.thirdSelectedType = data; } else { @@ -101,7 +110,10 @@ class _VideoAllTypePageState extends State { } logic.menuExchangeEvent(); }), - _buildItemMenuWidget("时间", logic.homeVideoLibrary?.timeType, logic.fivthSelectedType, (data) { + _buildItemMenuWidget( + "时间", + logic.homeVideoLibrary?.timeType, + logic.fivthSelectedType, (data) { if (logic.fivthSelectedType != data) { logic.fivthSelectedType = data; } else { @@ -208,7 +220,8 @@ class _VideoAllTypePageState extends State { child: LoadingCenterWidget(), ), ); - } else if (logic.searchVideoList?.isNotEmpty != true && logic.searchACGList?.isNotEmpty != true) { + } else if (logic.searchVideoList?.isNotEmpty != true && + logic.searchACGList?.isNotEmpty != true) { return SliverToBoxAdapter( child: SizedBox( height: 300, @@ -235,10 +248,14 @@ class _VideoAllTypePageState extends State { ); } if (typeName == "图集") { - return _buildWaterfall(logic, (vm) => PhotoGalleryItem(videoModel: vm, textline: 1)); + return _buildWaterfall( + logic, (vm) => PhotoGalleryItem(videoModel: vm, textline: 1)); } if (typeName == "抖音" || logic.firstSelectedType?.key == "sp") { - return _buildWaterfall(logic, (vm) => VideoSimpleCell(videoModel: vm, textLines: 1, isShort: true)); + return _buildWaterfall( + logic, + (vm) => + VideoSimpleCell(videoModel: vm, textLines: 1, isShort: true)); } else if (typeName == "动漫" || typeName == "漫画") { bool isCartoon = typeName == "动漫"; return SliverPadding( @@ -285,7 +302,8 @@ class _VideoAllTypePageState extends State { } //图集/抖音共用的 3 列瀑布流(仅 item 构建不同) - Widget _buildWaterfall(VideoAllTypeLogic logic, Widget Function(VideoModel vm) itemBuilder) { + Widget _buildWaterfall( + VideoAllTypeLogic logic, Widget Function(VideoModel vm) itemBuilder) { return SliverPadding( padding: const EdgeInsets.fromLTRB(12, 12, 12, 0), sliver: SliverWaterfallFlow( @@ -305,7 +323,8 @@ class _VideoAllTypePageState extends State { ); } - Widget _buildItemMenuWidget(String typeName, List? listData, TimeType? selectType, Function(TimeType timeType) callBack) { + Widget _buildItemMenuWidget(String typeName, List? listData, + TimeType? selectType, Function(TimeType timeType) callBack) { selectType ??= listData?[0]; return Container( height: 40, @@ -322,7 +341,8 @@ class _VideoAllTypePageState extends State { itemBuilder: (context, index) { TimeType data = listData![index]; bool isSelected = selectType?.name == data.name; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () async { callBack.call(data); }, @@ -336,7 +356,8 @@ class _VideoAllTypePageState extends State { ); } - Widget _buildTagMenuWidget(String typeName, List? listData, Tags? selectType, Function(Tags timeType) callBack) { + Widget _buildTagMenuWidget(String typeName, List? listData, + Tags? selectType, Function(Tags timeType) callBack) { selectType ??= listData?[0]; return Container( height: 40, diff --git a/lib/hj_page/home/search_page/widget/common_search_widget.dart b/lib/hj_page/home/search_page/widget/common_search_widget.dart index 446f308..57aade4 100644 --- a/lib/hj_page/home/search_page/widget/common_search_widget.dart +++ b/lib/hj_page/home/search_page/widget/common_search_widget.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../../tools_base/widget/marquee_widget.dart'; import '../../../../tools_base/widget/net_image_widget.dart'; @@ -69,7 +69,7 @@ class _CommonSearchBarViewState extends State { child: Image.asset('nav_logo.webp'.homePath, width: 28, height: 28), ), 6.sizeBoxW, - const Text('黄果漫剧', style: _titleStyle), + const Text('51短剧', style: _titleStyle), ], ); } @@ -89,18 +89,22 @@ class _CommonSearchBarViewState extends State { ), child: Row( children: [ - Image.asset('search_icon.png'.commonImgPath, width: 18, height: 18, color: Colors.white), + Image.asset('search_icon.png'.commonImgPath, + width: 18, height: 18, color: Colors.white), 8.sizeBoxW, Expanded( child: Config.searchHints.isEmpty ? Text('请输入关键字', style: _hintStyle) : MarqueeWidget( count: Config.searchHints.length, - onIndexChanged: (index) => _searchText = Config.searchHints[index], + onIndexChanged: (index) => + _searchText = Config.searchHints[index], itemBuilder: (_, index) => Container( alignment: Alignment.centerLeft, child: Text(Config.searchHints[index], - style: _hintStyle, maxLines: 1, overflow: TextOverflow.ellipsis), + style: _hintStyle, + maxLines: 1, + overflow: TextOverflow.ellipsis), ), ), ), diff --git a/lib/hj_page/home/search_page/widget/search_app_bar.dart b/lib/hj_page/home/search_page/widget/search_app_bar.dart index 573b0a5..6e89e9d 100644 --- a/lib/hj_page/home/search_page/widget/search_app_bar.dart +++ b/lib/hj_page/home/search_page/widget/search_app_bar.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../video_all_type_page.dart'; @@ -76,7 +76,9 @@ class _SearchAppBarState extends State { height: 32, padding: EdgeInsets.symmetric(horizontal: 10), alignment: Alignment.centerLeft, - decoration: BoxDecoration(color: Color(0x11FFFFFF), borderRadius: BorderRadius.circular(20)), + decoration: BoxDecoration( + color: Color(0x11FFFFFF), + borderRadius: BorderRadius.circular(20)), child: Row( children: [ InkWell( @@ -87,7 +89,8 @@ class _SearchAppBarState extends State { child: Row( children: [ 2.sizeBoxW, - Image.asset('libary_search.webp'.homePath, width: 20, color: Color(0xFFFFC000)), + Image.asset('libary_search.webp'.homePath, + width: 20, color: Color(0xFFFFC000)), 6.sizeBoxW, Text( '片库', @@ -109,7 +112,10 @@ class _SearchAppBarState extends State { Expanded( child: TextField( controller: searchTextCtr, - style: TextStyle(color: Colors.white.withValues(alpha: .8), fontSize: 14, height: 1), + style: TextStyle( + color: Colors.white.withValues(alpha: .8), + fontSize: 14, + height: 1), onSubmitted: (value) => widget.onSubmitted(value), onChanged: (value) { if (value.isNotEmpty == true) { @@ -125,7 +131,10 @@ class _SearchAppBarState extends State { textInputAction: TextInputAction.search, decoration: InputDecoration( hintText: '搜索关键词', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 14, height: 1), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 14, + height: 1), border: InputBorder.none, isDense: true, contentPadding: EdgeInsets.zero, @@ -142,7 +151,8 @@ class _SearchAppBarState extends State { showDeleteIcon = false; }); }, - child: Image.asset('search_close.webp'.homePath, width: 18), + child: Image.asset('search_close.webp'.homePath, + width: 18), ), ) ], diff --git a/lib/hj_page/home/search_page/widget/search_history_view.dart b/lib/hj_page/home/search_page/widget/search_history_view.dart index 7ee5dd4..0886b73 100644 --- a/lib/hj_page/home/search_page/widget/search_history_view.dart +++ b/lib/hj_page/home/search_page/widget/search_history_view.dart @@ -1,8 +1,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// 搜索历史区:纯展示,数据与增删由 SearchMainLogic 持有 class SearchHistoryView extends StatefulWidget { @@ -57,7 +57,8 @@ class _SearchHistoryViewState extends State { onTap: widget.onClearAll, child: Container( padding: const EdgeInsets.all(1), - child: Image.asset("history_delete.webp".homePath, width: 18, height: 18), + child: Image.asset("history_delete.webp".homePath, + width: 18, height: 18), ), ), ], @@ -74,7 +75,8 @@ class _SearchHistoryViewState extends State { mainAxisSpacing: 12, crossAxisSpacing: 12, ), - itemBuilder: (_, index) => _buildHistoryItem(widget.histories[index]), + itemBuilder: (_, index) => + _buildHistoryItem(widget.histories[index]), ), _buildMoreRecord(), ], @@ -108,7 +110,8 @@ class _SearchHistoryViewState extends State { return Container( padding: const EdgeInsets.only(top: 12), alignment: Alignment.topCenter, - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () => setState(() => isExpandData = !isExpandData), child: Row( mainAxisSize: MainAxisSize.min, diff --git a/lib/hj_page/home/search_page/widget/search_hot_tag_view.dart b/lib/hj_page/home/search_page/widget/search_hot_tag_view.dart index 43fba88..f60d547 100644 --- a/lib/hj_page/home/search_page/widget/search_hot_tag_view.dart +++ b/lib/hj_page/home/search_page/widget/search_hot_tag_view.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; - +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; class SearchHotTagView extends StatelessWidget { final Function(String keyword) onTagClick; diff --git a/lib/hj_page/home/search_page/widget/topic_item.dart b/lib/hj_page/home/search_page/widget/topic_item.dart index f78b78b..3fed581 100644 --- a/lib/hj_page/home/search_page/widget/topic_item.dart +++ b/lib/hj_page/home/search_page/widget/topic_item.dart @@ -1,20 +1,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../community/community_tag_page/community_tag_page.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; class TopicItem extends StatelessWidget { final TagsBean model; final bool isSelect; final Function()? onTap; - const TopicItem({super.key, required this.model, this.onTap, this.isSelect = false}); + const TopicItem( + {super.key, required this.model, this.onTap, this.isSelect = false}); @override Widget build(BuildContext context) { @@ -50,7 +51,10 @@ class TopicItem extends StatelessWidget { children: [ Text( '#${model.name}', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/lib/hj_page/home/section_all_page/section_all_logic.dart b/lib/hj_page/home/section_all_page/section_all_logic.dart index 7fd6571..b185b58 100644 --- a/lib/hj_page/home/section_all_page/section_all_logic.dart +++ b/lib/hj_page/home/section_all_page/section_all_logic.dart @@ -1,4 +1,4 @@ -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../../../hj_utils/api_service/vid_service.dart'; @@ -24,7 +24,8 @@ class SectionAllLogic extends ListBaseLogic { } Future<(List?, bool)> _fetch(int page) async { - final resp = await VidService.fetchSectionAll(id, pageNumber: page, pageSize: 20); + final resp = + await VidService.fetchSectionAll(id, pageNumber: page, pageSize: 20); //hasNext 为 null 时按"有更多"处理(保持原 == false 判断语义) return (resp?.list, resp?.hasNext != false); } diff --git a/lib/hj_page/home/section_all_page/section_all_page.dart b/lib/hj_page/home/section_all_page/section_all_page.dart index 75a3ba5..6376171 100644 --- a/lib/hj_page/home/section_all_page/section_all_page.dart +++ b/lib/hj_page/home/section_all_page/section_all_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../special_topic_detail/special_topics_detail_page.dart'; @@ -39,9 +39,11 @@ class SectionAllPage extends StatelessWidget { itemCount: list.length, itemBuilder: (context, index) { AllSection model = list[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { - Get.to(SpecialTopicsDetailPage(model), preventDuplicates: false); + Get.to(SpecialTopicsDetailPage(model), + preventDuplicates: false); }, child: Container( margin: EdgeInsets.only(bottom: 12), @@ -67,7 +69,8 @@ class SectionAllPage extends StatelessWidget { ), ), 12.sizeBoxW, - Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 16), + Icon(Icons.keyboard_arrow_right, + color: Colors.white, size: 16), ], ), ), diff --git a/lib/hj_page/home/special_topic_detail/special_topics_detail_logic.dart b/lib/hj_page/home/special_topic_detail/special_topics_detail_logic.dart index 7ff3724..b9183a8 100644 --- a/lib/hj_page/home/special_topic_detail/special_topics_detail_logic.dart +++ b/lib/hj_page/home/special_topic_detail/special_topics_detail_logic.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import '../home_cell_style/home_section_cell.dart'; @@ -40,7 +40,8 @@ class SpecialTopicsLogic extends ListBaseLogic { final List _adsList = []; // ========== Controllers ========== - late final TabController tabCtr = TabController(length: _sortTabs.length, vsync: this); + late final TabController tabCtr = + TabController(length: _sortTabs.length, vsync: this); // ========== 派生 getter ========== String get title => originModel?.sectionName ?? ''; @@ -74,7 +75,8 @@ class SpecialTopicsLogic extends ListBaseLogic { // ========== 公开方法 ========== /// [isRefresh] 刷新(回第 1 页并清空)/ 加载更多;[showLoading] 切排序时先转圈 /// 广告要等基类把新页并入 dataList 后再按全量列表重排,所以 await 完再插 - Future loadData({bool isRefresh = true, bool showLoading = false}) async { + Future loadData( + {bool isRefresh = true, bool showLoading = false}) async { if (showLoading) { dataList = null; // 置空即 isLoading update(); diff --git a/lib/hj_page/home/special_topic_detail/special_topics_detail_page.dart b/lib/hj_page/home/special_topic_detail/special_topics_detail_page.dart index ba0820b..54812b6 100644 --- a/lib/hj_page/home/special_topic_detail/special_topics_detail_page.dart +++ b/lib/hj_page/home/special_topic_detail/special_topics_detail_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../../hj_model/home/module_detail_model.dart'; import '../home_cell_style/video_simple_cell.dart'; @@ -56,7 +56,8 @@ class SpecialTopicsDetailPage extends StatelessWidget { logic.loadData(showLoading: true); }, tabs: [ - for (var i = 0; i < titles.length; i++) _sortTab(titles[i], isLast: i == titles.length - 1), + for (var i = 0; i < titles.length; i++) + _sortTab(titles[i], isLast: i == titles.length - 1), ], ), ); diff --git a/lib/hj_page/home/tag/cartoon_tag_logic.dart b/lib/hj_page/home/tag/cartoon_tag_logic.dart index feba308..8427d01 100644 --- a/lib/hj_page/home/tag/cartoon_tag_logic.dart +++ b/lib/hj_page/home/tag/cartoon_tag_logic.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/const.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_model/cartoon_media_info.dart'; @@ -29,7 +29,8 @@ class CartoonTagLogic extends GetxController { RefreshController? refreshController; List dataSource = []; int sortIndex = 0; - List> get _sortTabs => isSection ? _sectionSortTabs : _normalSortTabs; + List> get _sortTabs => + isSection ? _sectionSortTabs : _normalSortTabs; List get sorts => _sortTabs.map((e) => e.name).toList(); @override @@ -46,12 +47,15 @@ class CartoonTagLogic extends GetxController { isLoading = true; update(); } - final res = await ACGService.getMoreCartoon(page, 12, _sortTabs[sortIndex].sort, sId ?? ''); + final res = await ACGService.getMoreCartoon( + page, 12, _sortTabs[sortIndex].sort, sId ?? ''); if (isRefresh) { refreshController?.refreshCompleted(); dataSource.clear(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; diff --git a/lib/hj_page/home/tag/cartoon_tag_page.dart b/lib/hj_page/home/tag/cartoon_tag_page.dart index 2818d80..0994725 100644 --- a/lib/hj_page/home/tag/cartoon_tag_page.dart +++ b/lib/hj_page/home/tag/cartoon_tag_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../cartoon/acg_widget_item.dart'; import '../home_cell_style/divider_tab_bar.dart'; @@ -65,7 +65,8 @@ class _CartoonTagPageState extends State with UniqueTagMixin { ), itemCount: controller.dataSource.length, itemBuilder: (BuildContext context, int index) { - return AcgItemWidget(info: controller.dataSource[index]); + return AcgItemWidget( + info: controller.dataSource[index]); }, ); }(), diff --git a/lib/hj_page/home/tag/video_tag_logic.dart b/lib/hj_page/home/tag/video_tag_logic.dart index d78d95f..34d45e6 100644 --- a/lib/hj_page/home/tag/video_tag_logic.dart +++ b/lib/hj_page/home/tag/video_tag_logic.dart @@ -1,7 +1,7 @@ -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/tag_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/tag_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; //视频标签页排序 tab(标题与接口 sortType 绑定) const _sortTabs = [ diff --git a/lib/hj_page/home/tag/video_tag_page.dart b/lib/hj_page/home/tag/video_tag_page.dart index ffb0a35..82f9540 100644 --- a/lib/hj_page/home/tag/video_tag_page.dart +++ b/lib/hj_page/home/tag/video_tag_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../../routers/jump_router.dart'; import '../../../tools_base/global_store/store.dart'; @@ -68,14 +68,16 @@ class _VideoTagPageState extends State with UniqueTagMixin { crossAxisSpacing: 6, mainAxisSpacing: 12, crossAxisCount: 2, - childAspectRatio: widget.isShortStyle ? 168 / 266 : 168 / 136, + childAspectRatio: + widget.isShortStyle ? 168 / 266 : 168 / 136, ), itemCount: list.length, itemBuilder: (BuildContext context, int index) { VideoModel model = list[index]; return VideoSimpleCell( videoModel: model, - textLines: (widget.isShortStyle || widget.isHYStyle) ? 1 : 2, + textLines: + (widget.isShortStyle || widget.isHYStyle) ? 1 : 2, isFromHY: widget.isHYStyle, isFromSearch: widget.isFromSearch, isShort: widget.isShortStyle, @@ -83,7 +85,10 @@ class _VideoTagPageState extends State with UniqueTagMixin { if (model.isDarkTag && !globalStore.isAWVIP) { pushToWalletPage(vipId: Config.darkWebVipId); } else { - pushToVideoPage(videoModel: model, videoArr: list, isShort: widget.isShortStyle); + pushToVideoPage( + videoModel: model, + videoArr: list, + isShort: widget.isShortStyle); } }, ); diff --git a/lib/hj_page/home/widget/collect_status_wrapper.dart b/lib/hj_page/home/widget/collect_status_wrapper.dart index 6fac399..fba36a7 100644 --- a/lib/hj_page/home/widget/collect_status_wrapper.dart +++ b/lib/hj_page/home/widget/collect_status_wrapper.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'dart:math'; import 'package:flutter/cupertino.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; import '../../../hj_model/acg/cartoon_more_list.dart'; import '../../../hj_model/cartoon_media_info.dart'; @@ -60,7 +60,10 @@ class _CollectStatusWrapperState extends State { } void _listenCallback(CollectStatusModel model) { - String? obId = widget.allMediaInfo?.id ?? widget.mediaInfo?.id ?? widget.videoModel?.id ?? widget.tagModel?.id; + String? obId = widget.allMediaInfo?.id ?? + widget.mediaInfo?.id ?? + widget.videoModel?.id ?? + widget.tagModel?.id; //收藏和点赞逻辑 if (obId == model.id && obId?.isNotEmpty == true) { if (model.isCollected != null) { @@ -77,7 +80,8 @@ class _CollectStatusWrapperState extends State { } else {} } // 用户关注逻辑 - if (model.isFollowed != null && model.uid == widget.videoModel?.publisher?.uid) { + if (model.isFollowed != null && + model.uid == widget.videoModel?.publisher?.uid) { widget.videoModel?.publisher?.hasFollowed = model.isFollowed; setState(() {}); } diff --git a/lib/hj_page/home/widget/home_txt_marquee.dart b/lib/hj_page/home/widget/home_txt_marquee.dart index d77d28f..94b9c8a 100644 --- a/lib/hj_page/home/widget/home_txt_marquee.dart +++ b/lib/hj_page/home/widget/home_txt_marquee.dart @@ -5,10 +5,10 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_utils/api_service/vid_service.dart'; import '../../../routers/jump_router.dart'; @@ -44,7 +44,8 @@ class HomeTxtMarQuee extends StatefulWidget { } } -class HomeTxtMarQueeState extends State with SingleTickerProviderStateMixin { +class HomeTxtMarQueeState extends State + with SingleTickerProviderStateMixin { List? marquees; bool isShow = true; @@ -100,14 +101,16 @@ class HomeTxtMarQueeState extends State with SingleTickerProvide height: widget.height ?? 36, alignment: Alignment.centerLeft, margin: widget.margin, - padding: widget.padding ?? EdgeInsets.only(left: 14, right: 14, top: 8, bottom: 8), + padding: widget.padding ?? + EdgeInsets.only(left: 14, right: 14, top: 8, bottom: 8), decoration: BoxDecoration( color: Color(0xCC000000), borderRadius: BorderRadius.circular(widget.borderRadius), ), child: Row( children: [ - Image.asset("icon_broadcast.png".commonImgPath, width: widget.iconSize ?? 20), + Image.asset("icon_broadcast.png".commonImgPath, + width: widget.iconSize ?? 20), 6.sizeBoxW, Expanded( child: InfiniteMarquee( @@ -122,7 +125,10 @@ class HomeTxtMarQueeState extends State with SingleTickerProvide }, child: Text( model.content ?? '', - style: TextStyle(color: Color(0xE5FFFFFF), fontSize: widget.fontSize ?? 12, height: 1.4), + style: TextStyle( + color: Color(0xE5FFFFFF), + fontSize: widget.fontSize ?? 12, + height: 1.4), ), ); }, @@ -149,7 +155,8 @@ class InfiniteMarquee extends StatefulWidget { /// 自定义内容 final IndexedWidgetBuilder itemBuilder; - InfiniteMarquee({super.key, + InfiniteMarquee({ + super.key, this.stepOffset = 0.5, required this.itemBuilder, }); @@ -212,7 +219,8 @@ class _InfiniteMarqueeState extends State { controller: _controller, itemBuilder: widget.itemBuilder, physics: NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, int index) => SizedBox(width: Get.width - 100), + separatorBuilder: (BuildContext context, int index) => + SizedBox(width: Get.width - 100), anchor: 0, ); } @@ -239,7 +247,7 @@ class InfiniteListView extends StatefulWidget { this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, this.restorationId, this.clipBehavior = Clip.hardEdge, - }) : separatorBuilder = null; + }) : separatorBuilder = null; /// See [ListView.separated] const InfiniteListView.separated({ @@ -261,7 +269,7 @@ class InfiniteListView extends StatefulWidget { this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, this.restorationId, this.clipBehavior = Clip.hardEdge, - }) : itemExtent = null; + }) : itemExtent = null; /// See: [ScrollView.scrollDirection] final Axis scrollDirection; @@ -324,7 +332,8 @@ class InfiniteListView extends StatefulWidget { class _InfiniteListViewState extends State { InfiniteScrollController? _controller; - InfiniteScrollController get _effectiveController => widget.controller ?? _controller!; + InfiniteScrollController get _effectiveController => + widget.controller ?? _controller!; @override void initState() { @@ -356,7 +365,8 @@ class _InfiniteListViewState extends State { final List slivers = _buildSlivers(context, negative: false); final List negativeSlivers = _buildSlivers(context, negative: true); final AxisDirection axisDirection = _getDirection(context); - final scrollPhysics = widget.physics ?? const AlwaysScrollableScrollPhysics(); + final scrollPhysics = + widget.physics ?? const AlwaysScrollableScrollPhysics(); return Scrollable( axisDirection: axisDirection, controller: _effectiveController, @@ -403,7 +413,8 @@ class _InfiniteListViewState extends State { } AxisDirection _getDirection(BuildContext context) { - return getAxisDirectionFromAxisReverseAndDirectionality(context, widget.scrollDirection, widget.reverse); + return getAxisDirectionFromAxisReverseAndDirectionality( + context, widget.scrollDirection, widget.reverse); } List _buildSlivers(BuildContext context, {bool negative = false}) { @@ -411,14 +422,20 @@ class _InfiniteListViewState extends State { final padding = widget.padding ?? EdgeInsets.zero; return [ SliverPadding( - padding: negative ? padding - EdgeInsets.only(bottom: padding.bottom) : padding - EdgeInsets.only(top: padding.top), + padding: negative + ? padding - EdgeInsets.only(bottom: padding.bottom) + : padding - EdgeInsets.only(top: padding.top), sliver: (itemExtent != null) ? SliverFixedExtentList( - delegate: negative ? negativeChildrenDelegate : positiveChildrenDelegate, + delegate: negative + ? negativeChildrenDelegate + : positiveChildrenDelegate, itemExtent: itemExtent, ) : SliverList( - delegate: negative ? negativeChildrenDelegate : positiveChildrenDelegate, + delegate: negative + ? negativeChildrenDelegate + : positiveChildrenDelegate, ), ) ]; @@ -430,7 +447,9 @@ class _InfiniteListViewState extends State { final separatorBuilder = widget.separatorBuilder; if (separatorBuilder != null) { final itemIndex = (-1 - index) ~/ 2; - return index.isOdd ? widget.itemBuilder(context, itemIndex) : separatorBuilder(context, itemIndex); + return index.isOdd + ? widget.itemBuilder(context, itemIndex) + : separatorBuilder(context, itemIndex); } else { return widget.itemBuilder(context, -1 - index); } @@ -448,10 +467,14 @@ class _InfiniteListViewState extends State { (separatorBuilder != null) ? (BuildContext context, int index) { final itemIndex = index ~/ 2; - return index.isEven ? widget.itemBuilder(context, itemIndex) : separatorBuilder(context, itemIndex); + return index.isEven + ? widget.itemBuilder(context, itemIndex) + : separatorBuilder(context, itemIndex); } : widget.itemBuilder, - childCount: separatorBuilder == null ? itemCount : (itemCount != null ? max(0, itemCount * 2 - 1) : null), + childCount: separatorBuilder == null + ? itemCount + : (itemCount != null ? max(0, itemCount * 2 - 1) : null), addAutomaticKeepAlives: widget.addAutomaticKeepAlives, addRepaintBoundaries: widget.addRepaintBoundaries, ); @@ -460,13 +483,22 @@ class _InfiniteListViewState extends State { @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); - properties.add(EnumProperty('scrollDirection', widget.scrollDirection)); - properties.add(FlagProperty('reverse', value: widget.reverse, ifTrue: 'reversed', showName: true)); - properties.add(DiagnosticsProperty('controller', widget.controller, showName: false, defaultValue: null)); - properties.add(DiagnosticsProperty('physics', widget.physics, showName: false, defaultValue: null)); - properties.add(DiagnosticsProperty('padding', widget.padding, defaultValue: null)); - properties.add(DoubleProperty('itemExtent', widget.itemExtent, defaultValue: null)); - properties.add(DoubleProperty('cacheExtent', widget.cacheExtent, defaultValue: null)); + properties + .add(EnumProperty('scrollDirection', widget.scrollDirection)); + properties.add(FlagProperty('reverse', + value: widget.reverse, ifTrue: 'reversed', showName: true)); + properties.add(DiagnosticsProperty( + 'controller', widget.controller, + showName: false, defaultValue: null)); + properties.add(DiagnosticsProperty('physics', widget.physics, + showName: false, defaultValue: null)); + properties.add(DiagnosticsProperty( + 'padding', widget.padding, + defaultValue: null)); + properties.add( + DoubleProperty('itemExtent', widget.itemExtent, defaultValue: null)); + properties.add( + DoubleProperty('cacheExtent', widget.cacheExtent, defaultValue: null)); } } @@ -480,7 +512,8 @@ class InfiniteScrollController extends ScrollController { }); @override - ScrollPosition createScrollPosition(ScrollPhysics physics, ScrollContext context, ScrollPosition? oldPosition) { + ScrollPosition createScrollPosition(ScrollPhysics physics, + ScrollContext context, ScrollPosition? oldPosition) { return _InfiniteScrollPosition( physics: physics, context: context, diff --git a/lib/hj_page/home/widget/publist_entry_alert.dart b/lib/hj_page/home/widget/publist_entry_alert.dart index 5d3fd0c..bd7de66 100644 --- a/lib/hj_page/home/widget/publist_entry_alert.dart +++ b/lib/hj_page/home/widget/publist_entry_alert.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; // sizeBoxH/sizeBoxW 扩展 -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; // sizeBoxH/sizeBoxW 扩展 +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../community/publish_page/publish_page.dart'; @@ -27,7 +27,8 @@ class PublishButton extends StatelessWidget { @override Widget build(BuildContext context) { return GestureDetector( - onTap: () => Get.bottomSheet(CommunityPublishBottomSheet(), isScrollControlled: true, isDismissible: true), + onTap: () => Get.bottomSheet(CommunityPublishBottomSheet(), + isScrollControlled: true, isDismissible: true), child: Image.asset( entry.realPath(), width: entry.width.w, @@ -44,8 +45,14 @@ class CommunityPublishBottomSheet extends StatelessWidget { Widget build(BuildContext context) { return Container( // 底部加系统安全区,避免手势导航条遮住按钮(如 vivo iQOO 13) - padding: EdgeInsets.only(left: 18.w, right: 18.w, top: 18, bottom: 18 + Get.mediaQuery.padding.bottom), - decoration: BoxDecoration(color: AppColors.primaryColor, borderRadius: BorderRadius.vertical(top: Radius.circular(13))), + padding: EdgeInsets.only( + left: 18.w, + right: 18.w, + top: 18, + bottom: 18 + Get.mediaQuery.padding.bottom), + decoration: BoxDecoration( + color: AppColors.primaryColor, + borderRadius: BorderRadius.vertical(top: Radius.circular(13))), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -53,7 +60,10 @@ class CommunityPublishBottomSheet extends StatelessWidget { 18.sizeBoxH, Text( '选择发布类型', - style: TextStyle(color: Colors.white, fontSize: 20.sp, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 20.sp, + fontWeight: FontWeight.w500), ), 18.h.sizeBoxH, Row( @@ -63,7 +73,8 @@ class CommunityPublishBottomSheet extends StatelessWidget { 40.sizeBoxW, _publishItem('publish_video.webp', '视频', PublishType.homeVideo), 40.sizeBoxW, - _publishItem('publish_img_text.webp', '图文', PublishType.homeImgText), + _publishItem( + 'publish_img_text.webp', '图文', PublishType.homeImgText), ], ), ], @@ -83,7 +94,9 @@ class CommunityPublishBottomSheet extends StatelessWidget { children: [ Image.asset(img.communityPath, width: 45.w, height: 45.w), 4.sizeBoxH, - Text(label, style: TextStyle(color: const Color(0xffa3a2a2), fontSize: 18.sp)), + Text(label, + style: + TextStyle(color: const Color(0xffa3a2a2), fontSize: 18.sp)), ], ), ); diff --git a/lib/hj_page/home/widget/quick_search_view.dart b/lib/hj_page/home/widget/quick_search_view.dart index 37534d0..c69925c 100644 --- a/lib/hj_page/home/widget/quick_search_view.dart +++ b/lib/hj_page/home/widget/quick_search_view.dart @@ -2,9 +2,9 @@ import 'dart:math'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/comment/comment_list_res.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/comment/comment_list_res.dart'; +import 'package:wydj/routers/jump_router.dart'; class QuickSearchView extends StatefulWidget { final List dataSource; diff --git a/lib/hj_page/home/widget/support_up_alert.dart b/lib/hj_page/home/widget/support_up_alert.dart index c866c76..0ed057e 100644 --- a/lib/hj_page/home/widget/support_up_alert.dart +++ b/lib/hj_page/home/widget/support_up_alert.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import 'package:provider/provider.dart'; import '../../mine/mine_vip/mine_charge_coin_page.dart'; @@ -33,7 +33,9 @@ class _SupportUPAlertState extends State { }); selectValue.value = widget.selectCoin; final contain = coins.contains(widget.selectCoin.toString()); - if (!contain) textEidtCtr.text = widget.selectCoin == null ? '' : widget.selectCoin.toString(); + if (!contain) + textEidtCtr.text = + widget.selectCoin == null ? '' : widget.selectCoin.toString(); checkEnable(); } @@ -83,7 +85,10 @@ class _SupportUPAlertState extends State { ), Text( widget.isPublish ? '设置价格' : '为喜欢的UP主加油', - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 20, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 20, + fontWeight: FontWeight.w500), ), 18.sizeBoxH, Container( @@ -96,7 +101,8 @@ class _SupportUPAlertState extends State { return Wrap( spacing: 12, runSpacing: 12, - children: ['10', '20', '30', '40', '50', '60', '70', '80'].map( + children: + ['10', '20', '30', '40', '50', '60', '70', '80'].map( (e) { final gold = int.tryParse(e); return Obx(() { @@ -113,7 +119,9 @@ class _SupportUPAlertState extends State { child: Container( alignment: Alignment.center, decoration: BoxDecoration( - color: (gold != null && select) ? AppColors.actionRed : Color(0x0DFFFFFF), + color: (gold != null && select) + ? AppColors.actionRed + : Color(0x0DFFFFFF), borderRadius: BorderRadius.circular(10), border: (gold != null && select) ? Border.all(color: AppColors.actionRed) @@ -138,10 +146,15 @@ class _SupportUPAlertState extends State { ), gradient: LinearGradient( colors: select - ? [Color(0xffFFE8BE), Color(0xffE6B764)] + ? [ + Color(0xffFFE8BE), + Color(0xffE6B764) + ] : [ - Colors.white.withValues(alpha: .55), - Colors.white.withValues(alpha: .55), + Colors.white + .withValues(alpha: .55), + Colors.white + .withValues(alpha: .55), ], ), ) @@ -163,7 +176,9 @@ class _SupportUPAlertState extends State { Container( margin: EdgeInsets.symmetric(horizontal: 5, vertical: 0), width: 60, - decoration: BoxDecoration(color: Color(0x33FFFFFF), borderRadius: BorderRadius.circular(6)), + decoration: BoxDecoration( + color: Color(0x33FFFFFF), + borderRadius: BorderRadius.circular(6)), child: TextField( controller: textEidtCtr, focusNode: focusN, @@ -174,15 +189,22 @@ class _SupportUPAlertState extends State { }, keyboardType: TextInputType.number, maxLength: 4, - inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9]'))], - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp('[0-9]')) + ], + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500), decoration: InputDecoration( border: InputBorder.none, counterText: '', hintText: '100', isDense: true, contentPadding: EdgeInsets.zero, - hintStyle: TextStyle(color: Colors.white.withValues(alpha: .6), fontSize: 12), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: .6), + fontSize: 12), ), ), ), @@ -197,7 +219,10 @@ class _SupportUPAlertState extends State { if (!widget.isPublish) ...[ Text( '钱包余额:${store.wallet?.amount ?? 0}', - style: TextStyle(color: Colors.white.withValues(alpha: .6), fontSize: 12, height: 14 / 12), + style: TextStyle( + color: Colors.white.withValues(alpha: .6), + fontSize: 12, + height: 14 / 12), ), 16.sizeBoxH, ], @@ -207,7 +232,8 @@ class _SupportUPAlertState extends State { children: [ Expanded( child: GestureDetector( - onTap: () => Get.back(result: selectValue.value), + onTap: () => + Get.back(result: selectValue.value), child: Container( height: 54, alignment: Alignment.center, @@ -217,7 +243,10 @@ class _SupportUPAlertState extends State { ), child: Text( widget.isPublish ? '确定设置' : '立即打赏', - style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.w500), ), ), ), @@ -231,10 +260,15 @@ class _SupportUPAlertState extends State { height: 38, margin: EdgeInsets.symmetric(horizontal: 20), alignment: Alignment.center, - decoration: BoxDecoration(color: AppColors.actionRed, borderRadius: BorderRadius.circular(3)), + decoration: BoxDecoration( + color: AppColors.actionRed, + borderRadius: BorderRadius.circular(3)), child: Text( '余额不足 前往充值', - style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ); diff --git a/lib/hj_page/home/widget/user_avatar.dart b/lib/hj_page/home/widget/user_avatar.dart index fcdcc9e..ae8fed3 100644 --- a/lib/hj_page/home/widget/user_avatar.dart +++ b/lib/hj_page/home/widget/user_avatar.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/user_center_page/user_center_page.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/user_center_page/user_center_page.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; class UserAvatar extends StatelessWidget { final double size; @@ -39,7 +39,8 @@ class UserAvatar extends StatelessWidget { GestureDetector( onTap: onTap ?? () { - Get.to(() => UserCenterPage(uid: model?.uid ?? 0), preventDuplicates: false); + Get.to(() => UserCenterPage(uid: model?.uid ?? 0), + preventDuplicates: false); }, child: NetworkImageLoader( imageUrl: model?.portrait ?? '', diff --git a/lib/hj_page/live/live_detail_logic.dart b/lib/hj_page/live/live_detail_logic.dart index 37cdf7d..f099f98 100644 --- a/lib/hj_page/live/live_detail_logic.dart +++ b/lib/hj_page/live/live_detail_logic.dart @@ -1,17 +1,17 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; import 'dart:async'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/live/live_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/live/live_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:video_player/video_player.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; import '../../alert/video/share_media_dialog.dart'; import '../mine/mine_vip/mine_charge_vip_page.dart'; @@ -39,7 +39,8 @@ class LiveDetailLogic extends GetxController { bool isDispose = false; //判断播放权限 - bool get canWatchLive => DateTimeUtil.isExpireDate(globalStore.meInfo?.broadcastExpire); + bool get canWatchLive => + DateTimeUtil.isExpireDate(globalStore.meInfo?.broadcastExpire); LiveDetailLogic({this.anchor}); @@ -49,13 +50,15 @@ class LiveDetailLogic extends GetxController { void onInit() { super.onInit(); // 耳机/蓝牙断开、来电中断时暂停,防止外放泄露 - _pauseVideoSub = eventBus.on((_) => playerController?.pause()); + _pauseVideoSub = + eventBus.on((_) => playerController?.pause()); } @override void onReady() async { super.onReady(); - Future.wait([globalStore.updateUserInfo(), loadData(initVideo: false)]).then( + Future.wait([globalStore.updateUserInfo(), loadData(initVideo: false)]) + .then( (value) { update(); //接口调用成功刷新一次直播状态 loadingUserInfo = false; @@ -89,7 +92,8 @@ class LiveDetailLogic extends GetxController { try { await playerController?.initialize(); - if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 + if (isRetry) + confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 playerController?.addListener(_listenerCallback); if (isDispose) { playerController?.pause(); @@ -124,7 +128,8 @@ class LiveDetailLogic extends GetxController { //获取直播详情 Future loadData({bool initVideo = true}) async { - LiveAnchor? result = await LiveService.getLiveAnchorDetail(id: anchor?.id ?? ''); + LiveAnchor? result = + await LiveService.getLiveAnchorDetail(id: anchor?.id ?? ''); controller?.refreshCompleted(); if (result != null) { //不需要赋值图片url,因为图片随时在变,防止图片闪动 @@ -139,7 +144,8 @@ class LiveDetailLogic extends GetxController { //直播推荐列表 loadrecommendAnchors({int pageNum = 1}) async { - ListBaseModel? liveMainModels = await LiveService.getLiveAnchorRecom( + ListBaseModel? liveMainModels = + await LiveService.getLiveAnchorRecom( country: anchor?.country ?? '', pageNumber: pageNum, pageSize: 20, @@ -148,13 +154,16 @@ class LiveDetailLogic extends GetxController { if (liveMainModels != null) { currentPage = pageNum; if (currentPage == 1) recommendList.clear(); - if (liveMainModels.list != null && liveMainModels.list?.isNotEmpty == true) { + if (liveMainModels.list != null && + liveMainModels.list?.isNotEmpty == true) { recommendList.addAll(liveMainModels.list ?? []); } } controller?.refreshCompleted(); update(['recommend']); - liveMainModels?.hasNext == true ? controller?.loadComplete() : controller?.loadNoData(); + liveMainModels?.hasNext == true + ? controller?.loadComplete() + : controller?.loadNoData(); } loadMoreData() => loadrecommendAnchors(pageNum: currentPage + 1); @@ -195,6 +204,7 @@ class LiveDetailLogic extends GetxController { onShareAction() { VideoModel videoModel = VideoModel()..cover = anchor?.coverImg; - Get.dialog(ShareMediaDialog(videoModel: videoModel, needDecrypt: false), useSafeArea: false); + Get.dialog(ShareMediaDialog(videoModel: videoModel, needDecrypt: false), + useSafeArea: false); } } diff --git a/lib/hj_page/live/live_detail_page.dart b/lib/hj_page/live/live_detail_page.dart index 6e1f48f..dbe6ca9 100644 --- a/lib/hj_page/live/live_detail_page.dart +++ b/lib/hj_page/live/live_detail_page.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/live/live_item_widget.dart'; -import 'package:hgmj/hj_page/live/live_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/sliver_delegate.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/live/live_item_widget.dart'; +import 'package:wydj/hj_page/live/live_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/sliver_delegate.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:video_player/video_player.dart'; import '../video/video_full_page.dart'; @@ -54,7 +54,9 @@ class _LiveDetailPageState extends State { delegate: MySliverDelegate( forceRefresh: true, maxHeight: Get.width / (logic.aspectRatio ?? 1), - minHeight: logic.isVerticalVideo ? Get.width / (logic.aspectRatio ?? 1) : Get.height / 3 - 60, + minHeight: logic.isVerticalVideo + ? Get.width / (logic.aspectRatio ?? 1) + : Get.height / 3 - 60, child: ClipRRect( //部分机型会超出比例,裁剪掉多余部分 child: Container(color: Colors.black, child: _buildPlayer()), @@ -70,7 +72,10 @@ class _LiveDetailPageState extends State { padding: const EdgeInsets.fromLTRB(16, 18, 16, 12), child: const Text( '精彩推荐', - style: TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w500), ), ), ), @@ -91,7 +96,8 @@ class _LiveDetailPageState extends State { children: [ if (logic.loadingUserInfo) ...[ //1.加载用户直播权益信息 - AspectRatio(aspectRatio: logic.aspectRatio ?? 1, child: _buildCover(logic)), + AspectRatio( + aspectRatio: logic.aspectRatio ?? 1, child: _buildCover(logic)), const LoadingCenterWidget(), ] else if (!logic.canWatchLive) ...[ //2.无权限 @@ -105,7 +111,9 @@ class _LiveDetailPageState extends State { tag: 'player', child: AspectRatio( aspectRatio: logic.aspectRatio ?? 1, - child: logic.initedVideoController ? VideoPlayer(logic.playerController!) : _buildCover(logic), + child: logic.initedVideoController + ? VideoPlayer(logic.playerController!) + : _buildCover(logic), ), ), if (logic.initedVideoController) @@ -113,11 +121,15 @@ class _LiveDetailPageState extends State { right: 12, bottom: 6, child: GestureDetector( - onTap: () => Get.to(() => VideoFullPage(playCtr: logic.playerController!, showMenu: false)), - child: Image.asset("full_icon.png".videoPath, width: 26, height: 26), + onTap: () => Get.to(() => VideoFullPage( + playCtr: logic.playerController!, showMenu: false)), + child: Image.asset("full_icon.png".videoPath, + width: 26, height: 26), ), ), - Obx(() => Offstage(offstage: !logic.isLoading.value, child: const LoadingCenterWidget())), + Obx(() => Offstage( + offstage: !logic.isLoading.value, + child: const LoadingCenterWidget())), ], ], ), @@ -139,10 +151,14 @@ class _LiveDetailPageState extends State { children: [ const Text( '温馨提示', - style: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 14, + color: Colors.white, + fontWeight: FontWeight.w500), ), 12.sizeBoxH, - const Text('开通直播卡全站直播骚货免费观看', style: TextStyle(fontSize: 14, color: Colors.white)), + const Text('开通直播卡全站直播骚货免费观看', + style: TextStyle(fontSize: 14, color: Colors.white)), 18.sizeBoxH, GestureDetector( onTap: logic.onChargeAction, @@ -155,8 +171,11 @@ class _LiveDetailPageState extends State { colors: [Color(0xffffe8be), Color(0xffe5b764)], ), ), - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), - child: const Text('立即开通直播卡', style: TextStyle(fontSize: 14, color: Color(0xFF7b0000))), + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 6), + child: const Text('立即开通直播卡', + style: + TextStyle(fontSize: 14, color: Color(0xFF7b0000))), ), ), ], @@ -178,7 +197,8 @@ class _LiveDetailPageState extends State { Container( color: Colors.black.withValues(alpha: .7), alignment: Alignment.center, - child: const Text('当前主播离线,请前往观看其她热门主播喔~', style: TextStyle(fontSize: 14, color: Colors.white)), + child: const Text('当前主播离线,请前往观看其她热门主播喔~', + style: TextStyle(fontSize: 14, color: Colors.white)), ), ], ), @@ -204,7 +224,8 @@ class _LiveDetailPageState extends State { return const SliverToBoxAdapter(child: LoadingWidget()); } if (logic.recommendList.isEmpty) { - return const SliverToBoxAdapter(child: SizedBox(height: 300, child: CErrorWidget())); + return const SliverToBoxAdapter( + child: SizedBox(height: 300, child: CErrorWidget())); } return SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 16), @@ -238,8 +259,10 @@ class _LiveDetailPageState extends State { onTap: () => Get.back(), child: Container( padding: const EdgeInsets.only(left: 10, right: 2, top: 2, bottom: 2), - decoration: const BoxDecoration(color: Colors.grey, shape: BoxShape.circle), - child: Icon(Icons.arrow_back_ios, color: Colors.black.withValues(alpha: 0.8)), + decoration: + const BoxDecoration(color: Colors.grey, shape: BoxShape.circle), + child: Icon(Icons.arrow_back_ios, + color: Colors.black.withValues(alpha: 0.8)), ), ); } @@ -260,7 +283,8 @@ class _LiveDetailPageState extends State { encrypt: false, ), 4.sizeBoxW, - Text(logic.anchor?.name ?? '', style: const TextStyle(fontSize: 14, color: Colors.white)), + Text(logic.anchor?.name ?? '', + style: const TextStyle(fontSize: 14, color: Colors.white)), ], ), 18.sizeBoxH, @@ -275,9 +299,12 @@ class _LiveDetailPageState extends State { onTap: () => logic.onShareAction(), child: Row( children: [ - Image.asset('live_share.png'.livePath, width: 24, color: Colors.white), + Image.asset('live_share.png'.livePath, + width: 24, color: Colors.white), 2.sizeBoxW, - const Text('分享', style: TextStyle(fontSize: 12, color: Color(0xff999999))), + const Text('分享', + style: + TextStyle(fontSize: 12, color: Color(0xff999999))), ], ), ), diff --git a/lib/hj_page/live/live_item_widget.dart b/lib/hj_page/live/live_item_widget.dart index c954e59..7f475a8 100644 --- a/lib/hj_page/live/live_item_widget.dart +++ b/lib/hj_page/live/live_item_widget.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../hj_utils/widget_utils.dart'; import 'live_detail_page.dart'; @@ -29,7 +29,8 @@ class LiveItemWidget extends StatelessWidget { if (action != null) { action?.call(); } else { - Get.to(() => LiveDetailPage(anchor: anchor), preventDuplicates: false); + Get.to(() => LiveDetailPage(anchor: anchor), + preventDuplicates: false); } }, child: _buildContent(), @@ -50,7 +51,8 @@ class LiveItemWidget extends StatelessWidget { return Stack( children: [ Positioned.fill( - child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false), + child: NetworkImageLoader( + imageUrl: anchor?.coverImg ?? '', encrypt: false), ), Positioned( left: 4, @@ -61,7 +63,10 @@ class LiveItemWidget extends StatelessWidget { textAlign: TextAlign.start, overflow: TextOverflow.ellipsis, maxLines: 1, - style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w400), )), Positioned( top: 0, @@ -84,7 +89,10 @@ class LiveItemWidget extends StatelessWidget { ), child: Text( '王牌主播', - style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.w400), ), )), ], @@ -135,7 +143,8 @@ class LiveItemWidget extends StatelessWidget { ), padding: EdgeInsets.all(2), child: ClipOval( - child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false), + child: NetworkImageLoader( + imageUrl: anchor?.coverImg ?? '', encrypt: false), ), ), )), @@ -158,7 +167,10 @@ class LiveItemWidget extends StatelessWidget { children: [ Text( anchor?.name ?? '', - style: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 14, + color: Colors.white, + fontWeight: FontWeight.w400), maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -178,7 +190,10 @@ class LiveItemWidget extends StatelessWidget { ), child: Text( '霸占TA>', - style: TextStyle(fontSize: 10, color: Color(0xff6A00FF), fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 10, + color: Color(0xff6A00FF), + fontWeight: FontWeight.w400), ), ), ], @@ -195,14 +210,18 @@ class LiveItemWidget extends StatelessWidget { return Stack( children: [ Positioned.fill( - child: NetworkImageLoader(imageUrl: anchor?.coverImg ?? '', encrypt: false), + child: NetworkImageLoader( + imageUrl: anchor?.coverImg ?? '', encrypt: false), ), Positioned( left: 6, bottom: 6, child: Text( anchor?.name ?? '', - style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w400), )), if (index != null && index! < 4) Positioned( @@ -234,7 +253,10 @@ class LiveItemWidget extends StatelessWidget { bottom: 6, child: Text( anchor?.name ?? '', - style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w400), )), ], ); @@ -262,7 +284,10 @@ class LiveItemWidget extends StatelessWidget { bottom: 6, child: Text( anchor?.name ?? '', - style: TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w400), )), Positioned( right: 6, @@ -274,14 +299,19 @@ class LiveItemWidget extends StatelessWidget { height: 8, width: 8, decoration: BoxDecoration( - color: (anchor?.isOnline ?? false) ? Color(0xff0AEBED) : Color(0xff656565), + color: (anchor?.isOnline ?? false) + ? Color(0xff0AEBED) + : Color(0xff656565), borderRadius: BorderRadius.circular(4), ), ), SizedBox(width: 4), Text( (anchor?.isOnline ?? false) ? '直播中' : '离线', - style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.w400), ) ], )), @@ -298,7 +328,10 @@ class LiveItemWidget extends StatelessWidget { ), child: Text( '${anchor?.viewCount?.humanizeFormat() ?? 0}人观众', - style: TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.w400), ), )), ], diff --git a/lib/hj_page/live/live_main_logic.dart b/lib/hj_page/live/live_main_logic.dart index fb2beb8..58282c1 100644 --- a/lib/hj_page/live/live_main_logic.dart +++ b/lib/hj_page/live/live_main_logic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/live/live_service.dart'; +import 'package:wydj/hj_page/live/live_service.dart'; import 'live_model.dart'; @@ -26,7 +26,8 @@ class LiveMainLogic extends GetxController with GetTickerProviderStateMixin { loadData() async { liveMainModel = await LiveService.getLiveModuleList(); if (liveMainModel != null) { - if (liveMainModel?.module != null && liveMainModel?.module?.isNotEmpty == true) { + if (liveMainModel?.module != null && + liveMainModel?.module?.isNotEmpty == true) { liveTabs.clear(); liveTabs.add(LiveModule(id: '-1', title: '推荐')); //添加推荐数据 liveTabs.addAll(liveMainModel?.module ?? []); diff --git a/lib/hj_page/live/live_main_page.dart b/lib/hj_page/live/live_main_page.dart index 13848a2..4544e12 100644 --- a/lib/hj_page/live/live_main_page.dart +++ b/lib/hj_page/live/live_main_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'live_main_logic.dart'; import 'live_sub_page.dart'; @@ -29,7 +29,8 @@ class LiveMainPage extends StatelessWidget { controller: logic.tabController, children: List.generate( logic.liveTabs.length, - (index) => LiveSubPage(tagData: logic.liveTabs[index]).keepAlive, + (index) => + LiveSubPage(tagData: logic.liveTabs[index]).keepAlive, ), ), ), @@ -58,11 +59,13 @@ class LiveMainPage extends StatelessWidget { labelColor: Colors.white.withValues(alpha: .9), labelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), unselectedLabelColor: Colors.white.withValues(alpha: .45), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), indicator: CustomIndicator( height: 2, width: 16, - borderRadius: const BorderRadius.only(topLeft: Radius.circular(1), topRight: Radius.circular(1)), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(1), topRight: Radius.circular(1)), color: AppColors.actionRed, ), ), diff --git a/lib/hj_page/live/live_service.dart b/lib/hj_page/live/live_service.dart index ace399a..db8eee3 100644 --- a/lib/hj_page/live/live_service.dart +++ b/lib/hj_page/live/live_service.dart @@ -1,12 +1,13 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_page/live/live_model.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_page/live/live_model.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; class LiveService { //获取直播模块 static Future getLiveModuleList() async { - int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; + int time = + netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; final param = {'time': time}; final result = await httpManager.fetchResponseByPOST( '/live/module/list/91porn', @@ -22,7 +23,8 @@ class LiveService { int? pageNumber, int? pageSize, }) async { - int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; + int time = + netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; final param = { 'time': time, 'id': id, @@ -39,7 +41,8 @@ class LiveService { //获取直播详情模块 static Future getLiveAnchorDetail({String? id}) async { - int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; + int time = + netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; final param = { 'time': time, 'id': id, @@ -58,7 +61,8 @@ class LiveService { int? pageNumber, int? pageSize, }) async { - int time = netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; + int time = + netManager.getFixedCurTime().toUtc().millisecondsSinceEpoch ~/ 1000; final param = { 'time': time, 'country': country, diff --git a/lib/hj_page/live/live_sub_logic.dart b/lib/hj_page/live/live_sub_logic.dart index ed8d338..0901f87 100644 --- a/lib/hj_page/live/live_sub_logic.dart +++ b/lib/hj_page/live/live_sub_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/live/live_service.dart'; +import 'package:wydj/hj_page/live/live_service.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../mine/mine_vip/mine_charge_vip_page.dart'; @@ -50,7 +50,8 @@ class LiveSubLogic extends GetxController { //tag直播列表 loadCountryAnchor({int pageNum = 1, bool showLoading = false}) async { - ListBaseModel? liveMainModels = await LiveService.getLiveAnchorList( + ListBaseModel? liveMainModels = + await LiveService.getLiveAnchorList( id: tagData?.id ?? '', pageNumber: pageNum, ); @@ -58,12 +59,15 @@ class LiveSubLogic extends GetxController { if (liveMainModels != null) { currentPage = pageNum; if (currentPage == 1) liveList.clear(); - if (liveMainModels.list != null && liveMainModels.list?.isNotEmpty == true) { + if (liveMainModels.list != null && + liveMainModels.list?.isNotEmpty == true) { liveList.addAll(liveMainModels.list ?? []); } } update(); - liveMainModels?.hasNext == true ? controller?.loadComplete() : controller?.loadNoData(); + liveMainModels?.hasNext == true + ? controller?.loadComplete() + : controller?.loadNoData(); controller?.refreshCompleted(); } diff --git a/lib/hj_page/live/live_sub_page.dart b/lib/hj_page/live/live_sub_page.dart index 431163c..e22ee53 100644 --- a/lib/hj_page/live/live_sub_page.dart +++ b/lib/hj_page/live/live_sub_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/live/live_item_widget.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/widget/card_swiper/src/swiper.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/live/live_item_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/widget/card_swiper/src/swiper.dart'; import 'live_model.dart'; import 'live_sub_logic.dart'; @@ -28,7 +28,8 @@ class _LiveSubPageState extends State { Widget build(BuildContext context) { return Container( decoration: BoxDecoration( - image: DecorationImage(image: AssetImage('live_main_bg.webp'.livePath), fit: BoxFit.fill), + image: DecorationImage( + image: AssetImage('live_main_bg.webp'.livePath), fit: BoxFit.fill), ), child: GetBuilder( init: LiveSubLogic(tagData: widget.tagData), @@ -47,7 +48,8 @@ class _LiveSubPageState extends State { Widget _buildContent(LiveSubLogic logic) { //列表样式 if (!logic.isRecom) { - return CustomScrollView(slivers: [_buildAdBanner(), _buildAnchorGrid(logic)]); + return CustomScrollView( + slivers: [_buildAdBanner(), _buildAnchorGrid(logic)]); } //推荐样式 if (logic.liveMainModel?.recom == null) return const LoadingCenterWidget(); @@ -71,10 +73,12 @@ class _LiveSubPageState extends State { //国家/标签主播列表 Widget _buildAnchorGrid(LiveSubLogic logic) { if (logic.loading) { - return const SliverToBoxAdapter(child: SizedBox(height: 200, child: LoadingCenterWidget())); + return const SliverToBoxAdapter( + child: SizedBox(height: 200, child: LoadingCenterWidget())); } if (logic.liveList.isEmpty) { - return SliverToBoxAdapter(child: CErrorWidget(retryOnTap: () => logic.loadData())); + return SliverToBoxAdapter( + child: CErrorWidget(retryOnTap: () => logic.loadData())); } return SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 16), @@ -86,7 +90,8 @@ class _LiveSubPageState extends State { childAspectRatio: 168 / 105, ), delegate: SliverChildBuilderDelegate( - (_, index) => LiveItemWidget(showType: 5, anchor: logic.liveList[index]), + (_, index) => + LiveItemWidget(showType: 5, anchor: logic.liveList[index]), childCount: logic.liveList.length, ), ), @@ -107,13 +112,47 @@ class _LiveSubPageState extends State { Widget _buildRecomSection(LiveRecom recom) { switch (recom.recoShowType) { case 'nine_grid': - return _buildGridSection(recom, bg: 'live_section_bg_1.webp', title: 'nine_grid_bg.webp', titleHeight: 45, crossAxisCount: 3, mainSpacing: 12, crossSpacing: 5, aspectRatio: 1, showType: 0); + return _buildGridSection(recom, + bg: 'live_section_bg_1.webp', + title: 'nine_grid_bg.webp', + titleHeight: 45, + crossAxisCount: 3, + mainSpacing: 12, + crossSpacing: 5, + aspectRatio: 1, + showType: 0); case 'six_round': - return _buildGridSection(recom, bg: 'live_section_bg_2.webp', title: 'six_round_bg.webp', titleHeight: 45, crossAxisCount: 2, mainSpacing: 0, crossSpacing: 6, aspectRatio: 168 / 85, showType: 1, bottomSpace: 10); + return _buildGridSection(recom, + bg: 'live_section_bg_2.webp', + title: 'six_round_bg.webp', + titleHeight: 45, + crossAxisCount: 2, + mainSpacing: 0, + crossSpacing: 6, + aspectRatio: 168 / 85, + showType: 1, + bottomSpace: 10); case 'four_grid': - return _buildGridSectionHor(recom, bg: 'live_section_bg_3.webp', title: 'four_grid_bg.webp', titleHeight: 45, crossAxisCount: 2, mainSpacing: 12, crossSpacing: 7, aspectRatio: 1, showType: 2, bottomSpace: 18); + return _buildGridSectionHor(recom, + bg: 'live_section_bg_3.webp', + title: 'four_grid_bg.webp', + titleHeight: 45, + crossAxisCount: 2, + mainSpacing: 12, + crossSpacing: 7, + aspectRatio: 1, + showType: 2, + bottomSpace: 18); case 'six_grid': - return _buildGridSection(recom, bg: 'live_section_bg_4.webp', title: 'six_grid_bg.webp', titleHeight: 36, crossAxisCount: 3, mainSpacing: 12, crossSpacing: 5, aspectRatio: 1, showType: 3); + return _buildGridSection(recom, + bg: 'live_section_bg_4.webp', + title: 'six_grid_bg.webp', + titleHeight: 36, + crossAxisCount: 3, + mainSpacing: 12, + crossSpacing: 5, + aspectRatio: 1, + showType: 3); case 'horizontal_slide': return _buildHorizontalSlide(recom); case 'list': @@ -128,7 +167,9 @@ class _LiveSubPageState extends State { return Stack( alignment: Alignment.topCenter, children: [ - Column(mainAxisSize: MainAxisSize.min, children: [178.sizeBoxH, section, 10.sizeBoxH]), + Column( + mainAxisSize: MainAxisSize.min, + children: [178.sizeBoxH, section, 10.sizeBoxH]), Positioned( top: 20, child: GestureDetector( @@ -156,7 +197,8 @@ class _LiveSubPageState extends State { final anchors = recom?.anchors; return Container( decoration: BoxDecoration( - image: DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill), + image: + DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill), ), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 34), @@ -177,7 +219,8 @@ class _LiveSubPageState extends State { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), //index 仅 showType==2 用于渲染前三角标,其余样式忽略 - itemBuilder: (_, index) => LiveItemWidget(showType: showType, anchor: anchors?[index], index: index), + itemBuilder: (_, index) => LiveItemWidget( + showType: showType, anchor: anchors?[index], index: index), ), if (bottomSpace > 0) bottomSpace.sizeBoxH, ], @@ -187,21 +230,22 @@ class _LiveSubPageState extends State { //宫格类区块(九宫格/六圆形/四宫格/六宫格 共用)横向排序 Widget _buildGridSectionHor( - LiveRecom? recom, { - required String bg, - required String title, - required double titleHeight, - required int crossAxisCount, - required double mainSpacing, - required double crossSpacing, - required double aspectRatio, - required int showType, - double bottomSpace = 0, - }) { + LiveRecom? recom, { + required String bg, + required String title, + required double titleHeight, + required int crossAxisCount, + required double mainSpacing, + required double crossSpacing, + required double aspectRatio, + required int showType, + double bottomSpace = 0, + }) { final anchors = recom?.anchors; return Container( decoration: BoxDecoration( - image: DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill), + image: + DecorationImage(image: AssetImage(bg.livePath), fit: BoxFit.fill), ), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 34), @@ -210,7 +254,7 @@ class _LiveSubPageState extends State { final width = c.maxWidth; final itemWidth = (width - 12) / 2; - return Column( + return Column( children: [ 18.sizeBoxH, Image.asset(title.livePath, height: titleHeight), @@ -231,7 +275,10 @@ class _LiveSubPageState extends State { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), //index 仅 showType==2 用于渲染前三角标,其余样式忽略 - itemBuilder: (_, index) => LiveItemWidget(showType: showType, anchor: anchors?[index], index: index), + itemBuilder: (_, index) => LiveItemWidget( + showType: showType, + anchor: anchors?[index], + index: index), ), ), if (bottomSpace > 0) bottomSpace.sizeBoxH, @@ -274,7 +321,8 @@ class _LiveSubPageState extends State { viewportFraction: 0.8, scale: 0.93, itemCount: anchors?.length ?? 0, - itemBuilder: (c, index) => LiveItemWidget(showType: 4, anchor: anchors?[index]), + itemBuilder: (c, index) => + LiveItemWidget(showType: 4, anchor: anchors?[index]), ), ), ], @@ -297,7 +345,8 @@ class _LiveSubPageState extends State { itemCount: anchors?.length ?? 0, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (_, index) => LiveItemWidget(showType: 5, anchor: anchors?[index]), + itemBuilder: (_, index) => + LiveItemWidget(showType: 5, anchor: anchors?[index]), ), ); } diff --git a/lib/hj_page/main_page/drama_tip_bubble.dart b/lib/hj_page/main_page/drama_tip_bubble.dart index 3e3f7cc..4a15837 100644 --- a/lib/hj_page/main_page/drama_tip_bubble.dart +++ b/lib/hj_page/main_page/drama_tip_bubble.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; import 'main_logic.dart'; @@ -40,9 +40,11 @@ class DramaTipBubble extends StatefulWidget { State createState() => _DramaTipBubbleState(); } -class _DramaTipBubbleState extends State with SingleTickerProviderStateMixin { +class _DramaTipBubbleState extends State + with SingleTickerProviderStateMixin { //上下轻跳:0→1 映射成向上 0→4,来回循环 - late final _ani = AnimationController(vsync: this, duration: const Duration(milliseconds: 600)); + late final _ani = AnimationController( + vsync: this, duration: const Duration(milliseconds: 600)); @override void initState() { @@ -83,7 +85,8 @@ class _DramaTipBubbleState extends State with SingleTickerProvid offset: Offset(0, -4 * Curves.easeInOut.transform(_ani.value)), child: child, ), - child: Image.asset('drama_tip.webp'.homePath, width: 50, height: 50), + child: + Image.asset('drama_tip.webp'.homePath, width: 50, height: 50), ), ), ], diff --git a/lib/hj_page/main_page/main_logic.dart b/lib/hj_page/main_page/main_logic.dart index 18b9077..cec9039 100644 --- a/lib/hj_page/main_page/main_logic.dart +++ b/lib/hj_page/main_page/main_logic.dart @@ -1,13 +1,13 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/free_play_manager.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/free_play_manager.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../tools_base/event_bus/event_bus_util.dart'; import '../../tools_base/event_bus/events.dart'; @@ -66,7 +66,9 @@ class MainPageLogic extends GetxController { ), if (Config.darkWebEnable) MainTabModel( - title: Config.darkWebIconName?.isNotEmpty == true ? Config.darkWebIconName! : '暗网', + title: Config.darkWebIconName?.isNotEmpty == true + ? Config.darkWebIconName! + : '暗网', imageNor: 'home_2_0.png'.homePath, imageSel: 'home_2_1.png'.homePath, ), @@ -125,7 +127,8 @@ class MainPageLogic extends GetxController { final app = Config.plateModule; if (app == null) return; void put(List modules, int tab, int sub) { - modules.asMap().forEach((i, e) => moduleMap[e.id ?? ''] = ModuleModel(tab: tab, sub: sub, module: i)); + modules.asMap().forEach((i, e) => + moduleMap[e.id ?? ''] = ModuleModel(tab: tab, sub: sub, module: i)); } put(app.homePage, 0, 0); @@ -142,7 +145,8 @@ class MainPageLogic extends GetxController { _backToRoot(); jumpToPage(0); globalStore.refreshWallet(); - MineMsgProvider().loadData(); //内含 refreshPayPopup:重拉支付分层配置,即时刷新浮窗/我的横幅/播放器横幅 + MineMsgProvider() + .loadData(); //内含 refreshPayPopup:重拉支付分层配置,即时刷新浮窗/我的横幅/播放器横幅 unawaited(FreePlayManager().refresh()); //切号:免费观看次数是账户维度的,不重拉会一直用着上个账号的次数 HomeUpdateMarkerProvider().loadData(); presaleProvider.refreshStatus(); //刷新预售权益 @@ -172,7 +176,9 @@ class MainPageLogic extends GetxController { //首页/暗网共用 HomeMainLogic,靠 tag 区分;页面还没建时返回 null HomeMainLogic? _homeLogic([String tag = 'HomeMainLogic']) => - Get.isRegistered(tag: tag) ? Get.find(tag: tag) : null; + Get.isRegistered(tag: tag) + ? Get.find(tag: tag) + : null; void _openNavBar() { _backToRoot(); @@ -226,9 +232,15 @@ class MainPageLogic extends GetxController { return; } } else { - final tag = ["", MediaStyle.Pic.name, MediaStyle.Game.name, MediaStyle.Novel.name][module.sub]; + final tag = [ + "", + MediaStyle.Pic.name, + MediaStyle.Game.name, + MediaStyle.Novel.name + ][module.sub]; if (Get.isRegistered(tag: tag)) { - Get.find(tag: tag).skipToTabIndex(module.module); + Get.find(tag: tag) + .skipToTabIndex(module.module); return; } } @@ -238,7 +250,8 @@ class MainPageLogic extends GetxController { } //返回首页 - void _backToRoot() => Get.until((route) => route.settings.name == MainPage.routeName); + void _backToRoot() => + Get.until((route) => route.settings.name == MainPage.routeName); /// 切 tab:内容页和底栏选中态都监听 curPageIndex,改它一处即可 void jumpToPage(int index) { @@ -250,7 +263,8 @@ class MainPageLogic extends GetxController { bool confirmExit() { final now = DateTime.now(); // 物理键,两次间隔大于 2 秒,退出请求无效 - if (_lastBackAt == null || now.difference(_lastBackAt!) > const Duration(seconds: 2)) { + if (_lastBackAt == null || + now.difference(_lastBackAt!) > const Duration(seconds: 2)) { _lastBackAt = now; showToast('再次返回即可退出'); return false; diff --git a/lib/hj_page/main_page/main_page.dart b/lib/hj_page/main_page/main_page.dart index 0ab913d..aced3e1 100644 --- a/lib/hj_page/main_page/main_page.dart +++ b/lib/hj_page/main_page/main_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/short_video/short_main_video_page.dart'; -import 'package:hgmj/tools_base/widget/lazy_indexed_stack.dart'; +import 'package:wydj/hj_page/short_video/short_main_video_page.dart'; +import 'package:wydj/tools_base/widget/lazy_indexed_stack.dart'; import '../../alert/vip_guide/guide_push_banner.dart'; import '../../config/config.dart'; @@ -77,7 +77,8 @@ class _MainPageState extends State with RouteAware { children: [ _buildPages(), //引导气泡贴着底栏上沿,尾巴指短剧 tab - const Positioned(left: 0, right: 0, bottom: 0, child: DramaTipBubble()), + const Positioned( + left: 0, right: 0, bottom: 0, child: DramaTipBubble()), ], ), ), @@ -105,7 +106,8 @@ class _MainPageState extends State with RouteAware { // 短视频 Obx(() => ShortVideoMainPage(index: logic.shortIndex.value)), // 暗网 - if (Config.darkWebEnable) Obx(() => DarkHomePage(defaultId: logic.darkInitTabId.value)), + if (Config.darkWebEnable) + Obx(() => DarkHomePage(defaultId: logic.darkInitTabId.value)), // AI const AiHomePage(), // 社区 diff --git a/lib/hj_page/main_page/main_tabbar.dart b/lib/hj_page/main_page/main_tabbar.dart index c85052c..80fd4ed 100644 --- a/lib/hj_page/main_page/main_tabbar.dart +++ b/lib/hj_page/main_page/main_tabbar.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/main_page/provider/bottom_bar_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/main_page/provider/bottom_bar_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../config/config.dart'; @@ -50,13 +50,17 @@ class MainPageTabbar extends StatelessWidget { padding: EdgeInsets.fromLTRB(12, 0, 12, screen.paddingBottom), decoration: BoxDecoration( color: Colors.black, - border: Border(top: BorderSide(color: Colors.black.withValues(alpha: 0.02))), + border: Border( + top: BorderSide(color: Colors.black.withValues(alpha: 0.02))), ), child: Row( children: List.generate(logic.tabs.length, (index) { - if (index == 0) return _scrollTopItem(index, cur); - if (Config.darkWebEnable && index == 2) return _scrollTopItem(index, cur); - if (index == logic.communityTab) return _scrollTopItem(index, cur); + if (index == 0) + return _scrollTopItem(index, cur); + if (Config.darkWebEnable && index == 2) + return _scrollTopItem(index, cur); + if (index == logic.communityTab) + return _scrollTopItem(index, cur); return _normalItem(index, cur); }), ), @@ -69,9 +73,13 @@ class MainPageTabbar extends StatelessWidget { final isSelected = index == cur; return Consumer(builder: (_, provider, __) { final isTop = provider.showTop && isSelected; - final imagePath = isTop ? 'jump_to_top.png'.homePath : _iconPath(index, isSelected); + final imagePath = + isTop ? 'jump_to_top.png'.homePath : _iconPath(index, isSelected); //暗网配置Icon - final isDarkConfigImg = index == 2 && isSelected && Config.darkWebEnable && Config.darkWebIcon?.isNotEmpty == true; + final isDarkConfigImg = index == 2 && + isSelected && + Config.darkWebEnable && + Config.darkWebIcon?.isNotEmpty == true; return Expanded( child: InkWell( enableFeedback: false, @@ -80,7 +88,9 @@ class MainPageTabbar extends StatelessWidget { isSelected: isSelected, text: isTop ? '顶部' : logic.tabs[index].title, icon: isDarkConfigImg - ? NetworkImageLoader(key: const ValueKey('darkIcon'), imageUrl: Config.darkWebIcon) + ? NetworkImageLoader( + key: const ValueKey('darkIcon'), + imageUrl: Config.darkWebIcon) : Image.asset(imagePath, key: ValueKey(imagePath), width: 24), ), ), @@ -105,10 +115,12 @@ class MainPageTabbar extends StatelessWidget { ); } - String _iconPath(int index, bool isSelected) => isSelected ? logic.tabs[index].imageSel : logic.tabs[index].imageNor; + String _iconPath(int index, bool isSelected) => + isSelected ? logic.tabs[index].imageSel : logic.tabs[index].imageNor; /// 图标 + 文案:图标切换(key 变即图片路径变)交叉淡入,文字颜色平滑过渡 - Widget _tabContent({required Widget icon, required bool isSelected, required String text}) { + Widget _tabContent( + {required Widget icon, required bool isSelected, required String text}) { return Container( margin: const EdgeInsets.symmetric(vertical: 8), child: Column( @@ -117,13 +129,16 @@ class MainPageTabbar extends StatelessWidget { Container( height: 24, alignment: Alignment.center, - child: AnimatedSwitcher(duration: const Duration(milliseconds: 180), child: icon), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 180), child: icon), ), 2.sizeBoxH, AnimatedDefaultTextStyle( duration: const Duration(milliseconds: 200), style: TextStyle( - color: isSelected ? const Color(0xffFFC000) : const Color(0x59FFFFFF), + color: isSelected + ? const Color(0xffFFC000) + : const Color(0x59FFFFFF), fontSize: 10, ), child: Text(text), diff --git a/lib/hj_page/main_page/provider/bottom_bar_provider.dart b/lib/hj_page/main_page/provider/bottom_bar_provider.dart index f49b830..a46f2d3 100644 --- a/lib/hj_page/main_page/provider/bottom_bar_provider.dart +++ b/lib/hj_page/main_page/provider/bottom_bar_provider.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/const.dart'; class BaseBottomProvider extends ChangeNotifier { bool showTop = false; //选中的 tab 是否变成「回到顶部」 @@ -9,7 +9,8 @@ class BaseBottomProvider extends ChangeNotifier { ScrollController? _curCtr; /// 绑定第 [index] 个 tab 的滚动控制器,[controller] 不传则复用缓存里的 - void setScrollController(int index, {ScrollController? controller, bool forceToTop = false}) { + void setScrollController(int index, + {ScrollController? controller, bool forceToTop = false}) { controller ??= _ctrCaches[index]; if (controller == null) { _curCtr?.removeListener(_onScroll); //没有可绑的目标,旧监听也一并摘掉 @@ -98,5 +99,6 @@ class CommunityBottomProvider extends BaseBottomProvider { @Deprecated('请使用 scrollCtr / subIndex') @override - void setScrollController(int index, {ScrollController? controller, bool forceToTop = false}) {} + void setScrollController(int index, + {ScrollController? controller, bool forceToTop = false}) {} } diff --git a/lib/hj_page/main_page/provider/msg_provider.dart b/lib/hj_page/main_page/provider/msg_provider.dart index 1d6f667..be53497 100644 --- a/lib/hj_page/main_page/provider/msg_provider.dart +++ b/lib/hj_page/main_page/provider/msg_provider.dart @@ -1,11 +1,11 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/vip_product_manager.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_page/mine/mine_vip/vip_product_manager.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../hj_utils/light_model.dart'; @@ -38,14 +38,17 @@ class MineMsgProvider with ChangeNotifier { /// 支付状态分层配置(分层/卡ID/各展示位图片)——全站唯一数据源,原 Config.paymentStatusPopup 迁来此统一管理 PayTierModel? payTier; - static String get _payPopupShownKey => "PayLayeredPopup_shown_${globalStore.meInfo?.uid}"; // 支付分层首弹是否已弹过 - final ValueNotifier tick = ValueNotifier(0); //分层倒计时秒级 tick,倒计时块用 ValueListenableBuilder 监听它,避免每秒重建整卡/图片 + static String get _payPopupShownKey => + "PayLayeredPopup_shown_${globalStore.meInfo?.uid}"; // 支付分层首弹是否已弹过 + final ValueNotifier tick = ValueNotifier( + 0); //分层倒计时秒级 tick,倒计时块用 ValueListenableBuilder 监听它,避免每秒重建整卡/图片 Timer? _payTimer; //支付分层倒计时(基于 config.lastDiscountTime) int? _lastExpireRefreshAt; //上次"归零刷新"的时间戳(秒),用于 30s 防抖 /// 刷新用户分层弹窗配置(payTier),成功后写回并通知 UI 刷新 Future refreshPayPopup() async { - final model = await CommonService.refreshPayPopup(keys: ['paymentPopup', 'paymentGuide']); + final model = await CommonService.refreshPayPopup( + keys: ['paymentPopup', 'paymentGuide']); // 容错:接口返回空数据时 model 为 null,保留本地状态不替换 if (model != null) { // 分层状态前后不一致 → 用户权益/升级状态已变(VIP 支付是异步的,以分层变化为准),清会员卡缓存下次重开强制重拉 @@ -80,14 +83,17 @@ class MineMsgProvider with ChangeNotifier { } /// 支付分层首弹是否已弹过(不分新人/老人,全局只弹一次) - static Future isPayPopupShown() async => await lightKV.getBool(_payPopupShownKey) ?? false; + static Future isPayPopupShown() async => + await lightKV.getBool(_payPopupShownKey) ?? false; - static Future markPayPopupShown() async => await lightKV.setBool(_payPopupShownKey, true); + static Future markPayPopupShown() async => + await lightKV.setBool(_payPopupShownKey, true); /// 倒计时归零后刷新分层配置(带 30s 防抖,避免后端返回临界时间导致频繁刷新) void _refreshOnExpire() { final nowSec = DateTime.now().millisecondsSinceEpoch ~/ 1000; - if (_lastExpireRefreshAt != null && nowSec - _lastExpireRefreshAt! < 30) return; + if (_lastExpireRefreshAt != null && nowSec - _lastExpireRefreshAt! < 30) + return; _lastExpireRefreshAt = nowSec; refreshPayPopup(); // 成功后内部会按新 lastDiscountTime 重启/不重启计时 } diff --git a/lib/hj_page/mine/collec_history_buy/col_his_buy_page.dart b/lib/hj_page/mine/collec_history_buy/col_his_buy_page.dart index bda0d5f..64a5a22 100644 --- a/lib/hj_page/mine/collec_history_buy/col_his_buy_page.dart +++ b/lib/hj_page/mine/collec_history_buy/col_his_buy_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../hj_utils/widget_util.dart'; import 'col_his_buy_logic.dart'; @@ -29,7 +29,8 @@ class ColHisBuyPage extends StatelessWidget { const ColHisBuyPage(this.type, {super.key}); - static Future? to(PageType type) => Get.to(() => ColHisBuyPage(type), routeName: type.route); + static Future? to(PageType type) => + Get.to(() => ColHisBuyPage(type), routeName: type.route); @override Widget build(BuildContext context) { @@ -48,7 +49,10 @@ class ColHisBuyPage extends StatelessWidget { padding: EdgeInsets.only(right: 16), child: Text( logic.isEdit ? '完成' : '编辑', - style: textStyle(14, logic.isEdit ? Color(0xFFFFC000) : Color(0xff666666), FontWeight.w400), + style: textStyle( + 14, + logic.isEdit ? Color(0xFFFFC000) : Color(0xff666666), + FontWeight.w400), ), ), ), @@ -69,7 +73,8 @@ class ColHisBuyPage extends StatelessWidget { isGradient: true, ), indicatorWeight: 1, - unselectedLabelStyle: TextStyle(color: Color(0xffcccccc), fontSize: 14, height: 1), + unselectedLabelStyle: TextStyle( + color: Color(0xffcccccc), fontSize: 14, height: 1), labelStyle: TextStyle( color: Colors.white, fontSize: 14, @@ -80,7 +85,8 @@ class ColHisBuyPage extends StatelessWidget { tabs: logic.tabs .map( (e) => Padding( - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h), + padding: EdgeInsets.symmetric( + horizontal: 12.w, vertical: 8.h), child: Text(e.title), ), ) @@ -93,7 +99,9 @@ class ColHisBuyPage extends StatelessWidget { child: TabBarView( controller: logic.tabCtr, children: logic.tabs - .map((e) => ColHisBuySubPage(e, pageType: type, isEdit: logic.isEdit).keepAlive) + .map((e) => ColHisBuySubPage(e, + pageType: type, isEdit: logic.isEdit) + .keepAlive) .toList(), ), ) diff --git a/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart b/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart index 79ce456..d629a19 100644 --- a/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart +++ b/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; -import 'package:hgmj/tools_base/cache/history/drama_resume_store.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/history_util.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; +import 'package:wydj/tools_base/cache/history/drama_resume_store.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import '../../cartoon/acg_widget_item.dart'; import '../../community/widget/community_post_widget.dart'; @@ -28,7 +28,8 @@ ColHisBuySubLogic instanceLogic(PageType pageType, LoadDataType loadType) { if (loadType == LoadDataType.drama) return DramaLogic(loadType, pageType); return switch (pageType) { PageType.collect => CollectLogic(loadType), - PageType.buy => loadType.isAcg ? BuyAcgLogic(loadType) : BuyVideoLogic(loadType), + PageType.buy => + loadType.isAcg ? BuyAcgLogic(loadType) : BuyVideoLogic(loadType), PageType.history => HistoryLogic(loadType), PageType.like => LikeLogic(loadType), }; @@ -46,7 +47,8 @@ abstract class ColHisBuySubLogic extends ListBaseLogic { loadData(); } - void loadData({bool isRefresh = true}) => fetchData(isRefresh: isRefresh, fetch: fetch); + void loadData({bool isRefresh = true}) => + fetchData(isRefresh: isRefresh, fetch: fetch); /// 返回 (本页数据, 是否还有下一页),页码由基类算好传进来 Future<(List?, bool)> fetch(int page); @@ -60,14 +62,27 @@ abstract class ColHisBuySubLogic extends ListBaseLogic { Widget itemAt(int index) { final model = dataList![index]; return switch (loadType) { - LoadDataType.video => VideoSimpleCell(videoModel: model, isShowBottom: true,), - LoadDataType.game => VideoSimpleCell(videoModel: model, isFromHY: true, textLines: 1), - LoadDataType.short => - TiktokSimpleCell(videoModel: model, textLines: 1, isShowBottom: true, isShowTime: true), + LoadDataType.video => VideoSimpleCell( + videoModel: model, + isShowBottom: true, + ), + LoadDataType.game => + VideoSimpleCell(videoModel: model, isFromHY: true, textLines: 1), + LoadDataType.short => TiktokSimpleCell( + videoModel: model, + textLines: 1, + isShowBottom: true, + isShowTime: true), LoadDataType.pictures => PicSimpleCell(videoModel: model, textLines: 1), - LoadDataType.post => CommunityPostWidget(videoModel: model, tagsColor: this is LikeLogic ? Color(0xFFFFC000) : null,), + LoadDataType.post => CommunityPostWidget( + videoModel: model, + tagsColor: this is LikeLogic ? Color(0xFFFFC000) : null, + ), LoadDataType.collections => SimpleCollectionsItem(model), - LoadDataType.comics || LoadDataType.cartoon || LoadDataType.novel => AcgItemWidget(info: model), + LoadDataType.comics || + LoadDataType.cartoon || + LoadDataType.novel => + AcgItemWidget(info: model), //短剧卡片右下角挂集数状态,点进去续播 LoadDataType.drama => VideoSimpleCell( videoModel: model, @@ -103,10 +118,15 @@ class DramaLogic extends ColHisBuySubLogic { Future<(List?, bool)> fetch(int page) async { //历史记录只在本地:播放时写进 dramaResume 那张表,按最后观看时间倒序 final list = pageType == PageType.history - ? (await dramaResume.history(page: page, pageSize: _pageSize)).map((e) => e.drama!).toList() + ? (await dramaResume.history(page: page, pageSize: _pageSize)) + .map((e) => e.drama!) + .toList() : (await _api(page))?.list ?? []; //本地和接口都不看 hasNext,满页就当还有 - return (list.map((e) => e.toVideoModel(null)).toList(), list.length >= _pageSize); + return ( + list.map((e) => e.toVideoModel(null)).toList(), + list.length >= _pageSize + ); } Future?> _api(int page) => switch (pageType) { @@ -145,8 +165,10 @@ class HistoryLogic extends ColHisBuySubLogic { @override Future<(List?, bool)> fetch(int page) async { final List list = loadType.isAcg - ? await HistoryUtil.fetch(loadType.historyType, page: page, pageSize: _pageSize) - : await HistoryUtil.fetch(loadType.historyType, page: page, pageSize: _pageSize); + ? await HistoryUtil.fetch(loadType.historyType, + page: page, pageSize: _pageSize) + : await HistoryUtil.fetch(loadType.historyType, + page: page, pageSize: _pageSize); //满页说明还有更多,不满即到底 return (list, list.length >= _pageSize); } @@ -170,7 +192,8 @@ class BuyAcgLogic extends ColHisBuySubLogic { @override Future<(List?, bool)> fetch(int page) async { - final res = await ACGService.fetchAcgBuyData(page, 12, mediaType: loadType.apiType); + final res = await ACGService.fetchAcgBuyData(page, 12, + mediaType: loadType.apiType); return (res?.list, res?.hasNext ?? false); } } @@ -181,7 +204,8 @@ class BuyVideoLogic extends ColHisBuySubLogic { @override Future<(List?, bool)> fetch(int page) async { - final res = await MineService.fetchBuyVideo(newsType: loadType.apiType, page: page, size: 12); + final res = await MineService.fetchBuyVideo( + newsType: loadType.apiType, page: page, size: 12); return (res?.list, res?.hasNext ?? false); } } @@ -192,7 +216,8 @@ class LikeLogic extends ColHisBuySubLogic { @override Future<(List?, bool)> fetch(int page) async { - final res = await MineService.fetchLikes(likeType: loadType.apiType, page: page, size: 12); + final res = await MineService.fetchLikes( + likeType: loadType.apiType, page: page, size: 12); return (res?.list, res?.hasNext ?? false); } @@ -210,8 +235,10 @@ class CollectLogic extends ColHisBuySubLogic { @override Future<(List?, bool)> fetch(int page) async { final ListBaseModel? res = loadType.isAcg - ? await ACGService.fetchAcgBooklib(loadType.apiType, page: page, size: 12) - : await MineService.fetchCollectList(loadType.apiType, page: page, size: 12); + ? await ACGService.fetchAcgBooklib(loadType.apiType, + page: page, size: 12) + : await MineService.fetchCollectList(loadType.apiType, + page: page, size: 12); return (res?.list, res?.hasNext ?? false); } @@ -220,7 +247,8 @@ class CollectLogic extends ColHisBuySubLogic { final model = dataList![index]; final bool isDeleted; if (model is VideoModel) { - isDeleted = await MineService.postCollect(model.id, loadType.apiType, false); + isDeleted = + await MineService.postCollect(model.id, loadType.apiType, false); } else if (model is CartoonMediaInfo) { isDeleted = await ACGService.deleteBookshelf(model.id ?? ''); } else { diff --git a/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_page.dart b/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_page.dart index 0f68771..869298d 100644 --- a/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_page.dart +++ b/lib/hj_page/mine/collec_history_buy/col_his_buy_sub_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/mine/collec_history_buy/col_his_buy_page.dart'; -import 'package:hgmj/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/mine/collec_history_buy/col_his_buy_page.dart'; +import 'package:wydj/hj_page/mine/collec_history_buy/col_his_buy_sub_logic.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; enum LoadDataType { /// 长视频 diff --git a/lib/hj_page/mine/home_mine_logic.dart b/lib/hj_page/mine/home_mine_logic.dart index 1a42070..efb75ee 100644 --- a/lib/hj_page/mine/home_mine_logic.dart +++ b/lib/hj_page/mine/home_mine_logic.dart @@ -2,17 +2,17 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/track_event_manager/device_service.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/track_event_manager/device_service.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../config/config.dart'; import '../../hj_model/user/user_info_model.dart'; @@ -46,12 +46,37 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { /// 常用功能: (标题, 图标, 点击事件) List<(String, String, void Function())> get commonlyUsedFunction => [ - ("意见反馈", 'mine_menu_2.png'.mineImgPath, () => Get.to(() => const MineFeedbackPage())), - ("我的下载", 'mine_follow.png'.mineImgPath, () => Get.to(() => VideoCachePage())), - ("我的关注", 'mine_offical.png'.mineImgPath, () => Get.to(() => MineFollowingPage())), - ("分享邀请", 'mine_menu_5.png'.mineImgPath, () => Get.to(() => MineSharePage())), - ("应用推荐", 'mine_menu_8.png'.mineImgPath, () => Get.to(() => const WelfareHomePage(index: 1), preventDuplicates: false)), - ("账号凭证", 'mine_menu_9.png'.mineImgPath, () => Get.dialog(MineAccountIdentityPage())), + ( + "意见反馈", + 'mine_menu_2.png'.mineImgPath, + () => Get.to(() => const MineFeedbackPage()) + ), + ( + "我的下载", + 'mine_follow.png'.mineImgPath, + () => Get.to(() => VideoCachePage()) + ), + ( + "我的关注", + 'mine_offical.png'.mineImgPath, + () => Get.to(() => MineFollowingPage()) + ), + ( + "分享邀请", + 'mine_menu_5.png'.mineImgPath, + () => Get.to(() => MineSharePage()) + ), + ( + "应用推荐", + 'mine_menu_8.png'.mineImgPath, + () => Get.to(() => const WelfareHomePage(index: 1), + preventDuplicates: false) + ), + ( + "账号凭证", + 'mine_menu_9.png'.mineImgPath, + () => Get.dialog(MineAccountIdentityPage()) + ), ("锁屏密码", 'mine_menu_10.png'.mineImgPath, _toggleLockPassword), ("我的消息", 'mine_menu_11.png'.mineImgPath, () => menuTapEvent(3)), ]; @@ -129,7 +154,8 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { Get.to(() => MineFollowingPage()); } else if (index == 3) { //消息中心 - await Get.to(() => MessageCenterPage(), opaque: true, preventDuplicates: false); + await Get.to(() => MessageCenterPage(), + opaque: true, preventDuplicates: false); MineMsgProvider().getMessageTip(); } } @@ -143,7 +169,8 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { confirmText: '确定关闭', ); if (close) { - Get.toNamed(MinePasswordPage.routeName, arguments: MinePasswordType.close); + Get.toNamed(MinePasswordPage.routeName, + arguments: MinePasswordType.close); } } else { Get.toNamed( @@ -173,7 +200,8 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { showToast("获取商店地址失败~"); return; } - Get.to(H5Page(url: result, showTitle: false, showClose: true), popGesture: true); + Get.to(H5Page(url: result, showTitle: false, showClose: true), + popGesture: true); } changeIcon(int index) async { diff --git a/lib/hj_page/mine/home_mine_page.dart b/lib/hj_page/mine/home_mine_page.dart index 8c679b0..e8747c7 100644 --- a/lib/hj_page/mine/home_mine_page.dart +++ b/lib/hj_page/mine/home_mine_page.dart @@ -3,17 +3,17 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../hj_utils/widget_util.dart'; @@ -127,7 +127,8 @@ class HomeMinePage extends StatelessWidget { childAspectRatio: 1, ), itemBuilder: (context, index) { - final (titleDesc, imagePath, onTap) = logic.commonlyUsedFunction[index]; + final (titleDesc, imagePath, onTap) = + logic.commonlyUsedFunction[index]; // 仅「我的消息」带未读红点,按名称判断避免菜单顺序变动后红点错位 final isMessageEntry = titleDesc == _messageMenuTitle; return InkWell( @@ -145,7 +146,8 @@ class HomeMinePage extends StatelessWidget { width: 28, ), Consumer( - builder: (context, model, child) => Positioned( + builder: (context, model, child) => + Positioned( right: 2, top: 2, child: model.buildTipsView(), @@ -156,7 +158,8 @@ class HomeMinePage extends StatelessWidget { 5.sizeBoxH, Text( titleDesc, - style: TextStyle(color: Colors.white, fontSize: 12), + style: + TextStyle(color: Colors.white, fontSize: 12), ), ], ), @@ -171,14 +174,21 @@ class HomeMinePage extends StatelessWidget { children: [ Text( '设置桌面图标', - style: TextStyle(color: Color(0xffEFEFEF), fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xffEFEFEF), + fontSize: 14, + fontWeight: FontWeight.w500), ), Spacer(), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => logic.changeIcon(0), child: Text( '恢复默认', - style: TextStyle(color: Color(0xff989898), fontSize: 12, fontWeight: FontWeight.w400), + style: TextStyle( + color: Color(0xff989898), + fontSize: 12, + fontWeight: FontWeight.w400), ), ), ], @@ -194,7 +204,8 @@ class HomeMinePage extends StatelessWidget { itemCount: logic.iconList.length, itemBuilder: (BuildContext context, int index) { final data = logic.iconList[index]; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => logic.changeIcon(index), child: Column( children: [ @@ -279,7 +290,8 @@ class HomeMinePage extends StatelessWidget { Expanded( child: Consumer2( builder: (context, store, provider, child) { - int count = (store.wallet?.downloadCount ?? 0) + (provider.remain?.todayDownloadCount ?? 0); + int count = (store.wallet?.downloadCount ?? 0) + + (provider.remain?.todayDownloadCount ?? 0); return _buildCountItem(count.toString(), '剩余缓存次数'); }, ), @@ -293,7 +305,8 @@ class HomeMinePage extends StatelessWidget { child: Consumer2( builder: (context, store, provider, child) { //预售权益和免费次数的和 - final total = (store.wallet?.aiUndressFreeTimes ?? 0) + (provider.remain?.todayAiUndressCount ?? 0); + final total = (store.wallet?.aiUndressFreeTimes ?? 0) + + (provider.remain?.todayAiUndressCount ?? 0); return _buildCountItem(total.toString(), '剩余AI脱衣次数'); }, ), @@ -313,7 +326,8 @@ class HomeMinePage extends StatelessWidget { 4.sizeBoxH, Text( title, - style: textStyle(12, Colors.white.withValues(alpha: .7), FontWeight.w400), + style: textStyle( + 12, Colors.white.withValues(alpha: .7), FontWeight.w400), ), ], ); diff --git a/lib/hj_page/mine/identity/mine_identity_logic.dart b/lib/hj_page/mine/identity/mine_identity_logic.dart index 290b74f..2571a1b 100644 --- a/lib/hj_page/mine/identity/mine_identity_logic.dart +++ b/lib/hj_page/mine/identity/mine_identity_logic.dart @@ -1,8 +1,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../hj_model/user/user_info_model.dart'; diff --git a/lib/hj_page/mine/identity/mine_identity_page.dart b/lib/hj_page/mine/identity/mine_identity_page.dart index 6f74d75..e208e44 100644 --- a/lib/hj_page/mine/identity/mine_identity_page.dart +++ b/lib/hj_page/mine/identity/mine_identity_page.dart @@ -3,13 +3,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/image_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/image_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; @@ -49,7 +49,8 @@ class MineAccountIdentityPage extends StatelessWidget { Positioned.fill( child: ClipRRect( borderRadius: BorderRadius.circular(9), - child: Image.asset('share_bg.webp'.mineImgPath, fit: BoxFit.fill), + child: Image.asset('share_bg.webp'.mineImgPath, + fit: BoxFit.fill), ), ), Column( @@ -62,10 +63,12 @@ class MineAccountIdentityPage extends StatelessWidget { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(50), - border: Border.all(color: Color(0x4DF68804), width: 3), + border: Border.all( + color: Color(0x4DF68804), width: 3), ), child: NetworkImageLoader( - imageUrl: provider.meInfo?.portrait ?? '', + imageUrl: + provider.meInfo?.portrait ?? '', width: 82, height: 82, borderRadius: 50, @@ -92,14 +95,18 @@ class MineAccountIdentityPage extends StatelessWidget { ), ), 30.sizeBoxH, - Text("提示*可通过官方客服找回账号", style: TextStyle(fontSize: 12, color: Color(0xffFFC000))), + Text("提示*可通过官方客服找回账号", + style: TextStyle( + fontSize: 12, + color: Color(0xffFFC000))), 10.sizeBoxH, Center( child: Container( padding: EdgeInsets.all(11.w), decoration: BoxDecoration( image: DecorationImage( - image: AssetImage("code_bg.webp".mineImgPath), + image: AssetImage( + "code_bg.webp".mineImgPath), fit: BoxFit.fill, ), ), @@ -117,7 +124,8 @@ class MineAccountIdentityPage extends StatelessWidget { width: 100, height: 100, child: Center( - child: CupertinoActivityIndicator( + child: + CupertinoActivityIndicator( color: AppColors.actionRed, ), ), @@ -129,7 +137,11 @@ class MineAccountIdentityPage extends StatelessWidget { "APP更新可能会导致会员账号掉线\n请勿删除此凭证,此凭证是您永久有\n效的登陆途径。", textAlign: TextAlign.center, defaultStyle: TextStyle( - color: Colors.white.withValues(alpha: .55), fontSize: 12, fontWeight: FontWeight.w400, height: 1.5), + color: + Colors.white.withValues(alpha: .55), + fontSize: 12, + fontWeight: FontWeight.w400, + height: 1.5), patternList: [ EasyRichTextPattern( targetString: '请勿删除此凭证', @@ -143,11 +155,13 @@ class MineAccountIdentityPage extends StatelessWidget { ), Container( height: 30, - padding: EdgeInsets.symmetric(horizontal: 18, vertical: 3), + padding: EdgeInsets.symmetric( + horizontal: 18, vertical: 3), child: Text( '${Config.appName} 官网地址 ${Address.groundUrl}', style: TextStyle( - color: Colors.white.withValues(alpha: .55), + color: + Colors.white.withValues(alpha: .55), fontSize: 12, fontWeight: FontWeight.w400, ), @@ -165,7 +179,8 @@ class MineAccountIdentityPage extends StatelessWidget { children: [ GestureDetector( onTap: () async { - var success = await ImageUtil.saveWidgetToAlbum(controller.boundaryKey); + var success = await ImageUtil.saveWidgetToAlbum( + controller.boundaryKey); if (success) { showToast("保存成功"); Get.back(); @@ -193,9 +208,11 @@ class MineAccountIdentityPage extends StatelessWidget { ], ), 20.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.back(result: false), - child: Image.asset("close_button.png".commonImgPath, width: 32), + child: Image.asset("close_button.png".commonImgPath, + width: 32), ) ], ), diff --git a/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart b/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart index d18f812..5cd5c0f 100644 --- a/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart +++ b/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'mine_withdrawal_record_page.dart'; @@ -35,14 +35,17 @@ class WithDrawalRecordController extends MineWithdrawalRecordLogic { fetchPageData({bool isRefresh = true}) async { super.fetchPageData(isRefresh: isRefresh); - final result = await MineService.getWithdrawDetails(pageNumber: page, pageSize: 10); + final result = + await MineService.getWithdrawDetails(pageNumber: page, pageSize: 10); isLoading = false; if (isRefresh) { dataSource.clear(); refreshController?.refreshCompleted(); } - result?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + result?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(result?.list ?? []); page += 1; update(); @@ -69,7 +72,9 @@ class GoldBillRecordController extends MineWithdrawalRecordLogic { dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; update(); @@ -86,13 +91,16 @@ class RechargeRecordController extends MineWithdrawalRecordLogic { @override fetchPageData({bool isRefresh = true}) async { super.fetchPageData(isRefresh: isRefresh); - final res = await MineService.getRechargeBill(pageNumber: page, pageSize: 15); + final res = + await MineService.getRechargeBill(pageNumber: page, pageSize: 15); isLoading = false; if (isRefresh) { dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; update(); @@ -112,13 +120,16 @@ class IncomeRecordController extends MineWithdrawalRecordLogic { @override fetchPageData({bool isRefresh = true}) async { super.fetchPageData(isRefresh: isRefresh); - final res = await MineService.getIncomeRecord(pageNumber: page, pageSize: 15); + final res = + await MineService.getIncomeRecord(pageNumber: page, pageSize: 15); isLoading = false; if (isRefresh) { dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; update(); diff --git a/lib/hj_page/mine/make_money/mine_withdrawal_record_page.dart b/lib/hj_page/mine/make_money/mine_withdrawal_record_page.dart index 1b48d4a..e55441a 100644 --- a/lib/hj_page/mine/make_money/mine_withdrawal_record_page.dart +++ b/lib/hj_page/mine/make_money/mine_withdrawal_record_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'mine_withdrawal_record_logic.dart'; @@ -40,16 +40,20 @@ class _RecordsPageState extends State { appBar: AppBar(title: Text(widget.type.title)), body: pullYsRefresh( onRefresh: (refreshController) => controller.fetchPageData(), - onLoading: (refreshController) => controller.fetchPageData(isRefresh: false), + onLoading: (refreshController) => + controller.fetchPageData(isRefresh: false), onInit: (ctr) => controller.refreshController = ctr, child: () { if (controller.isLoading) return LoadingCenterWidget(); - if (controller.dataSource.isEmpty) return CErrorWidget(retryOnTap: () => controller.fetchPageData()); + if (controller.dataSource.isEmpty) + return CErrorWidget( + retryOnTap: () => controller.fetchPageData()); return ListView.builder( itemCount: controller.dataSource.length, padding: EdgeInsets.only(top: 12, left: 16.w, right: 16.w), - itemBuilder: (context, index) => controller.instanceChildItem(index), + itemBuilder: (context, index) => + controller.instanceChildItem(index), ); }(), ), diff --git a/lib/hj_page/mine/make_money/widget/record_list_item.dart b/lib/hj_page/mine/make_money/widget/record_list_item.dart index 8a3cee4..66a989f 100644 --- a/lib/hj_page/mine/make_money/widget/record_list_item.dart +++ b/lib/hj_page/mine/make_money/widget/record_list_item.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/mine/exchange/bill_item_model.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/mine/exchange/bill_item_model.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../withdraw_details_model.dart'; @@ -27,19 +27,28 @@ class GoldRecordItem extends StatelessWidget { 12.sizeBoxH, Text( model.desc ?? '', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), ), 4.sizeBoxH, Text( model.createdAt.utcToYMDHM(), - style: TextStyle(color: Colors.white.withValues(alpha: .5), fontSize: 12, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white.withValues(alpha: .5), + fontSize: 12, + fontWeight: FontWeight.w400), ), 4.sizeBoxH, Text( model.tranType ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Color(0xFFFFC000), fontSize: 14, fontWeight: FontWeight.w400), + style: TextStyle( + color: Color(0xFFFFC000), + fontSize: 14, + fontWeight: FontWeight.w400), ), 12.sizeBoxH, 1.line, @@ -51,12 +60,18 @@ class GoldRecordItem extends StatelessWidget { 12.sizeBoxH, Text( '${model.realCount}${model.unit}', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), ), 4.sizeBoxH, Text( '余额:${model.realAmount}', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), ), ], ) @@ -101,7 +116,10 @@ class RechargeRecordItem extends StatelessWidget { '账单编号' + ': ${model.orderId}', maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 14, color: Color(0xE5FFFFFF), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 14, + color: Color(0xE5FFFFFF), + fontWeight: FontWeight.w500), ), ), 2.sizeBoxW, @@ -178,7 +196,10 @@ class InComeRecordItem extends StatelessWidget { children: [ Text( "${model.tranType}", - style: const TextStyle(color: Color(0xFFEFEFEF), fontWeight: FontWeight.w500, fontSize: 14.0), + style: const TextStyle( + color: Color(0xFFEFEFEF), + fontWeight: FontWeight.w500, + fontSize: 14.0), ), Container( margin: EdgeInsets.symmetric(vertical: 4), @@ -189,15 +210,24 @@ class InComeRecordItem extends StatelessWidget { ), Text( DateTimeUtil.utc2iso(model.createdAt ?? ''), - style: const TextStyle(color: Color(0xFF525252), fontWeight: FontWeight.w400, fontSize: 12.0), + style: const TextStyle( + color: Color(0xFF525252), + fontWeight: FontWeight.w400, + fontSize: 12.0), ), 12.sizeBoxH, ], ), ), 12.sizeBoxW, - Text(model.tranTypeInt == 111 ? "+${model.actualAmount}次" : "+${model.actualAmount}金币", - style: const TextStyle(color: const Color(0xffFFC000), fontWeight: FontWeight.w400, fontSize: 12.0), + Text( + model.tranTypeInt == 111 + ? "+${model.actualAmount}次" + : "+${model.actualAmount}金币", + style: const TextStyle( + color: const Color(0xffFFC000), + fontWeight: FontWeight.w400, + fontSize: 12.0), textAlign: TextAlign.left) ], ), @@ -228,7 +258,10 @@ class _WithdrawalRecordItemState extends State { 12.sizeBoxH, Text( '${(model.money ?? 0) ~/ 100}元', - style: TextStyle(fontSize: 14, color: AppColors.actionRed, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 14, + color: AppColors.actionRed, + fontWeight: FontWeight.w500), ), 6.sizeBoxH, Row( @@ -238,7 +271,10 @@ class _WithdrawalRecordItemState extends State { '账单编号' + ': ${model.id}', maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 14, color: Color(0xE5FFFFFF), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 14, + color: Color(0xE5FFFFFF), + fontWeight: FontWeight.w500), ), ), InkWell( diff --git a/lib/hj_page/mine/make_money/withdrawal_logic.dart b/lib/hj_page/mine/make_money/withdrawal_logic.dart index dd5bbb3..23ac0ee 100644 --- a/lib/hj_page/mine/make_money/withdrawal_logic.dart +++ b/lib/hj_page/mine/make_money/withdrawal_logic.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/user/wallet_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/hj_model/user/wallet_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; import '../../../alert/mine/vip_level_dialog.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../track_event_manager/device_service.dart'; import '../mine_profit/bank_card_home_page.dart'; import '../mine_profit/model/alipay_bank_list_model.dart'; @@ -56,8 +56,11 @@ class WithdrawalLogic extends GetxController with GetTickerProviderStateMixin { void changeWithdrawType(String payType) { // withdrawType = value; - selectChannel = configData?.channels?.firstWhere((element) => element.payType == payType); - withdrawType = configData?.channels?.indexWhere((e) => e.payType == selectChannel?.payType) ?? 0; + selectChannel = configData?.channels + ?.firstWhere((element) => element.payType == payType); + withdrawType = configData?.channels + ?.indexWhere((e) => e.payType == selectChannel?.payType) ?? + 0; update(); } @@ -74,7 +77,8 @@ class WithdrawalLogic extends GetxController with GetTickerProviderStateMixin { actualAmount = withdrawAmoutNum; } else { double value = coinTax / 100.0; - final res = (withdrawAmoutNum * double.parse(value.toStringAsFixed(2))).toStringAsFixed(2); + final res = (withdrawAmoutNum * double.parse(value.toStringAsFixed(2))) + .toStringAsFixed(2); handlingFee = double.parse(res).floor(); actualAmount = withdrawAmoutNum - handlingFee; } @@ -105,14 +109,18 @@ class WithdrawalLogic extends GetxController with GetTickerProviderStateMixin { this.configData = configData; isLoading = false; // 优先银行卡,其次 usdt - selectChannel = configData?.channels?.firstWhereOrNull((element) => element.payType == 'bankcard') ?? - configData?.channels?.firstWhereOrNull((element) => element.payType == 'usdt'); + selectChannel = configData?.channels + ?.firstWhereOrNull((element) => element.payType == 'bankcard') ?? + configData?.channels + ?.firstWhereOrNull((element) => element.payType == 'usdt'); if (selectChannel == null) { showToast('暂无可用提现通道'); this.configData = null; } else { // 必须同步 withdrawType,页面按 channels[withdrawType] 取值,否则会索引错位甚至越界 - withdrawType = configData?.channels?.indexWhere((e) => e.payType == selectChannel?.payType) ?? 0; + withdrawType = configData?.channels + ?.indexWhere((e) => e.payType == selectChannel?.payType) ?? + 0; } update(); } @@ -128,7 +136,8 @@ class WithdrawalLogic extends GetxController with GetTickerProviderStateMixin { if ("bankcard" == selectChannel?.payType) { //检验银行卡信息 _commonWithdrawReq(true); - } else if ("alipay" == selectChannel?.payType || "usdt" == selectChannel?.payType) { + } else if ("alipay" == selectChannel?.payType || + "usdt" == selectChannel?.payType) { _commonWithdrawReq(false); } } catch (e) { diff --git a/lib/hj_page/mine/make_money/withdrawal_page.dart b/lib/hj_page/mine/make_money/withdrawal_page.dart index 85683be..6ab019e 100644 --- a/lib/hj_page/mine/make_money/withdrawal_page.dart +++ b/lib/hj_page/mine/make_money/withdrawal_page.dart @@ -3,11 +3,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/mine/widgets/gradient_text.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/mine/widgets/gradient_text.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; import '../../../assets_tool/app_colors.dart'; @@ -63,14 +63,16 @@ class WithdrawalPage extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, child: Container( margin: EdgeInsets.only(left: 16.w, right: 16.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - margin: EdgeInsets.only(top: 12.w, bottom: 18.w), + margin: + EdgeInsets.only(top: 12.w, bottom: 18.w), padding: EdgeInsets.symmetric(vertical: 12.w), decoration: BoxDecoration( color: Color(0x0DFFFFFF), @@ -106,20 +108,33 @@ class WithdrawalPage extends StatelessWidget { Padding( padding: EdgeInsets.only(left: 20), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, children: [ - Image.asset('coin_icon.webp'.mineImgPath, width: 30), + Image.asset( + 'coin_icon.webp'.mineImgPath, + width: 30), 4.sizeBoxW, - Consumer(builder: (_, store, __) { - logic.userIncomeModel = store.wallet; + Consumer( + builder: (_, store, __) { + logic.userIncomeModel = + store.wallet; return GradientText( - ((store.wallet?.balance ?? 0) * 10 / 100).toStringAsFixed(2), + ((store.wallet?.balance ?? 0) * + 10 / + 100) + .toStringAsFixed(2), gradient: LinearGradient( - colors: [Color(0xffFFE8BE), Color(0xffE6B764)], + colors: [ + Color(0xffFFE8BE), + Color(0xffE6B764) + ], tileMode: TileMode.mirror, ), style: TextStyle( - fontSize: 31.5, fontWeight: FontWeight.w500), //目前fontSize设置为31.5 设置为32,显示不完全,存在系统bug + fontSize: 31.5, + fontWeight: FontWeight + .w500), //目前fontSize设置为31.5 设置为32,显示不完全,存在系统bug ); }), ], @@ -131,12 +146,14 @@ class WithdrawalPage extends StatelessWidget { children: [ Text( '提现币类:', - style: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + style: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), ), 15.sizeBoxW, Text( '人民币', - style: textStyle(14, Color(0x8CFFFFFF), FontWeight.w400), + style: textStyle( + 14, Color(0x8CFFFFFF), FontWeight.w400), ), ], ), @@ -145,34 +162,48 @@ class WithdrawalPage extends StatelessWidget { children: [ Text( "提现金额:", - style: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + style: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), ), 10.sizeBoxW, Expanded( child: Container( alignment: Alignment.centerLeft, height: 40, - padding: EdgeInsets.symmetric(horizontal: 12), + padding: + EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( - color: Colors.white.withValues(alpha: .05), + color: + Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(6), ), child: TextField( inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp("[0-9]")), + FilteringTextInputFormatter.allow( + RegExp("[0-9]")), LengthLimitingTextInputFormatter(9), ], controller: logic.moneyController, - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), - cursorColor: Colors.white.withValues(alpha: 0.7), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), + cursorColor: + Colors.white.withValues(alpha: 0.7), decoration: InputDecoration( border: InputBorder.none, - contentPadding: EdgeInsets.only(bottom: 8), - hintStyle: TextStyle(color: Color(0xFF525252), fontSize: 12, fontWeight: FontWeight.w400), - hintText: '单笔提现金额范围 ${_getPayMoneyRange(logic)}元', //"您目前 + contentPadding: + EdgeInsets.only(bottom: 8), + hintStyle: TextStyle( + color: Color(0xFF525252), + fontSize: 12, + fontWeight: FontWeight.w400), + hintText: + '单笔提现金额范围 ${_getPayMoneyRange(logic)}元', //"您目前 ), focusNode: logic.focusNode, - onChanged: (value) => logic.calcWithdrawAmount(value)), + onChanged: (value) => + logic.calcWithdrawAmount(value)), ), ) ], @@ -182,7 +213,8 @@ class WithdrawalPage extends StatelessWidget { children: [ Text( "提现方式:", - style: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + style: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), ), 16.sizeBoxW, Expanded( @@ -193,7 +225,10 @@ class WithdrawalPage extends StatelessWidget { child: Row( children: logic.configData?.realChannel .asMap() - .map((index, e) => MapEntry(index, _buildPayTypeUI(e, logic, index))) + .map((index, e) => MapEntry( + index, + _buildPayTypeUI( + e, logic, index))) .values .toList() ?? [], @@ -209,27 +244,34 @@ class WithdrawalPage extends StatelessWidget { if (_isUsdt(logic)) ...[ Text( 'USDT地址:', - style: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + style: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), ), 10.sizeBoxW, Expanded( child: Container( decoration: BoxDecoration( - color: Colors.white.withValues(alpha: .05), + color: + Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(6), ), child: TextField( - textAlignVertical: TextAlignVertical.center, + textAlignVertical: + TextAlignVertical.center, controller: logic.accountController, maxLines: 1, decoration: InputDecoration( border: InputBorder.none, hintText: _getHintText(logic), - hintStyle: TextStyle(color: Color(0xff999999), fontSize: 14, fontWeight: FontWeight.w400), + hintStyle: TextStyle( + color: Color(0xff999999), + fontSize: 14, + fontWeight: FontWeight.w400), isCollapsed: true, contentPadding: EdgeInsets.symmetric( horizontal: 12, - vertical: (32 - textPainter.height) / 2, + vertical: + (32 - textPainter.height) / 2, ), ), style: TextStyle( @@ -243,18 +285,21 @@ class WithdrawalPage extends StatelessWidget { ] else ...[ Text( '银行卡号:', - style: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + style: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), ), 10.sizeBoxW, Expanded( - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: () => logic.gotoBankList(), child: Container( alignment: Alignment.centerLeft, height: 37, padding: EdgeInsets.only(left: 10), decoration: BoxDecoration( - color: Colors.white.withValues(alpha: .05), + color: + Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(6), ), child: Row( @@ -267,12 +312,15 @@ class WithdrawalPage extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14, - color: logic.bankModel == null ? Color(0xff525252) : Colors.white, + color: logic.bankModel == null + ? Color(0xff525252) + : Colors.white, ), ), ), 6.sizeBoxW, - Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 16), + Icon(Icons.keyboard_arrow_right, + color: Colors.white, size: 16), 10.sizeBoxW, ], ), @@ -287,10 +335,12 @@ class WithdrawalPage extends StatelessWidget { id: 'money', builder: (controller) => EasyRichText( '手续费率: ${logic.configData?.coinTax ?? 0}% 实际到账金额: ${logic.actualAmount}', - defaultStyle: textStyle(14, Color(0xE5FFFFFF), FontWeight.w500), + defaultStyle: textStyle( + 14, Color(0xE5FFFFFF), FontWeight.w500), patternList: [ EasyRichTextPattern( - targetString: '${logic.configData?.coinTax ?? 0}%', + targetString: + '${logic.configData?.coinTax ?? 0}%', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, @@ -298,7 +348,8 @@ class WithdrawalPage extends StatelessWidget { ), ), EasyRichTextPattern( - targetString: '实际到账金额: ${logic.handlingFee}', + targetString: + '实际到账金额: ${logic.handlingFee}', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, @@ -319,7 +370,10 @@ class WithdrawalPage extends StatelessWidget { 18.sizeBoxH, Text( "提现规则:", - style: const TextStyle(color: Color(0xE5FFFFFF), fontWeight: FontWeight.w500, fontSize: 16.0), + style: const TextStyle( + color: Color(0xE5FFFFFF), + fontWeight: FontWeight.w500, + fontSize: 16.0), ), 12.sizeBoxH, Text( @@ -328,7 +382,11 @@ class WithdrawalPage extends StatelessWidget { "2、每次提现收取${logic.configData?.coinTax}%手续费。\n" "3、仅支持银行卡提现,收款账户卡号与姓名一致,到账时间未72小时内。\n" "4、申请提现后请随时关注收款账户进款通知,长时间未到账,请及时联系客服。\n", - style: const TextStyle(color: Color(0x8CFFFFFF), fontWeight: FontWeight.w400, fontSize: 12.0, height: 2), + style: const TextStyle( + color: Color(0x8CFFFFFF), + fontWeight: FontWeight.w400, + fontSize: 12.0, + height: 2), ), 30.sizeBoxH, ], @@ -370,16 +428,24 @@ class WithdrawalPage extends StatelessWidget { ///支付类型 Widget _buildPayTypeUI(Channel channel, WithdrawalLogic logic, int index) { bool isSelected = logic.selectChannel?.payType == channel.payType; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => logic.changeWithdrawType(channel.payType ?? ''), child: Row( children: [ - Image.asset(channel.payType == 'usdt' ? 'ic_usdt.png'.mineImgPath : 'ic_union.png'.mineImgPath, width: 30), + Image.asset( + channel.payType == 'usdt' + ? 'ic_usdt.png'.mineImgPath + : 'ic_union.png'.mineImgPath, + width: 30), 4.sizeBoxW, - Text(_getPayTypeName(channel.payType ?? ""), style: TextStyle(color: Colors.white, fontSize: 14)), + Text(_getPayTypeName(channel.payType ?? ""), + style: TextStyle(color: Colors.white, fontSize: 14)), 10.sizeBoxW, Image.asset( - isSelected ? 'radio_sel.png'.commonImgPath : 'mine_withdraw_nor.png'.mineImgPath, + isSelected + ? 'radio_sel.png'.commonImgPath + : 'mine_withdraw_nor.png'.mineImgPath, width: 24, ), 24.sizeBoxW, @@ -421,7 +487,8 @@ class WithdrawalPage extends StatelessWidget { } } - bool _isUsdt(WithdrawalLogic logic) => (_currentChannel(logic)?.payType ?? "") == 'usdt'; + bool _isUsdt(WithdrawalLogic logic) => + (_currentChannel(logic)?.payType ?? "") == 'usdt'; // 按 withdrawType 取当前通道,带越界保护(配置异常时不崩溃) Channel? _currentChannel(WithdrawalLogic logic) { diff --git a/lib/hj_page/mine/message/message_center_page.dart b/lib/hj_page/mine/message/message_center_page.dart index 1e06481..1da8a02 100644 --- a/lib/hj_page/mine/message/message_center_page.dart +++ b/lib/hj_page/mine/message/message_center_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'message_center_logic.dart'; import 'message_center_sub_page.dart'; @@ -51,7 +51,8 @@ class MessageCenterPage extends StatelessWidget { controller: logic.tabController, children: logic.titleArr .asMap() - .map((key, value) => MapEntry(key, MessageCenterSubPage(logic.typeArr[key]).keepAlive)) + .map((key, value) => MapEntry(key, + MessageCenterSubPage(logic.typeArr[key]).keepAlive)) .values .toList()), ), diff --git a/lib/hj_page/mine/message/message_center_sub_controller.dart b/lib/hj_page/mine/message/message_center_sub_controller.dart index d974d2d..09838fa 100644 --- a/lib/hj_page/mine/message/message_center_sub_controller.dart +++ b/lib/hj_page/mine/message/message_center_sub_controller.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'message_center_sub_page.dart'; @@ -49,7 +49,9 @@ class MessageCommentLogic extends MessageCenterSubLogic { dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; update(); @@ -67,7 +69,9 @@ class MessageThumbUpLogic extends MessageCenterSubLogic { dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res?.list ?? []); page += 1; update(); diff --git a/lib/hj_page/mine/message/message_center_sub_page.dart b/lib/hj_page/mine/message/message_center_sub_page.dart index 4a5f680..5aadedd 100644 --- a/lib/hj_page/mine/message/message_center_sub_page.dart +++ b/lib/hj_page/mine/message/message_center_sub_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../../main.dart'; import 'message_center_sub_controller.dart'; @@ -23,7 +23,8 @@ class MessageCenterSubPage extends StatefulWidget { State createState() => _MessageCenterSubPageState(); } -class _MessageCenterSubPageState extends State with RouteAware { +class _MessageCenterSubPageState extends State + with RouteAware { late MessageCenterSubLogic logic; @override diff --git a/lib/hj_page/mine/message/widget/message_items.dart b/lib/hj_page/mine/message/widget/message_items.dart index 506e0ee..6050474 100644 --- a/lib/hj_page/mine/message/widget/message_items.dart +++ b/lib/hj_page/mine/message/widget/message_items.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/message/message_dynamic_list.dart'; -import 'package:hgmj/hj_page/user_center_page/user_center_page.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/message/message_dynamic_list.dart'; +import 'package:wydj/hj_page/user_center_page/user_center_page.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../community/post_detail_page/post_detail_page.dart'; @@ -18,7 +18,8 @@ class MessageThumbItem extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, - onTap: () => Get.to(() => PostDetailPage(argument: PostDetailPageArgument(id: model.objId, models: []))), + onTap: () => Get.to(() => PostDetailPage( + argument: PostDetailPageArgument(id: model.objId, models: []))), child: Container( padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), margin: EdgeInsets.only(bottom: 12), @@ -102,7 +103,8 @@ class MessageCommentItem extends StatelessWidget { Widget build(BuildContext context) { return InkWell( enableFeedback: false, - onTap: () => Get.to(() => PostDetailPage(argument: PostDetailPageArgument(id: model.objId, models: []))), + onTap: () => Get.to(() => PostDetailPage( + argument: PostDetailPageArgument(id: model.objId, models: []))), child: Container( padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12), margin: EdgeInsets.only(bottom: 12), @@ -115,7 +117,8 @@ class MessageCommentItem extends StatelessWidget { children: [ InkWell( enableFeedback: false, - onTap: () => Get.to(() => UserCenterPage(uid: model.sendUid ?? 0)), + onTap: () => + Get.to(() => UserCenterPage(uid: model.sendUid ?? 0)), child: NetworkImageLoader( imageUrl: model.sendAvatar ?? '', width: 40, diff --git a/lib/hj_page/mine/mine_drive/mine_drive_logic.dart b/lib/hj_page/mine/mine_drive/mine_drive_logic.dart index 52cdd76..3f987cd 100644 --- a/lib/hj_page/mine/mine_drive/mine_drive_logic.dart +++ b/lib/hj_page/mine/mine_drive/mine_drive_logic.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/mine/official_list_item_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_model/mine/official_list_item_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; class MineDriveLogic extends GetxController { /// null 表示未加载(loading 态),非 null 表示已加载(可能为空) diff --git a/lib/hj_page/mine/mine_drive/mine_drive_page.dart b/lib/hj_page/mine/mine_drive/mine_drive_page.dart index 664b59a..b5fe6e3 100644 --- a/lib/hj_page/mine/mine_drive/mine_drive_page.dart +++ b/lib/hj_page/mine/mine_drive/mine_drive_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/text_util.dart'; import '../../../hj_model/mine/official_list_item_model.dart'; import '../../../routers/jump_router.dart'; @@ -13,8 +13,10 @@ import 'mine_drive_logic.dart'; class MineDrivePage extends StatelessWidget { const MineDrivePage({super.key}); - static const _titleStyle = TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600); - static const _subtitleStyle = TextStyle(color: Color(0x80FFFFFF), fontSize: 12); + static const _titleStyle = + TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600); + static const _subtitleStyle = + TextStyle(color: Color(0x80FFFFFF), fontSize: 12); @override Widget build(BuildContext context) { @@ -32,9 +34,15 @@ class MineDrivePage extends StatelessWidget { child: CustomScrollView( slivers: [ if (controller.groupList.isNotEmpty) - _buildSection(title: '官方社群', subtitle: '一起看片一起分享心得', list: controller.groupList), + _buildSection( + title: '官方社群', + subtitle: '一起看片一起分享心得', + list: controller.groupList), if (controller.officialList.isNotEmpty) - _buildSection(title: '商务合作', subtitle: '代理合作/商务合作', list: controller.officialList), + _buildSection( + title: '商务合作', + subtitle: '代理合作/商务合作', + list: controller.officialList), ], ), ); @@ -82,7 +90,8 @@ class MineDrivePage extends StatelessWidget { alignment: Alignment.center, child: Row( children: [ - NetworkImageLoader(imageUrl: item.officialImg ?? '', width: 40, height: 40), + NetworkImageLoader( + imageUrl: item.officialImg ?? '', width: 40, height: 40), 12.sizeBoxW, Expanded( child: Column( @@ -91,13 +100,15 @@ class MineDrivePage extends StatelessWidget { children: [ Text( item.officialName ?? '', - style: const TextStyle(color: Colors.white, fontSize: 14, height: 1.1), + style: const TextStyle( + color: Colors.white, fontSize: 14, height: 1.1), ), if (TextUtil.isNotEmpty(item.officialDesc)) ...[ 6.sizeBoxH, Text( item.officialDesc ?? '', - style: const TextStyle(color: Color(0xff525252), fontSize: 12, height: 1.1), + style: const TextStyle( + color: Color(0xff525252), fontSize: 12, height: 1.1), ), ], ], @@ -113,7 +124,10 @@ class MineDrivePage extends StatelessWidget { ), child: const Text( '立即加入', - style: TextStyle(color: Colors.black, fontSize: 12, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 12, + fontWeight: FontWeight.w500), ), ), ], diff --git a/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart b/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart index b147a36..5fa9da5 100644 --- a/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart +++ b/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart @@ -1,17 +1,18 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/swipe_action_item.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/swipe_action_item.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_model/mine/follow_user_list_model.dart'; import 'mine_follow_sub_page.dart'; import 'widget/follow_list_items.dart'; -abstract class MineFollowSubLogic extends GetxController with GetTickerProviderStateMixin { +abstract class MineFollowSubLogic extends GetxController + with GetTickerProviderStateMixin { final int? uid; MineFollowSubLogic(this.uid); @@ -58,7 +59,9 @@ class ActressController extends MineFollowSubLogic { dataSource.clear(); refreshController?.refreshCompleted(); } - retModel?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + retModel?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(retModel?.list ?? []); pageNumber += 1; update(); @@ -87,7 +90,9 @@ class BloggerController extends MineFollowSubLogic { dataSource.clear(); refreshController?.refreshCompleted(); } - retModel?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + retModel?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(retModel?.list ?? []); pageNumber += 1; update(); @@ -131,13 +136,16 @@ class TopicController extends MineFollowSubLogic { @override fetchPageData({bool isRefresh = true}) async { super.fetchPageData(isRefresh: isRefresh); - final retModel = await MineService.fetchCollectList("tag", page: pageNumber, size: 10, uid: uid); + final retModel = await MineService.fetchCollectList("tag", + page: pageNumber, size: 10, uid: uid); isLoading = false; if (isRefresh) { dataSource.clear(); refreshController?.refreshCompleted(); } - retModel?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + retModel?.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(retModel?.list ?? []); pageNumber += 1; update(); diff --git a/lib/hj_page/mine/mine_following/widget/follow_list_items.dart b/lib/hj_page/mine/mine_following/widget/follow_list_items.dart index 9eebcd0..09dba46 100644 --- a/lib/hj_page/mine/mine_following/widget/follow_list_items.dart +++ b/lib/hj_page/mine/mine_following/widget/follow_list_items.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/mine/follow_user_list_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/mine/follow_user_list_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../community/community_tag_page/community_tag_page.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; /// 关注列表 - 女优项 class FollowActressItem extends StatefulWidget { @@ -24,7 +24,8 @@ class FollowActressItem extends StatefulWidget { class _FollowActressItemState extends State { @override Widget build(BuildContext context) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { // type:1 原跳女优主页 ActressMainPage(已下线),pushToPersonCenter 内 type==1 已 return null // → 当前点击不跳转,待产品确认替代页(objcId 与用户中心 uid 非同一体系,不能直接跳 UserCenterPage) @@ -77,7 +78,8 @@ class _FollowActressItemState extends State { GestureDetector( onTap: () async { final isFollow = widget.model.hasFollow ?? false; - final res = await MineService.postCollect(widget.model.objcId, 'actresss', !isFollow); + final res = await MineService.postCollect( + widget.model.objcId, 'actresss', !isFollow); if (res) { widget.model.hasFollow = !isFollow; setState(() {}); @@ -85,7 +87,9 @@ class _FollowActressItemState extends State { }, child: Container( padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 5.h), - decoration: BoxDecoration(color: Colors.white.withValues(alpha: .3), borderRadius: BorderRadius.circular(40)), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .3), + borderRadius: BorderRadius.circular(40)), child: Row( children: [ if (widget.model.hasFollow == true) ...[ @@ -119,7 +123,8 @@ class FollowBloggerItem extends StatefulWidget { class _FollowBloggerItemState extends State { @override Widget build(BuildContext context) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { pushToPersonCenter(widget.model.uid ?? 0); }, @@ -157,7 +162,10 @@ class _FollowBloggerItemState extends State { '${widget.model.totalWorks ?? 0} 作品', overflow: TextOverflow.ellipsis, maxLines: 1, - style: TextStyle(fontSize: 12, color: Color(0x8CFFFFFF), fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Color(0x8CFFFFFF), + fontWeight: FontWeight.w400), ), ), SizedBox(width: 12), @@ -166,7 +174,10 @@ class _FollowBloggerItemState extends State { '${widget.model.fans?.countStr} 粉丝', overflow: TextOverflow.ellipsis, maxLines: 1, - style: TextStyle(fontSize: 12, color: Color(0x8CFFFFFF), fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 12, + color: Color(0x8CFFFFFF), + fontWeight: FontWeight.w400), ), ), ], @@ -199,7 +210,8 @@ class FollowTopicItem extends StatefulWidget { class _FollowTopicItemState extends State { @override Widget build(BuildContext context) { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { Get.to(() => CommunityTagDetailPage(model: widget.model)); }, @@ -217,7 +229,9 @@ class _FollowTopicItemState extends State { borderRadius: 8, ), Container( - decoration: BoxDecoration(color: Colors.black.withValues(alpha: .6), borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.black.withValues(alpha: .6), + borderRadius: BorderRadius.circular(8)), ), Column( mainAxisAlignment: MainAxisAlignment.center, @@ -248,7 +262,8 @@ class _FollowTopicItemState extends State { GestureDetector( onTap: () async { final isCollected = widget.model.hasCollected ?? false; - final res = await MineService.postCollect(widget.model.id, "tag", !isCollected); + final res = await MineService.postCollect( + widget.model.id, "tag", !isCollected); if (res) { widget.model.hasCollected = !isCollected; setState(() {}); @@ -258,7 +273,9 @@ class _FollowTopicItemState extends State { width: 108, height: 27, alignment: Alignment.center, - decoration: BoxDecoration(color: Color(0xffFFC000), borderRadius: BorderRadius.circular(6)), + decoration: BoxDecoration( + color: Color(0xffFFC000), + borderRadius: BorderRadius.circular(6)), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/hj_page/mine/mine_post/mine_publish_main_logic.dart b/lib/hj_page/mine/mine_post/mine_publish_main_logic.dart index cf1e0cd..90059d3 100644 --- a/lib/hj_page/mine/mine_post/mine_publish_main_logic.dart +++ b/lib/hj_page/mine/mine_post/mine_publish_main_logic.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'mine_publish_sub_logic.dart'; class MinePublishLogic extends GetxController { diff --git a/lib/hj_page/mine/mine_post/mine_publish_main_page.dart b/lib/hj_page/mine/mine_post/mine_publish_main_page.dart index 7381000..b16cb3d 100644 --- a/lib/hj_page/mine/mine_post/mine_publish_main_page.dart +++ b/lib/hj_page/mine/mine_post/mine_publish_main_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/user/wallet_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_model/user/wallet_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:provider/provider.dart'; import '../../../hj_utils/widget_util.dart'; @@ -26,7 +26,8 @@ class MinePublishPostPage extends StatefulWidget { } } -class _MinePublishPostPageState extends State with TickerProviderStateMixin { +class _MinePublishPostPageState extends State + with TickerProviderStateMixin { final tabs = ['已发布', '待审核', '未通过']; WalletModel? get wallet => globalStore.wallet; late final tabCtr = TabController(length: tabs.length, vsync: this); @@ -53,7 +54,8 @@ class _MinePublishPostPageState extends State with TickerPr void _setSelectedTabDatas() { final logic = Get.find(); if (tabCtr.index == 2) { - logic.dataSource = List.from(Get.find(tag: '2').dataList ?? []); + logic.dataSource = List.from( + Get.find(tag: '2').dataList ?? []); } else { logic.dataSource = []; } @@ -67,7 +69,8 @@ class _MinePublishPostPageState extends State with TickerPr builder: (controller) { return Scaffold( appBar: AppBar( - title: Text("创作中心", style: textStyle(18, Color(0xE5FFFFFF), FontWeight.w600)), + title: Text("创作中心", + style: textStyle(18, Color(0xE5FFFFFF), FontWeight.w600)), actions: [ Visibility( visible: tabCtr.index == 2, @@ -98,7 +101,8 @@ class _MinePublishPostPageState extends State with TickerPr Consumer( builder: (context, store, child) { return Container( - margin: EdgeInsets.symmetric(horizontal: 16, vertical: 18), + margin: EdgeInsets.symmetric( + horizontal: 16, vertical: 18), padding: EdgeInsets.fromLTRB(0, 14, 0, 22), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(8)), @@ -109,7 +113,8 @@ class _MinePublishPostPageState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, children: [ _buildItem( '收益余额', @@ -121,7 +126,8 @@ class _MinePublishPostPageState extends State with TickerPr '累计收益', '${wallet?.vidIncome ?? '0'}', '业绩明细', - () => Get.to(RecordsPage(RecordType.income)), + () => + Get.to(RecordsPage(RecordType.income)), ), ], ), @@ -167,7 +173,8 @@ class _MinePublishPostPageState extends State with TickerPr alignment: Alignment.center, child: Text( controller.isAllChecked ? '取消全选' : '全选', - style: TextStyle(color: Color(0x99FFFFFF), fontSize: 16), + style: TextStyle( + color: Color(0x99FFFFFF), fontSize: 16), ), ), ), @@ -186,13 +193,19 @@ class _MinePublishPostPageState extends State with TickerPr width: 112, height: 38, decoration: BoxDecoration( - color: Color(0xFFF52C56).withValues(alpha: controller.isEmptyChecked ? 0.5 : 1), + color: Color(0xFFF52C56).withValues( + alpha: controller.isEmptyChecked ? 0.5 : 1), borderRadius: BorderRadius.circular(3), ), alignment: Alignment.center, child: Text( '删除(${controller.checkedList.length})', - style: TextStyle(color: Colors.white.withValues(alpha: controller.isEmptyChecked ? 0.5 : 1), fontSize: 16), + style: TextStyle( + color: Colors.white.withValues( + alpha: controller.isEmptyChecked + ? 0.5 + : 1), + fontSize: 16), ), ), ), @@ -232,7 +245,8 @@ class _MinePublishPostPageState extends State with TickerPr labelColor: Colors.white.withValues(alpha: .9), labelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), unselectedLabelColor: Colors.white.withValues(alpha: 0.35), - unselectedLabelStyle: const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + const TextStyle(fontSize: 14, fontWeight: FontWeight.w400), indicator: CustomIndicator( width: 13, height: 3, @@ -242,18 +256,23 @@ class _MinePublishPostPageState extends State with TickerPr ); } - _buildItem(String title, String count, String actionTitle, Function() action) { + _buildItem( + String title, String count, String actionTitle, Function() action) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( title, - style: TextStyle(color: Colors.white.withValues(alpha: .7), fontWeight: FontWeight.w500, fontSize: 14), + style: TextStyle( + color: Colors.white.withValues(alpha: .7), + fontWeight: FontWeight.w500, + fontSize: 14), ), 6.sizeBoxH, Text( count, - style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500, fontSize: 24), + style: TextStyle( + color: Colors.white, fontWeight: FontWeight.w500, fontSize: 24), ), 6.sizeBoxH, GestureDetector( @@ -268,7 +287,10 @@ class _MinePublishPostPageState extends State with TickerPr ), child: Text( actionTitle, - style: const TextStyle(color: Color(0xFF1F2029), fontWeight: FontWeight.w500, fontSize: 12.0), + style: const TextStyle( + color: Color(0xFF1F2029), + fontWeight: FontWeight.w500, + fontSize: 12.0), ), ), ), @@ -280,7 +302,9 @@ class _MinePublishPostPageState extends State with TickerPr Widget _buildContent() { return TabBarView( controller: tabCtr, - physics: inEdit && tabCtr.index == 2 ? const NeverScrollableScrollPhysics() : null, + physics: inEdit && tabCtr.index == 2 + ? const NeverScrollableScrollPhysics() + : null, children: [ MinePublishSubPage(status: 1, inEdit: false).keepAlive, MinePublishSubPage(status: 0, inEdit: false).keepAlive, diff --git a/lib/hj_page/mine/mine_post/mine_publish_sub_logic.dart b/lib/hj_page/mine/mine_post/mine_publish_sub_logic.dart index 703cb44..ded85ff 100644 --- a/lib/hj_page/mine/mine_post/mine_publish_sub_logic.dart +++ b/lib/hj_page/mine/mine_post/mine_publish_sub_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class MinePublishSubLogic extends ListBaseLogic { final int status; @@ -13,7 +13,8 @@ class MinePublishSubLogic extends ListBaseLogic { loadData(); } - void loadData({bool isRefresh = true}) => fetchData(isRefresh: isRefresh, fetch: _fetch); + void loadData({bool isRefresh = true}) => + fetchData(isRefresh: isRefresh, fetch: _fetch); Future<(List?, bool)> _fetch(int page) async { final res = await MineService.fetchPublishes(page: page, status: status); diff --git a/lib/hj_page/mine/mine_post/mine_publish_sub_page.dart b/lib/hj_page/mine/mine_post/mine_publish_sub_page.dart index 3a0bc85..6ed2c59 100644 --- a/lib/hj_page/mine/mine_post/mine_publish_sub_page.dart +++ b/lib/hj_page/mine/mine_post/mine_publish_sub_page.dart @@ -1,20 +1,22 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../community/widget/community_post_widget.dart'; import 'mine_publish_main_logic.dart'; import 'mine_publish_sub_logic.dart'; -typedef OnItemCheckCallback = void Function(VideoModel videoModel, bool isChecked); +typedef OnItemCheckCallback = void Function( + VideoModel videoModel, bool isChecked); class MinePublishSubPage extends StatelessWidget { final int status; final bool inEdit; final OnItemCheckCallback? onItemCheck; - const MinePublishSubPage({super.key, this.status = 0, this.inEdit = false, this.onItemCheck}); + const MinePublishSubPage( + {super.key, this.status = 0, this.inEdit = false, this.onItemCheck}); @override Widget build(BuildContext context) { diff --git a/lib/hj_page/mine/mine_profit/bank_card_home_page.dart b/lib/hj_page/mine/mine_profit/bank_card_home_page.dart index 9afd83e..84d8699 100644 --- a/lib/hj_page/mine/mine_profit/bank_card_home_page.dart +++ b/lib/hj_page/mine/mine_profit/bank_card_home_page.dart @@ -3,13 +3,13 @@ import 'dart:convert' as convert; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../../../hj_utils/light_model.dart'; import '../../../../hj_utils/store_keys.dart'; import '../../../../tools_base/refresh/pull_refresh.dart'; @@ -58,7 +58,8 @@ class _BankCardHomePageState extends State { if (result) { var result = await lightKV.getString(StoreKeys.LAST_A_ACCOUNT); if (result != null) { - AccountInfoModel listBean = AccountInfoModel.fromMap(convert.jsonDecode(result)); + AccountInfoModel listBean = + AccountInfoModel.fromMap(convert.jsonDecode(result)); if (model.id == listBean.id) { lightKV.setString(StoreKeys.LAST_A_ACCOUNT, ""); } @@ -96,12 +97,14 @@ class _BankCardHomePageState extends State { return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( - title: Text('选择银行卡', style: textStyle(18, Color(0xE5FFFFFF), FontWeight.w600)), + title: Text('选择银行卡', + style: textStyle(18, Color(0xE5FFFFFF), FontWeight.w600)), leading: BackButton( onPressed: () => Get.back(result: selectItem), ), actions: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { isEdit = !isEdit; if (isEdit) { @@ -193,7 +196,8 @@ class _BankCardHomePageState extends State { } else { isSelected = selectItem?.id == item?.id; } - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { if (isEdit) { if (deleteList.contains(item) == true) { @@ -209,7 +213,9 @@ class _BankCardHomePageState extends State { child: Container( margin: EdgeInsets.only(bottom: 12), padding: EdgeInsets.symmetric(horizontal: 12, vertical: 18), - decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(9)), color: const Color(0x0DFFFFFF)), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(9)), + color: const Color(0x0DFFFFFF)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -223,18 +229,27 @@ class _BankCardHomePageState extends State { children: [ Text( item?.getBankName() ?? "", - style: const TextStyle(color: const Color(0xE5ffffff), fontWeight: FontWeight.w500, fontSize: 16.0), + style: const TextStyle( + color: const Color(0xE5ffffff), + fontWeight: FontWeight.w500, + fontSize: 16.0), ), 9.sizeBoxW, Text( item?.actName ?? "", - style: const TextStyle(color: const Color(0xE5ffffff), fontWeight: FontWeight.w400, fontSize: 12.0), + style: const TextStyle( + color: const Color(0xE5ffffff), + fontWeight: FontWeight.w400, + fontSize: 12.0), ) ], ), 6.sizeBoxH, Text("卡号:${item?.act}", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w400, fontSize: 12.0)) + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w400, + fontSize: 12.0)) ], ), ), @@ -250,7 +265,9 @@ class _BankCardHomePageState extends State { ), ), Icon( - isSelected ? CupertinoIcons.checkmark_circle_fill : CupertinoIcons.circle, + isSelected + ? CupertinoIcons.checkmark_circle_fill + : CupertinoIcons.circle, color: isSelected ? Color(0xFFFFC000) : Color(0x99000000), ), ], @@ -263,9 +280,11 @@ class _BankCardHomePageState extends State { //添加银行卡 _buildCardAddView() { - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () async { - final res = await Get.dialog(AddBankDialog(), barrierColor: Colors.black.withValues(alpha: .7)); + final res = await Get.dialog(AddBankDialog(), + barrierColor: Colors.black.withValues(alpha: .7)); if (res != null) { _getAliListData(); } diff --git a/lib/hj_page/mine/mine_profit/widget/add_bank_dialog.dart b/lib/hj_page/mine/mine_profit/widget/add_bank_dialog.dart index 99789aa..bfa6d5a 100644 --- a/lib/hj_page/mine/mine_profit/widget/add_bank_dialog.dart +++ b/lib/hj_page/mine/mine_profit/widget/add_bank_dialog.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; import '../../make_money/alipay_ccdcapi_model.dart'; @@ -33,7 +33,8 @@ class _AddBankDialogState extends State { children: [ Text( '添加银行卡', - style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, fontSize: 20, fontWeight: FontWeight.w500), ), 12.sizeBoxH, Divider(height: .5, color: Colors.white.withValues(alpha: .1)), @@ -50,7 +51,10 @@ class _AddBankDialogState extends State { maxLength: 20, controller: bankNameCtr, style: TextStyle(color: Colors.white), - inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z\u4E00-\u9F5a]'))], + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp(r'[a-zA-Z\u4E00-\u9F5a]')) + ], decoration: InputDecoration( border: InputBorder.none, counterText: '', @@ -77,8 +81,11 @@ class _AddBankDialogState extends State { child: TextField( maxLength: 20, controller: bankNoCtr, - style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400), - inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[0-9]'))], + style: + TextStyle(color: Colors.white, fontWeight: FontWeight.w400), + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')) + ], keyboardType: TextInputType.number, decoration: InputDecoration( border: InputBorder.none, @@ -117,7 +124,10 @@ class _AddBankDialogState extends State { ), child: Text( "立即提交", - style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ) @@ -158,7 +168,8 @@ class _AddBankDialogState extends State { } _addBankCard(ApcApiModel model) async { - final res = await MineService.addBankCard(model.key, bankNameCtr.text, model.bank, model.cardType); + final res = await MineService.addBankCard( + model.key, bankNameCtr.text, model.bank, model.cardType); if (res) { Get.back(result: true); } diff --git a/lib/hj_page/mine/mine_setting/bind_phone_logic.dart b/lib/hj_page/mine/mine_setting/bind_phone_logic.dart index 71c5ea3..34836ba 100644 --- a/lib/hj_page/mine/mine_setting/bind_phone_logic.dart +++ b/lib/hj_page/mine/mine_setting/bind_phone_logic.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../tools_base/event_bus/event_bus_util.dart'; import '../../../tools_base/event_bus/events.dart'; @@ -62,7 +62,8 @@ class BindPhoneLogic extends GetxController { Get.back(); } } else { - final result = await globalStore.loginByMobile(phoneCtr.text, codeCtr.text); + final result = + await globalStore.loginByMobile(phoneCtr.text, codeCtr.text); if (result != null) { showToast('登录成功'); eventBus.emit(ReLoginEvent()); diff --git a/lib/hj_page/mine/mine_setting/bing_phone_page.dart b/lib/hj_page/mine/mine_setting/bing_phone_page.dart index 0bf7164..e521836 100644 --- a/lib/hj_page/mine/mine_setting/bing_phone_page.dart +++ b/lib/hj_page/mine/mine_setting/bing_phone_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'bind_phone_logic.dart'; @@ -41,7 +41,9 @@ class BindPhonePage extends StatelessWidget { children: [ Text( '手机号', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 16), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 16), ), 12.sizeBoxW, Expanded( @@ -58,7 +60,9 @@ class BindPhonePage extends StatelessWidget { isCollapsed: true, contentPadding: EdgeInsets.zero, counterText: '', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: 0.5), fontSize: 14)), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: 0.5), + fontSize: 14)), ), ) ], @@ -78,7 +82,9 @@ class BindPhonePage extends StatelessWidget { children: [ Text( '验证码', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 16), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 16), ), 12.sizeBoxW, Expanded( @@ -95,7 +101,9 @@ class BindPhonePage extends StatelessWidget { isCollapsed: true, contentPadding: EdgeInsets.zero, counterText: '', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: 0.5), fontSize: 14)), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: 0.5), + fontSize: 14)), ), ), 12.sizeBoxW, @@ -103,13 +111,17 @@ class BindPhonePage extends StatelessWidget { onTap: () => controller.onSendCode(), child: ValueListenableBuilder( valueListenable: controller.countDownNof, - builder: (BuildContext context, int value, Widget? child) { + builder: + (BuildContext context, int value, Widget? child) { final iscountdown = value > -1; return Container( - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4), + padding: EdgeInsets.symmetric( + horizontal: 4, vertical: 4), child: Text( iscountdown ? '${60 - value}秒' : '获取验证码', - style: TextStyle(color: Colors.white.withValues(alpha: 0.5), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.5), + fontSize: 12), ), ); }, @@ -139,7 +151,10 @@ class BindPhonePage extends StatelessWidget { ), child: Text( controller.pageType.buttonTitle, - style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.w500), ), ), ) diff --git a/lib/hj_page/mine/mine_setting/invite_bind_logic.dart b/lib/hj_page/mine/mine_setting/invite_bind_logic.dart index cf1b66b..99a09ea 100644 --- a/lib/hj_page/mine/mine_setting/invite_bind_logic.dart +++ b/lib/hj_page/mine/mine_setting/invite_bind_logic.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; /// 绑定邀请码逻辑 class InviteBindLogic extends GetxController { diff --git a/lib/hj_page/mine/mine_setting/invite_bind_page.dart b/lib/hj_page/mine/mine_setting/invite_bind_page.dart index bb12daa..0af9db5 100644 --- a/lib/hj_page/mine/mine_setting/invite_bind_page.dart +++ b/lib/hj_page/mine/mine_setting/invite_bind_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'invite_bind_logic.dart'; @@ -26,7 +26,10 @@ class InviteBindPage extends StatelessWidget { // 标题 Text( '输入邀请码', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 30, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 30, + fontWeight: FontWeight.w500), ), 12.sizeBoxH, Text( @@ -46,7 +49,9 @@ class InviteBindPage extends StatelessWidget { children: [ Text( '邀请码', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 16), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 16), ), 24.sizeBoxW, Expanded( @@ -63,7 +68,9 @@ class InviteBindPage extends StatelessWidget { isCollapsed: true, contentPadding: EdgeInsets.zero, counterText: '', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 14)), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: 0.35), + fontSize: 14)), ), ) ], @@ -77,7 +84,8 @@ class InviteBindPage extends StatelessWidget { 18.sizeBoxH, Text( '邀请1人 获得1天会员', - style: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 14), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.35), fontSize: 14), ), 30.sizeBoxH, // 立即绑定按钮 @@ -93,7 +101,10 @@ class InviteBindPage extends StatelessWidget { ), child: Text( '立即绑定', - style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.w500), ), ), ) diff --git a/lib/hj_page/mine/mine_setting/mine_code_logic.dart b/lib/hj_page/mine/mine_setting/mine_code_logic.dart index fbd2dc5..b1ebad1 100644 --- a/lib/hj_page/mine/mine_setting/mine_code_logic.dart +++ b/lib/hj_page/mine/mine_setting/mine_code_logic.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/mine/exchange_record_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/hj_model/mine/exchange_record_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; class MineExchangeCodeLogic extends GetxController { @@ -33,7 +33,9 @@ class MineExchangeCodeLogic extends GetxController { groupList.addAll(res.data ?? []); } refreshController?.refreshCompleted(); - (res?.total ?? 0) > (res?.data?.length ?? 0) ? refreshController?.loadComplete() : refreshController?.loadNoData(); + (res?.total ?? 0) > (res?.data?.length ?? 0) + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); } catch (e) { refreshController?.refreshCompleted(); refreshController?.loadComplete(); diff --git a/lib/hj_page/mine/mine_setting/mine_code_page.dart b/lib/hj_page/mine/mine_setting/mine_code_page.dart index 0638a62..f136d41 100644 --- a/lib/hj_page/mine/mine_setting/mine_code_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_code_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/mine/exchange_record_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/mine/exchange_record_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'mine_code_logic.dart'; @@ -35,7 +35,8 @@ class _MineExchangeCodePageState extends State { onRefresh: (controller) => _.loadData(), onLoading: (controller) => _.loadMoreData(), child: CustomScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, slivers: [ SliverToBoxAdapter( child: _buildContent(_), @@ -47,7 +48,8 @@ class _MineExchangeCodePageState extends State { ), ), ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => _.onExChangeCode(), child: Container( height: 44, @@ -142,7 +144,8 @@ class _MineExchangeCodePageState extends State { style: TextStyle(color: Colors.white, fontSize: 14), decoration: InputDecoration( hintText: '请输入${widget.type == 0 ? '邀请码' : '兑换码'}(字母大写)', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: .35)), + hintStyle: + TextStyle(color: Colors.white.withValues(alpha: .35)), border: InputBorder.none, ), ), @@ -212,7 +215,8 @@ class _MineExchangeCodePageState extends State { alignment: Alignment.center, child: Text( item.code ?? '', - style: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: .55), fontSize: 12), ), ), ), @@ -224,7 +228,8 @@ class _MineExchangeCodePageState extends State { item.desc ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: .55), fontSize: 12), ), ), ), @@ -234,7 +239,8 @@ class _MineExchangeCodePageState extends State { alignment: Alignment.center, child: Text( '${item.createdAt.utcToYMD(gap: '.')}', - style: TextStyle(color: Colors.white.withValues(alpha: .55), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: .55), fontSize: 12), ), ), ), diff --git a/lib/hj_page/mine/mine_setting/mine_find_account_page.dart b/lib/hj_page/mine/mine_setting/mine_find_account_page.dart index f24830c..aa26dcc 100644 --- a/lib/hj_page/mine/mine_setting/mine_find_account_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_find_account_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_utils/permission_util.dart'; import 'bing_phone_page.dart'; @@ -10,7 +10,8 @@ class MineFindAccountPage extends StatelessWidget { late final dataSource = [ { 'title': '手机号找回', - 'ontap': () => Get.to(() => const BindPhonePage(pageType: PhonePageType.find)), + 'ontap': () => + Get.to(() => const BindPhonePage(pageType: PhonePageType.find)), }, { 'title': '凭证找回', @@ -58,7 +59,9 @@ class MineFindAccountPage extends StatelessWidget { children: [ Text( (data['title'] ?? '').toString(), - style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: 0.9)), + style: TextStyle( + fontSize: 14, + color: Colors.white.withValues(alpha: 0.9)), ), Spacer(), Icon( diff --git a/lib/hj_page/mine/mine_setting/mine_password_logic.dart b/lib/hj_page/mine/mine_setting/mine_password_logic.dart index 1b74952..5c11bd9 100644 --- a/lib/hj_page/mine/mine_setting/mine_password_logic.dart +++ b/lib/hj_page/mine/mine_setting/mine_password_logic.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_page/splash/splash_page.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_page/splash/splash_page.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; /// 手势密码用途:设置 / 关闭 / 进 app 解锁校验 enum MinePasswordType { setting, close, check } @@ -22,8 +22,9 @@ class MinePasswordLogic extends GetxController { /// 校验/关闭模式下,把手势组件的 [answer] 设为已保存密码,让组件自己判断对错、 /// 画错时展示错误态并停留;设置模式无旧密码,传 null 走 minLength 判断 - List? get answer => - (isCheck || type == MinePasswordType.close) ? List.from(globalStore.password) : null; + List? get answer => (isCheck || type == MinePasswordType.close) + ? List.from(globalStore.password) + : null; /// 画完手势:设置/关闭成功即退出本页,解锁通过则回启动页重走流程 Future onComplete(List result) async { @@ -37,7 +38,8 @@ class MinePasswordLogic extends GetxController { case MinePasswordType.close: if (await globalStore.closeLockPassword(result) == true) Get.back(); case MinePasswordType.check: - if (await globalStore.checkLockPassword(result) == true) Get.toNamed(SplashPage.routeName); + if (await globalStore.checkLockPassword(result) == true) + Get.toNamed(SplashPage.routeName); } } } diff --git a/lib/hj_page/mine/mine_setting/mine_password_page.dart b/lib/hj_page/mine/mine_setting/mine_password_page.dart index 94ed630..f08f03f 100644 --- a/lib/hj_page/mine/mine_setting/mine_password_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_password_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../mine_gesture_pwd/widget/gesture_password_widget.dart'; import 'mine_password_logic.dart'; @@ -31,15 +31,16 @@ class MinePasswordPage extends StatelessWidget { 100.sizeBoxH, SafeArea( bottom: false, - child: Image.asset('mine_lock_password.png'.mineImgPath, width: 29), + child: Image.asset('mine_lock_password.png'.mineImgPath, + width: 29), ), ], - if(!logic.isCheck) - 129.sizeBoxH, + if (!logic.isCheck) 129.sizeBoxH, 24.sizeBoxH, Text( logic.title, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 18), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), fontSize: 18), ), 75.sizeBoxH, GesturePasswordWidget( diff --git a/lib/hj_page/mine/mine_setting/mine_scan_login_logic.dart b/lib/hj_page/mine/mine_setting/mine_scan_login_logic.dart index bfe1558..f0914da 100644 --- a/lib/hj_page/mine/mine_setting/mine_scan_login_logic.dart +++ b/lib/hj_page/mine/mine_setting/mine_scan_login_logic.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/hj_utils/image_util.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/image_util.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; import '../identity/mine_identity_page.dart'; diff --git a/lib/hj_page/mine/mine_setting/mine_scan_login_page.dart b/lib/hj_page/mine/mine_setting/mine_scan_login_page.dart index d4e16c9..cd5ee36 100644 --- a/lib/hj_page/mine/mine_setting/mine_scan_login_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_scan_login_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; import 'mine_scan_login_logic.dart'; @@ -27,7 +27,8 @@ class _MineScanLoginPageState extends State { backgroundColor: Colors.transparent, title: Text( '扫码登录', - style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), ), ), body: Stack( @@ -59,7 +60,10 @@ class _MineScanLoginPageState extends State { 12.sizeBoxH, Text( '相册', - style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.w500), ) ], ), @@ -74,7 +78,10 @@ class _MineScanLoginPageState extends State { 12.sizeBoxH, Text( '我的凭证', - style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.w500), ) ], ), diff --git a/lib/hj_page/mine/mine_setting/mine_setting_page.dart b/lib/hj_page/mine/mine_setting/mine_setting_page.dart index c5d689f..7dfc514 100644 --- a/lib/hj_page/mine/mine_setting/mine_setting_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_setting_page.dart @@ -1,21 +1,21 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/routers/jump_router.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/hj_utils/version_util.dart'; -import 'package:hgmj/hj_utils/video_cache_manager.dart'; -import 'package:hgmj/tools_base/cache/cache_util.dart'; -import 'package:hgmj/tools_base/cache/image_cache_manager.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/image/image_disk_cache.dart'; -import 'package:hgmj/tools_base/video_download/video_download_manager.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/version_util.dart'; +import 'package:wydj/hj_utils/video_cache_manager.dart'; +import 'package:wydj/tools_base/cache/cache_util.dart'; +import 'package:wydj/tools_base/cache/image_cache_manager.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/image/image_disk_cache.dart'; +import 'package:wydj/tools_base/video_download/video_download_manager.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../../alert/splash/update_dialog.dart'; import '../identity/mine_identity_page.dart'; @@ -103,7 +103,8 @@ class _MineSettingPageState extends State { } return; } - Get.to(() => const SettingProfilePage(SettingProfileType.nickName)); + Get.to(() => + const SettingProfilePage(SettingProfileType.nickName)); }), _buildLine(), _buildItem( @@ -167,7 +168,9 @@ class _MineSettingPageState extends State { onTap: () { //比对启动页拉到的版本配置,确实有新版才弹更新框 final target = checkUpdate(); - target == null ? showToast("当前已是最新版!") : UpdateDialog.show(target); + target == null + ? showToast("当前已是最新版!") + : UpdateDialog.show(target); }), _buildLine(), ], @@ -197,7 +200,8 @@ class _MineSettingPageState extends State { children: [ Text( title, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 14), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), fontSize: 14), ), Spacer(), if (avatarUrl != null) @@ -210,13 +214,15 @@ class _MineSettingPageState extends State { if (subTitle != null) Text( subTitle, - style: TextStyle(color: Colors.white.withValues(alpha: 0.45), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.45), fontSize: 12), ), if (showCopy) ...[ 4.sizeBoxW, GestureDetector( onTap: () { - Clipboard.setData(ClipboardData(text: '${globalStore.meInfo?.uid}')); + Clipboard.setData( + ClipboardData(text: '${globalStore.meInfo?.uid}')); showToast('复制成功'); }, child: Container( @@ -230,7 +236,10 @@ class _MineSettingPageState extends State { ), child: const Text( '复制', - style: TextStyle(color: Colors.black, fontSize: 12, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 12, + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart b/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart index c3709a0..8bfbfc4 100644 --- a/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart +++ b/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'mine_setting_profile_page.dart'; import 'setting_profile_widget.dart'; @@ -76,7 +76,8 @@ class SettingSloganController extends MineSettingProfilePage { } } -MineSettingProfilePage instanceSettingProfileController(SettingProfileType type) { +MineSettingProfilePage instanceSettingProfileController( + SettingProfileType type) { switch (type) { case SettingProfileType.nickName: return SettingNickNameController(); diff --git a/lib/hj_page/mine/mine_setting/mine_setting_profile_page.dart b/lib/hj_page/mine/mine_setting/mine_setting_profile_page.dart index 432ff90..ca1924c 100644 --- a/lib/hj_page/mine/mine_setting/mine_setting_profile_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_setting_profile_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'mine_setting_profile_logic.dart'; diff --git a/lib/hj_page/mine/mine_setting/setting_avatar_logic.dart b/lib/hj_page/mine/mine_setting/setting_avatar_logic.dart index 760dbef..201df25 100644 --- a/lib/hj_page/mine/mine_setting/setting_avatar_logic.dart +++ b/lib/hj_page/mine/mine_setting/setting_avatar_logic.dart @@ -1,8 +1,8 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; class SettingAvatarLogic extends ListBaseLogic { int selectIndex = -1; diff --git a/lib/hj_page/mine/mine_setting/setting_avatar_page.dart b/lib/hj_page/mine/mine_setting/setting_avatar_page.dart index 0a1efeb..48ec939 100644 --- a/lib/hj_page/mine/mine_setting/setting_avatar_page.dart +++ b/lib/hj_page/mine/mine_setting/setting_avatar_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import 'setting_avatar_logic.dart'; @@ -21,11 +21,13 @@ class SettingAvatarPage extends StatelessWidget { appBar: AppBar( title: Text('选择头像'), actions: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: controller.confirmChangeAvatar, child: Text( '保存', - style: TextStyle(color: Colors.white.withValues(alpha: 0.55), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.55), fontSize: 12), ), ), 16.sizeBoxW, @@ -48,7 +50,8 @@ class SettingAvatarPage extends StatelessWidget { 10.verticalSpace, Text( '当前头像', - style: TextStyle(color: Colors.white.withValues(alpha: 0.55), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.55), fontSize: 12), ), 20.verticalSpace, Expanded( diff --git a/lib/hj_page/mine/mine_setting/setting_profile_widget.dart b/lib/hj_page/mine/mine_setting/setting_profile_widget.dart index 0e16a49..fe07b8b 100644 --- a/lib/hj_page/mine/mine_setting/setting_profile_widget.dart +++ b/lib/hj_page/mine/mine_setting/setting_profile_widget.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import 'mine_setting_profile_logic.dart'; @@ -35,21 +35,27 @@ class _SettingNickNameState extends State { child: TextField( controller: controller.nickNameTfCtr, maxLength: 20, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 18), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), fontSize: 18), decoration: InputDecoration( border: InputBorder.none, hintText: '输入新的昵称', - hintStyle: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 18), + hintStyle: TextStyle( + color: Colors.white.withValues(alpha: 0.35), + fontSize: 18), counterText: '', isCollapsed: true, contentPadding: EdgeInsets.zero), ), ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => controller.nickNameTfCtr.clear(), child: Container( padding: EdgeInsets.all(2), - decoration: BoxDecoration(color: Colors.black.withValues(alpha: 0.9), borderRadius: BorderRadius.circular(90)), + decoration: BoxDecoration( + color: Colors.black.withValues(alpha: 0.9), + borderRadius: BorderRadius.circular(90)), child: Image.asset( 'close_button.png'.commonImgPath, width: 24, @@ -62,7 +68,8 @@ class _SettingNickNameState extends State { 12.sizeBoxH, Text( '昵称30天内可修改4次', - style: TextStyle(color: Colors.white.withValues(alpha: 0.35), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.35), fontSize: 12), ) ], ), @@ -85,7 +92,9 @@ class _SettingSloganState extends State { return Container( margin: EdgeInsets.only(left: 16, top: 12, right: 16), padding: EdgeInsets.all(10), - decoration: BoxDecoration(color: Colors.black.withValues(alpha: .04), borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.black.withValues(alpha: .04), + borderRadius: BorderRadius.circular(8)), constraints: BoxConstraints( minHeight: 111, ), diff --git a/lib/hj_page/mine/mine_share/mine_share_page.dart b/lib/hj_page/mine/mine_share/mine_share_page.dart index dc42068..e41812e 100644 --- a/lib/hj_page/mine/mine_share/mine_share_page.dart +++ b/lib/hj_page/mine/mine_share/mine_share_page.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; @@ -49,176 +49,185 @@ class MineSharePage extends StatelessWidget { ), body: SingleChildScrollView( child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - spacing: 10.w, - children: [ - RepaintBoundary( - key: boundaryKey, - child: Container( - margin: EdgeInsets.only(top: 30), - padding: EdgeInsets.symmetric(horizontal: 16), - child: SizedBox( - width: 300, - child: Stack( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(9), - child: Image.asset('share_bg.webp'.mineImgPath), - ), - // 整张卡片统一响应 meInfo 变化:头像/邀请码/二维码同源刷新 - Consumer( - builder: (_, provider, __) { - final me = provider.meInfo; - return Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 10.w, + children: [ + RepaintBoundary( + key: boundaryKey, + child: Container( + margin: EdgeInsets.only(top: 30), + padding: EdgeInsets.symmetric(horizontal: 16), + child: SizedBox( + width: 300, + child: Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(9), + child: Image.asset('share_bg.webp'.mineImgPath), + ), + // 整张卡片统一响应 meInfo 变化:头像/邀请码/二维码同源刷新 + Consumer( + builder: (_, provider, __) { + final me = provider.meInfo; + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + 30.sizeBoxH, + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(45), + border: Border.all( + color: Color(0x4DF68804), width: 3), + ), + child: NetworkImageLoader( + imageUrl: me?.portrait ?? '', + width: 82, + height: 82, + borderRadius: 45), + ), + 10.sizeBoxH, + Text( + '我的邀请码', + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + 10.sizeBoxH, + Text( + me?.promotionCode ?? "", + style: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + 30.sizeBoxH, + Text("每邀请3人,送3天VIP", + style: TextStyle( + fontSize: 14, color: Color(0xffFFC000))), + 10.sizeBoxH, + Row( children: [ - 30.sizeBoxH, - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(45), - border: Border.all(color: Color(0x4DF68804), width: 3), - ), - child: NetworkImageLoader( - imageUrl: me?.portrait ?? '', width: 82, height: 82, borderRadius: 45), - ), - 10.sizeBoxH, - Text( - '我的邀请码', - style: TextStyle( - color: Colors.white.withValues(alpha: .9), - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - 10.sizeBoxH, - Text( - me?.promotionCode ?? "", - style: TextStyle( - color: Colors.white.withValues(alpha: .55), - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - 30.sizeBoxH, - Text("每邀请3人,送3天VIP", style: TextStyle(fontSize: 14, color: Color(0xffFFC000))), - 10.sizeBoxH, - Row( - children: [ - Spacer(), - Center( - child: Container( - padding: EdgeInsets.all(11.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("code_bg.webp".mineImgPath), - fit: BoxFit.fill, - ), - ), - child: Container( - padding: EdgeInsets.all(6.w), - color: Colors.white, - child: QrImageView( - data: me?.promoteURL ?? "", - version: QrVersions.auto, - size: 100, - backgroundColor: Colors.white, - ), - ), + Spacer(), + Center( + child: Container( + padding: EdgeInsets.all(11.w), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "code_bg.webp".mineImgPath), + fit: BoxFit.fill, ), ), - Spacer(), - ], - ), - 4.sizeBoxH, - Text( - '提示*苹果手机请用相机扫码/安卓手机\n推荐UC浏览器扫码', - style: TextStyle( - color: Colors.white.withValues(alpha: .55), - fontSize: 12, - fontWeight: FontWeight.w400, - ), - textAlign: TextAlign.center, - ), - 6.sizeBoxH, - Container( - height: 30, - padding: EdgeInsets.symmetric(horizontal: 18, vertical: 3), - child: Text( - '${Config.appName} 官网地址 ${Address.groundUrl}', - style: TextStyle( - color: Colors.white.withValues(alpha: .55), - fontSize: 12, - fontWeight: FontWeight.w400, + child: Container( + padding: EdgeInsets.all(6.w), + color: Colors.white, + child: QrImageView( + data: me?.promoteURL ?? "", + version: QrVersions.auto, + size: 100, + backgroundColor: Colors.white, + ), ), ), ), + Spacer(), ], - ); - }, - ), - ], - ), - ), - ), - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 20), - padding: EdgeInsets.symmetric(vertical: 12), - child: Column( - children: [ - GestureDetector( - onTap: () async { - final ok = await ImageUtil.saveWidgetToAlbum(boundaryKey); - showToast(ok ? "保存成功" : "保存失败,请重试"); + ), + 4.sizeBoxH, + Text( + '提示*苹果手机请用相机扫码/安卓手机\n推荐UC浏览器扫码', + style: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 12, + fontWeight: FontWeight.w400, + ), + textAlign: TextAlign.center, + ), + 6.sizeBoxH, + Container( + height: 30, + padding: EdgeInsets.symmetric( + horizontal: 18, vertical: 3), + child: Text( + '${Config.appName} 官网地址 ${Address.groundUrl}', + style: TextStyle( + color: Colors.white.withValues(alpha: .55), + fontSize: 12, + fontWeight: FontWeight.w400, + ), + ), + ), + ], + ); }, - child: Container( - height: 44, - alignment: Alignment.center, - margin: EdgeInsets.symmetric( - horizontal: 78, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(22), - color: AppColors.actionRed, - ), - child: Text( - "保存图片", - style: TextStyle( - fontSize: 16, - color: Colors.white, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - 16.sizeBoxH, - GestureDetector( - onTap: () { - Clipboard.setData(ClipboardData(text: globalStore.meInfo?.promoteURL ?? "")); - showToast('复制成功'); - }, - child: Container( - width: 112, - height: 44, - alignment: Alignment.center, - child: Text( - "复制链接", - style: TextStyle( - fontSize: 12, - color: Color(0x8CFFFFFF), - decoration: TextDecoration.underline, // 添加下划线 - decorationColor: Color(0xFF11887C), // 下划线颜色 - decorationThickness: 1.0, // 下划线粗细 - decorationStyle: TextDecorationStyle.solid, // 下划线样式 - ), - ), - ), ), ], ), ), - ], - )), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 20), + padding: EdgeInsets.symmetric(vertical: 12), + child: Column( + children: [ + GestureDetector( + onTap: () async { + final ok = await ImageUtil.saveWidgetToAlbum(boundaryKey); + showToast(ok ? "保存成功" : "保存失败,请重试"); + }, + child: Container( + height: 44, + alignment: Alignment.center, + margin: EdgeInsets.symmetric( + horizontal: 78, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(22), + color: AppColors.actionRed, + ), + child: Text( + "保存图片", + style: TextStyle( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + 16.sizeBoxH, + GestureDetector( + onTap: () { + Clipboard.setData(ClipboardData( + text: globalStore.meInfo?.promoteURL ?? "")); + showToast('复制成功'); + }, + child: Container( + width: 112, + height: 44, + alignment: Alignment.center, + child: Text( + "复制链接", + style: TextStyle( + fontSize: 12, + color: Color(0x8CFFFFFF), + decoration: TextDecoration.underline, // 添加下划线 + decorationColor: Color(0xFF11887C), // 下划线颜色 + decorationThickness: 1.0, // 下划线粗细 + decorationStyle: TextDecorationStyle.solid, // 下划线样式 + ), + ), + ), + ), + ], + ), + ), + ], + )), ); } } diff --git a/lib/hj_page/mine/mine_share/mine_share_record_logic.dart b/lib/hj_page/mine/mine_share/mine_share_record_logic.dart index 5d8317d..e90751c 100644 --- a/lib/hj_page/mine/mine_share/mine_share_record_logic.dart +++ b/lib/hj_page/mine/mine_share/mine_share_record_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/user/user_income_info_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/user/user_income_info_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; import '../../../hj_model/mine/promotion_record.dart'; @@ -21,7 +21,8 @@ class MineShareRecordLogic extends ListBaseLogic { } // 邀请记录列表:下拉刷新 / 上拉加载更多(分页、防重入、异常兜底交给基类) - void loadData({bool isRefresh = true}) => fetchData(isRefresh: isRefresh, fetch: _fetch); + void loadData({bool isRefresh = true}) => + fetchData(isRefresh: isRefresh, fetch: _fetch); Future<(List?, bool)> _fetch(int page) async { final resp = await MineService.getBindRecord(10, page); diff --git a/lib/hj_page/mine/mine_share/mine_share_record_page.dart b/lib/hj_page/mine/mine_share/mine_share_record_page.dart index 49e57bb..6bf3d34 100644 --- a/lib/hj_page/mine/mine_share/mine_share_record_page.dart +++ b/lib/hj_page/mine/mine_share/mine_share_record_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/mine/promotion_record.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/mine/promotion_record.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_utils/widget_util.dart'; import 'mine_share_record_logic.dart'; @@ -23,7 +23,8 @@ class MineShareRecordPage extends StatelessWidget { body: Column( children: [ 12.sizeBoxH, - Text('已邀请:${logic.model?.totalInviteUserCount ?? 0}人', style: textStyle(12, Color(0xff525252), FontWeight.w400)), + Text('已邀请:${logic.model?.totalInviteUserCount ?? 0}人', + style: textStyle(12, Color(0xff525252), FontWeight.w400)), Expanded( child: pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, @@ -48,7 +49,8 @@ class MineShareRecordPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), shrinkWrap: true, itemCount: list.length, - separatorBuilder: (_, __) => Divider(height: 0.5, color: Colors.white.withValues(alpha: .1)), + separatorBuilder: (_, __) => + Divider(height: 0.5, color: Colors.white.withValues(alpha: .1)), itemBuilder: (_, index) => _buildItemView(list[index]), ); } @@ -60,9 +62,7 @@ class MineShareRecordPage extends StatelessWidget { width: double.infinity, margin: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( - color: Color(0x0D1F2029), - borderRadius: BorderRadius.circular(8) - ), + color: Color(0x0D1F2029), borderRadius: BorderRadius.circular(8)), child: Row( children: [ NetworkImageLoader( @@ -74,12 +74,18 @@ class MineShareRecordPage extends StatelessWidget { 11.sizeBoxW, Text( item.name ?? '', - style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500, fontSize: 16.0), + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w500, + fontSize: 16.0), ), Spacer(), Text( '注册时间:${item.createAt.utcToYMD(gap: '/')}', - style: TextStyle(color: Colors.white.withValues(alpha: .5), fontWeight: FontWeight.w400, fontSize: 12.0), + style: TextStyle( + color: Colors.white.withValues(alpha: .5), + fontWeight: FontWeight.w400, + fontSize: 12.0), ) ], ), diff --git a/lib/hj_page/mine/mine_video_cache/video_cache_cell.dart b/lib/hj_page/mine/mine_video_cache/video_cache_cell.dart index f715b75..cd33513 100644 --- a/lib/hj_page/mine/mine_video_cache/video_cache_cell.dart +++ b/lib/hj_page/mine/mine_video_cache/video_cache_cell.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../hj_model/video_model.dart'; import '../../../tools_base/toast.dart'; @@ -171,7 +171,8 @@ class _VideoCacheCellState extends State { maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.left, - style: const TextStyle(fontSize: 11, color: Color(0xffd43f61), height: 1.5), + style: const TextStyle( + fontSize: 11, color: Color(0xffd43f61), height: 1.5), ), ), // 仅下载完成且非动漫显示"保存到相册",避免下载中误触 + 右侧溢出 @@ -218,7 +219,8 @@ class _VideoCacheCellState extends State { child: Text( "${(model.progress * 100).toStringAsFixed(1)}%", textAlign: TextAlign.right, - style: const TextStyle(fontSize: 11, color: Color(0xffaab2b7), height: 1.2), + style: const TextStyle( + fontSize: 11, color: Color(0xffaab2b7), height: 1.2), ), ), ], @@ -282,7 +284,8 @@ class _VideoCacheCellState extends State { mainAxisSize: MainAxisSize.min, // 按内容收窄,不再固定 120 宽 children: [ Image.asset( - (isDownloading ? "cache_stop.webp" : "cache_start.webp").videoPath, + (isDownloading ? "cache_stop.webp" : "cache_start.webp") + .videoPath, width: 10, fit: BoxFit.cover, ), @@ -323,7 +326,8 @@ class _VideoCacheCellState extends State { ), ), child: Image.asset( - (selected ? "cache_selected.webp" : "cache_unselected.webp").videoPath, + (selected ? "cache_selected.webp" : "cache_unselected.webp") + .videoPath, key: ValueKey(selected), width: 40, height: 40, @@ -366,7 +370,8 @@ class VideoACGCacheCell extends StatelessWidget { textAlign: TextAlign.left, style: TextStyle( fontSize: 12, - color: model.updateStatus == 2 ? Color(0xff757575) : Color(0xffFFC000), + color: + model.updateStatus == 2 ? Color(0xff757575) : Color(0xffFFC000), ), maxLines: 1, overflow: TextOverflow.ellipsis, diff --git a/lib/hj_page/mine/mine_video_cache/video_cache_logic.dart b/lib/hj_page/mine/mine_video_cache/video_cache_logic.dart index bcdceb2..bbf686a 100644 --- a/lib/hj_page/mine/mine_video_cache/video_cache_logic.dart +++ b/lib/hj_page/mine/mine_video_cache/video_cache_logic.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../hj_model/video_model.dart'; import '../../../tools_base/video_download/video_cache_store.dart'; @@ -13,7 +13,12 @@ class VideoCacheLogic extends GetxController with GetTickerProviderStateMixin { static const removeAnimDuration = Duration(milliseconds: 260); //顺序与 _cacheMap 一致 - final tabStyles = const [MediaStyle.Video, MediaStyle.ShortVideo, MediaStyle.Drama, MediaStyle.Cartoon]; + final tabStyles = const [ + MediaStyle.Video, + MediaStyle.ShortVideo, + MediaStyle.Drama, + MediaStyle.Cartoon + ]; late final tabTitles = tabStyles.map((e) => e.cacheTabTitle).toList(); @@ -31,7 +36,8 @@ class VideoCacheLogic extends GetxController with GetTickerProviderStateMixin { List listOf(MediaStyle style) => _cacheMap[style] ?? const []; - List get allVideos => [for (final list in _cacheMap.values) ...list]; + List get allVideos => + [for (final list in _cacheMap.values) ...list]; bool isLoading = true; bool isEditing = false; @@ -73,7 +79,9 @@ class VideoCacheLogic extends GetxController with GetTickerProviderStateMixin { /// cell 挂载时注册自己的局部刷新回调 void registerCellRefresher(VideoModel model, VoidCallback refresh) { - _cellRefreshers.putIfAbsent(VideoDownloadManager.taskKey(model.realVideoUrl), () => {}).add(refresh); + _cellRefreshers + .putIfAbsent(VideoDownloadManager.taskKey(model.realVideoUrl), () => {}) + .add(refresh); } /// cell 卸载 / 换绑视频时注销 @@ -115,7 +123,8 @@ class VideoCacheLogic extends GetxController with GetTickerProviderStateMixin { for (final entry in _cacheMap.entries) { entry.value ..clear() - ..addAll(await VideoCacheStore.instance.getMovieCacheVideoList(entry.key)); + ..addAll( + await VideoCacheStore.instance.getMovieCacheVideoList(entry.key)); } // 本地记录只有 url,进度/暂停态要逐条问下载器;顺带把 _callback 挂上去 for (final item in allVideos) { @@ -223,7 +232,8 @@ class VideoCacheLogic extends GetxController with GetTickerProviderStateMixin { // 表现为「短视频页点下载 → 来缓存页看一眼 → 退回去,那个按钮的进度就再也不动了」。 // _callback 是同一个实例注册在多个 url 上(_loadData 逐个 searchInfo 都传了它),故逐个摘除 for (final item in allVideos) { - VideoDownloadManager.instance.removeCallback(item.realVideoUrl, _callback); + VideoDownloadManager.instance + .removeCallback(item.realVideoUrl, _callback); } _cellRefreshers.clear(); tabCtr.dispose(); diff --git a/lib/hj_page/mine/mine_video_cache/video_cache_page.dart b/lib/hj_page/mine/mine_video_cache/video_cache_page.dart index 68ed60f..35303a2 100644 --- a/lib/hj_page/mine/mine_video_cache/video_cache_page.dart +++ b/lib/hj_page/mine/mine_video_cache/video_cache_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; -import 'package:hgmj/tools_base/widget/stagger_in_item.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/stagger_in_item.dart'; import '../../../hj_model/drama_media_info.dart'; import '../../../hj_model/video_model.dart'; @@ -32,7 +32,8 @@ class VideoCachePage extends StatelessWidget { enableFeedback: false, onTap: () => logic.editEvent(), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 12), + padding: + const EdgeInsets.symmetric(horizontal: 6, vertical: 12), alignment: Alignment.centerRight, child: Text( logic.isEditing ? "删除" : "编辑", @@ -58,7 +59,8 @@ class VideoCachePage extends StatelessWidget { indicatorWeight: 1, unselectedLabelColor: Color(0x8CFFFFFF), unselectedLabelStyle: TextStyle(fontSize: 14), - labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + labelStyle: TextStyle( + fontSize: 14, fontWeight: FontWeight.w500), labelColor: Color(0xE5FFFFFF), tabs: logic.tabTitles .map( @@ -76,7 +78,8 @@ class VideoCachePage extends StatelessWidget { controller: logic.tabCtr, children: [ // keepAlive:切 tab 不重建,保留滚动位置,也避免入场动画反复重播 - for (final style in logic.tabStyles) _buildGrid(logic, style).keepAlive, + for (final style in logic.tabStyles) + _buildGrid(logic, style).keepAlive, ], ), ) @@ -96,7 +99,10 @@ class VideoCachePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( //短剧跟「热门短剧」橱窗同规格:2 列 168/266 - crossAxisCount: style == MediaStyle.ShortVideo || style == MediaStyle.Cartoon ? 3 : 2, + crossAxisCount: + style == MediaStyle.ShortVideo || style == MediaStyle.Cartoon + ? 3 + : 2, crossAxisSpacing: 6, mainAxisSpacing: 12, childAspectRatio: switch (style) { @@ -123,7 +129,8 @@ class VideoCachePage extends StatelessWidget { } /// 单个缓存 cell:被标记删除时缩放 + 淡出(时长与 logic 一致,播完 logic 才真删数据) - Widget _buildCell(VideoCacheLogic logic, VideoModel videoModel, MediaStyle style) { + Widget _buildCell( + VideoCacheLogic logic, VideoModel videoModel, MediaStyle style) { final isRemoving = logic.isRemoving(videoModel); // 退场中屏蔽点击:opacity 到 0 也照样命中手势,否则那 260 毫秒里 // 点到看不见的 cell 会跳进播放页 @@ -159,7 +166,8 @@ class VideoCachePage extends StatelessWidget { //下载就是为了离线看:有本地文件就直接放,不进二级页——二级页是纯网络播放器 //(VideoPlayerBaseLogic.initPlayer 只认 network),进那儿等于没用上下好的文件,断网还打不开 if (style == MediaStyle.Drama && videoModel.localPath?.isNotEmpty == true) { - _playLocal(videoModel, '${videoModel.title ?? ""} 第${videoModel.episodeNo ?? 1}集'); + _playLocal(videoModel, + '${videoModel.title ?? ""} 第${videoModel.episodeNo ?? 1}集'); return; } //没下完(或只有下载态没落到文件)的没有本地文件可放,进二级页在线看这一集: @@ -179,11 +187,13 @@ class VideoCachePage extends StatelessWidget { _playLocal(videoModel, videoModel.title ?? ""); return; } - pushToVideoPage(videoModel: videoModel, isCartoon: videoModel.videoType == 1); + pushToVideoPage( + videoModel: videoModel, isCartoon: videoModel.videoType == 1); } /// 用本地文件播([SimpleVideoPlayerLogic] 拿到 localPath 就走 PlayerFactory.file) - void _playLocal(VideoModel videoModel, String title) => Get.to(SimpleVideoPlayerPage( + void _playLocal(VideoModel videoModel, String title) => + Get.to(SimpleVideoPlayerPage( localPath: videoModel.localPath, videoUrl: videoModel.realVideoUrl, title: title, diff --git a/lib/hj_page/mine/mine_vip/charge_user_header.dart b/lib/hj_page/mine/mine_vip/charge_user_header.dart index 5cf0f83..0d9c6db 100644 --- a/lib/hj_page/mine/mine_vip/charge_user_header.dart +++ b/lib/hj_page/mine/mine_vip/charge_user_header.dart @@ -2,11 +2,11 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../widgets/gradient_text.dart'; @@ -16,7 +16,8 @@ class UserChargeView extends StatelessWidget { /// true:旧版文案/配色(会员中心 A / DISABLED) final bool classic; - const UserChargeView({super.key, this.isFromCoin = false, this.classic = false}); + const UserChargeView( + {super.key, this.isFromCoin = false, this.classic = false}); @override Widget build(BuildContext context) { @@ -49,7 +50,9 @@ class UserChargeView extends StatelessWidget { Text( provider.meInfo == null ? '未知' - : provider.meInfo?.name?.substring(0, min(provider.meInfo?.name?.length ?? 0, 9)) ?? '', + : provider.meInfo?.name?.substring( + 0, min(provider.meInfo?.name?.length ?? 0, 9)) ?? + '', overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( @@ -61,7 +64,8 @@ class UserChargeView extends StatelessWidget { 8.sizeBoxW, if (!provider.isVIP) Container( - padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + padding: + const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), border: Border.all(color: Color(0x14FFFFFF), width: 1), @@ -138,7 +142,9 @@ class UserChargeView extends StatelessWidget { Text( provider.meInfo == null ? '未知' - : provider.meInfo?.name?.substring(0, min(provider.meInfo?.name?.length ?? 0, 9)) ?? '', + : provider.meInfo?.name?.substring( + 0, min(provider.meInfo?.name?.length ?? 0, 9)) ?? + '', overflow: TextOverflow.ellipsis, maxLines: 1, style: TextStyle( @@ -148,7 +154,8 @@ class UserChargeView extends StatelessWidget { ), ), 12.sizeBoxW, - if (provider.isVIP && vipIcon.isNotEmpty) Image.asset(vipIcon, height: 20), + if (provider.isVIP && vipIcon.isNotEmpty) + Image.asset(vipIcon, height: 20), ], ), 4.sizeBoxH, diff --git a/lib/hj_page/mine/mine_vip/mine_charge_coin_logic.dart b/lib/hj_page/mine/mine_vip/mine_charge_coin_logic.dart index fb7fcc3..61ed418 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_coin_logic.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_coin_logic.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../hj_model/mine/exchange/recharge_list_model.dart'; import '../../../hj_model/mine/exchange/recharge_type_list_model.dart'; @@ -14,7 +14,8 @@ class MineChargeCoinLogic extends GetxController { /// 下单埋点上下文(短剧付费墙要带 mediaId/contentId/checkoutContextId 做归因) final PayOrderTrackInfo? orderTrack; - MineChargeCoinLogic({this.sourcePage = PaySourcePage.unknown, this.orderTrack}); + MineChargeCoinLogic( + {this.sourcePage = PaySourcePage.unknown, this.orderTrack}); bool isInitLoading = true; // 首屏加载中 RechargeListModel? model; // 金币充值档位列表 @@ -57,7 +58,8 @@ class MineChargeCoinLogic extends GetxController { Get.bottomSheet( OnlinePayPage( coinRcModel: selectedCoin, - orderTrack: (orderTrack ?? const PayOrderTrackInfo()).copyWith(sourcePage: sourcePage), + orderTrack: (orderTrack ?? const PayOrderTrackInfo()) + .copyWith(sourcePage: sourcePage), ), isScrollControlled: true, ); diff --git a/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart b/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart index adbc15c..4340584 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; import '../../../hj_utils/widget_util.dart'; @@ -20,7 +20,8 @@ class MineChargeCoinPage extends StatelessWidget { /// 下单来源,入口不传则 UNKNOWN(金币没有专属来源枚举,别拿会员的顶上) final PaySourcePage sourcePage; - const MineChargeCoinPage({super.key, this.sourcePage = PaySourcePage.unknown}); + const MineChargeCoinPage( + {super.key, this.sourcePage = PaySourcePage.unknown}); @override Widget build(BuildContext context) { @@ -31,7 +32,8 @@ class MineChargeCoinPage extends StatelessWidget { return Scaffold( body: () { if (controller.isInitLoading) return const LoadingCenterWidget(); - if (controller.model == null) return CErrorWidget(retryOnTap: () => controller.loadData()); + if (controller.model == null) + return CErrorWidget(retryOnTap: () => controller.loadData()); return Column( children: [ Expanded( @@ -50,10 +52,12 @@ class MineChargeCoinPage extends StatelessWidget { actions: [ InkWell( enableFeedback: false, - onTap: () => Get.to(RecordsPage(RecordType.recharge)), + onTap: () => + Get.to(RecordsPage(RecordType.recharge)), child: Text( '充值记录', - style: TextStyle(color: Color(0xff666666), fontSize: 16.sp), + style: TextStyle( + color: Color(0xff666666), fontSize: 16.sp), ), ), 18.w.sizeBoxW @@ -75,7 +79,8 @@ class MineChargeCoinPage extends StatelessWidget { SliverPadding( padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverGrid.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 12, crossAxisSpacing: 6, @@ -84,7 +89,8 @@ class MineChargeCoinPage extends StatelessWidget { itemCount: controller.model?.list?.length ?? 0, itemBuilder: (BuildContext context, int index) { final model = controller.model!.list![index]; - final isSelected = controller.selectedCoin?.id == model.id; + final isSelected = + controller.selectedCoin?.id == model.id; return CoinItem( model, onTap: () => controller.onSelectCoin(index), @@ -97,7 +103,8 @@ class MineChargeCoinPage extends StatelessWidget { SliverToBoxAdapter( child: Text( '*如提示【交易失败】【账户风险】等,可重新发起订单,或在15分钟后重试支付。', - style: TextStyle(color: Color(0xff666666), fontSize: 12), + style: + TextStyle(color: Color(0xff666666), fontSize: 12), ).paddingSymmetric(horizontal: 16), ), ], @@ -122,11 +129,16 @@ class MineChargeCoinPage extends StatelessWidget { child: Container( height: 44, margin: EdgeInsets.symmetric(horizontal: 16), - decoration: BoxDecoration(color: AppColors.actionRed, borderRadius: BorderRadius.circular(22)), + decoration: BoxDecoration( + color: AppColors.actionRed, + borderRadius: BorderRadius.circular(22)), alignment: Alignment.center, child: Text( '¥${controller.selectedCoin?.moneyYuan ?? 0}/立即支付', - style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), @@ -151,7 +163,10 @@ class MineChargeCoinPage extends StatelessWidget { children: [ Text( '我的金币余额', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500), ), 8.sizeBoxH, Row( @@ -164,13 +179,17 @@ class MineChargeCoinPage extends StatelessWidget { final total = (wallet?.amount ?? 0) + (wallet?.income ?? 0); return Text( "$total", - style: TextStyle(color: Color(0xffFFD460), fontSize: 32, fontWeight: FontWeight.w600), + style: TextStyle( + color: Color(0xffFFD460), + fontSize: 32, + fontWeight: FontWeight.w600), ); }), Spacer(), InkWell( enableFeedback: false, - onTap: () => Get.to(RecordsPage(RecordType.bill), opaque: false), + onTap: () => + Get.to(RecordsPage(RecordType.bill), opaque: false), child: Container( alignment: Alignment.center, height: 30, diff --git a/lib/hj_page/mine/mine_vip/mine_charge_vip_logic.dart b/lib/hj_page/mine/mine_vip/mine_charge_vip_logic.dart index 243a7b1..dafe077 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_vip_logic.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_vip_logic.dart @@ -1,11 +1,11 @@ import 'package:carousel_slider/carousel_controller.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/alert/vip_guide/guide_manager.dart'; -import 'package:hgmj/alert/vip_guide/timed_popup_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/alert/vip_guide/guide_manager.dart'; +import 'package:wydj/alert/vip_guide/timed_popup_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../alert/vip_guide/guide_countdown_dialog.dart'; import '../../../alert/vip_guide/guide_config.dart'; @@ -35,7 +35,11 @@ class MineChargeVipLogic extends GetxController { /// 入口透传的整份下单上下文,字段比 [videoId] 全时以它为准(短剧付费墙带 mediaId/contentId/checkoutContextId) final PayOrderTrackInfo? orderTrack; - MineChargeVipLogic({this.vipID, this.sourcePage = PaySourcePage.vipCenter, this.videoId, this.orderTrack}); + MineChargeVipLogic( + {this.vipID, + this.sourcePage = PaySourcePage.vipCenter, + this.videoId, + this.orderTrack}); /// 当前选中的会员卡(页面级状态,多入口各自独立) VipProductModel? currentProductModel; @@ -101,7 +105,8 @@ class MineChargeVipLogic extends GetxController { void _selectCard(VipProductModel card) { _guideCardId = card.productID; if (vipProductManager.isLoading || !pageCtr.ready) return; - final index = vipProductManager.vipCards.indexWhere((e) => e.productID == card.productID); + final index = vipProductManager.vipCards + .indexWhere((e) => e.productID == card.productID); if (index >= 0) pageCtr.animateToPage(index, curve: Curves.fastOutSlowIn); } @@ -113,13 +118,17 @@ class MineChargeVipLogic extends GetxController { /// 数据就绪后按优先级确定默认选中卡,并滚动到对应位置;UI 展示后再上报曝光 void _syncSelection() { - currentProductModel = vipProductManager.defaultVipCard(vipID: _guideCardId ?? vipID, current: currentProductModel); + currentProductModel = vipProductManager.defaultVipCard( + vipID: _guideCardId ?? vipID, current: currentProductModel); final pid = currentProductModel?.productID; - final index = pid == null ? -1 : vipProductManager.vipCards.indexWhere((e) => e.productID == pid); + final index = pid == null + ? -1 + : vipProductManager.vipCards.indexWhere((e) => e.productID == pid); // 会话尽早创建:避免仅在 post-frame 里建,用户快速返回时 onClose 拿不到 session、CLOSE 丢报。 // 必须等有卡数据再建:首次请求失败时卡列表还是空,会把「无实验」快照锁进 session, // 之后错误页重试成功也不会上报(快照 late final 不可变)。 - if (vipProductManager.vipCards.isNotEmpty) _analytics ??= VipCardAnalyticsSession(); + if (vipProductManager.vipCards.isNotEmpty) + _analytics ??= VipCardAnalyticsSession(); WidgetsBinding.instance.addPostFrameCallback((_) { if (isClosed) return; // 卡列表为空时页面渲染的是错误页,轮播压根没 build,controller 没 attach, @@ -127,7 +136,8 @@ class MineChargeVipLogic extends GetxController { if (index >= 0 && pageCtr.ready) pageCtr.jumpToPage(index); // 曝光必须在 UI 实际展示后上报 _analytics?.reportPageViewAfterPaint(); - _analytics?.reportProductImpression(currentProductModel, afterPaint: true); + _analytics?.reportProductImpression(currentProductModel, + afterPaint: true); }); update(); } @@ -143,7 +153,8 @@ class MineChargeVipLogic extends GetxController { final model = data[index]; final card = VipCardItem( model, - isSelect: currentProductModel?.productID != null && currentProductModel?.productID == model.productID, + isSelect: currentProductModel?.productID != null && + currentProductModel?.productID == model.productID, callback: () { pageCtr.animateToPage(index, curve: Curves.fastOutSlowIn); }, @@ -202,7 +213,8 @@ class MineChargeVipLogic extends GetxController { checkoutContextId: base?.checkoutContextId, sessionId: base?.sessionId ?? _analytics?.sessionId, experimentId: vipProductManager.isExperimentActive - ? (currentProductModel?.experimentId ?? vipProductManager.experimentId) + ? (currentProductModel?.experimentId ?? + vipProductManager.experimentId) : null, experimentVariant: vipProductManager.isExperimentActive ? (currentProductModel?.variant ?? vipProductManager.variant) diff --git a/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart b/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart index 62e6082..b884b97 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart @@ -3,11 +3,11 @@ import 'dart:math' as math; import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../pre_sale/pre_sale_entry.dart'; @@ -37,12 +37,14 @@ class MineChargeVipPage extends StatefulWidget { } // 多入口可叠栈,用 per-实例唯一 tag 隔离 controller,避免轮播/选中卡/onReady 串味 -class _MineChargeVipPageState extends State with UniqueTagMixin { +class _MineChargeVipPageState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( tag: uniqueTag, - init: MineChargeVipLogic(vipID: widget.vipID, sourcePage: widget.sourcePage), + init: MineChargeVipLogic( + vipID: widget.vipID, sourcePage: widget.sourcePage), builder: (logic) => Consumer( builder: (_, mgr, __) { // ACTIVE+B → 改版 UI;A / DISABLED / 无实验 → 旧版 UI @@ -59,7 +61,10 @@ class _MineChargeVipPageState extends State with UniqueTagMix InkWell( enableFeedback: false, onTap: () => Get.to(RecordsPage(RecordType.recharge)), - child: Text('充值记录', style: TextStyle(color: Colors.white.withValues(alpha: .45), fontSize: 12)), + child: Text('充值记录', + style: TextStyle( + color: Colors.white.withValues(alpha: .45), + fontSize: 12)), ), 16.sizeBoxW, ], @@ -134,7 +139,8 @@ class _MineChargeVipPageState extends State with UniqueTagMix ), ], ), - Positioned(bottom: 0, left: 0, right: 0, child: _buildPay(classic: classic)), + Positioned( + bottom: 0, left: 0, right: 0, child: _buildPay(classic: classic)), ], ); } @@ -179,7 +185,9 @@ class _MineChargeVipPageState extends State with UniqueTagMix mainAxisSize: MainAxisSize.min, children: [ // classic ? _buildClassicCorePrivileges(coreList) : _buildCorePrivileges(coreList), - classic ? _buildClassicMorePrivileges(privileges) : _buildMorePrivileges(privileges), + classic + ? _buildClassicMorePrivileges(privileges) + : _buildMorePrivileges(privileges), ], ); }, @@ -200,7 +208,7 @@ class _MineChargeVipPageState extends State with UniqueTagMix if (list.isEmpty) return const SizedBox.shrink(); return Column( children: [ - // const VipSectionTitle("会员权益", classic: true), + // const VipSectionTitle("会员权益", classic: true), VipMoreSectionTitleImage(), 12.sizeBoxH, GridView.builder( @@ -214,7 +222,8 @@ class _MineChargeVipPageState extends State with UniqueTagMix childAspectRatio: 63 / 100, ), itemCount: list.length, - itemBuilder: (_, index) => VipProductPrivilegeItem(list[index], classic: true), + itemBuilder: (_, index) => + VipProductPrivilegeItem(list[index], classic: true), ), ], ); @@ -256,7 +265,8 @@ class _VipMorePrivilegesPanel extends StatefulWidget { const _VipMorePrivilegesPanel({required this.list, required this.title}); @override - State<_VipMorePrivilegesPanel> createState() => _VipMorePrivilegesPanelState(); + State<_VipMorePrivilegesPanel> createState() => + _VipMorePrivilegesPanelState(); } class _VipMorePrivilegesPanelState extends State<_VipMorePrivilegesPanel> { @@ -274,7 +284,8 @@ class _VipMorePrivilegesPanelState extends State<_VipMorePrivilegesPanel> { @override Widget build(BuildContext context) { final canToggle = widget.list.length > _collapsedCount; - final showCount = (!_expanded && canToggle) ? _collapsedCount : widget.list.length; + final showCount = + (!_expanded && canToggle) ? _collapsedCount : widget.list.length; return Container( margin: const EdgeInsets.symmetric(horizontal: 16), @@ -299,14 +310,16 @@ class _VipMorePrivilegesPanelState extends State<_VipMorePrivilegesPanel> { padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, mainAxisSpacing: 12, crossAxisSpacing: 10, childAspectRatio: 72 / 110, ), itemCount: showCount, - itemBuilder: (_, index) => VipProductPrivilegeItem(widget.list[index]), + itemBuilder: (_, index) => + VipProductPrivilegeItem(widget.list[index]), ), if (canToggle) ...[ 8.sizeBoxH, @@ -326,7 +339,9 @@ class _VipMorePrivilegesPanelState extends State<_VipMorePrivilegesPanel> { ), ), Icon( - _expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, + _expanded + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, size: 16, color: Colors.white.withValues(alpha: 0.55), ), diff --git a/lib/hj_page/mine/mine_vip/online_pay_page.dart b/lib/hj_page/mine/mine_vip/online_pay_page.dart index c611aca..99027dd 100644 --- a/lib/hj_page/mine/mine_vip/online_pay_page.dart +++ b/lib/hj_page/mine/mine_vip/online_pay_page.dart @@ -3,13 +3,13 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../assets_tool/app_colors.dart'; @@ -62,13 +62,16 @@ class _OnlinePayPageState extends State { CouponModel? coupon; // 支付方式列表。会员卡与金币档位二选一,getter 每次访问都会重建列表,故每帧只取一次 - List get _payTypes => widget.vipProductModel?.rchgTypeUI ?? widget.coinRcModel!.rechargeTypeListUI; + List get _payTypes => + widget.vipProductModel?.rchgTypeUI ?? + widget.coinRcModel!.rechargeTypeListUI; /// 支付按钮文案:预售(尾款/升级/预订) → 会员卡(升级/普通) → 金币充值 String get _payText { final vip = widget.vipProductModel; if (vip == null) return '¥${widget.coinRcModel?.moneyYuan ?? 0}/立即支付'; - if (!vip.isPreSale) return '¥${vip.discountedPriceUI}/${vip.isUpgrade == true ? '补差价升级' : '立即支付'}'; + if (!vip.isPreSale) + return '¥${vip.discountedPriceUI}/${vip.isUpgrade == true ? '补差价升级' : '立即支付'}'; // 预售:可付尾款优先,其次升级,最后预订 final preSale = PreSaleProvider(); final detail = preSale.preSaleModel?.detailModel; @@ -110,11 +113,14 @@ class _OnlinePayPageState extends State { 18.sizeBoxH, const Text( '选择支付方式', - style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500, color: Colors.white), + style: TextStyle( + fontSize: 20, fontWeight: FontWeight.w500, color: Colors.white), ), 18.sizeBoxH, //支付方式列表 - Wrap(children: [for (var i = 0; i < types.length; i++) _payItem(types[i], i)]), + Wrap(children: [ + for (var i = 0; i < types.length; i++) _payItem(types[i], i) + ]), //支付小贴士 Padding( padding: EdgeInsets.only(bottom: 24.h, left: 16, right: 16), @@ -123,13 +129,15 @@ class _OnlinePayPageState extends State { children: [ Text( '支付小贴士:', - style: textStyle(14, Colors.white.withValues(alpha: .9), FontWeight.w500), + style: textStyle( + 14, Colors.white.withValues(alpha: .9), FontWeight.w500), ), 6.sizeBoxH, Text( '''1.因超时支付无法到账,请重新发起。 2.每天发起支付不能超过5次,连续发起且未支付,账号可能被加入黑名单。''', - style: textStyle(12, Colors.white.withValues(alpha: .45), FontWeight.w400), + style: textStyle( + 12, Colors.white.withValues(alpha: .45), FontWeight.w400), ), ], ), @@ -148,7 +156,10 @@ class _OnlinePayPageState extends State { ), child: Text( _payText, - style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.sp, color: Colors.black), + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 20.sp, + color: Colors.black), ), ), ), @@ -178,15 +189,22 @@ class _OnlinePayPageState extends State { margin: EdgeInsets.only(bottom: 20.h), child: Row( children: [ - icon.isEmpty ? const SizedBox(width: 36, height: 36) : Image.asset(icon, width: 36), + icon.isEmpty + ? const SizedBox(width: 36, height: 36) + : Image.asset(icon, width: 36), 13.sizeBoxW, Expanded( child: Text( "${type.typeName}", - style: textStyle(16, Colors.white.withValues(alpha: .9), FontWeight.w500), + style: textStyle( + 16, Colors.white.withValues(alpha: .9), FontWeight.w500), ), ), - Image.asset(payIndex == index ? 'radio_sel.png'.commonImgPath : 'mine_withdraw_nor.png'.mineImgPath, width: 16), + Image.asset( + payIndex == index + ? 'radio_sel.png'.commonImgPath + : 'mine_withdraw_nor.png'.mineImgPath, + width: 16), ], ), ), @@ -231,10 +249,14 @@ class _OnlinePayPageState extends State { contentId: base.contentId, checkoutContextId: base.checkoutContextId, experimentId: vipProductManager.isExperimentActive - ? (base.experimentId ?? (vip == null ? null : vip.experimentId ?? vipProductManager.experimentId)) + ? (base.experimentId ?? + (vip == null + ? null + : vip.experimentId ?? vipProductManager.experimentId)) : null, experimentVariant: vipProductManager.isExperimentActive - ? (base.experimentVariant ?? (vip == null ? null : vip.variant ?? vipProductManager.variant)) + ? (base.experimentVariant ?? + (vip == null ? null : vip.variant ?? vipProductManager.variant)) : null, ); final urlModel = await MineService.chargeGoldCoin( @@ -242,7 +264,9 @@ class _OnlinePayPageState extends State { productId: productId, isVip: vip != null, goldExtraID: coupon?.cId, - finalPayStatus: vip?.isPreSale == true ? PreSaleProvider().preSaleModel?.detailModel?.balancePayment : null, + finalPayStatus: vip?.isPreSale == true + ? PreSaleProvider().preSaleModel?.detailModel?.balancePayment + : null, orderTrack: orderTrack, ); LoadingHelper.dismissLoading(); @@ -285,10 +309,20 @@ class _OnlinePayPageState extends State { vip?.discountedPrice, source: 'online_pay', jumpWalletOnInsufficient: false, // 当前就在充值页,余额不足不跳转 - finalPayStatus: vip?.isPreSale == true ? PreSaleProvider().preSaleModel?.detailModel?.balancePayment : null, + finalPayStatus: vip?.isPreSale == true + ? PreSaleProvider().preSaleModel?.detailModel?.balancePayment + : null, // 与 /mine/topay 一致:仅实验 ACTIVE 时回传;sessionId 有则带上 - experimentId: experimentActive ? (track?.experimentId ?? vip?.experimentId ?? vipProductManager.experimentId) : null, - experimentVariant: experimentActive ? (track?.experimentVariant ?? vip?.variant ?? vipProductManager.variant) : null, + experimentId: experimentActive + ? (track?.experimentId ?? + vip?.experimentId ?? + vipProductManager.experimentId) + : null, + experimentVariant: experimentActive + ? (track?.experimentVariant ?? + vip?.variant ?? + vipProductManager.variant) + : null, sessionId: track?.sessionId, //短剧付费墙开卡:金币余额支付这条也要带归因,否则只有第三方充值那条统计得到 mediaId: track?.mediaId, @@ -307,7 +341,8 @@ class _OnlinePayPageState extends State { } ///代充支付:拼装代充参数后跳 H5 收银台 - Future _payByDc(bool isVip, RchgType payType, DCModel? dcModel, int? money) async { + Future _payByDc( + bool isVip, RchgType payType, DCModel? dcModel, int? money) async { // daichong 是所有会员卡/金币档位共用的同一实例,下面的改写只为拼给 H5,必须在副本上做: // 原地改会把 payInfos 截成单条(支付方式列表变短→下标越界)、ordUrl 被重复拼 host final dc = dcModel!.clone(); @@ -341,7 +376,8 @@ class _OnlinePayPageState extends State { //bt64 final data = base64Encode(utf8.encode(json.encode(dc))); if (isVip) VipCardAnalyticsSession.markPurchaseOnActiveSessions(); - Get.to(H5Page(title: "代理充值", url: "$channel/?data=$data&token=$token"), opaque: false); + Get.to(H5Page(title: "代理充值", url: "$channel/?data=$data&token=$token"), + opaque: false); } } @@ -378,7 +414,9 @@ class _ChoseCouponViewState extends State { refreshCtr?.refreshCompleted(); _dataSource.clear(); } - _dataSource.length < 20 ? refreshCtr?.loadNoData() : refreshCtr?.loadComplete(); + _dataSource.length < 20 + ? refreshCtr?.loadNoData() + : refreshCtr?.loadComplete(); _dataSource.addAll(res); page += 1; setState(() {}); @@ -411,7 +449,10 @@ class _ChoseCouponViewState extends State { const Center( child: Text( '选择加赠券', - style: TextStyle(color: Colors.black, fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.w600), ), ) ], @@ -443,7 +484,9 @@ class _ChoseCouponViewState extends State { padding: const EdgeInsets.only(left: 24, right: 11), alignment: Alignment.centerLeft, width: double.infinity, - decoration: BoxDecoration(color: Color(0xffff891c).withValues(alpha: .4), borderRadius: BorderRadius.circular(4)), + decoration: BoxDecoration( + color: Color(0xffff891c).withValues(alpha: .4), + borderRadius: BorderRadius.circular(4)), child: Row( children: [ //券面额 @@ -460,13 +503,18 @@ class _ChoseCouponViewState extends State { 4.sizeBoxW, Text( '${model.price ?? 0}', - style: TextStyle(color: Colors.black, fontSize: 24, fontWeight: FontWeight.w500, height: 33 / 24), + style: TextStyle( + color: Colors.black, + fontSize: 24, + fontWeight: FontWeight.w500, + height: 33 / 24), ) ], ), Text( '充值加送金币', - style: TextStyle(color: Colors.black.withValues(alpha: .6), fontSize: 12), + style: TextStyle( + color: Colors.black.withValues(alpha: .6), fontSize: 12), ) ], ), @@ -476,10 +524,11 @@ class _ChoseCouponViewState extends State { height: 45, child: DecoratedBox( decoration: BoxDecoration( - gradient: LinearGradient( - colors: [Colors.black.withValues(alpha: 0), Colors.black.withValues(alpha: .5), Colors.black.withValues(alpha: 0)], - begin: Alignment.topCenter, - end: Alignment.bottomCenter), + gradient: LinearGradient(colors: [ + Colors.black.withValues(alpha: 0), + Colors.black.withValues(alpha: .5), + Colors.black.withValues(alpha: 0) + ], begin: Alignment.topCenter, end: Alignment.bottomCenter), ), ), ), @@ -512,11 +561,16 @@ class _ChoseCouponViewState extends State { GestureDetector( onTap: () => widget.onSelect(model), child: Container( - decoration: BoxDecoration(color: Color(0xffF68216), borderRadius: BorderRadius.circular(22)), + decoration: BoxDecoration( + color: Color(0xffF68216), + borderRadius: BorderRadius.circular(22)), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5), child: Text( '立即使用', - style: TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.w500), ), ), ) diff --git a/lib/hj_page/mine/mine_vip/pay_success_alert.dart b/lib/hj_page/mine/mine_vip/pay_success_alert.dart index ef3fc09..a486c8f 100644 --- a/lib/hj_page/mine/mine_vip/pay_success_alert.dart +++ b/lib/hj_page/mine/mine_vip/pay_success_alert.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; import '../../../tools_base/global_store/store.dart'; @@ -43,7 +43,8 @@ class PaySuccessAlert extends StatelessWidget { ), ), 24.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { globalStore.updateUserInfo(); Get.back(); diff --git a/lib/hj_page/mine/mine_vip/vip_card_analytics.dart b/lib/hj_page/mine/mine_vip/vip_card_analytics.dart index 1699dcc..fe48044 100644 --- a/lib/hj_page/mine/mine_vip/vip_card_analytics.dart +++ b/lib/hj_page/mine/mine_vip/vip_card_analytics.dart @@ -1,10 +1,10 @@ import 'package:flutter/scheduler.dart'; -import 'package:hgmj/hj_model/mine/vip_card_analytics_event.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/vip_product_manager.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/vip_support_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/mine/vip_card_analytics_event.dart'; +import 'package:wydj/hj_page/mine/mine_vip/vip_product_manager.dart'; +import 'package:wydj/hj_page/mine/mine_vip/vip_support_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:uuid/uuid.dart'; /// VIP 卡片统计:一次进入会员卡页/购买弹窗对应一个 session,关闭时按是否下单上报。 @@ -33,10 +33,12 @@ class VipCardAnalyticsSession { bool _purchased = false; bool _closed = false; String? _lastImpressedProductId; + /// 同一帧内 jumpToPage + onPageChanged 去重 String? _pendingImpressionProductId; - static String _nowUtc() => DateTimeUtil.format2utc(DateTime.now().toUtc()) ?? ''; + static String _nowUtc() => + DateTimeUtil.format2utc(DateTime.now().toUtc()) ?? ''; /// DISABLED / 无实验 ID:不上报(空 experimentId 会参数错误) bool get _canReport { @@ -82,9 +84,11 @@ class VipCardAnalyticsSession { } /// 套餐曝光:选中 / 默认选中各算一次;同 product 连续重复不重复报 - void reportProductImpression(VipProductModel? product, {bool afterPaint = false}) { + void reportProductImpression(VipProductModel? product, + {bool afterPaint = false}) { final productId = product?.productID; - if (productId == null || productId.isEmpty || _closed || !_canReport) return; + if (productId == null || productId.isEmpty || _closed || !_canReport) + return; if (_lastImpressedProductId == productId) return; void doReport() { @@ -128,7 +132,8 @@ class VipCardAnalyticsSession { _closed = true; _active.remove(this); if (_purchased) { - debugLog('VipCardAnalytics', 'skip CLOSE_WITHOUT_PURCHASE: already purchased'); + debugLog( + 'VipCardAnalytics', 'skip CLOSE_WITHOUT_PURCHASE: already purchased'); return; } if (!_canReport) { diff --git a/lib/hj_page/mine/mine_vip/vip_card_item.dart b/lib/hj_page/mine/mine_vip/vip_card_item.dart index 2e60ba8..a45b4b8 100644 --- a/lib/hj_page/mine/mine_vip/vip_card_item.dart +++ b/lib/hj_page/mine/mine_vip/vip_card_item.dart @@ -3,9 +3,9 @@ import 'dart:math' as math; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../main_page/provider/msg_provider.dart'; import 'vip_product_manager.dart'; @@ -17,7 +17,8 @@ class VipCardItem extends StatefulWidget { final bool isSelect; final VipProductModel model; - const VipCardItem(this.model, {super.key, this.callback, this.isSelect = false}); + const VipCardItem(this.model, + {super.key, this.callback, this.isSelect = false}); @override State createState() { @@ -57,7 +58,11 @@ class _VipCardItemState extends State { if (!_isNewerOfferCard) return null; final layered = MineMsgProvider().countdownConfig; if (layered != null) { - return (hour: layered.discountHour, min: layered.discountMin, sec: layered.discountSec); + return ( + hour: layered.discountHour, + min: layered.discountMin, + sec: layered.discountSec + ); } final hours = widget.model.showCountdownTime ?? 0; if (hours <= 0) return null; @@ -106,10 +111,9 @@ class _VipCardItemState extends State { } } - String get _title => - (widget.model.newName?.trim().isNotEmpty == true) - ? widget.model.newName!.trim() - : (widget.model.productName ?? ''); + String get _title => (widget.model.newName?.trim().isNotEmpty == true) + ? widget.model.newName!.trim() + : (widget.model.productName ?? ''); @override Widget build(BuildContext context) { @@ -223,7 +227,10 @@ class _VipCardItemState extends State { ? const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, - colors: [Color(0xffFBF0CD), Color(0xffE5B75D)], + colors: [ + Color(0xffFBF0CD), + Color(0xffE5B75D) + ], ) : null, ), @@ -273,8 +280,10 @@ class _VipCardItemState extends State { Widget _buildBCardBody(bool selected) { final titleColor = selected ? const Color(0xff3B2B0E) : Color(0xffF6EEDC); - final priceColor = selected ? const Color(0xff3B2B0E) : const Color(0xffF6EEDC); - final originColor = selected ? const Color(0xff6C644F) : const Color(0xff9A927C); + final priceColor = + selected ? const Color(0xff3B2B0E) : const Color(0xffF6EEDC); + final originColor = + selected ? const Color(0xff6C644F) : const Color(0xff9A927C); final showOrigin = widget.model.originalPriceUI > 0 && widget.model.originalPriceUI != widget.model.discountedPriceUI; @@ -368,7 +377,10 @@ class _VipCardItemState extends State { 4.sizeBoxW, const Text( '结束', - style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w600), ), ], ), @@ -437,8 +449,10 @@ class _VipCardItemState extends State { fg = const Color(0xFFE8C078); border = Border.all(color: const Color(0xFFE8C078), width: 0.8); } else { - bg = apiBg ?? (isMostPopular ? const Color(0xCC1A1A1A) : const Color(0xffE1351F)); - fg = apiFg ?? (isMostPopular ? const Color(0xFFE8C078) : const Color(0xE5FFFFFF)); + bg = apiBg ?? + (isMostPopular ? const Color(0xCC1A1A1A) : const Color(0xffE1351F)); + fg = apiFg ?? + (isMostPopular ? const Color(0xFFE8C078) : const Color(0xE5FFFFFF)); border = (apiBg == null && isMostPopular) ? Border.all(color: const Color(0xFFE8C078), width: 0.8) : null; @@ -508,20 +522,29 @@ class _VipCardItemState extends State { ), child: Text( value, - style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.w500, height: 1.0), + style: const TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.w500, + height: 1.0), ), ); } Widget _timerColon() => const Padding( padding: EdgeInsets.symmetric(horizontal: 3), - child: Text(':', style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w600)), + child: Text(':', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w600)), ); } class VipProductPrivilegeItem extends StatelessWidget { final NewPrivilege? model; final bool isShowOnePrivilege; + /// true:旧版白字圆图标样式(会员中心 A / DISABLED) final bool classic; @@ -547,7 +570,10 @@ class VipProductPrivilegeItem extends StatelessWidget { Text( model?.privilegeName ?? '', maxLines: 1, - style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Colors.white.withValues(alpha: .9)), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: Colors.white.withValues(alpha: .9)), ), if (!isShowOnePrivilege) ...[ 4.sizeBoxH, @@ -591,7 +617,8 @@ class VipProductPrivilegeItem extends StatelessWidget { model?.privilegeName ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Colors.white), + style: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w500, color: Colors.white), ), ), if (!isShowOnePrivilege) ...[ @@ -750,7 +777,11 @@ class VipCorePrivilegeCard extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - NetworkImageLoader(imageUrl: model?.img ?? '', width: 22, height: 22, borderRadius: 0), + NetworkImageLoader( + imageUrl: model?.img ?? '', + width: 22, + height: 22, + borderRadius: 0), 5.sizeBoxH, ShaderMask( shaderCallback: (bounds) => const LinearGradient( @@ -765,7 +796,10 @@ class VipCorePrivilegeCard extends StatelessWidget { textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w500), ), ), 3.sizeBoxH, @@ -807,7 +841,8 @@ class VipCorePrivilegeCard extends StatelessWidget { raw, maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Color(0xff9A927C), fontSize: 11, height: 1.2), + style: + const TextStyle(color: Color(0xff9A927C), fontSize: 11, height: 1.2), ); } } diff --git a/lib/hj_page/mine/mine_vip/vip_pay_button.dart b/lib/hj_page/mine/mine_vip/vip_pay_button.dart index c28853e..f35d9b3 100644 --- a/lib/hj_page/mine/mine_vip/vip_pay_button.dart +++ b/lib/hj_page/mine/mine_vip/vip_pay_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_alert.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_alert.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; import 'mine_charge_vip_logic.dart'; import 'vip_support_model.dart'; @@ -20,7 +20,8 @@ class VipPayButton extends StatelessWidget { //预售首付或非升级预售 → 预售按钮(透传会员中心 sessionId / 实验字段) if (product?.isPreSale == true && product?.isUpgrade == false) { return PreSaleActivityButton(onTap: () async { - await PreSaleProvider().startPay(product!, orderTrack: logic.buildOrderTrack()); + await PreSaleProvider() + .startPay(product!, orderTrack: logic.buildOrderTrack()); logic.update(); }); } @@ -68,7 +69,8 @@ class VipPayButton extends StatelessWidget { ), child: Text( _payText, - style: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), ), ), ); diff --git a/lib/hj_page/mine/mine_vip/vip_product_manager.dart b/lib/hj_page/mine/mine_vip/vip_product_manager.dart index 6c9625a..3839dd2 100644 --- a/lib/hj_page/mine/mine_vip/vip_product_manager.dart +++ b/lib/hj_page/mine/mine_vip/vip_product_manager.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../hj_page/main_page/provider/msg_provider.dart'; import '../../../hj_page/pre_sale/pre_sale_provider.dart'; @@ -24,7 +24,9 @@ class VipProductManager with ChangeNotifier { /// 空串必须当「未指定」:分层/实验/短剧默认卡没配时下发的都是空串, /// 不拦会跟 productID 为空的脏数据撞上 VipProductModel? _pick(List list, String? id) => - (id ?? '').isEmpty ? null : list.firstWhereOrNull((e) => e.productID == id); + (id ?? '').isEmpty + ? null + : list.firstWhereOrNull((e) => e.productID == id); // ===== 会员卡数据 ===== @@ -69,7 +71,8 @@ class VipProductManager with ChangeNotifier { } /// 角标配色:按套餐 badgeType 匹配皮肤配置 - VipBadgeStyle? badgeStyleFor(String? badgeType) => _uiConfig?.styleFor(badgeType); + VipBadgeStyle? badgeStyleFor(String? badgeType) => + _uiConfig?.styleFor(badgeType); // ===== 会员卡:请求 / 组装 ===== @@ -143,7 +146,9 @@ class VipProductManager with ChangeNotifier { return _pick(vipCards, vipID) ?? _pick(vipCards, MineMsgProvider().payTier?.config?.vipCard) ?? _pick(vipCards, _abCardId) ?? - (globalStore.meInfo?.isUpgrade == true ? _cheapestUpgrade(vipCards) : null) ?? + (globalStore.meInfo?.isUpgrade == true + ? _cheapestUpgrade(vipCards) + : null) ?? _pick(vipCards, current?.productID) ?? // 二次刷新时保留当前选中 vipCards.first; } @@ -179,7 +184,9 @@ class VipProductManager with ChangeNotifier { final card = _pick(list, cardId) ?? _pick(list, MineMsgProvider().payTier?.config?.vipCard) ?? _pick(list, _abCardId) ?? - (globalStore.meInfo?.isUpgrade == true ? _cheapestUpgrade(list) : null) ?? + (globalStore.meInfo?.isUpgrade == true + ? _cheapestUpgrade(list) + : null) ?? list.first; if (card.rchgTypeUI.isEmpty) { showToast("未配置支付方式,请联系客服"); @@ -199,8 +206,12 @@ class VipProductManager with ChangeNotifier { contentId: base.contentId, checkoutContextId: base.checkoutContextId, // DISABLED:正常下单但不传实验字段 - experimentId: isExperimentActive ? (base.experimentId ?? card.experimentId ?? experimentId) : null, - experimentVariant: isExperimentActive ? (base.experimentVariant ?? card.variant ?? variant) : null, + experimentId: isExperimentActive + ? (base.experimentId ?? card.experimentId ?? experimentId) + : null, + experimentVariant: isExperimentActive + ? (base.experimentVariant ?? card.variant ?? variant) + : null, ); analytics?.reportPageViewAfterPaint(); analytics?.reportProductImpression(card, afterPaint: true); @@ -229,7 +240,9 @@ class VipProductManager with ChangeNotifier { /// 升级比价用价:预售卡用实际待付(已付首款=尾款 balanceAmount / 未付=定金 advanceAmount),普通卡用 discountedPrice(对齐 mrhs) int _upgradePrice(VipProductModel card) { if (card.isPreSale) { - return PreSaleProvider().isPayFirst ? (card.balanceAmount ?? 0) : (card.advanceAmount ?? 0); + return PreSaleProvider().isPayFirst + ? (card.balanceAmount ?? 0) + : (card.advanceAmount ?? 0); } return card.discountedPrice ?? 0; } diff --git a/lib/hj_page/mine/mine_vip/vip_support_model.dart b/lib/hj_page/mine/mine_vip/vip_support_model.dart index 1c25fa4..2fe9c38 100644 --- a/lib/hj_page/mine/mine_vip/vip_support_model.dart +++ b/lib/hj_page/mine/mine_vip/vip_support_model.dart @@ -1,6 +1,6 @@ //会员支持model -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; import '../../../hj_model/mine/exchange/dc_model.dart'; @@ -71,16 +71,22 @@ class VipSupportModel { bool? isNewUser; List? list; List? upgradeableVipCardList; + /// A/B 实验状态:ACTIVE / DISABLED String? experimentStatus; + /// A/B 实验:实验 ID(下单时原样回传;DISABLED 时后端不返回) String? experimentId; + /// A/B 实验:分组 A / B(下单时原样回传) String? variant; + /// A/B 实验:默认选中卡 ID String? defaultProductId; + /// 皮肤 key,如 vip-card-skin-b(视觉皮肤标识,UI 分支仍以 variant 为准) String? skinKey; + /// 皮肤 UI 配置(背景图 / 角标样式表) VipUiConfig? uiConfig; @@ -102,7 +108,8 @@ class VipSupportModel { }); VipSupportModel.fromJson(Map? json) { - daichong = json?['daichong'] != null ? DCModel.fromJson(json?['daichong']) : null; + daichong = + json?['daichong'] != null ? DCModel.fromJson(json?['daichong']) : null; if (json?['integralList'] != null) { integralList = []; json?['integralList'].forEach((v) { @@ -115,7 +122,9 @@ class VipSupportModel { variant = json?['variant']?.toString(); defaultProductId = json?['defaultProductId']?.toString(); skinKey = json?['skinKey']?.toString(); - uiConfig = json?['uiConfig'] != null ? VipUiConfig.fromJson(json?['uiConfig']) : null; + uiConfig = json?['uiConfig'] != null + ? VipUiConfig.fromJson(json?['uiConfig']) + : null; /// 升级卡 upgradeableVipCardList = (json?['upgradeableVipCardList'] as List?) @@ -124,7 +133,8 @@ class VipSupportModel { if (json?['list'] != null) { list = []; json?['list'].forEach((v) { - VipProductListModel vipModel = VipProductListModel.fromJson(v, daichong); + VipProductListModel vipModel = + VipProductListModel.fromJson(v, daichong); list!.add(vipModel); }); } @@ -182,7 +192,14 @@ class IntegralList { int? type; String? bgImg; - IntegralList({this.desc, this.duration, this.id, this.img, this.name, this.price, this.type}); + IntegralList( + {this.desc, + this.duration, + this.id, + this.img, + this.name, + this.price, + this.type}); IntegralList.fromJson(Map json) { desc = json['desc']; @@ -214,7 +231,8 @@ class VipProductListModel { String? positionID; int? showType; - VipProductListModel({this.list, this.position, this.positionID, this.showType}); + VipProductListModel( + {this.list, this.position, this.positionID, this.showType}); VipProductListModel.fromJson(Map json, DCModel? daichong) { if (json['list'] != null) { @@ -244,8 +262,10 @@ class VipProductListModel { class VipProductModel { String? actionDesc; + /// 角标类型,如 MOST_POPULAR String? badgeType; + /// 角标文案,如「最受欢迎」 String? badgeText; int? aiUndressCount; @@ -522,12 +542,12 @@ class VipProductModel { vipCardDesc = json['vipCardDesc']; vipLevel = json['vipLevel']; isPreSale = false; - isUpgrade= json['isUpgrade']; - currentVipName= json['currentVipName']; - currentVipPrice= "${json['currentVipPrice']}"; - purchasePrice= json['purchasePrice']; - advanceAmount= json['advanceAmount']; - balanceAmount= json['balanceAmount']; + isUpgrade = json['isUpgrade']; + currentVipName = json['currentVipName']; + currentVipPrice = "${json['currentVipPrice']}"; + purchasePrice = json['purchasePrice']; + advanceAmount = json['advanceAmount']; + balanceAmount = json['balanceAmount']; } //是否有折扣 @@ -598,12 +618,12 @@ class VipProductModel { data['videoDiscount'] = videoDiscount; data['vipCardDesc'] = vipCardDesc; data['vipLevel'] = vipLevel; - data['isUpgrade']= isUpgrade; - data['currentVipName']= currentVipName; - data['currentVipPrice']= currentVipPrice; - data['purchasePrice']= purchasePrice; - data['advanceAmount']= advanceAmount; - data['balanceAmount']= balanceAmount; + data['isUpgrade'] = isUpgrade; + data['currentVipName'] = currentVipName; + data['currentVipPrice'] = currentVipPrice; + data['purchasePrice'] = purchasePrice; + data['advanceAmount'] = advanceAmount; + data['balanceAmount'] = balanceAmount; return data; } } @@ -667,7 +687,8 @@ class RchgType { bool? isOfficial = false; // 官方推荐 int? payMethod; - RchgType({this.channel, this.incTax, this.incrAmount, this.type, this.typeName}); + RchgType( + {this.channel, this.incTax, this.incrAmount, this.type, this.typeName}); RchgType.fromJson(Map json) { channel = json['channel']; diff --git a/lib/hj_page/mine/mine_vip/vip_ui_kit.dart b/lib/hj_page/mine/mine_vip/vip_ui_kit.dart index 72c734c..e6f9a37 100644 --- a/lib/hj_page/mine/mine_vip/vip_ui_kit.dart +++ b/lib/hj_page/mine/mine_vip/vip_ui_kit.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; /// VIP 金色标题渐变 #F5E7BC → #DCAD55 /// 会员中心 / 购买弹窗 / 权益标题等金色文案共用,调色只改此处 @@ -56,6 +56,7 @@ class VipMoreSectionTitleImage extends StatelessWidget { /// 区块标题:两侧「金渐变横线 + 菱形」+ 居中金渐变文字(会员中心 B / 购买弹窗共用) class VipSectionTitle extends StatelessWidget { final String text; + /// true:旧版橙色标题(会员中心 A / DISABLED) final bool classic; @@ -71,7 +72,11 @@ class VipSectionTitle extends StatelessWidget { children: [ _classicDeco(lineFirst: true), 8.sizeBoxW, - Text(text, style: const TextStyle(color: _classicOrange, fontSize: 18, fontWeight: FontWeight.w600)), + Text(text, + style: const TextStyle( + color: _classicOrange, + fontSize: 18, + fontWeight: FontWeight.w600)), 8.sizeBoxW, _classicDeco(lineFirst: false), ], @@ -85,7 +90,8 @@ class VipSectionTitle extends StatelessWidget { VipGradientMask( child: Text( text, - style: const TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600), ), ), 8.sizeBoxW, @@ -109,7 +115,8 @@ class VipSectionTitle extends StatelessWidget { // 标题两侧装饰:金渐变细横线 + 菱形(lineFirst=true 横线在外侧,false 镜像) Widget _buildDeco({required bool lineFirst}) { const line = VipGradientMask( - child: SizedBox(width: 40, height: 0.5, child: ColoredBox(color: Colors.white)), + child: SizedBox( + width: 40, height: 0.5, child: ColoredBox(color: Colors.white)), ); return Row( mainAxisSize: MainAxisSize.min, @@ -121,7 +128,8 @@ class VipSectionTitle extends StatelessWidget { Widget get _diamond => Transform.rotate( angle: 0.7853981633974483, child: const VipGradientMask( - child: SizedBox(width: 5, height: 5, child: ColoredBox(color: Colors.white)), + child: SizedBox( + width: 5, height: 5, child: ColoredBox(color: Colors.white)), ), ); } diff --git a/lib/hj_page/mine/mine_vip/widgets/coin_item.dart b/lib/hj_page/mine/mine_vip/widgets/coin_item.dart index 0317194..2b6b663 100644 --- a/lib/hj_page/mine/mine_vip/widgets/coin_item.dart +++ b/lib/hj_page/mine/mine_vip/widgets/coin_item.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/mine/exchange/recharge_type_list_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/mine/exchange/recharge_type_list_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; // 金币充值档位卡片 class CoinItem extends StatelessWidget { @@ -24,7 +24,9 @@ class CoinItem extends StatelessWidget { decoration: BoxDecoration( color: Colors.white.withValues(alpha: .1), borderRadius: BorderRadius.circular(8), - border: isSelected ? Border.all(width: 1, color: const Color(0xffF9C142)) : null, + border: isSelected + ? Border.all(width: 1, color: const Color(0xffF9C142)) + : null, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -33,12 +35,14 @@ class CoinItem extends StatelessWidget { 4.sizeBoxH, Text( "${model.amount}金币", - style: const TextStyle(color: Color(0xFF656565), fontSize: 14), + style: + const TextStyle(color: Color(0xFF656565), fontSize: 14), ), 4.sizeBoxH, Text( '¥${model.moneyYuan}', - style: const TextStyle(color: Color(0xffF9C142), fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xffF9C142), fontWeight: FontWeight.w500), ), 4.sizeBoxH, ], @@ -53,7 +57,9 @@ class CoinItem extends StatelessWidget { height: 20, padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), decoration: const BoxDecoration( - borderRadius: BorderRadius.only(topLeft: Radius.circular(12), bottomRight: Radius.circular(12)), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12), + bottomRight: Radius.circular(12)), color: Color(0xffFFD460), ), child: Text( diff --git a/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart b/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart index bd623f1..1eac6de 100644 --- a/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart +++ b/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../make_money/mine_withdrawal_record_page.dart'; import '../mine_charge_coin_logic.dart'; @@ -21,7 +21,10 @@ class CoinPayBottomSheet extends StatelessWidget { /// 下单埋点上下文(短剧付费墙充金币要带剧/集/付费墙上下文) final PayOrderTrackInfo? orderTrack; - const CoinPayBottomSheet({super.key, this.sourcePage = PaySourcePage.videoBottomSheet, this.orderTrack}); + const CoinPayBottomSheet( + {super.key, + this.sourcePage = PaySourcePage.videoBottomSheet, + this.orderTrack}); /// 弹窗展示中,防连点叠多个 bottomSheet static bool _isShowing = false; @@ -166,7 +169,8 @@ class CoinPayBottomSheet extends StatelessWidget { children: [ const Text( '我的金币余额', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), ), 8.sizeBoxH, Row( @@ -191,7 +195,8 @@ class CoinPayBottomSheet extends StatelessWidget { const Spacer(), InkWell( enableFeedback: false, - onTap: () => Get.to(RecordsPage(RecordType.bill), opaque: false), + onTap: () => + Get.to(RecordsPage(RecordType.bill), opaque: false), child: Container( alignment: Alignment.center, height: 30, diff --git a/lib/hj_page/mine/more_question/feedback_question_category_view.dart b/lib/hj_page/mine/more_question/feedback_question_category_view.dart index f6376c2..4f741e4 100644 --- a/lib/hj_page/mine/more_question/feedback_question_category_view.dart +++ b/lib/hj_page/mine/more_question/feedback_question_category_view.dart @@ -1,16 +1,27 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_utils/screen.dart'; class FeedbackQuestionCategoryView extends StatefulWidget { final Function(String category)? choseCategory; const FeedbackQuestionCategoryView({super.key, this.choseCategory}); @override - State createState() => _FeedbackQuestionCategoryViewState(); + State createState() => + _FeedbackQuestionCategoryViewState(); } -class _FeedbackQuestionCategoryViewState extends State { - final dataSource = ['账号问题', '影视资源', 'APP体验', '播放失败', '播放卡顿', '分类有误', '充值问题', '其他']; +class _FeedbackQuestionCategoryViewState + extends State { + final dataSource = [ + '账号问题', + '影视资源', + 'APP体验', + '播放失败', + '播放卡顿', + '分类有误', + '充值问题', + '其他' + ]; String? selectCategory; @override @@ -26,7 +37,10 @@ class _FeedbackQuestionCategoryViewState extends State createState() => _InfomationInputViewState(); @@ -76,7 +95,10 @@ class _InfomationInputViewState extends State { width: 90, child: Text( widget.title, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 14, + fontWeight: FontWeight.w500), ), ), Expanded( @@ -88,7 +110,8 @@ class _InfomationInputViewState extends State { decoration: InputDecoration( border: InputBorder.none, hintText: widget.hint, - hintStyle: TextStyle(color: Color(0xff525252), fontSize: 12), + hintStyle: + TextStyle(color: Color(0xff525252), fontSize: 12), counterText: '', contentPadding: EdgeInsets.zero, isDense: true), diff --git a/lib/hj_page/mine/more_question/mine_feedback_logic.dart b/lib/hj_page/mine/more_question/mine_feedback_logic.dart index 14c6dea..3ab1375 100644 --- a/lib/hj_page/mine/more_question/mine_feedback_logic.dart +++ b/lib/hj_page/mine/more_question/mine_feedback_logic.dart @@ -2,10 +2,10 @@ import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/file_upload/file_upload_tool.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/file_upload/file_upload_tool.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; class MineFeedbackLogic extends GetxController { /// 问题描述 diff --git a/lib/hj_page/mine/more_question/mine_feedback_page.dart b/lib/hj_page/mine/more_question/mine_feedback_page.dart index b79ba23..7a3cf88 100644 --- a/lib/hj_page/mine/more_question/mine_feedback_page.dart +++ b/lib/hj_page/mine/more_question/mine_feedback_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'feedback_question_category_view.dart'; import 'mine_feedback_logic.dart'; @@ -19,7 +19,8 @@ class MineFeedbackPage extends StatelessWidget { appBar: AppBar( title: Text('意见反馈'), actions: [ - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.to(() => MineQAPage()), child: Text( 'Q&A', @@ -37,7 +38,8 @@ class MineFeedbackPage extends StatelessWidget { children: [ Expanded( child: SingleChildScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, child: Padding( padding: EdgeInsets.only(left: 10, right: 10, top: 12), child: Column( @@ -58,12 +60,16 @@ class MineFeedbackPage extends StatelessWidget { 24.sizeBoxH, Text( '问题描述(必填)', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 18, + fontWeight: FontWeight.w600), ), 12.sizeBoxH, Container( constraints: BoxConstraints(minHeight: 160), - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 11), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 11), decoration: BoxDecoration( color: Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(8), @@ -72,13 +78,16 @@ class MineFeedbackPage extends StatelessWidget { children: [ TextField( maxLines: 8, - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 12), maxLength: 300, controller: controller.inputFeedback, decoration: InputDecoration( border: InputBorder.none, hintText: '请简单描述一下您遇到的问题...', - hintStyle: TextStyle(color: Color(0xff525252), fontSize: 12), + hintStyle: TextStyle( + color: Color(0xff525252), fontSize: 12), counterStyle: TextStyle(fontSize: 8), counter: SizedBox(), contentPadding: EdgeInsets.zero, @@ -93,7 +102,8 @@ class MineFeedbackPage extends StatelessWidget { builder: (_, value, __) => Text( '${value.text.length}/300', style: TextStyle( - color: Colors.white.withValues(alpha: 0.5), + color: + Colors.white.withValues(alpha: 0.5), fontSize: 12, ), ), @@ -103,14 +113,21 @@ class MineFeedbackPage extends StatelessWidget { ), ), 14.sizeBoxH, - InfomationInputView(controller.areaFeedback, title: '所在地区', hint: '例:浙江杭州'), - InfomationInputView(controller.deviceFeedback, title: '设备信息', hint: '例:苹果14'), - InfomationInputView(controller.netFeedback, title: '网络运营商', hint: '电信/联通/移动'), - InfomationInputView(controller.contactFeedback, title: '联系方式', hint: 'QQ/微信/邮箱等'), + InfomationInputView(controller.areaFeedback, + title: '所在地区', hint: '例:浙江杭州'), + InfomationInputView(controller.deviceFeedback, + title: '设备信息', hint: '例:苹果14'), + InfomationInputView(controller.netFeedback, + title: '网络运营商', hint: '电信/联通/移动'), + InfomationInputView(controller.contactFeedback, + title: '联系方式', hint: 'QQ/微信/邮箱等'), 24.sizeBoxH, Text( '上传图片', - style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 18, fontWeight: FontWeight.w700), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.9), + fontSize: 18, + fontWeight: FontWeight.w700), ), 12.sizeBoxH, PhotoManageView( @@ -119,7 +136,8 @@ class MineFeedbackPage extends StatelessWidget { 24.sizeBoxH, Text( '以方便我们给您回复,有效的改进建议,有惊喜赠送哟!', - style: TextStyle(color: Color(0xff525252), fontSize: 12), + style: + TextStyle(color: Color(0xff525252), fontSize: 12), ), 60.sizeBoxH, ], @@ -138,7 +156,10 @@ class MineFeedbackPage extends StatelessWidget { ), child: Text( '提交意见', - style: TextStyle(color: const Color(0xff1f2029), fontSize: 16, fontWeight: FontWeight.w600), + style: TextStyle( + color: const Color(0xff1f2029), + fontSize: 16, + fontWeight: FontWeight.w600), ), ), ), diff --git a/lib/hj_page/mine/more_question/mine_qa_page.dart b/lib/hj_page/mine/more_question/mine_qa_page.dart index 0b367bc..5390d2a 100644 --- a/lib/hj_page/mine/more_question/mine_qa_page.dart +++ b/lib/hj_page/mine/more_question/mine_qa_page.dart @@ -3,14 +3,13 @@ import 'dart:math'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; ///帮助反馈 class MineQAPage extends StatefulWidget { - const MineQAPage({super.key}); @override State createState() => _MineQAPageState(); @@ -22,7 +21,11 @@ class _MineQAPageState extends State { final String url = Address.groundUrl; late final questionList = [ - {"question": "描述文件安装失败?", "answer": "若提示【新的MDM有效负载与旧的有效负载不匹配】,请移除移动设备管理步骤:【设置-通用-设备管理-移动设备管理-移除管理】", 'isOpen': true}, + { + "question": "描述文件安装失败?", + "answer": "若提示【新的MDM有效负载与旧的有效负载不匹配】,请移除移动设备管理步骤:【设置-通用-设备管理-移动设备管理-移除管理】", + 'isOpen': true + }, { "question": "怎么找回账号?", "answer": @@ -35,8 +38,18 @@ class _MineQAPageState extends State { "1.因超时支付无法到账,请重新发起。\n2.每天发起支付不能超过5次,连续发起且未支付,账号可能被加入黑名单。\n3.支付通道在夜间比较忙碌,尝试多次发起,后台会为您自动切换不同支付通道。\n4.若充值成功,用户权益通常会在数分钟内到账,请刷新APP或重启。", 'isOpen': false }, - {"question": "收到手机报毒提醒?", "answer": "本平台有主要收益为广告赞助,且保证APP安全无毒,因平台主要展示内容为色情属于特殊行业,某些杀毒软件会误报毒提醒,如遇此类提醒请忽略继续使用。", 'isOpen': false}, - {"question": "联系方式?", "answer": "商务合作TG: $tg\n${(email != null && email!.isNotEmpty) ? '官方邮箱: $email\n' : ''}永久下载地址: $url", 'isOpen': false}, + { + "question": "收到手机报毒提醒?", + "answer": + "本平台有主要收益为广告赞助,且保证APP安全无毒,因平台主要展示内容为色情属于特殊行业,某些杀毒软件会误报毒提醒,如遇此类提醒请忽略继续使用。", + 'isOpen': false + }, + { + "question": "联系方式?", + "answer": + "商务合作TG: $tg\n${(email != null && email!.isNotEmpty) ? '官方邮箱: $email\n' : ''}永久下载地址: $url", + 'isOpen': false + }, ]; @override @@ -63,7 +76,8 @@ class _MineQAPageState extends State { Widget _getItem(int index) { final item = questionList[index]; final isOpen = item["isOpen"] as bool; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () { item["isOpen"] = !isOpen; setState(() {}); diff --git a/lib/hj_page/mine/more_question/photo_manage_view.dart b/lib/hj_page/mine/more_question/photo_manage_view.dart index e186c55..f68ebec 100644 --- a/lib/hj_page/mine/more_question/photo_manage_view.dart +++ b/lib/hj_page/mine/more_question/photo_manage_view.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:image_pickers/image_pickers.dart'; -import 'package:hgmj/tools_base/widget/add_media_source_button.dart'; +import 'package:wydj/tools_base/widget/add_media_source_button.dart'; class PhotoManageView extends StatefulWidget { final Function(List resources)? resourceOnchanged; diff --git a/lib/hj_page/mine/welfare/lou_feng_ad_logic.dart b/lib/hj_page/mine/welfare/lou_feng_ad_logic.dart index 2ddd951..81ab948 100644 --- a/lib/hj_page/mine/welfare/lou_feng_ad_logic.dart +++ b/lib/hj_page/mine/welfare/lou_feng_ad_logic.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; import '../../../hj_model/mine/happy/happy_model.dart'; import '../../../hj_model/splash/ads_model.dart'; /// 应用推荐页:按分类拉广告位数据,每个分类一个 tab -class LouFengAdLogic extends GetxController with GetSingleTickerProviderStateMixin { +class LouFengAdLogic extends GetxController + with GetSingleTickerProviderStateMixin { bool isLoading = true; HappyModel? model; // null 表示加载失败,页面展示重试 @@ -38,11 +39,17 @@ class LouFengAdLogic extends GetxController with GetSingleTickerProviderStateMix /// 「应用」固定展示,其余分类有 banner 或有应用才建 tab void _buildTabs() { - _add('应用', AdTabConfig( - bannerAds: _banners(1), - hengAds: model?.hengApp != null ? AdGroup(items: model?.hengApp, title: '官方推荐') : null, - shuAds: model?.shuApp != null ? AdGroup(items: model?.shuApp, title: '热门应用') : null, - )); + _add( + '应用', + AdTabConfig( + bannerAds: _banners(1), + hengAds: model?.hengApp != null + ? AdGroup(items: model?.hengApp, title: '官方推荐') + : null, + shuAds: model?.shuApp != null + ? AdGroup(items: model?.shuApp, title: '热门应用') + : null, + )); final others = [ ('炮台', 3, model?.ypApp), @@ -53,10 +60,12 @@ class LouFengAdLogic extends GetxController with GetSingleTickerProviderStateMix for (final (name, moduleType, apps) in others) { final banners = _banners(moduleType); if (banners.isEmpty && (apps?.isEmpty ?? true)) continue; - _add(name, AdTabConfig( - bannerAds: banners, - shuAds: apps != null ? AdGroup(items: apps, title: '热门推荐') : null, - )); + _add( + name, + AdTabConfig( + bannerAds: banners, + shuAds: apps != null ? AdGroup(items: apps, title: '热门推荐') : null, + )); } // tab 数量随数据变化,controller 要跟着重建 diff --git a/lib/hj_page/mine/welfare/lou_feng_ad_page.dart b/lib/hj_page/mine/welfare/lou_feng_ad_page.dart index f578938..149f344 100644 --- a/lib/hj_page/mine/welfare/lou_feng_ad_page.dart +++ b/lib/hj_page/mine/welfare/lou_feng_ad_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'lou_feng_ad_logic.dart'; import 'widget/recommend_app_page.dart'; @@ -24,7 +24,8 @@ class _LouFengAdPageState extends State with UniqueTagMixin { init: LouFengAdLogic(), builder: (logic) { if (logic.isLoading) return const LoadingCenterWidget(); - if (logic.model == null) return CErrorWidget(retryOnTap: logic.loadData); + if (logic.model == null) + return CErrorWidget(retryOnTap: logic.loadData); //只有「应用」一个分类时不展示 tab if (logic.tabs.length <= 1) return _adView(logic, 0); @@ -35,7 +36,8 @@ class _LouFengAdPageState extends State with UniqueTagMixin { Expanded( child: TabBarView( controller: logic.tabCtr, - children: List.generate(logic.configs.length, (i) => _adView(logic, i).keepAlive), + children: List.generate( + logic.configs.length, (i) => _adView(logic, i).keepAlive), ), ), ], @@ -70,7 +72,8 @@ class _LouFengAdPageState extends State with UniqueTagMixin { height: 27, alignment: Alignment.center, decoration: BoxDecoration( - color: selected ? const Color(0xFFFFC000) : Colors.transparent, + color: + selected ? const Color(0xFFFFC000) : Colors.transparent, borderRadius: BorderRadius.circular(46), ), child: Text( @@ -79,7 +82,9 @@ class _LouFengAdPageState extends State with UniqueTagMixin { fontSize: 12, height: 18 / 12, fontWeight: selected ? FontWeight.w500 : FontWeight.w400, - color: selected ? const Color(0xFF1F2029) : const Color(0x8CFFFFFF), + color: selected + ? const Color(0xFF1F2029) + : const Color(0x8CFFFFFF), ), ), ), @@ -91,5 +96,6 @@ class _LouFengAdPageState extends State with UniqueTagMixin { ); } - Widget _adView(LouFengAdLogic logic, int index) => RecommendAppPage(logic.configs[index]); + Widget _adView(LouFengAdLogic logic, int index) => + RecommendAppPage(logic.configs[index]); } diff --git a/lib/hj_page/mine/welfare/mine_income_page.dart b/lib/hj_page/mine/welfare/mine_income_page.dart index e748cf3..10fdaec 100644 --- a/lib/hj_page/mine/welfare/mine_income_page.dart +++ b/lib/hj_page/mine/welfare/mine_income_page.dart @@ -1,12 +1,12 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../config/config.dart'; @@ -41,7 +41,8 @@ class _MineIncomePageState extends State with UniqueTagMixin { Stack( children: [ Positioned.fill( - child: Image.asset("proxy_header_bg.webp".mineImgPath, fit: BoxFit.fill), + child: Image.asset("proxy_header_bg.webp".mineImgPath, + fit: BoxFit.fill), ), Container( padding: EdgeInsets.fromLTRB(10, 23, 10, 6), @@ -63,12 +64,18 @@ class _MineIncomePageState extends State with UniqueTagMixin { children: [ Text( globalStore.meInfo?.name ?? "", - style: const TextStyle(color: Color(0xFFFFFFFF), fontWeight: FontWeight.w700, fontSize: 18.0), + style: const TextStyle( + color: Color(0xFFFFFFFF), + fontWeight: FontWeight.w700, + fontSize: 18.0), ), 5.sizeBoxH, Text( "开通会员 畅享专属特权", - style: const TextStyle(color: Color(0xff989898), fontWeight: FontWeight.w400, fontSize: 12), + style: const TextStyle( + color: Color(0xff989898), + fontWeight: FontWeight.w400, + fontSize: 12), ) ], ), @@ -83,12 +90,18 @@ class _MineIncomePageState extends State with UniqueTagMixin { children: [ Text( "邀请人数", - style: const TextStyle(color: Color(0xB2FFFFFF), fontWeight: FontWeight.w500, fontSize: 12.0), + style: const TextStyle( + color: Color(0xB2FFFFFF), + fontWeight: FontWeight.w500, + fontSize: 12.0), ), SizedBox(height: 1), Text( "${logic.model?.totalInviteUserCount ?? 0}", - style: const TextStyle(color: Color(0xffFFC000), fontWeight: FontWeight.w500, fontSize: 24.0), + style: const TextStyle( + color: Color(0xffFFC000), + fontWeight: FontWeight.w500, + fontSize: 24.0), ) ], ), @@ -100,13 +113,20 @@ class _MineIncomePageState extends State with UniqueTagMixin { Column( children: [ 29.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () { - pushToPageByLink(Config.proxyBanner?.additionalProp?.url ?? ""); + pushToPageByLink( + Config.proxyBanner?.additionalProp?.url ?? + ""); }, - child: Config.proxyBanner?.additionalProp?.banner != null + child: Config.proxyBanner?.additionalProp + ?.banner != + null ? NetworkImageLoader( - imageUrl: Config.proxyBanner?.additionalProp?.banner ?? '', + imageUrl: Config.proxyBanner + ?.additionalProp?.banner ?? + '', width: double.infinity, borderRadius: 0, ) @@ -129,7 +149,10 @@ class _MineIncomePageState extends State with UniqueTagMixin { children: [ Text( "规则说明", - style: const TextStyle(color: Color(0xFFFFFFFF), fontWeight: FontWeight.bold, fontSize: 18.0), + style: const TextStyle( + color: Color(0xFFFFFFFF), + fontWeight: FontWeight.bold, + fontSize: 18.0), ), ], ), @@ -140,7 +163,8 @@ class _MineIncomePageState extends State with UniqueTagMixin { child: EasyRichText( '每邀请3名好友成功注册即可获得3天VIP', textAlign: TextAlign.left, - defaultStyle: TextStyle(fontSize: 12, color: Color(0x73FFFFFF)), + defaultStyle: + TextStyle(fontSize: 12, color: Color(0x73FFFFFF)), patternList: [ EasyRichTextPattern( targetString: '3名好友', @@ -155,7 +179,8 @@ class _MineIncomePageState extends State with UniqueTagMixin { child: EasyRichText( '邀请说明:点击【保存二维码】或【复制推广链接】分享给朋友下载即可', textAlign: TextAlign.left, - defaultStyle: TextStyle(fontSize: 12, color: Color(0x73FFFFFF)), + defaultStyle: + TextStyle(fontSize: 12, color: Color(0x73FFFFFF)), ), ), MineShareQRView(), diff --git a/lib/hj_page/mine/welfare/more_free_video_logic.dart b/lib/hj_page/mine/welfare/more_free_video_logic.dart index bf5a9b5..ed10387 100644 --- a/lib/hj_page/mine/welfare/more_free_video_logic.dart +++ b/lib/hj_page/mine/welfare/more_free_video_logic.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; //免费专区排序 tab(标题与接口 sort 值绑定) const _sortTabs = [SortTab('最多收藏', 1), SortTab('最新上架', 2), SortTab('最多观看', 3)]; -class MoreFreeVideoLogic extends GetxController with GetTickerProviderStateMixin { +class MoreFreeVideoLogic extends GetxController + with GetTickerProviderStateMixin { final String vId; List get sortTitles => _sortTabs.map((e) => e.name).toList(); MoreFreeVideoLogic(this.vId); @@ -16,7 +17,8 @@ class MoreFreeVideoLogic extends GetxController with GetTickerProviderStateMixin bool isLoading = true; int page = 1; int sort = 0; - late final TabController tabController = TabController(length: _sortTabs.length, vsync: this); + late final TabController tabController = + TabController(length: _sortTabs.length, vsync: this); RefreshController? refreshController; List dataSource = []; @@ -28,13 +30,16 @@ class MoreFreeVideoLogic extends GetxController with GetTickerProviderStateMixin isLoading = true; update(); } - final res = await VidService.fetchFreeSourceList(vId, page: page, sortType: _sortTabs[sort].sort); + final res = await VidService.fetchFreeSourceList(vId, + page: page, sortType: _sortTabs[sort].sort); isLoading = false; if (isRefresh) { dataSource.clear(); refreshController?.refreshCompleted(); } - res.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + res.hasNext ?? false + ? refreshController?.loadComplete() + : refreshController?.loadNoData(); dataSource.addAll(res.list ?? []); page += 1; update(); diff --git a/lib/hj_page/mine/welfare/more_free_video_page.dart b/lib/hj_page/mine/welfare/more_free_video_page.dart index 5b94c95..9386e5e 100644 --- a/lib/hj_page/mine/welfare/more_free_video_page.dart +++ b/lib/hj_page/mine/welfare/more_free_video_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../home/home_cell_style/video_simple_cell.dart'; import 'more_free_video_logic.dart'; diff --git a/lib/hj_page/mine/welfare/share_data_list_page.dart b/lib/hj_page/mine/welfare/share_data_list_page.dart index 2a5042f..e0cb2f4 100644 --- a/lib/hj_page/mine/welfare/share_data_list_page.dart +++ b/lib/hj_page/mine/welfare/share_data_list_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/user/user_income_info_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/hj_model/user/user_income_info_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import '../make_money/withdrawal_page.dart'; import 'share_details_page.dart'; @@ -69,7 +69,8 @@ class _ShareDataListPageState extends State { height: 160, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), - border: Border.all(color: const Color(0xff1e262e), width: 1), + border: + Border.all(color: const Color(0xff1e262e), width: 1), color: Color(0xFF131b23)), child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -84,11 +85,17 @@ class _ShareDataListPageState extends State { children: [ Text( "钱包余额", - style: const TextStyle(color: const Color(0xffb8bbbd), fontWeight: FontWeight.w900, fontSize: 12.0), + style: const TextStyle( + color: const Color(0xffb8bbbd), + fontWeight: FontWeight.w900, + fontSize: 12.0), ), Text( "${_model?.totalAmount}", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w500, fontSize: 24.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w500, + fontSize: 24.0), ) ], ), @@ -96,7 +103,9 @@ class _ShareDataListPageState extends State { SizedBox( height: 57, width: .5, - child: DecoratedBox(decoration: BoxDecoration(color: Color(0xff444444))), + child: DecoratedBox( + decoration: + BoxDecoration(color: Color(0xff444444))), ), Expanded( child: Column( @@ -104,11 +113,17 @@ class _ShareDataListPageState extends State { children: [ Text( "累积收益", - style: const TextStyle(color: Color(0xffb8bbbd), fontWeight: FontWeight.w900, fontSize: 12.0), + style: const TextStyle( + color: Color(0xffb8bbbd), + fontWeight: FontWeight.w900, + fontSize: 12.0), ), Text( "${_model?.totalIncomeAmount}", - style: const TextStyle(color: Color(0xffffffff), fontWeight: FontWeight.w500, fontSize: 24.0), + style: const TextStyle( + color: Color(0xffffffff), + fontWeight: FontWeight.w500, + fontSize: 24.0), ) ], ), @@ -116,7 +131,8 @@ class _ShareDataListPageState extends State { ], ), ), - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.to(WithdrawalPage()), child: Container( width: 276, @@ -129,7 +145,10 @@ class _ShareDataListPageState extends State { child: Center( child: Text( "立即提现", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w900, fontSize: 12.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w900, + fontSize: 12.0), ), ), ), @@ -141,7 +160,8 @@ class _ShareDataListPageState extends State { Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(6)), - border: Border.all(color: const Color(0xff1e262e), width: 1), + border: + Border.all(color: const Color(0xff1e262e), width: 1), color: Color(0xFF131b23), ), child: GridView.count( @@ -149,13 +169,17 @@ class _ShareDataListPageState extends State { physics: NeverScrollableScrollPhysics(), crossAxisCount: 2, childAspectRatio: 5 / 3, - children: incomeList.map((e) => _buildIncomeGItem(e)).toList(), + children: + incomeList.map((e) => _buildIncomeGItem(e)).toList(), ), ), 15.sizeBoxH, Text( "推广总统计", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w600, fontSize: 16.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w600, + fontSize: 16.0), ), 15.sizeBoxH, _buildTGItem("累计推广用户", _model?.totalInviteUserCount ?? '0'), @@ -174,11 +198,17 @@ class _ShareDataListPageState extends State { children: [ Text( title, - style: const TextStyle(color: const Color(0xffb8bbbd), fontWeight: FontWeight.w400, fontSize: 12.0), + style: const TextStyle( + color: const Color(0xffb8bbbd), + fontWeight: FontWeight.w400, + fontSize: 12.0), ), Text( "$value", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w500, fontSize: 18.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w500, + fontSize: 18.0), ), ], ), @@ -192,11 +222,17 @@ class _ShareDataListPageState extends State { children: [ Text( "${item.value}", - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w900, fontSize: 18.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w900, + fontSize: 18.0), ), Text( item.title, - style: const TextStyle(color: const Color(0xffb8bbbd), fontWeight: FontWeight.w400, fontSize: 12.0), + style: const TextStyle( + color: const Color(0xffb8bbbd), + fontWeight: FontWeight.w400, + fontSize: 12.0), ) ], ), diff --git a/lib/hj_page/mine/welfare/share_details_page.dart b/lib/hj_page/mine/welfare/share_details_page.dart index ce795d7..ac5b7bd 100644 --- a/lib/hj_page/mine/welfare/share_details_page.dart +++ b/lib/hj_page/mine/welfare/share_details_page.dart @@ -1,15 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/user/user_income_info_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_model/user/user_income_info_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'share_data_list_page.dart'; class ShareDetailsPage extends StatefulWidget { - final UserIncomeModel? model; const ShareDetailsPage({super.key, this.model}); @@ -47,7 +46,9 @@ class _ShareDetailsPageState extends State { if (isRefresh) { dataSource.clear(); } - res?.hasNext ?? false ? _controller?.loadComplete() : _controller?.loadNoData(); + res?.hasNext ?? false + ? _controller?.loadComplete() + : _controller?.loadNoData(); dataSource.addAll(res?.items ?? []); page += 1; if (mounted) setState(() {}); @@ -79,7 +80,10 @@ class _ShareDetailsPageState extends State { // 收益明细 Text( "收益明细", - style: const TextStyle(color: const Color(0xffbec4d6), fontWeight: FontWeight.w500, fontSize: 18.0), + style: const TextStyle( + color: const Color(0xffbec4d6), + fontWeight: FontWeight.w500, + fontSize: 18.0), ), SizedBox(height: 10), ], @@ -93,7 +97,9 @@ class _ShareDetailsPageState extends State { child: LoadingCenterWidget(), ), ); - if (dataSource.isEmpty) return SliverToBoxAdapter(child: SizedBox(height: 300, child: CErrorWidget())); + if (dataSource.isEmpty) + return SliverToBoxAdapter( + child: SizedBox(height: 300, child: CErrorWidget())); return SliverList.builder( itemCount: dataSource.length, itemBuilder: (_, index) { @@ -117,11 +123,17 @@ class _ShareDetailsPageState extends State { children: [ Text( title, - style: const TextStyle(color: const Color(0xffffffff), fontWeight: FontWeight.w400, fontSize: 14.0), + style: const TextStyle( + color: const Color(0xffffffff), + fontWeight: FontWeight.w400, + fontSize: 14.0), ), Text( "收益+$value元", - style: const TextStyle(color: const Color(0xffFFC000), fontWeight: FontWeight.w400, fontSize: 14.0), + style: const TextStyle( + color: const Color(0xffFFC000), + fontWeight: FontWeight.w400, + fontSize: 14.0), ), ], ), @@ -142,11 +154,17 @@ class _ShareDetailsPageState extends State { children: [ Text( item.title, - style: const TextStyle(color: const Color(0xE5FFFFFF), fontWeight: FontWeight.w400, fontSize: 14.0), + style: const TextStyle( + color: const Color(0xE5FFFFFF), + fontWeight: FontWeight.w400, + fontSize: 14.0), ), Text( "${item.value}", - style: const TextStyle(color: const Color(0x8CFFFFFF), fontWeight: FontWeight.w500, fontSize: 20.0), + style: const TextStyle( + color: const Color(0x8CFFFFFF), + fontWeight: FontWeight.w500, + fontSize: 20.0), ), ], ), diff --git a/lib/hj_page/mine/welfare/sign_daily_page.dart b/lib/hj_page/mine/welfare/sign_daily_page.dart index a1df489..56219c3 100644 --- a/lib/hj_page/mine/welfare/sign_daily_page.dart +++ b/lib/hj_page/mine/welfare/sign_daily_page.dart @@ -5,12 +5,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/mine/widgets/integral_exchange_page.dart'; -import 'package:hgmj/hj_utils/free_play_manager.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/mine/widgets/integral_exchange_page.dart'; +import 'package:wydj/hj_utils/free_play_manager.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:provider/provider.dart'; import '../../../tools_base/global_store/store.dart'; @@ -52,7 +52,8 @@ class SignDailyPage extends StatelessWidget { id: 'appbar', builder: (_) => AppBar( title: const Text('每日签到'), - backgroundColor: const Color(0xff030F18).withValues(alpha: logic.appbarOpacity), + backgroundColor: + const Color(0xff030F18).withValues(alpha: logic.appbarOpacity), elevation: 0, ), ), @@ -91,12 +92,18 @@ class SignDailyPage extends StatelessWidget { children: [ const Text( '我的积分 ', - style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w400), + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w400), ), Consumer( builder: (_, provider, __) => Text( '${globalStore.wallet?.integral ?? 0}', - style: const TextStyle(color: Color(0xffFFC000), fontSize: 24, fontWeight: FontWeight.w700), + style: const TextStyle( + color: Color(0xffFFC000), + fontSize: 24, + fontWeight: FontWeight.w700), ), ), ], @@ -122,7 +129,10 @@ class SignDailyPage extends StatelessWidget { padding: EdgeInsets.zero, isScrollable: true, tabAlignment: TabAlignment.start, - labelStyle: const TextStyle(fontSize: 16, color: Color(0xffFFC000), fontWeight: FontWeight.w500), + labelStyle: const TextStyle( + fontSize: 16, + color: Color(0xffFFC000), + fontWeight: FontWeight.w500), unselectedLabelStyle: const TextStyle( fontSize: 16, color: Color(0xff999999), @@ -199,11 +209,17 @@ class SignDailyPage extends StatelessWidget { globalStore.meInfo?.name ?? "", maxLines: 1, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.w500), ), if ((globalStore.meInfo?.vipLevel ?? 0) > 0) ...[ 4.sizeBoxW, - Image.asset(globalStore.meInfo?.vipImageName ?? "", width: 30, height: 18), + Image.asset( + globalStore.meInfo?.vipImageName ?? "", + width: 30, + height: 18), ], ], ), @@ -211,12 +227,18 @@ class SignDailyPage extends StatelessWidget { Consumer( builder: (context, provider, child) { final isVip = globalStore.isVIP; - final watch = FreePlayManager().remain?.watchCount ?? 0; - final aiFree = globalStore.wallet?.aiUndressFreeTimes ?? 0; - final aiToday = provider.remain?.todayAiUndressCount ?? 0; + final watch = + FreePlayManager().remain?.watchCount ?? 0; + final aiFree = + globalStore.wallet?.aiUndressFreeTimes ?? 0; + final aiToday = + provider.remain?.todayAiUndressCount ?? 0; return Text( - isVip ? "剩余AI次数:${max(aiFree + aiToday, 0)}" : "剩余观看次数:${max(watch, 0)}", - style: const TextStyle(fontSize: 12, color: Color(0xff656565)), + isVip + ? "剩余AI次数:${max(aiFree + aiToday, 0)}" + : "剩余观看次数:${max(watch, 0)}", + style: const TextStyle( + fontSize: 12, color: Color(0xff656565)), ); }, ) @@ -236,7 +258,8 @@ class SignDailyPage extends StatelessWidget { height: 44, width: double.infinity, alignment: Alignment.center, - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 5.h), + padding: + EdgeInsets.symmetric(horizontal: 12.w, vertical: 5.h), margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 0), decoration: const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(90)), @@ -249,7 +272,10 @@ class SignDailyPage extends StatelessWidget { child: Text( globalStore.isVIP ? '已开通会员' : '开通VIP不限次数免费观看', style: TextStyle( - color: Color(globalStore.isVIP ? 0xfffffffff : 0xfffffffff), fontSize: 16, fontWeight: FontWeight.w700), + color: Color( + globalStore.isVIP ? 0xfffffffff : 0xfffffffff), + fontSize: 16, + fontWeight: FontWeight.w700), ), ), ), diff --git a/lib/hj_page/mine/welfare/welfare_home_page.dart b/lib/hj_page/mine/welfare/welfare_home_page.dart index b2b95cc..a69ca3f 100644 --- a/lib/hj_page/mine/welfare/welfare_home_page.dart +++ b/lib/hj_page/mine/welfare/welfare_home_page.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../../tools_base/indicator/custom_tab_indicator.dart'; import 'lou_feng_ad_page.dart'; class WelfareHomePage extends StatefulWidget { - ///默认选中的 tab:0 分享邀请 / 1 应用推荐 final int index; @@ -18,9 +17,11 @@ class WelfareHomePage extends StatefulWidget { } } -class _WelfareHomePageState extends State with TickerProviderStateMixin { - final tabs = [/*'分享邀请', */"应用推荐"]; - late final TabController _tabController = TabController(initialIndex: /*widget.index*/0, length: tabs.length, vsync: this); +class _WelfareHomePageState extends State + with TickerProviderStateMixin { + final tabs = [/*'分享邀请', */ "应用推荐"]; + late final TabController _tabController = TabController( + initialIndex: /*widget.index*/ 0, length: tabs.length, vsync: this); @override Widget build(BuildContext context) { @@ -40,8 +41,12 @@ class _WelfareHomePageState extends State with TickerProviderSt child: TabBar( padding: EdgeInsets.symmetric(horizontal: 0, vertical: 5), isScrollable: false, - labelStyle: TextStyle(fontSize: 14, color: Color(0xFFFFC000), fontWeight: FontWeight.w400), - unselectedLabelStyle: TextStyle(fontSize: 14, color: Color(0x73FFFFFF)), + labelStyle: TextStyle( + fontSize: 14, + color: Color(0xFFFFC000), + fontWeight: FontWeight.w400), + unselectedLabelStyle: + TextStyle(fontSize: 14, color: Color(0x73FFFFFF)), indicator: CustomIndicator( width: 18, height: 4, diff --git a/lib/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart b/lib/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart index 657eedf..3b9bc37 100644 --- a/lib/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart +++ b/lib/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:video_player/video_player.dart'; import 'checkin_model.dart'; @@ -46,7 +46,10 @@ class CongratulationsRewardDialog extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, - children: prizeList?.map((e) => _buildRewardItem(e.name ?? "", e.icon ?? "")).toList() ?? [], + children: prizeList + ?.map((e) => _buildRewardItem(e.name ?? "", e.icon ?? "")) + .toList() ?? + [], ), SizedBox(height: 36), // 底部按钮 @@ -63,7 +66,8 @@ class CongratulationsRewardDialog extends StatelessWidget { alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), - border: Border.all(color: const Color(0xFFFFD700), width: 2), + border: Border.all( + color: const Color(0xFFFFD700), width: 2), ), child: Text( "兑换好礼", @@ -115,7 +119,8 @@ class CongratulationsRewardDialog extends StatelessWidget { decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.white.withValues(alpha: .5), width: 0.5)), + border: Border.all( + color: Colors.white.withValues(alpha: .5), width: 0.5)), padding: EdgeInsets.all(6), child: NetworkImageLoader(imageUrl: iconPath, fit: BoxFit.contain), ), diff --git a/lib/hj_page/mine/welfare/widget/custom_progressbar.dart b/lib/hj_page/mine/welfare/widget/custom_progressbar.dart index b4cf39f..5b1eaea 100644 --- a/lib/hj_page/mine/welfare/widget/custom_progressbar.dart +++ b/lib/hj_page/mine/welfare/widget/custom_progressbar.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; class CustomProgressBar extends StatelessWidget { final double progress; // 0 ~ 1 @@ -46,7 +46,8 @@ class CustomProgressBar extends StatelessWidget { // 小图标(跟随进度,两端不溢出) Positioned( left: (width - 18) * progress, - child: Image.asset("ic_sign_indicator.webp".mineImgPath, width: 18, height: 18, fit: BoxFit.cover), + child: Image.asset("ic_sign_indicator.webp".mineImgPath, + width: 18, height: 18, fit: BoxFit.cover), ), ], ); diff --git a/lib/hj_page/mine/welfare/widget/mine_sign_logic.dart b/lib/hj_page/mine/welfare/widget/mine_sign_logic.dart index 440c37a..a58f895 100644 --- a/lib/hj_page/mine/welfare/widget/mine_sign_logic.dart +++ b/lib/hj_page/mine/welfare/widget/mine_sign_logic.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/hj_page/mine/mine_share/mine_share_page.dart'; -import 'package:hgmj/hj_page/mine/welfare/sign_daily_logic.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/checkin_model.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/sign_dialog.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/sign_in_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/hj_page/mine/mine_share/mine_share_page.dart'; +import 'package:wydj/hj_page/mine/welfare/sign_daily_logic.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/checkin_model.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/congratulations_reward_dialog.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/sign_dialog.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/sign_in_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:linked_scroll_controller/linked_scroll_controller.dart'; import 'package:video_player/video_player.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; /// 每日签到 Logic /// 负责签到列表加载、签到/补领接口、双倍奖励视频播放、跳转积分兑换 Tab @@ -155,7 +155,8 @@ class MineSignLogic extends GetxController { if (parent == null) return; parent.tabCtr.animateTo(1); // 等一帧让弹窗 dismiss 后 layout 稳定,再算位置 - WidgetsBinding.instance.addPostFrameCallback((_) => _scrollTabKeyBelowAppBar()); + WidgetsBinding.instance + .addPostFrameCallback((_) => _scrollTabKeyBelowAppBar()); } /// 让 parent.tabKey 对应的 widget 滚到 AppBar 下沿 @@ -261,9 +262,11 @@ class _ResignGuideDialog extends StatelessWidget { const SizedBox(height: 260), Row( children: [ - Expanded(child: _btn(onCancel, '离开', isPrimary: false)), + Expanded( + child: _btn(onCancel, '离开', isPrimary: false)), const SizedBox(width: 16), - Expanded(child: _btn(onConfirm, '立即邀请', isPrimary: true)), + Expanded( + child: _btn(onConfirm, '立即邀请', isPrimary: true)), ], ), ], @@ -277,7 +280,8 @@ class _ResignGuideDialog extends StatelessWidget { right: 10, child: GestureDetector( onTap: onCancel, - child: Image.asset('icon_resign_close.png'.mineImgPath, width: 30, height: 30), + child: Image.asset('icon_resign_close.png'.mineImgPath, + width: 30, height: 30), ), ), ], @@ -301,7 +305,9 @@ class _ResignGuideDialog extends StatelessWidget { ) : null, borderRadius: BorderRadius.circular(25), - border: isPrimary ? null : Border.all(color: const Color(0xFFB7B7B7), width: 1), + border: isPrimary + ? null + : Border.all(color: const Color(0xFFB7B7B7), width: 1), ), child: Text( text, diff --git a/lib/hj_page/mine/welfare/widget/recommend_app_page.dart b/lib/hj_page/mine/welfare/widget/recommend_app_page.dart index ce567f5..3b1af85 100644 --- a/lib/hj_page/mine/welfare/widget/recommend_app_page.dart +++ b/lib/hj_page/mine/welfare/widget/recommend_app_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/mine/happy/happy_model.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_banner.dart'; +import 'package:wydj/hj_model/mine/happy/happy_model.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_banner.dart'; import '../../../../tools_base/banner/ads_item.dart'; @@ -46,7 +46,8 @@ class RecommendAppPage extends StatelessWidget { mainAxisSpacing: 10, childAspectRatio: 82 / 105, ), - itemBuilder: (_, index) => _buildVItem(model.hengAds!.items![index], index)), + itemBuilder: (_, index) => + _buildVItem(model.hengAds!.items![index], index)), ) ], ), @@ -60,10 +61,12 @@ class RecommendAppPage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16), sliver: SliverList.separated( itemCount: model.shuAds?.items?.length ?? 0, - separatorBuilder: (_, __) => model.shuAds?.title == '热门推荐' ? 10.sizeBoxH : 1.line, + separatorBuilder: (_, __) => + model.shuAds?.title == '热门推荐' ? 10.sizeBoxH : 1.line, itemBuilder: (_, index) { final info = model.shuAds!.items![index]; - if (model.shuAds?.title == '热门推荐') return _buildHBItem(info, index); + if (model.shuAds?.title == '热门推荐') + return _buildHBItem(info, index); return _buildHItem(info, index); }, ), @@ -81,12 +84,11 @@ class RecommendAppPage extends StatelessWidget { children: [ Container( decoration: BoxDecoration( - color: Color(0xFFFFC000), - borderRadius: BorderRadius.only( - topRight: Radius.circular(4), - bottomRight: Radius.circular(4), - ) - ), + color: Color(0xFFFFC000), + borderRadius: BorderRadius.only( + topRight: Radius.circular(4), + bottomRight: Radius.circular(4), + )), width: 8, height: 22, ), diff --git a/lib/hj_page/mine/welfare/widget/sign_dialog.dart b/lib/hj_page/mine/welfare/widget/sign_dialog.dart index 65c3eca..c8bd8a6 100644 --- a/lib/hj_page/mine/welfare/widget/sign_dialog.dart +++ b/lib/hj_page/mine/welfare/widget/sign_dialog.dart @@ -1,8 +1,8 @@ import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../../../tools_base/widget/net_image_widget.dart'; import 'checkin_model.dart'; @@ -13,7 +13,12 @@ class SignInDialog extends StatelessWidget { final Function? callback; final List? prizeList; - SignInDialog({super.key, this.signInList, this.continuousDays, this.callback, this.prizeList}); + SignInDialog( + {super.key, + this.signInList, + this.continuousDays, + this.callback, + this.prizeList}); @override Widget build(BuildContext context) { @@ -26,7 +31,9 @@ class SignInDialog extends StatelessWidget { padding: EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 40), margin: EdgeInsets.only(top: 50), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), color: Color(0xff0F0F0F), border: Border.all(width: 1, color: Color(0xffFFE7B4))), + borderRadius: BorderRadius.circular(20), + color: Color(0xff0F0F0F), + border: Border.all(width: 1, color: Color(0xffFFE7B4))), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -55,7 +62,9 @@ class SignInDialog extends StatelessWidget { 13.sizeBoxH, Container( padding: EdgeInsets.all(12), - decoration: BoxDecoration(color: Color(0xffFFD900).withValues(alpha: .1), borderRadius: BorderRadius.circular(12)), + decoration: BoxDecoration( + color: Color(0xffFFD900).withValues(alpha: .1), + borderRadius: BorderRadius.circular(12)), child: Column( children: [ Text( @@ -70,7 +79,11 @@ class SignInDialog extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, - children: prizeList?.map((e) => _buildRewardItem(e.name ?? "", e.icon ?? "")).toList() ?? [], + children: prizeList + ?.map((e) => _buildRewardItem( + e.name ?? "", e.icon ?? "")) + .toList() ?? + [], ), ], ), @@ -90,7 +103,8 @@ class SignInDialog extends StatelessWidget { alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), - border: Border.all(color: const Color(0xFFFFD700), width: 2), + border: Border.all( + color: const Color(0xFFFFD700), width: 2), ), child: Text( "兑换好礼", @@ -132,7 +146,11 @@ class SignInDialog extends StatelessWidget { ], ), ), - Positioned(left: 0, right: 0, child: Image.asset('sign_take_top.webp'.mineImgPath, height: 30, fit: BoxFit.contain)), + Positioned( + left: 0, + right: 0, + child: Image.asset('sign_take_top.webp'.mineImgPath, + height: 30, fit: BoxFit.contain)), ], ), ); @@ -145,7 +163,9 @@ class SignInDialog extends StatelessWidget { final list = signInList?.take(6).toList() ?? []; return Container( height: 68, - decoration: BoxDecoration(color: Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(20)), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: .05), + borderRadius: BorderRadius.circular(20)), child: ListView.builder( shrinkWrap: true, scrollDirection: Axis.horizontal, @@ -174,7 +194,9 @@ class SignInDialog extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.white.withValues(alpha: .1), - border: active ? Border.all(color: const Color(0xffFFDA0B), width: 0.5) : null, + border: active + ? Border.all(color: const Color(0xffFFDA0B), width: 0.5) + : null, ), // padding: EdgeInsets.all(5), child: Column( @@ -206,13 +228,25 @@ class SignInDialog extends StatelessWidget { 1, 0, ]) - : ColorFilter.mode(Colors.transparent, BlendMode.multiply), - child: NetworkImageLoader(imageUrl: item.image!, width: 34, height: 34, fit: BoxFit.contain)) - : Image.asset(isSigned == true ? 'checked_in_coin.webp'.mineImgPath : 'check_in_coin.webp'.mineImgPath, - width: 34, height: 34, fit: BoxFit.cover), + : ColorFilter.mode( + Colors.transparent, BlendMode.multiply), + child: NetworkImageLoader( + imageUrl: item.image!, + width: 34, + height: 34, + fit: BoxFit.contain)) + : Image.asset( + isSigned == true + ? 'checked_in_coin.webp'.mineImgPath + : 'check_in_coin.webp'.mineImgPath, + width: 34, + height: 34, + fit: BoxFit.cover), Text( item.prizeName ?? '', - style: TextStyle(color: isSigned == true ? Colors.white : Color(0xffFFD900), fontSize: 10), + style: TextStyle( + color: isSigned == true ? Colors.white : Color(0xffFFD900), + fontSize: 10), ), ], ), @@ -228,7 +262,8 @@ class SignInDialog extends StatelessWidget { decoration: BoxDecoration( color: Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(10), - border: Border.all(color: Colors.white.withValues(alpha: .2), width: 0.5)), + border: Border.all( + color: Colors.white.withValues(alpha: .2), width: 0.5)), padding: EdgeInsets.all(6), child: NetworkImageLoader(imageUrl: iconPath, fit: BoxFit.contain), ), diff --git a/lib/hj_page/mine/welfare/widget/task_widgets.dart b/lib/hj_page/mine/welfare/widget/task_widgets.dart index c4b9d7d..ee44803 100644 --- a/lib/hj_page/mine/welfare/widget/task_widgets.dart +++ b/lib/hj_page/mine/welfare/widget/task_widgets.dart @@ -2,28 +2,28 @@ import 'dart:async'; import 'package:easy_rich_text/easy_rich_text.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/mine/task_center_data.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/checkin_model.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/custom_progressbar.dart'; -import 'package:hgmj/hj_page/mine/welfare/widget/mine_sign_logic.dart'; -import 'package:hgmj/hj_page/mine/widgets/gradient_text.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/mine/task_center_data.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/checkin_model.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/custom_progressbar.dart'; +import 'package:wydj/hj_page/mine/welfare/widget/mine_sign_logic.dart'; +import 'package:wydj/hj_page/mine/widgets/gradient_text.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../home/home_cell_style/video_simple_cell.dart'; @@ -41,7 +41,8 @@ final ColorFilter _kGrayFilter = ColorFilter.matrix([ 0.2126, 0.7152, 0.0722, 0, 0, // 0, 0, 0, 1, 0, // ]); -const ColorFilter _kNoFilter = ColorFilter.mode(Colors.transparent, BlendMode.multiply); +const ColorFilter _kNoFilter = + ColorFilter.mode(Colors.transparent, BlendMode.multiply); // ============================================================ // 1. TaskVIPVideosView:福利页 - VIP/特价视频区 @@ -68,7 +69,8 @@ class _TaskVIPVideosViewState extends State { if (!mounted) return; rawData.addAll(res ?? []); for (final element in res ?? []) { - dataSource.add(VidService.fetchFreeSourceList(element.id ?? '', size: 4, sortType: 0)); + dataSource.add(VidService.fetchFreeSourceList(element.id ?? '', + size: 4, sortType: 0)); } setState(() {}); } @@ -82,7 +84,8 @@ class _TaskVIPVideosViewState extends State { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: EdgeInsets.symmetric(horizontal: 18.w), - itemBuilder: (_, index) => FreeAreaVideoGridView(dataSource[index], model: rawData[index]), + itemBuilder: (_, index) => + FreeAreaVideoGridView(dataSource[index], model: rawData[index]), ); } } @@ -102,17 +105,21 @@ class FreeAreaVideoGridView extends StatelessWidget { if (!snapshot.hasData) { return const SizedBox(height: 340, child: LoadingCenterWidget()); } - if (snapshot.hasError || snapshot.data == null || (snapshot.data?.list?.isEmpty ?? true)) { + if (snapshot.hasError || + snapshot.data == null || + (snapshot.data?.list?.isEmpty ?? true)) { return const SizedBox.shrink(); } return SizedBox( height: 342, child: Stack( children: [ - Image.asset('area_discount_bg.webp'.mineImgPath, height: double.infinity, fit: BoxFit.fill), + Image.asset('area_discount_bg.webp'.mineImgPath, + height: double.infinity, fit: BoxFit.fill), Positioned.fill( child: Padding( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 8), + padding: + const EdgeInsets.symmetric(vertical: 20, horizontal: 8), child: Column( children: [ _buildHeader(), @@ -135,15 +142,19 @@ class FreeAreaVideoGridView extends StatelessWidget { children: [ Text( model?.title ?? '', - style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), ), const Spacer(), GestureDetector( - onTap: () => Get.to(MoreFreeVideoPage(model?.title ?? '', model?.id ?? '')), + onTap: () => + Get.to(MoreFreeVideoPage(model?.title ?? '', model?.id ?? '')), child: const Row( children: [ - Text('更多', style: TextStyle(color: Color(0xff999999), fontSize: 12)), - Icon(Icons.arrow_forward_ios_rounded, size: 10, color: Color(0xff999999)), + Text('更多', + style: TextStyle(color: Color(0xff999999), fontSize: 12)), + Icon(Icons.arrow_forward_ios_rounded, + size: 10, color: Color(0xff999999)), ], ), ), @@ -179,7 +190,11 @@ class FreeAreaVideoGridView extends StatelessWidget { class TaskCenterVIPGuideView extends StatelessWidget { TaskCenterVIPGuideView({super.key}); - static const _privilegeIcons = ['privilege_gold.webp', 'privilege_ai.webp', 'privilege_game.webp']; + static const _privilegeIcons = [ + 'privilege_gold.webp', + 'privilege_ai.webp', + 'privilege_game.webp' + ]; static const _privilegeTitles = ['至尊金币', 'AI科技', '成人游戏']; static const _privilegeSubTs = ['价值100元', '价值500元', '价值1000元']; @@ -198,7 +213,9 @@ class TaskCenterVIPGuideView extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(horizontal: 15), decoration: BoxDecoration( - image: DecorationImage(image: AssetImage('vip_privilege_bg.webp'.mineImgPath), fit: BoxFit.fill), + image: DecorationImage( + image: AssetImage('vip_privilege_bg.webp'.mineImgPath), + fit: BoxFit.fill), ), child: Column( children: [ @@ -223,11 +240,15 @@ class TaskCenterVIPGuideView extends StatelessWidget { 10.sizeBoxW, EasyRichText( '开通荣耀至尊卡会员预计年省1800元', - defaultStyle: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + defaultStyle: const TextStyle( + color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), patternList: [ EasyRichTextPattern( targetString: '荣耀至尊卡|1800元', - style: const TextStyle(color: Color(0xffE3C891), fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xffE3C891), + fontSize: 14, + fontWeight: FontWeight.w500), ), ], ), @@ -252,7 +273,9 @@ class TaskCenterVIPGuideView extends StatelessWidget { child: Container( width: double.infinity, decoration: BoxDecoration( - image: DecorationImage(image: AssetImage('privilege_bg.webp'.mineImgPath), fit: BoxFit.fill), + image: DecorationImage( + image: AssetImage('privilege_bg.webp'.mineImgPath), + fit: BoxFit.fill), ), child: Column( children: [ @@ -261,25 +284,36 @@ class TaskCenterVIPGuideView extends StatelessWidget { 1.sizeBoxH, Text( _privilegeTitles[index], - style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w600), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w600), ), 3.sizeBoxH, - Text(_privilegeSubTs[index], style: const TextStyle(color: Color(0xff9FA19F), fontSize: 10)), + Text(_privilegeSubTs[index], + style: const TextStyle( + color: Color(0xff9FA19F), fontSize: 10)), ], ), ), ), 6.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () => Get.to(MineChargeVipPage()), child: Container( width: 50, height: 24, alignment: Alignment.center, - decoration: BoxDecoration(color: const Color(0xffFFD5A8), borderRadius: BorderRadius.circular(18)), + decoration: BoxDecoration( + color: const Color(0xffFFD5A8), + borderRadius: BorderRadius.circular(18)), child: const Text( '待领取', - style: TextStyle(color: Color(0xff692A1F), fontSize: 10, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xff692A1F), + fontSize: 10, + fontWeight: FontWeight.w500), ), ), ), @@ -294,7 +328,9 @@ class TaskCenterVIPGuideView extends StatelessWidget { alignment: Alignment.centerLeft, children: [ Image.asset( - globalStore.isVIP ? 'welfare_vip_bg.webp'.mineImgPath : 'welfare_normal_bg.webp'.mineImgPath, + globalStore.isVIP + ? 'welfare_vip_bg.webp'.mineImgPath + : 'welfare_normal_bg.webp'.mineImgPath, width: double.infinity, fit: BoxFit.fitWidth, ), @@ -323,7 +359,10 @@ class TaskCenterVIPGuideView extends StatelessWidget { children: [ const Text( 'VIP限时特惠 畅享全场', - style: TextStyle(color: Color(0xffF37952), fontSize: 14, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xffF37952), + fontSize: 14, + fontWeight: FontWeight.w500), ), 3.sizeBoxH, Row( @@ -331,15 +370,20 @@ class TaskCenterVIPGuideView extends StatelessWidget { children: [ Text( globalStore.isVIP - ? ((globalStore.meInfo?.vipName == null || globalStore.meInfo?.vipName == '') + ? ((globalStore.meInfo?.vipName == null || + globalStore.meInfo?.vipName == '') ? '至尊永久卡' : globalStore.meInfo!.vipName!) : '新人限时特惠', - style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w500), ), 4.sizeBoxW, Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + padding: + const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Colors.black.withValues(alpha: .5), borderRadius: BorderRadius.circular(32), @@ -354,7 +398,8 @@ class TaskCenterVIPGuideView extends StatelessWidget { : cd != null ? '${cd.discountHour}:${cd.discountMin}:${cd.discountSec}' : '活动已结束', - style: const TextStyle(color: Color(0xff999999), fontSize: 11), + style: const TextStyle( + color: Color(0xff999999), fontSize: 11), ); }, ), @@ -392,7 +437,9 @@ class TaskCenterVIPGuideView extends StatelessWidget { ), 2.w.sizeBoxW, SvgPicture.asset( - isVip ? 'vip_upgrade_arrow.svg'.mineImgPath : 'vip_arrow.svg'.mineImgPath, + isVip + ? 'vip_upgrade_arrow.svg'.mineImgPath + : 'vip_arrow.svg'.mineImgPath, width: 12, ), ], @@ -415,7 +462,8 @@ class MineTaskView extends StatelessWidget { return ListView.separated( physics: const ClampingScrollPhysics(), // 底部加上系统安全区,避免最后一个任务被导航条遮挡 - padding: EdgeInsets.fromLTRB(16, 0, 16, 20 + Get.mediaQuery.padding.bottom), + padding: + EdgeInsets.fromLTRB(16, 0, 16, 20 + Get.mediaQuery.padding.bottom), itemCount: tasks.length, separatorBuilder: (_, __) => 12.sizeBoxH, itemBuilder: (_, index) => TaskItem(tasks[index]), @@ -466,7 +514,11 @@ class _TaskItemState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ 20.sizeBoxH, - NetworkImageLoader(imageUrl: task.img ?? '', width: 40, height: 40, borderRadius: 30), + NetworkImageLoader( + imageUrl: task.img ?? '', + width: 40, + height: 40, + borderRadius: 30), 8.sizeBoxW, Expanded( child: Column( @@ -477,26 +529,36 @@ class _TaskItemState extends State { Flexible( child: Text( task.title ?? task.subTitle ?? '', - style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontSize: 14), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w700, + fontSize: 14), overflow: TextOverflow.ellipsis, ), ), - if (task.prizesIntegral != null && task.prizesIntegral != 0) ...[ + if (task.prizesIntegral != null && + task.prizesIntegral != 0) ...[ 4.sizeBoxW, Text( ' +${task.prizesIntegral}积分', - style: const TextStyle(color: Color(0xffF54570), fontWeight: FontWeight.w400, fontSize: 12), + style: const TextStyle( + color: Color(0xffF54570), + fontWeight: FontWeight.w400, + fontSize: 12), ), ], if (task.countdownType == 1) ...[ 8.sizeBoxW, Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 3), decoration: BoxDecoration( borderRadius: BorderRadius.circular(26), color: const Color(0xffFFA800), ), - child: const Text('限时', style: TextStyle(color: Colors.white, fontSize: 10)), + child: const Text('限时', + style: + TextStyle(color: Colors.white, fontSize: 10)), ), ], ], @@ -558,7 +620,8 @@ class _TaskItemState extends State { return task.desc ?? ''; } - String _formatCountdown(Duration duration) => DateTimeUtil.formatHMS(duration.inSeconds, alwaysHour: true); + String _formatCountdown(Duration duration) => + DateTimeUtil.formatHMS(duration.inSeconds, alwaysHour: true); String _getTaskStatus(int? status) { if (widget.task.countdownType == 1 && @@ -595,16 +658,21 @@ class _TaskItemState extends State { : const Color(0xffFFC000); final textColor = isClaimStyle ? const Color(0xff692A1F) : Colors.white; final isSmall = isClaimStyle || isDone; - return InkWell(enableFeedback: false, + return InkWell( + enableFeedback: false, onTap: () => _onBtnTap(task, btnText), child: Container( width: 70, height: 32, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(24), color: bgColor), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), color: bgColor), child: Center( child: Text( btnText, - style: TextStyle(color: textColor, fontWeight: FontWeight.w500, fontSize: isSmall ? 12 : 14), + style: TextStyle( + color: textColor, + fontWeight: FontWeight.w500, + fontSize: isSmall ? 12 : 14), ), ), ), @@ -634,7 +702,8 @@ class _TaskItemState extends State { /// 完成任务(标记 doType 为 1/2 的任务) Future _doTask(DailyTask task) async { - final needDotask = (task.doType == 1 && task.type == 0) || (task.doType == 2 && task.type == 2); + final needDotask = (task.doType == 1 && task.type == 0) || + (task.doType == 2 && task.type == 2); if (!needDotask) return; final res = await CommonService.doTask(task.id ?? '', task.doType); if (res) { @@ -683,11 +752,14 @@ class MineSignView extends StatelessWidget { children: [ GradientText( '每日签到领福利', - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), - gradient: const LinearGradient(colors: [Color(0xffFFE580), Color(0xffFACC15)]), + style: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w500), + gradient: const LinearGradient( + colors: [Color(0xffFFE580), Color(0xffFACC15)]), ), 4.sizeBoxH, - if (logic.continuousDays <= 7) CustomProgressBar(progress: logic.continuousDays / 7), + if (logic.continuousDays <= 7) + CustomProgressBar(progress: logic.continuousDays / 7), 6.sizeBoxH, _buildContinuousText(logic.continuousDays), 12.sizeBoxH, @@ -710,7 +782,8 @@ class MineSignView extends StatelessWidget { Widget _buildContinuousText(int continuousDays) { return EasyRichText( '已连续签到 $continuousDays 天 神秘大礼在等你', - defaultStyle: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .55)), + defaultStyle: + TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .55)), patternList: [ EasyRichTextPattern( targetString: '$continuousDays', @@ -724,11 +797,20 @@ class MineSignView extends StatelessWidget { Widget _buildSignInGrid(MineSignLogic logic) { return Column( children: [ - _SignInRow(_SignRowType.title, controller: logic.titleScrollCtr, list: logic.checkList ?? [], logic: logic), + _SignInRow(_SignRowType.title, + controller: logic.titleScrollCtr, + list: logic.checkList ?? [], + logic: logic), 12.sizeBoxH, - _SignInRow(_SignRowType.normal, controller: logic.normalScrollCtr, list: logic.checkList ?? [], logic: logic), + _SignInRow(_SignRowType.normal, + controller: logic.normalScrollCtr, + list: logic.checkList ?? [], + logic: logic), 12.sizeBoxH, - _SignInRow(_SignRowType.vip, controller: logic.vipScrollCtr, list: logic.vipCheckList ?? [], logic: logic), + _SignInRow(_SignRowType.vip, + controller: logic.vipScrollCtr, + list: logic.vipCheckList ?? [], + logic: logic), ], ); } @@ -744,7 +826,9 @@ class MineSignView extends StatelessWidget { height: 38, alignment: Alignment.center, decoration: BoxDecoration( - color: isSigned ? Colors.white.withValues(alpha: .3) : const Color(0xffFFC000), + color: isSigned + ? Colors.white.withValues(alpha: .3) + : const Color(0xffFFC000), borderRadius: BorderRadius.circular(24), ), child: Row( @@ -787,7 +871,10 @@ class MineSignView extends StatelessWidget { '立即解锁可领"免费+豪奖"双重奖励', maxLines: 1, overflow: TextOverflow.ellipsis, - defaultStyle: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .88), fontWeight: FontWeight.w400), + defaultStyle: TextStyle( + fontSize: 12, + color: Colors.white.withValues(alpha: .88), + fontWeight: FontWeight.w400), patternList: [ EasyRichTextPattern( targetString: r'"免费\+豪奖"双重奖励', @@ -806,13 +893,18 @@ class MineSignView extends StatelessWidget { height: 18, alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 6), - decoration: BoxDecoration(color: const Color(0xFFFFD900), borderRadius: BorderRadius.circular(12)), + decoration: BoxDecoration( + color: const Color(0xFFFFD900), + borderRadius: BorderRadius.circular(12)), child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text( '开通会员', - style: TextStyle(fontSize: 10, color: Color(0xFF111111), fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 10, + color: Color(0xFF111111), + fontWeight: FontWeight.w500), ), 4.sizeBoxW, Image.asset('ic_vip_enter.png'.mineImgPath, width: 12), @@ -842,7 +934,8 @@ class _SignInRow extends StatelessWidget { final List list; final MineSignLogic? logic; - const _SignInRow(this.type, {required this.controller, required this.list, this.logic}); + const _SignInRow(this.type, + {required this.controller, required this.list, this.logic}); bool get _isTitle => type == _SignRowType.title; bool get _isVip => type == _SignRowType.vip; @@ -859,7 +952,10 @@ class _SignInRow extends StatelessWidget { ? const Color(0xffFFDA0B).withValues(alpha: .08) : Colors.white.withValues(alpha: .05), borderRadius: BorderRadius.circular(_isTitle ? 0 : 18), - border: _isVip ? const Border(bottom: BorderSide(color: Color(0x99FFD900), width: 1)) : null, + border: _isVip + ? const Border( + bottom: BorderSide(color: Color(0x99FFD900), width: 1)) + : null, ), child: Column( children: [ @@ -877,7 +973,10 @@ class _SignInRow extends StatelessWidget { Divider(height: 1, color: Colors.white.withValues(alpha: .1)), 4.sizeBoxH, Image.asset( - (type == _SignRowType.normal ? 'no_vip_bottom.webp' : 'vip_bottom.webp').mineImgPath, + (type == _SignRowType.normal + ? 'no_vip_bottom.webp' + : 'vip_bottom.webp') + .mineImgPath, height: 20, ), ], @@ -889,19 +988,24 @@ class _SignInRow extends StatelessWidget { Widget _buildCell(CheckinPrize prize, int i) { if (_isTitle) { // 顶部标签:已签到灰底,未签到金底;今日未签到时该格显示"今天" - final isTodayCell = logic != null && !logic!.isSigned && i == logic!.continuousDays; + final isTodayCell = + logic != null && !logic!.isSigned && i == logic!.continuousDays; return Container( width: 42, margin: const EdgeInsets.only(right: 6), alignment: Alignment.center, decoration: BoxDecoration( - color: prize.isCheckedIn == true ? Colors.white.withValues(alpha: .1) : const Color(0xffFFD900), + color: prize.isCheckedIn == true + ? Colors.white.withValues(alpha: .1) + : const Color(0xffFFD900), borderRadius: BorderRadius.circular(4), ), child: Text( isTodayCell ? '今天' : '第${i + 1}天', style: TextStyle( - color: prize.isCheckedIn == true ? const Color(0xff999999) : const Color(0xff62020E), + color: prize.isCheckedIn == true + ? const Color(0xff999999) + : const Color(0xff62020E), fontSize: 10, ), ), @@ -927,7 +1031,9 @@ class _SignDayItem extends StatelessWidget { /// 灰度滤镜规则:会员行需 isCheckedIn && isReceive 才置灰;普通行只看 isCheckedIn ColorFilter get _filter { if (isVipRow) { - return (model.isCheckedIn == true && model.isReceive == true) ? _kGrayFilter : (model.isExpired == true ? _kGrayFilter : _kNoFilter); + return (model.isCheckedIn == true && model.isReceive == true) + ? _kGrayFilter + : (model.isExpired == true ? _kGrayFilter : _kNoFilter); } return model.isCheckedIn == true ? _kGrayFilter : _kNoFilter; } @@ -937,9 +1043,13 @@ class _SignDayItem extends StatelessWidget { if (isVipRow) { return (model.isCheckedIn == true && model.isReceive == true) ? 'checked_in_coin.webp'.mineImgPath - : (model.isExpired == true ? 'checked_in_coin.webp'.mineImgPath : 'check_in_coin.webp'.mineImgPath); + : (model.isExpired == true + ? 'checked_in_coin.webp'.mineImgPath + : 'check_in_coin.webp'.mineImgPath); } - return model.isCheckedIn == true ? 'checked_in_coin.webp'.mineImgPath : 'check_in_coin.webp'.mineImgPath; + return model.isCheckedIn == true + ? 'checked_in_coin.webp'.mineImgPath + : 'check_in_coin.webp'.mineImgPath; } @override @@ -955,7 +1065,10 @@ class _SignDayItem extends StatelessWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: const Color(0x0DFFFFFF), - border: isVipRow ? const Border(bottom: BorderSide(color: Color(0x99FFD900), width: 1)) : null, + border: isVipRow + ? const Border( + bottom: BorderSide(color: Color(0x99FFD900), width: 1)) + : null, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -977,11 +1090,18 @@ class _SignDayItem extends StatelessWidget { hasImg ? ColorFiltered( colorFilter: _filter, - child: NetworkImageLoader(width: 34, height: 34, fit: BoxFit.contain, imageUrl: model.image!), + child: NetworkImageLoader( + width: 34, + height: 34, + fit: BoxFit.contain, + imageUrl: model.image!), ) - : Image.asset(_defaultImg, width: 34, height: 34, fit: BoxFit.contain), + : Image.asset(_defaultImg, + width: 34, height: 34, fit: BoxFit.contain), //覆盖在上面的过期图标 - if (model.isExpired == true) Image.asset("ic_sign_expired.webp".mineImgPath, width: 31, height: 31, fit: BoxFit.contain) + if (model.isExpired == true) + Image.asset("ic_sign_expired.webp".mineImgPath, + width: 31, height: 31, fit: BoxFit.contain) ], ), @@ -992,7 +1112,9 @@ class _SignDayItem extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10, - color: model.isCheckedIn == true ? Colors.white : const Color(0xFFFFD900), + color: model.isCheckedIn == true + ? Colors.white + : const Color(0xFFFFD900), ), ), ], @@ -1000,7 +1122,11 @@ class _SignDayItem extends StatelessWidget { ), // 非 VIP 用户在 VIP 行显示锁 if (!globalStore.isVIP && isVipRow) - Positioned(left: 0, top: 0, child: Image.asset('ic_sign_lock.png'.mineImgPath, width: 18, height: 18)), + Positioned( + left: 0, + top: 0, + child: Image.asset('ic_sign_lock.png'.mineImgPath, + width: 18, height: 18)), // 可补领标识 if (isVipRow && model.canClaim == true) Positioned( @@ -1011,11 +1137,17 @@ class _SignDayItem extends StatelessWidget { child: GestureDetector( onTap: () => logic?.doCheckinClaimVip(), child: Container( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), - decoration: BoxDecoration(color: const Color(0xffD70000), borderRadius: BorderRadius.circular(4)), + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 1), + decoration: BoxDecoration( + color: const Color(0xffD70000), + borderRadius: BorderRadius.circular(4)), child: const Text( '补领', - style: TextStyle(color: Colors.white, fontSize: 8, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white, + fontSize: 8, + fontWeight: FontWeight.w500), ), ), ), @@ -1023,7 +1155,10 @@ class _SignDayItem extends StatelessWidget { ), // 高 VIP 等级 + 普通行:显示 +1 标识 if ((globalStore.meInfo?.vipLevel ?? 0) >= 1 && !isVipRow) - Positioned(top: 6, right: 2, child: Image.asset('ic_add2.png'.mineImgPath, width: 11)), + Positioned( + top: 6, + right: 2, + child: Image.asset('ic_add2.png'.mineImgPath, width: 11)), ], ), ); diff --git a/lib/hj_page/mine/widgets/exchange_vip_page.dart b/lib/hj_page/mine/widgets/exchange_vip_page.dart index 2b975eb..e94b1cd 100644 --- a/lib/hj_page/mine/widgets/exchange_vip_page.dart +++ b/lib/hj_page/mine/widgets/exchange_vip_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import '../../../hj_model/mine/credit_record_model.dart'; import 'integral_record_logic.dart'; @@ -30,11 +30,13 @@ class _ExchangeVipPageState extends State { children: [ Expanded( child: pullYsRefresh( - onInit: (controller) => _.refreshController = controller, + onInit: (controller) => + _.refreshController = controller, onRefresh: (controller) => _.loadData(), onLoading: (controller) => _.loadMoreData(), child: CustomScrollView( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, slivers: [ ...[ _buildHistoryTable(_), @@ -92,7 +94,10 @@ class _ExchangeVipPageState extends State { children: [ Text( item.desc ?? '', - style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500), ), Text( DateTimeUtil.utcTurnYear(item.createdAt), @@ -105,7 +110,10 @@ class _ExchangeVipPageState extends State { "${item.integral ?? 0}积分", maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(color: Color(0xffFFC000), fontSize: 12, fontWeight: FontWeight.w500), + style: TextStyle( + color: Color(0xffFFC000), + fontSize: 12, + fontWeight: FontWeight.w500), ), ], ), diff --git a/lib/hj_page/mine/widgets/integral_exchange_page.dart b/lib/hj_page/mine/widgets/integral_exchange_page.dart index 6f4fe10..f088b3b 100644 --- a/lib/hj_page/mine/widgets/integral_exchange_page.dart +++ b/lib/hj_page/mine/widgets/integral_exchange_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/mine/task_center_data.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/hj_model/mine/task_center_data.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import '../../../tools_base/loading/loading_helper.dart'; import '../../../tools_base/widget/net_image_widget.dart'; @@ -41,14 +41,16 @@ class IntegralExchangePage extends StatelessWidget { color: Color(0xff303030), borderRadius: BorderRadius.circular(9), ), - padding: EdgeInsets.only(left: 12.w, right: 12.w, top: 16.h, bottom: 9.h), + padding: EdgeInsets.only( + left: 12.w, right: 12.w, top: 16.h, bottom: 9.h), width: double.infinity, height: double.infinity, child: Column( children: [ Expanded( child: ClipRRect( - borderRadius: BorderRadius.vertical(top: Radius.circular(9)), + borderRadius: + BorderRadius.vertical(top: Radius.circular(9)), child: Stack( alignment: Alignment.centerLeft, children: [ @@ -68,17 +70,22 @@ class IntegralExchangePage extends StatelessWidget { Expanded( child: Text( '花费${model?.price ?? 0}积分', - style: TextStyle(color: Color(0xFF989898), fontSize: 14.sp), + style: TextStyle( + color: Color(0xFF989898), fontSize: 14.sp), ), ), GestureDetector( onTap: () => onExchange(model!), child: Container( - padding: EdgeInsets.symmetric(horizontal: 9.w, vertical: 3.h), - decoration: BoxDecoration(color: Color(0xffFFC000), borderRadius: BorderRadius.circular(11)), + padding: EdgeInsets.symmetric( + horizontal: 9.w, vertical: 3.h), + decoration: BoxDecoration( + color: Color(0xffFFC000), + borderRadius: BorderRadius.circular(11)), child: Text( '立即兑换', - style: TextStyle(color: Color(0xFF141414), fontSize: 12.sp), + style: TextStyle( + color: Color(0xFF141414), fontSize: 12.sp), ), ), ) diff --git a/lib/hj_page/mine/widgets/integral_record_logic.dart b/lib/hj_page/mine/widgets/integral_record_logic.dart index b902773..1047a7e 100644 --- a/lib/hj_page/mine/widgets/integral_record_logic.dart +++ b/lib/hj_page/mine/widgets/integral_record_logic.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_model/mine/credit_record_model.dart'; @@ -21,14 +21,17 @@ class IntegralRecordLogic extends GetxController { void loadData({int page = 1}) async { try { - final res = await MineService.getCreditRecords(pageNumber: page, pageSize: 20); + final res = + await MineService.getCreditRecords(pageNumber: page, pageSize: 20); if (res.isNotEmpty) { if (page == 1) groupList.clear(); currentPage = page; groupList.addAll(res); } refreshController?.refreshCompleted(); - (res.length) < 20 ? refreshController?.loadNoData() : refreshController?.loadComplete(); + (res.length) < 20 + ? refreshController?.loadNoData() + : refreshController?.loadComplete(); } catch (e) { refreshController?.refreshCompleted(); refreshController?.loadComplete(); diff --git a/lib/hj_page/mine/widgets/mine_info_widget.dart b/lib/hj_page/mine/widgets/mine_info_widget.dart index 7b4abba..dd50eb3 100644 --- a/lib/hj_page/mine/widgets/mine_info_widget.dart +++ b/lib/hj_page/mine/widgets/mine_info_widget.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:provider/provider.dart'; import '../../home/widget/user_avatar.dart'; @@ -65,7 +65,8 @@ class MineInfoWidget extends StatelessWidget { ), ), 8.sizeBoxW, - if (store.isVIP && vipIcon.isNotEmpty) Image.asset(vipIcon, height: 20), + if (store.isVIP && vipIcon.isNotEmpty) + Image.asset(vipIcon, height: 20), ], ); }, @@ -74,7 +75,8 @@ class MineInfoWidget extends StatelessWidget { InkWell( enableFeedback: false, onTap: () { - Clipboard.setData(ClipboardData(text: (logic.userInfo?.uid ?? 0).toString())); + Clipboard.setData(ClipboardData( + text: (logic.userInfo?.uid ?? 0).toString())); showToast('复制成功'); }, child: Text( @@ -100,7 +102,9 @@ class MineInfoWidget extends StatelessWidget { padding: EdgeInsets.symmetric(vertical: 5), decoration: BoxDecoration( color: Color(0xFFF68804), - borderRadius: BorderRadius.only(topLeft: Radius.circular(15), bottomLeft: Radius.circular(15))), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(15), + bottomLeft: Radius.circular(15))), margin: EdgeInsets.only(left: 30, top: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -153,7 +157,8 @@ class MineTaskMenuWidget extends StatelessWidget { final items = [ InkWell( enableFeedback: false, - onTap: () => Get.to(() => MineChargeVipPage(), preventDuplicates: false), + onTap: () => + Get.to(() => MineChargeVipPage(), preventDuplicates: false), child: _buildItem("", 'mine_vip_enter.webp'.mineImgPath, 0), ), InkWell( @@ -227,7 +232,10 @@ class MineTaskMenuWidget extends StatelessWidget { bottom: 10, child: Text( title, - style: TextStyle(fontSize: 10, color: Colors.white.withValues(alpha: .55), fontWeight: FontWeight.w400), + style: TextStyle( + fontSize: 10, + color: Colors.white.withValues(alpha: .55), + fontWeight: FontWeight.w400), ), ), ], @@ -240,12 +248,17 @@ class MineFunchtionGridView extends StatelessWidget { /// 处理 final functionLabels = ['历史记录', '我的购买', '我的收藏', '我的喜欢']; - final functionImgs = ['mine_collect.png', 'mine_menu_3.png', 'mine_post.png', 'mine_menu_4.png']; + final functionImgs = [ + 'mine_collect.png', + 'mine_menu_3.png', + 'mine_post.png', + 'mine_menu_4.png' + ]; final functions = [ - () => ColHisBuyPage.to(PageType.history), - () => ColHisBuyPage.to(PageType.buy), - () => ColHisBuyPage.to(PageType.collect), - () => ColHisBuyPage.to(PageType.like), + () => ColHisBuyPage.to(PageType.history), + () => ColHisBuyPage.to(PageType.buy), + () => ColHisBuyPage.to(PageType.collect), + () => ColHisBuyPage.to(PageType.like), ]; @override diff --git a/lib/hj_page/mine/widgets/mine_share_qr_view.dart b/lib/hj_page/mine/widgets/mine_share_qr_view.dart index 5d9fa4a..7317be4 100644 --- a/lib/hj_page/mine/widgets/mine_share_qr_view.dart +++ b/lib/hj_page/mine/widgets/mine_share_qr_view.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import 'package:provider/provider.dart'; import 'package:qr_flutter/qr_flutter.dart'; import '../../../config/address.dart'; import '../../../config/config.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../hj_utils/image_util.dart'; import '../../../tools_base/widget/net_image_widget.dart'; @@ -161,7 +161,8 @@ class _MineShareQRViewState extends State { ), ), 20.sizeBoxH, - InkWell(enableFeedback: false, + InkWell( + enableFeedback: false, onTap: () async { final ok = await ImageUtil.saveWidgetToAlbum(boundaryKey); showToast(ok ? "保存成功" : "保存失败,请重试"); diff --git a/lib/hj_page/mine/widgets/stage_cell_widget.dart b/lib/hj_page/mine/widgets/stage_cell_widget.dart index 7cb5c80..6d937ab 100644 --- a/lib/hj_page/mine/widgets/stage_cell_widget.dart +++ b/lib/hj_page/mine/widgets/stage_cell_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../../hj_model/home/collection_model.dart'; diff --git a/lib/hj_page/mine/widgets/vip_entry_card.dart b/lib/hj_page/mine/widgets/vip_entry_card.dart index f09178f..34a0760 100644 --- a/lib/hj_page/mine/widgets/vip_entry_card.dart +++ b/lib/hj_page/mine/widgets/vip_entry_card.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../../tools_base/global_store/store.dart'; @@ -55,15 +55,20 @@ class VipEntryCard extends StatelessWidget { ), Consumer2( builder: (context, global, provider, child) { - final isUpgrade = global.isVIP && global.meInfo?.isUpgrade == true; - if (global.isVIP) return _vipRow(global, isUpgrade: isUpgrade); + final isUpgrade = + global.isVIP && global.meInfo?.isUpgrade == true; + if (global.isVIP) + return _vipRow(global, isUpgrade: isUpgrade); // 倒计时态/默认态的切换跟着 tick 走,过期当帧即收起,不必等分层配置刷新回来 return ValueListenableBuilder( valueListenable: provider.tick, builder: (_, __, ___) { final cd = provider.countdownConfig; if (cd != null) return _newerRow(cd); - return _titleRow(title: '开通会员 享专属特权', subtitle: '解锁专属 畅享无限', buttonText: '开通会员'); + return _titleRow( + title: '开通会员 享专属特权', + subtitle: '解锁专属 畅享无限', + buttonText: '开通会员'); }, ); }, @@ -92,12 +97,17 @@ class VipEntryCard extends StatelessWidget { child: Stack( children: [ NetworkImageLoader( - imageUrl: config.meTab ?? "", width: 343, height: 64, fit: BoxFit.fill, borderRadius: 0), + imageUrl: config.meTab ?? "", + width: 343, + height: 64, + fit: BoxFit.fill, + borderRadius: 0), // 倒计时块监听 tick 每秒刷新(过期自动收起) ValueListenableBuilder( valueListenable: MineMsgProvider().tick, - builder: (_, __, ___) => - config.hasDiscountCountdown ? _layeredCountdown(config) : const SizedBox.shrink(), + builder: (_, __, ___) => config.hasDiscountCountdown + ? _layeredCountdown(config) + : const SizedBox.shrink(), ), ], ), @@ -136,7 +146,8 @@ class VipEntryCard extends StatelessWidget { borderRadius: BorderRadius.circular(3), border: Border.all(color: const Color(0xffFFE381), width: 0.5), ), - child: Text(value, style: const TextStyle(color: Colors.white, fontSize: 12)), + child: Text(value, + style: const TextStyle(color: Colors.white, fontSize: 12)), ); } @@ -169,7 +180,8 @@ class VipEntryCard extends StatelessWidget { } return _titleRow( title: '$vipTitle会员', - subtitle: '到期时间:${DateTimeUtil.utcTurnYear(global.meInfo?.vipExpireDate, char: ".")}', + subtitle: + '到期时间:${DateTimeUtil.utcTurnYear(global.meInfo?.vipExpireDate, char: ".")}', buttonText: isUpgrade ? '补差价升级' : '会员中心', onButtonTap: isUpgrade ? () => Get.to(() => MineChargeVipPage()) : null, ); @@ -177,14 +189,18 @@ class VipEntryCard extends StatelessWidget { //通用布局:标题+副标题+按钮 Widget _titleRow( - {required String title, required String subtitle, required String buttonText, VoidCallback? onButtonTap}) { + {required String title, + required String subtitle, + required String buttonText, + VoidCallback? onButtonTap}) { return _cardRow( left: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ _goldText(title, 16), - Text(subtitle, style: TextStyle(fontSize: 10, color: Color(0xFFE9E8E7))), + Text(subtitle, + style: TextStyle(fontSize: 10, color: Color(0xFFE9E8E7))), ], ), buttonText: buttonText, @@ -192,7 +208,10 @@ class VipEntryCard extends StatelessWidget { ); } - Widget _cardRow({required Widget left, required String buttonText, VoidCallback? onButtonTap}) { + Widget _cardRow( + {required Widget left, + required String buttonText, + VoidCallback? onButtonTap}) { return Container( padding: EdgeInsets.only(left: 60, right: 16), alignment: Alignment.centerLeft, @@ -208,7 +227,8 @@ class VipEntryCard extends StatelessWidget { Widget _button(String text, {VoidCallback? onTap}) { return GestureDetector( onTap: onTap, - behavior: onTap != null ? HitTestBehavior.opaque : HitTestBehavior.translucent, + behavior: + onTap != null ? HitTestBehavior.opaque : HitTestBehavior.translucent, child: Container( alignment: Alignment.center, height: 26, @@ -222,7 +242,10 @@ class VipEntryCard extends StatelessWidget { ), child: Text( text, - style: TextStyle(fontSize: 10, color: Color(0xFF000000), fontWeight: FontWeight.w600), + style: TextStyle( + fontSize: 10, + color: Color(0xFF000000), + fontWeight: FontWeight.w600), ), ), ); @@ -235,7 +258,8 @@ class VipEntryCard extends StatelessWidget { colors: [Color(0xffFAE6D2), Color(0xffFFFFFF)], ).createShader(bounds), blendMode: BlendMode.srcIn, - child: Text(text, style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.w600)), + child: Text(text, + style: TextStyle(fontSize: fontSize, fontWeight: FontWeight.w600)), ); } @@ -259,8 +283,10 @@ class VipEntryCard extends StatelessWidget { Widget _timeUnit(String val) => Padding( padding: EdgeInsets.symmetric(horizontal: 2), - child: Text(val, style: TextStyle(fontSize: 12, color: Color(0xFFFF844D))), + child: + Text(val, style: TextStyle(fontSize: 12, color: Color(0xFFFF844D))), ); - Widget _timeColon() => Text(":", style: TextStyle(fontSize: 10, color: Color(0xFFFF844D))); + Widget _timeColon() => + Text(":", style: TextStyle(fontSize: 10, color: Color(0xFFFF844D))); } diff --git a/lib/hj_page/pre_sale/limit_time_provider.dart b/lib/hj_page/pre_sale/limit_time_provider.dart index e0f56a4..547177e 100644 --- a/lib/hj_page/pre_sale/limit_time_provider.dart +++ b/lib/hj_page/pre_sale/limit_time_provider.dart @@ -1,12 +1,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; -import 'package:hgmj/hj_utils/widget_util.dart'; +import 'package:wydj/hj_utils/widget_util.dart'; final limitTimeProvider = LimitTimeProvider(); @@ -26,7 +26,8 @@ class LimitTimeProvider extends ChangeNotifier { final deadline = ValueNotifier(''); /// 距截止时间的剩余秒数 - int get endSeconds => bannerJump?.additionalProp?.endAt?.remainingSeconds() ?? -1; + int get endSeconds => + bannerJump?.additionalProp?.endAt?.remainingSeconds() ?? -1; //是否展示活动 后台返回bannerjump && 结束时间未到 bool get canShow => bannerJump != null && endSeconds > 0; @@ -77,8 +78,11 @@ class LimitTimeBanner extends StatelessWidget { Positioned( right: 12, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 3), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(99), color: Colors.black.withValues(alpha: 0.2)), + padding: + const EdgeInsets.symmetric(horizontal: 18, vertical: 3), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(99), + color: Colors.black.withValues(alpha: 0.2)), child: ValueListenableBuilder( valueListenable: limitTimeProvider.deadline, builder: (_, value, __) => Text( diff --git a/lib/hj_page/pre_sale/pre_sale_alert.dart b/lib/hj_page/pre_sale/pre_sale_alert.dart index aa8ad60..291bd7d 100644 --- a/lib/hj_page/pre_sale/pre_sale_alert.dart +++ b/lib/hj_page/pre_sale/pre_sale_alert.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_page.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_page.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import 'pre_sale_provider.dart'; diff --git a/lib/hj_page/pre_sale/pre_sale_entry.dart b/lib/hj_page/pre_sale/pre_sale_entry.dart index 8ddbe8a..9581ea0 100644 --- a/lib/hj_page/pre_sale/pre_sale_entry.dart +++ b/lib/hj_page/pre_sale/pre_sale_entry.dart @@ -2,8 +2,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import 'pre_sale_page.dart'; @@ -17,7 +17,8 @@ class PreSaleEntry extends StatefulWidget { State createState() => _PreSaleEntryState(); } -class _PreSaleEntryState extends State with SingleTickerProviderStateMixin { +class _PreSaleEntryState extends State + with SingleTickerProviderStateMixin { //不能写成惰性 late:不展示时 build 不碰它,到 dispose 才首次创建会在已卸载的树上找 TickerMode late final AnimationController _aniCtr; late final Animation _scaleAni; @@ -26,9 +27,12 @@ class _PreSaleEntryState extends State with SingleTickerProviderSt @override void initState() { super.initState(); - _aniCtr = AnimationController(vsync: this, duration: const Duration(milliseconds: 900)); - _scaleAni = Tween(begin: 1, end: 1.02).animate(CurvedAnimation(parent: _aniCtr, curve: const Interval(0, 0.8))); - _rotateAni = Tween(begin: 0, end: 2 * pi).animate(CurvedAnimation(parent: _aniCtr, curve: const Interval(0.8, 1))); + _aniCtr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 900)); + _scaleAni = Tween(begin: 1, end: 1.02).animate( + CurvedAnimation(parent: _aniCtr, curve: const Interval(0, 0.8))); + _rotateAni = Tween(begin: 0, end: 2 * pi).animate( + CurvedAnimation(parent: _aniCtr, curve: const Interval(0.8, 1))); if (PreSaleProvider().canShowEnter) _aniCtr.repeat(reverse: true); } @@ -51,7 +55,8 @@ class _PreSaleEntryState extends State with SingleTickerProviderSt builder: (_, __) => Transform( transform: Matrix4.rotationZ(sin(0.2 * sin(_rotateAni.value))), alignment: Alignment.center, - child: NetworkImageLoader(imageUrl: provider.enterBg, width: 65 * _scaleAni.value), + child: NetworkImageLoader( + imageUrl: provider.enterBg, width: 65 * _scaleAni.value), ), ), ); @@ -73,7 +78,11 @@ class PreSaleVipEntry extends StatelessWidget { if (!provider.canShowEnter) return const SizedBox.shrink(); return Stack( children: [ - NetworkImageLoader(imageUrl: provider.payBanner, width: double.infinity, fit: BoxFit.fill, height: 76), + NetworkImageLoader( + imageUrl: provider.payBanner, + width: double.infinity, + fit: BoxFit.fill, + height: 76), //尾款期叠倒计时 if (provider.canPayBalance) Positioned( @@ -83,7 +92,10 @@ class PreSaleVipEntry extends StatelessWidget { valueListenable: provider.deadline, builder: (_, value, __) => Text( '剩余 $value', - style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700), + style: const TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w700), ), ), ), @@ -103,7 +115,8 @@ class LuckyDrawButton extends StatelessWidget { @override Widget build(BuildContext context) { - if (presaleProvider.luckyDrawH5?.isNotEmpty != true) return const SizedBox(); + if (presaleProvider.luckyDrawH5?.isNotEmpty != true) + return const SizedBox(); final icon = presaleProvider.luckyDrawIcon; return Container( margin: margin, diff --git a/lib/hj_page/pre_sale/pre_sale_page.dart b/lib/hj_page/pre_sale/pre_sale_page.dart index 931203e..1bf8719 100644 --- a/lib/hj_page/pre_sale/pre_sale_page.dart +++ b/lib/hj_page/pre_sale/pre_sale_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../hj_utils/screen.dart'; @@ -31,7 +31,8 @@ class _PreSalePageState extends State with UniqueTagMixin { init: PreSaleLogic(), builder: (logic) { if (logic.isLoading) return const LoadingCenterWidget(); - if (logic.pageData == null) return CErrorWidget(retryOnTap: logic.loadData); + if (logic.pageData == null) + return CErrorWidget(retryOnTap: logic.loadData); return Consumer( builder: (_, provider, __) => Stack( children: [ @@ -67,7 +68,9 @@ class _PreSalePageState extends State with UniqueTagMixin { child: Container( padding: const EdgeInsets.symmetric(horizontal: 44), height: 46, - child: logic.useActivityBtn ? PreSaleActivityButton(onTap: logic.onPay) : _upgradeButton(logic), + child: logic.useActivityBtn + ? PreSaleActivityButton(onTap: logic.onPay) + : _upgradeButton(logic), ), ), //返回 @@ -77,7 +80,8 @@ class _PreSalePageState extends State with UniqueTagMixin { child: InkWell( enableFeedback: false, onTap: Get.back, - child: const Icon(Icons.arrow_back_ios_sharp, size: 18, color: Colors.white), + child: const Icon(Icons.arrow_back_ios_sharp, + size: 18, color: Colors.white), ), ), ], @@ -138,7 +142,10 @@ class _PreSalePageState extends State with UniqueTagMixin { ), child: Text( logic.payText, - style: const TextStyle(color: Color(0xFFFFF0D3), fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xFFFFF0D3), + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ); @@ -158,7 +165,9 @@ class _PreSalePageState extends State with UniqueTagMixin { top: 10, bottom: 0, child: DecoratedBox( - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(8))), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8))), ), ), Positioned.fill( @@ -170,7 +179,12 @@ class _PreSalePageState extends State with UniqueTagMixin { margin: const EdgeInsets.symmetric(horizontal: 3.5), padding: const EdgeInsets.all(4), decoration: BoxDecoration( - boxShadow: [BoxShadow(color: const Color(0xffD43824).withValues(alpha: .2), blurRadius: 2)], + boxShadow: [ + BoxShadow( + color: + const Color(0xffD43824).withValues(alpha: .2), + blurRadius: 2) + ], color: Colors.white, borderRadius: BorderRadius.circular(8), ), @@ -180,7 +194,10 @@ class _PreSalePageState extends State with UniqueTagMixin { //标题 Text( '${video.vidTitle}', - style: const TextStyle(color: Color(0xffDA0101), fontWeight: FontWeight.w500, fontSize: 12), + style: const TextStyle( + color: Color(0xffDA0101), + fontWeight: FontWeight.w500, + fontSize: 12), overflow: TextOverflow.ellipsis, maxLines: 1, ).paddingSymmetric(horizontal: 15, vertical: 3), @@ -189,7 +206,12 @@ class _PreSalePageState extends State with UniqueTagMixin { height: 25, margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( - boxShadow: [BoxShadow(color: const Color(0xffD43824).withValues(alpha: .2), blurRadius: 2)], + boxShadow: [ + BoxShadow( + color: + const Color(0xffD43824).withValues(alpha: .2), + blurRadius: 2) + ], gradient: const LinearGradient( colors: [Color(0xffFFF7E9), Color(0xffF9DC9A)], begin: Alignment.topLeft, @@ -203,7 +225,10 @@ class _PreSalePageState extends State with UniqueTagMixin { 10.sizeBoxW, const Text( '免费', - style: TextStyle(color: Color(0xffDA0101), fontSize: 14, fontWeight: FontWeight.w600), + style: TextStyle( + color: Color(0xffDA0101), + fontSize: 14, + fontWeight: FontWeight.w600), ), 10.sizeBoxW, Expanded( diff --git a/lib/hj_page/pre_sale/pre_sale_provider.dart b/lib/hj_page/pre_sale/pre_sale_provider.dart index a1d2a88..8aebcf1 100644 --- a/lib/hj_page/pre_sale/pre_sale_provider.dart +++ b/lib/hj_page/pre_sale/pre_sale_provider.dart @@ -2,12 +2,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_page/web_page/h5_page.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_page/web_page/h5_page.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../hj_model/splash/domain_source_model.dart'; import '../../hj_model/video_model.dart'; @@ -83,19 +83,23 @@ class PreSaleProvider extends ChangeNotifier { return status == 2 || status == 3; //支付首款未付尾款 } - bool get balancePayment => preSaleModel?.detailModel?.balancePayment ?? false; //是否有尾款支付 + bool get balancePayment => + preSaleModel?.detailModel?.balancePayment ?? false; //是否有尾款支付 - bool get hasLimit => advanceStatus?.privilegeLimit?.hasLimit ?? false; //是否有权益限制 + bool get hasLimit => + advanceStatus?.privilegeLimit?.hasLimit ?? false; //是否有权益限制 Remain? get remain => advanceStatus?.privilegeLimit?.remain; //剩余权限次数 String? get startTimeMD => preSaleModel?.detailModel?.startTime?.utcToCnMD(); /// 开始时间已过秒数。> 0 表示已到达开始时间 - int get _startSeconds => preSaleModel?.detailModel?.startTime?.elapsedSeconds() ?? -1; + int get _startSeconds => + preSaleModel?.detailModel?.startTime?.elapsedSeconds() ?? -1; /// 距截止时间的剩余秒数 - int get endSeconds => preSaleModel?.detailModel?.endTime?.remainingSeconds() ?? -1; + int get endSeconds => + preSaleModel?.detailModel?.endTime?.remainingSeconds() ?? -1; /// 是否可以支付尾款 bool get canPayBalance => isPayFirst && _startSeconds > 0; @@ -125,15 +129,21 @@ class PreSaleProvider extends ChangeNotifier { } /// 预售小图标入口背景图 - String get enterBg => balancePayment ? advancePage?.enterBgProc ?? '' : advancePage?.enterBgWait ?? ''; + String get enterBg => balancePayment + ? advancePage?.enterBgProc ?? '' + : advancePage?.enterBgWait ?? ''; /// 首页弹窗背景图(整张图就是弹窗内容) - String get popBg => balancePayment ? advancePage?.popBgProc ?? '' : advancePage?.popBgWait ?? ''; + String get popBg => balancePayment + ? advancePage?.popBgProc ?? '' + : advancePage?.popBgWait ?? ''; /// 预售 banner String get payBanner { if (!balancePayment) return advancePage?.banner ?? ''; //开启预定 - return canPayBalance ? advancePage?.bannerProc ?? '' : advancePage?.bannerWait ?? ''; //开启支付尾款 + return canPayBalance + ? advancePage?.bannerProc ?? '' + : advancePage?.bannerWait ?? ''; //开启支付尾款 } // ===== 数据刷新 ===== @@ -167,12 +177,14 @@ class PreSaleProvider extends ChangeNotifier { final status = preSaleModel?.detailModel?.status ?? -1; if (status == -1 || status == 4) return; //未知或者已经完成 //预定期直接弹;尾款期只在能付尾款时弹。两期的图由 popBg 自己分流 - if (!balancePayment || canPayBalance) await Get.dialog(const PreSaleAlert()); + if (!balancePayment || canPayBalance) + await Get.dialog(const PreSaleAlert()); } // 拉起支付 /// [orderTrack] 透传下单埋点(会员中心传入 sessionId / 实验字段;预售独立页可不传) - Future startPay(VipProductModel model, {PayOrderTrackInfo? orderTrack}) async { + Future startPay(VipProductModel model, + {PayOrderTrackInfo? orderTrack}) async { if (isPayFirst && _startSeconds <= 0) { showToast("还未到尾款支付时间,无法支付~"); return; @@ -182,9 +194,11 @@ class PreSaleProvider extends ChangeNotifier { return; } //copyWith 原样带上短剧付费墙等归因字段,只补默认来源页 - final track = (orderTrack ?? const PayOrderTrackInfo()).copyWith(sourcePage: orderTrack?.sourcePage ?? PaySourcePage.vipCenter); + final track = (orderTrack ?? const PayOrderTrackInfo()).copyWith( + sourcePage: orderTrack?.sourcePage ?? PaySourcePage.vipCenter); await Get.bottomSheet( - OnlinePayPage(vipProductModel: model..isPreSale = true, orderTrack: track), + OnlinePayPage( + vipProductModel: model..isPreSale = true, orderTrack: track), isScrollControlled: true, ); await refreshConfig(); @@ -194,12 +208,15 @@ class PreSaleProvider extends ChangeNotifier { Future useCoinPrivilege(VideoModel? video) async { if (video?.videoType == 1) return; // 动漫视频不享受金币权益 if (video?.freeArea == true) return; - if (video?.isCoinVideo() != true || (video?.coins ?? 0) <= 0 || video?.vidStatus?.hasPaid == true) return; + if (video?.isCoinVideo() != true || + (video?.coins ?? 0) <= 0 || + video?.vidStatus?.hasPaid == true) return; if (!isOpen || isPayAll || !hasLimit) return; //没有首款权益 final count = remain?.todayCoinVideoCount ?? 0; remain?.reduceVideoCoinCount(); //有无次数都先本地减,取数要在减之前 if (count <= 0) return; //已无次数,不必再调接口 - final resp = await PreSaleService.consumePrivilege(type: PrivilegeType.coinVideo); + final resp = + await PreSaleService.consumePrivilege(type: PrivilegeType.coinVideo); if (resp.isSuccess) { debugLog("权益次数消费成功: ${remain?.todayCoinVideoCount}"); } @@ -228,7 +245,8 @@ class PreSaleProvider extends ChangeNotifier { _timer?.cancel(); // 防重入:先清掉已有定时器,杜绝多重泄漏 _timer = Timer.periodic(const Duration(seconds: 1), (timer) { // 每秒只更新 deadline,交给 ValueListenableBuilder 局部刷新,不触发全局 notifyListeners - deadline.value = preSaleModel?.detailModel?.endTime?.countdownText() ?? ''; + deadline.value = + preSaleModel?.detailModel?.endTime?.countdownText() ?? ''; if (endSeconds < 0) { timer.cancel(); _timer = null; diff --git a/lib/hj_page/pre_sale/pre_sale_service.dart b/lib/hj_page/pre_sale/pre_sale_service.dart index c98e8ef..2a3fbb9 100644 --- a/lib/hj_page/pre_sale/pre_sale_service.dart +++ b/lib/hj_page/pre_sale/pre_sale_service.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import 'pre_sale_model.dart'; diff --git a/lib/hj_page/short_video/short_main_video_page.dart b/lib/hj_page/short_video/short_main_video_page.dart index 76cc56f..a004b9e 100644 --- a/lib/hj_page/short_video/short_main_video_page.dart +++ b/lib/hj_page/short_video/short_main_video_page.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/short_video/short_main_video_logic.dart'; -import 'package:hgmj/hj_page/short_video/short_video_page.dart'; -import 'package:hgmj/hj_page/short_video/view/short_top_menu.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/short_video/short_main_video_logic.dart'; +import 'package:wydj/hj_page/short_video/short_video_page.dart'; +import 'package:wydj/hj_page/short_video/view/short_top_menu.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../drama/drama_feed_page.dart'; import '../drama/drama_list_page.dart'; @@ -28,7 +28,8 @@ class ShortVideoMainPage extends StatelessWidget { Positioned.fill( child: Obx( () => logic.tabIndex.value == 0 - ? Image.asset('live_main_bg2.webp'.livePath, alignment: Alignment.topCenter, fit: BoxFit.cover) + ? Image.asset('live_main_bg2.webp'.livePath, + alignment: Alignment.topCenter, fit: BoxFit.cover) : logic.tabIndex.value == kDramaHotTab ? const ColoredBox(color: Color(0xFF05000E)) : const SizedBox.shrink(), @@ -45,14 +46,28 @@ class ShortVideoMainPage extends StatelessWidget { physics: const NeverScrollableScrollPhysics(), //顺序必须与 kDramaTabs 一致。直播/热门短剧是普通页面,要给顶部菜单让位;两个信息流页自己铺满 children: [ - const Padding(padding: EdgeInsets.only(top: 44), child: LiveMainPage()), - ShortVideoPage(type: VideoListType.RECOMMEND, tabIndex: 1, superTabCtr: logic.tabCtr).keepAlive, - DramaFeedPage(tabIndex: 2, superTabCtr: logic.tabCtr).keepAlive, - const Padding(padding: EdgeInsets.only(top: 44), child: DramaListPage()).keepAlive, + const Padding( + padding: EdgeInsets.only(top: 44), + child: LiveMainPage()), + ShortVideoPage( + type: VideoListType.RECOMMEND, + tabIndex: 1, + superTabCtr: logic.tabCtr) + .keepAlive, + DramaFeedPage(tabIndex: 2, superTabCtr: logic.tabCtr) + .keepAlive, + const Padding( + padding: EdgeInsets.only(top: 44), + child: DramaListPage()) + .keepAlive, ], ), ), - Positioned(top: 0, left: 0, right: 0, child: ShortTopMenu(tabCtr: logic.tabCtr)), + Positioned( + top: 0, + left: 0, + right: 0, + child: ShortTopMenu(tabCtr: logic.tabCtr)), ], ), ), diff --git a/lib/hj_page/short_video/short_video_logic.dart b/lib/hj_page/short_video/short_video_logic.dart index 00e96cf..131f6c8 100644 --- a/lib/hj_page/short_video/short_video_logic.dart +++ b/lib/hj_page/short_video/short_video_logic.dart @@ -2,14 +2,14 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/short_video/short_video_page.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/vid_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/history_util.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/hj_page/short_video/short_video_page.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/vid_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/history_util.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import '../../hj_model/splash/ads_model.dart'; import '../../hj_model/video_model.dart'; @@ -88,7 +88,8 @@ class ShortVideoLogic extends GetxController { Future _loadVideoDetail() async { try { - VideoModel? videoModel = await VidService.getDetail(videoList?.first.id ?? ''); + VideoModel? videoModel = + await VidService.getDetail(videoList?.first.id ?? ''); if (videoModel != null) { secondVideoModel = videoModel; videoList?.removeAt(0); @@ -110,7 +111,8 @@ class ShortVideoLogic extends GetxController { loadData(isInit: true); } - Future loadData({int page = 1, int pageSize = 12, bool isInit = false}) async { + Future loadData( + {int page = 1, int pageSize = 12, bool isInit = false}) async { if (listType == VideoListType.SECOND) { return; } @@ -122,7 +124,8 @@ class ShortVideoLogic extends GetxController { List list = []; try { if (listType == VideoListType.FOLLOW) { - final resp = await CommonService.fetchFollowDynamics(page: page, size: pageSize, type: 1); + final resp = await CommonService.fetchFollowDynamics( + page: page, size: pageSize, type: 1); list = resp?.videos ?? []; hasNext = resp?.hasNext ?? false; } else { diff --git a/lib/hj_page/short_video/short_video_page.dart b/lib/hj_page/short_video/short_video_page.dart index 4a9d429..be0a4fc 100644 --- a/lib/hj_page/short_video/short_video_page.dart +++ b/lib/hj_page/short_video/short_video_page.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/short_video/short_video_logic.dart'; -import 'package:hgmj/hj_page/short_video/view/feed_ad_view.dart'; -import 'package:hgmj/hj_page/short_video/view/short_video_player.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/short_video/short_video_logic.dart'; +import 'package:wydj/hj_page/short_video/view/feed_ad_view.dart'; +import 'package:wydj/hj_page/short_video/view/short_video_player.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; /// SECOND 短视频只有一个视频(入参视频需要通过视频详情接口获取权限),需要加载推荐列表数据; /// SECONDList 传过来的不止一个视频,不需要加载推荐列表数据(列表视频数据,都需要视频详情接口获取权限); @@ -133,7 +133,8 @@ class _ShortVideoPageState extends State with UniqueTagMixin { Icons.arrow_back_ios, color: Colors.white, shadows: [ - Shadow(color: Colors.black, offset: Offset(1, 1), blurRadius: 1), + Shadow( + color: Colors.black, offset: Offset(1, 1), blurRadius: 1), ], ), onPressed: () => Get.back(), diff --git a/lib/hj_page/short_video/view/feed_ad_view.dart b/lib/hj_page/short_video/view/feed_ad_view.dart index cdc697a..a4ba037 100644 --- a/lib/hj_page/short_video/view/feed_ad_view.dart +++ b/lib/hj_page/short_video/view/feed_ad_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/routers/jump_router.dart'; import '../../../hj_model/splash/ads_model.dart'; import '../../../tools_base/widget/net_image_widget.dart'; diff --git a/lib/hj_page/short_video/view/float_ad_view.dart b/lib/hj_page/short_video/view/float_ad_view.dart index 35c65be..2c09ab6 100644 --- a/lib/hj_page/short_video/view/float_ad_view.dart +++ b/lib/hj_page/short_video/view/float_ad_view.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// 短视频左上角浮动广告(position=8) class FloatAdView extends StatefulWidget { @@ -21,7 +21,8 @@ class _FloatAdViewState extends State { @override Widget build(BuildContext context) { final ad = _adInfo; // 取局部变量做类型提升,后续无需 ! 断言 - if (_isDismissed || ad == null || !AdManager().showAbTestAd) return const SizedBox.shrink(); + if (_isDismissed || ad == null || !AdManager().showAbTestAd) + return const SizedBox.shrink(); final cover = ad.cover; if (cover == null || cover.isEmpty) return const SizedBox.shrink(); diff --git a/lib/hj_page/short_video/view/media_action_menu.dart b/lib/hj_page/short_video/view/media_action_menu.dart index 8e487ea..82caaaa 100644 --- a/lib/hj_page/short_video/view/media_action_menu.dart +++ b/lib/hj_page/short_video/view/media_action_menu.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/video_download/download_button.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/video_download/download_button.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:uuid/uuid.dart'; import 'package:video_player/video_player.dart'; @@ -47,7 +47,8 @@ class MediaActionMenu extends StatefulWidget { State createState() => _MediaActionMenuState(); } -class _MediaActionMenuState extends State with TickerProviderStateMixin { +class _MediaActionMenuState extends State + with TickerProviderStateMixin { bool _isFollowLoading = false; bool _isCollectLoading = false; bool _isLikeLoading = false; @@ -91,7 +92,8 @@ class _MediaActionMenuState extends State with TickerProviderSt super.initState(); VideoMenuSwitch.addListen(_menuListen); if (!_isDrama) { - _followAniCtr = AnimationController(duration: const Duration(milliseconds: 500), vsync: this); + _followAniCtr = AnimationController( + duration: const Duration(milliseconds: 500), vsync: this); } } @@ -111,7 +113,8 @@ class _MediaActionMenuState extends State with TickerProviderSt //局部刷新:只重建依赖该信号的子树(点赞/收藏/关注互不牵连) Widget _refreshOn(ValueNotifier tick, Widget Function() builder) => - ValueListenableBuilder(valueListenable: tick, builder: (_, __, ___) => builder()); + ValueListenableBuilder( + valueListenable: tick, builder: (_, __, ___) => builder()); @override Widget build(BuildContext context) { @@ -138,7 +141,9 @@ class _MediaActionMenuState extends State with TickerProviderSt _likeTick, () => menuActionItem( (_video?.likeCount ?? 0).countStr, - isLike ? 'like_red.png'.commonImgPath : 'like_white.png'.commonImgPath, + isLike + ? 'like_red.png'.commonImgPath + : 'like_white.png'.commonImgPath, onTap: _onLikeEvent, ), ), @@ -153,7 +158,9 @@ class _MediaActionMenuState extends State with TickerProviderSt _collectTick, () => menuActionItem( isCollect ? "已收藏" : "收藏", - isCollect ? 'collect_red.png'.commonImgPath : 'collect_white.png'.commonImgPath, + isCollect + ? 'collect_red.png'.commonImgPath + : 'collect_white.png'.commonImgPath, onTap: _onCollectEvent, ), ), @@ -167,13 +174,15 @@ class _MediaActionMenuState extends State with TickerProviderSt style: _isDrama ? MediaStyle.Drama : null, ), itemGap.sizeBoxH, - menuActionItem('分享', 'share_arrow.png'.videoPath, onTap: _onShareEvent), + menuActionItem('分享', 'share_arrow.png'.videoPath, + onTap: _onShareEvent), itemGap.sizeBoxH, menuActionItem( '切换', "line_white2.png".videoPath, onTap: () async { - if (await VideoLineMenuAlert.show()) widget.onSwitchLine?.call(); + if (await VideoLineMenuAlert.show()) + widget.onSwitchLine?.call(); setState(() {}); }, ), @@ -182,7 +191,9 @@ class _MediaActionMenuState extends State with TickerProviderSt ), ), // 眼睛按钮常驻:仅切换图标(eye_open/eye_close),menuActionItem 内置 AnimatedSwitcher 交叉淡入 - menuActionItem("", (show ? "eye_open.png" : "eye_close.png").videoPath, onTap: () { + menuActionItem( + "", (show ? "eye_open.png" : "eye_close.png").videoPath, + onTap: () { //广播给本页其他播放器/进度条,再刷新自身 VideoMenuSwitch.toggle(); setState(() {}); @@ -199,7 +210,8 @@ class _MediaActionMenuState extends State with TickerProviderSt children: [ InkWell( enableFeedback: false, - onTap: () => Get.to(() => UserCenterPage(uid: _video?.publisher?.uid ?? 0)), + onTap: () => + Get.to(() => UserCenterPage(uid: _video?.publisher?.uid ?? 0)), child: Padding( padding: const EdgeInsets.only(bottom: 8), child: NetworkImageLoader( @@ -215,7 +227,8 @@ class _MediaActionMenuState extends State with TickerProviderSt onTap: _onFollowEvent, child: _refreshOn( _followTick, - () => CollectStatusWrapper(videoModel: _video, builder: _buildFollowPlus), + () => CollectStatusWrapper( + videoModel: _video, builder: _buildFollowPlus), ), ), ], @@ -232,7 +245,9 @@ class _MediaActionMenuState extends State with TickerProviderSt turns: ctr, child: ScaleTransition( scale: Tween(begin: 1, end: 0).animate( - CurvedAnimation(parent: ctr, curve: const Interval(0.5, 1.0, curve: Curves.easeIn)), + CurvedAnimation( + parent: ctr, + curve: const Interval(0.5, 1.0, curve: Curves.easeIn)), ), child: Image.asset('add_red.webp'.videoPath, width: 16, height: 16), ), @@ -248,11 +263,14 @@ class _MediaActionMenuState extends State with TickerProviderSt try { final preCollect = isCollect; if (_isDrama) { - await (preCollect ? ACGService.deleteBookshelf(_objId ?? '') : ACGService.addBookshelf(_objId ?? '')); + await (preCollect + ? ACGService.deleteBookshelf(_objId ?? '') + : ACGService.addBookshelf(_objId ?? '')); } else { await MineService.postCollect(_objId, "SHORT", !preCollect); } - _video?.collectCount = (_video?.collectCount ?? (preCollect ? 1 : 0)) + (preCollect ? -1 : 1); + _video?.collectCount = (_video?.collectCount ?? (preCollect ? 1 : 0)) + + (preCollect ? -1 : 1); _video?.vidStatus?.hasCollected = !preCollect; if (!preCollect) showToast("收藏成功"); _collectTick.value++; @@ -274,7 +292,8 @@ class _MediaActionMenuState extends State with TickerProviderSt await CommonService.sendLike(_objId, _likeType); showToast("已点赞"); } - _video?.likeCount = (_video?.likeCount ?? (preLike ? 1 : 0)) + (preLike ? -1 : 1); + _video?.likeCount = + (_video?.likeCount ?? (preLike ? 1 : 0)) + (preLike ? -1 : 1); _video?.vidStatus?.hasLiked = !preLike; _likeTick.value++; } catch (e) { diff --git a/lib/hj_page/short_video/view/short_top_menu.dart b/lib/hj_page/short_video/view/short_top_menu.dart index 88fa240..71a3f33 100644 --- a/lib/hj_page/short_video/view/short_top_menu.dart +++ b/lib/hj_page/short_video/view/short_top_menu.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; import '../../home/search_page/search_main_page.dart'; import '../short_main_video_logic.dart'; @@ -33,7 +33,8 @@ class ShortTopMenu extends StatelessWidget { borderRadius: BorderRadius.circular(2), ), labelColor: Colors.white.withValues(alpha: 0.9), - labelStyle: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500), + labelStyle: + const TextStyle(fontSize: 15, fontWeight: FontWeight.w500), unselectedLabelColor: Colors.white.withValues(alpha: 0.55), unselectedLabelStyle: const TextStyle(fontSize: 15), labelPadding: EdgeInsets.zero, @@ -45,7 +46,8 @@ class ShortTopMenu extends StatelessWidget { ), InkWell( enableFeedback: false, - onTap: () => Get.to(SearchMainPage(initialResultType: MediaStyle.Drama)), + onTap: () => + Get.to(SearchMainPage(initialResultType: MediaStyle.Drama)), child: Container( padding: const EdgeInsets.only(bottom: 2), child: Image.asset( diff --git a/lib/hj_page/short_video/view/short_video_menu.dart b/lib/hj_page/short_video/view/short_video_menu.dart index d9f691e..744edfc 100644 --- a/lib/hj_page/short_video/view/short_video_menu.dart +++ b/lib/hj_page/short_video/view/short_video_menu.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/short_video/view/media_action_menu.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_page/video/view/long_video_status.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/free_play_manager.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/short_video/view/media_action_menu.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_page/video/view/long_video_status.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/free_play_manager.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import 'package:video_player/video_player.dart'; import '../../../hj_model/splash/watch_count_model.dart'; @@ -71,7 +71,8 @@ class _ShortVideoMenuState extends State { children: [ Container( //底部留白避开文字广告条:无广告 40,有广告(type33) 56 - padding: EdgeInsets.only(bottom: AdManager().adsByType(33).isEmpty ? 40 : 56), + padding: EdgeInsets.only( + bottom: AdManager().adsByType(33).isEmpty ? 40 : 56), child: Row( children: [ Expanded( @@ -320,7 +321,9 @@ class _ShortVideoMenuState extends State { ), child: Text( isShowFreeCount ? "免费视频剩余${watchValue + 1}次" : "开通会员 畅享完整版", - style: TextStyle(color: isShowFreeCount ? Color(0xffFF9D00) : Color(0xff7B0000), fontSize: 12), + style: TextStyle( + color: isShowFreeCount ? Color(0xffFF9D00) : Color(0xff7B0000), + fontSize: 12), ), ), ); diff --git a/lib/hj_page/short_video/view/short_video_player.dart b/lib/hj_page/short_video/view/short_video_player.dart index 744c08b..91b8e2d 100644 --- a/lib/hj_page/short_video/view/short_video_player.dart +++ b/lib/hj_page/short_video/view/short_video_player.dart @@ -1,15 +1,15 @@ import 'package:flutter/cupertino.dart' show CupertinoActivityIndicator; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/short_video/view/float_ad_view.dart'; -import 'package:hgmj/hj_page/short_video/view/short_video_menu.dart'; -import 'package:hgmj/hj_page/short_video/view/short_video_player_logic.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_page/short_video/view/video_progress_widget.dart'; -import 'package:hgmj/hj_page/video/view/video_mask_buy_view.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/short_video/view/float_ad_view.dart'; +import 'package:wydj/hj_page/short_video/view/short_video_menu.dart'; +import 'package:wydj/hj_page/short_video/view/short_video_player_logic.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_page/short_video/view/video_progress_widget.dart'; +import 'package:wydj/hj_page/video/view/video_mask_buy_view.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -36,7 +36,8 @@ class ShortVideoPlayer extends StatefulWidget { } // PageView 里 2~3 条同时存活,用 per-实例唯一 tag 隔离各自的播放器 logic -class _ShortVideoPlayerState extends State with UniqueTagMixin { +class _ShortVideoPlayerState extends State + with UniqueTagMixin { //进度条压暗档位:滑动中 / 挂着买量蒙层都用这一档 static const _dimOpacity = 0.4; @@ -94,7 +95,10 @@ class _ShortVideoPlayerState extends State with UniqueTagMixin ), _bufferLoading(logic), Container( - padding: EdgeInsets.only(bottom: widget.listType == VideoListType.SECOND ? Get.mediaQuery.padding.bottom : 0), + padding: EdgeInsets.only( + bottom: widget.listType == VideoListType.SECOND + ? Get.mediaQuery.padding.bottom + : 0), child: ShortVideoMenu( videoModel: logic.video, playerCtr: logic.playerCtr, @@ -138,13 +142,16 @@ class _ShortVideoPlayerState extends State with UniqueTagMixin /// 无 isScrolling 信号则常显 Widget _progressBar(ShortVideoPlayerLogic logic) { //二级页进度条贴底,避让系统手势条(home indicator),否则 thumb 和横线重合难点中;其他场景不加 - final bottomSafe = widget.listType == VideoListType.SECOND ? Get.mediaQuery.padding.bottom + 10 : 0.0; + final bottomSafe = widget.listType == VideoListType.SECOND + ? Get.mediaQuery.padding.bottom + 10 + : 0.0; final Widget bar = VideoProgressWidget( controller: logic.playerCtr, padding: EdgeInsets.only(left: 12, right: 12, bottom: bottomSafe), ); final scrolling = widget.isScrolling; - if (scrolling == null) return Opacity(opacity: logic.showBuyMask ? _dimOpacity : 1, child: bar); + if (scrolling == null) + return Opacity(opacity: logic.showBuyMask ? _dimOpacity : 1, child: bar); return ValueListenableBuilder( valueListenable: scrolling, //只做透明+屏蔽点击,不能用 Visibility——它会卸载 child,重建时 initState 会拿旧 controller 挂监听 @@ -163,13 +170,16 @@ class _ShortVideoPlayerState extends State with UniqueTagMixin /// 未就绪/缓冲中的居中转圈。直接监听 playerCtr(本身是 ValueNotifier), /// 切视频/切线路换了控制器时 ValueListenableBuilder 会自动改订阅,无需手动 add/removeListener Widget _bufferLoading(ShortVideoPlayerLogic logic) { - const indicator = Center(child: CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15)); + const indicator = Center( + child: + CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15)); final ctr = logic.playerCtr; if (ctr == null) return indicator; // 控制器还没建好,同样转圈 return ValueListenableBuilder( valueListenable: ctr, - builder: (_, value, __) => !value.isInitialized || value.isBuffering ? indicator : const SizedBox(), + builder: (_, value, __) => !value.isInitialized || value.isBuffering + ? indicator + : const SizedBox(), ); } - } diff --git a/lib/hj_page/short_video/view/short_video_player_logic.dart b/lib/hj_page/short_video/view/short_video_player_logic.dart index 99ae871..a7ed8c7 100644 --- a/lib/hj_page/short_video/view/short_video_player_logic.dart +++ b/lib/hj_page/short_video/view/short_video_player_logic.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/short_video/view/video_player_base_logic.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/short_video/view/video_player_base_logic.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../../alert/video/buy_vip_alert.dart'; import '../../../alert/vip_guide/guide_bottom_sheet.dart'; @@ -19,7 +19,8 @@ import '../short_video_page.dart'; /// 单条短视频的试看/付费逻辑。播放器本身的机制(建控制器、265 降级、可见性播停)在基类。 /// PageView 每项一个实例,由页面用唯一 tag 隔离 class ShortVideoPlayerLogic extends VideoPlayerBaseLogic { - ShortVideoPlayerLogic({required this.index, required this.videoInfo, this.listType}); + ShortVideoPlayerLogic( + {required this.index, required this.videoInfo, this.listType}); /// index / videoInfo 会被页面同步刷新:列表可能用**同 id 的新对象**替换某条 /// (如首条拉完详情后 removeAt+insert),PageView 按 id 做 key 会复用 State, @@ -106,7 +107,8 @@ class ShortVideoPlayerLogic extends VideoPlayerBaseLogic { // 历史记录已统一收到 ShortVideoLogic.onPageChanged:滑到即记,与播放器/权限/进度无关 // vip用遮罩, 金币用弹窗;有金币免费观看次数时不再要求购买 final status = videoStatus; - final isNeedBuy = status.isNeedBuy && (watchCount?.coinWatchCount ?? -1) < 0; + final isNeedBuy = + status.isNeedBuy && (watchCount?.coinWatchCount ?? -1) < 0; if (!isNeedBuy && !status.isNeedVip) return; _showPayAhead(); // 场景1(短):under7/over7 播满3秒的前置提示 if (position < (video?.freeTime ?? 10)) return; @@ -145,7 +147,8 @@ class ShortVideoPlayerLogic extends VideoPlayerBaseLogic { await TimedPopupManager().trigger( canShow: () => _canShowGuide, //短视频按钮无价文案;长视频才用默认的「立即开通 · 仅需¥价格」 - onShow: () async => goVip = await GuideBottomSheet.showVideo(buttonText: '开通会员 · 查看完整内容'), + onShow: () async => + goVip = await GuideBottomSheet.showVideo(buttonText: '开通会员 · 查看完整内容'), ); // 跳了会员页就不恢复播放;滑到别条 / 期间被试看结束拦下弹了蒙层,由 syncPlay 兜住 if (goVip || isClosed) return; diff --git a/lib/hj_page/short_video/view/video_menu_kit.dart b/lib/hj_page/short_video/view/video_menu_kit.dart index 7c73e1c..90f721a 100644 --- a/lib/hj_page/short_video/view/video_menu_kit.dart +++ b/lib/hj_page/short_video/view/video_menu_kit.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/short_video/view/video_player_base_logic.dart'; -import 'package:hgmj/hj_page/video/video_full_page.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/short_video/view/video_player_base_logic.dart'; +import 'package:wydj/hj_page/video/video_full_page.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:video_player/video_player.dart'; typedef MenuSwitchCallback = void Function(bool); // true 显示 @@ -17,9 +17,11 @@ class VideoMenuSwitch { static final List _listeners = []; - static void addListen(MenuSwitchCallback callback) => _listeners.add(callback); + static void addListen(MenuSwitchCallback callback) => + _listeners.add(callback); - static void removeLister(MenuSwitchCallback callback) => _listeners.remove(callback); + static void removeLister(MenuSwitchCallback callback) => + _listeners.remove(callback); static void toggle() { isShow = !isShow; @@ -35,7 +37,8 @@ class VideoMenuSwitch { } /// 操作台右侧的动作项:图标 + 文案,图标切换(点赞/收藏选中态)带缩放淡入 -Widget menuActionItem(String title, String imgPath, {GestureTapCallback? onTap}) { +Widget menuActionItem(String title, String imgPath, + {GestureTapCallback? onTap}) { return InkWell( enableFeedback: false, onTap: onTap, @@ -58,7 +61,11 @@ Widget menuActionItem(String title, String imgPath, {GestureTapCallback? onTap}) //FittedBox 让线路名之类的长文案缩成一行,别撑成两行把菜单项间距顶乱 if (title.isNotEmpty) FittedBox( - child: Text(title, style: const TextStyle(color: Color(0xffDCDCDC), fontSize: 11, fontWeight: FontWeight.w500)), + child: Text(title, + style: const TextStyle( + color: Color(0xffDCDCDC), + fontSize: 11, + fontWeight: FontWeight.w500)), ), ], ), @@ -109,7 +116,8 @@ class CenterPlayPause extends StatefulWidget { State createState() => CenterPlayPauseState(); } -class CenterPlayPauseState extends State with SingleTickerProviderStateMixin { +class CenterPlayPauseState extends State + with SingleTickerProviderStateMixin { // play_pause 形变进度:0=播放三角,1=暂停双杠 late final AnimationController _morphCtr = AnimationController( duration: const Duration(milliseconds: 260), @@ -217,9 +225,11 @@ class FullScreenButton extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Image.asset('full_screen.webp'.videoPath, width: 14, height: 14), + Image.asset('full_screen.webp'.videoPath, + width: 14, height: 14), 4.sizeBoxW, - const Text('全屏观看', style: TextStyle(color: Colors.white, fontSize: 12)), + const Text('全屏观看', + style: TextStyle(color: Colors.white, fontSize: 12)), ], ), ), diff --git a/lib/hj_page/short_video/view/video_player_base_logic.dart b/lib/hj_page/short_video/view/video_player_base_logic.dart index f4da795..15a3553 100644 --- a/lib/hj_page/short_video/view/video_player_base_logic.dart +++ b/lib/hj_page/short_video/view/video_player_base_logic.dart @@ -1,10 +1,10 @@ import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/hj_utils/play_diagnose.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/hj_utils/play_diagnose.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -141,7 +141,8 @@ abstract class VideoPlayerBaseLogic extends GetxController { /// [model] 显式传入而不读 getter:失败重试链要一路用同一个 model Future initPlayer(VideoModel? model, {bool isRetry = false}) async { if (isClosed) return; // 已销毁(快速滑走/失败重试排队中),别再建控制器,否则没人释放 - VideoPlayerController? preVideoCtr = playerCtr; // 旧控制器,切线路/失败后需释放(声明在 try 外,catch 才能拿到) + VideoPlayerController? preVideoCtr = + playerCtr; // 旧控制器,切线路/失败后需释放(声明在 try 外,catch 才能拿到) try { preVideoCtr?.pause(); int prePosition = preVideoCtr?.value.position.inSeconds ?? 0; @@ -154,7 +155,8 @@ abstract class VideoPlayerBaseLogic extends GetxController { playerCtr = PlayerFactory.network(_playUrl); // 仅网络播放,不走本地文件 notify(); await playerCtr?.initialize(); - if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 + if (isRetry) + confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 preVideoCtr?.removeListener(_onProgress); preVideoCtr?.dispose(); // 切线路/刷新:释放旧控制器,避免解码器泄漏累积导致后续视频全部加载失败 // initialize 期间可能已被销毁(快速连滑),playerCtr 已在 onClose() 里释放, @@ -231,7 +233,8 @@ abstract class VideoPlayerBaseLogic extends GetxController { //所以再认播放器自己的 isCompleted 兜底(播完必为 true 且会通知一次,seek 回去自动转 false)。 //duration 为 0 的异常流 isCompleted 也是 true,必须由外层这个条件挡住,别刚起播就当播完 if (duration.inMilliseconds > 0 && - (ctr.value.isCompleted || position.inMilliseconds >= duration.inMilliseconds - 300)) { + (ctr.value.isCompleted || + position.inMilliseconds >= duration.inMilliseconds - 300)) { //回调只发一次:条件成立后每个 tick 都会再进来 if (!_completedSent) { _completedSent = true; diff --git a/lib/hj_page/short_video/view/video_progress_widget.dart b/lib/hj_page/short_video/view/video_progress_widget.dart index 24fcb92..b5a7832 100644 --- a/lib/hj_page/short_video/view/video_progress_widget.dart +++ b/lib/hj_page/short_video/view/video_progress_widget.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'package:hgmj/hj_page/short_video/view/video_menu_kit.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_page/short_video/view/video_menu_kit.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:video_player/video_player.dart'; const double _kSliderThumbRadius = 6; //滑杆圆点外圈半径(按设计稿外圈直径12;轨道两端按此内缩,避免压到时间文字) @@ -127,8 +127,10 @@ class _VideoProgressWidgetState extends State { final result = _clampSeek(duration); final minMs = widget.minSeekDuration?.inMilliseconds; final maxMs = widget.maxSeekDuration?.inMilliseconds; - if (minMs != null && result.inMilliseconds < minMs) return widget.minSeekDuration!; - if (maxMs != null && result.inMilliseconds > maxMs) return widget.maxSeekDuration!; + if (minMs != null && result.inMilliseconds < minMs) + return widget.minSeekDuration!; + if (maxMs != null && result.inMilliseconds > maxMs) + return widget.maxSeekDuration!; return result; } @@ -199,14 +201,17 @@ class _VideoProgressWidgetState extends State { _timeKey = totalText; _timeWidth = _measureWidth(totalText); } - final curSeconds = _displaySeek?.inSeconds ?? playerCtr?.value.position.inSeconds ?? 0; + final curSeconds = + _displaySeek?.inSeconds ?? playerCtr?.value.position.inSeconds ?? 0; return Row( children: [ - _timeText(curSeconds, alignment: Alignment.centerRight, forceHour: forceHour), + _timeText(curSeconds, + alignment: Alignment.centerRight, forceHour: forceHour), 3.sizeBoxW, Expanded(child: _buildSlider()), 3.sizeBoxW, - _timeText(totalSeconds, alignment: Alignment.centerLeft, forceHour: forceHour), + _timeText(totalSeconds, + alignment: Alignment.centerLeft, forceHour: forceHour), ], ); } @@ -217,7 +222,10 @@ class _VideoProgressWidgetState extends State { final painter = TextPainter( text: TextSpan( text: text, - style: const TextStyle(color: Colors.white, fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontFeatures: [FontFeature.tabularFigures()]), ), textDirection: TextDirection.ltr, textScaler: MediaQuery.textScalerOf(context), @@ -229,13 +237,18 @@ class _VideoProgressWidgetState extends State { //tabularFigures 必须要:宽度是拿总时长那串量的,两边共用;iOS 系统字体数字是比例宽度 //(0 比 1 宽不少),00:05 会比 16:31 宽而撑出 SizedBox,被最左端的圆点压住。 //等宽数字后所有时间串同宽,顺带消掉秒数跳动时的左右抖动 - Widget _timeText(int seconds, {required Alignment alignment, bool forceHour = false}) => SizedBox( + Widget _timeText(int seconds, + {required Alignment alignment, bool forceHour = false}) => + SizedBox( width: _timeWidth, child: Align( alignment: alignment, child: Text( _formatTime(seconds, forceHour: forceHour), - style: const TextStyle(color: Colors.white, fontSize: 12, fontFeatures: [FontFeature.tabularFigures()]), + style: const TextStyle( + color: Colors.white, + fontSize: 12, + fontFeatures: [FontFeature.tabularFigures()]), maxLines: 1, softWrap: false, ), @@ -283,7 +296,8 @@ class _VideoTrackShape extends SliderTrackShape { final top = offset.dy + (parentBox.size.height - h) / 2; //左右各内缩一个圆点半径,thumb 到达两端时不越界压到时间文字 final w = parentBox.size.width - _kSliderThumbRadius * 2; - return Rect.fromLTWH(offset.dx + _kSliderThumbRadius, top, w > 0 ? w : 0, h); + return Rect.fromLTWH( + offset.dx + _kSliderThumbRadius, top, w > 0 ? w : 0, h); } @override @@ -299,13 +313,19 @@ class _VideoTrackShape extends SliderTrackShape { required TextDirection textDirection, required Offset thumbCenter, }) { - final rect = getPreferredRect(parentBox: parentBox, sliderTheme: sliderTheme, offset: offset); + final rect = getPreferredRect( + parentBox: parentBox, sliderTheme: sliderTheme, offset: offset); final canvas = context.canvas; //整条轨道裁成圆角(高度一半=胶囊),内部两段平涂:外侧两端圆角、thumb 处接缝平齐 canvas.save(); - canvas.clipRRect(RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))); - canvas.drawRect(Rect.fromLTRB(rect.left, rect.top, thumbCenter.dx, rect.bottom), _active); - canvas.drawRect(Rect.fromLTRB(thumbCenter.dx, rect.top, rect.right, rect.bottom), _inactive); + canvas.clipRRect( + RRect.fromRectAndRadius(rect, Radius.circular(rect.height / 2))); + canvas.drawRect( + Rect.fromLTRB(rect.left, rect.top, thumbCenter.dx, rect.bottom), + _active); + canvas.drawRect( + Rect.fromLTRB(thumbCenter.dx, rect.top, rect.right, rect.bottom), + _inactive); canvas.restore(); } } @@ -318,7 +338,8 @@ class _VideoThumbShape extends SliderComponentShape { const _VideoThumbShape(); @override - Size getPreferredSize(bool isEnabled, bool isDiscrete) => Size.fromRadius(_kSliderThumbRadius); + Size getPreferredSize(bool isEnabled, bool isDiscrete) => + Size.fromRadius(_kSliderThumbRadius); @override void paint( diff --git a/lib/hj_page/splash/splash_ad_view.dart b/lib/hj_page/splash/splash_ad_view.dart index 1d73920..4aad925 100644 --- a/lib/hj_page/splash/splash_ad_view.dart +++ b/lib/hj_page/splash/splash_ad_view.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../hj_model/splash/ads_model.dart'; import '../../routers/jump_router.dart'; @@ -127,7 +127,8 @@ class _SplashAdViewState extends State { final begin = isIncoming ? const Offset(0, -1) : const Offset(0, 1); return ClipRect( child: SlideTransition( - position: Tween(begin: begin, end: Offset.zero).animate(anim), + position: + Tween(begin: begin, end: Offset.zero).animate(anim), child: child, ), ); diff --git a/lib/hj_page/splash/splash_logic.dart b/lib/hj_page/splash/splash_logic.dart index 8b29bff..4610ca5 100644 --- a/lib/hj_page/splash/splash_logic.dart +++ b/lib/hj_page/splash/splash_logic.dart @@ -3,30 +3,30 @@ import 'dart:convert'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_model/splash/cut_info.dart'; -import 'package:hgmj/hj_model/splash/domain_source_model.dart'; -import 'package:hgmj/hj_model/user/user_info_model.dart'; -import 'package:hgmj/hj_page/main_page/main_logic.dart'; -import 'package:hgmj/hj_page/main_page/main_page.dart'; -import 'package:hgmj/hj_page/pre_sale/limit_time_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/detect_line_manager.dart'; -import 'package:hgmj/hj_utils/local_server.dart'; -import 'package:hgmj/hj_utils/local_server_guard.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/hj_utils/version_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/net/api_exception.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_model/splash/cut_info.dart'; +import 'package:wydj/hj_model/splash/domain_source_model.dart'; +import 'package:wydj/hj_model/user/user_info_model.dart'; +import 'package:wydj/hj_page/main_page/main_logic.dart'; +import 'package:wydj/hj_page/main_page/main_page.dart'; +import 'package:wydj/hj_page/pre_sale/limit_time_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/detect_line_manager.dart'; +import 'package:wydj/hj_utils/local_server.dart'; +import 'package:wydj/hj_utils/local_server_guard.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/version_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/net/api_exception.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; import 'package:path/path.dart' as path; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../../alert/splash/line_error_dialog.dart'; import '../../alert/splash/update_dialog.dart'; @@ -88,7 +88,8 @@ class SplashLogic extends GetxController { ///isLast = true 取出上次展示的广告 Future _loadAds({bool isLast = true}) async { - final list = isLast ? await AdManager().lastAdsByType(1) : AdManager().adsByType(1); + final list = + isLast ? await AdManager().lastAdsByType(1) : AdManager().adsByType(1); if (AdManager().showAbTestAd) adsList = list; isAdLoaded = true; update(); @@ -220,13 +221,13 @@ class SplashLogic extends GetxController { break; case "GUIDE": final url = source.domain![0].url; - if(url != null && url.isNotEmpty) { + if (url != null && url.isNotEmpty) { Address.groundUrl = url; } break; case 'WEBSITE': final url = source.domain?.firstOrNull?.url; - if(url != null && url.isNotEmpty) { + if (url != null && url.isNotEmpty) { Address.backUpURl = url; } break; @@ -235,7 +236,7 @@ class SplashLogic extends GetxController { break; case "TELEGRAM": final url = source.domain![0].url; - if(url != null && url.isNotEmpty) { + if (url != null && url.isNotEmpty) { Address.groupTelegram = url; } break; @@ -306,6 +307,8 @@ class SplashLogic extends GetxController { //广告和数据两边都就绪才进首页 void _tryJump() { //opaque 在 offAll 里默认 false,不显式打开会在转场时透出下层 - if (isAdDone && isDataReady) Get.offAll(() => const MainPage(), binding: MainPageBinding(), opaque: true); + if (isAdDone && isDataReady) + Get.offAll(() => const MainPage(), + binding: MainPageBinding(), opaque: true); } } diff --git a/lib/hj_page/splash/splash_page.dart b/lib/hj_page/splash/splash_page.dart index fc35972..0c62036 100644 --- a/lib/hj_page/splash/splash_page.dart +++ b/lib/hj_page/splash/splash_page.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/splash/splash_ad_view.dart'; -import 'package:hgmj/hj_page/splash/splash_logic.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/splash/splash_ad_view.dart'; +import 'package:wydj/hj_page/splash/splash_logic.dart'; import '../../config/config.dart'; import '../../tools_base/loading/loading_alert_widget.dart'; diff --git a/lib/hj_page/user_center_page/user_center_logic.dart b/lib/hj_page/user_center_page/user_center_logic.dart index 92fe47f..fef6e74 100644 --- a/lib/hj_page/user_center_page/user_center_logic.dart +++ b/lib/hj_page/user_center_page/user_center_logic.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/user/user_info_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_model/user/user_info_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; -class UserCenterController extends GetxController with GetTickerProviderStateMixin { +class UserCenterController extends GetxController + with GetTickerProviderStateMixin { // ===== 数据 ===== final int id; UserInfoModel? model; @@ -14,7 +15,12 @@ class UserCenterController extends GetxController with GetTickerProviderStateMix UserCenterController(this.id); final titleArr = ['影视', '抖音', '帖子', '图集']; - final titleParam = [MediaStyle.Video, MediaStyle.ShortVideo, MediaStyle.Community, MediaStyle.Pic]; + final titleParam = [ + MediaStyle.Video, + MediaStyle.ShortVideo, + MediaStyle.Community, + MediaStyle.Pic + ]; // ===== 头部测量 ===== //头部高度需实测:量到之前只渲染 header 本身,量到后才切 SliverAppBar @@ -54,7 +60,8 @@ class UserCenterController extends GetxController with GetTickerProviderStateMix /// 量出头部实际高度,量到后 build 才切到 NestedScrollView void calculateHeaderHeight() { if (expandedHeight != null) return; - final renderBox = headerKey.currentContext?.findRenderObject() as RenderBox?; + final renderBox = + headerKey.currentContext?.findRenderObject() as RenderBox?; if (renderBox == null) { debugLog('无法获取 calculateHeaderHeight'); } else { diff --git a/lib/hj_page/user_center_page/user_center_page.dart b/lib/hj_page/user_center_page/user_center_page.dart index 3014ca4..2ea980d 100644 --- a/lib/hj_page/user_center_page/user_center_page.dart +++ b/lib/hj_page/user_center_page/user_center_page.dart @@ -1,14 +1,14 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/user_center_page/view/user_work_list_view.dart'; -import 'package:hgmj/hj_page/user_center_page/widget/user_center_header.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/follow_button.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_page/user_center_page/view/user_work_list_view.dart'; +import 'package:wydj/hj_page/user_center_page/widget/user_center_header.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/follow_button.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import '../../tools_base/indicator/custom_tab_indicator.dart'; import '../../tools_base/widget/net_image_widget.dart'; @@ -16,7 +16,6 @@ import 'user_center_logic.dart'; //用户首页 class UserCenterPage extends StatefulWidget { - final int uid; const UserCenterPage({super.key, required this.uid}); @@ -43,7 +42,8 @@ class _UserCenterPageState extends State with UniqueTagMixin { if (logic.model == null) return const LoadingCenterWidget(); // 头部高度未知:先只渲染 header 供测量,量到后 update 会切到下面的正式布局 if (logic.expandedHeight == null) { - WidgetsBinding.instance.addPostFrameCallback((_) => logic.calculateHeaderHeight()); + WidgetsBinding.instance + .addPostFrameCallback((_) => logic.calculateHeaderHeight()); return Container( alignment: Alignment.topCenter, child: UserCenterHeader(key: logic.headerKey, logic: logic), @@ -58,7 +58,9 @@ class _UserCenterPageState extends State with UniqueTagMixin { controller: logic.mainTabCtr, children: List.generate( logic.titleArr.length, - (index) => UserWorkListView(logic.model?.uid ?? 0, logic.titleParam[index]).keepAlive, + (index) => + UserWorkListView(logic.model?.uid ?? 0, logic.titleParam[index]) + .keepAlive, ), ), ); @@ -95,7 +97,10 @@ class _UserCenterPageState extends State with UniqueTagMixin { child: TabBar( controller: logic.mainTabCtr, tabAlignment: TabAlignment.fill, - tabs: logic.titleArr.map((e) => Container(alignment: Alignment.center, child: Text(e))).toList(), + tabs: logic.titleArr + .map((e) => + Container(alignment: Alignment.center, child: Text(e))) + .toList(), labelStyle: const TextStyle(fontSize: 14), labelColor: const Color(0xE5FFFFFF), unselectedLabelStyle: const TextStyle(fontSize: 14), diff --git a/lib/hj_page/user_center_page/view/user_work_list_logic.dart b/lib/hj_page/user_center_page/view/user_work_list_logic.dart index 91d3bd5..9e22530 100644 --- a/lib/hj_page/user_center_page/view/user_work_list_logic.dart +++ b/lib/hj_page/user_center_page/view/user_work_list_logic.dart @@ -1,7 +1,7 @@ -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/base_list_controller.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/base_list_controller.dart'; class UserWorkListLogic extends ListBaseLogic { final int uid; @@ -25,7 +25,8 @@ class UserWorkListLogic extends ListBaseLogic { } Future<(List?, bool)> _fetch(int page) async { - final res = await MineService.fetchPublishes(page: page, uid: uid, newsType: newsType.searchRealm); + final res = await MineService.fetchPublishes( + page: page, uid: uid, newsType: newsType.searchRealm); return (res.list, res.hasNext ?? false); } } diff --git a/lib/hj_page/user_center_page/view/user_work_list_view.dart b/lib/hj_page/user_center_page/view/user_work_list_view.dart index c7c78c8..15fb267 100644 --- a/lib/hj_page/user_center_page/view/user_work_list_view.dart +++ b/lib/hj_page/user_center_page/view/user_work_list_view.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/user_center_page/view/user_work_list_logic.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/hj_page/user_center_page/view/user_work_list_logic.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import '../../../routers/jump_router.dart'; import '../../cartoon/photo_gallery_item.dart'; @@ -21,7 +21,8 @@ class UserWorkListView extends StatefulWidget { State createState() => _UserWorkListViewState(); } -class _UserWorkListViewState extends State with UniqueTagMixin { +class _UserWorkListViewState extends State + with UniqueTagMixin { @override Widget build(BuildContext context) { return GetBuilder( @@ -29,7 +30,9 @@ class _UserWorkListViewState extends State with UniqueTagMixin tag: uniqueTag, builder: (logic) { if (logic.isLoading) return const LoadingCenterWidget(); - if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData(showLoading: true)); + if (logic.isEmptyData) + return CErrorWidget( + retryOnTap: () => logic.loadData(showLoading: true)); return pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, onRefresh: (_) => logic.loadData(), @@ -47,7 +50,8 @@ class _UserWorkListViewState extends State with UniqueTagMixin return ListView.builder( padding: EdgeInsets.zero, itemCount: list.length, - itemBuilder: (_, index) => CommunityPostWidget(videoModel: list[index], videoModels: list), + itemBuilder: (_, index) => + CommunityPostWidget(videoModel: list[index], videoModels: list), ); } // 其余(影视/抖音/图集)都是双列网格,只差宽高比与 item 样式 @@ -68,7 +72,8 @@ class _UserWorkListViewState extends State with UniqueTagMixin videoModel: list[index], textLines: isShort ? 1 : 2, isShowBottom: !isShort, - onTap: () => pushToVideoPage(videoModel: list[index], videoArr: list), + onTap: () => + pushToVideoPage(videoModel: list[index], videoArr: list), ), ); } diff --git a/lib/hj_page/user_center_page/widget/user_center_header.dart b/lib/hj_page/user_center_page/widget/user_center_header.dart index 3c47482..9837452 100644 --- a/lib/hj_page/user_center_page/widget/user_center_header.dart +++ b/lib/hj_page/user_center_page/widget/user_center_header.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_page/user_center_page/user_center_logic.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/widget/follow_button.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_page/user_center_page/user_center_logic.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/widget/follow_button.dart'; import '../../../tools_base/widget/net_image_widget.dart'; @@ -26,8 +26,10 @@ class UserCenterHeader extends StatelessWidget { right: 0, child: Container( height: 190, - foregroundDecoration: BoxDecoration(color: const Color(0xff151515).withValues(alpha: 0.1)), - child: Image.asset("user_center_bg.webp".mineImgPath, fit: BoxFit.fill), + foregroundDecoration: BoxDecoration( + color: const Color(0xff151515).withValues(alpha: 0.1)), + child: Image.asset("user_center_bg.webp".mineImgPath, + fit: BoxFit.fill), ), ), Padding( @@ -60,7 +62,8 @@ class UserCenterHeader extends StatelessWidget { ), ), const Spacer(), - if (!globalStore.isMe(logic.model?.uid)) ..._actionButtons(), + if (!globalStore.isMe(logic.model?.uid)) + ..._actionButtons(), ], ), ), @@ -78,7 +81,8 @@ class UserCenterHeader extends StatelessWidget { //作品数 / 粉丝数 Text( "${logic.model?.totalWorkCount ?? "0"} 作品 ${logic.model?.fans?.countStr ?? "0"}粉丝", - style: const TextStyle(color: Color(0xff656565), fontSize: 12), + style: + const TextStyle(color: Color(0xff656565), fontSize: 12), ), 24.sizeBoxH, //个人简介 @@ -89,7 +93,8 @@ class UserCenterHeader extends StatelessWidget { logic.model?.summary ?? "", maxLines: 3, overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Color(0x99FFFFFF), fontSize: 12, height: 1.5), + style: const TextStyle( + color: Color(0x99FFFFFF), fontSize: 12, height: 1.5), ), ), ], diff --git a/lib/hj_page/video/cartoon/cartoon_episode_menu_alert.dart b/lib/hj_page/video/cartoon/cartoon_episode_menu_alert.dart index 65f5275..1b9bc04 100644 --- a/lib/hj_page/video/cartoon/cartoon_episode_menu_alert.dart +++ b/lib/hj_page/video/cartoon/cartoon_episode_menu_alert.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; -import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart'; +import 'package:wydj/tools_base/widget/sheet_handle_bar.dart'; import '../../../hj_model/acg/comic_chapters_model.dart'; import '../../../hj_model/cartoon_media_info.dart'; @@ -19,7 +19,8 @@ class CartoonEpisodeMenuAlert extends StatefulWidget { final CartoonMediaInfo? cartoonModel; final Function(ComicChapterInfo)? callback; - CartoonEpisodeMenuAlert(this.curModel, {super.key, this.callback, this.cartoonModel}); + CartoonEpisodeMenuAlert(this.curModel, + {super.key, this.callback, this.cartoonModel}); @override State createState() { @@ -58,7 +59,9 @@ class _CartoonEpisodeMenuAlertState extends State { //异步返回时 sheet 可能已关闭,避免对已卸载组件 setState / 操作已释放的 refreshCtr if (!mounted) return; setState(() {}); - cartoonModel?.haxNextEpisode == true ? refreshCtr?.loadComplete() : refreshCtr?.loadNoData(); + cartoonModel?.haxNextEpisode == true + ? refreshCtr?.loadComplete() + : refreshCtr?.loadNoData(); } @override @@ -68,8 +71,9 @@ class _CartoonEpisodeMenuAlertState extends State { child: Container( padding: EdgeInsets.fromLTRB(18.w, 21, 18.w, 32), height: 460, - decoration: - BoxDecoration(borderRadius: BorderRadius.vertical(top: Radius.circular(18)), color: Color(0xff0F0F0F)), + decoration: BoxDecoration( + borderRadius: BorderRadius.vertical(top: Radius.circular(18)), + color: Color(0xff0F0F0F)), child: Column( children: [ const SheetHandleBar(color: Color(0x4DFFFFFF)), @@ -146,7 +150,9 @@ class CartoonChapterItem extends StatelessWidget { }); // 前 N 集免费(当前集号 <= freeEpisode)且整本无任何权限时,展示「免费」角标 - bool get _isFree => fatherM.hasPermission == false && fatherM.isFreeEpisodeNumber(model.episodeNumber); + bool get _isFree => + fatherM.hasPermission == false && + fatherM.isFreeEpisodeNumber(model.episodeNumber); @override Widget build(BuildContext context) { @@ -155,13 +161,17 @@ class CartoonChapterItem extends StatelessWidget { decoration: BoxDecoration( color: isSelected ? Color(0x1A6975FF) : Colors.transparent, borderRadius: BorderRadius.circular(8), - border: Border.all(color: isSelected ? AppColors.actionRed : Color(0x1AFFFFFF), width: 1), + border: Border.all( + color: isSelected ? AppColors.actionRed : Color(0x1AFFFFFF), + width: 1), ), child: Stack( alignment: Alignment.center, children: [ //前 N 集免费且整本无权限 → 左上角「免费」角标 - if (_isFree && isCanShowFree) const Positioned(top: 0, right: 0, child: FreeBadge(isCorner: true)), + if (_isFree && isCanShowFree) + const Positioned( + top: 0, right: 0, child: FreeBadge(isCorner: true)), Container( padding: EdgeInsets.only(top: 12), child: Row( diff --git a/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart b/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart index 4859313..a7ce0b7 100644 --- a/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart +++ b/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart @@ -1,17 +1,17 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/widget/shrink_wrap.dart'; -import 'package:hgmj/hj_page/home/tag/cartoon_tag_page.dart'; -import 'package:hgmj/hj_page/video/view/video_detail_bottom_menu.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/routers/jump_router.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/widget/shrink_wrap.dart'; +import 'package:wydj/hj_page/home/tag/cartoon_tag_page.dart'; +import 'package:wydj/hj_page/video/view/video_detail_bottom_menu.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/routers/jump_router.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:video_player/video_player.dart'; import '../../../hj_model/acg/comic_chapters_model.dart'; @@ -75,7 +75,8 @@ class _VideoDetailCartoonViewState extends State child: Container( padding: const EdgeInsets.only(top: 18), margin: EdgeInsets.symmetric(horizontal: 12), - child: VideoDetailBottomMenu(model: videoModel, onShare: _onShare), + child: + VideoDetailBottomMenu(model: videoModel, onShare: _onShare), ), ), SliverToBoxAdapter( diff --git a/lib/hj_page/video/simple_video_player_logic.dart b/lib/hj_page/video/simple_video_player_logic.dart index 61fb38c..2ba56ba 100644 --- a/lib/hj_page/video/simple_video_player_logic.dart +++ b/lib/hj_page/video/simple_video_player_logic.dart @@ -1,11 +1,11 @@ import 'dart:async'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:video_player/video_player.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; import '../../tools_base/debug_log.dart'; @@ -40,7 +40,8 @@ class SimpleVideoPlayerLogic extends GetxController { videoCtr = PlayerFactory.network(videoUrl); } await videoCtr?.initialize(); - if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 + if (isRetry) + confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 videoCtr?.play(); update(); } catch (e) { diff --git a/lib/hj_page/video/simple_video_player_page.dart b/lib/hj_page/video/simple_video_player_page.dart index d6fa6ae..732a963 100644 --- a/lib/hj_page/video/simple_video_player_page.dart +++ b/lib/hj_page/video/simple_video_player_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/video/view/video_menu_view.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/hj_page/video/view/video_menu_view.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:video_player/video_player.dart'; import 'simple_video_player_logic.dart'; @@ -12,7 +12,8 @@ class SimpleVideoPlayerPage extends StatelessWidget { final String title; final String? localPath; - const SimpleVideoPlayerPage({super.key, required this.videoUrl, required this.title, this.localPath}); + const SimpleVideoPlayerPage( + {super.key, required this.videoUrl, required this.title, this.localPath}); @override Widget build(BuildContext context) { diff --git a/lib/hj_page/video/video_full_page.dart b/lib/hj_page/video/video_full_page.dart index ae697f0..efac805 100644 --- a/lib/hj_page/video/video_full_page.dart +++ b/lib/hj_page/video/video_full_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/video/video_full_logic.dart'; -import 'package:hgmj/hj_page/video/view/video_menu_view.dart'; +import 'package:wydj/hj_page/video/video_full_logic.dart'; +import 'package:wydj/hj_page/video/view/video_menu_view.dart'; import 'package:video_player/video_player.dart'; import '../../hj_model/video_model.dart'; diff --git a/lib/hj_page/video/video_logic.dart b/lib/hj_page/video/video_logic.dart index 00129fe..01aa8ae 100644 --- a/lib/hj_page/video/video_logic.dart +++ b/lib/hj_page/video/video_logic.dart @@ -3,13 +3,13 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/video/video_full_page.dart'; -import 'package:hgmj/hj_page/video/view/long_video_status.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/hj_utils/play_diagnose.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_page/video/video_full_page.dart'; +import 'package:wydj/hj_page/video/view/long_video_status.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/hj_utils/play_diagnose.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:video_player/video_player.dart'; import '../../alert/video/buy_vip_alert.dart'; @@ -73,7 +73,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { bool isFullScreen = false; // true:视频进入全屏页面 RxBool isShowBuy = false.obs; // 显示购买和vip弹窗 - late final TabController tabCtr = TabController(length: 2, vsync: this); // 简介/评论 + late final TabController tabCtr = + TabController(length: 2, vsync: this); // 简介/评论 CartoonMediaInfo? cartoonModel; //动漫 ComicChapterInfo? currentEpisode; //动漫集数 @@ -101,7 +102,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { double get normalRatio => 16 / 9; /// 实际播放比例:动漫和未初始化都用 16:9 兜底,否则用控制器报告的实际比例 - double get videoRatio => (!isCartoon && isInited) ? playerCtr!.value.aspectRatio : normalRatio; + double get videoRatio => + (!isCartoon && isInited) ? playerCtr!.value.aspectRatio : normalRatio; StreamSubscription? _pauseVideoSub; @@ -138,13 +140,16 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { GuideManager().canShow(GuideFreeTrialSheet.scene) && MineMsgProvider().payTier?.status == PayTier.newUnpay && FreePlayManager().useFreePlay(videoModel) == true && - GuideFreeTrialSheet.isCountLow, //必须排在 useFreePlay 之后:它会先扣一次,扣完才是该显示的剩余数 + GuideFreeTrialSheet + .isCountLow, //必须排在 useFreePlay 之后:它会先扣一次,扣完才是该显示的剩余数 onShow: () async { // 先备好卡数据再暂停,否则拉数据期间视频白停几百毫秒;场景没配卡就压根不弹,别白暂停一下 - if (await loadGuideCard(GuideFreeTrialSheet.scene) == null || isDispose) return; + if (await loadGuideCard(GuideFreeTrialSheet.scene) == null || isDispose) + return; // 只暂停本来在播的:用户自己停在那看简介/评论时,弹完别擅自续播 final wasPlaying = playerCtr?.value.isPlaying == true; - if (wasPlaying) playerCtr?.pause(); // 图标由 VideoMenuView 的 Rx 自动跟,不用 update() + if (wasPlaying) + playerCtr?.pause(); // 图标由 VideoMenuView 的 Rx 自动跟,不用 update() final goVip = await GuideFreeTrialSheet.show(); // 跳了会员页 / 已退页 / 期间被硬拦截弹了蒙层,都不能恢复播放 if (!wasPlaying || goVip || isDispose || isShowBuy.value) return; @@ -159,8 +164,9 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { bool get _needPayGuide => videoStatus.isNeedPay; /// 能连续看的秒数:有试看片就是试看片长,否则是正片免费时长 - int get _freeSeconds => - videoModel?.previewURL?.isNotEmpty == true ? (playerCtr?.value.duration.inSeconds ?? 0) : (videoModel?.freeTime ?? 0); + int get _freeSeconds => videoModel?.previewURL?.isNotEmpty == true + ? (playerCtr?.value.duration.inSeconds ?? 0) + : (videoModel?.freeTime ?? 0); /// 各类「整片免看」权益:免费次数 / 免费区 / 动漫整本已购 / 动漫免费章节 / VIP 金币限免。 /// 命中任一说明用户本来就能看完整片,场景1、场景2 都不该打扰他。 @@ -169,8 +175,11 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { bool get _hasFreeWatchRight { if (FreePlayManager().useFreePlay(videoModel)) return true; if (videoModel?.freeArea == true) return true; - if (cartoonModel?.mediaStatus?.hasPaid == true) return true; // 动漫整本解锁, 都可以看, 不管vip权限 - if (isCartoon && cartoonModel?.isFreeEpisodeNumber(currentEpisode?.episodeNumber) == true) return true; + if (cartoonModel?.mediaStatus?.hasPaid == true) + return true; // 动漫整本解锁, 都可以看, 不管vip权限 + if (isCartoon && + cartoonModel?.isFreeEpisodeNumber(currentEpisode?.episodeNumber) == + true) return true; return isVipCoinFree; } @@ -199,7 +208,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { if (playerCtr?.value.isPlaying != true) return; _payGuideShown = true; // 先备好卡数据再暂停,否则拉数据期间视频白停几百毫秒;场景没配卡就压根不弹,别白暂停一下 - if (await loadGuideCard(GuideScene.videoPreviewEnd) == null || isDispose) return; + if (await loadGuideCard(GuideScene.videoPreviewEnd) == null || + isDispose) return; playerCtr?.pause(); // 图标由 VideoMenuView 的 Rx 自动跟,不用 update() final goVip = await _showPayGuide(); // 跳了会员页 / 已退页 / 期间被硬拦截弹了蒙层,都不能恢复播放 @@ -218,7 +228,10 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { /// 是否允许直接退页。false=先弹返回挽留(VIDEO_BACK):长视频 + 场景开关允许 + 本页未弹过。 /// 供 PopScope.canPop 与返回箭头共用,类型跟当前在播内容走 - bool get canPop => _backGuideShown || isCartoon || !GuideManager().canShow(GuideScene.videoBack); + bool get canPop => + _backGuideShown || + isCartoon || + !GuideManager().canShow(GuideScene.videoBack); /// VIDEO_BACK:长视频返回挽留。弹优惠倒计时,标记已弹并 update() 让 canPop 放行后续返回。 /// 用户是按了返回才弹的,所以挽留失败(点X/点蒙层/被互斥挡下)就把这次返回执行完; @@ -232,7 +245,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { try { await TimedPopupManager().trigger( canShow: () => GuideManager().canShow(GuideScene.videoBack), - onShow: () async => goVip = await GuideCountdownDialog.show(scene: GuideScene.videoBack), + onShow: () async => goVip = + await GuideCountdownDialog.show(scene: GuideScene.videoBack), ); } catch (e) { debugLog('showBackGuide', e.toString()); @@ -276,7 +290,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { cartoonModel?.haxNextEpisode = episodeModel?.hasNext ?? true; videoModel?.mediaInfo = cartoonModel; currentEpisode = episodeModel?.list?.first; - MediaContent? mediaContent = await ACGService.getMediaDetail(id: currentEpisode?.id ?? ""); + MediaContent? mediaContent = + await ACGService.getMediaDetail(id: currentEpisode?.id ?? ""); episodeModel?.list?.first.mediaContent = mediaContent; videoModel = cartoonModel?.toVideoModel(currentEpisode) ?? VideoModel(); } else { @@ -350,7 +365,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { return; } isFullScreen = true; - await Get.to(() => VideoFullPage(playCtr: playerCtr!, videoModel: videoModel)); + await Get.to( + () => VideoFullPage(playCtr: playerCtr!, videoModel: videoModel)); isFullScreen = false; } @@ -358,7 +374,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { void exitFullScreen() { if (!isFullScreen) return; isFullScreen = false; - SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, + overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); Get.back(); } @@ -395,7 +412,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { playerCtr = PlayerFactory.network(videoUrl); // 仅网络播放,不走本地文件 try { await playerCtr?.initialize(); - if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 + if (isRetry) + confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 update(); } catch (e) { debugLog("视频初始化失败:$e play url = $videoUrl"); @@ -443,7 +461,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { playerCtr?.addListener(_onProgress); int previewStart = videoModel?.previewStart ?? 0; if (previewStart > 0) { - final canFree = FreePlayManager().useFreePlay(videoModel) || videoModel?.freeArea == true; + final canFree = FreePlayManager().useFreePlay(videoModel) || + videoModel?.freeArea == true; // 免金币视频 / 有免费观看次数(vip视频):从头播,不需要 seekTo // 需要付费/会员才能看的视频,跳到预览起始位置开始播放 if (!canFree && videoStatus.isNeedPay) { @@ -469,7 +488,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { if (!_isPreview()) { //每帧都走这里,videoStatus 是重算 getter,只读一次 final status = videoStatus; - final inFreeTime = videoModel?.isInFreeTime(playerCtr!.value.position.inSeconds) == true; + final inFreeTime = + videoModel?.isInFreeTime(playerCtr!.value.position.inSeconds) == true; final isPlaying = playerCtr?.value.isPlaying == true; if (inFreeTime || !isPlaying) return; // 全屏中:仍处于免费时长则不打扰;否则需付费的视频在播放时先退出全屏,给后续弹窗腾出空间 @@ -484,7 +504,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { if (!isCartoon && status.isNeedVip) { // 刚退全屏要等 pop 动画和转屏落定再弹:exitFullScreen 的 Get.back() 带动画, // 此刻 push 会叠在正在 pop 的全屏页上,且弹窗高度取的是实时 Get.height,横屏下算出来是错的 - if (wasFullScreen) await Future.delayed(const Duration(milliseconds: 350)); + if (wasFullScreen) + await Future.delayed(const Duration(milliseconds: 350)); if (!isDispose) BuyVipAlert.show(videoId: videoModel?.id); } } @@ -527,7 +548,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { void _fallbackTo264() { if (isDispose || !isPlayingH265 || _forceH264) return; _forceH264 = true; // 本条视频后续重建都走 264 - debugLog("H.265 运行时报错,回退 264 续播 pos=${playerCtr?.value.position.inSeconds}"); + debugLog( + "H.265 运行时报错,回退 264 续播 pos=${playerCtr?.value.position.inSeconds}"); releasePlayer(); // 释放当前 → 下一帧按进度续播,选流因 _forceH264 走 264 } @@ -609,8 +631,10 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { isShowBuy.value = false; releasePlayer(rebuild: false); update(); - currentEpisode?.mediaContent ??= await ACGService.getMediaDetail(id: currentEpisode?.id ?? ""); - startPlay(model: cartoonModel?.toVideoModel(currentEpisode) ?? VideoModel()); + currentEpisode?.mediaContent ??= + await ACGService.getMediaDetail(id: currentEpisode?.id ?? ""); + startPlay( + model: cartoonModel?.toVideoModel(currentEpisode) ?? VideoModel()); } catch (e) { debugLog(e); } @@ -618,7 +642,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { /// 释放播放器。[rebuild]=false 只释放(切集前清理);[model] 非空则切新视频,为空则按上次进度续播。 /// dispose 走下一帧,避免在播放回调中销毁导致 use-after-free - void releasePlayer({VideoModel? model, bool rebuild = true, bool resetPos = false}) { + void releasePlayer( + {VideoModel? model, bool rebuild = true, bool resetPos = false}) { final old = playerCtr; old?.pause(); // resetPos:预览片→正片场景,两者时间轴不对应,不能沿用预览片进度,从头播 @@ -641,7 +666,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { /// 页面销毁清理:取消事件订阅 → 非预览视频上报观看记录 → 释放播放器 @override void onClose() { - isDispose = true; // 第一时间置位,让所有异步回调(initialize/postFrame/Future.delayed)能尽早 return + isDispose = + true; // 第一时间置位,让所有异步回调(initialize/postFrame/Future.delayed)能尽早 return TimedPopupManager().cancel(TimedPopupType.freeWatchPay); TimedPopupManager().cancel(TimedPopupType.videoPayAhead); @@ -651,13 +677,15 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { if (playerCtr != null) { bool isPreview = false; if (videoModel?.previewURL?.isNotEmpty == true) { - if (playerCtr?.dataSource.contains(videoModel?.previewURL ?? "") == true) { + if (playerCtr?.dataSource.contains(videoModel?.previewURL ?? "") == + true) { isPreview = true; } } if (!isPreview) { try { - _reportPlay(playerCtr?.value.position, playerCtr?.value.duration, videoModel); + _reportPlay( + playerCtr?.value.position, playerCtr?.value.duration, videoModel); } catch (e) { debugLog(e); } @@ -670,7 +698,8 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { } /// 上报播放记录(static:不碰实例状态,避免请求在飞时把已销毁的 logic 一起吊住) - static Future _reportPlay(Duration? position, Duration? duration, VideoModel? video) async { + static Future _reportPlay( + Duration? position, Duration? duration, VideoModel? video) async { if (position == null || duration == null) return; if (position.inMilliseconds < 1000) return; // 不足 1 秒不记 if (video?.videoType == 1) return; // 动漫不走这个接口 diff --git a/lib/hj_page/video/video_page.dart b/lib/hj_page/video/video_page.dart index 80f5a4a..19cc274 100644 --- a/lib/hj_page/video/video_page.dart +++ b/lib/hj_page/video/video_page.dart @@ -6,19 +6,19 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/video/video_logic.dart'; -import 'package:hgmj/hj_page/video/view/video_ad_widget.dart'; -import 'package:hgmj/hj_page/video/view/video_mask_buy_view.dart'; -import 'package:hgmj/hj_page/video/view/video_menu_view.dart'; -import 'package:hgmj/hj_page/video/view/video_status_view.dart'; -import 'package:hgmj/hj_page/video/view/video_tabbar_menu_widget.dart'; -import 'package:hgmj/hj_page/video/view/vip_promo_banner.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/video/video_logic.dart'; +import 'package:wydj/hj_page/video/view/video_ad_widget.dart'; +import 'package:wydj/hj_page/video/view/video_mask_buy_view.dart'; +import 'package:wydj/hj_page/video/view/video_menu_view.dart'; +import 'package:wydj/hj_page/video/view/video_status_view.dart'; +import 'package:wydj/hj_page/video/view/video_tabbar_menu_widget.dart'; +import 'package:wydj/hj_page/video/view/vip_promo_banner.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:video_player/video_player.dart'; import '../../hj_model/video_model.dart'; @@ -159,12 +159,16 @@ class _VideoPageState extends State with UniqueTagMixin { alignment: Alignment.center, child: AspectRatio( aspectRatio: logic.videoRatio, - child: logic.playerCtr != null ? VideoPlayer(logic.playerCtr!) : SizedBox(), + child: logic.playerCtr != null + ? VideoPlayer(logic.playerCtr!) + : SizedBox(), ), ), ), if (logic.playerCtr?.value.isInitialized != true) - NetworkImageLoader(imageUrl: logic.videoModel?.cover ?? widget.videoCover ?? "", borderRadius: 0), + NetworkImageLoader( + imageUrl: logic.videoModel?.cover ?? widget.videoCover ?? "", + borderRadius: 0), if (logic.playerCtr?.value.isInitialized == true) ...[ Positioned( top: 12, @@ -240,7 +244,9 @@ class _VideoPageState extends State with UniqueTagMixin { return ValueListenableBuilder( valueListenable: ctr, builder: (_, value, __) => value.isInitialized && value.isBuffering - ? const Center(child: CupertinoActivityIndicator(color: AppColors.actionRed, radius: 15)) + ? const Center( + child: CupertinoActivityIndicator( + color: AppColors.actionRed, radius: 15)) : const SizedBox(), ); } diff --git a/lib/hj_page/video/video_player_alert.dart b/lib/hj_page/video/video_player_alert.dart index 97be4f7..9db9472 100644 --- a/lib/hj_page/video/video_player_alert.dart +++ b/lib/hj_page/video/video_player_alert.dart @@ -2,15 +2,15 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_page/video/video_full_page.dart'; -import 'package:hgmj/hj_page/video/view/video_menu_view.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_page/video/video_full_page.dart'; +import 'package:wydj/hj_page/video/view/video_menu_view.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import 'package:video_player/video_player.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; import '../../tools_base/widget/net_image_widget.dart'; @@ -40,7 +40,8 @@ class _VideoPlayerAlertState extends State { videoCtr = PlayerFactory.network(widget.movieUrl); try { await videoCtr?.initialize(); - if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 + if (isRetry) + confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 if (mounted) { videoCtr?.play(); setState(() {}); @@ -74,11 +75,13 @@ class _VideoPlayerAlertState extends State { Positioned( left: 0, top: 0, - child: InkWell(enableFeedback: false, + child: InkWell( + enableFeedback: false, onTap: Get.back, child: Container( padding: EdgeInsets.only(left: 16, top: 6), - child: Image.asset('back_circle.png'.commonImgPath, width: 24, height: 24), + child: Image.asset('back_circle.png'.commonImgPath, + width: 24, height: 24), ), ), ), @@ -94,7 +97,8 @@ class _VideoPlayerAlertState extends State { return Stack( alignment: Alignment.center, children: [ - if (widget.imgCover?.isNotEmpty == true) NetworkImageLoader(imageUrl: widget.imgCover ?? ""), + if (widget.imgCover?.isNotEmpty == true) + NetworkImageLoader(imageUrl: widget.imgCover ?? ""), LoadingCenterWidget(), ], ); @@ -113,7 +117,8 @@ class _VideoPlayerAlertState extends State { VideoMenuView( playCtr: videoCtr!, isFull: true, - onFullScreen: () => Get.to(() => VideoFullPage(playCtr: videoCtr!, isAutoV: false)), + onFullScreen: () => + Get.to(() => VideoFullPage(playCtr: videoCtr!, isAutoV: false)), ), ], ); diff --git a/lib/hj_page/video/view/long_video_status.dart b/lib/hj_page/video/view/long_video_status.dart index f15b05e..8d78482 100644 --- a/lib/hj_page/video/view/long_video_status.dart +++ b/lib/hj_page/video/view/long_video_status.dart @@ -1,6 +1,6 @@ -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../../../hj_utils/free_play_manager.dart'; import '../../pre_sale/pre_sale_provider.dart'; @@ -37,9 +37,12 @@ class LongVideoStatus { //复用多处的固定状态,抽出来免得同一串文案散落 const _none = LongVideoStatus(); -const _coinFree = LongVideoStatus(type: LongVideoStatusType.coinFree, desc: '已享金币视频免费特权'); -const _skipVip = LongVideoStatus(type: LongVideoStatusType.skipPreview, desc: '跳过预览', isNeedVip: true); -const _skipBuy = LongVideoStatus(type: LongVideoStatusType.skipPreview, desc: '跳过预览', isNeedBuy: true); +const _coinFree = + LongVideoStatus(type: LongVideoStatusType.coinFree, desc: '已享金币视频免费特权'); +const _skipVip = LongVideoStatus( + type: LongVideoStatusType.skipPreview, desc: '跳过预览', isNeedVip: true); +const _skipBuy = LongVideoStatus( + type: LongVideoStatusType.skipPreview, desc: '跳过预览', isNeedBuy: true); /// 计算长视频的观看状态(展示文案 + 是否需付费/开会员) /// @@ -70,35 +73,46 @@ LongVideoStatus longVideoStatus(VideoModel? model) { late final canFree = FreePlayManager().useFreePlay(model); if (model.freeArea == true) { - return const LongVideoStatus(type: LongVideoStatusType.freeVideo, desc: '免费视频'); + return const LongVideoStatus( + type: LongVideoStatusType.freeVideo, desc: '免费视频'); } if (!isVIP && freeCount >= 0 && isZeroCoin && canFree) { - return LongVideoStatus(type: LongVideoStatusType.freeRemain, desc: '免费视频剩余${freeCount + 1}次'); + return LongVideoStatus( + type: LongVideoStatusType.freeRemain, desc: '免费视频剩余${freeCount + 1}次'); } if (isVIP && isZeroCoin) { // 交给 VipFreeTipView 显示,独立于操作台、3 秒后消失 - return const LongVideoStatus(type: LongVideoStatusType.vipFree, desc: '已享VIP免费特权'); + return const LongVideoStatus( + type: LongVideoStatusType.vipFree, desc: '已享VIP免费特权'); } if (hasPaid) { - return const LongVideoStatus(type: LongVideoStatusType.purchased, desc: '已购买完整版'); + return const LongVideoStatus( + type: LongVideoStatusType.purchased, desc: '已购买完整版'); } if (!isVIP && isZeroCoin && canFree) { return _none; // 免费次数内看过的视频,重复观看仍免费(不显示文案) } if (coinFreeLeft >= 0) { - return LongVideoStatus(type: LongVideoStatusType.coinFreeRemain, desc: '免费金币观影数剩余: $coinFreeLeft次'); + return LongVideoStatus( + type: LongVideoStatusType.coinFreeRemain, + desc: '免费金币观影数剩余: $coinFreeLeft次'); } // 往下不再判 !hasPaid:已购的上面就 return 了,走到这儿必定是未购 if (hasCoin && globalStore.isAWVIP) { // 暗网视频要顶级会员,否则仍需单独买 if (model.isDarkTag && !globalStore.isVIPTopLevel) { - return LongVideoStatus(type: LongVideoStatusType.skipPreview, desc: '${model.coins}金币 跳过预览', isNeedBuy: true); + return LongVideoStatus( + type: LongVideoStatusType.skipPreview, + desc: '${model.coins}金币 跳过预览', + isNeedBuy: true); } return _coinFree; } // 二级会员 / 金币免费期内 / 本片金币已抵扣,都算已享金币免费特权 if ((hasCoin && globalStore.isSuperVip) || - (isVIP && DateTimeUtil.calTime3(globalStore.meInfo?.goldVideoFreeExpire) > 0 && (coins ?? 50) <= 50) || + (isVIP && + DateTimeUtil.calTime3(globalStore.meInfo?.goldVideoFreeExpire) > 0 && + (coins ?? 50) <= 50) || (isVIP && hasCoin && model.coins == 0)) { return _coinFree; } diff --git a/lib/hj_page/video/view/video_ad_widget.dart b/lib/hj_page/video/view/video_ad_widget.dart index e475f47..b1d7527 100644 --- a/lib/hj_page/video/view/video_ad_widget.dart +++ b/lib/hj_page/video/view/video_ad_widget.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; import '../../../hj_model/splash/ads_model.dart'; import '../../../tools_base/banner/ads_banner.dart'; diff --git a/lib/hj_page/video/view/video_detail_bottom_menu.dart b/lib/hj_page/video/view/video_detail_bottom_menu.dart index 26fc8a2..86794b6 100644 --- a/lib/hj_page/video/view/video_detail_bottom_menu.dart +++ b/lib/hj_page/video/view/video_detail_bottom_menu.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/api_service/acg_service.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/api_service/acg_service.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:like_button/like_button.dart'; /// 底部操作栏:观看量 + 点赞/收藏/分享。计数与状态就地改在传入的 [VideoModel] 上, @@ -37,7 +37,8 @@ class _VideoDetailBottomMenuState extends State { static const _labelStyle = TextStyle(color: Color(0xff989898), fontSize: 12); /// 计数±1:原值为 null 时按操作前的状态兜底,保证取消后不会变成负数 - int _nextCount(int? cur, bool wasOn) => (cur ?? (wasOn ? 1 : 0)) + (wasOn ? -1 : 1); + int _nextCount(int? cur, bool wasOn) => + (cur ?? (wasOn ? 1 : 0)) + (wasOn ? -1 : 1); // ========== 点赞 ========== Future _onLike() async { @@ -74,7 +75,8 @@ class _VideoDetailBottomMenuState extends State { } else { await MineService.postCollect(videoModel?.id, "SP", !preCollect); } - videoModel?.collectCount = _nextCount(videoModel?.collectCount, preCollect); + videoModel?.collectCount = + _nextCount(videoModel?.collectCount, preCollect); videoModel?.vidStatus?.hasCollected = !preCollect; videoModel?.mediaInfo?.mediaStatus?.hasCollected = !preCollect; videoModel?.mediaInfo?.countCollect = videoModel?.collectCount; @@ -91,7 +93,8 @@ class _VideoDetailBottomMenuState extends State { return Row( children: [ Expanded( - child: Text("${videoModel?.playCount?.countStr ?? ""}观看量", style: _labelStyle), + child: Text("${videoModel?.playCount?.countStr ?? ""}观看量", + style: _labelStyle), ), _likeItem(), 12.sizeBoxW, @@ -110,7 +113,9 @@ class _VideoDetailBottomMenuState extends State { isLiked: isLike, size: 24, likeBuilder: (isLiked) => Image.asset( - isLiked ? "like_red.png".commonImgPath : "video_like_grey.webp".videoPath, + isLiked + ? "like_red.png".commonImgPath + : "video_like_grey.webp".videoPath, ), onTap: (_) => _onLike(), ), @@ -128,15 +133,20 @@ class _VideoDetailBottomMenuState extends State { // 收藏状态切换时,图标 grey↔red 做 scale 弹出过渡 AnimatedSwitcher( duration: const Duration(milliseconds: 200), - transitionBuilder: (child, anim) => ScaleTransition(scale: anim, child: child), + transitionBuilder: (child, anim) => + ScaleTransition(scale: anim, child: child), child: Image.asset( - isCollect ? 'collect_yellow.png'.commonImgPath : 'collect_grey.png'.commonImgPath, - key: ValueKey(isCollect), // key 按状态区分,AnimatedSwitcher 才当成新 child 触发动画 + isCollect + ? 'collect_yellow.png'.commonImgPath + : 'collect_grey.png'.commonImgPath, + key: ValueKey( + isCollect), // key 按状态区分,AnimatedSwitcher 才当成新 child 触发动画 width: 24, ), ), 2.sizeBoxW, - Text(videoModel?.collectCount.countOr('收藏') ?? '收藏', style: _labelStyle), + Text(videoModel?.collectCount.countOr('收藏') ?? '收藏', + style: _labelStyle), ], ), ); diff --git a/lib/hj_page/video/view/video_detail_view.dart b/lib/hj_page/video/view/video_detail_view.dart index dc31c47..554376b 100644 --- a/lib/hj_page/video/view/video_detail_view.dart +++ b/lib/hj_page/video/view/video_detail_view.dart @@ -1,17 +1,17 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/cartoon_media_info.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/widget/shrink_wrap.dart'; -import 'package:hgmj/hj_page/home/tag/video_tag_page.dart'; -import 'package:hgmj/hj_page/video/view/video_detail_bottom_menu.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/banner/ads_grid_view.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/keep_alive_widget.dart'; +import 'package:wydj/hj_model/cartoon_media_info.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/widget/shrink_wrap.dart'; +import 'package:wydj/hj_page/home/tag/video_tag_page.dart'; +import 'package:wydj/hj_page/video/view/video_detail_bottom_menu.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/banner/ads_grid_view.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/keep_alive_widget.dart'; import 'package:video_player/video_player.dart'; import '../../../alert/video/share_media_dialog.dart'; @@ -35,11 +35,13 @@ class VideoDetailView extends StatefulWidget { State createState() => _VideoDetailViewState(); } -class _VideoDetailViewState extends State with SingleTickerProviderStateMixin { +class _VideoDetailViewState extends State + with SingleTickerProviderStateMixin { VideoModel? get videoModel => widget.model; // 视频(SP)推荐按当前视频第一个 tag 拉同类;tags 为空则全局推荐 - String? get _videoTagId => videoModel?.tags?.isNotEmpty == true ? videoModel?.tags?.first.id : null; + String? get _videoTagId => + videoModel?.tags?.isNotEmpty == true ? videoModel?.tags?.first.id : null; late final TabController tabCtr = TabController(length: 3, vsync: this); @@ -66,7 +68,8 @@ class _VideoDetailViewState extends State with SingleTickerProv SliverToBoxAdapter( child: Container( margin: EdgeInsets.fromLTRB(12, 18, 12, 0), - child: VideoDetailBottomMenu(model: videoModel, onShare: _onShare), + child: + VideoDetailBottomMenu(model: videoModel, onShare: _onShare), ), ), SliverToBoxAdapter( @@ -137,7 +140,11 @@ class _VideoDetailViewState extends State with SingleTickerProv child: Text( videoModel?.title?.trim() ?? "", maxLines: 2, - style: const TextStyle(color: Colors.white, height: 1.5, fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.white, + height: 1.5, + fontSize: 16, + fontWeight: FontWeight.w500), ), ); } @@ -193,14 +200,19 @@ class _VideoDetailViewState extends State with SingleTickerProv labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), labelColor: Color(0xE5FFFFFF), unselectedLabelColor: Color(0x8CFFFFFF), - unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.w400), + unselectedLabelStyle: + TextStyle(fontSize: 14, fontWeight: FontWeight.w400), tabs: menuTitles .map((e) => Padding( padding: const EdgeInsets.only(bottom: 5), child: Text(e), )) .toList(), - indicator: CustomIndicator(isGradient: true, width: 13, height: 3, borderRadius: BorderRadius.circular(1.5)), + indicator: CustomIndicator( + isGradient: true, + width: 13, + height: 3, + borderRadius: BorderRadius.circular(1.5)), ), ], ); diff --git a/lib/hj_page/video/view/video_mask_buy_view.dart b/lib/hj_page/video/view/video_mask_buy_view.dart index e67304b..5f844e4 100644 --- a/lib/hj_page/video/view/video_mask_buy_view.dart +++ b/lib/hj_page/video/view/video_mask_buy_view.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/video/view/long_video_status.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/video/view/long_video_status.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:video_player/video_player.dart'; import '../../../alert/video/buy_vip_alert.dart'; @@ -44,12 +44,16 @@ class _VideoMaskBuyViewState extends State { String get vipBtnTitle { if (!hasPresale) return "开通VIP免费看"; if (!presaleProvider.isPayFirst) return "开通预售免费看"; - return presaleProvider.canPayBalance ? "支付尾款免费看" : "请在${presaleProvider.startTimeMD}支付尾款"; + return presaleProvider.canPayBalance + ? "支付尾款免费看" + : "请在${presaleProvider.startTimeMD}支付尾款"; } /// 开通预售/VIP,回来后刷新按钮文案 Future _onVipTap() async { - await (hasPresale ? Get.to(() => PreSalePage()) : BuyVipAlert.show(videoId: widget.model?.id)); + await (hasPresale + ? Get.to(() => PreSalePage()) + : BuyVipAlert.show(videoId: widget.model?.id)); if (mounted) setState(() {}); } @@ -80,7 +84,9 @@ class _VideoMaskBuyViewState extends State { if (isBuying) return; isBuying = true; // 观影券抵扣:取能覆盖本片金币的券面额 - final couponNum = useCoupon ? globalStore.meInfo?.couponGold(widget.model?.originCoins) : null; + final couponNum = useCoupon + ? globalStore.meInfo?.couponGold(widget.model?.originCoins) + : null; await PayManager().buy( widget.model?.id, ProductType.media, @@ -116,18 +122,30 @@ class _VideoMaskBuyViewState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text(widget.maskTitle, style: const TextStyle(color: Color(0xffffffff), fontSize: 16, fontWeight: FontWeight.w500)), + Text(widget.maskTitle, + style: const TextStyle( + color: Color(0xffffffff), + fontSize: 16, + fontWeight: FontWeight.w500)), 18.sizeBoxH, - const Text("开通VIP 全站视频免费看", style: TextStyle(color: Color(0xffffffff), fontSize: 16, fontWeight: FontWeight.w500)), + const Text("开通VIP 全站视频免费看", + style: TextStyle( + color: Color(0xffffffff), + fontSize: 16, + fontWeight: FontWeight.w500)), 18.sizeBoxH, Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _btn( - title: status.isNeedBuy ? "${widget.model?.coins ?? 0}金币解锁" : "邀请得3日VIP", + title: status.isNeedBuy + ? "${widget.model?.coins ?? 0}金币解锁" + : "邀请得3日VIP", colors: const [Color(0xffFFE8BE), Color(0xffE6B764)], textColor: const Color(0xff694923), - onTap: () => status.isNeedBuy ? _onCoinUnlock() : Get.to(() => MineSharePage()), + onTap: () => status.isNeedBuy + ? _onCoinUnlock() + : Get.to(() => MineSharePage()), ), 18.sizeBoxW, _btn( @@ -147,11 +165,13 @@ class _VideoMaskBuyViewState extends State { child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Text("使用观影券", style: TextStyle(color: Colors.white, fontSize: 12)), + const Text("使用观影券", + style: TextStyle(color: Colors.white, fontSize: 12)), 3.sizeBoxW, Text( "x${me?.couponCount ?? 0}", - style: const TextStyle(color: Color(0xffE5365C), fontSize: 12), + style: const TextStyle( + color: Color(0xffE5365C), fontSize: 12), ), ], ), diff --git a/lib/hj_page/video/view/video_menu_view.dart b/lib/hj_page/video/view/video_menu_view.dart index 4ee9ced..e008ad0 100644 --- a/lib/hj_page/video/view/video_menu_view.dart +++ b/lib/hj_page/video/view/video_menu_view.dart @@ -4,11 +4,11 @@ import 'dart:ui' show ImageFilter; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:video_player/video_player.dart'; import '../../../hj_utils/buy_util.dart'; @@ -75,13 +75,15 @@ class _VideoMenuViewState extends State { bool get isPreview { final model = widget.videoModel; if (FreePlayManager().useFreePlay(model)) return false; - return model?.previewURL?.isNotEmpty == true && (needVip(model) || needCoin(model)); + return model?.previewURL?.isNotEmpty == true && + (needVip(model) || needCoin(model)); } /// 未购买/未开通 VIP 时,松手后超出试看区间则回弹到边界 bool get _shouldLimitSeek { final model = widget.videoModel; - if (model?.mediaInfo?.isCartoonFreeEpisode == true) return false; // 动漫免费集:整条进度可拖,不锁试看区间 + if (model?.mediaInfo?.isCartoonFreeEpisode == true) + return false; // 动漫免费集:整条进度可拖,不锁试看区间 if (FreePlayManager().useFreePlay(model)) return false; if (model?.freeArea == true) return false; if (model?.vidStatus?.hasPaid == true) return false; @@ -89,7 +91,8 @@ class _VideoMenuViewState extends State { if (coinFreeCount(model) >= 0) return false; if (model?.isCoinVideo() == true) { if (globalStore.isVIP && model?.coins == 0) return false; - if (model?.videoType != 1 && presaleProvider.coinVideoFreeCount >= 0) return false; + if (model?.videoType != 1 && presaleProvider.coinVideoFreeCount >= 0) + return false; } final status = longVideoStatus(model); return status.isNeedPay; @@ -122,7 +125,8 @@ class _VideoMenuViewState extends State { } /// 试看锁定:需付费(区间非空)且 [sec] 已超出免费试看区间 → 禁止拖动 - bool _isSeekLocked(int sec) => _seekRange.$1 != null && widget.videoModel?.isInFreeTime(sec) != true; + bool _isSeekLocked(int sec) => + _seekRange.$1 != null && widget.videoModel?.isInFreeTime(sec) != true; /// 松手落点:先夹到 [0,总时长],再夹回试看区间边界 Duration _snapSeek(Duration target) { @@ -234,7 +238,8 @@ class _VideoMenuViewState extends State { @override Widget build(BuildContext context) { - final menuVisible = _showMenu || !_isInited || _isLongPress; //操作台/未初始化/长按倍速时可见 + final menuVisible = + _showMenu || !_isInited || _isLongPress; //操作台/未初始化/长按倍速时可见 //试看区间每帧只算一次:_shouldLimitSeek 内含 useFreePlay 等带副作用的判断,不能每次拖动都重跑 _seekRange = _calcSeekRange(); return GestureDetector( @@ -242,7 +247,8 @@ class _VideoMenuViewState extends State { onTap: _toggleMenu, onHorizontalDragStart: (_) { //试看结束/未初始化禁止拖动 - if (_isSeekLocked(playCtr.value.position.inSeconds) || !playCtr.value.isInitialized) return; + if (_isSeekLocked(playCtr.value.position.inSeconds) || + !playCtr.value.isInitialized) return; _wasPlaying = playCtr.value.isPlaying; if (_wasPlaying) playCtr.pause(); _seekPos = playCtr.value.position; @@ -250,7 +256,8 @@ class _VideoMenuViewState extends State { setState(() {}); }, onHorizontalDragUpdate: (details) { - if (_isSeekLocked(playCtr.value.position.inSeconds) || !playCtr.value.isInitialized) return; + if (_isSeekLocked(playCtr.value.position.inSeconds) || + !playCtr.value.isInitialized) return; _wakeMenu(); _dragSeek(details.delta); }, @@ -310,7 +317,8 @@ class _VideoMenuViewState extends State { Positioned( top: 12, right: 16, - child: VideoStatusView(model: widget.videoModel, onBuyEvent: widget.onBuyEvent), + child: VideoStatusView( + model: widget.videoModel, onBuyEvent: widget.onBuyEvent), ), Positioned(bottom: 0, left: 0, right: 0, child: _bottomMenu()), Obx(() { @@ -323,7 +331,9 @@ class _VideoMenuViewState extends State { scale: animation, child: FadeTransition(opacity: animation, child: child), ), - child: (!_isInited || buffering || playing) ? const SizedBox(key: ValueKey('playIconEmpty')) : _playIcon(), + child: (!_isInited || buffering || playing) + ? const SizedBox(key: ValueKey('playIconEmpty')) + : _playIcon(), ); }), if (_showSeekText) _seekText(), @@ -334,7 +344,8 @@ class _VideoMenuViewState extends State { top: 0, bottom: 0, right: _showSpeed ? 0 : -150, - child: IgnorePointer(ignoring: !_showSpeed, child: _speedPanel()), + child: IgnorePointer( + ignoring: !_showSpeed, child: _speedPanel()), ), if (_skipDir != 0) Positioned( @@ -350,7 +361,11 @@ class _VideoMenuViewState extends State { duration: const Duration(milliseconds: 220), child: Container( color: Colors.black.withValues(alpha: 0.5), - padding: EdgeInsets.fromLTRB((_skipDir == 1) ? 12 : 24, 12, (_skipDir == 1) ? 24 : 12, 12), + padding: EdgeInsets.fromLTRB( + (_skipDir == 1) ? 12 : 24, + 12, + (_skipDir == 1) ? 24 : 12, + 12), child: _skipHint(), ), ), @@ -397,7 +412,9 @@ class _VideoMenuViewState extends State { child: FadeTransition(opacity: animation, child: child), ), child: Image.asset( - showPause ? "pause_icon.webp".videoPath : "play.webp".videoPath, + showPause + ? "pause_icon.webp".videoPath + : "play.webp".videoPath, key: ValueKey(showPause), width: 20.w, ), @@ -442,7 +459,8 @@ class _VideoMenuViewState extends State { }, child: const Padding( padding: EdgeInsets.fromLTRB(4, 6, 6, 6), - child: Text("倍速", style: TextStyle(color: Colors.white, fontSize: 14)), + child: Text("倍速", + style: TextStyle(color: Colors.white, fontSize: 14)), ), ), InkWell( @@ -452,7 +470,8 @@ class _VideoMenuViewState extends State { height: 26, width: 26, margin: const EdgeInsets.only(right: 6), - child: Image.asset("full_icon.png".videoPath, width: 26, height: 26), + child: Image.asset("full_icon.png".videoPath, + width: 26, height: 26), ), ), ], @@ -480,7 +499,8 @@ class _VideoMenuViewState extends State { child: ListView.separated( padding: EdgeInsets.zero, itemCount: speeds.length, - separatorBuilder: (_, __) => Container(height: 1, color: Colors.white.withValues(alpha: 0.05)), + separatorBuilder: (_, __) => Container( + height: 1, color: Colors.white.withValues(alpha: 0.05)), itemBuilder: (_, i) => _speedItem(speeds[i]), ), ), @@ -538,7 +558,8 @@ class _VideoMenuViewState extends State { children: [ //顶部偏移叠加安全区高度,避免竖屏被刘海/灵动岛遮挡 //注意:必须用 context 的 MediaQuery(外层 SafeArea 已吃掉 top 时这里就该是 0),Get.mediaQuery 拿的是根节点值会多顶 47 - ((widget.isFull ? 24 : 12) + MediaQuery.of(context).padding.top).sizeBoxH, + ((widget.isFull ? 24 : 12) + MediaQuery.of(context).padding.top) + .sizeBoxH, Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), //半透明黑底:亮色画面上也能看清时间 @@ -551,7 +572,8 @@ class _VideoMenuViewState extends State { children: [ Text( DateTimeUtil.formatDuration(showDuration) ?? "", - style: const TextStyle(color: AppColors.actionRed, fontSize: 14), //主题黄 + style: const TextStyle( + color: AppColors.actionRed, fontSize: 14), //主题黄 ), if (playCtr.value.isInitialized) Text( @@ -571,12 +593,14 @@ class _VideoMenuViewState extends State { final isForward = _skipDir == 1; final text = Text( isForward ? "快进10秒" : "快退10秒", - style: TextStyle(color: Colors.white.withValues(alpha: 0.8), fontSize: 13), + style: + TextStyle(color: Colors.white.withValues(alpha: 0.8), fontSize: 13), ); final arrows = _SeekArrows(forward: isForward); return Row( mainAxisSize: MainAxisSize.min, - children: isForward ? [text, 4.sizeBoxW, arrows] : [arrows, 4.sizeBoxW, text], + children: + isForward ? [text, 4.sizeBoxW, arrows] : [arrows, 4.sizeBoxW, text], ); } } @@ -590,8 +614,11 @@ class _SeekArrows extends StatefulWidget { State<_SeekArrows> createState() => _SeekArrowsState(); } -class _SeekArrowsState extends State<_SeekArrows> with SingleTickerProviderStateMixin { - late final AnimationController _ctr = AnimationController(vsync: this, duration: const Duration(milliseconds: 900))..repeat(); +class _SeekArrowsState extends State<_SeekArrows> + with SingleTickerProviderStateMixin { + late final AnimationController _ctr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 900)) + ..repeat(); @override void dispose() { @@ -605,7 +632,8 @@ class _SeekArrowsState extends State<_SeekArrows> with SingleTickerProviderState ? const Icon(Icons.play_arrow_rounded, color: Colors.white, size: 18) : const RotatedBox( quarterTurns: 2, - child: Icon(Icons.play_arrow_rounded, color: Colors.white, size: 18), + child: + Icon(Icons.play_arrow_rounded, color: Colors.white, size: 18), ); return AnimatedBuilder( animation: _ctr, @@ -615,9 +643,11 @@ class _SeekArrowsState extends State<_SeekArrows> with SingleTickerProviderState // 波沿方向流动:快进 左→右、快退 右→左 final i = widget.forward ? index : (2 - index); final phase = (_ctr.value + i / 3.0) % 1.0; - final opacity = 0.25 + 0.75 * (1 - (2 * phase - 1).abs()); // 三角波 0.25~1.0 + final opacity = + 0.25 + 0.75 * (1 - (2 * phase - 1).abs()); // 三角波 0.25~1.0 // 压窄每个箭头的占位宽度,让三角波间距更紧凑 - return SizedBox(width: 10, child: Opacity(opacity: opacity, child: arrow)); + return SizedBox( + width: 10, child: Opacity(opacity: opacity, child: arrow)); }), ), ); diff --git a/lib/hj_page/video/view/video_status_view.dart b/lib/hj_page/video/view/video_status_view.dart index bf30d36..7b6e87a 100644 --- a/lib/hj_page/video/view/video_status_view.dart +++ b/lib/hj_page/video/view/video_status_view.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/video_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; import 'long_video_status.dart'; @@ -39,7 +39,8 @@ class _VipFreeTipViewState extends State { Widget build(BuildContext context) { if (!_isShowTip) return const SizedBox(); // 仅「已享VIP免费特权」走本 view,3 秒后自动隐藏;其余状态归 VideoStatusView - if (longVideoStatus(widget.videoModel).type != LongVideoStatusType.vipFree) { + if (longVideoStatus(widget.videoModel).type != + LongVideoStatusType.vipFree) { return const SizedBox(); } _startHideTimer(); @@ -70,9 +71,12 @@ class VideoStatusView extends StatelessWidget { if (model == null) return const SizedBox.shrink(); final status = longVideoStatus(model); final isCartoon = model?.videoType == 1; - final hideForCartoon = - isCartoon && (status.type == LongVideoStatusType.skipPreview || status.type == LongVideoStatusType.coinFree); - if (hideForCartoon || status.type == LongVideoStatusType.none || status.type == LongVideoStatusType.vipFree) { + final hideForCartoon = isCartoon && + (status.type == LongVideoStatusType.skipPreview || + status.type == LongVideoStatusType.coinFree); + if (hideForCartoon || + status.type == LongVideoStatusType.none || + status.type == LongVideoStatusType.vipFree) { return const SizedBox(); } return GestureDetector( diff --git a/lib/hj_page/video/view/video_tabbar_menu_widget.dart b/lib/hj_page/video/view/video_tabbar_menu_widget.dart index 36df279..43a5267 100644 --- a/lib/hj_page/video/view/video_tabbar_menu_widget.dart +++ b/lib/hj_page/video/view/video_tabbar_menu_widget.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/video_download/download_button.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/indicator/custom_tab_indicator.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/video_download/download_button.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/indicator/custom_tab_indicator.dart'; import '../../../alert/video/video_line_menu_alert.dart'; import '../../../hj_model/splash/domain_source_model.dart'; @@ -40,7 +40,8 @@ class _VideoTabbarMenuWidgetState extends State { Widget build(BuildContext context) { Domain? selectedCnd; try { - selectedCnd = Address.cdnAddressLists.firstWhere((element) => element.url == Address.cdnAddress); + selectedCnd = Address.cdnAddressLists + .firstWhere((element) => element.url == Address.cdnAddress); } catch (e) { debugLog(e); } @@ -61,15 +62,18 @@ class _VideoTabbarMenuWidgetState extends State { labelPadding: const EdgeInsets.symmetric(horizontal: 12), labelColor: const Color(0xE5FFFFFF), unselectedLabelColor: const Color(0x73FFFFFF), - labelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600), - unselectedLabelStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w400), + labelStyle: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w600), + unselectedLabelStyle: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400), indicatorSize: TabBarIndicatorSize.label, dividerHeight: 0, // 去掉 TabBar 默认底部分割线(外层已有 0.5.line) indicator: CustomIndicator( color: AppColors.actionRed, width: 16, height: 4, - borderRadius: const BorderRadius.vertical(top: Radius.circular(3)), + borderRadius: + const BorderRadius.vertical(top: Radius.circular(3)), ), tabs: [ const Tab(text: "简介"), @@ -104,12 +108,14 @@ class _VideoTabbarMenuWidgetState extends State { InkWell( enableFeedback: false, onTap: () async { - if (await VideoLineMenuAlert.show()) widget.onSwitchLine?.call(); + if (await VideoLineMenuAlert.show()) + widget.onSwitchLine?.call(); setState(() {}); }, child: Row( children: [ - Image.asset("line_switch.webp".videoPath, width: 16), + Image.asset("line_switch.webp".videoPath, + width: 16), 2.sizeBoxW, Text( selectedCnd?.desc ?? '', diff --git a/lib/hj_page/video/view/vip_promo_banner.dart b/lib/hj_page/video/view/vip_promo_banner.dart index ca52074..f1ad99d 100644 --- a/lib/hj_page/video/view/vip_promo_banner.dart +++ b/lib/hj_page/video/view/vip_promo_banner.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:provider/provider.dart'; import 'package:video_player/video_player.dart'; @@ -42,7 +42,8 @@ class _VipPromoBanner extends State { if (limitTime.canShow) return LimitTimeBanner(); // 2. 支付分层横幅(playPage 图 + vipCard 跳转),都没有则不展示 final layeredConfig = MineMsgProvider().payTier?.config; - if ((layeredConfig?.playPage ?? '').isNotEmpty) return _buildLayeredBanner(layeredConfig!); + if ((layeredConfig?.playPage ?? '').isNotEmpty) + return _buildLayeredBanner(layeredConfig!); return const SizedBox(); }, ); @@ -75,11 +76,16 @@ class _VipPromoBanner extends State { fit: StackFit.expand, children: [ // 分层横幅图(后端加密图) - NetworkImageLoader(imageUrl: config.playPage ?? "", fit: BoxFit.fill, borderRadius: 0), + NetworkImageLoader( + imageUrl: config.playPage ?? "", + fit: BoxFit.fill, + borderRadius: 0), // 分层倒计时:监听 tick 每秒刷新,过期自动收起 ValueListenableBuilder( valueListenable: MineMsgProvider().tick, - builder: (_, __, ___) => config.hasDiscountCountdown ? _buildLayeredCountdown(config) : const SizedBox.shrink(), + builder: (_, __, ___) => config.hasDiscountCountdown + ? _buildLayeredCountdown(config) + : const SizedBox.shrink(), ), ], ), @@ -112,7 +118,8 @@ class _VipPromoBanner extends State { borderRadius: BorderRadius.circular(3), border: Border.all(color: const Color(0xffFFE381), width: 0.5), ), - child: Text(value, style: const TextStyle(color: Colors.white, fontSize: 12)), + child: Text(value, + style: const TextStyle(color: Colors.white, fontSize: 12)), ); } diff --git a/lib/hj_page/web_page/h5_logic.dart b/lib/hj_page/web_page/h5_logic.dart index 9489ed6..6cd9369 100644 --- a/lib/hj_page/web_page/h5_logic.dart +++ b/lib/hj_page/web_page/h5_logic.dart @@ -1,7 +1,7 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/pay_order_source.dart'; -import 'package:hgmj/routers/jump_router.dart'; +import 'package:wydj/hj_page/mine/mine_vip/pay_order_source.dart'; +import 'package:wydj/routers/jump_router.dart'; class H5Logic extends GetxController { // ========== 属性声明 ========== @@ -23,12 +23,15 @@ class H5Logic extends GetxController { // ========== 私有方法 ========== // 注册 H5 与 native 的 JS 桥 void _setupHandlers(InAppWebViewController controller) { - controller.addJavaScriptHandler(handlerName: 'prizeBack', callback: (_) => Get.back()); - controller.addJavaScriptHandler(handlerName: 'shopBack', callback: (_) => Get.back()); + controller.addJavaScriptHandler( + handlerName: 'prizeBack', callback: (_) => Get.back()); + controller.addJavaScriptHandler( + handlerName: 'shopBack', callback: (_) => Get.back()); // 跳金币充值 controller.addJavaScriptHandler( handlerName: 'shopCharge', - callback: (_) => pushToWalletPage(tabPosition: 1, sourcePage: PaySourcePage.h5Activity), + callback: (_) => pushToWalletPage( + tabPosition: 1, sourcePage: PaySourcePage.h5Activity), ); // H5 触发外部链接跳转 controller.addJavaScriptHandler( diff --git a/lib/hj_page/web_page/h5_page.dart b/lib/hj_page/web_page/h5_page.dart index 3cd34e1..42349f6 100644 --- a/lib/hj_page/web_page/h5_page.dart +++ b/lib/hj_page/web_page/h5_page.dart @@ -3,8 +3,8 @@ import 'dart:collection'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/unique_tag_mixin.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/unique_tag_mixin.dart'; import 'h5_logic.dart'; import 'h5_webview_settings.dart'; @@ -37,7 +37,8 @@ class _H5PageState extends State with UniqueTagMixin { init: H5Logic(url: widget.url), builder: (logic) { return Scaffold( - appBar: widget.showTitle ? AppBar(title: Text(widget.title ?? "")) : null, + appBar: + widget.showTitle ? AppBar(title: Text(widget.title ?? "")) : null, body: SafeArea( child: Stack( children: [ diff --git a/lib/hj_utils/api_service/acg_service.dart b/lib/hj_utils/api_service/acg_service.dart index 10c6590..e50c099 100644 --- a/lib/hj_utils/api_service/acg_service.dart +++ b/lib/hj_utils/api_service/acg_service.dart @@ -1,9 +1,9 @@ //acg模块网络请求 -import 'package:hgmj/hj_model/acg/comic_chapters_model.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/acg/comic_chapters_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import '../../hj_model/acg/cartoon_more_list.dart'; import '../../hj_model/cartoon_media_info.dart'; @@ -38,7 +38,8 @@ class ACGService { final result = await httpManager.fetchResponseByGET( "/tag/media/list", param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -56,8 +57,8 @@ class ACGService { /// 获取标签详情 static Future fetchMediaTag(String tagId) async { final param = {'id': tagId}; - final result = - await httpManager.fetchResponseByGET('/media_tag/info', param: param, jsonTransformation: (json) => TagsBean.fromMap(json)); + final result = await httpManager.fetchResponseByGET('/media_tag/info', + param: param, jsonTransformation: (json) => TagsBean.fromMap(json)); return result.isSuccess ? result.data : null; } @@ -87,7 +88,8 @@ class ACGService { final result = await httpManager.fetchResponseByGET( '/media/hot', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -146,14 +148,17 @@ class ACGService { final result = await httpManager.fetchResponseByGET( '/media/ranking', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } //获取动漫内容章节列表 sortType: 0-正序 1-倒序 - static Future?> getChapterList(String mediaId, int pageNumber, int pageSize, {int? sortType = 0}) async { + static Future?> getChapterList( + String mediaId, int pageNumber, int pageSize, + {int? sortType = 0}) async { final param = { 'pageNumber': pageNumber, 'pageSize': pageSize, @@ -163,7 +168,8 @@ class ACGService { final result = await httpManager.fetchResponseByGET( '/media_content/list', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -187,7 +193,8 @@ class ACGService { final result = await httpManager.fetchResponseByGET( '/media/recommend', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -195,8 +202,20 @@ class ACGService { //kind:1动漫 2漫画 3小说 4短剧 //sortType:1-最新上架 2-最多观看 static Future mediaSearch( - {int page = 1, int size = 20, int? kind, String? tagName, int? sortType, String? keyword}) async { - final param = {'pageNumber': page, 'pageSize': size, 'kind': kind, 'tagName': tagName, 'sortType': sortType, 'keyword': keyword}; + {int page = 1, + int size = 20, + int? kind, + String? tagName, + int? sortType, + String? keyword}) async { + final param = { + 'pageNumber': page, + 'pageSize': size, + 'kind': kind, + 'tagName': tagName, + 'sortType': sortType, + 'keyword': keyword + }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET( '/media/search', @@ -244,7 +263,8 @@ class ACGService { final result = await httpManager.fetchResponseByGET( '/media/topic', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } diff --git a/lib/hj_utils/api_service/ai_service.dart b/lib/hj_utils/api_service/ai_service.dart index e68c26a..9944535 100644 --- a/lib/hj_utils/api_service/ai_service.dart +++ b/lib/hj_utils/api_service/ai_service.dart @@ -1,9 +1,9 @@ //AI相关接口 -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_page/ai/ai_sub_type/ai_function_logic.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_page/ai/ai_sub_type/ai_function_logic.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import '../../hj_page/ai/models/ai_girl_resp_model.dart'; import '../../hj_page/ai/models/ai_mod_list_model.dart'; @@ -18,7 +18,11 @@ class AIService { int? pageSize, int? status, ) async { - final param = {'pageNumber': pageNumber, 'pageSize': pageSize, 'status': status}; + final param = { + 'pageNumber': pageNumber, + 'pageSize': pageSize, + 'status': status + }; final result = await httpManager.fetchResponseByGET( '/ai/undress/list', param: param, @@ -68,8 +72,13 @@ class AIService { } //生成AI脱衣记录 - static Future generateUndress(List? originPics, bool shareStatus, String? shareTitle) async { - final param = {'originPic': originPics, 'shareStatus': shareStatus ? 1 : 0, 'shareTitle': shareTitle}..removeWhere((k, v) => v == null); + static Future generateUndress( + List? originPics, bool shareStatus, String? shareTitle) async { + final param = { + 'originPic': originPics, + 'shareStatus': shareStatus ? 1 : 0, + 'shareTitle': shareTitle + }..removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByPOST( '/ai/undress/generate', param: param, @@ -93,12 +102,15 @@ class AIService { 'shareTitle': shareTitle }..removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByPOST('/ai/changeface/generate', param: param); + final result = await httpManager + .fetchResponseByPOST('/ai/changeface/generate', param: param); return result.isSuccess && result.data == 'success'; } //生成图片AI换脸 - static Future generateImg(String picture, String imgModId, bool shareStatus, String? shareTitle, {String? discount}) async { + static Future generateImg( + String picture, String imgModId, bool shareStatus, String? shareTitle, + {String? discount}) async { final param = { 'originPic': picture, 'mId': imgModId, @@ -129,7 +141,8 @@ class AIService { String? categoryId, //模版分类id,如果为空,则默认第一个模版分类 }) async { //接口只认 type=0/1,枚举在这一层换回去 - final param = {'type': type.isVideoFace ? 1 : 0, 'categoryId': categoryId}..removeWhere((k, v) => v == null); + final param = {'type': type.isVideoFace ? 1 : 0, 'categoryId': categoryId} + ..removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET( '/ai/mod/v2/list', param: param, @@ -141,21 +154,24 @@ class AIService { ///删除AI订单脱衣 static Future deleteUndress(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai/undress/hide', param: param); + final result = + await httpManager.fetchResponseByPOST('/ai/undress/hide', param: param); return result.isSuccess; } ///删除AI换脸Video订单 static Future deleteChangeFace(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai/changeface/hide', param: param); + final result = await httpManager.fetchResponseByPOST('/ai/changeface/hide', + param: param); return result.isSuccess; } ///删除AI换脸 Img订单 static Future deleteImg(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai/img/hide', param: param); + final result = + await httpManager.fetchResponseByPOST('/ai/img/hide', param: param); return result.isSuccess; } @@ -200,9 +216,12 @@ class AIService { } ///获取AI广场列表 - static Future?> getPlazaList(int pageNumber, {int pageSize = 10}) async { + static Future?> getPlazaList(int pageNumber, + {int pageSize = 10}) async { final result = await httpManager.fetchResponseByGET('/aiplaza/list', - param: {'pageNumber': pageNumber, 'pageSize': pageSize}, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + param: {'pageNumber': pageNumber, 'pageSize': pageSize}, + jsonTransformation: (json) => + ListBaseModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -210,7 +229,8 @@ class AIService { static Future getModelInfo(String? id, int? type) async { final param = {'id': id, 'type': type}; param.removeWhere((k, v) => v == null); - final resultData = await httpManager.fetchResponseByGET('/ai/mod/info', param: param); + final resultData = + await httpManager.fetchResponseByGET('/ai/mod/info', param: param); if (resultData.isSuccess) { final data = resultData.data; if (data is Map) { @@ -234,7 +254,11 @@ class AIService { int? pageSize, int? status, ) async { - final param = {'pageNumber': pageNumber, 'pageSize': pageSize, 'status': status}; + final param = { + 'pageNumber': pageNumber, + 'pageSize': pageSize, + 'status': status + }; final result = await httpManager.fetchResponseByGET( '/ai/text_to_image/list', param: param, @@ -246,7 +270,8 @@ class AIService { ///删除文字绘图 static Future deleteTextToImage(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai/text_to_image/hide', param: param); + final result = await httpManager + .fetchResponseByPOST('/ai/text_to_image/hide', param: param); return result.isSuccess; } @@ -257,7 +282,11 @@ class AIService { int? pageSize, int? status, ) async { - final param = {'pageNumber': pageNumber, 'pageSize': pageSize, 'status': status}; + final param = { + 'pageNumber': pageNumber, + 'pageSize': pageSize, + 'status': status + }; final result = await httpManager.fetchResponseByGET( '/ai/imagetovideo/list', param: param, @@ -269,7 +298,8 @@ class AIService { ///删除AI图生视频 static Future deleteImgVideo(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai/imagetovideo/hide', param: param); + final result = await httpManager + .fetchResponseByPOST('/ai/imagetovideo/hide', param: param); return result.isSuccess; } @@ -345,7 +375,11 @@ class AIService { int? pageSize, int? status, ) async { - final param = {'pageNumber': pageNumber, 'pageSize': pageSize, 'status': status}; + final param = { + 'pageNumber': pageNumber, + 'pageSize': pageSize, + 'status': status + }; final result = await httpManager.fetchResponseByGET( '/ai_text_to_novel/list', param: param, @@ -357,7 +391,8 @@ class AIService { ///删除AI文生图 static Future deleteNovel(String? id) async { final param = {'id': id}; - final result = await httpManager.fetchResponseByPOST('/ai_text_to_novel/hide', param: param); + final result = await httpManager + .fetchResponseByPOST('/ai_text_to_novel/hide', param: param); return result.isSuccess; } } diff --git a/lib/hj_utils/api_service/buy_service.dart b/lib/hj_utils/api_service/buy_service.dart index f0456ea..45997db 100644 --- a/lib/hj_utils/api_service/buy_service.dart +++ b/lib/hj_utils/api_service/buy_service.dart @@ -1,6 +1,6 @@ import 'package:dio/dio.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import 'package:uuid/uuid.dart'; /// 购买相关接口 @@ -56,7 +56,8 @@ class BuyService { ///[source] 来源页面标识 ///[experimentId]/[experimentVariant]/[sessionId] VIP 卡皮 A/B:与 /mine/topay 对齐回传 ///[requestId] 幂等键,见 [_idempotent] - static Future buyVip(int? productType, String? productID, String? productName, int? discountedPrice, + static Future buyVip(int? productType, String? productID, + String? productName, int? discountedPrice, {String? couponId = "", bool? finalPayStatus, String? source, @@ -80,11 +81,18 @@ class BuyService { 'contentId': contentId, 'checkoutContextId': checkoutContextId, // 空值不传,避免参数错误(DISABLED / 无实验时上游不填) - 'experimentId': (experimentId != null && experimentId.isNotEmpty) ? experimentId : null, - 'experimentVariant': (experimentVariant != null && experimentVariant.isNotEmpty) ? experimentVariant : null, - 'sessionId': (sessionId != null && sessionId.isNotEmpty) ? sessionId : null, + 'experimentId': (experimentId != null && experimentId.isNotEmpty) + ? experimentId + : null, + 'experimentVariant': + (experimentVariant != null && experimentVariant.isNotEmpty) + ? experimentVariant + : null, + 'sessionId': + (sessionId != null && sessionId.isNotEmpty) ? sessionId : null, }; param.removeWhere((k, v) => v == null); - return httpManager.fetchResponseByPOST('/product/buy', param: param, options: _idempotent(requestId)); + return httpManager.fetchResponseByPOST('/product/buy', + param: param, options: _idempotent(requestId)); } } diff --git a/lib/hj_utils/api_service/comment_service.dart b/lib/hj_utils/api_service/comment_service.dart index 58bb648..c713008 100644 --- a/lib/hj_utils/api_service/comment_service.dart +++ b/lib/hj_utils/api_service/comment_service.dart @@ -1,10 +1,10 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; //评论相关接口 -import 'package:hgmj/hj_model/comment/comment_list_res.dart'; -import 'package:hgmj/hj_model/comment/comment_model.dart'; -import 'package:hgmj/hj_model/comment/reply_model.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/comment/comment_list_res.dart'; +import 'package:wydj/hj_model/comment/comment_model.dart'; +import 'package:wydj/hj_model/comment/reply_model.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; class CommentService { // //一级评论的全部列表 diff --git a/lib/hj_utils/api_service/common_service.dart b/lib/hj_utils/api_service/common_service.dart index 893356a..715aa72 100644 --- a/lib/hj_utils/api_service/common_service.dart +++ b/lib/hj_utils/api_service/common_service.dart @@ -1,8 +1,8 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; //公共服务api接口 -import 'package:hgmj/hj_model/home/video_list_model.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/home/video_list_model.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import '../../hj_model/banner/comment_top_banner_model.dart'; import '../../hj_model/home/plate_model.dart'; @@ -64,14 +64,18 @@ class CommonService { } /// 按场景拉取 Banner 列表(如评论置顶 COMMENT_TOP) - static Future> fetchBannerList({required String scene}) async { + static Future> fetchBannerList( + {required String scene}) async { final result = await httpManager.fetchResponseByGET( '/banner/list', param: {'scene': scene}, jsonTransformation: (json) { final list = json['list'] as List?; if (list == null) return []; - final items = list.map((e) => CommentTopBannerModel.fromJson(e is Map ? Map.from(e) : null)).toList(); + final items = list + .map((e) => CommentTopBannerModel.fromJson( + e is Map ? Map.from(e) : null)) + .toList(); items.sort((a, b) => (b.sort ?? 0).compareTo(a.sort ?? 0)); return items; }, @@ -100,14 +104,16 @@ class CommonService { param: param, ); if (result.isSuccess) { - eventBus.emit(CollectStatusModel(id: objID, isLiked: true, type: type, likeCountDelta: 1)); + eventBus.emit(CollectStatusModel( + id: objID, isLiked: true, type: type, likeCountDelta: 1)); } return result.isSuccess; } //取消点赞 //SP:长视频 SHORT:短视频 COVER:图文帖子 PIC:图集帖子 SEED_LINK:种子/黄油帖子 TAG:标签 COMMENT:评论 video:动漫 image:漫画 text:小说 - static Future cancelLike(String? objID, String? type, {List? objIDArr}) async { + static Future cancelLike(String? objID, String? type, + {List? objIDArr}) async { assert((type != null && type.isNotEmpty), 'cancelLike type 不能为空'); List ids = []; if (objIDArr?.isNotEmpty == true) { @@ -121,18 +127,31 @@ class CommonService { param: param, ); if (result.isSuccess) { - eventBus.emit(CollectStatusModel(id: objID, isLiked: false, type: type, likeCountDelta: -1)); + eventBus.emit(CollectStatusModel( + id: objID, isLiked: false, type: type, likeCountDelta: -1)); } return result.isSuccess; } /// 获取我关注用户发的视频 /// type 为0 获取用户所有动态, 1为获取用户全部视频 - static Future fetchFollowDynamics({int page = 1, int size = 20, int? uid, int? type, String? newsType}) async { - final param = {'pageSize': size, 'pageNumber': page, 'uid': uid, 'type': type, 'newsType': newsType}; + static Future fetchFollowDynamics( + {int page = 1, + int size = 20, + int? uid, + int? type, + String? newsType}) async { + final param = { + 'pageSize': size, + 'pageNumber': page, + 'uid': uid, + 'type': type, + 'newsType': newsType + }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET('/follow/dynamics/list', - param: param, jsonTransformation: (json) => VideoListResp.fromJson(json)); + param: param, + jsonTransformation: (json) => VideoListResp.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -150,7 +169,8 @@ class CommonService { 'type': followUserType, }; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByGET('/follow/list', param: param, jsonTransformation: (json) { + final result = await httpManager.fetchResponseByGET('/follow/list', + param: param, jsonTransformation: (json) { return ListBaseModel.fromJson(json); }); return result.isSuccess ? result.data : null; @@ -198,7 +218,8 @@ class CommonService { 'newsType': newsType, }; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByGET('/vid/recommend/list', param: param, jsonTransformation: (json) { + final result = await httpManager.fetchResponseByGET('/vid/recommend/list', + param: param, jsonTransformation: (json) { return VideoListResp.fromJson(json); }); return result.isSuccess ? result.data : null; diff --git a/lib/hj_utils/api_service/drama_service.dart b/lib/hj_utils/api_service/drama_service.dart index 5fa501b..351a5b4 100644 --- a/lib/hj_utils/api_service/drama_service.dart +++ b/lib/hj_utils/api_service/drama_service.dart @@ -1,20 +1,22 @@ import 'package:dio/dio.dart'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/media_content.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/media_content.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; /// 短剧接口。金币解锁已并入 PayManager/BuyService,这里只剩读操作 + 两个计数型写操作: /// 信息流翻页去重、分享互动计数,都必须带 `X-Request-ID`——同一次业务的重试要复用同一个 id, /// 换新 id 就会重复计数。 class DramaService { - static Options _idempotent(String requestId) => Options(headers: {'X-Request-ID': requestId}); + static Options _idempotent(String requestId) => + Options(headers: {'X-Request-ID': requestId}); /// AI短剧信息流:一条 = 一部剧 + 该剧第 1 集。 /// 排序、去重、已看沉底全在服务端,客户端不得二次排序,也不分页页码——每次请求都是下一批 - static Future?> fetchFeed({int size = 20, String? requestId}) async { + static Future?> fetchFeed( + {int size = 20, String? requestId}) async { final result = await httpManager.fetchResponseByGET( '/media/drama/feed', param: {'pageSize': size}, @@ -29,7 +31,10 @@ class DramaService { final result = await httpManager.fetchResponseByGET( '/media/drama/topics', jsonTransformation: (json) => - (json['list'] as List?)?.map((e) => DramaTopic.fromJson(e)).toList() ?? [], + (json['list'] as List?) + ?.map((e) => DramaTopic.fromJson(e)) + .toList() ?? + [], ); return result.isSuccess ? result.data : null; } @@ -48,7 +53,8 @@ class DramaService { 'pageNumber': page, 'pageSize': size, }, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -104,17 +110,24 @@ class DramaService { final result = await httpManager.fetchResponseByPOST( '/media/library/search', param: param, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } /// 分集列表(选集面板用) [sortType] 0-正序 1-倒序 - static Future?> fetchEpisodeList(String dramaId, int page, int size) async { + static Future?> fetchEpisodeList( + String dramaId, int page, int size) async { if (dramaId.isEmpty) return null; // 与 fetchDetail 一致:没有剧 id 就别发空请求 final result = await httpManager.fetchResponseByGET( '/media_content/list', - param: {'mediaId': dramaId, 'pageNumber': page, 'pageSize': size, 'sortType': 0}, + param: { + 'mediaId': dramaId, + 'pageNumber': page, + 'pageSize': size, + 'sortType': 0 + }, jsonTransformation: (json) => ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; @@ -133,31 +146,42 @@ class DramaService { } /// 我的喜欢-短剧 - static Future?> fetchLikes(int page, {int size = 20}) async { + static Future?> fetchLikes(int page, + {int size = 20}) async { final result = await httpManager.fetchResponseByGET( '/mine/like', param: {'likeType': 'drama', 'pageNumber': page, 'pageSize': size}, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } /// 我的收藏-短剧 [sortType] 0-最新收藏 1-最近更新 - static Future?> fetchFavorites(int page, {int size = 20, int sortType = 0}) async { + static Future?> fetchFavorites(int page, + {int size = 20, int sortType = 0}) async { final result = await httpManager.fetchResponseByGET( '/media_bookshelf/list', - param: {'type': 'drama', 'sortType': sortType, 'pageNumber': page, 'pageSize': size}, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + param: { + 'type': 'drama', + 'sortType': sortType, + 'pageNumber': page, + 'pageSize': size + }, + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } /// 我的已购-短剧(按剧去重,点进去看每集的 hasBuy) - static Future?> fetchPurchased(int page, {int size = 20}) async { + static Future?> fetchPurchased(int page, + {int size = 20}) async { final result = await httpManager.fetchResponseByGET( '/media/my_buy', param: {'mediaType': 'drama', 'pageNumber': page, 'pageSize': size}, - jsonTransformation: (json) => ListBaseModel.fromJson(json), + jsonTransformation: (json) => + ListBaseModel.fromJson(json), ); return result.isSuccess ? result.data : null; } @@ -198,6 +222,8 @@ class DramaService { }, options: _idempotent(eventId), ); - return result.isSuccess ? (result.data is Map ? result.data['qrCode'] : null) : null; + return result.isSuccess + ? (result.data is Map ? result.data['qrCode'] : null) + : null; } } diff --git a/lib/hj_utils/api_service/group_service.dart b/lib/hj_utils/api_service/group_service.dart index f13b457..8e78994 100644 --- a/lib/hj_utils/api_service/group_service.dart +++ b/lib/hj_utils/api_service/group_service.dart @@ -1,34 +1,43 @@ -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; import '../../hj_page/community/group_chat/model/im_group_list_model.dart'; import '../../hj_page/community/group_chat/model/im_message_resp.dart'; class GroupService { ///获取im群组列表 - static Future getList(int pageNumber, {int pageSize = 10}) async { + static Future getList(int pageNumber, + {int pageSize = 10}) async { final result = await httpManager.fetchResponseByGET('/imgroup/list', - param: {'pageNumber': pageNumber, 'pageSize': pageSize}, jsonTransformation: (json) => IMGroupListModel.fromJson(json)); + param: {'pageNumber': pageNumber, 'pageSize': pageSize}, + jsonTransformation: (json) => IMGroupListModel.fromJson(json)); return result.isSuccess ? result.data : null; } ///获取是否加入群组详情 static Future getHasJoin(int? groupId) async { - return httpManager.fetchResponseByGET('/imgroup/hasjoin', param: {'groupId': groupId}); + return httpManager + .fetchResponseByGET('/imgroup/hasjoin', param: {'groupId': groupId}); } ///获取im消息列表 - static Future getMessages(int? groupId, int pageNumber, int pageSize) async { + static Future getMessages( + int? groupId, int pageNumber, int pageSize) async { final result = await httpManager.fetchResponseByGET('/immessage/list', - param: {'groupId': groupId, 'pageNumber': pageNumber, 'pageSize': pageSize}, + param: { + 'groupId': groupId, + 'pageNumber': pageNumber, + 'pageSize': pageSize + }, jsonTransformation: (json) => IMMessageResp.fromJson(json)); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } ///发送im消息 - static Future sendMessage(int? groupId, String? content, String? image) async { + static Future sendMessage( + int? groupId, String? content, String? image) async { final data = {'groupId': groupId, 'content': content, 'image': image}; data.removeWhere((k, v) => v == null); return httpManager.fetchResponseByPOST('/immessage/send', param: data); diff --git a/lib/hj_utils/api_service/mine_service.dart b/lib/hj_utils/api_service/mine_service.dart index f6b31ba..e83c5a8 100644 --- a/lib/hj_utils/api_service/mine_service.dart +++ b/lib/hj_utils/api_service/mine_service.dart @@ -1,13 +1,13 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/mine/exchange_record_model.dart'; -import 'package:hgmj/hj_model/user/user_income_info_model.dart'; -import 'package:hgmj/hj_model/user/user_info_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/mine/exchange_record_model.dart'; +import 'package:wydj/hj_model/user/user_income_info_model.dart'; +import 'package:wydj/hj_model/user/user_info_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/main_page/provider/msg_provider.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import '../../hj_model/cartoon_media_info.dart'; import '../../hj_model/message/message_dynamic_list.dart'; @@ -79,7 +79,9 @@ class MineService { } static Future reduceDownloadCount() async { - return (await httpManager.fetchResponseByPOST('/mine/download/use', param: {})).isSuccess; + return (await httpManager.fetchResponseByPOST('/mine/download/use', + param: {})) + .isSuccess; } /// 获取用户信息 @@ -96,7 +98,8 @@ class MineService { } /// 提现明细 - static Future getWithdrawDetails({int pageNumber = 1, int pageSize = 10}) async { + static Future getWithdrawDetails( + {int pageNumber = 1, int pageSize = 10}) async { final result = await httpManager.fetchResponseByGET( '/withdraw/order', param: { @@ -159,7 +162,13 @@ class MineService { } static Future mobileLogin( - String? mobile, String? code, String? devID, String? devType, String? sysType, String? ver, String? buildID, + String? mobile, + String? code, + String? devID, + String? devType, + String? sysType, + String? ver, + String? buildID, [String? cutInfos = ""]) async { final param = { 'mobile': mobile, @@ -172,34 +181,45 @@ class MineService { 'cutInfos': cutInfos }; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByPOST('/mine/mobileLoginOnly', - param: param, jsonTransformation: (json) => UserInfoModel.fromJson(json['userInfo'])); + final result = await httpManager.fetchResponseByPOST( + '/mine/mobileLoginOnly', + param: param, + jsonTransformation: (json) => UserInfoModel.fromJson(json['userInfo'])); return result.isSuccess ? result.data : null; } /// 积分兑换商品 - static Future integralExchange(String id, {String? name, String? tel, String? address}) async { - final param = {"id": id, "name": name, "tel": tel, "address": address}; + static Future integralExchange(String id, + {String? name, String? tel, String? address}) async { + final param = { + "id": id, + "name": name, + "tel": tel, + "address": address + }; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByPOST('/integral/exchangeIntegral', param: param); + final result = await httpManager + .fetchResponseByPOST('/integral/exchangeIntegral', param: param); return result.isSuccess; } //收藏类型 SP:长视频 SHORT:短视频 COVER:图文帖子 PIC:图集帖子 SEED_LINK:种子/黄油帖子 - static Future postCollect(String? objID, String? type, bool? isCollect) async { + static Future postCollect( + String? objID, String? type, bool? isCollect) async { final param = {'objID': objID, 'type': type, 'isCollect': isCollect}; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByPOST( '/mine/collect', param: param, ); - eventBus.emit(CollectStatusModel(id: objID, isCollected: isCollect, type: type)); + eventBus.emit( + CollectStatusModel(id: objID, isCollected: isCollect, type: type)); return result.isSuccess; } static Future fetchWalletData() async { - final result = - await httpManager.fetchResponseByGET('/mine/wallet', param: {}, jsonTransformation: (json) => WalletModel.fromJson(json)); + final result = await httpManager.fetchResponseByGET('/mine/wallet', + param: {}, jsonTransformation: (json) => WalletModel.fromJson(json)); if (result.data is WalletModel) { globalStore.wallet = result.data; } @@ -218,7 +238,8 @@ class MineService { } //推广记录 - static Future?> getBindRecord(int? pageSize, int? pageNumber) async { + static Future?> getBindRecord( + int? pageSize, int? pageNumber) async { final param = {'pageSize': pageSize, 'pageNumber': pageNumber}; final result = await httpManager.fetchResponseByPOST( '/userinvite/userlist', @@ -234,18 +255,22 @@ class MineService { // newsType: SEED_LINK 游戏, MOVIE 视频,抖音:SP,图文:COVER static Future fetchIncomeInfo() async { - final result = - await httpManager.fetchResponseByPOST('/userinvite/info', param: {}, jsonTransformation: (json) => UserIncomeModel.fromJson(json)); + final result = await httpManager.fetchResponseByPOST('/userinvite/info', + param: {}, + jsonTransformation: (json) => UserIncomeModel.fromJson(json)); return result.isSuccess ? result.data : null; } /// 获取用户分享列表 - static Future fetchIncomeList({int page = 1, int size = 10}) async { + static Future fetchIncomeList( + {int page = 1, int size = 10}) async { final param = {'pageSize': page, 'pageNumber': size}; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByPOST('/userinvite/incomelist', - param: param, jsonTransformation: (json) => InviteIncomeModel.fromJson(json)); + final result = await httpManager.fetchResponseByPOST( + '/userinvite/incomelist', + param: param, + jsonTransformation: (json) => InviteIncomeModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -294,7 +319,8 @@ class MineService { }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET('/mine/buyVid', - param: param, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + param: param, + jsonTransformation: (json) => ListBaseModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -312,8 +338,10 @@ class MineService { 'month': DateTime.now().month }; param.removeWhere((k, v) => v == null); - final result = - await httpManager.fetchResponseByGET('/mine/zhangdan', param: param, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + final result = await httpManager.fetchResponseByGET('/mine/zhangdan', + param: param, + jsonTransformation: (json) => + ListBaseModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -327,7 +355,8 @@ class MineService { 'pageSize': pageSize, }; final result = await httpManager.fetchResponseByPOST('/mine/transaction', - param: param, jsonTransformation: (json) => WithdrawDetailsModel.fromJson(json)); + param: param, + jsonTransformation: (json) => WithdrawDetailsModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -374,7 +403,8 @@ class MineService { static Future getChatRechargeTypes(int? type) async { final param = {'type': type}; final result = await httpManager.fetchResponseByGET('/mine/currencys', - param: param, jsonTransformation: (json) => RechargeListModel.fromJson(json)); + param: param, + jsonTransformation: (json) => RechargeListModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -418,7 +448,8 @@ class MineService { 'contentId': track?.contentId, 'checkoutContextId': track?.checkoutContextId, 'experimentId': (expId != null && expId.isNotEmpty) ? expId : null, - 'experimentVariant': (expVariant != null && expVariant.isNotEmpty) ? expVariant : null, + 'experimentVariant': + (expVariant != null && expVariant.isNotEmpty) ? expVariant : null, }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByPOST( @@ -457,7 +488,8 @@ class MineService { } //积分兑换记录 - static Future> getCreditRecords({int pageNumber = 1, int pageSize = 20}) async { + static Future> getCreditRecords( + {int pageNumber = 1, int pageSize = 20}) async { final param = {'pageNumber': pageNumber, 'pageSize': pageSize}; final result = await httpManager.fetchResponseByGET( '/integral/record/list', @@ -466,7 +498,8 @@ class MineService { final List list = []; if (result.isSuccess) { List? values = result.data as List?; - list.addAll(values?.map((e) => CreditRecordModel.fromJson(e)).toList() ?? []); + list.addAll( + values?.map((e) => CreditRecordModel.fromJson(e)).toList() ?? []); } return list; } @@ -484,7 +517,8 @@ class MineService { } /// VIP 卡片统计事件批量上报 - static Future reportAnalyticsEvents(List events) async { + static Future reportAnalyticsEvents( + List events) async { if (events.isEmpty) return true; final result = await httpManager.fetchResponseByPOST( '/analytics/events', @@ -504,7 +538,8 @@ class MineService { final List list = []; if (result.isSuccess) { List? values = result.data as List?; - list.addAll(values?.map((e) => IntegralExchangeModel.fromJson(e)).toList() ?? []); + list.addAll( + values?.map((e) => IntegralExchangeModel.fromJson(e)).toList() ?? []); } return list; } @@ -521,7 +556,8 @@ class MineService { final List list = []; if (result.isSuccess) { List? values = result.data as List?; - list.addAll(values?.map((e) => OfficialListItemModel.fromJson(e)).toList() ?? []); + list.addAll( + values?.map((e) => OfficialListItemModel.fromJson(e)).toList() ?? []); } return list; } @@ -571,7 +607,12 @@ class MineService { //绑定手机 static Future bindPhone(String phone, String code, - {String? devID, String? smsId, String? sysType, String? ver, String? devType, String? applicationID}) async { + {String? devID, + String? smsId, + String? sysType, + String? ver, + String? devType, + String? applicationID}) async { final param = { 'mobile': "+86$phone", 'code': code, @@ -591,7 +632,8 @@ class MineService { } //动态、收益列表 - static Future?> getDynamicList({int pageNumber = 1, int pageSize = 20, int? msgType}) async { + static Future?> getDynamicList( + {int pageNumber = 1, int pageSize = 20, int? msgType}) async { final param = { 'pageNumber': pageNumber, 'pageSize': pageSize, @@ -599,7 +641,9 @@ class MineService { }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET('/msg/dynamic/list', - param: param, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + param: param, + jsonTransformation: (json) => + ListBaseModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -614,7 +658,8 @@ class MineService { } /// 黑料社获取用户优惠券 - static Future> fetchUserCoupons(int type, {int page = 1, int size = 0}) async { + static Future> fetchUserCoupons(int type, + {int page = 1, int size = 0}) async { final param = { 'type': type, 'pageNumber': page, @@ -622,7 +667,12 @@ class MineService { }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET('/coupon/list', - param: param, jsonTransformation: (json) => (json['list'] as List?)?.map((e) => CouponModel.fromJson(e)).toList() ?? []); + param: param, + jsonTransformation: (json) => + (json['list'] as List?) + ?.map((e) => CouponModel.fromJson(e)) + .toList() ?? + []); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } @@ -639,7 +689,8 @@ class MineService { static Future getBankCards() async { final result = await httpManager.fetchResponseByGET('/mine/txnact/yh/get', - param: {}, jsonTransformation: (json) => ApBankListModel.fromJson(json)); + param: {}, + jsonTransformation: (json) => ApBankListModel.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -649,7 +700,12 @@ class MineService { String? bankCode, String? cardType, ) async { - final param = {'act': act, 'actName': actName, 'bankCode': bankCode, 'cardType': cardType}; + final param = { + 'act': act, + 'actName': actName, + 'bankCode': bankCode, + 'cardType': cardType + }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByPOST( '/mine/txnact/yh/add', @@ -659,7 +715,8 @@ class MineService { } //获取兑换码记录 - static Future getExchangeRecord(int pageNumber, int pageSize) async { + static Future getExchangeRecord( + int pageNumber, int pageSize) async { final result = await httpManager.fetchResponseByGET( '/code/userRecord', param: { @@ -725,10 +782,17 @@ class MineService { String? newsType, int? uid, }) async { - final param = {'pageNumber': page, 'pageSize': size, 'status': status, 'uid': uid, 'newsType': newsType}; + final param = { + 'pageNumber': page, + 'pageSize': size, + 'status': status, + 'uid': uid, + 'newsType': newsType + }; param.removeWhere((k, v) => v == null); final result = await httpManager.fetchResponseByGET('/mine/publish', - param: param, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + param: param, + jsonTransformation: (json) => ListBaseModel.fromJson(json)); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } @@ -737,7 +801,8 @@ class MineService { List? ids, }) async { final param = {'ids': ids}; - final result = await httpManager.fetchResponseByPOST('/mine/publish/delete', param: param); + final result = await httpManager.fetchResponseByPOST('/mine/publish/delete', + param: param); if (result.isSuccess) { return ''; } @@ -800,7 +865,8 @@ class MineService { final List list = []; if (result.isSuccess) { List? values = result.data as List?; - list.addAll(values?.map((e) => ExtraSignRewardItem.fromJson(e)).toList() ?? []); + list.addAll( + values?.map((e) => ExtraSignRewardItem.fromJson(e)).toList() ?? []); } return list; } diff --git a/lib/hj_utils/api_service/search_service.dart b/lib/hj_utils/api_service/search_service.dart index c194886..34b25e6 100644 --- a/lib/hj_utils/api_service/search_service.dart +++ b/lib/hj_utils/api_service/search_service.dart @@ -1,20 +1,25 @@ //搜索相关业务 -import 'package:hgmj/hj_model/home/video_list_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/home/video_list_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; class SearchService { /// 获取交友发布tag static Future> fetchPublishTags() async { - final result = await httpManager.fetchResponseByGET('/search/publisher/list', - param: {}, jsonTransformation: (json) => (json['list'] as List?)?.map((e) => TagsBean.fromMap(e)).toList() ?? []); + final result = await httpManager.fetchResponseByGET( + '/search/publisher/list', + param: {}, + jsonTransformation: (json) => + (json['list'] as List?)?.map((e) => TagsBean.fromMap(e)).toList() ?? + []); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } //猜你想要 type: 0v本周, 1本月,2上月 3.最多收藏 - static Future getHotVideos(int pageNumber, int pageSize, int sortType) async { + static Future getHotVideos( + int pageNumber, int pageSize, int sortType) async { final param = { "pageNumber": pageNumber, "pageSize": pageSize, diff --git a/lib/hj_utils/api_service/tag_service.dart b/lib/hj_utils/api_service/tag_service.dart index b6ebaf9..107dbce 100644 --- a/lib/hj_utils/api_service/tag_service.dart +++ b/lib/hj_utils/api_service/tag_service.dart @@ -1,19 +1,25 @@ -import 'package:hgmj/hj_model/home/video_list_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_model/home/video_list_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; class TagService { static Future fetchInfo(String? tagId) async { final param = {'tagID': tagId}; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByGET('/tag/info', param: param, jsonTransformation: (json) => TagsBean.fromMap(json)); + final result = await httpManager.fetchResponseByGET('/tag/info', + param: param, jsonTransformation: (json) => TagsBean.fromMap(json)); return result.isSuccess ? result.data : null; } /// 标签详情拉去视频数据 ///sortType 1、推荐,2、最新,3、最热 4、精华,5、视频 static Future fetchList(String? tagId, - {int? sortType, int page = 1, int size = 10, String? newsType, String? sortBy, int? videoType}) async { + {int? sortType, + int page = 1, + int size = 10, + String? newsType, + String? sortBy, + int? videoType}) async { final param = { 'pageNumber': page, 'pageSize': size, @@ -24,8 +30,9 @@ class TagService { 'videoType': videoType }; param.removeWhere((k, v) => v == null); - final result = - await httpManager.fetchResponseByGET('/tag/vid/list', param: param, jsonTransformation: (json) => VideoListResp.fromJson(json)); + final result = await httpManager.fetchResponseByGET('/tag/vid/list', + param: param, + jsonTransformation: (json) => VideoListResp.fromJson(json)); return result.isSuccess ? result.data : null; } } diff --git a/lib/hj_utils/api_service/vid_service.dart b/lib/hj_utils/api_service/vid_service.dart index 7ebab80..e098eaa 100644 --- a/lib/hj_utils/api_service/vid_service.dart +++ b/lib/hj_utils/api_service/vid_service.dart @@ -1,8 +1,8 @@ -import 'package:hgmj/hj_model/list_base_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/list_base_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../config/config.dart'; import '../../hj_model/home/video_library_model.dart'; @@ -18,8 +18,8 @@ class VidService { static Future fetchWatchCount({String? vid}) async { final param = {'vid': vid}; param.removeWhere((k, v) => v == null); - final result = - await httpManager.fetchResponseByGET('/vid/user/count', param: param, jsonTransformation: (json) => WatchCount.fromJson(json)); + final result = await httpManager.fetchResponseByGET('/vid/user/count', + param: param, jsonTransformation: (json) => WatchCount.fromJson(json)); return result.isSuccess ? result.data : null; } @@ -40,7 +40,8 @@ class VidService { 'via': via, 'tagID': tagID, }; - final result = await httpManager.fetchResponseByPOST('/vid/play', param: param); + final result = + await httpManager.fetchResponseByPOST('/vid/play', param: param); return result.isSuccess; } @@ -122,7 +123,8 @@ class VidService { 'bountyPoint': bountyPoint, }; param.removeWhere((k, v) => v == null); - final result = await httpManager.fetchResponseByPOST('/vid/submit', param: param); + final result = + await httpManager.fetchResponseByPOST('/vid/submit', param: param); if (!result.isSuccess) { showToast(result.toast); } @@ -133,7 +135,11 @@ class VidService { /// [moduleSort] 默认视频排序 1、最新,2、最热,3、最多播放量或者推荐,4、十分钟以上视频,5、精华,6、视频 9 最新热评 /// [showType]0 默认为hj static Future getModuleDetail(String? subModuleID, - {int? moduleSort, int pageNumber = 1, int pageSize = 10, int? showType, String? tagId}) async { + {int? moduleSort, + int pageNumber = 1, + int pageSize = 10, + int? showType, + String? tagId}) async { final param = { 'pageSize': pageSize, 'pageNumber': pageNumber, @@ -154,7 +160,9 @@ class VidService { /// 只回 allVideoInfo,不含专题/精选等结构,调用方别整个替换 dataSource /// [refreshToken] 每次用户主动下拉换新 UUID;同一 token 重取顺序不变,所以网络层自动重试是安全的 static Future refreshRandomModule(String? subModuleID, - {int? moduleSort, required String refreshToken, int pageSize = 30}) async { + {int? moduleSort, + required String refreshToken, + int pageSize = 30}) async { final param = { 'moduleSort': moduleSort, 'pageSize': pageSize, @@ -170,7 +178,8 @@ class VidService { } ///sortType 1:最新 2:本周热门 4:本月最热 5:年度最热 - static Future getNewestModule({int? sortType, int pageNumber = 1, int pageSize = 10}) async { + static Future getNewestModule( + {int? sortType, int pageNumber = 1, int pageSize = 10}) async { final param = { 'pageSize': pageSize, 'pageNumber': pageNumber, @@ -186,7 +195,8 @@ class VidService { } static Future getShopAddress() async { - final result = await httpManager.fetchResponseByGET('/ping/store_url', param: {}); + final result = + await httpManager.fetchResponseByGET('/ping/store_url', param: {}); return result.isSuccess ? result.data : null; } @@ -290,14 +300,18 @@ class VidService { /// 获取福利任务下面的视频 static Future?> fetchFreeSource() async { final result = await httpManager.fetchResponseByGET('/vid/discount/area', - param: {}, jsonTransformation: (json) => (json['List'] as List?)?.map((e) => WareDiscountAreaData.fromJson(e)).toList()); + param: {}, + jsonTransformation: (json) => (json['List'] as List?) + ?.map((e) => WareDiscountAreaData.fromJson(e)) + .toList()); return result.isSuccess ? result.data : null; } /// 获取免费福利视频数据 /// [sortType] 0 = 福利任务下面 1 最新 2最热 - static Future> fetchFreeSourceList(String id, {int page = 1, int size = 10, required int sortType}) async { + static Future> fetchFreeSourceList(String id, + {int page = 1, int size = 10, required int sortType}) async { final param = { 'pageNumber': page, 'pageSize': size, @@ -305,7 +319,8 @@ class VidService { 'sortType': sortType, }; final result = await httpManager.fetchResponseByGET('/vid/discount/list', - param: param, jsonTransformation: (json) => ListBaseModel.fromJson(json)); + param: param, + jsonTransformation: (json) => ListBaseModel.fromJson(json)); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } @@ -313,7 +328,8 @@ class VidService { /// 获取跑马灯数据 static Future?> fetchAnnounce(int type) async { final param = {"type": type}; - final result = await httpManager.fetchResponseByGET('/mine/announce/list', param: param); + final result = await httpManager.fetchResponseByGET('/mine/announce/list', + param: param); final List list = []; if (result.isSuccess) { @@ -368,15 +384,17 @@ class VidService { /// 获取片库筛选条件 static Future fetchLibrary() async { - final result = - await httpManager.fetchResponseByGET('/vid/library', param: {}, jsonTransformation: (json) => HomeVideoLibrary.fromJson(json)); + final result = await httpManager.fetchResponseByGET('/vid/library', + param: {}, + jsonTransformation: (json) => HomeVideoLibrary.fromJson(json)); //返回类型非空,给不了 null:失败时这里抛,由调用方 try/catch 兜底(改可空要连调用方一起改) return result.data; } ///视频专题样式-更换一批 static Future sectionVideoExchange(String? sectionID) async { - final result = await httpManager.fetchResponseByGET('/vid/section/changeVideo/$sectionID', param: {}); + final result = await httpManager + .fetchResponseByGET('/vid/section/changeVideo/$sectionID', param: {}); //失败时 data 是原始结构,别拿它当模型解析;fromJson 内部 json ??= {},传 null 就是空列表 return VideoListResp.fromJson(result.isSuccess ? result.data : null); } diff --git a/lib/hj_utils/codec_support.dart b/lib/hj_utils/codec_support.dart index 21ceec1..6ee19bb 100644 --- a/lib/hj_utils/codec_support.dart +++ b/lib/hj_utils/codec_support.dart @@ -1,6 +1,6 @@ import 'package:flutter/services.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/track_event_manager/device_service.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/track_event_manager/device_service.dart'; import 'light_model.dart'; @@ -34,7 +34,8 @@ class CodecSupport { static Future init() async { _deviceDisabled = await lightKV.getBool(StoreKeys.H265_DISABLED) ?? false; try { - _hwSupport = await _channel.invokeMethod('isH265HardwareSupported') ?? false; + _hwSupport = + await _channel.invokeMethod('isH265HardwareSupported') ?? false; } catch (e) { _hwSupport = false; } diff --git a/lib/hj_utils/date_time_util.dart b/lib/hj_utils/date_time_util.dart index d0db47d..89bb09c 100644 --- a/lib/hj_utils/date_time_util.dart +++ b/lib/hj_utils/date_time_util.dart @@ -1,10 +1,11 @@ -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; class DateTimeUtil { /// 计算当前时间差值 static int calTime3(String? date) { - if (TextUtil.isEmpty(date) || date?.contains("0001-01-01") == true) return -1; + if (TextUtil.isEmpty(date) || date?.contains("0001-01-01") == true) + return -1; final time = DateTime.parse(utc2iso(date)).toLocal(); return time.difference(DateTime.now()).inSeconds; } @@ -63,7 +64,8 @@ class DateTimeUtil { } /// utc 转 年月日 - static String utcTurnYear(String? date, {String? char, bool? isChina, bool showHM = false}) { + static String utcTurnYear(String? date, + {String? char, bool? isChina, bool showHM = false}) { if (date == null || date.isEmpty) return ''; final gap = char ?? '-'; final dt = DateTime.parse(date).toLocal(); @@ -106,7 +108,8 @@ class DateTimeUtil { } /// 时长 → MM:SS / HH:MM:SS(统一走 [formatHMS]) - static String? formatDuration(Duration position) => formatHMS(position.inSeconds); + static String? formatDuration(Duration position) => + formatHMS(position.inSeconds); /// 秒 → (时, 分, 秒) 各两位补零字符串;时为总小时数(不取模 24),供分段倒计时 UI 用 static (String, String, String) hms(int seconds) => ( @@ -165,7 +168,8 @@ bool _isSameDay(DateTime a, DateTime b) => a.year == b.year && a.month == b.month && a.day == b.day; /// 1 小时内 →「X分钟前」;当天 →「HH:mm」;其余 →「MM-DD HH:mm」;非正常时间 →「—」 -String formatTime(String? utcTime, {String gap = '-', bool hasTimeGap = false}) { +String formatTime(String? utcTime, + {String gap = '-', bool hasTimeGap = false}) { final date = _parseFormatTimeDate(utcTime); if (date == null) return kFormatTimeFallback; @@ -189,7 +193,8 @@ String formatTimeTwo(String? utcTime) { if (utcTime?.isNotEmpty != true) return '近期'; final now = DateTime.now(); final date = DateTime.parse(utcTime!).toLocal(); - final changeTime = (now.millisecondsSinceEpoch - date.millisecondsSinceEpoch) ~/ 1000; + final changeTime = + (now.millisecondsSinceEpoch - date.millisecondsSinceEpoch) ~/ 1000; final s = changeTime; if (s >= 0 && s < 60) return '刚刚'; @@ -207,6 +212,7 @@ String formatTimeTwo(String? utcTime) { if (month > 0 && month < 12) return DateTimeUtil.utc2isoMD(utcTime); final year = month ~/ 12; - if (year > 0 && year < 12) return DateTimeUtil.utcTurnYear(utcTime, isChina: true); + if (year > 0 && year < 12) + return DateTimeUtil.utcTurnYear(utcTime, isChina: true); return ''; } diff --git a/lib/hj_utils/detect_line_manager.dart b/lib/hj_utils/detect_line_manager.dart index 00453cb..bc1d38c 100644 --- a/lib/hj_utils/detect_line_manager.dart +++ b/lib/hj_utils/detect_line_manager.dart @@ -3,13 +3,13 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/dns_solve/dnsolve.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/dns_solve/dnsolve.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; //选线管理 class DetectLineManager { @@ -96,7 +96,8 @@ class DetectLineManager { ), cancelToken: cancelToken, ); - debugLog("ping", "pingCheck()...line:$line cost ${DateTime.now().difference(startTime).inMilliseconds} milSeconds"); + debugLog("ping", + "pingCheck()...line:$line cost ${DateTime.now().difference(startTime).inMilliseconds} milSeconds"); if (TextUtil.isNotEmpty(resp.time)) { httpManager.setServerTime(resp.time); } @@ -122,7 +123,11 @@ class DetectLineManager { if (record.data.isEmpty) continue; debugLog("selectLine", "dnsSolve ==== ${record.data}"); //DNS TXT 值带引号,去掉后按 _ 拆成多条线路 - final lines = record.data.split('_').map((e) => e.replaceAll("\"", "")).where(TextUtil.isNotEmpty).toList(); + final lines = record.data + .split('_') + .map((e) => e.replaceAll("\"", "")) + .where(TextUtil.isNotEmpty) + .toList(); if (lines.isEmpty) continue; // 这条记录没解析出线路,接着看下一条,别直接放弃 lightKV.setStringList(StoreKeys.DETECT_LINE, lines); return await _pingCheckBatch(lines); diff --git a/lib/hj_utils/file_util.dart b/lib/hj_utils/file_util.dart index fa6b1d7..2afae59 100644 --- a/lib/hj_utils/file_util.dart +++ b/lib/hj_utils/file_util.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'dart:typed_data'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; const KB_SIZE = 1024; const MB_SIZE = 1024 * KB_SIZE; @@ -34,7 +34,8 @@ class FileUtil { /// [offset] 起始偏移位置 /// [blockSize] 分块大小 /// [file] 文件 - static Future getFileBlock(int offset, int blockSize, File file) async { + static Future getFileBlock( + int offset, int blockSize, File file) async { RandomAccessFile? accessFile; try { accessFile = await file.open(); diff --git a/lib/hj_utils/free_play_manager.dart b/lib/hj_utils/free_play_manager.dart index 1ac9290..08db6f2 100644 --- a/lib/hj_utils/free_play_manager.dart +++ b/lib/hj_utils/free_play_manager.dart @@ -1,6 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/scheduler.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import '../hj_model/splash/watch_count_model.dart'; import '../hj_model/video_model.dart'; @@ -32,7 +32,8 @@ class FreePlayManager { /// 故这些阶段推迟到帧末再通知;空闲/帧末阶段则立即通知。 void _bumpRevision() { final phase = SchedulerBinding.instance.schedulerPhase; - final safeNow = phase == SchedulerPhase.idle || phase == SchedulerPhase.postFrameCallbacks; + final safeNow = phase == SchedulerPhase.idle || + phase == SchedulerPhase.postFrameCallbacks; if (safeNow) { revision.value++; return; @@ -49,7 +50,9 @@ class FreePlayManager { /// 合并去重而不是清空重填:两个 await 期间可能有视频正好扣了次数 add 进来,清掉会导致它被重复扣 Future refresh() async { remain = await VidService.fetchWatchCount(); - final saved = await lightKV.getStringList(StoreKeys.NEW_FREE_WATCH_VIDEOS) ?? const []; + final saved = + await lightKV.getStringList(StoreKeys.NEW_FREE_WATCH_VIDEOS) ?? + const []; usedIds.addAll(saved.where((e) => !usedIds.contains(e))); _bumpRevision(); } @@ -100,7 +103,8 @@ class FreePlayManager { // 后台上报,成功才落本地缓存;失败只记日志、不影响本次放行 // 注:上报是异步的,异常只能用 catchError 接(try-catch 包不住 then 里的异步错误) VidService.fetchWatchCount(vid: video.subid ?? id).then((value) { - if (value != null) lightKV.setStringList(StoreKeys.NEW_FREE_WATCH_VIDEOS, usedIds); + if (value != null) + lightKV.setStringList(StoreKeys.NEW_FREE_WATCH_VIDEOS, usedIds); }).catchError((Object e) => debugLog('免费次数上报失败', e)); return true; } diff --git a/lib/hj_utils/history_util.dart b/lib/hj_utils/history_util.dart index 7c39c19..0866ddf 100644 --- a/lib/hj_utils/history_util.dart +++ b/lib/hj_utils/history_util.dart @@ -1,19 +1,19 @@ import 'dart:convert'; -import 'package:hgmj/hj_model/home/collection_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/cache/history/base_history_record_store.dart'; -import 'package:hgmj/tools_base/cache/history/cartoon_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/comics_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/community_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/game_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/novel_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/pic_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/search_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/short_video_history_store.dart'; -import 'package:hgmj/tools_base/cache/history/video_history_store.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/home/collection_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/cache/history/base_history_record_store.dart'; +import 'package:wydj/tools_base/cache/history/cartoon_history_store.dart'; +import 'package:wydj/tools_base/cache/history/comics_history_store.dart'; +import 'package:wydj/tools_base/cache/history/community_history_store.dart'; +import 'package:wydj/tools_base/cache/history/game_history_store.dart'; +import 'package:wydj/tools_base/cache/history/novel_history_store.dart'; +import 'package:wydj/tools_base/cache/history/pic_history_store.dart'; +import 'package:wydj/tools_base/cache/history/search_history_store.dart'; +import 'package:wydj/tools_base/cache/history/short_video_history_store.dart'; +import 'package:wydj/tools_base/cache/history/video_history_store.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import '../hj_model/cartoon_media_info.dart'; @@ -74,7 +74,8 @@ class HistoryUtil { } /// 指定类型的浏览历史(按时间倒序,分页)。解析不出的条目直接丢弃,不让一条脏数据废掉整页 - static Future> fetch(MediaStyle type, {int page = 1, int pageSize = 20}) async { + static Future> fetch(MediaStyle type, + {int page = 1, int pageSize = 20}) async { try { final store = _storeOf(type); if (store == null) return []; @@ -112,10 +113,12 @@ class HistoryUtil { } //搜索历史(按时间倒序) - static Future> searchHistories() => SearchHistoryStore().fetchAll(); + static Future> searchHistories() => + SearchHistoryStore().fetchAll(); //新增一条搜索历史(已存在则去重提到最前,超上限自动删最旧) - static Future addSearch(String keyword) => SearchHistoryStore().save(keyword); + static Future addSearch(String keyword) => + SearchHistoryStore().save(keyword); //清空搜索历史 static Future clearSearch() => SearchHistoryStore().clean(); diff --git a/lib/hj_utils/image_util.dart b/lib/hj_utils/image_util.dart index 26695ad..6e73bb6 100644 --- a/lib/hj_utils/image_util.dart +++ b/lib/hj_utils/image_util.dart @@ -10,8 +10,8 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_native_image/flutter_native_image.dart'; import 'package:image/image.dart' as img; import 'package:image_gallery_saver/image_gallery_saver.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:zxing2/qrcode.dart'; @@ -23,7 +23,8 @@ class ImageUtil { static Future decodeQr(String path) async { var decodePath = path; try { - final converted = await FlutterNativeImage.compressImage(path, percentage: 100, quality: 100); + final converted = await FlutterNativeImage.compressImage(path, + percentage: 100, quality: 100); decodePath = converted.path; } catch (_) { // 转换失败就拿原图碰运气(本就是 jpg/png 时不影响) @@ -39,7 +40,11 @@ class ImageUtil { final source = RGBLuminanceSource( image.width, image.height, - image.convert(numChannels: 4).getBytes(order: img.ChannelOrder.rgba).buffer.asInt32List(), + image + .convert(numChannels: 4) + .getBytes(order: img.ChannelOrder.rgba) + .buffer + .asInt32List(), ); final bitmap = BinaryBitmap(HybridBinarizer(source)); // tryHarder:相册照片有边框/轻微旋转/噪点,放开更费时但识别率更高 @@ -54,7 +59,8 @@ class ImageUtil { /// 注:boundary 必须完整渲染在屏幕内,被滚动容器裁剪会截不全甚至失败 static Future saveWidgetToAlbum(GlobalKey boundaryKey) async { await WidgetsBinding.instance.endOfFrame; - final boundary = boundaryKey.currentContext?.findRenderObject() as RenderRepaintBoundary?; + final boundary = boundaryKey.currentContext?.findRenderObject() + as RenderRepaintBoundary?; if (boundary == null) return false; Image? image; @@ -112,7 +118,8 @@ class ImageUtil { if (decoder == null) return null; decoder.startDecode(bytes); //只解头/块信息,不解像素,很便宜 final total = decoder.numFrames(); - debugLog('saveToAlbum', '${decoder.runtimeType} frames=$total size=${bytes.length}'); + debugLog('saveToAlbum', + '${decoder.runtimeType} frames=$total size=${bytes.length}'); if (total <= 1) return null; // 必须整体 decode:animated webp 的每帧只是个局部矩形,靠 dispose/blend 往画布上叠, @@ -133,11 +140,16 @@ class ImageUtil { var delay = 0; for (var i = 0; i < src.numFrames; i += step) { //frames[0] 就是 src 本身、挂着整条动画,copyResize 会连整条一起缩放,得先取单帧副本 - final f = i == 0 ? img.Image.from(src.frames[0], noAnimation: true) : src.frames[i]; + final f = i == 0 + ? img.Image.from(src.frames[0], noAnimation: true) + : src.frames[i]; //必须指定 average:copyResize 默认是 nearest,降采样直接丢像素,出来全是锯齿 final out = (f.width == outW && f.height == outH) ? f - : img.copyResize(f, width: outW, height: outH, interpolation: img.Interpolation.average); + : img.copyResize(f, + width: outW, + height: outH, + interpolation: img.Interpolation.average); sink.writeFromSync(out.getBytes(order: img.ChannelOrder.rgba)); if (delay == 0 && f.frameDuration > 0) delay = f.frameDuration; count++; @@ -145,9 +157,15 @@ class ImageUtil { sink.closeSync(); if (count < 2) return null; - debugLog('saveToAlbum', 'raw ${outW}x$outH frames=$count step=$step delay=$delay'); + debugLog('saveToAlbum', + 'raw ${outW}x$outH frames=$count step=$step delay=$delay'); //抽帧后帧间隔要乘上 step,整体播放速度才不变;源没写时长就兜 80ms - return {'w': outW, 'h': outH, 'n': count, 'delay': (delay > 0 ? delay : 80) * step}; + return { + 'w': outW, + 'h': outH, + 'n': count, + 'delay': (delay > 0 ? delay : 80) * step + }; } catch (e) { debugLog('saveToAlbum', 'decodeToRaw failed: $e'); return null; @@ -155,17 +173,20 @@ class ImageUtil { } /// RGBA 裸流 → H.264 mp4(x264 在 -gpl 变体里才有) - static Future _rawToMp4(String rawPath, Map meta) async { + static Future _rawToMp4( + String rawPath, Map meta) async { final outPath = rawPath.replaceFirst(RegExp(r'\.rgba$'), '.mp4'); final fps = (1000 / (meta['delay'] ?? 80)).clamp(1.0, 60.0); - final cmd = '-y -f rawvideo -pixel_format rgba -video_size ${meta['w']}x${meta['h']} ' + final cmd = + '-y -f rawvideo -pixel_format rgba -video_size ${meta['w']}x${meta['h']} ' '-framerate ${fps.toStringAsFixed(2)} -i "$rawPath" ' '-c:v libx264 -preset veryfast -crf 23 -pix_fmt yuv420p -movflags +faststart "$outPath"'; final out = File(outPath); try { final session = await FFmpegKit.execute(cmd); if (!ReturnCode.isSuccess(await session.getReturnCode())) { - debugLog('saveToAlbum', 'ffmpeg failed: ${await session.getAllLogsAsString()}'); + debugLog('saveToAlbum', + 'ffmpeg failed: ${await session.getAllLogsAsString()}'); return null; } return await out.readAsBytes(); @@ -196,10 +217,13 @@ class ImageUtil { // 而那条分支用 URL(string:) 解析,裸路径没 scheme 会被 PhotoKit 拒,得传 file:// 形式 final isVideo = ext == 'mp4'; final result = await ImageGallerySaver.saveFile( - (Platform.isIOS && !isVideo) ? Uri.file(file.path).toString() : file.path, + (Platform.isIOS && !isVideo) + ? Uri.file(file.path).toString() + : file.path, name: fileName, isReturnPathOfIOS: !isVideo, - ).timeout(const Duration(seconds: 20), onTimeout: () => null); //插件在拿不到 fullSizeImageURL 时不回调,兜底防卡死 + ).timeout(const Duration(seconds: 20), + onTimeout: () => null); //插件在拿不到 fullSizeImageURL 时不回调,兜底防卡死 return result is Map && result["isSuccess"] == true; } catch (e) { debugLog('saveRawToAlbum 写入相册失败', e); diff --git a/lib/hj_utils/light_model.dart b/lib/hj_utils/light_model.dart index 902613b..4ea0dd8 100644 --- a/lib/hj_utils/light_model.dart +++ b/lib/hj_utils/light_model.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/text_util.dart'; import 'package:mmkv/mmkv.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/hj_utils/local_server.dart b/lib/hj_utils/local_server.dart index 571a733..edb4ae7 100644 --- a/lib/hj_utils/local_server.dart +++ b/lib/hj_utils/local_server.dart @@ -4,10 +4,10 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:hgmj/extension/extensions.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/hj_utils/video_cache_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/extension/extensions.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/hj_utils/video_cache_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../tools_base/cache/cancel_token_manager.dart'; import '../tools_base/net/load_apk/dio_cli.dart'; @@ -61,7 +61,8 @@ class ReqFilter { final int? port; // null or 12345 final String pathPrefix; //m3u8 是api/app/vid/m3u8 final HeadersBuilder? headersBuilder; - ReqFilter(this.reg, this.schema, this.host, {this.port, this.pathPrefix = "", this.headersBuilder}) + ReqFilter(this.reg, this.schema, this.host, + {this.port, this.pathPrefix = "", this.headersBuilder}) : assert(TextUtil.isNotEmpty(reg)), assert(TextUtil.isNotEmpty(host)); @@ -192,7 +193,8 @@ class CacheServer { await stop(true); _server = await _bindAlways(); csPrint("_startInner()...begin listen:$serverPort"); - _server?.listen(_onRequest, onDone: _onServerDone, onError: _onServerError, cancelOnError: true); + _server?.listen(_onRequest, + onDone: _onServerDone, onError: _onServerError, cancelOnError: true); csPrint("_bind success, start listen address:$localServerUri"); _startCompleter?.complete(); @@ -230,7 +232,8 @@ class CacheServer { /// 请求转发过滤器 /// 根据文件后缀转发 /// [reg] 正则表达式fileExtension需要带上. ".m3u8" ".ts" - void addReqFilter(String reg, String forwardUrl, {bool force = false, String pathPrefix = "", HeadersBuilder? hb}) { + void addReqFilter(String reg, String forwardUrl, + {bool force = false, String pathPrefix = "", HeadersBuilder? hb}) { assert(reg.startsWith(".")); if (TextUtil.isEmpty(forwardUrl)) { showToast("CDN地址为空"); @@ -241,7 +244,8 @@ class CacheServer { return; } // 转发结构体 - final reqFilter = ReqFilter(reg, uri.scheme, uri.host, port: uri.port, pathPrefix: pathPrefix, headersBuilder: hb); + final reqFilter = ReqFilter(reg, uri.scheme, uri.host, + port: uri.port, pathPrefix: pathPrefix, headersBuilder: hb); if (force) { // 不同的转发域,对应的转发函数 _reqFilterMap[reg] = reqFilter; @@ -251,7 +255,8 @@ class CacheServer { } /// 添加外部系统拦截调用,对于localserver一般是ttl - void addCustomResponse(String path, CustomResponse response, {bool force = false}) { + void addCustomResponse(String path, CustomResponse response, + {bool force = false}) { if (force) { _customResponse[path] = response; } else { @@ -260,7 +265,8 @@ class CacheServer { } /// 获取localserver的信息 - Uri get localServerUri => Uri(scheme: "http", host: _server?.address.host, port: _server?.port); + Uri get localServerUri => + Uri(scheme: "http", host: _server?.address.host, port: _server?.port); /// localserver的请求拦截 void _onRequest(HttpRequest request) { @@ -331,7 +337,8 @@ class CacheServer { // 根据文件扩展名字获取请求过滤 final fileExtension = localReq.uri.path.substring(dot); - var reqFilter = _reqFilterMap[fileExtension] ?? _reqFilterMap[LOCAL_ALL_FILTER]; + var reqFilter = + _reqFilterMap[fileExtension] ?? _reqFilterMap[LOCAL_ALL_FILTER]; if (reqFilter == null) { //l.e(local_server_tag, "_handleGet path not find ${localReq.uri} reqFilter:$fileExtension"); localReq.response.statusCode = HttpStatus.badRequest; @@ -353,7 +360,8 @@ class CacheServer { scheme: reqFilter.schema, host: reqFilter.host, port: reqFilter.port, - queryParameters: fileExtension == LOCAL_TS_FILTER ? {} : queryParameters); + queryParameters: + fileExtension == LOCAL_TS_FILTER ? {} : queryParameters); var remoteUriStr = remoteUri.toString(); if (remoteUriStr.endsWith("?")) { remoteUri = Uri.parse(remoteUriStr.replaceAll("?", "")); @@ -471,7 +479,9 @@ class CacheServer { var cacheManager = _getCacheManager(remoteUri.toString()); var s = cacheManager - .getFileStream(remoteUri.toString(), headers: localReqHeaders, withProgress: fileExtension != LOCAL_M3U8_FILTER) + .getFileStream(remoteUri.toString(), + headers: localReqHeaders, + withProgress: fileExtension != LOCAL_M3U8_FILTER) .handleError( (e) { if (!isPreCache) { @@ -479,7 +489,9 @@ class CacheServer { } // TODO 是否需要处理 //l.e(local_server_tag, "getFileStream()...开始处理远端请求$remoteUri 错误"); - if (TextUtil.isNotEmpty(cacheKey) && cacheKey.contains(LOCAL_M3U8_FILTER) && !failedM3u8List.contains(cacheKey)) { + if (TextUtil.isNotEmpty(cacheKey) && + cacheKey.contains(LOCAL_M3U8_FILTER) && + !failedM3u8List.contains(cacheKey)) { //l.e(local_server_tag, "getFileStream()...添加到失败错误列表$cacheKey"); failedM3u8List.add(cacheKey); } @@ -513,10 +525,12 @@ class CacheServer { } /// 处理M3u8 - _handleM3u8(Uri remoteUri, HttpRequest localReq, Stream s, BaseCacheManager cacheManager) async { + _handleM3u8(Uri remoteUri, HttpRequest localReq, Stream s, + BaseCacheManager cacheManager) async { final sc = s.listen((f) { if (f is FileInfo) { - var len = localReq.response.headers.value(HttpHeaders.contentLengthHeader); + var len = + localReq.response.headers.value(HttpHeaders.contentLengthHeader); if (null != len) { // 避���文件30天过期之后重新请求再次发送 //l.e(local_server_tag, "handleM3u8()...$remoteUri already send resp to user now skip"); @@ -548,11 +562,14 @@ class CacheServer { // .add(HttpHeaders.contentLengthHeader, afterSize); // localReq.response.headers // .add(HttpHeaders.contentTypeHeader, "application/octet-stream"); - localReq.response.headers.add(HttpHeaders.contentLengthHeader, afterSize); - localReq.response.headers.add(HttpHeaders.contentTypeHeader, "application/octet-stream"); + localReq.response.headers + .add(HttpHeaders.contentLengthHeader, afterSize); + localReq.response.headers + .add(HttpHeaders.contentTypeHeader, "application/octet-stream"); // localReq.response.contentLength = source.length; localReq.response.add(source.codeUnits); - csPrint("handleM3u8()...本地请求$remoteUri 完成:sourceSize:$sourceSize afterSize:$afterSize"); + csPrint( + "handleM3u8()...本地请求$remoteUri 完成:sourceSize:$sourceSize afterSize:$afterSize"); localReq.response.close(); } else { //l.e(local_server_tag, "handleM3u8()...本地请求$remoteUri 完成但是���件不存在"); @@ -681,7 +698,11 @@ class CacheServer { } else { //这里替换local127.0.0.1 var localUrl = remoteUri - .replace(scheme: localServerUri.scheme, host: localServerUri.host, port: localServerUri.port, queryParameters: query) + .replace( + scheme: localServerUri.scheme, + host: localServerUri.host, + port: localServerUri.port, + queryParameters: query) .toString(); return localUrl; } @@ -707,7 +728,8 @@ class CacheServer { } var uri = Uri.parse(remotePath); //这里替换远程 - final remoteUri = uri.replace(scheme: reqFilter.schema, host: reqFilter.host, port: reqFilter.port); + final remoteUri = uri.replace( + scheme: reqFilter.schema, host: reqFilter.host, port: reqFilter.port); return remoteUri.toString(); } } diff --git a/lib/hj_utils/permission_util.dart b/lib/hj_utils/permission_util.dart index 8a37ac2..c27724c 100644 --- a/lib/hj_utils/permission_util.dart +++ b/lib/hj_utils/permission_util.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:hgmj/tools_base/widget/common_alert.dart'; +import 'package:wydj/tools_base/widget/common_alert.dart'; import '../tools_base/toast.dart'; @@ -15,13 +15,17 @@ class PermissionUtil { final androidInfo = await DeviceInfoPlugin().androidInfo; // 按 API 级别(sdkInt)判断:Android 13(API 33)起用照片权限,以下用存储权限。 // 不能用 version.release(营销版本号字符串,ROM 可能写成 "12L" 等致解析跑偏) - permission = androidInfo.version.sdkInt < 33 ? Permission.storage : Permission.photos; + permission = androidInfo.version.sdkInt < 33 + ? Permission.storage + : Permission.photos; } return _ensure(permission, '需要相册权限才能继续'); } static Future checkPhotoAddOnlyPermission() async { - final permission = (Platform.isIOS || Platform.isMacOS) ? Permission.photosAddOnly : Permission.storage; + final permission = (Platform.isIOS || Platform.isMacOS) + ? Permission.photosAddOnly + : Permission.storage; return _ensure(permission, '需要相册权限才能继续'); } @@ -39,7 +43,8 @@ class PermissionUtil { // 会误判成永久拒绝、不弹框直接去设置。所以 Android 一律先 request(), // 由系统决定弹框还是立即返回结果;iOS/macOS 的 status 可靠,永久拒绝/受限直接去设置。 // 前提:申请的权限必须已在 AndroidManifest 声明,否则 request() 会立即返回 denied 不弹框。 - if ((Platform.isIOS || Platform.isMacOS) && (status.isPermanentlyDenied || status.isRestricted)) { + if ((Platform.isIOS || Platform.isMacOS) && + (status.isPermanentlyDenied || status.isRestricted)) { _toSettings(); return false; } @@ -49,7 +54,8 @@ class PermissionUtil { /// 处理 request() 后的结果:授权放行;永久拒绝引导去设置;普通拒绝弹 toast, /// 下次仍会弹系统授权框,避免误报"已禁止权限" - static bool _handleStatus(PermissionStatus status, {String denyTip = '未授权,无法继续'}) { + static bool _handleStatus(PermissionStatus status, + {String denyTip = '未授权,无法继续'}) { if (status.isGranted || status.isLimited) return true; if (status.isPermanentlyDenied || status.isRestricted) { _toSettings(); diff --git a/lib/hj_utils/play_diagnose.dart b/lib/hj_utils/play_diagnose.dart index 391d8e5..5fbea8e 100644 --- a/lib/hj_utils/play_diagnose.dart +++ b/lib/hj_utils/play_diagnose.dart @@ -1,12 +1,12 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/services.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/track_event_manager/device_service.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/track_event_manager/device_service.dart'; /// 播放失败诊断(**测试包专用**)。 /// @@ -39,14 +39,19 @@ class PlayDiagnose { ..writeln('【$scene】${DateTime.now()}') ..writeln('视频: ${videoTitle ?? '-'} (id=${videoId ?? '-'})') ..writeln('地址: ${url ?? '-'}') - ..writeln('本次选流: ${isH265 == true ? 'H265' : 'H264'} 已回退264=${forceH264 ?? false}') + ..writeln( + '本次选流: ${isH265 == true ? 'H265' : 'H264'} 已回退264=${forceH264 ?? false}') ..writeln('--- 编解码 ---') - ..writeln('芯片硬解265=${CodecSupport.hwSupport} 本机已禁265=${CodecSupport.deviceDisabled} 最终用265=${CodecSupport.useH265}') - ..writeln('渲染方式=${needPlatformView ? 'platformView' : 'textureView'} 已持久化=$platformViewPersisted') + ..writeln( + '芯片硬解265=${CodecSupport.hwSupport} 本机已禁265=${CodecSupport.deviceDisabled} 最终用265=${CodecSupport.useH265}') + ..writeln( + '渲染方式=${needPlatformView ? 'platformView' : 'textureView'} 已持久化=$platformViewPersisted') ..writeln('判定为解码错误=${isDecoderError(error)}') ..writeln('--- 环境 ---') - ..writeln('机型: ${DeviceInfoService.brand} ${DeviceInfoService.model} 系统: ${DeviceInfoService.deviceOS} ${DeviceInfoService.systemVersion}') - ..writeln('版本: ${Config.innerVersion} 用户: ${globalStore.meInfo?.uid ?? '-'} 设备: ${DeviceInfoService.deviceId}') + ..writeln( + '机型: ${DeviceInfoService.brand} ${DeviceInfoService.model} 系统: ${DeviceInfoService.deviceOS} ${DeviceInfoService.systemVersion}') + ..writeln( + '版本: ${Config.innerVersion} 用户: ${globalStore.meInfo?.uid ?? '-'} 设备: ${DeviceInfoService.deviceId}') ..writeln('网络: $net 线路: ${httpManager.baseUrl}') ..writeln('--- 错误原文 ---') ..writeln('$error'); @@ -54,7 +59,8 @@ class PlayDiagnose { _records.add(buffer.toString()); if (_records.length > _maxRecords) _records.removeAt(0); - await Clipboard.setData(ClipboardData(text: _records.join('\n${'=' * 30}\n'))); + await Clipboard.setData( + ClipboardData(text: _records.join('\n${'=' * 30}\n'))); showToast('失败信息已复制(${_records.length}条)\n请粘贴发给客服'); } diff --git a/lib/hj_utils/store_keys.dart b/lib/hj_utils/store_keys.dart index 1a510c7..3b6919e 100644 --- a/lib/hj_utils/store_keys.dart +++ b/lib/hj_utils/store_keys.dart @@ -1,6 +1,6 @@ // ignore_for_file: constant_identifier_names -import 'package:hgmj/config/config.dart'; +import 'package:wydj/config/config.dart'; /// lightKV 本地存储 key 集中管理 class StoreKeys { @@ -61,7 +61,8 @@ class StoreKeys { static const String DRAMA_CACHE_LIST = 'AppPlayDramaCacheVideoListKey'; /// 短剧下载授权的幂等键表:contentId -> X-Request-ID - static const String DRAMA_DOWNLOAD_REQUEST_ID = 'AppDramaDownloadRequestIdKey'; + static const String DRAMA_DOWNLOAD_REQUEST_ID = + 'AppDramaDownloadRequestIdKey'; /// 免费观看视频列表 static const String NEW_FREE_WATCH_VIDEOS = 'new_free_watch_videos'; @@ -71,20 +72,24 @@ class StoreKeys { static const String TRACK_SESSION_SID = 'track_session_current_sid'; /// 最近一次事件时间戳 - static const String TRACK_SESSION_LAST_EVENT_TS = 'track_session_last_event_ts'; + static const String TRACK_SESSION_LAST_EVENT_TS = + 'track_session_last_event_ts'; /// 进入后台的时间戳 - static const String TRACK_SESSION_BACKGROUND_TS = 'track_session_background_ts'; + static const String TRACK_SESSION_BACKGROUND_TS = + 'track_session_background_ts'; // ===== 首页更新红点 ===== /// 「最新」Tab 最后查看的服务端更新时间(ISO8601) static const String HOME_LATEST_LAST_VIEW_AT = 'home_latest_last_view_at'; /// 「今日最新」最后查看的服务端更新时间(ISO8601) - static const String HOME_TODAY_LATEST_LAST_VIEW_AT = 'home_today_latest_last_view_at'; + static const String HOME_TODAY_LATEST_LAST_VIEW_AT = + 'home_today_latest_last_view_at'; /// 首页模块最后查看时间前缀,完整 key = 前缀 + uid + '_' + moduleId - static const String HOME_MODULE_LAST_VIEW_AT_PREFIX = 'home_module_last_view_at_'; + static const String HOME_MODULE_LAST_VIEW_AT_PREFIX = + 'home_module_last_view_at_'; // ===== 短剧引导气泡 ===== /// 已进过短剧 tab,「AI爽剧来袭」气泡永久不再出现 diff --git a/lib/hj_utils/video_view_type.dart b/lib/hj_utils/video_view_type.dart index 81c8382..d23aaf7 100644 --- a/lib/hj_utils/video_view_type.dart +++ b/lib/hj_utils/video_view_type.dart @@ -1,7 +1,7 @@ import 'dart:io'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; import 'package:video_player/video_player.dart'; /// 本机是否用 platformView 渲染(内存态,构造 controller 时同步读)。 @@ -22,7 +22,8 @@ bool _persisted = false; /// [confirmPlatformView] 落本地,之后该机所有视频与下次启动自动改用 platformView。 /// 健康机型永远 textureView,零影响。 Future initVideoViewType() async { - _needPlatformView = await lightKV.getBool(StoreKeys.NEED_PLATFORM_VIEW) ?? false; + _needPlatformView = + await lightKV.getBool(StoreKeys.NEED_PLATFORM_VIEW) ?? false; _persisted = _needPlatformView; // 本地已有 = 已确认,后续不再重复写 } @@ -77,7 +78,8 @@ bool isDecoderError(Object? error) { /// m3u8 的 ts 切片;iOS 的 AVPlayer 对 HLS 切片不可靠,需本地代理另解。 class PlayerFactory { /// 网络视频(m3u8/mp4)。 - static VideoPlayerController network(String? url, {VideoPlayerOptions? options}) { + static VideoPlayerController network(String? url, + {VideoPlayerOptions? options}) { return VideoPlayerController.networkUrl( Uri.parse(url ?? ''), viewType: resolveVideoViewType(), @@ -86,7 +88,8 @@ class PlayerFactory { } /// 本地缓存视频。 - static VideoPlayerController file(String? path, {VideoPlayerOptions? options}) { + static VideoPlayerController file(String? path, + {VideoPlayerOptions? options}) { return VideoPlayerController.file( File(path ?? ''), viewType: resolveVideoViewType(), diff --git a/lib/main.dart b/lib/main.dart index c9ef0fe..277aa2b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,21 +5,21 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:hgmj/hj_page/main_page/provider/bottom_bar_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/limit_time_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_page/splash/splash_page.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/hj_utils/video_view_type.dart'; -import 'package:hgmj/routers/router_map.dart'; +import 'package:wydj/hj_page/main_page/provider/bottom_bar_provider.dart'; +import 'package:wydj/hj_page/pre_sale/limit_time_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_page/splash/splash_page.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/hj_utils/video_view_type.dart'; +import 'package:wydj/routers/router_map.dart'; import 'package:visibility_detector/visibility_detector.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/headphone_monitor.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/video_download/video_download_manager.dart'; -import 'package:hgmj/track_event_manager/device_service.dart'; -import 'package:hgmj/track_event_manager/track_session.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/headphone_monitor.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/video_download/video_download_manager.dart'; +import 'package:wydj/track_event_manager/device_service.dart'; +import 'package:wydj/track_event_manager/track_session.dart'; // 只引 OKToast 挂载所需符号:oktoast 也导出同名 showToast,全量 import 会与自家 toast.dart 冲突 import 'package:oktoast/oktoast.dart' show OKToast, ToastPosition; import 'package:provider/provider.dart'; @@ -35,14 +35,16 @@ import 'hj_page/main_page/provider/msg_provider.dart'; import 'hj_page/mine/mine_vip/vip_product_manager.dart'; import 'hj_utils/light_model.dart'; -final RouteObserver> routeObserver = RouteObserver>(); +final RouteObserver> routeObserver = + RouteObserver>(); void main() async { runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); // 可见性回调默认攒 500ms 才发,短视频切 tab 会拖半秒才静音;压到 100ms(听不出延迟)。 // 不设 0:那样滚动中每帧都回调 - VisibilityDetectorController.instance.updateInterval = const Duration(milliseconds: 100); + VisibilityDetectorController.instance.updateInterval = + const Duration(milliseconds: 100); VideoDownloadManager.instance.init(); await lightKV.init(); //初始化本地存储(lightKV/MMKV),其余初始化都依赖它,必须最先 httpManager.initDefault(); @@ -53,7 +55,8 @@ void main() async { initVideoViewType(), //视频渲染方式:读本机持久化标记,决定 textureView/platformView CodecSupport.init(), //H.265 硬解能力:查芯片能力 + 读本机禁用标记,决定选 265 还是回落 264 ]); - await TrackSessionManager().onAppColdStart(); //初始化请求头 sid(依赖 DeviceInfoService) + await TrackSessionManager() + .onAppColdStart(); //初始化请求头 sid(依赖 DeviceInfoService) WidgetsBinding.instance.addObserver(_TrackLifecycleObserver()); PromoCountdown.reset(); //优惠倒计时(场景3/4):app 启动时设定一次起点,全局仅此一次,进程存活期间自然倒数、不重置 HeadphoneMonitor.instance.start(); //耳机/蓝牙断开、来电等自动暂停视频,防止音频外放泄露隐私 @@ -109,9 +112,12 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider.value(value: HomeBottomProvider()), ChangeNotifierProvider.value(value: DarkwebBottomProvider()), ChangeNotifierProvider.value(value: CommunityBottomProvider()), - ChangeNotifierProvider.value(value: MineMsgProvider()), //消息中心红点,新人倒计时 - ChangeNotifierProvider.value(value: HomeUpdateMarkerProvider()), //首页最新/今日最新红点 - ChangeNotifierProvider.value(value: vipProductManager), //会员卡列表统一数据源 + ChangeNotifierProvider.value( + value: MineMsgProvider()), //消息中心红点,新人倒计时 + ChangeNotifierProvider.value( + value: HomeUpdateMarkerProvider()), //首页最新/今日最新红点 + ChangeNotifierProvider.value( + value: vipProductManager), //会员卡列表统一数据源 ChangeNotifierProvider.value(value: LimitTimeProvider()), //限时活动 ], child: GetMaterialApp( @@ -159,7 +165,8 @@ class MyApp extends StatelessWidget { ), // 全局 BackButton 用 iOS 经典风格箭头(与项目历史 BaseAppBar 视觉一致) actionIconTheme: ActionIconThemeData( - backButtonIconBuilder: (context) => const Icon(Icons.arrow_back_ios), + backButtonIconBuilder: (context) => + const Icon(Icons.arrow_back_ios), ), ), builder: (context, child) => OKToast( @@ -167,7 +174,8 @@ class MyApp extends StatelessWidget { backgroundColor: Colors.black.withValues(alpha: .85), radius: 8, textStyle: const TextStyle(color: Colors.white, fontSize: 14), - textPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + textPadding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: child!, ), ), @@ -183,7 +191,9 @@ class _TrackLifecycleObserver extends WidgetsBindingObserver { @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); - if (state == AppLifecycleState.paused || state == AppLifecycleState.inactive || state == AppLifecycleState.detached) { + if (state == AppLifecycleState.paused || + state == AppLifecycleState.inactive || + state == AppLifecycleState.detached) { TrackSessionManager().onAppPause(); } else if (state == AppLifecycleState.resumed) { TrackSessionManager().onAppResume(); diff --git a/lib/routers/jump_router.dart b/lib/routers/jump_router.dart index 6a55c0d..28ef632 100644 --- a/lib/routers/jump_router.dart +++ b/lib/routers/jump_router.dart @@ -1,14 +1,14 @@ import 'package:get/get.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_page.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_page/user_center_page/user_center_page.dart'; -import 'package:hgmj/hj_page/video/video_page.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; -import 'package:hgmj/tools_base/headphone_monitor.dart'; -import 'package:hgmj/tools_base/loading/loading_helper.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_page.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_page/user_center_page/user_center_page.dart'; +import 'package:wydj/hj_page/video/video_page.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; +import 'package:wydj/tools_base/headphone_monitor.dart'; +import 'package:wydj/tools_base/loading/loading_helper.dart'; +import 'package:wydj/tools_base/toast.dart'; import 'package:url_launcher/url_launcher.dart'; import '../config/config.dart'; @@ -56,7 +56,8 @@ Future? pushToVideoPage({ // 2. SEED_LINK:跳 ACG 游戏详情 if (videoModel?.newsType == 'SEED_LINK') { - return Get.to(() => AcgGameDetailPage(id: videoModel?.id ?? ''), preventDuplicates: false); + return Get.to(() => AcgGameDetailPage(id: videoModel?.id ?? ''), + preventDuplicates: false); } // // 3. 短视频:playTime < 300 且非 0(此分支 videoModel 必非 null,playTime 取自它) @@ -93,14 +94,17 @@ void pushToCartoonPage(CartoonMediaInfo? info) { Get.to(NovelDetailPage(info?.id), preventDuplicates: false); return; case 'video': - pushToVideoPage(videoModel: VideoModel(id: info?.id, cover: info?.coverV), isCartoon: true); + pushToVideoPage( + videoModel: VideoModel(id: info?.id, cover: info?.coverV), + isCartoon: true); return; } } /// 解析 deeplink/h5 链接并执行跳转 /// [sourcePage] 链接落到会员/金币页时的下单来源(如首页浮窗),不传走 pushToWalletPage 的默认 -Future? pushToPageByLink(String? url, {Map? arguments, PaySourcePage? sourcePage}) async { +Future? pushToPageByLink(String? url, + {Map? arguments, PaySourcePage? sourcePage}) async { if (url?.isNotEmpty != true) return null; Uri? uri; @@ -124,7 +128,8 @@ Future? pushToPageByLink(String? url, {Map? arguments, PaySourc if (uri.queryParameters["inner"] == "1") { // InAppWebView 是 PlatformView,创建时会重建渲染 Surface;视频在播放(Texture持续产帧)会导致部分机型画面放大/闪烁,先暂停所有播放 HeadphoneMonitor.instance.pauseAll(); - return Get.to(H5Page(url: url!, showTitle: false, showClose: true), popGesture: true); + return Get.to(H5Page(url: url!, showTitle: false, showClose: true), + popGesture: true); } return launchUrlToWeb(url!); } @@ -133,7 +138,8 @@ Future? pushToPageByLink(String? url, {Map? arguments, PaySourc } /// 处理 yinseinner:// 内部 scheme 跳转 -Future? _handleYinseInnerLink(String host, Map arguments, [PaySourcePage? sourcePage]) async { +Future? _handleYinseInnerLink(String host, Map arguments, + [PaySourcePage? sourcePage]) async { switch (host) { case "submodule": // 亚模块分类 eventBus.emit(YinseinnerModel(routeName: "module", id: arguments["id"])); @@ -145,7 +151,8 @@ Future? _handleYinseInnerLink(String host, Map arguments, [PayS eventBus.emit(YinseinnerModel(routeName: "community_page")); return null; case "community_module": // 社区 - eventBus.emit(YinseinnerModel(routeName: "community_module", id: arguments["id"])); + eventBus.emit( + YinseinnerModel(routeName: "community_module", id: arguments["id"])); return null; case "vip_page": // 会员中心 return pushToWalletPage(vipId: arguments['id'], sourcePage: sourcePage); @@ -159,11 +166,14 @@ Future? _handleYinseInnerLink(String host, Map arguments, [PayS case "rankinglist": // 排行榜 return Get.to(RankMainPage(), preventDuplicates: false); case "postdetail": // 帖子详情 - return Get.to(() => PostDetailPage(argument: PostDetailPageArgument(id: arguments["id"]))); + return Get.to(() => PostDetailPage( + argument: PostDetailPageArgument(id: arguments["id"]))); case "video_page": // 长视频播放页 - return Get.to(() => VideoPage(model:VideoModel(id:arguments["id"])), preventDuplicates: false); + return Get.to(() => VideoPage(model: VideoModel(id: arguments["id"])), + preventDuplicates: false); case "taskhall": // 福利任务 - return Get.to(() => const WelfareHomePage(index: 1), preventDuplicates: false); + return Get.to(() => const WelfareHomePage(index: 1), + preventDuplicates: false); case "advancepage": // 预售 return Get.to(() => const PreSalePage()); case "live_streaming": // 直播 @@ -243,9 +253,12 @@ Future? pushToPersonCenter(dynamic id, {int? type}) { /// [sourcePage] 落地页下单时的来源。不传时各分支用各自的默认:会员页记会员中心 /// (绝大多数入口都是「跳进会员页再下单」),金币页记 UNKNOWN(没有专属枚举,别拿会员的顶上); /// 有独立来源的(H5 活动等)自己传 -Future pushToWalletPage({int? tabPosition, String? vipId, PaySourcePage? sourcePage}) async { +Future pushToWalletPage( + {int? tabPosition, String? vipId, PaySourcePage? sourcePage}) async { if (tabPosition == 1) { - return Get.to(MineChargeCoinPage(sourcePage: sourcePage ?? PaySourcePage.unknown), preventDuplicates: false); + return Get.to( + MineChargeCoinPage(sourcePage: sourcePage ?? PaySourcePage.unknown), + preventDuplicates: false); } return Get.to( MineChargeVipPage( diff --git a/lib/routers/router_map.dart b/lib/routers/router_map.dart index df1ac00..98e3731 100644 --- a/lib/routers/router_map.dart +++ b/lib/routers/router_map.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; import '../hj_page/mine/mine_setting/mine_password_logic.dart'; import '../hj_page/mine/mine_setting/mine_password_page.dart'; @@ -16,14 +16,18 @@ class AppRoutes { page: () => const SplashPage(), middlewares: [SplashPasswordMiddleware()], ), - GetPage(name: MinePasswordPage.routeName, page: () => const MinePasswordPage()), //设置锁屏密码 + GetPage( + name: MinePasswordPage.routeName, + page: () => const MinePasswordPage()), //设置锁屏密码 ]; } class SplashPasswordMiddleware extends GetMiddleware { @override RouteSettings? redirect(String? route) { - if (globalStore.password.isEmpty || globalStore.isUnlocked) return super.redirect(route); - return RouteSettings(name: MinePasswordPage.routeName, arguments: MinePasswordType.check); + if (globalStore.password.isEmpty || globalStore.isUnlocked) + return super.redirect(route); + return RouteSettings( + name: MinePasswordPage.routeName, arguments: MinePasswordType.check); } } diff --git a/lib/tools_base/ad_manager.dart b/lib/tools_base/ad_manager.dart index b7cddf4..697a553 100644 --- a/lib/tools_base/ad_manager.dart +++ b/lib/tools_base/ad_manager.dart @@ -1,13 +1,13 @@ import 'dart:convert'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/hj_model/home/module_detail_model.dart'; -import 'package:hgmj/hj_model/splash/ads_model.dart'; -import 'package:hgmj/hj_model/user/user_info_model.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/hj_model/home/module_detail_model.dart'; +import 'package:wydj/hj_model/splash/ads_model.dart'; +import 'package:wydj/hj_model/user/user_info_model.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/hj_utils/text_util.dart'; import 'package:path/path.dart' as path; /// 广告总管:广告数据(内存+本地缓存)、免广告策略、列表插广告 @@ -29,12 +29,14 @@ class AdManager { } /// 按 [position] 同步取广告,走内存缓存 - List adsByType(int? position) => _filterByPosition(_adsList, position); + List adsByType(int? position) => + _filterByPosition(_adsList, position); /// 按 [position] 异步取上次展示的广告,直接读磁盘(不走/不写内存缓存,splash 启动早期用) Future> lastAdsByType(int? position) async { if (position == null) return const []; - return _filterByPosition(_decodeAds(await lightKV.getString(StoreKeys.ADS_LIST)), position); + return _filterByPosition( + _decodeAds(await lightKV.getString(StoreKeys.ADS_LIST)), position); } /// 保存服务端下发的广告:cover 补全成完整地址后刷内存、写磁盘 @@ -42,7 +44,9 @@ class AdManager { for (final model in ads ?? const []) { final cover = model.cover; // 完整链接只取 path 拼当前图片域名,相对路径直接拼 - final subPath = cover?.startsWith('http') == true ? Uri.tryParse(cover!)?.path : cover; + final subPath = cover?.startsWith('http') == true + ? Uri.tryParse(cover!)?.path + : cover; model.cover = path.join(Address.baseImagePath ?? '', subPath); } _adsList = ads; @@ -58,7 +62,9 @@ class AdManager { List? _decodeAds(String? jsonStr) { if (TextUtil.isEmpty(jsonStr)) return null; try { - return (jsonDecode(jsonStr!) as List?)?.map((o) => AdsInfoModel.fromMap(o)).toList(); + return (jsonDecode(jsonStr!) as List?) + ?.map((o) => AdsInfoModel.fromMap(o)) + .toList(); } catch (_) { return null; } @@ -91,14 +97,17 @@ class AdManager { // 注册时刻起算 type 分钟:注册时间是固定的绝对时刻,重进 app 既不会续期也不会丢剩余时长 // createdAt 是 UTC 串,缺时区标记时补 Z 再解析,否则会被当成本地时间差出时区偏移 final raw = userInfo?.createdAt ?? ''; - final registeredAt = DateTime.tryParse(raw.endsWith('Z') || raw.contains('+') ? raw : '${raw}Z')?.toLocal(); + final registeredAt = DateTime.tryParse( + raw.endsWith('Z') || raw.contains('+') ? raw : '${raw}Z') + ?.toLocal(); _adFreeUntil = registeredAt?.add(Duration(minutes: type)); } } /// 专题列表插入广告:每隔 [adGap] 条普通内容插一条广告位 /// [modelArr] 原始列表(会被原地修改);[advList] 广告数据;[adGap] 间隔条数 - void insertSectionAds(List modelArr, List advList, {int adGap = 5}) { + void insertSectionAds(List modelArr, List advList, + {int adGap = 5}) { if (advList.isEmpty || modelArr.isEmpty || !showAbTestAd) return; int countGap = 0; // 距上一条广告已累计的普通内容数 modelArr.removeWhere((it) => it.isAdsArr()); // 先清掉旧广告,避免重复插入 @@ -127,7 +136,8 @@ class AdManager { } /// 视频流插入「单条随机广告」:每隔 [adGap] 条插一条,广告按 adIndex 轮播取用 - void insertRandomAds(List modelArr, List advList, {int adGap = 5}) { + void insertRandomAds(List modelArr, List advList, + {int adGap = 5}) { if (advList.isEmpty || modelArr.isEmpty || !showAbTestAd) return; int countGap = 0; // 距上一条广告已累计的普通内容数 int adIndex = 0; // 当前取到第几条广告,与 advList 取模实现轮播 @@ -158,7 +168,8 @@ class AdManager { } /// 视频流插入「整组广告」:每隔 [adGap] 条插一条,广告位携带整个 advList(与 [insertRandomAds] 的单条随机不同) - void insertGroupAds(List modelArr, List advList, {int adGap = 5}) { + void insertGroupAds(List modelArr, List advList, + {int adGap = 5}) { if (advList.isEmpty || modelArr.isEmpty || !showAbTestAd) return; int countGap = 0; // 距上一条广告已累计的普通内容数 modelArr.removeWhere((it) => it.isAdsArr()); // 先清掉旧广告 diff --git a/lib/tools_base/banner/ads_banner.dart b/lib/tools_base/banner/ads_banner.dart index ba00295..b9ac09b 100644 --- a/lib/tools_base/banner/ads_banner.dart +++ b/lib/tools_base/banner/ads_banner.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/card_swiper/src/swiper.dart'; -import 'package:hgmj/tools_base/widget/image_browser_page.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/card_swiper/src/swiper.dart'; +import 'package:wydj/tools_base/widget/image_browser_page.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; import '../../hj_model/splash/ads_model.dart'; import 'ads_item.dart'; @@ -73,7 +73,13 @@ class _AdsBannerState extends State { SizedBox(height: 256, child: _swiper()), 12.sizeBoxH, if (_count > 1) - Center(child: _indicator(space: 4, dotSize: 4, selectWidth: 8, color: widget.color, selectColor: widget.selectColor)), + Center( + child: _indicator( + space: 4, + dotSize: 4, + selectWidth: 8, + color: widget.color, + selectColor: widget.selectColor)), ], ), ); @@ -98,15 +104,22 @@ class _AdsBannerState extends State { dotSize: 2, selectWidth: 5, //视频广告 cell:主题黄(未选中半透明,选中实心) - color: widget.color ?? const Color(0xffFFD900).withValues(alpha: 0.4), - selectColor: widget.selectColor ?? const Color(0xffFFD900), + color: widget.color ?? + const Color(0xffFFD900).withValues(alpha: 0.4), + selectColor: + widget.selectColor ?? const Color(0xffFFD900), ), ), ) : Positioned( bottom: 7, right: 7, - child: _indicator(space: 4, dotSize: 4, selectWidth: 8, color: widget.color, selectColor: widget.selectColor), + child: _indicator( + space: 4, + dotSize: 4, + selectWidth: 8, + color: widget.color, + selectColor: widget.selectColor), ), ], ), @@ -189,8 +202,12 @@ class DotIndicator extends StatelessWidget { @override Widget build(BuildContext context) { final isBar = style == IndicatorStyle.bar; - final activeColor = selectColor ?? (isBar ? const Color(0xffE1351F) : Colors.white); - final inactiveColor = color ?? (isBar ? const Color(0xffE1351F).withValues(alpha: 0.3) : Colors.white.withValues(alpha: 0.5)); + final activeColor = + selectColor ?? (isBar ? const Color(0xffE1351F) : Colors.white); + final inactiveColor = color ?? + (isBar + ? const Color(0xffE1351F).withValues(alpha: 0.3) + : Colors.white.withValues(alpha: 0.5)); return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -248,7 +265,8 @@ class _ImageSwiperState extends State { loop: _count > 1, itemBuilder: (_, index) => InkWell( enableFeedback: false, - onTap: () => ImageBrowserPage.open(widget.imgs ?? [], index: index), + onTap: () => + ImageBrowserPage.open(widget.imgs ?? [], index: index), child: NetworkImageLoader(imageUrl: widget.imgs![index]), ), onIndexChanged: (index) => _index.value = index, @@ -260,7 +278,8 @@ class _ImageSwiperState extends State { right: 12, child: ValueListenableBuilder( valueListenable: _index, - builder: (_, index, __) => DotIndicator(count: _count, index: index, space: 6), + builder: (_, index, __) => + DotIndicator(count: _count, index: index, space: 6), ), ), ], @@ -303,8 +322,12 @@ class _AiBannerState extends State { final item = widget.models?[index]; //左:原图 右:AI 生成图 return Row(children: [ - Expanded(child: NetworkImageLoader(imageUrl: item?.cover ?? '', borderRadius: 0)), - Expanded(child: NetworkImageLoader(imageUrl: item?.newUrl ?? '', borderRadius: 0)), + Expanded( + child: NetworkImageLoader( + imageUrl: item?.cover ?? '', borderRadius: 0)), + Expanded( + child: NetworkImageLoader( + imageUrl: item?.newUrl ?? '', borderRadius: 0)), ]); }, onIndexChanged: (index) => _index.value = index, @@ -316,7 +339,8 @@ class _AiBannerState extends State { right: 10, child: ValueListenableBuilder( valueListenable: _index, - builder: (_, index, __) => DotIndicator(count: _count, index: index), + builder: (_, index, __) => + DotIndicator(count: _count, index: index), ), ), ], diff --git a/lib/tools_base/banner/ads_grid_view.dart b/lib/tools_base/banner/ads_grid_view.dart index c7e4fea..accbccd 100644 --- a/lib/tools_base/banner/ads_grid_view.dart +++ b/lib/tools_base/banner/ads_grid_view.dart @@ -2,8 +2,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_infinite_marquee/flutter_infinite_marquee.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; import '../../hj_model/splash/ads_model.dart'; import 'ads_banner.dart'; diff --git a/lib/tools_base/banner/ads_item.dart b/lib/tools_base/banner/ads_item.dart index 3a8dd0e..a6b959e 100644 --- a/lib/tools_base/banner/ads_item.dart +++ b/lib/tools_base/banner/ads_item.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/api_service/common_service.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/api_service/common_service.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../hj_model/splash/ads_model.dart'; import '../../routers/jump_router.dart'; @@ -70,7 +70,8 @@ class _AdsItemState extends State { width: Get.width, height: Get.height, fit: BoxFit.cover, - placeHolderWidget: Image.asset('ic_splash_bg.webp'.launchPath, fit: BoxFit.cover, width: Get.width, height: Get.height), + placeHolderWidget: Image.asset('ic_splash_bg.webp'.launchPath, + fit: BoxFit.cover, width: Get.width, height: Get.height), ); } @@ -80,7 +81,8 @@ class _AdsItemState extends State { children: [ AspectRatio( aspectRatio: widget.aspectRatio ?? 1, - child: NetworkImageLoader(imageUrl: adInfo.cover ?? '', borderRadius: 12), + child: NetworkImageLoader( + imageUrl: adInfo.cover ?? '', borderRadius: 12), ), const Spacer(), Text( @@ -111,7 +113,10 @@ class _AdsItemState extends State { 10.sizeBoxH, Text( adInfo.title ?? '', - style: const TextStyle(color: Color(0xffdddfdf), fontWeight: FontWeight.w300, fontSize: 12), + style: const TextStyle( + color: Color(0xffdddfdf), + fontWeight: FontWeight.w300, + fontSize: 12), ), ], ); @@ -125,7 +130,9 @@ class _AdsItemState extends State { fit: BoxFit.fill, ); final ratio = widget.aspectRatio; - return ratio == null ? image : AspectRatio(aspectRatio: ratio, child: image); + return ratio == null + ? image + : AspectRatio(aspectRatio: ratio, child: image); } //水平样式:左图 + 标题,右「立即下载」按钮 @@ -136,19 +143,30 @@ class _AdsItemState extends State { Row( children: [ //图片自己切 10 的圆角 - NetworkImageLoader(imageUrl: adInfo.cover ?? '', borderRadius: 10, width: 50, height: 50), + NetworkImageLoader( + imageUrl: adInfo.cover ?? '', + borderRadius: 10, + width: 50, + height: 50), 10.sizeBoxW, Text( adInfo.title ?? '', - style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w300, fontSize: 12), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w300, + fontSize: 12), ), ], ), Container( width: 72, height: 28, - decoration: BoxDecoration(color: const Color(0xff3476FF), borderRadius: BorderRadius.circular(14)), - child: const Center(child: Text('立即下载', style: TextStyle(color: Colors.white, fontSize: 12))), + decoration: BoxDecoration( + color: const Color(0xff3476FF), + borderRadius: BorderRadius.circular(14)), + child: const Center( + child: Text('立即下载', + style: TextStyle(color: Colors.white, fontSize: 12))), ), ], ); diff --git a/lib/tools_base/cache/cache_util.dart b/lib/tools_base/cache/cache_util.dart index 37b2cf2..4873b19 100644 --- a/lib/tools_base/cache/cache_util.dart +++ b/lib/tools_base/cache/cache_util.dart @@ -3,11 +3,12 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart' show DefaultCacheManager; +import 'package:flutter_cache_manager/flutter_cache_manager.dart' + show DefaultCacheManager; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; -import 'package:hgmj/tools_base/image/image_disk_cache.dart'; -import 'package:hgmj/tools_base/video_download/video_download_manager.dart'; +import 'package:wydj/tools_base/image/image_disk_cache.dart'; +import 'package:wydj/tools_base/video_download/video_download_manager.dart'; import '../../hj_utils/file_util.dart'; import '../../hj_utils/video_cache_manager.dart'; @@ -16,11 +17,13 @@ import 'image_cache_manager.dart'; ///加载缓存 统计缓存大小 Future loadCache() async { double total = 0; - Directory videoCacheDir = Directory(await VideoCacheManager().getFilePath() ?? ''); + Directory videoCacheDir = + Directory(await VideoCacheManager().getFilePath() ?? ''); if (await videoCacheDir.exists()) { total += await _getTotalSizeOfFilesInDir(videoCacheDir); } - Directory videoLoadedDir = Directory(await VideoDownloadManager.instance.cacheDir()); + Directory videoLoadedDir = + Directory(await VideoDownloadManager.instance.cacheDir()); if (await videoLoadedDir.exists()) { total += await _getTotalSizeOfFilesInDir(videoLoadedDir); } @@ -61,7 +64,8 @@ Future _getTotalSizeOfFilesInDir(final FileSystemEntity file) async { double total = 0; // recursive 已一次性列出所有后代文件,只累加 File 即可;不再对子目录二次递归, // 避免同一文件被重复计入导致缓存大小翻倍。异步 list 替代 listSync,避免大目录阻塞 UI。 - await for (final child in file.list(recursive: true, followLinks: false)) { + await for (final child + in file.list(recursive: true, followLinks: false)) { if (child is File) { total += (await child.length()).toDouble(); } @@ -95,10 +99,12 @@ Future clearCacheIfNeed({bool force = false, bool isHandle = false}) async { //await VideoDownloadManager.instance.emptyCache(); // await ImageDiskCache.emptyCache(); } - debugPrint(" ------------------ VideoCacheManager ImageCacheManager clear completely"); + debugPrint( + " ------------------ VideoCacheManager ImageCacheManager clear completely"); } else { double total = 0; - Directory videoCacheDir = Directory(await VideoCacheManager().getFilePath() ?? ''); + Directory videoCacheDir = + Directory(await VideoCacheManager().getFilePath() ?? ''); if (await videoCacheDir.exists()) { total += await _getTotalSizeOfFilesInDir(videoCacheDir); } @@ -107,7 +113,8 @@ Future clearCacheIfNeed({bool force = false, bool isHandle = false}) async { await VideoCacheManager().emptyCache(); } total = 0; - Directory imageCacheDir = Directory(await ImageCacheManager().getFilePath()); + Directory imageCacheDir = + Directory(await ImageCacheManager().getFilePath()); if (await imageCacheDir.exists()) { total += await _getTotalSizeOfFilesInDir(imageCacheDir); } @@ -124,7 +131,8 @@ clearAllCache(bool isHandle) async { PaintingBinding.instance.imageCache.clear(); PaintingBinding.instance.imageCache.clearLiveImages(); - debugPrint(" ----------- PaintingBinding.instance.imageCache.clearLiveImages()"); + debugPrint( + " ----------- PaintingBinding.instance.imageCache.clearLiveImages()"); } ///递归方式删除目录 diff --git a/lib/tools_base/cache/dio_file_service.dart b/lib/tools_base/cache/dio_file_service.dart index 883bc3a..9ece318 100644 --- a/lib/tools_base/cache/dio_file_service.dart +++ b/lib/tools_base/cache/dio_file_service.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:http/http.dart' hide Response; import '../../extension/extensions.dart'; @@ -16,7 +16,8 @@ class DioFileService extends FileService { final _dio = createDio(); @override - Future get(String url, {Map? headers = const {}}) async { + Future get(String url, + {Map? headers = const {}}) async { // cancelToken 用文件名注册、下载结束后按同一 key 移除 //(原来 createToken 用 name 而 remove 用 url,key 不一致:既移不掉导致泄漏,又会 firstWhere 抛 StateError) final name = FileUtil.getName(url); @@ -35,7 +36,8 @@ class DioFileService extends FileService { Response? resp; try { debugLog("DioFileService get: $url"); - resp = await _dio.get(url, cancelToken: token, options: options); + resp = await _dio.get(url, + cancelToken: token, options: options); } catch (e) { debugLog("DioFileService get error: $url -> $e"); } finally { @@ -53,9 +55,11 @@ class DioFileService extends FileService { if (values.notEmpty()) respHeaders[key] = values.first; }); // Content-Length 可能缺失/非数字,安全解析(原 contentLengthS[0] 在空串时会 RangeError);缺失传 null 表示长度未知 - final contentLength = int.tryParse(respHeaders[Headers.contentLengthHeader] ?? ''); + final contentLength = + int.tryParse(respHeaders[Headers.contentLengthHeader] ?? ''); - debugLog("DioFileService resp($statusCode): $url contentLength:$contentLength"); + debugLog( + "DioFileService resp($statusCode): $url contentLength:$contentLength"); return HttpGetResponse(StreamedResponse( resp.data!.stream, diff --git a/lib/tools_base/cache/history/drama_resume_store.dart b/lib/tools_base/cache/history/drama_resume_store.dart index b53c5d2..58efa87 100644 --- a/lib/tools_base/cache/history/drama_resume_store.dart +++ b/lib/tools_base/cache/history/drama_resume_store.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/drama_media_info.dart'; -import 'package:hgmj/tools_base/cache/history/base_history_record_store.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/drama_media_info.dart'; +import 'package:wydj/tools_base/cache/history/base_history_record_store.dart'; +import 'package:wydj/tools_base/debug_log.dart'; /// 短剧观看记录:纯本地,不依赖后端。一部剧一行(看到哪一集、第几秒 + 剧信息快照), /// 最多留 [BaseHistoryRecordStore.maxRows] 条,超了先淘汰最久没看的那部。 @@ -114,7 +114,8 @@ class DramaResumeStore extends BaseHistoryRecordStore { record( mediaId: mediaId, //空 contentId 会被 record 挡掉,那样这次刷新就白记了,退回当前这一集 - contentId: last?.contentId.isNotEmpty == true ? last!.contentId : contentId, + contentId: + last?.contentId.isNotEmpty == true ? last!.contentId : contentId, seconds: last?.progressSeconds ?? 0, drama: drama ?? last?.drama, ); @@ -130,7 +131,10 @@ class DramaResumeStore extends BaseHistoryRecordStore { }) { //空串和 null 一样要挡:contentId 为空的记录谁都匹配不上, //却会把这部剧上一条好记录顶掉,还会让 _resumeIndex 白翻完整部剧的分页 - if (mediaId == null || mediaId.isEmpty || contentId == null || contentId.isEmpty) return; + if (mediaId == null || + mediaId.isEmpty || + contentId == null || + contentId.isEmpty) return; final item = DramaResume( mediaId: mediaId, contentId: contentId, @@ -141,7 +145,8 @@ class DramaResumeStore extends BaseHistoryRecordStore { _put(mediaId, item); //不等落盘:主键冲突走 REPLACE,顺带把 create_time 刷成本次时间,超量时最久没看的先淘汰。 //必须接住异常,否则 db 出错会变成没人管的 async error - save(modelId: mediaId, modelDataJson: jsonEncode(item.toJson())).catchError((e) { + save(modelId: mediaId, modelDataJson: jsonEncode(item.toJson())) + .catchError((e) { debugLog('短剧续播记录写入失败', e.toString()); return false; }); diff --git a/lib/tools_base/file_upload/file_upload_tool.dart b/lib/tools_base/file_upload/file_upload_tool.dart index a9cb337..4a2a775 100644 --- a/lib/tools_base/file_upload/file_upload_tool.dart +++ b/lib/tools_base/file_upload/file_upload_tool.dart @@ -6,7 +6,7 @@ import 'dart:typed_data'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import '../../config/address.dart'; import '../../hj_utils/file_util.dart'; @@ -34,9 +34,11 @@ class FileUploadTool { // ==================== 图片上传 ==================== /// 上传单张图片(读本地文件 → 压缩 → 上传),本地文件读不到时返回 null - Future uploadImage(String path, {Function(int, int)? callback}) async { + Future uploadImage(String path, + {Function(int, int)? callback}) async { final ext = FileUtil.getNameSuffix(path); - final fileName = '${DateTime.now().toIso8601String()}_${Random().nextInt(1024)}.$ext'; + final fileName = + '${DateTime.now().toIso8601String()}_${Random().nextInt(1024)}.$ext'; Uint8List fileData; try { // 相册图被删/路径失效时 readAsBytes 会抛,统一转成 null 失败,别让异常穿到调用方 @@ -55,8 +57,10 @@ class FileUploadTool { String? fileName, Function(int, int)? callback, }) async { - final compressedData = await _compressImage(imageData, maxSize: maxImageSize); - final name = fileName ?? '${DateTime.now().toIso8601String()}_${Random().nextInt(1024)}.jpg'; + final compressedData = + await _compressImage(imageData, maxSize: maxImageSize); + final name = fileName ?? + '${DateTime.now().toIso8601String()}_${Random().nextInt(1024)}.jpg'; debugLog("开始上传----", name); final formData = FormData.fromMap({ @@ -142,10 +146,12 @@ class FileUploadTool { LoadingAlertWidget.show(title: "$title..."); try { results = await uploadImageList(paths, onProgress: (progress) { - LoadingAlertWidget.showExchangeTitle("$title${(progress * 100).toStringAsFixed(1)}%"); + LoadingAlertWidget.showExchangeTitle( + "$title${(progress * 100).toStringAsFixed(1)}%"); }); } catch (e) { - debugLog("uploadImagesWithProgress()...error:$e"); // 兜底:异常也要把 loading 关掉,别卡死转圈 + debugLog( + "uploadImagesWithProgress()...error:$e"); // 兜底:异常也要把 loading 关掉,别卡死转圈 } finally { LoadingAlertWidget.cancel(); } @@ -207,7 +213,9 @@ class FileUploadTool { final start = index * patchSize; final end = min(start + patchSize, fileBytes.length); // 正常 start 必 < fileBytes.length;越界(文件被截短)时取空块,不抛 RangeError - final blockData = start < end ? Uint8List.sublistView(fileBytes, start, end) : Uint8List(0); + final blockData = start < end + ? Uint8List.sublistView(fileBytes, start, end) + : Uint8List(0); final postData = { 'data': base64.encode(blockData), 'pos': index + 1, @@ -220,7 +228,8 @@ class FileUploadTool { for (int attempt = 0; attempt <= maxChunkRetry; attempt++) { if (failed) return; // 其它 worker 已判定失败,无谓再传 if (attempt > 0) { - await Future.delayed(Duration(milliseconds: 500 * (1 << (attempt - 1)))); + await Future.delayed( + Duration(milliseconds: 500 * (1 << (attempt - 1)))); debugLog("uploadVideo() 第${index + 1}片 第$attempt 次重试"); } try { @@ -280,7 +289,8 @@ class FileUploadTool { }) async { LoadingAlertWidget.show(title: "$title..."); final result = await uploadVideo(localPath, onProgress: (progress) { - LoadingAlertWidget.showExchangeTitle("$title${(progress * 100).toStringAsFixed(1)}%"); + LoadingAlertWidget.showExchangeTitle( + "$title${(progress * 100).toStringAsFixed(1)}%"); }); LoadingAlertWidget.cancel(); @@ -314,8 +324,10 @@ class FileUploadTool { /// 压缩图片:长边限到 maxImageEdge 保清晰,从高质量起逐档降(每次都从原图重压,避免二次劣化), /// 直到体积 ≤ maxSize 或触及质量下限 minCompressQuality(保清晰优先,不无脑压糊)。统一转 JPEG。 - Future _compressImage(Uint8List bytes, {required int maxSize}) async { - Future compress(int quality) => FlutterImageCompress.compressWithList( + Future _compressImage(Uint8List bytes, + {required int maxSize}) async { + Future compress(int quality) => + FlutterImageCompress.compressWithList( bytes, minWidth: maxImageEdge, minHeight: maxImageEdge, @@ -329,7 +341,8 @@ class FileUploadTool { quality -= 15; // 90 → 75 → 60 result = await compress(quality); } - debugLog("图片压缩 ${bytes.length ~/ 1024}KB → ${result.length ~/ 1024}KB (q$quality)"); + debugLog( + "图片压缩 ${bytes.length ~/ 1024}KB → ${result.length ~/ 1024}KB (q$quality)"); return result; } } diff --git a/lib/tools_base/global_store/store.dart b/lib/tools_base/global_store/store.dart index 9da3b00..560dcc5 100644 --- a/lib/tools_base/global_store/store.dart +++ b/lib/tools_base/global_store/store.dart @@ -2,12 +2,12 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/tools_base/ad_manager.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/tools_base/ad_manager.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../config/config.dart'; import '../../hj_model/user/user_info_model.dart'; @@ -55,7 +55,8 @@ class GlobalStore extends ChangeNotifier { /// 设置锁屏密码 Future setLockPassword(List input) async { - final res = await lightKV.setString(StoreKeys.PASSWORD_LOCK, json.encode(input)); + final res = + await lightKV.setString(StoreKeys.PASSWORD_LOCK, json.encode(input)); if (res == true) { showToast('设置密码成功'); //落盘写的是 input(覆盖),内存也得覆盖;addAll 会把旧密码留在前面,与落盘的对不上 @@ -74,7 +75,8 @@ class GlobalStore extends ChangeNotifier { showToast('密码验证失败,请重新输入~'); return false; } - final res = await lightKV.setString(StoreKeys.PASSWORD_LOCK, json.encode([])); + final res = + await lightKV.setString(StoreKeys.PASSWORD_LOCK, json.encode([])); if (res == true) { showToast('取消锁屏密码成功'); password.clear(); @@ -145,7 +147,8 @@ class GlobalStore extends ChangeNotifier { /// 二维码登录 /// [refresh] 是否刷新关联 globalStore 状态的页面,==false 则仅发起网络请求 - Future loginByQr(String qr, {String paste = "", bool refresh = true}) async { + Future loginByQr(String qr, + {String paste = "", bool refresh = true}) async { //1.存下当前 token,扫码失败要还原 final token = await netManager.getToken(); //2.设置 token 为空,否则获取的二维码也是老账号 @@ -166,7 +169,8 @@ class GlobalStore extends ChangeNotifier { /// 设备登录 /// [refresh] 刷新所有 user 全局状态 - Future loginByDevice(String deviceId, {String paste = "", bool refresh = true}) async { + Future loginByDevice(String deviceId, + {String paste = "", bool refresh = true}) async { final userInfo = await MineService.devLogin( deviceId, "", @@ -182,7 +186,8 @@ class GlobalStore extends ChangeNotifier { /// 手机号登录 /// [refresh] 刷新所有 user 全局状态 - Future loginByMobile(String mobile, String code, {String paste = "", bool refresh = true}) async { + Future loginByMobile(String mobile, String code, + {String paste = "", bool refresh = true}) async { final userInfo = await MineService.mobileLogin( mobile, code, @@ -214,7 +219,8 @@ class GlobalStore extends ChangeNotifier { } /// 处理登录结果:写 token、按需刷新;失败时还原原 token - Future _onLogin(UserInfoModel? userInfo, String? oldToken, bool refresh) async { + Future _onLogin( + UserInfoModel? userInfo, String? oldToken, bool refresh) async { if (userInfo != null) { if (TextUtil.isNotEmpty(userInfo.token)) { await netManager.setToken(userInfo.token); @@ -233,7 +239,8 @@ class GlobalStore extends ChangeNotifier { /// 更新并获取用户信息;[map] 为空则仅拉取用户信息 /// [refresh] 刷新所有 user 全局状态(会触发 Consumer 包裹的 widget 重建) - Future updateUserInfo({Map? map, bool refresh = true}) async { + Future updateUserInfo( + {Map? map, bool refresh = true}) async { // 传了 map 才是更新,更新成功后再拉取最新信息 final isUpdate = (map?.keys.length ?? 0) > 0; if (isUpdate) { diff --git a/lib/tools_base/headphone_monitor.dart b/lib/tools_base/headphone_monitor.dart index b5ced89..5a885f9 100644 --- a/lib/tools_base/headphone_monitor.dart +++ b/lib/tools_base/headphone_monitor.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'package:audio_session/audio_session.dart'; -import 'package:hgmj/hj_page/short_video/view/video_player_base_logic.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/event_bus/event_bus_util.dart'; -import 'package:hgmj/tools_base/event_bus/events.dart'; +import 'package:wydj/hj_page/short_video/view/video_player_base_logic.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/event_bus/event_bus_util.dart'; +import 'package:wydj/tools_base/event_bus/events.dart'; /// 监听音频环境变化,自动暂停所有视频播放,防止音频通过手机外放泄露隐私: /// 1. 耳机 / 蓝牙断开(音频切回外放) @@ -40,7 +40,8 @@ class HeadphoneMonitor { }); // 兜底:部分机型(华为/荣耀等)蓝牙断开不发 becomingNoisy 广播,改用更底层的设备移除回调兜底 _deviceSub = session.devicesChangedEventStream.listen((event) { - final unplugged = event.devicesRemoved.any((d) => d.isOutput && _privateOutputTypes.contains(d.type)); + final unplugged = event.devicesRemoved + .any((d) => d.isOutput && _privateOutputTypes.contains(d.type)); if (unplugged) { debugLog('音频输出设备移除(蓝牙/耳机) → 自动暂停所有播放'); pauseAll(); diff --git a/lib/tools_base/loading/loading_center_widget.dart b/lib/tools_base/loading/loading_center_widget.dart index 8cca81b..ac5ae2c 100644 --- a/lib/tools_base/loading/loading_center_widget.dart +++ b/lib/tools_base/loading/loading_center_widget.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; int logicMultiCount = 0; @@ -12,11 +12,13 @@ class LoadingWidget extends StatelessWidget { final double? height; final double size; - const LoadingWidget({super.key, this.width = 40, this.height = 20, this.size = 40}); + const LoadingWidget( + {super.key, this.width = 40, this.height = 20, this.size = 40}); @override Widget build(BuildContext context) { - return LoadingAnimationWidget.horizontalRotatingDots(color: Colors.white, size: size); + return LoadingAnimationWidget.horizontalRotatingDots( + color: Colors.white, size: size); } } @@ -53,7 +55,8 @@ class CErrorWidget extends StatefulWidget { final String? errorMsg; final String? errorMsg2; final VoidCallback? retryOnTap; - const CErrorWidget({super.key, this.errorMsg = "什么也没有...", this.errorMsg2, this.retryOnTap}); + const CErrorWidget( + {super.key, this.errorMsg = "什么也没有...", this.errorMsg2, this.retryOnTap}); @override State createState() => _CErrorWidgetState(); @@ -90,7 +93,8 @@ class _CErrorWidgetState extends State { 4.sizeBoxH, Text( widget.errorMsg ?? '', - style: TextStyle(color: Colors.white.withValues(alpha: 0.6), fontSize: 12), + style: TextStyle( + color: Colors.white.withValues(alpha: 0.6), fontSize: 12), ), if (widget.retryOnTap != null) ...[ 4.sizeBoxH, diff --git a/lib/tools_base/loading/loading_helper.dart b/lib/tools_base/loading/loading_helper.dart index cba121e..8e1b0c0 100644 --- a/lib/tools_base/loading/loading_helper.dart +++ b/lib/tools_base/loading/loading_helper.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/loading/loading_center_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/loading/loading_center_widget.dart'; import '../../hj_utils/widget_util.dart'; @@ -20,7 +20,8 @@ class LoadingHelper { 4.sizeBoxH, Text( msg, - style: textStyle(16, AppColors.mainTextColor33, FontWeight.w500), + style: + textStyle(16, AppColors.mainTextColor33, FontWeight.w500), ), ] ], diff --git a/lib/tools_base/module_sort_manager.dart b/lib/tools_base/module_sort_manager.dart index 714ad7a..96fb1f1 100644 --- a/lib/tools_base/module_sort_manager.dart +++ b/lib/tools_base/module_sort_manager.dart @@ -1,8 +1,8 @@ import 'dart:convert'; -import 'package:hgmj/hj_model/home/plate_model.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/home/plate_model.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/tools_base/debug_log.dart'; /// 模块亚 tab 排序:合并本地自定义顺序与后端最新数据(后端为内容源,本地只定顺序) class ModuleSortManager { @@ -31,7 +31,7 @@ class ModuleSortManager { debugLog(e); } } - if(localTabs.isEmpty) return serverTabs; + if (localTabs.isEmpty) return serverTabs; // 2.后端装载成 {id: 最新 model} final serverMap = {}; for (final t in serverTabs) { diff --git a/lib/tools_base/net/http_manager.dart b/lib/tools_base/net/http_manager.dart index 84b5208..4031bc0 100644 --- a/lib/tools_base/net/http_manager.dart +++ b/lib/tools_base/net/http_manager.dart @@ -5,13 +5,13 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:crypto/crypto.dart'; import 'package:dio/dio.dart'; import 'package:dio/io.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/text_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/http_response_interceptor.dart'; -import 'package:hgmj/tools_base/net/net_code.dart'; -import 'package:hgmj/tools_base/net/net_manager.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/text_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/http_response_interceptor.dart'; +import 'package:wydj/tools_base/net/net_code.dart'; +import 'package:wydj/tools_base/net/net_manager.dart'; import 'package:uuid/uuid.dart'; import '../../track_event_manager/device_service.dart'; @@ -56,7 +56,8 @@ abstract class HttpManger { if (TextUtil.isNotEmpty(serverTimeS)) { _serverTime = DateTime.parse(serverTimeS!); _diffTimeInSeconds = DateTime.now().difference(_serverTime!).inSeconds; - debugLog("============>server diff from local in seconds:$_diffTimeInSeconds"); + debugLog( + "============>server diff from local in seconds:$_diffTimeInSeconds"); } } @@ -95,37 +96,50 @@ abstract class HttpManger { }) async { // 给默认值兜底:若 response 非 null 但 data 不是 Map/BaseRespBean(null/String/List), // 下面 resultData 不会被赋值,late 变量访问会抛 LateInitializationError - BaseRespBean resultData = BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); + BaseRespBean resultData = + BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); Response? response; try { - response = await dio.request(url, queryParameters: queryParameters, options: options, data: data, cancelToken: cancelToken); + response = await dio.request(url, + queryParameters: queryParameters, + options: options, + data: data, + cancelToken: cancelToken); } on DioException catch (e) { debugLog('DioException $e'); if (e.type == DioExceptionType.cancel) { - resultData = BaseRespBean(Code.LOCAL_CANCEL_REQUEST, msg: '请求已经取消~,请重试', data: null); + resultData = BaseRespBean(Code.LOCAL_CANCEL_REQUEST, + msg: '请求已经取消~,请重试', data: null); } else if (e.type == DioExceptionType.connectionTimeout || e.type == DioExceptionType.receiveTimeout || e.type == DioExceptionType.sendTimeout) { - resultData = BaseRespBean(Code.NETWORK_TIMEOUT, msg: '网络连接超时~', data: null); + resultData = + BaseRespBean(Code.NETWORK_TIMEOUT, msg: '网络连接超时~', data: null); } final connectivityResult = await Connectivity().checkConnectivity(); if (connectivityResult == ConnectivityResult.none) { //没有网络 - resultData = BaseRespBean(Code.LOCAL_NO_NETWORK, msg: '暂无网络,请检查网络设置', data: null); + resultData = BaseRespBean(Code.LOCAL_NO_NETWORK, + msg: '暂无网络,请检查网络设置', data: null); } else { - resultData = BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常,请重新试试~', data: null); + resultData = + BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常,请重新试试~', data: null); } } on SocketException catch (e) { - resultData = BaseRespBean(Code.NETWORK_TIMEOUT, msg: '网络连接超时~', data: null); + resultData = + BaseRespBean(Code.NETWORK_TIMEOUT, msg: '网络连接超时~', data: null); debugLog('SocketException $e'); } on HttpException catch (e) { - resultData = BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); + resultData = + BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); debugLog('HttpException $e'); } on FormatException catch (e) { debugLog('FormatException $e'); - resultData = BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); + resultData = + BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); } catch (e) { - resultData = BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); + resultData = + BaseRespBean(Code.NETWORK_ERROR, msg: '网络异常请稍后再试~', data: null); debugLog(e); } @@ -141,7 +155,8 @@ abstract class HttpManger { final data_ = resultData.data; if (data_ is Map) { try { - resultData.data = jsonTransformation.call(Map.from(data_)); + resultData.data = + jsonTransformation.call(Map.from(data_)); } catch (e) { print('jsonTransformation error $e'); resultData.data = null; @@ -178,14 +193,16 @@ abstract class HttpManger { var adapter = DefaultHttpClientAdapter(); adapter.onHttpClientCreate = (client) { - client.badCertificateCallback = (X509Certificate cert, String host, int port) => true; + client.badCertificateCallback = + (X509Certificate cert, String host, int port) => true; return client; }; dio.httpClientAdapter = adapter; } // 获取统一的请求头 - Future generateRequestOption(String apiUrl, {Options? options, required HttpMethod method}) async { + Future generateRequestOption(String apiUrl, + {Options? options, required HttpMethod method}) async { //调用方可以自带 options(比如 X-Request-ID 这种单接口的头),公共头往上加,method 一律以本次请求为准 options ??= Options(); options.method = method.method; @@ -203,7 +220,11 @@ abstract class HttpManger { options.headers?["api_version"] = "1.0.0"; options.headers?["device"] = Platform.operatingSystem; Uri? baseUri = Uri.tryParse(baseUrl); - Uri targetUri = Uri(scheme: baseUri?.scheme, host: baseUri?.host, port: baseUri?.port, path: baseUri!.path + apiUrl); + Uri targetUri = Uri( + scheme: baseUri?.scheme, + host: baseUri?.host, + port: baseUri?.port, + path: baseUri!.path + apiUrl); options.headers?["x-api-key"] = await _sign(targetUri.path); options.headers?["sid"] = TrackSessionManager().currentSid; options.headers?["DeviceModel"] = DeviceInfoService.model; @@ -226,15 +247,20 @@ abstract class HttpManger { var digest = sha1Encrypt.convert(bytes); return 'timestamp=$timestamp;sign=${digest.toString()};nonce=${signObj['nonce']}'; } - } class _HttpManagerImp extends HttpManger { @override Future fetchResponseByDELETE(String url, - {Map? param, Options? options, Function(Map json)? jsonTransformation}) async { - final reqOptions = await generateRequestOption(url, options: options, method: HttpMethod.delete); - return await _requestByUrl(url, options: reqOptions, data: param, jsonTransformation: jsonTransformation); + {Map? param, + Options? options, + Function(Map json)? jsonTransformation}) async { + final reqOptions = await generateRequestOption(url, + options: options, method: HttpMethod.delete); + return await _requestByUrl(url, + options: reqOptions, + data: param, + jsonTransformation: jsonTransformation); } @override @@ -244,8 +270,12 @@ class _HttpManagerImp extends HttpManger { Options? options, Function(Map json)? jsonTransformation, }) async { - final reqOptions = await generateRequestOption(url, options: options, method: HttpMethod.get); - return await _requestByUrl(url, options: reqOptions, queryParameters: param, jsonTransformation: jsonTransformation); + final reqOptions = await generateRequestOption(url, + options: options, method: HttpMethod.get); + return await _requestByUrl(url, + options: reqOptions, + queryParameters: param, + jsonTransformation: jsonTransformation); } @override @@ -255,18 +285,24 @@ class _HttpManagerImp extends HttpManger { Options? options, Function(Map json)? jsonTransformation, }) async { - final reqOptions = await generateRequestOption(url, options: options, method: HttpMethod.post); - return await _requestByUrl(url, options: reqOptions, data: param, jsonTransformation: jsonTransformation); + final reqOptions = await generateRequestOption(url, + options: options, method: HttpMethod.post); + return await _requestByUrl(url, + options: reqOptions, + data: param, + jsonTransformation: jsonTransformation); } - Future fetchDetectLineResponse(String url, {Options? options, CancelToken? cancelToken}) async { + Future fetchDetectLineResponse(String url, + {Options? options, CancelToken? cancelToken}) async { options ??= Options( method: HttpMethod.get.method, sendTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), headers: {}, ); - final result = await _requestByUrl(url, options: options, cancelToken: cancelToken); + final result = + await _requestByUrl(url, options: options, cancelToken: cancelToken); return result; } } diff --git a/lib/tools_base/net/http_resp_interceptor.dart b/lib/tools_base/net/http_resp_interceptor.dart index 2d942d2..621a051 100755 --- a/lib/tools_base/net/http_resp_interceptor.dart +++ b/lib/tools_base/net/http_resp_interceptor.dart @@ -3,8 +3,8 @@ import 'dart:convert'; import 'package:dio/dio.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../config/config.dart'; import '../../hj_utils/text_util.dart'; @@ -19,7 +19,8 @@ class HttpRespInterceptor { static Future handleResponse(Response response) async { if (response.statusCode != 200) { - return Future.error(ApiException(response.statusCode, "statusCode is not 200")); + return Future.error( + ApiException(response.statusCode, "statusCode is not 200")); } BaseRespBean? baseResp; if (response.data is Map) { @@ -27,7 +28,8 @@ class HttpRespInterceptor { } else if (response.data is String) { baseResp = BaseRespBean.fromJson(json.decode(response.data)); } else { - return Future.error(ApiException(Code.PARSE_DATE_ERROR, Lang.PARSE_DATE_ERROR)); + return Future.error( + ApiException(Code.PARSE_DATE_ERROR, Lang.PARSE_DATE_ERROR)); } int? code = baseResp.code; @@ -65,7 +67,9 @@ class HttpRespInterceptor { /// 展示提示 if (code != Code.SUCCESS) { - if (TextUtil.isEmpty(baseResp.msg) && TextUtil.isEmpty(baseResp.tip) && response.statusCode != 200) { + if (TextUtil.isEmpty(baseResp.msg) && + TextUtil.isEmpty(baseResp.tip) && + response.statusCode != 200) { showToast("服务器错误"); } else { if (!TextUtil.isEmpty(baseResp.tip)) { @@ -75,7 +79,8 @@ class HttpRespInterceptor { } } } - debugLog('path:${response.requestOptions.baseUrl}${response.requestOptions.path}'); + debugLog( + 'path:${response.requestOptions.baseUrl}${response.requestOptions.path}'); debugLog('param: ${response.requestOptions.queryParameters}'); debugLog('data: ${response.requestOptions.data}'); debugLog('head: ${response.requestOptions.headers}'); diff --git a/lib/tools_base/net/http_response_interceptor.dart b/lib/tools_base/net/http_response_interceptor.dart index bc53b0e..3c0ccb6 100644 --- a/lib/tools_base/net/http_response_interceptor.dart +++ b/lib/tools_base/net/http_response_interceptor.dart @@ -2,17 +2,17 @@ import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; -import 'package:hgmj/config/address.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/net/aes_util.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/curl_util.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; -import 'package:hgmj/tools_base/net/net_code.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/config/address.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/net/aes_util.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/curl_util.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/net/net_code.dart'; +import 'package:wydj/tools_base/toast.dart'; /// 统一处理网络响应:解析 BaseRespBean、按业务码分发、密文解密、错误提示 class HttpResponseInterceptor extends InterceptorsWrapper { @@ -25,7 +25,8 @@ class HttpResponseInterceptor extends InterceptorsWrapper { // curl/响应体仅 debug 下生成:generateCurl 会 json.encode 整个请求体、 // '$data' 会序列化整个响应,无条件求值在 release 也跑、纯属浪费 if (kDebugMode) { - debugLog('$tag curl ====== ${CurlUtil.generateCurl(response.requestOptions)}'); + debugLog( + '$tag curl ====== ${CurlUtil.generateCurl(response.requestOptions)}'); debugLog('==========response==========\n${response.data}'); } handleResponse(response); @@ -55,12 +56,14 @@ class HttpResponseInterceptor extends InterceptorsWrapper { try { baseResp = BaseRespBean.fromJson(json.decode(response.data)); } catch (e) { - baseResp = BaseRespBean(Code.PARSE_DATE_ERROR, msg: Lang.PARSE_DATE_ERROR); + baseResp = + BaseRespBean(Code.PARSE_DATE_ERROR, msg: Lang.PARSE_DATE_ERROR); } } else if (response.data is BaseRespBean) { baseResp = response.data; } else { - baseResp = BaseRespBean(Code.PARSE_DATE_ERROR, msg: Lang.PARSE_DATE_ERROR); + baseResp = + BaseRespBean(Code.PARSE_DATE_ERROR, msg: Lang.PARSE_DATE_ERROR); } // 同步下服务器时间 httpManager.setServerTime(baseResp.time); diff --git a/lib/tools_base/net/load_apk/dio_slice_downloader.dart b/lib/tools_base/net/load_apk/dio_slice_downloader.dart index 8791043..9b3e9c9 100644 --- a/lib/tools_base/net/load_apk/dio_slice_downloader.dart +++ b/lib/tools_base/net/load_apk/dio_slice_downloader.dart @@ -8,7 +8,7 @@ import 'dart:typed_data'; import 'package:convert/convert.dart'; import 'package:dio/dio.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:path/path.dart' as p; import 'dio_cli.dart'; diff --git a/lib/tools_base/net/net_manager.dart b/lib/tools_base/net/net_manager.dart index 9501604..1a835b5 100644 --- a/lib/tools_base/net/net_manager.dart +++ b/lib/tools_base/net/net_manager.dart @@ -4,8 +4,8 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:dio/io.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; -import 'package:hgmj/tools_base/net/http_manager.dart'; +import 'package:wydj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/net/http_manager.dart'; import '../../config/address.dart'; import '../../hj_utils/light_model.dart'; @@ -56,7 +56,8 @@ class NetManager { Future userAgent() => DeviceInfoService.getCachedUserAgent(); /// 强制重新生成并写回缓存(扫码登录、设备切换等场景)。 - Future refreshUserAgent() => DeviceInfoService.getCachedUserAgent(deviceId: DeviceInfoService.deviceId); + Future refreshUserAgent() => DeviceInfoService.getCachedUserAgent( + deviceId: DeviceInfoService.deviceId); /// 清除ua Future clearUserAgent() => DeviceInfoService.clearCachedUserAgent(); @@ -81,7 +82,8 @@ class NetManager { if (TextUtil.isNotEmpty(serverTimeS)) { _serverTime = DateTime.parse(serverTimeS!); _diffTimeInSeconds = DateTime.now().difference(_serverTime!).inSeconds; - debugLog("============>server diff from local in seconds:$_diffTimeInSeconds"); + debugLog( + "============>server diff from local in seconds:$_diffTimeInSeconds"); } } @@ -106,7 +108,8 @@ Dio createDio({BaseOptions? options}) { var adapter = DefaultHttpClientAdapter(); // var adapter = DefaultHttpClientAdapter(); adapter.onHttpClientCreate = (client) { - client.badCertificateCallback = (X509Certificate cert, String host, int port) => true; + client.badCertificateCallback = + (X509Certificate cert, String host, int port) => true; return client; }; dio.httpClientAdapter = adapter; diff --git a/lib/tools_base/refresh/horizontal_load_more.dart b/lib/tools_base/refresh/horizontal_load_more.dart index 8200b90..d24c22b 100644 --- a/lib/tools_base/refresh/horizontal_load_more.dart +++ b/lib/tools_base/refresh/horizontal_load_more.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/tools_base/refresh/pull_refresh.dart'; // 复用 CustomRefreshView 的手感调优 +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/tools_base/refresh/pull_refresh.dart'; // 复用 CustomRefreshView 的手感调优 import 'package:pull_to_refresh/pull_to_refresh.dart'; /// 横向列表"拉到底查看更多"组件(手感同上拉加载更多,只是横向)。 @@ -37,7 +37,8 @@ class HorizontalLoadMore extends StatefulWidget { class _HorizontalLoadMoreState extends State { final RefreshController _refreshCtr = RefreshController(); - final ValueNotifier _armed = ValueNotifier(false); // 当前过拉是否已过阈值(驱动 footer 文案 + 触发判定) + final ValueNotifier _armed = + ValueNotifier(false); // 当前过拉是否已过阈值(驱动 footer 文案 + 触发判定) @override void dispose() { @@ -49,7 +50,8 @@ class _HorizontalLoadMoreState extends State { // 拖动中持续更新是否已过阈值(公式同 SmartRefresher footer 的 offset 计算) bool _onScroll(ScrollNotification n) { if (n.metrics.axis != Axis.horizontal) return false; - final double overscroll = n.metrics.pixels - n.metrics.maxScrollExtent; // 拉过末尾的距离 + final double overscroll = + n.metrics.pixels - n.metrics.maxScrollExtent; // 拉过末尾的距离 _armed.value = overscroll >= widget.triggerDistance; return false; } @@ -92,7 +94,8 @@ class _HorizontalLoadMoreState extends State { builder: (_, armed, ___) => _footer(armed), ), ), - onLoading: () => _refreshCtr.loadComplete(), // 触发已由指针事件把关,这里只复位 footer + onLoading: () => + _refreshCtr.loadComplete(), // 触发已由指针事件把关,这里只复位 footer child: widget.child, ), ), @@ -112,13 +115,15 @@ class _HorizontalLoadMoreState extends State { AnimatedRotation( turns: armed ? 0.5 : 0, duration: const Duration(milliseconds: 200), - child: Image.asset("arrow_right_grey.webp".commonImgPath, width: 18), + child: + Image.asset("arrow_right_grey.webp".commonImgPath, width: 18), ), const SizedBox(height: 6), Text( armed ? widget.releaseText : widget.idleText, textAlign: TextAlign.center, - style: const TextStyle(color: Color(0x59FFFFFF), fontSize: 10, height: 1.3), + style: const TextStyle( + color: Color(0x59FFFFFF), fontSize: 10, height: 1.3), ), ], ), diff --git a/lib/tools_base/refresh/pull_refresh.dart b/lib/tools_base/refresh/pull_refresh.dart index 8d18d1f..2a68afd 100644 --- a/lib/tools_base/refresh/pull_refresh.dart +++ b/lib/tools_base/refresh/pull_refresh.dart @@ -3,14 +3,15 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; // 回弹弹簧:临界阻尼(≈2√(stiffness·mass)=34.6) → 松手快速收回不过冲 // 注:实测此调优手感优于 3.16.8 包默认(mass2.2/stiffness150/damping16,欠阻尼、回弹更夸张), // 故采用这套调优值,不复刻 3.16.8 原值 // 提成常量供横向的 HorizontalLoadMore 复用,两处手感必须一致,改这里即全改 -const SpringDescription kRefreshSpring = SpringDescription(mass: 1.5, stiffness: 200, damping: 35); +const SpringDescription kRefreshSpring = + SpringDescription(mass: 1.5, stiffness: 200, damping: 35); const double kRefreshDragSpeedRatio = 0.91; Widget pullYsRefresh({ @@ -106,14 +107,19 @@ class _CustomIRefreshViewState extends State { WaterDropHeader( waterDropColor: AppColors.actionRed, // iOS 刷新菊花用主题色;Android 保持默认 loading - refresh: Platform.isIOS ? const CupertinoActivityIndicator(color: AppColors.actionRed) : null, + refresh: Platform.isIOS + ? const CupertinoActivityIndicator( + color: AppColors.actionRed) + : null, complete: const Text( "刷新完成!", - style: TextStyle(color: AppColors.tipTextColor99, fontSize: 12), + style: TextStyle( + color: AppColors.tipTextColor99, fontSize: 12), ), failed: const Text( "刷新失敗!", - style: TextStyle(color: AppColors.tipTextColor99, fontSize: 12), + style: TextStyle( + color: AppColors.tipTextColor99, fontSize: 12), ), ), footer: widget.footerHeader ?? @@ -130,7 +136,8 @@ class _CustomIRefreshViewState extends State { ? const CupertinoActivityIndicator() : const CircularProgressIndicator( strokeWidth: 2.0, - valueColor: AlwaysStoppedAnimation(AppColors.actionRed), + valueColor: + AlwaysStoppedAnimation(AppColors.actionRed), ), ), textStyle: TextStyle( diff --git a/lib/tools_base/richTextParsing/html_pro_parser.dart b/lib/tools_base/richTextParsing/html_pro_parser.dart index 601a727..9143011 100644 --- a/lib/tools_base/richTextParsing/html_pro_parser.dart +++ b/lib/tools_base/richTextParsing/html_pro_parser.dart @@ -1,5 +1,5 @@ import 'package:flutter/widgets.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/tools_base/debug_log.dart'; class HtmlProParser { static Color? spanBg(String? value) { @@ -44,7 +44,8 @@ class HtmlProParser { static double? lineHeight(String? value) { try { if (value?.contains("line-height:") == true) { - final sizeStr = value!.replaceAll("line-height:", "").replaceAll(";", ""); + final sizeStr = + value!.replaceAll("line-height:", "").replaceAll(";", ""); return double.tryParse(sizeStr); } } catch (e) { diff --git a/lib/tools_base/video_download/download_button.dart b/lib/tools_base/video_download/download_button.dart index b222dcf..f877eea 100644 --- a/lib/tools_base/video_download/download_button.dart +++ b/lib/tools_base/video_download/download_button.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/video_download/media_download_manager.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/video_download/media_download_manager.dart'; /// 视频下载按钮,短视频 / 长视频 / 短剧 / 动漫共用。 /// 只管画状态和转发点击;权限、扣次、落记录、进度回调全在 [MediaDownloadManager] @@ -17,7 +17,8 @@ class DownloadButton extends StatefulWidget { /// 短剧在操作台里排版同短视频,但要单独归类,所以显式传 [MediaStyle.Drama] final MediaStyle? style; - const DownloadButton({super.key, this.video, this.isShort = true, this.style}); + const DownloadButton( + {super.key, this.video, this.isShort = true, this.style}); @override State createState() => _DownloadButtonState(); @@ -45,7 +46,8 @@ class _DownloadButtonState extends State { @override void initState() { super.initState(); - _task = MediaDownloadManager.instance.attach(video: widget.video, style: _mediaStyle, onChanged: _refresh); + _task = MediaDownloadManager.instance + .attach(video: widget.video, style: _mediaStyle, onChanged: _refresh); } @override @@ -55,7 +57,8 @@ class _DownloadButtonState extends State { //点下载下的也是上一条。同一个对象(父级只是重建)就别白折腾 if (identical(oldWidget.video, widget.video)) return; _task.detach(); - _task = MediaDownloadManager.instance.attach(video: widget.video, style: _mediaStyle, onChanged: _refresh); + _task = MediaDownloadManager.instance + .attach(video: widget.video, style: _mediaStyle, onChanged: _refresh); } @override @@ -80,7 +83,10 @@ class _DownloadButtonState extends State { final label = Text( _task.state.desc, style: isShort - ? const TextStyle(color: Color(0xffdcdcdc), fontSize: 12, fontWeight: FontWeight.w500) + ? const TextStyle( + color: Color(0xffdcdcdc), + fontSize: 12, + fontWeight: FontWeight.w500) : const TextStyle(color: Color(0xff989898), fontSize: 12), ); return InkWell( @@ -88,7 +94,9 @@ class _DownloadButtonState extends State { onTap: _task.start, child: isShort ? Column(mainAxisSize: MainAxisSize.min, children: [icon, label]) - : Row(mainAxisSize: MainAxisSize.min, children: [icon, 2.sizeBoxW, label]), + : Row( + mainAxisSize: MainAxisSize.min, + children: [icon, 2.sizeBoxW, label]), ); } } diff --git a/lib/tools_base/video_download/media_download_manager.dart b/lib/tools_base/video_download/media_download_manager.dart index 85d48c1..2ed9d93 100644 --- a/lib/tools_base/video_download/media_download_manager.dart +++ b/lib/tools_base/video_download/media_download_manager.dart @@ -1,26 +1,26 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; -import 'package:hgmj/alert/mine/vip_level_dialog.dart'; -import 'package:hgmj/alert/video/buy_vip_alert.dart'; -import 'package:hgmj/config/config.dart'; -import 'package:hgmj/hj_model/drama/drama_models.dart'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_page/drama/view/drama_video_player_logic.dart'; -import 'package:hgmj/hj_page/mine/mine_vip/pay_order_source.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:hgmj/hj_page/pre_sale/pre_sale_service.dart'; -import 'package:hgmj/hj_page/video/view/long_video_status.dart'; -import 'package:hgmj/hj_utils/api_service/drama_service.dart'; -import 'package:hgmj/hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/hj_utils/codec_support.dart'; -import 'package:hgmj/hj_utils/const.dart'; -import 'package:hgmj/tools_base/global_store/store.dart'; -import 'package:hgmj/tools_base/net/base_resp_bean.dart'; -import 'package:hgmj/tools_base/net/net_code.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/video_download/video_cache_store.dart'; -import 'package:hgmj/tools_base/video_download/video_download_manager.dart'; +import 'package:wydj/alert/mine/vip_level_dialog.dart'; +import 'package:wydj/alert/video/buy_vip_alert.dart'; +import 'package:wydj/config/config.dart'; +import 'package:wydj/hj_model/drama/drama_models.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_page/drama/view/drama_video_player_logic.dart'; +import 'package:wydj/hj_page/mine/mine_vip/pay_order_source.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_provider.dart'; +import 'package:wydj/hj_page/pre_sale/pre_sale_service.dart'; +import 'package:wydj/hj_page/video/view/long_video_status.dart'; +import 'package:wydj/hj_utils/api_service/drama_service.dart'; +import 'package:wydj/hj_utils/api_service/mine_service.dart'; +import 'package:wydj/hj_utils/codec_support.dart'; +import 'package:wydj/hj_utils/const.dart'; +import 'package:wydj/tools_base/global_store/store.dart'; +import 'package:wydj/tools_base/net/base_resp_bean.dart'; +import 'package:wydj/tools_base/net/net_code.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/video_download/video_cache_store.dart'; +import 'package:wydj/tools_base/video_download/video_download_manager.dart'; import 'package:permission_handler/permission_handler.dart'; /// 下载状态(对应 VideoModel.isLoaderRunning 的 "0"/"1"/"2") @@ -60,14 +60,17 @@ class DownloadTask { String get _contentId => video?.subid ?? ''; // 短剧的分集 id 存在 subid,不是 video.id DownloadState get state { - if (video?.localPath?.isNotEmpty == true || video?.isLoaderRunning == "2") return DownloadState.done; + if (video?.localPath?.isNotEmpty == true || video?.isLoaderRunning == "2") + return DownloadState.done; if (video?.isDownloading == true) return DownloadState.loading; return DownloadState.idle; } /// 回调匹配用 taskKey(剥掉 token/cdn):token 刷新或切线路后整条 url 会变, /// 拿整条 url 比对会匹配失败,进度条卡死不再刷新(下载其实仍按 path 继续跑) - bool _isMine(String url) => VideoDownloadManager.taskKey(taskUrl) == VideoDownloadManager.taskKey(url); + bool _isMine(String url) => + VideoDownloadManager.taskKey(taskUrl) == + VideoDownloadManager.taskKey(url); /// 点下载。连点必须挡住:两次并发会各自生成一个幂等键(第一次还没落盘第二次就读到了空表), /// 服务端当成两次下载扣两次次数;长视频那条 reduceDownloadCount 同理 @@ -101,7 +104,10 @@ class MediaDownloadManager { /// 挂上进度回调并回填这条内容当前的缓存状态。同步返回句柄,绑定在后台走完—— /// UI 在 initState 里拿到就能持有,dispose 时不用等 - DownloadTask attach({required VideoModel? video, required MediaStyle style, required VoidCallback onChanged}) { + DownloadTask attach( + {required VideoModel? video, + required MediaStyle style, + required VoidCallback onChanged}) { final task = DownloadTask._(video, style, onChanged); unawaited(_bind(task)); return task; @@ -111,8 +117,11 @@ class MediaDownloadManager { final video = task.video; //短剧下载的是授权接口现签的那条地址,只按播放地址查会认不出「已经下过」, //得先从缓存记录里把当时那条捞回来 - final resolved = - (task._isDrama ? (await VideoCacheStore.instance.find(MediaStyle.Drama, video))?.realVideoUrl : null) ?? video?.realVideoUrl; + final resolved = (task._isDrama + ? (await VideoCacheStore.instance.find(MediaStyle.Drama, video)) + ?.realVideoUrl + : null) ?? + video?.realVideoUrl; if (task._detached) return; //用 ??=:查记录这一路是异步的,用户抢先点了下载的话地址已被 _enqueue 定过,别再顶回去 task.taskUrl ??= resolved; @@ -136,7 +145,8 @@ class MediaDownloadManager { task._onChanged(); }, ); - final info = await VideoDownloadManager.instance.searchInfo(url: task.taskUrl, callback: task._callback); + final info = await VideoDownloadManager.instance + .searchInfo(url: task.taskUrl, callback: task._callback); if (task._detached) { task.detach(); // searchInfo 顺手挂上的回调,走到这里已经没人要了 return; @@ -178,8 +188,11 @@ class MediaDownloadManager { return; } // 预售特权:还有今日下载次数就消耗一次特权,消耗失败不下载 - if (presaleProvider.isOpen && presaleProvider.hasLimit == true && (presaleProvider.remain?.todayDownloadCount ?? 0) > 0) { - final resp = await PreSaleService.consumePrivilege(type: PrivilegeType.download); + if (presaleProvider.isOpen && + presaleProvider.hasLimit == true && + (presaleProvider.remain?.todayDownloadCount ?? 0) > 0) { + final resp = + await PreSaleService.consumePrivilege(type: PrivilegeType.download); if (resp.isSuccess) { presaleProvider.reduceDownload(); await _enqueue(task); @@ -228,7 +241,8 @@ class MediaDownloadManager { /// [allowRetry] 只留给 5003(扣次结果不确定)自动补问一次,且必须复用同一个 requestId Future _authorize(DownloadTask task, {required bool allowRetry}) async { //幂等键先落盘再发请求:响应丢了/超时重试都得拿同一个键回来,换新键服务端会再扣一次次数 - final requestId = await VideoCacheStore.instance.dramaRequestId(task._contentId); + final requestId = + await VideoCacheStore.instance.dramaRequestId(task._contentId); final resp = await DramaService.authorizeDownload( mediaId: task._mediaId, contentId: task._contentId, @@ -250,7 +264,9 @@ class MediaDownloadManager { globalStore.wallet?.downloadCount = auth.remainingDownloadCount; globalStore.refreshWallet(); final h265 = auth.h265DownloadUrl ?? ''; - final source = CodecSupport.useH265 && h265.isNotEmpty ? h265 : (auth.downloadUrl ?? ''); + final source = CodecSupport.useH265 && h265.isNotEmpty + ? h265 + : (auth.downloadUrl ?? ''); if (source.isEmpty) { showToast("资源异常,请稍后再试"); // 两条地址都空,别建一个下不动的空任务 return; @@ -263,11 +279,13 @@ class MediaDownloadManager { } /// 授权失败分流。有响应的失败网络层已经按 tip 弹过提示,这里只做要额外引导/善后的几种 - Future _onAuthorizeFailed(DownloadTask task, BaseRespBean resp, {required bool allowRetry}) async { + Future _onAuthorizeFailed(DownloadTask task, BaseRespBean resp, + {required bool allowRetry}) async { final data = resp.data; switch (resp.code) { //1000 既是封号也是「没有短剧权益」,只有 data.reason 能区分,封号那种交给网络层的提示 - case Code.ACCOUNT_INVISIBLE when data is Map && data['reason'] == 'DRAMA_ENTITLEMENT_REQUIRED': + case Code.ACCOUNT_INVISIBLE + when data is Map && data['reason'] == 'DRAMA_ENTITLEMENT_REQUIRED': await _openDramaCard(task); //次数不足:引导买带下载次数的商品 case Code.NOT_ENOUGH_DOWNLOAD: @@ -307,7 +325,8 @@ class MediaDownloadManager { ); await _refreshEpisode(task); //开卡放行了要叫醒播放器:下载这条链自己不碰播放器,不广播的话买完卡付费墙还杵在原地 - if (task.video?.dramaEpisode?.canPlay == true) DramaVideoPlayerLogic.broadcastUnlock(); + if (task.video?.dramaEpisode?.canPlay == true) + DramaVideoPlayerLogic.broadcastUnlock(); } /// 重拉分集详情:本地那份的解锁状态/地址可能已经过期 @@ -321,7 +340,8 @@ class MediaDownloadManager { /// [url] 本次真正要下的地址(短剧走授权接口现签的那条),不传就用播放地址; /// [record] 落进缓存库的记录,不传就用当前 model - Future _enqueue(DownloadTask task, {String? url, VideoModel? record}) async { + Future _enqueue(DownloadTask task, + {String? url, VideoModel? record}) async { //拿不到权限也照旧下(部分机型无需存储权限),所以不看结果 final status = await Permission.storage.status; if (!status.isGranted) await Permission.storage.request(); @@ -329,12 +349,15 @@ class MediaDownloadManager { final target = url ?? video?.realVideoUrl ?? ""; //换地址要把回调从老 key 上摘掉,否则那条既收不到事件、detach 也清不掉 final cb = task._callback; - if (cb != null && VideoDownloadManager.taskKey(target) != VideoDownloadManager.taskKey(task.taskUrl)) { + if (cb != null && + VideoDownloadManager.taskKey(target) != + VideoDownloadManager.taskKey(task.taskUrl)) { VideoDownloadManager.instance.removeCallback(task.taskUrl, cb); } task.taskUrl = target; //返回值是 VideoDownloadManager.download 的约定:null=新任务开起来了,两个中文串=已有任务,其余是错误文案 - switch (await VideoDownloadManager.instance.download(url: target, callback: cb)) { + switch (await VideoDownloadManager.instance + .download(url: target, callback: cb)) { case null: VideoCacheStore.instance.saveVideoInfo(task.style, record ?? video); video?.isLoaderRunning = "1"; diff --git a/lib/tools_base/video_download/video_cache_store.dart b/lib/tools_base/video_download/video_cache_store.dart index 92bba2d..b872be9 100644 --- a/lib/tools_base/video_download/video_cache_store.dart +++ b/lib/tools_base/video_download/video_cache_store.dart @@ -1,8 +1,8 @@ import 'dart:convert'; -import 'package:hgmj/hj_model/video_model.dart'; -import 'package:hgmj/hj_utils/date_time_util.dart'; -import 'package:hgmj/tools_base/debug_log.dart'; +import 'package:wydj/hj_model/video_model.dart'; +import 'package:wydj/hj_utils/date_time_util.dart'; +import 'package:wydj/tools_base/debug_log.dart'; import 'package:uuid/uuid.dart'; import '../../hj_utils/const.dart'; @@ -29,7 +29,12 @@ class VideoCacheStore { } /// 有独立存储桶的业务;[_listKey] 未列到的一律落影视桶 - static const _buckets = [MediaStyle.Video, MediaStyle.ShortVideo, MediaStyle.Cartoon, MediaStyle.Drama]; + static const _buckets = [ + MediaStyle.Video, + MediaStyle.ShortVideo, + MediaStyle.Cartoon, + MediaStyle.Drama + ]; /// 各业务的存储 key,未列到的一律落影视桶 static String _listKey(MediaStyle type) => switch (type) { @@ -44,7 +49,9 @@ class VideoCacheStore { /// 只比 id 会让第二集把第一集的记录挤掉,所以短剧必须带上 subid。 /// 其余业务维持原样只认 id(动漫虽然也有 subid,但它一条记录就是一部作品) static String _identity(MediaStyle type, VideoModel video) => - type == MediaStyle.Drama ? '${video.id}#${video.subid}' : (video.id ?? ''); + type == MediaStyle.Drama + ? '${video.id}#${video.subid}' + : (video.id ?? ''); /// 缓存记录 Future> getMovieCacheVideoList(MediaStyle type) async { @@ -84,7 +91,8 @@ class VideoCacheStore { Future saveVideoInfo(MediaStyle type, VideoModel? video) async { if (video == null) return; final id = _identity(type, video); - final rest = (await getMovieCacheVideoList(type)).where((e) => _identity(type, e) != id); + final rest = (await getMovieCacheVideoList(type)) + .where((e) => _identity(type, e) != id); await _write(type, [video, ...rest]); } @@ -95,10 +103,12 @@ class VideoCacheStore { Future removeVideoList(MediaStyle type, List videos) async { final ids = videos.map((e) => _identity(type, e)).toSet(); - final rest = (await getMovieCacheVideoList(type)).where((e) => !ids.contains(_identity(type, e))); + final rest = (await getMovieCacheVideoList(type)) + .where((e) => !ids.contains(_identity(type, e))); await _write(type, rest); //删了就是这次下载结束了,幂等键跟着清;留着的话重下会命中上一次的授权(不扣次也拿不到新地址) - if (type == MediaStyle.Drama) await _dropDramaRequestIds(videos.map((e) => e.subid)); + if (type == MediaStyle.Drama) + await _dropDramaRequestIds(videos.map((e) => e.subid)); } /// 按身份取一条已存的记录。短剧下载地址是授权接口现签的,和播放地址不是同一条 path, @@ -128,7 +138,8 @@ class VideoCacheStore { /// 丢弃这一集的幂等键:下次点下载算新的一次,服务端会正常扣次。 /// 4009(同一个键换了剧集)也走它把脏映射清掉 - Future dropDramaRequestId(String? contentId) => _dropDramaRequestIds([contentId]); + Future dropDramaRequestId(String? contentId) => + _dropDramaRequestIds([contentId]); Future _dropDramaRequestIds(Iterable contentIds) async { final map = await _dramaRequestIds(); @@ -138,7 +149,8 @@ class VideoCacheStore { } Future> _dramaRequestIds() async { - final str = await lightKV.getString(StoreKeys.DRAMA_DOWNLOAD_REQUEST_ID) ?? ''; + final str = + await lightKV.getString(StoreKeys.DRAMA_DOWNLOAD_REQUEST_ID) ?? ''; if (str.isEmpty) return {}; try { return Map.from(json.decode(str)); @@ -168,5 +180,6 @@ class VideoCacheStore { } Future _write(MediaStyle type, Iterable videos) => - lightKV.setStringList(_listKey(type), videos.map((e) => json.encode(e.toJson())).toList()); + lightKV.setStringList( + _listKey(type), videos.map((e) => json.encode(e.toJson())).toList()); } diff --git a/lib/tools_base/video_download/video_download_manager.dart b/lib/tools_base/video_download/video_download_manager.dart index 627412f..9bbffad 100644 --- a/lib/tools_base/video_download/video_download_manager.dart +++ b/lib/tools_base/video_download/video_download_manager.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'dart:isolate'; import 'dart:ui'; -import 'package:hgmj/tools_base/video_download/video_cache_store.dart'; +import 'package:wydj/tools_base/video_download/video_cache_store.dart'; import 'package:m3u8_downloader/m3u8_downloader.dart'; import 'package:path_provider/path_provider.dart'; @@ -32,7 +32,8 @@ class VideoDownloadManager { factory VideoDownloadManager() => instance; - static VideoDownloadManager get instance => _instance ??= VideoDownloadManager._(); + static VideoDownloadManager get instance => + _instance ??= VideoDownloadManager._(); static VideoDownloadManager? _instance; // ===== 状态 ===== @@ -95,7 +96,8 @@ class VideoDownloadManager { _callbacks.remove(key); case 2: // 进度 final raw = data["progress"]; - final progress = raw is double ? raw.toStringAsFixed(2) : raw.toString(); + final progress = + raw is double ? raw.toStringAsFixed(2) : raw.toString(); notify('progress', (cb) => cb.progress?.call(url, progress)); } } @@ -107,7 +109,9 @@ class VideoDownloadManager { Future init() async { if (Platform.isIOS) return false; if (_isInited) return true; - final dir = Platform.isAndroid ? await getExternalStorageDirectory() : await getApplicationDocumentsDirectory(); + final dir = Platform.isAndroid + ? await getExternalStorageDirectory() + : await getApplicationDocumentsDirectory(); _basePath = '${dir!.path}/vPlayDownload'; final root = Directory(_basePath); if (!root.existsSync()) await root.create(); @@ -157,9 +161,11 @@ class VideoDownloadManager { /// 查询 url 当前缓存状态,两端的裸 Map 统一解析成 [DownloadInfo] /// 返回 null 表示:url 为空 / 未下载过 / 缓存初始化失败 /// [callback] 仅在查到任务正在下载时挂上,用于后续接收进度回调 - Future searchInfo({String? url, DownloadCallback? callback}) async { + Future searchInfo( + {String? url, DownloadCallback? callback}) async { if (Platform.isIOS) { - final ret = await IOSVideoDownloader.instance.searchInfo(url ?? '', callback: callback); + final ret = await IOSVideoDownloader.instance + .searchInfo(url ?? '', callback: callback); return ret is Map ? DownloadInfo.fromJson(ret) : null; } if (!_isInited && !await init()) { @@ -179,10 +185,12 @@ class VideoDownloadManager { /// 返回值: /// - null / "正在执行": 任务已开启或已在跑,会自动挂上 [callback] /// - 其它 String: 错误提示,如 "缓存加载失败" / "视频链接为空" / 异常文案 - Future download({required String url, DownloadCallback? callback}) async { + Future download( + {required String url, DownloadCallback? callback}) async { try { if (Platform.isIOS) { - return IOSVideoDownloader.instance.download(url: url, callback: callback); + return IOSVideoDownloader.instance + .download(url: url, callback: callback); } if (!_isInited && !await init()) return "缓存加载失败"; if (url.isEmpty) return "视频链接为空"; @@ -208,7 +216,9 @@ class VideoDownloadManager { /// 删除指定 url 的缓存文件,同时清掉它的回调 Future delete(String url) async { - final ret = Platform.isIOS ? await IOSVideoDownloader.instance.delete(url) : await M3u8Downloader.delete(url); + final ret = Platform.isIOS + ? await IOSVideoDownloader.instance.delete(url) + : await M3u8Downloader.delete(url); _callbacks.remove(taskKey(url)); return ret; } @@ -263,13 +273,18 @@ _onProgress(dynamic args) { _onSuccess(dynamic args) { debugLog("=======load success!!!!!!"); debugLog(args); - IsolateNameServer.lookupPortByName(_portName) - ?.send({"status": 1, "url": args["url"], "filePath": args["filePath"], "dir": args["dir"]}); + IsolateNameServer.lookupPortByName(_portName)?.send({ + "status": 1, + "url": args["url"], + "filePath": args["filePath"], + "dir": args["dir"] + }); } @pragma('vm:entry-point') _onError(dynamic args) { - IsolateNameServer.lookupPortByName(_portName)?.send({"status": 0, "url": args["url"]}); + IsolateNameServer.lookupPortByName(_portName) + ?.send({"status": 0, "url": args["url"]}); } /// [VideoDownloadManager.searchInfo] 的查询结果:某个 url 当前的下载状态。 @@ -280,7 +295,8 @@ class DownloadInfo { String? isLoaderRunning; // "1" 下载中 / "0" 已暂停;已完成时不下发 String? status; // "2" 下载完成;下载中时由 isLoaderRunning 推出 "1" - DownloadInfo({this.progress, this.localPath, this.status, this.isLoaderRunning}); + DownloadInfo( + {this.progress, this.localPath, this.status, this.isLoaderRunning}); DownloadInfo.fromJson(Map json) { localPath = json['localPath']; diff --git a/lib/tools_base/video_download/video_save_util.dart b/lib/tools_base/video_download/video_save_util.dart index 11e7f0c..44664de 100644 --- a/lib/tools_base/video_download/video_save_util.dart +++ b/lib/tools_base/video_download/video_save_util.dart @@ -5,9 +5,9 @@ import 'package:ffmpeg_kit_flutter_new_https_gpl/ffmpeg_kit.dart'; import 'package:ffmpeg_kit_flutter_new_https_gpl/return_code.dart'; import 'package:ffmpeg_kit_flutter_new_https_gpl/statistics.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; -import 'package:hgmj/hj_utils/image_util.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/hj_utils/image_util.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../debug_log.dart'; import 'video_download_manager.dart'; @@ -25,7 +25,8 @@ class VideoSaveUtil { /// 视频转换成 mp4 保存到本地相册中 /// 在 VideoDownloadManager 下载完成后调用 - Future convertVideoMp4(String url, {DownloadInfo? loadInfo, bool isShowLoading = true}) async { + Future convertVideoMp4(String url, + {DownloadInfo? loadInfo, bool isShowLoading = true}) async { // iOS 下载产物本身就是 mp4(ffmpeg 下载时已转码),localPath 直接指向 mp4, // 不能走下面的 m3u8 转码逻辑(会把 mp4 当 m3u8 文本读),直接保存即可 if (Platform.isIOS) { @@ -46,7 +47,8 @@ class VideoSaveUtil { } try { //队列里补跑的任务(_consumeQueue)不带 loadInfo,得自己查一次 - final localFileInfo = loadInfo ?? await VideoDownloadManager.instance.searchInfo(url: url); + final localFileInfo = + loadInfo ?? await VideoDownloadManager.instance.searchInfo(url: url); if (localFileInfo?.localPath?.isNotEmpty != true) { showToast("视频文件不存在"); if (isShowLoading) LoadingAlertWidget.cancel(); @@ -67,19 +69,21 @@ class VideoSaveUtil { } final m3u8ContentList = await m3u8Path.readAsLines(); - final keyLineIndex = m3u8ContentList.indexWhere((e) => e.startsWith('#EXT-X-KEY')); + final keyLineIndex = + m3u8ContentList.indexWhere((e) => e.startsWith('#EXT-X-KEY')); // local.m3u8 里 ts 是本地文件,但 KEY 的 URI 仍是远程地址:把 key 拉到本地, // 再把 m3u8 的 KEY 行改成指向本地 sec.key,交给 ffmpeg 自行解密(不重编码) if (keyLineIndex >= 0) { - final keyUrl = await _resolveKeyUrl(dirPath, m3u8ContentList[keyLineIndex], url); + final keyUrl = + await _resolveKeyUrl(dirPath, m3u8ContentList[keyLineIndex], url); if (keyUrl.isEmpty) throw "密钥地址解析失败"; final secKeyPath = '$dirPath/sec.key'; if (!await _prepareKeyFile(keyUrl, secKeyPath)) throw "密钥获取失败,请重试"; // 只替换 KEY 行里的 URI,保留 METHOD/IV 等其它属性。 // 整行重写会丢掉 IV,带显式 IV 的流会因默认 IV(分片序号)解密错位。 // 连到下一个逗号为止整段换掉:老数据的 URI 可能被原生插件多包了一层引号 - m3u8ContentList[keyLineIndex] = - m3u8ContentList[keyLineIndex].replaceFirst(RegExp(r'URI=[^,]*'), 'URI="$secKeyPath"'); + m3u8ContentList[keyLineIndex] = m3u8ContentList[keyLineIndex] + .replaceFirst(RegExp(r'URI=[^,]*'), 'URI="$secKeyPath"'); } final localM3u8File = File('$dirPath/download.m3u8'); await localM3u8File.writeAsString(m3u8ContentList.join('\n')); @@ -88,7 +92,8 @@ class VideoSaveUtil { // 也不会因为播放器在老机型上初始化失败把整个保存流程带崩 final totalDurationMs = _totalDurationMs(m3u8ContentList); - final command = '-allowed_extensions ALL -i "${localM3u8File.path}" -c copy -bsf:a aac_adtstoasc -movflags +faststart "$outputPath"'; + final command = + '-allowed_extensions ALL -i "${localM3u8File.path}" -c copy -bsf:a aac_adtstoasc -movflags +faststart "$outputPath"'; FFmpegKit.executeAsync( command, (session) async { @@ -106,7 +111,8 @@ class VideoSaveUtil { await File(outputPath).delete(); } catch (_) {} showToast("保存失败"); - debugLog('转换失败,返回码:${returnCode?.getValue()}', await session.getFailStackTrace()); + debugLog('转换失败,返回码:${returnCode?.getValue()}', + await session.getFailStackTrace()); } _consumeQueue(); }, @@ -136,10 +142,12 @@ class VideoSaveUtil { } /// iOS:下载完成的文件已是 mp4,直接保存到相册 - Future _saveIosMp4(String url, {DownloadInfo? loadInfo, bool isShowLoading = true}) async { + Future _saveIosMp4(String url, + {DownloadInfo? loadInfo, bool isShowLoading = true}) async { String? mp4Path = loadInfo?.localPath; if (mp4Path?.isNotEmpty != true) { - mp4Path = (await VideoDownloadManager.instance.searchInfo(url: url))?.localPath; + mp4Path = + (await VideoDownloadManager.instance.searchInfo(url: url))?.localPath; } if (mp4Path?.isNotEmpty != true || !await File(mp4Path!).exists()) { showToast("视频文件不存在"); @@ -178,7 +186,8 @@ class VideoSaveUtil { /// local.m3u8 的 KEY 行是原生插件重新拼的,两种情况会拼坏:绝对地址会多包一层引号 /// (取到空串)、带 query 的地址会被 '=' 截断(取到半截地址),所以优先从同目录的 /// remote.m3u8(下载时存下的原始 m3u8 全文)里取原始 URI,相对地址再按视频地址补全 - Future _resolveKeyUrl(String dirPath, String localKeyLine, String videoUrl) async { + Future _resolveKeyUrl( + String dirPath, String localKeyLine, String videoUrl) async { String raw = ''; final remoteFile = File('$dirPath/remote.m3u8'); if (await remoteFile.exists()) { @@ -190,7 +199,8 @@ class VideoSaveUtil { } //remote.m3u8 丢了才退回 local 的 KEY 行,多余的引号一并去掉 if (raw.isEmpty) { - raw = (RegExp(r'URI=([^,]*)').firstMatch(localKeyLine)?.group(1) ?? '').replaceAll('"', ''); + raw = (RegExp(r'URI=([^,]*)').firstMatch(localKeyLine)?.group(1) ?? '') + .replaceAll('"', ''); } if (raw.isEmpty) return ''; try { @@ -229,7 +239,8 @@ class VideoSaveUtil { double seconds = 0; for (final line in lines) { if (!line.startsWith('#EXTINF:')) continue; - seconds += double.tryParse(line.substring(8).split(',').first.trim()) ?? 0; + seconds += + double.tryParse(line.substring(8).split(',').first.trim()) ?? 0; } return (seconds * 1000).round(); } diff --git a/lib/tools_base/widget/add_media_source_button.dart b/lib/tools_base/widget/add_media_source_button.dart index 4f9514d..63832f5 100644 --- a/lib/tools_base/widget/add_media_source_button.dart +++ b/lib/tools_base/widget/add_media_source_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import 'package:mobkit_dashed_border/mobkit_dashed_border.dart'; class AddMediaSourceButton extends StatelessWidget { @@ -43,11 +43,13 @@ class AddMediaSourceButton extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ ((111 - 24) / 2).sizeBoxH, - Image.asset('add_grey.png'.communityPath, width: 24, color: const Color(0xffDCDCDC)), + Image.asset('add_grey.png'.communityPath, + width: 24, color: const Color(0xffDCDCDC)), 9.sizeBoxH, Text( title ?? (isVideo ? '添加视频' : '添加图片'), - style: TextStyle(color: const Color(0xff999999), fontSize: 14.sp), + style: + TextStyle(color: const Color(0xff999999), fontSize: 14.sp), ), ], ), diff --git a/lib/tools_base/widget/card_swiper/src/swiper_control.dart b/lib/tools_base/widget/card_swiper/src/swiper_control.dart index 73f2f1f..c0fe5d4 100644 --- a/lib/tools_base/widget/card_swiper/src/swiper_control.dart +++ b/lib/tools_base/widget/card_swiper/src/swiper_control.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/tools_base/widget/card_swiper/src/swiper_plugin.dart'; +import 'package:wydj/tools_base/widget/card_swiper/src/swiper_plugin.dart'; class SwiperControl extends SwiperPlugin { const SwiperControl({ diff --git a/lib/tools_base/widget/common_alert.dart b/lib/tools_base/widget/common_alert.dart index 181bc39..22d7991 100644 --- a/lib/tools_base/widget/common_alert.dart +++ b/lib/tools_base/widget/common_alert.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/widget/common_dialog.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/widget/common_dialog.dart'; /// 全站统一的提示/确认弹窗:标题 + 分割线 + 正文 + 副文案 + 灰「取消」红「确定」双按钮。 /// 壳走 [CommonDialog],业务结果一律用返回值传(点确定=true),别在弹窗里塞跳转逻辑。 @@ -68,7 +68,10 @@ class CommonAlert extends StatelessWidget { children: [ Text( title, - style: TextStyle(color: Colors.white.withValues(alpha: .9), fontSize: 20, fontWeight: FontWeight.w600), + style: TextStyle( + color: Colors.white.withValues(alpha: .9), + fontSize: 20, + fontWeight: FontWeight.w600), ), if (showDivider) ...[ 12.sizeBoxH, @@ -79,7 +82,10 @@ class CommonAlert extends StatelessWidget { Text( content!, textAlign: TextAlign.center, - style: TextStyle(color: Colors.white.withValues(alpha: .5), fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + color: Colors.white.withValues(alpha: .5), + fontSize: 16, + fontWeight: FontWeight.w500), ), ], if (subContent?.isNotEmpty == true) ...[ @@ -89,7 +95,8 @@ class CommonAlert extends StatelessWidget { child: Text( subContent!, textAlign: TextAlign.center, - style: TextStyle(color: Colors.white.withValues(alpha: .5), fontSize: 16), + style: TextStyle( + color: Colors.white.withValues(alpha: .5), fontSize: 16), ), ), ], @@ -111,7 +118,10 @@ class CommonAlert extends StatelessWidget { ), child: Text( cancelText, - style: const TextStyle(color: Color(0xff989898), fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Color(0xff989898), + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), @@ -129,7 +139,10 @@ class CommonAlert extends StatelessWidget { ), child: Text( confirmText, - style: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w500), ), ), ), diff --git a/lib/tools_base/widget/follow_button.dart b/lib/tools_base/widget/follow_button.dart index 3da3088..5ef5f78 100644 --- a/lib/tools_base/widget/follow_button.dart +++ b/lib/tools_base/widget/follow_button.dart @@ -1,12 +1,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; import '../../assets_tool/app_colors.dart'; import '../../hj_utils/api_service/acg_service.dart'; import '../../hj_utils/api_service/mine_service.dart'; -import 'package:hgmj/tools_base/toast.dart'; +import 'package:wydj/tools_base/toast.dart'; import '../../hj_utils/widget_util.dart'; enum FollowEnum { @@ -64,7 +64,9 @@ class _FollowButtonState extends State { child: isLoading ? _loading() : Image.asset( - isFollow ? 'collect_red.png'.commonImgPath : 'collect_path.png'.commonImgPath, + isFollow + ? 'collect_red.png'.commonImgPath + : 'collect_path.png'.commonImgPath, width: 24, ), ); @@ -86,11 +88,17 @@ class _FollowButtonState extends State { ), child: Row( children: [ - isLoading ? _loading() : const Icon(Icons.check, size: 14, color: Color(0xff989898)), + isLoading + ? _loading() + : const Icon(Icons.check, + size: 14, color: Color(0xff989898)), 4.sizeBoxW, const Text( '关注', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.w500, color: Color(0xff989898)), + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + color: Color(0xff989898)), ), ], ), @@ -104,11 +112,17 @@ class _FollowButtonState extends State { ), child: Row( children: [ - isLoading ? _loading() : const Icon(Icons.add, size: 14, color: AppColors.actionRed), + isLoading + ? _loading() + : const Icon(Icons.add, + size: 14, color: AppColors.actionRed), 4.sizeBoxW, const Text( '关注', - style: TextStyle(fontSize: 10, fontWeight: FontWeight.w500, color: AppColors.actionRed), + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + color: AppColors.actionRed), ), ], ), @@ -132,20 +146,25 @@ class _FollowButtonState extends State { borderRadius: BorderRadius.circular(3), ), child: isFollow - ? Text('已收藏', style: textStyle(10, Colors.white, FontWeight.w400)) + ? Text('已收藏', + style: textStyle(10, Colors.white, FontWeight.w400)) : Row( mainAxisSize: MainAxisSize.min, children: [ - Image.asset('add_red.png'.commonImgPath, width: 16, color: Colors.black), + Image.asset('add_red.png'.commonImgPath, + width: 16, color: Colors.black), 2.sizeBoxW, - Text('收藏', style: textStyle(10, Colors.black, FontWeight.w400)), + Text('收藏', + style: + textStyle(10, Colors.black, FontWeight.w400)), ], ), ), ); } - Widget _loading() => const CupertinoActivityIndicator(color: Colors.white, radius: 8); + Widget _loading() => + const CupertinoActivityIndicator(color: Colors.white, radius: 8); //加入书架 / 取消收藏 void _onCollectTap() => isFollow ? _unCollect() : _collect(); @@ -153,7 +172,8 @@ class _FollowButtonState extends State { void _unCollect() async { if (isLoading) return; setState(() => isLoading = true); - if (await ACGService.deleteBookshelf(mediaId ?? '')) widget.onSuccess?.call(false); + if (await ACGService.deleteBookshelf(mediaId ?? '')) + widget.onSuccess?.call(false); isLoading = false; if (mounted) setState(() {}); } @@ -161,7 +181,8 @@ class _FollowButtonState extends State { void _collect() async { if (isLoading) return; setState(() => isLoading = true); - if (await ACGService.addBookshelf(mediaId ?? '')) widget.onSuccess?.call(true); + if (await ACGService.addBookshelf(mediaId ?? '')) + widget.onSuccess?.call(true); isLoading = false; if (mounted) setState(() {}); } diff --git a/lib/tools_base/widget/header_widget.dart b/lib/tools_base/widget/header_widget.dart index 0490547..d7dacdb 100644 --- a/lib/tools_base/widget/header_widget.dart +++ b/lib/tools_base/widget/header_widget.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; ///用户头像 class HeaderWidget extends StatelessWidget { @@ -27,7 +27,8 @@ class HeaderWidget extends StatelessWidget { height: headHeight, decoration: isCircle ? const BoxDecoration( - border: Border.fromBorderSide(BorderSide(width: 4, color: Color.fromRGBO(253, 45, 85, 1))), + border: Border.fromBorderSide( + BorderSide(width: 4, color: Color.fromRGBO(253, 45, 85, 1))), shape: BoxShape.circle, ) : null, diff --git a/lib/tools_base/widget/image_browser_page.dart b/lib/tools_base/widget/image_browser_page.dart index d2cf0e7..e735664 100644 --- a/lib/tools_base/widget/image_browser_page.dart +++ b/lib/tools_base/widget/image_browser_page.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hgmj/assets_tool/app_colors.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/image_util.dart'; -import 'package:hgmj/tools_base/cache/image_cache_manager.dart'; -import 'package:hgmj/tools_base/loading/loading_alert_widget.dart'; -import 'package:hgmj/tools_base/toast.dart'; -import 'package:hgmj/tools_base/widget/net_image_widget.dart'; +import 'package:wydj/assets_tool/app_colors.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/image_util.dart'; +import 'package:wydj/tools_base/cache/image_cache_manager.dart'; +import 'package:wydj/tools_base/loading/loading_alert_widget.dart'; +import 'package:wydj/tools_base/toast.dart'; +import 'package:wydj/tools_base/widget/net_image_widget.dart'; /// 微信风格图片浏览器 /// 横滑切图 + 双指/双击缩放 + 上下滑拖拽退出(图片跟手、背景随拖动渐隐露出下层页面) + 长按保存 @@ -20,18 +20,26 @@ class ImageBrowserPage extends StatefulWidget { final int initialIndex; final bool showSaveButton; // 右上角显式"保存到相册"按钮(AI 生成图等场景);默认只支持长按保存 - const ImageBrowserPage({super.key, required this.images, this.initialIndex = 0, this.showSaveButton = false}); + const ImageBrowserPage( + {super.key, + required this.images, + this.initialIndex = 0, + this.showSaveButton = false}); /// 打开浏览器(透明路由 + 淡入) /// [showSaveButton] 显示右上角"保存到相册"按钮 - static void open(List images, {int index = 0, bool showSaveButton = false}) { + static void open(List images, + {int index = 0, bool showSaveButton = false}) { final valid = images.where((e) => e.isNotEmpty).toList(); if (valid.isEmpty) return; // fullscreenDialog:true → GetX canTransitionTo 返回 false,下层页面不做外出转场, // 保持完整渲染 → 拖拽偷看时看到的是整页而非"pop 一半"。 // 瞬时 fadeIn:打开无残影。仍是 Get.to → Get.back 能正常 pop,下滑退出正常 Get.to( - () => ImageBrowserPage(images: valid, initialIndex: index.clamp(0, valid.length - 1), showSaveButton: showSaveButton), + () => ImageBrowserPage( + images: valid, + initialIndex: index.clamp(0, valid.length - 1), + showSaveButton: showSaveButton), opaque: false, transition: Transition.fadeIn, duration: Duration.zero, @@ -43,7 +51,8 @@ class ImageBrowserPage extends StatefulWidget { State createState() => _ImageBrowserPageState(); } -class _ImageBrowserPageState extends State with TickerProviderStateMixin { +class _ImageBrowserPageState extends State + with TickerProviderStateMixin { // ========== 分页 ========== late final PageController _pageCtr; late int _curIndex; @@ -72,11 +81,17 @@ class _ImageBrowserPageState extends State with TickerProvider super.initState(); _curIndex = widget.initialIndex; _pageCtr = PageController(initialPage: _curIndex); - _transCtrs = List.generate(widget.images.length, (_) => TransformationController()); - _resetCtr = AnimationController(vsync: this, duration: const Duration(milliseconds: 200)); - _zoomCtr = AnimationController(vsync: this, duration: const Duration(milliseconds: 200)); - _enterCtr = AnimationController(vsync: this, duration: const Duration(milliseconds: 220))..forward(); - _exitCtr = AnimationController(vsync: this, duration: const Duration(milliseconds: 200)); + _transCtrs = + List.generate(widget.images.length, (_) => TransformationController()); + _resetCtr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 200)); + _zoomCtr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 200)); + _enterCtr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 220)) + ..forward(); + _exitCtr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 200)); } @override @@ -97,10 +112,12 @@ class _ImageBrowserPageState extends State with TickerProvider bool get _isZoomed => _transCtrs[_curIndex].value.getMaxScaleOnAxis() > 1.05; // 背景不透明度:随竖直拖动距离渐隐(下拉偷看下层) - double get _bgOpacity => (1 - _dragY.abs() / (Get.height * 0.6)).clamp(0.0, 1.0); + double get _bgOpacity => + (1 - _dragY.abs() / (Get.height * 0.6)).clamp(0.0, 1.0); // 拖动时图片轻微缩小 - double get _dragScale => (1 - _dragY.abs() / (Get.height * 2)).clamp(0.85, 1.0); + double get _dragScale => + (1 - _dragY.abs() / (Get.height * 2)).clamp(0.85, 1.0); // 退出淡出系数:1→0 double get _exitFactor => 1 - _exitCtr.value; @@ -119,8 +136,8 @@ class _ImageBrowserPageState extends State with TickerProvider _exit(); return; } - final anim = - Tween(begin: _dragY, end: 0).animate(CurvedAnimation(parent: _resetCtr, curve: Curves.easeOut)); + final anim = Tween(begin: _dragY, end: 0) + .animate(CurvedAnimation(parent: _resetCtr, curve: Curves.easeOut)); void listener() => setState(() => _dragY = anim.value); anim.addListener(listener); // whenComplete 在 dispose 取消 ticker 时也会触发,一律先判 mounted @@ -156,8 +173,8 @@ class _ImageBrowserPageState extends State with TickerProvider -pos.dx * (scale - 1), -pos.dy * (scale - 1), 0, 1, // ); } - final anim = - Matrix4Tween(begin: ctr.value, end: target).animate(CurvedAnimation(parent: _zoomCtr, curve: Curves.easeOut)); + final anim = Matrix4Tween(begin: ctr.value, end: target) + .animate(CurvedAnimation(parent: _zoomCtr, curve: Curves.easeOut)); void listener() => ctr.value = anim.value; anim.addListener(listener); _zoomCtr.forward(from: 0).whenComplete(() { @@ -195,7 +212,10 @@ class _ImageBrowserPageState extends State with TickerProvider builder: (_, __) => Stack( children: [ // 黑色背景,随拖动/退出渐隐 - Positioned.fill(child: ColoredBox(color: Colors.black.withValues(alpha: _bgOpacity * _exitFactor))), + Positioned.fill( + child: ColoredBox( + color: Colors.black + .withValues(alpha: _bgOpacity * _exitFactor))), GestureDetector( onLongPress: _saveCurrent, // 长按保存 onDoubleTapDown: (d) => _tapPos = d.localPosition, @@ -209,7 +229,8 @@ class _ImageBrowserPageState extends State with TickerProvider opacity: _enterCtr, child: Transform.translate( offset: Offset(0, _dragY), - child: Transform.scale(scale: _dragScale, child: _pageView()), + child: + Transform.scale(scale: _dragScale, child: _pageView()), ), ), ), @@ -226,7 +247,9 @@ class _ImageBrowserPageState extends State with TickerProvider if (_isSaving) const Positioned.fill( child: AbsorbPointer( - child: ColoredBox(color: Color(0x80000000), child: LoadingAlertWidget(title: '保存中...')), + child: ColoredBox( + color: Color(0x80000000), + child: LoadingAlertWidget(title: '保存中...')), ), ), ], @@ -272,7 +295,8 @@ class _ImageBrowserPageState extends State with TickerProvider right: 20, child: Container( padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 2), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(20)), child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -287,7 +311,8 @@ class _ImageBrowserPageState extends State with TickerProvider : (isIncoming ? const Offset(0, -1) : const Offset(0, 1)); return ClipRect( child: SlideTransition( - position: Tween(begin: begin, end: Offset.zero).animate(anim), + position: Tween(begin: begin, end: Offset.zero) + .animate(anim), child: child, ), ); @@ -295,10 +320,12 @@ class _ImageBrowserPageState extends State with TickerProvider child: Text( '${_curIndex + 1}', key: ValueKey(_curIndex), - style: const TextStyle(color: AppColors.actionRed, fontSize: 12), + style: + const TextStyle(color: AppColors.actionRed, fontSize: 12), ), ), - Text('/${widget.images.length}', style: const TextStyle(color: Color(0xff3D3D3D), fontSize: 12)), + Text('/${widget.images.length}', + style: const TextStyle(color: Color(0xff3D3D3D), fontSize: 12)), ], ), ), @@ -331,8 +358,11 @@ class _ImageBrowserPageState extends State with TickerProvider onTap: _saveCurrent, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(4), color: const Color(0xFFE57310)), - child: const Text('保存到相册', style: TextStyle(color: Colors.white, fontSize: 14)), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: const Color(0xFFE57310)), + child: const Text('保存到相册', + style: TextStyle(color: Colors.white, fontSize: 14)), ), ), ), diff --git a/lib/tools_base/widget/like_burst_view.dart b/lib/tools_base/widget/like_burst_view.dart index 22f8f29..eb51e64 100644 --- a/lib/tools_base/widget/like_burst_view.dart +++ b/lib/tools_base/widget/like_burst_view.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; +import 'package:wydj/assets_tool/images.dart'; /// 双击点赞爱心动效的触发器。onDoubleTapDown 里 [markAt] 记落点,onDoubleTap 里 [burst] 放动画 class LikeBurstController extends ChangeNotifier { @@ -31,16 +31,19 @@ class LikeBurstView extends StatefulWidget { State createState() => _LikeBurstViewState(); } -class _LikeBurstViewState extends State with SingleTickerProviderStateMixin { +class _LikeBurstViewState extends State + with SingleTickerProviderStateMixin { late final AnimationController _ctr; Offset? _at; @override void initState() { super.initState(); - _ctr = AnimationController(vsync: this, duration: const Duration(milliseconds: 600)) + _ctr = AnimationController( + vsync: this, duration: const Duration(milliseconds: 600)) ..addStatusListener((status) { - if (status == AnimationStatus.completed && mounted) setState(() => _at = null); + if (status == AnimationStatus.completed && mounted) + setState(() => _at = null); }); widget.controller.addListener(_onBurst); } @@ -81,8 +84,10 @@ class _LikeBurstViewState extends State with SingleTickerProvider TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.0), weight: 40), ]).animate(_ctr), child: ScaleTransition( - scale: Tween(begin: 0.5, end: 1.3).animate(CurvedAnimation(parent: _ctr, curve: Curves.easeOutBack)), - child: Image.asset(widget.icon.commonImgPath, width: widget.size, height: widget.size), + scale: Tween(begin: 0.5, end: 1.3).animate( + CurvedAnimation(parent: _ctr, curve: Curves.easeOutBack)), + child: Image.asset(widget.icon.commonImgPath, + width: widget.size, height: widget.size), ), ), ), diff --git a/lib/tools_base/widget/net_image_widget.dart b/lib/tools_base/widget/net_image_widget.dart index aa18bb7..9d4b81b 100644 --- a/lib/tools_base/widget/net_image_widget.dart +++ b/lib/tools_base/widget/net_image_widget.dart @@ -2,9 +2,9 @@ import 'dart:ui'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'package:hgmj/assets_tool/images.dart'; -import 'package:hgmj/hj_utils/screen.dart'; -import 'package:hgmj/tools_base/cache/image_cache_manager.dart'; +import 'package:wydj/assets_tool/images.dart'; +import 'package:wydj/hj_utils/screen.dart'; +import 'package:wydj/tools_base/cache/image_cache_manager.dart'; class NetworkImageLoader extends StatelessWidget { final String? imageUrl; @@ -55,12 +55,15 @@ class NetworkImageLoader extends StatelessWidget { fadeOutCurve: Curves.linear, ); final radius = imgBorderRadius ?? BorderRadius.circular(borderRadius); - if (borderRadius != 0) image = ClipRRect(borderRadius: radius, child: image); + if (borderRadius != 0) + image = ClipRRect(borderRadius: radius, child: image); //模糊会溢出边界,外面再裁一层 if (blur) { image = ClipRRect( borderRadius: radius, - child: ImageFiltered(imageFilter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: image), + child: ImageFiltered( + imageFilter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: image), ); } return image; @@ -72,7 +75,9 @@ class NetworkImageLoader extends StatelessWidget { final dpr = screen.devicePixelRatio; if (!isResizeImage) return (screen.screenWidth * dpr).toInt(); //约束无限时用屏幕宽兜底,避免退化成按原图解码(图片过载) - final w = (cons.maxWidth == double.infinity || cons.maxWidth.isNaN) ? screen.screenWidth : cons.maxWidth; + final w = (cons.maxWidth == double.infinity || cons.maxWidth.isNaN) + ? screen.screenWidth + : cons.maxWidth; return (w * dpr).toInt(); } @@ -82,7 +87,8 @@ class NetworkImageLoader extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), decoration: const BoxDecoration(color: Color(0xff151E2D)), alignment: Alignment.center, - child: Image.asset('place_holder_logo.webp'.commonImgPath, width: 100, height: 35), + child: Image.asset('place_holder_logo.webp'.commonImgPath, + width: 100, height: 35), ); } } diff --git a/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart b/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart index 157a46e..fe4f215 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart @@ -8,15 +8,14 @@ import 'dart:math'; import 'package:collection/collection.dart' show IterableExtension; import 'package:flutter/scheduler.dart'; import 'package:flutter/widgets.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/item_positions_notifier.dart'; -import 'package:hgmj/tools_base/widget/scroll_positioned_list/src/scroll_offset_listener.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/item_positions_notifier.dart'; +import 'package:wydj/tools_base/widget/scroll_positioned_list/src/scroll_offset_listener.dart'; import 'positioned_list.dart'; import 'post_mount_callback.dart'; import 'scroll_offset_notifier.dart'; - /// Number of screens to scroll when scrolling a long distance. const int _screenScrollCount = 2; diff --git a/lib/track_event_manager/device_service.dart b/lib/track_event_manager/device_service.dart index ef4b511..b1e5b54 100644 --- a/lib/track_event_manager/device_service.dart +++ b/lib/track_event_manager/device_service.dart @@ -6,7 +6,7 @@ import 'package:device_identity/device_identity.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/services.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:hgmj/extension/extensions.dart'; +import 'package:wydj/extension/extensions.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -263,8 +263,8 @@ class DeviceInfoService { } catch (_) {} } if (_isInvalidId(raw)) raw = const Uuid().v4(); - // 业务规则:hgmj_ 前缀,去空格,限制 50 字符(日志系统约束) - return 'hgmj_${raw.replaceAll(' ', '')}'.limit(50); + // 业务规则:wydj_ 前缀,去空格,限制 50 字符(日志系统约束) + return 'wydj_${raw.replaceAll(' ', '')}'.limit(50); } /// 脏值检测:空 / 太短 / 全 0 / 已知脏值 diff --git a/lib/track_event_manager/track_session.dart b/lib/track_event_manager/track_session.dart index c8ae861..2bd54d8 100644 --- a/lib/track_event_manager/track_session.dart +++ b/lib/track_event_manager/track_session.dart @@ -1,5 +1,5 @@ -import 'package:hgmj/hj_utils/light_model.dart'; -import 'package:hgmj/hj_utils/store_keys.dart'; +import 'package:wydj/hj_utils/light_model.dart'; +import 'package:wydj/hj_utils/store_keys.dart'; import 'package:uuid/uuid.dart'; /// 会话管理器 - 生成并维护统一的会话 ID (sid) @@ -44,7 +44,8 @@ class TrackSessionManager { /// 调用时机:AppLifecycleState.paused / inactive / detached Future onAppPause() async { _backgroundedAt = DateTime.now(); - await lightKV.setInt(StoreKeys.TRACK_SESSION_BACKGROUND_TS, _backgroundedAt!.millisecondsSinceEpoch); + await lightKV.setInt(StoreKeys.TRACK_SESSION_BACKGROUND_TS, + _backgroundedAt!.millisecondsSinceEpoch); } /// App 回到前台:后台停留超时或会话本身超时都换新 sid(规则2、3) @@ -63,11 +64,15 @@ class TrackSessionManager { _sid = (await lightKV.getString(StoreKeys.TRACK_SESSION_SID)) ?? ''; //键名沿用历史的 LAST_EVENT_TS,存的是会话创建时间 - final sessionTs = await lightKV.getInt(StoreKeys.TRACK_SESSION_LAST_EVENT_TS); - if (sessionTs != null && sessionTs > 0) _sessionAt = DateTime.fromMillisecondsSinceEpoch(sessionTs); + final sessionTs = + await lightKV.getInt(StoreKeys.TRACK_SESSION_LAST_EVENT_TS); + if (sessionTs != null && sessionTs > 0) + _sessionAt = DateTime.fromMillisecondsSinceEpoch(sessionTs); - final backgroundTs = await lightKV.getInt(StoreKeys.TRACK_SESSION_BACKGROUND_TS); - if (backgroundTs != null && backgroundTs > 0) _backgroundedAt = DateTime.fromMillisecondsSinceEpoch(backgroundTs); + final backgroundTs = + await lightKV.getInt(StoreKeys.TRACK_SESSION_BACKGROUND_TS); + if (backgroundTs != null && backgroundTs > 0) + _backgroundedAt = DateTime.fromMillisecondsSinceEpoch(backgroundTs); if (_sid.isEmpty || _isExpired(_sessionAt)) _newSession(); _inited = true; @@ -84,6 +89,7 @@ class TrackSessionManager { _sid = Uuid().v4().replaceAll('-', ''); _sessionAt = DateTime.now(); lightKV.setString(StoreKeys.TRACK_SESSION_SID, _sid); - lightKV.setInt(StoreKeys.TRACK_SESSION_LAST_EVENT_TS, _sessionAt!.millisecondsSinceEpoch); + lightKV.setInt(StoreKeys.TRACK_SESSION_LAST_EVENT_TS, + _sessionAt!.millisecondsSinceEpoch); } } diff --git a/project.md b/project.md index c87cd94..dd8ab1f 100644 --- a/project.md +++ b/project.md @@ -80,7 +80,7 @@ DMP编码: #无则留空 项目目录结构: ``` -hgmj/ +wydj/ ├── lib/ │ ├── alert/ # 全局弹窗 │ ├── assets_tool/ # 颜色、图片、资源路径 @@ -142,9 +142,9 @@ hgmj/ ``` 常用:`sh build_apk.sh a`(Android release,arm64 单 ABI)、`sh build_apk.sh i release ad-hoc`(iOS 内测包)、`sh build_apk.sh all` -4. 产物命名(`APP_NAME` 取自 `pubspec.yaml` 的 `name`,即 `hgmj`): - - Android:`hgmj___.apk` - - iOS:`hgmj____.ipa`,如 `hgmj_release_adhoc_1.12.1_0806-0925.ipa` +4. 产物命名(`APP_NAME` 取自 `pubspec.yaml` 的 `name`,即 `wydj`): + - Android:`wydj___.apk` + - iOS:`wydj____.ipa`,如 `wydj_release_adhoc_1.12.1_0806-0925.ipa` 5. Android 发版前跑 VirusTotal 包毒检测 6. 上传到分发平台(落地页 / 蒲公英 / 自有 CDN),Telegram 告警群通知 diff --git a/pubspec.yaml b/pubspec.yaml index e936853..43e37e9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ #项目名称,必填字端 -name: hgmj +name: wydj #项目描述,非必填,若需要将项目托管在pub.dev则该字段必填 description: A new Flutter project. publish_to: "none" # Remove this line if you wish to publish to pub.dev diff --git a/test/widget_test.dart b/test/widget_test.dart index 6c5cf4f..b38feb0 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:hgmj/main.dart'; +import 'package:wydj/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async {