logo和名称替换

This commit is contained in:
谢宇宁
2026-10-14 11:23:36 +07:00
parent 1cb514cd02
commit c5c04a7967
478 changed files with 8990 additions and 4948 deletions
@@ -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
@@ -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,
),
@@ -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<CollectStatusModel>(_onCollectStatusChanged);
_collectStatusSub =
eventBus.on<CollectStatusModel>(_onCollectStatusChanged);
}
@override
@@ -91,7 +93,8 @@ class CommunityTabLogic extends GetxController {
sctrl.jumpTo(0);
}
Future<void> fetchPagedata({bool isRefresh = true, bool needLoading = false}) async {
Future<void> 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();
@@ -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),
),
],
),
@@ -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<MediaStyle> _tabTypes = [MediaStyle.Community, MediaStyle.Pic, MediaStyle.Novel];
static const List<MediaStyle> _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];
@@ -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<CommunityMainPage> with SingleTickerProviderStateMixin {
class CommunityMainPageState extends State<CommunityMainPage>
with SingleTickerProviderStateMixin {
@override
void initState() {
super.initState();
@@ -37,7 +38,8 @@ class CommunityMainPageState extends State<CommunityMainPage> 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<CommunityMainPage> 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<CommunityMainPage> with SingleTickerP
children: [
//社区
CommunityModulePage(
defaultIndex: widget.index == 0 ? widget.subTabIndex : 0,
defaultIndex:
widget.index == 0 ? widget.subTabIndex : 0,
).keepAlive,
//图集
CartoonSubModulePage(
@@ -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<bool> 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:最多观看
@@ -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<CommunityTagDetailPage> createState() => _CommunityTagDetailPageState();
}
class _CommunityTagDetailPageState extends State<CommunityTagDetailPage> with UniqueTagMixin {
class _CommunityTagDetailPageState extends State<CommunityTagDetailPage>
with UniqueTagMixin {
@override
Widget build(BuildContext context) {
return GetBuilder<CommunityTagLogic>(
@@ -44,7 +44,8 @@ class _CommunityTagDetailPageState extends State<CommunityTagDetailPage> 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<CommunityTagDetailPage> with Un
controller: controller.mainTabCtr,
children: controller.sorts
.map(
(e) => TagDetailSubView<TagCOVERController>(tag: controller.model, postSort: e).keepAlive,
(e) => TagDetailSubView<TagCOVERController>(
tag: controller.model, postSort: e)
.keepAlive,
)
.toList(),
),
@@ -98,7 +101,9 @@ class _CommunityTagDetailPageState extends State<CommunityTagDetailPage> 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<CommunityTagDetailPage> 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 ...[
@@ -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<CollectStatusModel>(_onCollectStatusChanged);
_collectStatusSub =
eventBus.on<CollectStatusModel>(_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<T>(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 没有对应类型';
@@ -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<T extends TagDetailSubController> extends StatelessWidget {
class TagDetailSubView<T extends TagDetailSubController>
extends StatelessWidget {
final TagsBean tag;
final int? postSort;
@@ -25,7 +26,8 @@ class TagDetailSubView<T extends TagDetailSubController> 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();
@@ -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<GroupBuyBottomSheet> {
Widget build(BuildContext context) {
return Consumer<GlobalStore>(
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<GroupBuyBottomSheet> {
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<GroupBuyBottomSheet> {
),
),
12.sizeBoxW,
InkWell(enableFeedback: false,
InkWell(
enableFeedback: false,
onTap: () => pushToWalletPage(tabPosition: 1),
child: Text(
'充值',
@@ -137,8 +140,13 @@ class _GroupBuyBottomSheetState extends State<GroupBuyBottomSheet> {
),
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),
),
),
),
@@ -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);
@@ -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';
@@ -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<ChatItemCell> {
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<ChatItemCell> {
),
),
if (isImg)
InkWell(enableFeedback: false,
InkWell(
enableFeedback: false,
onTap: () {
_showImageScan(widget.model?.image ?? "");
},
@@ -155,7 +157,8 @@ class _ChatItemCellState extends State<ChatItemCell> {
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<ChatItemCell> {
),
),
if (isImg)
InkWell(enableFeedback: false,
InkWell(
enableFeedback: false,
onTap: () {
_showImageScan(widget.model?.image ?? "");
},
@@ -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();
@@ -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,
),
],
@@ -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<ChatGroupCell> {
} 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<ChatGroupCell> {
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<ChatGroupCell> {
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<ChatGroupCell> {
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(
@@ -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<PostDetailVideoContent> {
@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<PostDetailVideoContent> {
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<PostDetailVideoContent> {
'你只需花费 $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<PostDetailVideoContent> {
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<PostDetailVideoContent> {
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;
}
}
@@ -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<PostDetailOperationView> createState() => _PostDetailOperationViewState();
State<PostDetailOperationView> createState() =>
_PostDetailOperationViewState();
}
class _PostDetailOperationViewState extends State<PostDetailOperationView> {
@@ -46,7 +47,9 @@ class _PostDetailOperationViewState extends State<PostDetailOperationView> {
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<PostDetailOperationView> {
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));
@@ -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),
),
],
),
@@ -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(),
@@ -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<PostResourceInfoWidget> {
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<PostResourceInfoWidget> {
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),
),
),
],
@@ -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';
@@ -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<VideoModel>? _filters(List<VideoModel>? videoModel) {
return (videoModel ?? []).where((e) => !e.isRandomAd() && !e.isAdsArr()).toList();
return (videoModel ?? [])
.where((e) => !e.isRandomAd() && !e.isAdsArr())
.toList();
}
class PostDetailPageArgument {
final List<VideoModel>? videoModels;
String? id;
PostDetailPageArgument({List<VideoModel>? models, this.id}) : videoModels = _filters(models);
PostDetailPageArgument({List<VideoModel>? 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<PostDetailPage> 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<PostDetailPage> 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<PostDetailPage> 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<PostDetailPage> 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<PostDetailPage> 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<PostDetailPage> 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)),
],
);
},
@@ -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';
@@ -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,
@@ -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<void> _submitPost(List<String> seriesCover, MediaInfo? mediaInfo) async {
Future<void> _submitPost(
List<String> 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';
@@ -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),
),
),
),
@@ -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<PublishLogic>();
@@ -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)
],
),
),
@@ -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),
);
}
}
@@ -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<CommunityMiddleHeader> createState() => _CommunityMiddleHeaderState();
}
class _CommunityMiddleHeaderState extends State<CommunityMiddleHeader> with SingleTickerProviderStateMixin {
class _CommunityMiddleHeaderState extends State<CommunityMiddleHeader>
with SingleTickerProviderStateMixin {
//别在这里另写一份标题
final sorts = CommunityTabLogic.sortTabs.map((e) => e.name).toList();
late final TabController _controller;
@@ -47,8 +48,15 @@ class _CommunityMiddleHeaderState extends State<CommunityMiddleHeader> 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,
),
@@ -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),
@@ -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<CommunitySortHeader> createState() => _CommunitySortHeaderState();
}
class _CommunitySortHeaderState extends State<CommunitySortHeader> with SingleTickerProviderStateMixin {
class _CommunitySortHeaderState extends State<CommunitySortHeader>
with SingleTickerProviderStateMixin {
final sorts = ['最多收藏', '最新上架', '最新热评'];
late TabController _controller;
@@ -27,7 +28,8 @@ class _CommunitySortHeaderState extends State<CommunitySortHeader> 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<CommunitySortHeader> 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,
@@ -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 {
@@ -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(
@@ -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<PostUserInfoView> {
builder: () => InkWell(
enableFeedback: false,
onTap: _toggleFollow,
child: FollowLoadingButton(isFollow: publisher?.hasFollowed ?? false, isLoading: _isLoading),
child: FollowLoadingButton(
isFollow: publisher?.hasFollowed ?? false,
isLoading: _isLoading),
),
),
],
@@ -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)),
),
);
}