logo和名称替换
This commit is contained in:
@@ -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<DramaTipBubble> createState() => _DramaTipBubbleState();
|
||||
}
|
||||
|
||||
class _DramaTipBubbleState extends State<DramaTipBubble> with SingleTickerProviderStateMixin {
|
||||
class _DramaTipBubbleState extends State<DramaTipBubble>
|
||||
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<DramaTipBubble> 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),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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<ModuleData> 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<HomeMainLogic>(tag: tag) ? Get.find<HomeMainLogic>(tag: tag) : null;
|
||||
Get.isRegistered<HomeMainLogic>(tag: tag)
|
||||
? Get.find<HomeMainLogic>(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<CartoonSubModuleLogic>(tag: tag)) {
|
||||
Get.find<CartoonSubModuleLogic>(tag: tag).skipToTabIndex(module.module);
|
||||
Get.find<CartoonSubModuleLogic>(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;
|
||||
|
||||
@@ -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<MainPage> 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<MainPage> 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(),
|
||||
// 社区
|
||||
|
||||
@@ -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<HomeBottomProvider>(index, cur);
|
||||
if (Config.darkWebEnable && index == 2) return _scrollTopItem<DarkwebBottomProvider>(index, cur);
|
||||
if (index == logic.communityTab) return _scrollTopItem<CommunityBottomProvider>(index, cur);
|
||||
if (index == 0)
|
||||
return _scrollTopItem<HomeBottomProvider>(index, cur);
|
||||
if (Config.darkWebEnable && index == 2)
|
||||
return _scrollTopItem<DarkwebBottomProvider>(index, cur);
|
||||
if (index == logic.communityTab)
|
||||
return _scrollTopItem<CommunityBottomProvider>(index, cur);
|
||||
return _normalItem(index, cur);
|
||||
}),
|
||||
),
|
||||
@@ -69,9 +73,13 @@ class MainPageTabbar extends StatelessWidget {
|
||||
final isSelected = index == cur;
|
||||
return Consumer<T>(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),
|
||||
|
||||
@@ -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}) {}
|
||||
}
|
||||
|
||||
@@ -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<int> tick = ValueNotifier<int>(0); //分层倒计时秒级 tick,倒计时块用 ValueListenableBuilder 监听它,避免每秒重建整卡/图片
|
||||
static String get _payPopupShownKey =>
|
||||
"PayLayeredPopup_shown_${globalStore.meInfo?.uid}"; // 支付分层首弹是否已弹过
|
||||
final ValueNotifier<int> tick = ValueNotifier<int>(
|
||||
0); //分层倒计时秒级 tick,倒计时块用 ValueListenableBuilder 监听它,避免每秒重建整卡/图片
|
||||
Timer? _payTimer; //支付分层倒计时(基于 config.lastDiscountTime)
|
||||
int? _lastExpireRefreshAt; //上次"归零刷新"的时间戳(秒),用于 30s 防抖
|
||||
|
||||
/// 刷新用户分层弹窗配置(payTier),成功后写回并通知 UI 刷新
|
||||
Future<PayTierModel?> 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<bool> isPayPopupShown() async => await lightKV.getBool(_payPopupShownKey) ?? false;
|
||||
static Future<bool> isPayPopupShown() async =>
|
||||
await lightKV.getBool(_payPopupShownKey) ?? false;
|
||||
|
||||
static Future<void> markPayPopupShown() async => await lightKV.setBool(_payPopupShownKey, true);
|
||||
static Future<void> 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 重启/不重启计时
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user