初始化
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../hj_utils/api_service/mine_service.dart';
|
||||
|
||||
class MessageCenterLogic extends GetxController with GetTickerProviderStateMixin {
|
||||
MessageCenterLogic get to => Get.find<MessageCenterLogic>();
|
||||
|
||||
late TabController tabController = TabController(length: titleArr.length, vsync: this);
|
||||
|
||||
List<String> titleArr = ['评论', '点赞'];
|
||||
|
||||
void getUnReadNum() async {
|
||||
await MineService.getUnreadNum();
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/tools_base/widget/keep_alive_widget.dart';
|
||||
|
||||
import 'message_center_logic.dart';
|
||||
import 'message_center_sub_page.dart';
|
||||
|
||||
class MessageCenterPage extends StatelessWidget {
|
||||
const MessageCenterPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
'消息中心',
|
||||
style: TextStyle(
|
||||
color: Color(0xE5FFFFFF),
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
)),
|
||||
body: GetBuilder<MessageCenterLogic>(
|
||||
init: MessageCenterLogic(),
|
||||
builder: (logic) {
|
||||
return Column(
|
||||
children: [
|
||||
TabBar(
|
||||
isScrollable: true,
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withValues(alpha: .9),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
unselectedLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withValues(alpha: .45),
|
||||
),
|
||||
indicator: BoxDecoration(),
|
||||
tabAlignment: TabAlignment.start,
|
||||
controller: logic.tabController,
|
||||
labelPadding: EdgeInsets.symmetric(horizontal: 0),
|
||||
tabs: logic.titleArr
|
||||
.map((it) => Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
margin: EdgeInsets.symmetric(vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: it == logic.titleArr.first
|
||||
? Colors.transparent
|
||||
: Color(0x1AFFFFFF),
|
||||
width: 1)),
|
||||
),
|
||||
child: Text(it),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
controller: logic.tabController,
|
||||
children: logic.titleArr
|
||||
.asMap()
|
||||
.map((key, value) => MapEntry(
|
||||
key,
|
||||
MessageCenterSubPage(MessageType.values[key])
|
||||
.keepAlive))
|
||||
.values
|
||||
.toList()),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/hj_utils/api_service/mine_service.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
|
||||
import 'message_center_sub_page.dart';
|
||||
import 'widget/message_items.dart';
|
||||
|
||||
abstract class MessageCenterSubLogic extends GetxController {
|
||||
final dataSource = [];
|
||||
int page = 1;
|
||||
bool isLoading = true;
|
||||
|
||||
RefreshController? refreshController;
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
fetchPageData();
|
||||
}
|
||||
|
||||
@mustCallSuper
|
||||
fetchPageData({bool isRefresh = true, bool showLoading = false}) {
|
||||
if (isRefresh) {
|
||||
page = 1;
|
||||
}
|
||||
if (showLoading) {
|
||||
isLoading = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
Widget instanceChildItem(int index);
|
||||
}
|
||||
|
||||
//评论
|
||||
class MessageCommentLogic extends MessageCenterSubLogic {
|
||||
@override
|
||||
Widget instanceChildItem(int index) {
|
||||
return MessageCommentItem(dataSource[index]);
|
||||
}
|
||||
|
||||
@override
|
||||
fetchPageData({bool isRefresh = true, bool showLoading = false}) async {
|
||||
super.fetchPageData(isRefresh: isRefresh, showLoading: showLoading);
|
||||
final res = await MineService.getDynamicList(pageNumber: page, msgType: 2);
|
||||
isLoading = false;
|
||||
if (isRefresh) {
|
||||
dataSource.clear();
|
||||
refreshController?.refreshCompleted();
|
||||
}
|
||||
res?.hasNext ?? false
|
||||
? refreshController?.loadComplete()
|
||||
: refreshController?.loadNoData();
|
||||
dataSource.addAll(res?.list ?? []);
|
||||
page += 1;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
//点赞
|
||||
class MessageThumbUpLogic extends MessageCenterSubLogic {
|
||||
@override
|
||||
fetchPageData({bool isRefresh = true, bool showLoading = false}) async {
|
||||
super.fetchPageData(isRefresh: isRefresh, showLoading: showLoading);
|
||||
final res = await MineService.getDynamicList(pageNumber: page, msgType: 1);
|
||||
isLoading = false;
|
||||
if (isRefresh) {
|
||||
dataSource.clear();
|
||||
refreshController?.refreshCompleted();
|
||||
}
|
||||
res?.hasNext ?? false
|
||||
? refreshController?.loadComplete()
|
||||
: refreshController?.loadNoData();
|
||||
dataSource.addAll(res?.list ?? []);
|
||||
page += 1;
|
||||
update();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget instanceChildItem(int index) {
|
||||
return MessageThumbItem(dataSource[index]);
|
||||
}
|
||||
}
|
||||
|
||||
MessageCenterSubLogic instanceController(MessageType type) {
|
||||
switch (type) {
|
||||
case MessageType.comment:
|
||||
return MessageCommentLogic();
|
||||
case MessageType.thumb:
|
||||
return MessageThumbUpLogic();
|
||||
default:
|
||||
throw '未知的类型${type}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
|
||||
import 'package:hgdj/tools_base/refresh/pull_refresh.dart';
|
||||
|
||||
import '../../../main.dart';
|
||||
import 'message_center_sub_controller.dart';
|
||||
|
||||
enum MessageType {
|
||||
comment(1), //评论
|
||||
thumb(2); //点赞
|
||||
|
||||
final int type;
|
||||
const MessageType(this.type);
|
||||
}
|
||||
|
||||
class MessageCenterSubPage extends StatefulWidget {
|
||||
final MessageType type;
|
||||
const MessageCenterSubPage(this.type, {super.key});
|
||||
|
||||
@override
|
||||
State<MessageCenterSubPage> createState() => _MessageCenterSubPageState();
|
||||
}
|
||||
|
||||
class _MessageCenterSubPageState extends State<MessageCenterSubPage>
|
||||
with RouteAware {
|
||||
late MessageCenterSubLogic logic;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
logic = instanceController(widget.type);
|
||||
}
|
||||
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
routeObserver.subscribe(this, ModalRoute.of(context)!);
|
||||
}
|
||||
|
||||
@override
|
||||
void didPopNext() {
|
||||
super.didPopNext();
|
||||
}
|
||||
|
||||
@override
|
||||
dispose() {
|
||||
super.dispose();
|
||||
routeObserver.unsubscribe(this);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MessageCenterSubLogic>(
|
||||
init: logic,
|
||||
global: false,
|
||||
builder: (controller) => pullYsRefresh(
|
||||
onLoading: (_) => controller.fetchPageData(isRefresh: false),
|
||||
onRefresh: (_) => controller.fetchPageData(),
|
||||
onInit: (_) => controller.refreshController = _,
|
||||
child: () {
|
||||
if (controller.isLoading) return LoadingCenterWidget();
|
||||
if (controller.dataSource.isEmpty) return CErrorWidget();
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.only(left: 16, right: 16, top: 12),
|
||||
itemCount: controller.dataSource.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return controller.instanceChildItem(index);
|
||||
},
|
||||
);
|
||||
}()),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
class UnReadMsgNumModel {
|
||||
UnReadMsgNumModel({
|
||||
this.dtCount,
|
||||
this.incomeCount,
|
||||
this.msgCount,
|
||||
});
|
||||
|
||||
UnReadMsgNumModel.fromJson(dynamic json) {
|
||||
dtCount = json['dtCount'];
|
||||
incomeCount = json['incomeCount'];
|
||||
msgCount = json['msgCount'];
|
||||
}
|
||||
num? dtCount;
|
||||
num? incomeCount;
|
||||
num? msgCount;
|
||||
UnReadMsgNumModel copyWith({
|
||||
num? dtCount,
|
||||
num? incomeCount,
|
||||
num? msgCount,
|
||||
}) =>
|
||||
UnReadMsgNumModel(
|
||||
dtCount: dtCount ?? this.dtCount,
|
||||
incomeCount: incomeCount ?? this.incomeCount,
|
||||
msgCount: msgCount ?? this.msgCount,
|
||||
);
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['dtCount'] = dtCount;
|
||||
map['incomeCount'] = incomeCount;
|
||||
map['msgCount'] = msgCount;
|
||||
return map;
|
||||
}
|
||||
|
||||
num get allNum => (dtCount ?? 0) + (incomeCount ?? 0) + (msgCount ?? 0);
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/extension/extensions.dart';
|
||||
import 'package:hgdj/hj_model/message/message_dynamic_list.dart';
|
||||
import 'package:hgdj/hj_page/user_center_page/user_center_page.dart';
|
||||
import 'package:hgdj/hj_utils/date_time_util.dart';
|
||||
import 'package:hgdj/hj_utils/screen.dart';
|
||||
import 'package:hgdj/tools_base/widget/net_image_widget.dart';
|
||||
|
||||
import '../../../community/post_detail_page/post_detail_page.dart';
|
||||
|
||||
/// 点赞
|
||||
class MessageThumbItem extends StatelessWidget {
|
||||
final MessageDynamicList model;
|
||||
const MessageThumbItem(this.model, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => Get.to(() => PostDetailPage(
|
||||
argument: PostDetailPageArgument(id: model.objId, models: []))),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
margin: EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0x0DFFFFFF),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"#$lTypeText",
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Text(
|
||||
model.createdAt.utcToYMD(),
|
||||
style: TextStyle(
|
||||
color: Color(0xE5FFFFFF),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
7.sizeBoxH,
|
||||
Text(
|
||||
'${model.objName}',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Color(0x8CFFFFFF),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
6.sizeBoxH,
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"${model.likeCount}人为你点赞",
|
||||
style: TextStyle(
|
||||
color: Color(0x59FFFFFF),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String get lTypeText {
|
||||
// video:对帖子点赞 comment:对评论点赞
|
||||
switch (model.msgType) {
|
||||
case 'like_msg':
|
||||
return '帖子点赞';
|
||||
case 'like_comment_msg':
|
||||
return '评论点赞';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessageCommentItem extends StatelessWidget {
|
||||
final MessageDynamicList model;
|
||||
|
||||
const MessageCommentItem(this.model, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () => Get.to(() => PostDetailPage(
|
||||
argument: PostDetailPageArgument(id: model.objId, models: []))),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 12),
|
||||
margin: EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0x0DFFFFFF),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () =>
|
||||
Get.to(() => UserCenterPage(uid: model.sendUid ?? 0)),
|
||||
child: NetworkImageLoader(
|
||||
imageUrl: model.sendAvatar ?? '',
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
),
|
||||
),
|
||||
12.sizeBoxW,
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
model.sendName ?? '',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
DateTimeUtil.utc2iso(model.createdAt),
|
||||
style: TextStyle(
|
||||
color: Color(0xFF989898),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
11.sizeBoxH,
|
||||
Text(
|
||||
model.content ?? '',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: Color(0xFF989898),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
8.sizeBoxW,
|
||||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
height: 82,
|
||||
child: NetworkImageLoader(
|
||||
imageUrl: model.objCover ?? '',
|
||||
height: 60,
|
||||
width: 60,
|
||||
borderRadius: 6,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user