logo和名称替换
This commit is contained in:
@@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -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<int?> 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<int?> showVipLevelDialog(
|
||||
),
|
||||
),
|
||||
24.sizeBoxH,
|
||||
InkWell(enableFeedback: false,
|
||||
InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () {
|
||||
if (vipEvent != null) {
|
||||
vipEvent.call();
|
||||
|
||||
@@ -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<AppCenterDialog> {
|
||||
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<AppCenterDialog> {
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
)
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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<UpdateDialog> {
|
||||
//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<UpdateDialog> {
|
||||
|
||||
///下载 apk(仅 Android,iOS 走商店)
|
||||
Future<void> _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) {
|
||||
|
||||
@@ -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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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<BuyVipAlert> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ComicBuyAlert> {
|
||||
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<ComicBuyAlert> {
|
||||
//支付按钮:余额不足直接去充值
|
||||
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<ComicBuyAlert> {
|
||||
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,
|
||||
|
||||
@@ -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<ShareMediaDialog> {
|
||||
//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<ShareMediaDialog> {
|
||||
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<ShareMediaDialog> {
|
||||
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<ShareMediaDialog> {
|
||||
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<ShareMediaDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
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<ShareMediaDialog> {
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(fontSize: 16, color: textColor, fontWeight: FontWeight.w500),
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: textColor, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -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<VideoBuyBottomSheet> {
|
||||
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<VideoBuyBottomSheet> {
|
||||
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<VideoBuyBottomSheet> {
|
||||
//我的金币余额 + 充值入口
|
||||
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<VideoBuyBottomSheet> {
|
||||
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<VideoBuyBottomSheet> {
|
||||
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<VideoBuyBottomSheet> {
|
||||
];
|
||||
}
|
||||
|
||||
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<VideoBuyBottomSheet> {
|
||||
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<VideoBuyBottomSheet> {
|
||||
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,
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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<VipProductModel?> 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));
|
||||
}
|
||||
|
||||
@@ -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<VipProductModel>? onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡)
|
||||
final ValueChanged<VipProductModel>?
|
||||
onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡)
|
||||
final PaySourcePage sourcePage;
|
||||
final String cover; // 场景下发的主图,相对路径由 ImageCacheManager 拼域名
|
||||
const GuideCountdownDialog({
|
||||
@@ -47,7 +48,9 @@ class GuideCountdownDialog extends StatelessWidget {
|
||||
|
||||
/// [scene] 决定主图/卡/下单来源,调用方须先用开关判过能弹
|
||||
/// 返回 true = 点了「立即开通」(点X/点蒙层/没弹成都是 false),返回挽留场景据此决定要不要放行返回
|
||||
static Future<bool> show({required GuideScene scene, ValueChanged<VipProductModel>? onConfirm}) async {
|
||||
static Future<bool> show(
|
||||
{required GuideScene scene,
|
||||
ValueChanged<VipProductModel>? onConfirm}) async {
|
||||
final card = await loadGuideCard(scene);
|
||||
if (card == null) return false; // 配置有误不弹
|
||||
final confirmed = await Get.dialog<bool>(
|
||||
@@ -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<Duration>(
|
||||
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)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<GuideHomeDialog> {
|
||||
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<GuideHomeDialog> {
|
||||
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<GuideHomeDialog> {
|
||||
right: 0,
|
||||
child: ValueListenableBuilder<int>(
|
||||
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<GuideHomeDialog> {
|
||||
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<GuideHomeDialog> {
|
||||
),
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user