opt: 消息页面增加骨架屏

This commit is contained in:
guozhigq
2024-06-08 04:09:00 +08:00
parent 976f0c7bec
commit 01783b70ed

View File

@ -1,6 +1,7 @@
import 'package:easy_debounce/easy_throttle.dart'; import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/skeleton/skeleton.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
@ -102,134 +103,83 @@ class _WhisperPageState extends State<WhisperPage> {
}, },
child: SingleChildScrollView( child: SingleChildScrollView(
controller: _scrollController, controller: _scrollController,
child: Column( child: FutureBuilder(
children: [ future: _futureBuilderFuture,
FutureBuilder( builder: (context, snapshot) {
future: _futureBuilderFuture, if (snapshot.connectionState == ConnectionState.done) {
builder: (context, snapshot) { Map? data = snapshot.data;
if (snapshot.connectionState == ConnectionState.done) { if (data != null && data['status']) {
Map? data = snapshot.data; RxList sessionList = _whisperController.sessionList;
if (data != null && data['status']) { return Obx(
RxList sessionList = _whisperController.sessionList; () => sessionList.isEmpty
return Obx( ? const SizedBox()
() => sessionList.isEmpty : ListView.separated(
? const SizedBox() itemCount: sessionList.length,
: ListView.separated( shrinkWrap: true,
itemCount: sessionList.length, physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, itemBuilder: (_, int i) {
physics: return SessionItem(
const NeverScrollableScrollPhysics(), sessionItem: sessionList[i],
itemBuilder: (_, int i) { changeFucCall: () =>
return ListTile( sessionList.refresh(),
onTap: () { );
sessionList[i].unreadCount = 0; },
sessionList.refresh(); separatorBuilder:
Get.toNamed( (BuildContext context, int index) {
'/whisperDetail', return Divider(
parameters: { indent: 72,
'talkerId': sessionList[i] endIndent: 20,
.talkerId height: 6,
.toString(), color: Colors.grey.withOpacity(0.1),
'name': sessionList[i] );
.accountInfo },
.name, ),
'face': sessionList[i] );
.accountInfo } else {
.face, // 请求错误
'mid': sessionList[i] return Center(
.accountInfo child: Text(data?['msg'] ?? '请求异常'),
.mid );
.toString(), }
}, } else {
); // 骨架屏
}, return ListView.builder(
leading: Badge( itemCount: 15,
isLabelVisible: shrinkWrap: true,
sessionList[i].unreadCount > 0, physics: const NeverScrollableScrollPhysics(),
label: Text(sessionList[i] itemBuilder: (context, int i) {
.unreadCount return Skeleton(
.toString()), child: ListTile(
alignment: Alignment.topRight, leading: Container(
child: NetworkImgLayer( width: 45,
width: 45, height: 45,
height: 45, decoration: BoxDecoration(
type: 'avatar', color: Theme.of(context)
src: sessionList[i] .colorScheme
.accountInfo .onInverseSurface,
.face, borderRadius: BorderRadius.circular(25),
), ),
), ),
title: Text( title: Container(
sessionList[i].accountInfo.name), width: 100,
subtitle: Text( height: 14,
sessionList[i].lastMsg.content != color: Theme.of(context)
null && .colorScheme
sessionList[i] .onInverseSurface,
.lastMsg ),
.content != subtitle: Container(
'' width: 80,
? (sessionList[i] height: 14,
.lastMsg color: Theme.of(context)
.content['text'] ?? .colorScheme
sessionList[i] .onInverseSurface,
.lastMsg ),
.content['content'] ?? ),
sessionList[i] );
.lastMsg },
.content['title'] ?? );
sessionList[i] }
.lastMsg },
.content[
'reply_content'] ??
'不支持的消息类型')
: '不支持的消息类型',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context)
.textTheme
.labelMedium!
.copyWith(
color: Theme.of(context)
.colorScheme
.outline)),
trailing: Text(
Utils.dateFormat(sessionList[i]
.lastMsg
.timestamp),
style: Theme.of(context)
.textTheme
.labelSmall!
.copyWith(
color: Theme.of(context)
.colorScheme
.outline),
),
);
},
separatorBuilder:
(BuildContext context, int index) {
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withOpacity(0.1),
);
},
),
);
} else {
// 请求错误
return Center(
child: Text(data?['msg'] ?? '请求异常'),
);
}
} else {
// 骨架屏
return const SizedBox();
}
},
)
],
), ),
), ),
), ),
@ -239,3 +189,67 @@ class _WhisperPageState extends State<WhisperPage> {
); );
} }
} }
class SessionItem extends StatelessWidget {
final dynamic sessionItem;
final Function changeFucCall;
const SessionItem({
super.key,
required this.sessionItem,
required this.changeFucCall,
});
@override
Widget build(BuildContext context) {
final content = sessionItem.lastMsg.content;
return ListTile(
onTap: () {
sessionItem.unreadCount = 0;
changeFucCall.call();
Get.toNamed(
'/whisperDetail',
parameters: {
'talkerId': sessionItem.talkerId.toString(),
'name': sessionItem.accountInfo.name,
'face': sessionItem.accountInfo.face,
'mid': sessionItem.accountInfo.mid.toString(),
},
);
},
leading: Badge(
isLabelVisible: sessionItem.unreadCount > 0,
label: Text(sessionItem.unreadCount.toString()),
alignment: Alignment.topRight,
child: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
src: sessionItem.accountInfo.face,
),
),
title: Text(sessionItem.accountInfo.name),
subtitle: Text(
content != null && content != ''
? (content['text'] ??
content['content'] ??
content['title'] ??
content['reply_content'] ??
'不支持的消息类型')
: '不支持的消息类型',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context)
.textTheme
.labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline)),
trailing: Text(
Utils.dateFormat(sessionItem.lastMsg.timestamp),
style: Theme.of(context)
.textTheme
.labelSmall!
.copyWith(color: Theme.of(context).colorScheme.outline),
),
);
}
}