[Party Room] 创建,列表展示

This commit is contained in:
xkeyC 2024-01-13 20:00:06 +08:00
parent fbdfd61c09
commit 839125528b
7 changed files with 203 additions and 9 deletions

View File

@ -518,6 +518,7 @@ class RoomData extends $pb.GeneratedMessage {
RoomStatus? status, RoomStatus? status,
$core.String? deviceUUID, $core.String? deviceUUID,
$core.String? announcement, $core.String? announcement,
$core.String? avatar,
}) { }) {
final $result = create(); final $result = create();
if (id != null) { if (id != null) {
@ -550,6 +551,9 @@ class RoomData extends $pb.GeneratedMessage {
if (announcement != null) { if (announcement != null) {
$result.announcement = announcement; $result.announcement = announcement;
} }
if (avatar != null) {
$result.avatar = avatar;
}
return $result; return $result;
} }
RoomData._() : super(); RoomData._() : super();
@ -567,6 +571,7 @@ class RoomData extends $pb.GeneratedMessage {
..e<RoomStatus>(8, _omitFieldNames ? '' : 'status', $pb.PbFieldType.OE, defaultOrMaker: RoomStatus.All, valueOf: RoomStatus.valueOf, enumValues: RoomStatus.values) ..e<RoomStatus>(8, _omitFieldNames ? '' : 'status', $pb.PbFieldType.OE, defaultOrMaker: RoomStatus.All, valueOf: RoomStatus.valueOf, enumValues: RoomStatus.values)
..aOS(9, _omitFieldNames ? '' : 'deviceUUID', protoName: 'deviceUUID') ..aOS(9, _omitFieldNames ? '' : 'deviceUUID', protoName: 'deviceUUID')
..aOS(10, _omitFieldNames ? '' : 'announcement') ..aOS(10, _omitFieldNames ? '' : 'announcement')
..aOS(11, _omitFieldNames ? '' : 'avatar')
..hasRequiredFields = false ..hasRequiredFields = false
; ;
@ -674,6 +679,15 @@ class RoomData extends $pb.GeneratedMessage {
$core.bool hasAnnouncement() => $_has(9); $core.bool hasAnnouncement() => $_has(9);
@$pb.TagNumber(10) @$pb.TagNumber(10)
void clearAnnouncement() => clearField(10); void clearAnnouncement() => clearField(10);
@$pb.TagNumber(11)
$core.String get avatar => $_getSZ(10);
@$pb.TagNumber(11)
set avatar($core.String v) { $_setString(10, v); }
@$pb.TagNumber(11)
$core.bool hasAvatar() => $_has(10);
@$pb.TagNumber(11)
void clearAvatar() => clearField(11);
} }
class RoomListPageReqData extends $pb.GeneratedMessage { class RoomListPageReqData extends $pb.GeneratedMessage {

View File

@ -164,6 +164,7 @@ const RoomData$json = {
{'1': 'status', '3': 8, '4': 1, '5': 14, '6': '.RoomStatus', '10': 'status'}, {'1': 'status', '3': 8, '4': 1, '5': 14, '6': '.RoomStatus', '10': 'status'},
{'1': 'deviceUUID', '3': 9, '4': 1, '5': 9, '10': 'deviceUUID'}, {'1': 'deviceUUID', '3': 9, '4': 1, '5': 9, '10': 'deviceUUID'},
{'1': 'announcement', '3': 10, '4': 1, '5': 9, '10': 'announcement'}, {'1': 'announcement', '3': 10, '4': 1, '5': 9, '10': 'announcement'},
{'1': 'avatar', '3': 11, '4': 1, '5': 9, '10': 'avatar'},
], ],
}; };
@ -174,7 +175,8 @@ final $typed_data.Uint8List roomDataDescriptor = $convert.base64Decode(
'KAlSBW93bmVyEhwKCW1heFBsYXllchgFIAEoBVIJbWF4UGxheWVyEh4KCmNyZWF0ZVRpbWUYBi' 'KAlSBW93bmVyEhwKCW1heFBsYXllchgFIAEoBVIJbWF4UGxheWVyEh4KCmNyZWF0ZVRpbWUYBi'
'ABKANSCmNyZWF0ZVRpbWUSHAoJY3VyUGxheWVyGAcgASgFUgljdXJQbGF5ZXISIwoGc3RhdHVz' 'ABKANSCmNyZWF0ZVRpbWUSHAoJY3VyUGxheWVyGAcgASgFUgljdXJQbGF5ZXISIwoGc3RhdHVz'
'GAggASgOMgsuUm9vbVN0YXR1c1IGc3RhdHVzEh4KCmRldmljZVVVSUQYCSABKAlSCmRldmljZV' 'GAggASgOMgsuUm9vbVN0YXR1c1IGc3RhdHVzEh4KCmRldmljZVVVSUQYCSABKAlSCmRldmljZV'
'VVSUQSIgoMYW5ub3VuY2VtZW50GAogASgJUgxhbm5vdW5jZW1lbnQ='); 'VVSUQSIgoMYW5ub3VuY2VtZW50GAogASgJUgxhbm5vdW5jZW1lbnQSFgoGYXZhdGFyGAsgASgJ'
'UgZhdmF0YXI=');
@$core.Deprecated('Use roomListPageReqDataDescriptor instead') @$core.Deprecated('Use roomListPageReqDataDescriptor instead')
const RoomListPageReqData$json = { const RoomListPageReqData$json = {

View File

@ -31,7 +31,7 @@ class PartyRoomGrpcServer {
return await _indexService.getRoomList(req); return await _indexService.getRoomList(req);
} }
static Future createRoom(RoomData roomData) async { static Future<RoomData> createRoom(RoomData roomData) async {
await _indexService.createRoom(roomData); return await _indexService.createRoom(roomData);
} }
} }

View File

@ -1,3 +1,6 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:starcitizen_doctor/base/ui.dart'; import 'package:starcitizen_doctor/base/ui.dart';
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart'; import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
@ -119,6 +122,15 @@ class PartyRoomCreateDialogUI extends BaseUI<PartyRoomCreateDialogUIModel> {
); );
} }
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));
}
List<Widget> makeSubTypeSelectWidgets( List<Widget> makeSubTypeSelectWidgets(
BuildContext context, PartyRoomCreateDialogUIModel model) { BuildContext context, PartyRoomCreateDialogUIModel model) {
bool isItemSelected(RoomSubtype subtype) { bool isItemSelected(RoomSubtype subtype) {
@ -135,7 +147,7 @@ class PartyRoomCreateDialogUI extends BaseUI<PartyRoomCreateDialogUIModel> {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isItemSelected(item) color: isItemSelected(item)
? Colors.green ? generateColorFromSeed(item.name).withOpacity(.4)
: FluentTheme.of(context).cardColor, : FluentTheme.of(context).cardColor,
borderRadius: BorderRadius.circular(1000)), borderRadius: BorderRadius.circular(1000)),
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 12),

View File

@ -67,6 +67,7 @@ class PartyRoomCreateDialogUIModel extends BaseUIModel {
roomSubTypeIds: [for (var value in selectedSubType) value.id], roomSubTypeIds: [for (var value in selectedSubType) value.id],
owner: userName, owner: userName,
deviceUUID: AppConf.deviceUUID, deviceUUID: AppConf.deviceUUID,
maxPlayer: maxPlayer,
announcement: announcementCtrl.text.trim()))); announcement: announcementCtrl.text.trim())));
isWorking = false; isWorking = false;
notifyListeners(); notifyListeners();

View File

@ -1,5 +1,12 @@
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';
import 'package:starcitizen_doctor/base/ui.dart'; import 'package:starcitizen_doctor/base/ui.dart';
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart'; import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
import 'package:starcitizen_doctor/widgets/cache_image.dart';
import 'party_room_home_ui_model.dart'; import 'party_room_home_ui_model.dart';
@ -22,8 +29,160 @@ class PartyRoomHomeUI extends BaseUI<PartyRoomHomeUIModel> {
const Expanded( const Expanded(
child: Center( child: Center(
child: Text("没有符合条件的房间!"), child: Text("没有符合条件的房间!"),
)), ))
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) {
final item = model.rooms![index];
final itemType = model.roomTypes?[item.roomTypeID];
final itemSubTypes = {
for (var t in itemType?.subTypes ?? <RoomSubtype>[]) t.id: t
};
return 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: 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]}")),
], ],
),
const SizedBox(height: 6),
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
makeItemRow("房主:", item.owner),
makeItemRow(
"当前人数:", "${item.curPlayer}"),
makeItemRow(
"最大人数:", "${item.maxPlayer}"),
],
),
),
ClipRRect(
borderRadius: BorderRadius.circular(1000),
child: CacheNetImage(
url: item.avatar,
width: 64,
height: 64,
),
),
],
),
const SizedBox(height: 12),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (var value in item.roomSubTypeIds)
makeSubTypeTag(
value, model, itemSubTypes),
],
),
)
],
),
),
),
),
),
);
},
),
),
),
],
);
}
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,
),
),
],
),
); );
} }
@ -95,7 +254,7 @@ class PartyRoomHomeUI extends BaseUI<PartyRoomHomeUIModel> {
onChanged: model.onChangeRoomSort)), onChanged: model.onChangeRoomSort)),
const Spacer(), const Spacer(),
Button( Button(
onPressed: () {}, onPressed: model.onRefreshRoom,
child: const Padding( child: const Padding(
padding: EdgeInsets.all(6), padding: EdgeInsets.all(6),
child: Icon(FluentIcons.refresh), child: Icon(FluentIcons.refresh),

View File

@ -68,8 +68,8 @@ class PartyRoomHomeUIModel extends BaseUIModel {
final r = await handleError(() => PartyRoomGrpcServer.getRoomList( final r = await handleError(() => PartyRoomGrpcServer.getRoomList(
RoomListPageReqData( RoomListPageReqData(
pageNum: Int64.tryParseInt("$pageNum"), pageNum: Int64.tryParseInt("$pageNum"),
typeID: selectedRoomType?.id, typeID: selectedRoomType?.id ?? "",
subTypeID: selectedRoomSubType?.id, subTypeID: selectedRoomSubType?.id ?? "",
status: selectedStatus))); status: selectedStatus)));
if (r == null) return; if (r == null) return;
if (r.pageData.hasNext) { if (r.pageData.hasNext) {
@ -115,7 +115,7 @@ class PartyRoomHomeUIModel extends BaseUIModel {
types[element.id] = element; types[element.id] = element;
} }
if (types.isEmpty) return null; if (types.isEmpty) return null;
final allSubType = RoomSubtype(id: "all", name: "全部"); final allSubType = RoomSubtype(id: "", name: "全部");
selectedRoomSubType ??= allSubType; selectedRoomSubType ??= allSubType;
return {"all": allSubType}..addAll(types); return {"all": allSubType}..addAll(types);
} }
@ -159,6 +159,12 @@ class PartyRoomHomeUIModel extends BaseUIModel {
PartyRoomCreateDialogUIModel(Map.from(roomTypes!))); PartyRoomCreateDialogUIModel(Map.from(roomTypes!)));
}, },
); );
if (room == null) return;
dPrint(room); dPrint(room);
reloadData();
}
onRefreshRoom() {
reloadData();
} }
} }