app/lib/ui/party_room/party_room_home_ui.dart

358 lines
12 KiB
Dart
Raw Normal View History

2024-01-13 20:00:06 +08:00
import 'dart:convert';
import 'dart:math';
import 'dart:ui';
import 'package:extended_image/extended_image.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
2024-01-14 20:47:15 +08:00
import 'package:flutter_tilt/flutter_tilt.dart';
2024-01-07 14:57:49 +08:00
import 'package:starcitizen_doctor/base/ui.dart';
2024-01-07 18:52:06 +08:00
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
2024-01-13 20:00:06 +08:00
import 'package:starcitizen_doctor/widgets/cache_image.dart';
2024-01-30 21:45:51 +08:00
import 'package:url_launcher/url_launcher_string.dart';
2024-01-07 14:57:49 +08:00
import 'party_room_home_ui_model.dart';
class PartyRoomHomeUI extends BaseUI<PartyRoomHomeUIModel> {
2024-01-14 20:47:15 +08:00
@override
void initState() {
Future.delayed(const Duration(milliseconds: 16)).then((_) {
ref.watch(provider).checkUIInit();
});
super.initState();
}
@override
Widget build(BuildContext context) {
2024-01-29 20:37:15 +08:00
// final model = ref.watch(provider);
2024-01-30 21:45:51 +08:00
return Center(
2024-01-29 20:37:15 +08:00
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
2024-01-30 21:45:51 +08:00
const Text(
"联机大厅,敬请期待 ",
style: TextStyle(fontSize: 20),
),
const SizedBox(height: 12),
GestureDetector(
onTap: () {
launchUrlString("https://wj.qq.com/s2/14112124/f4c8/");
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text("诚邀您参与 "),
Text(
"问卷调查。",
style: TextStyle(
color: Colors.blue,
),
)
],
),
),
2024-01-29 20:37:15 +08:00
],
),
2024-01-14 20:47:15 +08:00
);
2024-01-29 20:37:15 +08:00
// return PageView(
// controller: model.pageCtrl,
// physics: const NeverScrollableScrollPhysics(),
// children: [
// super.build(context),
// BaseUIContainer(
// uiCreate: () => PartyRoomChatUI(),
// modelCreate: () =>
// model.getChildUIModelProviders<PartyRoomChatUIModel>("chat"))
// ],
// );
2024-01-14 20:47:15 +08:00
}
2024-01-07 14:57:49 +08:00
@override
Widget? buildBody(BuildContext context, PartyRoomHomeUIModel model) {
if (model.pingServerMessage == null) return makeLoading(context);
if (model.pingServerMessage!.isNotEmpty) {
return Center(
child: Text("${model.pingServerMessage}"),
);
}
2024-01-07 18:52:06 +08:00
if (model.roomTypes == null) return makeLoading(context);
return Column(
children: [
makeHeader(context, model),
2024-01-13 13:54:32 +08:00
if (model.rooms == null)
Expanded(child: makeLoading(context))
else if (model.rooms!.isEmpty)
const Expanded(
child: Center(
child: Text("没有符合条件的房间!"),
2024-01-13 20:00:06 +08:00
))
else
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 24, right: 24),
child: AlignedGridView.count(
crossAxisCount: 3,
mainAxisSpacing: 24,
crossAxisSpacing: 24,
itemCount: model.rooms!.length,
itemBuilder: (context, index) {
2024-01-14 20:47:15 +08:00
return makeRoomItemWidget(context, model, index);
},
),
),
),
],
);
}
Widget makeRoomItemWidget(
BuildContext context,
PartyRoomHomeUIModel model,
int index,
) {
final item = model.rooms![index];
final itemType = model.roomTypes?[item.roomTypeID];
final itemSubTypes = {
for (var t in itemType?.subTypes ?? <RoomSubtype>[]) t.id: t
};
final createTime =
DateTime.fromMillisecondsSinceEpoch(item.createTime.toInt());
return Tilt(
borderRadius: BorderRadius.circular(13),
2024-01-29 20:37:15 +08:00
clipBehavior: Clip.hardEdge,
2024-01-14 20:47:15 +08:00
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(13),
image: DecorationImage(
image: ExtendedNetworkImageProvider(item.avatar, cache: true),
fit: BoxFit.cover)),
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(.4),
borderRadius: BorderRadius.circular(13),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(13),
clipBehavior: Clip.hardEdge,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: Padding(
padding: const EdgeInsets.only(
left: 16, right: 16, top: 12, bottom: 12),
child: GestureDetector(
onTap: () => model.onTapRoom(item),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
"${itemType?.name ?? item.roomTypeID}房间",
style: const TextStyle(fontSize: 20),
),
const SizedBox(width: 16),
Container(
padding: const EdgeInsets.only(
top: 3, bottom: 3, left: 12, right: 12),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(1000)),
child: Text("${model.roomStatus[item.status]}")),
],
2024-01-13 20:00:06 +08:00
),
2024-01-14 20:47:15 +08:00
const SizedBox(height: 6),
Row(
children: [
Expanded(
2024-01-13 20:00:06 +08:00
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2024-01-14 20:47:15 +08:00
makeItemRow("房主:", item.owner),
makeItemRow("玩家数量:",
"${item.curPlayer} / ${item.maxPlayer}"),
makeItemRow("创建时间:", "${createTime.toLocal()}"),
2024-01-13 20:00:06 +08:00
],
),
),
2024-01-14 20:47:15 +08:00
ClipRRect(
borderRadius: BorderRadius.circular(1000),
child: CacheNetImage(
url: item.avatar,
width: 64,
height: 64,
),
),
],
2024-01-13 20:00:06 +08:00
),
2024-01-14 20:47:15 +08:00
const SizedBox(height: 12),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (var value in item.roomSubTypeIds)
makeSubTypeTag(value, model, itemSubTypes),
],
),
)
],
),
),
2024-01-13 20:00:06 +08:00
),
),
),
2024-01-14 20:47:15 +08:00
),
),
2024-01-07 18:52:06 +08:00
);
}
2024-01-13 20:00:06 +08:00
Widget makeSubTypeTag(String id, PartyRoomHomeUIModel model,
Map<String, RoomSubtype> itemSubTypes) {
final name = itemSubTypes[id]?.name ?? id;
final color = generateColorFromSeed(name).withOpacity(.6);
return Container(
padding: const EdgeInsets.only(left: 12, right: 12, top: 5, bottom: 5),
margin: const EdgeInsets.only(right: 6),
decoration:
BoxDecoration(color: color, borderRadius: BorderRadius.circular(12)),
child: Text(
name,
style: const TextStyle(fontSize: 13),
),
);
}
Color generateColorFromSeed(String seed) {
int hash = utf8
.encode(seed)
.fold(0, (previousValue, element) => 31 * previousValue + element);
Random random = Random(hash);
return Color.fromARGB(
255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
Widget makeItemRow(String title, String value) {
return Padding(
padding: const EdgeInsets.only(top: 1, bottom: 1),
child: Row(
children: [
Text(
title,
style: TextStyle(color: Colors.white.withOpacity(.6)),
),
const SizedBox(width: 12),
Expanded(
child: Text(
value,
),
),
],
),
);
}
2024-01-07 18:52:06 +08:00
Widget makeHeader(BuildContext context, PartyRoomHomeUIModel model) {
final subTypes = model.getCurRoomSubTypes();
return Container(
padding: const EdgeInsets.only(left: 24, right: 24, top: 16, bottom: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Text("房间类型:"),
SizedBox(
height: 36,
child: ComboBox<RoomType>(
value: model.selectedRoomType,
items: [
for (final t in model.roomTypes!.entries)
ComboBoxItem(
value: t.value,
child: Text(t.value.name),
)
],
onChanged: model.onChangeRoomType)),
if (subTypes != null) ...[
const SizedBox(width: 24),
const Text("子类型:"),
SizedBox(
height: 36,
child: ComboBox<RoomSubtype>(
value: model.selectedRoomSubType,
items: [
for (final t in subTypes.entries)
ComboBoxItem(
value: t.value,
child: Text(t.value.name),
)
],
onChanged: model.onChangeRoomSubType)),
],
const SizedBox(width: 24),
const Text("房间状态:"),
SizedBox(
height: 36,
child: ComboBox<RoomStatus>(
value: model.selectedStatus,
items: [
for (final t in model.roomStatus.entries)
ComboBoxItem(
value: t.key,
child: Text(t.value),
)
],
onChanged: model.onChangeRoomStatus)),
const SizedBox(width: 24),
const Text("排序:"),
SizedBox(
height: 36,
child: ComboBox<RoomSortType>(
value: model.selectedSortType,
items: [
for (final t in model.roomSorts.entries)
ComboBoxItem(
value: t.key,
child: Text(t.value),
)
],
onChanged: model.onChangeRoomSort)),
const Spacer(),
Button(
2024-01-13 20:00:06 +08:00
onPressed: model.onRefreshRoom,
2024-01-07 18:52:06 +08:00
child: const Padding(
padding: EdgeInsets.all(6),
child: Icon(FluentIcons.refresh),
),
),
const SizedBox(width: 12),
Button(
2024-01-13 17:29:41 +08:00
onPressed: () => model.onCreateRoom(),
2024-01-07 18:52:06 +08:00
child: const Padding(
padding: EdgeInsets.all(3),
child: Row(
children: [
Icon(FluentIcons.add),
SizedBox(width: 6),
Text("创建房间")
],
),
),
),
],
),
const SizedBox(
height: 6,
),
Text(
model.selectedRoomType?.desc ?? "",
style: TextStyle(fontSize: 13, color: Colors.white.withOpacity(.4)),
),
],
),
2024-01-07 14:57:49 +08:00
);
}
@override
String getUITitle(BuildContext context, PartyRoomHomeUIModel model) =>
"PartyRoom";
}