mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-06-28 11:24:46 +08:00
[Party Room] 创建房间
This commit is contained in:
185
lib/ui/party_room/dialogs/party_room_create_dialog_ui.dart
Normal file
185
lib/ui/party_room/dialogs/party_room_create_dialog_ui.dart
Normal file
@ -0,0 +1,185 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:starcitizen_doctor/base/ui.dart';
|
||||
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
|
||||
|
||||
import 'party_room_create_dialog_ui_model.dart';
|
||||
|
||||
class PartyRoomCreateDialogUI extends BaseUI<PartyRoomCreateDialogUIModel> {
|
||||
@override
|
||||
Widget? buildBody(BuildContext context, PartyRoomCreateDialogUIModel model) {
|
||||
return ContentDialog(
|
||||
title: makeTitle(context, model),
|
||||
constraints:
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .6),
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 12),
|
||||
child: AnimatedSize(
|
||||
duration: const Duration(milliseconds: 130),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (model.userName == null) ...[
|
||||
SizedBox(
|
||||
height: 200,
|
||||
child: makeLoading(context),
|
||||
)
|
||||
] else ...[
|
||||
Row(
|
||||
children: [
|
||||
const Text("请选择一种玩法"),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: 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 (model.selectedRoomType != null &&
|
||||
(model.selectedRoomType?.subTypes.isNotEmpty ?? false))
|
||||
...makeSubTypeSelectWidgets(context, model),
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
children: [
|
||||
const Text("游戏用户名(自动获取)"),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextFormBox(
|
||||
initialValue: model.userName,
|
||||
enabled: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Row(
|
||||
children: [
|
||||
const Text("最大玩家数(2 ~ 32)"),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextFormBox(
|
||||
controller: model.playerMaxCtrl,
|
||||
onChanged: (_) => model.notifyListeners(),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly
|
||||
],
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const Text("公告(可选)"),
|
||||
const SizedBox(height: 12),
|
||||
TextFormBox(
|
||||
controller: model.announcementCtrl,
|
||||
maxLines: 5,
|
||||
placeholder: "可编写 任务简报,集合地点,船只要求,活动规则等,公告将会自动发送给进入房间的玩家。",
|
||||
placeholderStyle:
|
||||
TextStyle(color: Colors.white.withOpacity(.4)),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
for (var v in [
|
||||
"创建房间后,其他玩家可以在大厅首页看到您的房间和您选择的玩法,当一个玩家选择加入房间时,你们将可以互相看到对方的用户名。当房间人数达到最大玩家数时,将不再接受新的玩家加入。",
|
||||
"这是《SC汉化盒子》提供的公益服务,请勿滥用,我们保留拒绝服务的权力。"
|
||||
]) ...[
|
||||
Text(
|
||||
v,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.6)),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
if (model.isWorking)
|
||||
const ProgressRing()
|
||||
else
|
||||
FilledButton(
|
||||
onPressed: model.onSubmit(),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(3),
|
||||
child: Text("创建房间"),
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> makeSubTypeSelectWidgets(
|
||||
BuildContext context, PartyRoomCreateDialogUIModel model) {
|
||||
bool isItemSelected(RoomSubtype subtype) {
|
||||
return model.selectedSubType.contains(subtype);
|
||||
}
|
||||
|
||||
return [
|
||||
const SizedBox(height: 24),
|
||||
const Text("标签(可选)"),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
for (var item in model.selectedRoomType!.subTypes)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isItemSelected(item)
|
||||
? Colors.green
|
||||
: FluentTheme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(1000)),
|
||||
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 12),
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
child: IconButton(
|
||||
icon: Row(
|
||||
children: [
|
||||
Icon(isItemSelected(item)
|
||||
? FluentIcons.check_mark
|
||||
: FluentIcons.add),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
item.name,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: isItemSelected(item)
|
||||
? null
|
||||
: Colors.white.withOpacity(.4)),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () => model.onTapSubType(item)),
|
||||
)
|
||||
],
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
Widget makeTitle(BuildContext context, PartyRoomCreateDialogUIModel model) {
|
||||
return Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
FluentIcons.back,
|
||||
size: 22,
|
||||
),
|
||||
onPressed: model.onBack()),
|
||||
const SizedBox(width: 12),
|
||||
Text(getUITitle(context, model)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String getUITitle(BuildContext context, PartyRoomCreateDialogUIModel model) =>
|
||||
"创建房间";
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
import 'package:starcitizen_doctor/base/ui_model.dart';
|
||||
import 'package:starcitizen_doctor/common/conf.dart';
|
||||
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
|
||||
import 'package:starcitizen_doctor/global_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/grpc/party_room_server.dart';
|
||||
|
||||
class PartyRoomCreateDialogUIModel extends BaseUIModel {
|
||||
Map<String?, RoomType> roomTypes;
|
||||
|
||||
RoomType? selectedRoomType;
|
||||
|
||||
List<RoomSubtype> selectedSubType = [];
|
||||
|
||||
PartyRoomCreateDialogUIModel(this.roomTypes);
|
||||
|
||||
String? userName;
|
||||
|
||||
bool isWorking = false;
|
||||
|
||||
final playerMaxCtrl = TextEditingController(text: "8");
|
||||
final announcementCtrl = TextEditingController();
|
||||
|
||||
@override
|
||||
initModel() {
|
||||
super.initModel();
|
||||
roomTypes.removeWhere((key, value) => key == "");
|
||||
}
|
||||
|
||||
@override
|
||||
loadData() async {
|
||||
userName = await globalUIModel.getRunningGameUser();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
onBack() {
|
||||
if (isWorking) return null;
|
||||
return () {
|
||||
Navigator.pop(context!);
|
||||
};
|
||||
}
|
||||
|
||||
void onChangeRoomType(RoomType? value) {
|
||||
selectedSubType = [];
|
||||
selectedRoomType = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
onTapSubType(RoomSubtype item) {
|
||||
if (!selectedSubType.contains(item)) {
|
||||
selectedSubType.add(item);
|
||||
} else {
|
||||
selectedSubType.remove(item);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
final maxPlayer = int.tryParse(playerMaxCtrl.text) ?? 0;
|
||||
if (selectedRoomType == null) return null;
|
||||
if (maxPlayer < 2 || maxPlayer > 32) return null;
|
||||
return () async {
|
||||
isWorking = true;
|
||||
notifyListeners();
|
||||
final room = await handleError(() => PartyRoomGrpcServer.createRoom(
|
||||
RoomData(
|
||||
roomTypeID: selectedRoomType?.id,
|
||||
roomSubTypeIds: [for (var value in selectedSubType) value.id],
|
||||
owner: userName,
|
||||
deviceUUID: AppConf.deviceUUID,
|
||||
announcement: announcementCtrl.text.trim())));
|
||||
isWorking = false;
|
||||
notifyListeners();
|
||||
if (room != null) {
|
||||
Navigator.pop(context!, room);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -103,7 +103,7 @@ class PartyRoomHomeUI extends BaseUI<PartyRoomHomeUIModel> {
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () {},
|
||||
onPressed: () => model.onCreateRoom(),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(3),
|
||||
child: Row(
|
||||
|
@ -2,6 +2,9 @@ import 'package:fixnum/fixnum.dart';
|
||||
import 'package:starcitizen_doctor/base/ui_model.dart';
|
||||
import 'package:starcitizen_doctor/generated/grpc/party_room_server/index.pb.dart';
|
||||
import 'package:starcitizen_doctor/grpc/party_room_server.dart';
|
||||
import 'package:starcitizen_doctor/ui/party_room/dialogs/party_room_create_dialog_ui_model.dart';
|
||||
|
||||
import 'dialogs/party_room_create_dialog_ui.dart';
|
||||
|
||||
class PartyRoomHomeUIModel extends BaseUIModel {
|
||||
String? pingServerMessage;
|
||||
@ -33,7 +36,7 @@ class PartyRoomHomeUIModel extends BaseUIModel {
|
||||
|
||||
RoomSortType selectedSortType = RoomSortType.Default;
|
||||
|
||||
int pageNum = 1;
|
||||
int pageNum = 0;
|
||||
|
||||
List<RoomData>? rooms;
|
||||
|
||||
@ -48,17 +51,27 @@ class PartyRoomHomeUIModel extends BaseUIModel {
|
||||
if (pingServerMessage != "") {
|
||||
pingServerMessage = null;
|
||||
notifyListeners();
|
||||
await _pingServer();
|
||||
}
|
||||
await _pingServer();
|
||||
_loadPage();
|
||||
await _loadPage();
|
||||
}
|
||||
|
||||
@override
|
||||
reloadData() async {
|
||||
pageNum = 0;
|
||||
rooms = null;
|
||||
notifyListeners();
|
||||
return super.reloadData();
|
||||
}
|
||||
|
||||
_loadPage() async {
|
||||
final r = await PartyRoomGrpcServer.getRoomList(RoomListPageReqData(
|
||||
pageNum: Int64.tryParseInt("$pageNum"),
|
||||
typeID: selectedRoomType?.id,
|
||||
subTypeID: selectedRoomSubType?.id,
|
||||
status: selectedStatus));
|
||||
final r = await handleError(() => PartyRoomGrpcServer.getRoomList(
|
||||
RoomListPageReqData(
|
||||
pageNum: Int64.tryParseInt("$pageNum"),
|
||||
typeID: selectedRoomType?.id,
|
||||
subTypeID: selectedRoomSubType?.id,
|
||||
status: selectedStatus)));
|
||||
if (r == null) return;
|
||||
if (r.pageData.hasNext) {
|
||||
pageNum++;
|
||||
} else {
|
||||
@ -88,7 +101,7 @@ class PartyRoomHomeUIModel extends BaseUIModel {
|
||||
selectedRoomType =
|
||||
RoomType(id: "", name: "全部", desc: "查看所有类型的房间,寻找一起玩的伙伴。");
|
||||
selectedRoomSubType = RoomSubtype(id: "", name: "全部");
|
||||
roomTypes = {null: selectedRoomType!};
|
||||
roomTypes = {"": selectedRoomType!};
|
||||
for (var element in r.roomTypes) {
|
||||
roomTypes![element.id] = element;
|
||||
}
|
||||
@ -110,24 +123,42 @@ class PartyRoomHomeUIModel extends BaseUIModel {
|
||||
void onChangeRoomType(RoomType? value) {
|
||||
selectedRoomType = value;
|
||||
selectedRoomSubType = null;
|
||||
reloadData();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void onChangeRoomStatus(RoomStatus? value) {
|
||||
if (value == null) return;
|
||||
selectedStatus = value;
|
||||
reloadData();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void onChangeRoomSort(RoomSortType? value) {
|
||||
if (value == null) return;
|
||||
selectedSortType = value;
|
||||
reloadData();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void onChangeRoomSubType(RoomSubtype? value) {
|
||||
if (value == null) return;
|
||||
selectedRoomSubType = value;
|
||||
reloadData();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
onCreateRoom() async {
|
||||
final room = await showDialog(
|
||||
context: context!,
|
||||
dismissWithEsc: false,
|
||||
builder: (BuildContext context) {
|
||||
return BaseUIContainer(
|
||||
uiCreate: () => PartyRoomCreateDialogUI(),
|
||||
modelCreate: () =>
|
||||
PartyRoomCreateDialogUIModel(Map.from(roomTypes!)));
|
||||
},
|
||||
);
|
||||
dPrint(room);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user