Skip to content

Commit caa44f3

Browse files
committed
Add page switch system
1 parent 9f7709b commit caa44f3

File tree

6 files changed

+239
-4
lines changed

6 files changed

+239
-4
lines changed

api/lib/src/models/data.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class QuokkaData extends ArchiveData<QuokkaData> {
4747
utf8.encode(table.toJson()),
4848
);
4949

50+
Iterable<String> getTables() => getAssets(kGameTablePath, true);
51+
5052
FileMetadata? getMetadata() {
5153
final data = getAsset(kPackMetadataPath);
5254
if (data == null) {

app/lib/bloc/world/bloc.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ class WorldBloc extends Bloc<PlayableWorldEvent, ClientWorldState> {
8181
switchCellOnMove: event.value,
8282
));
8383
});
84+
on<TableSwitched>((event, emit) {
85+
emit(state.copyWith(
86+
table: state.data.getTableOrDefault(event.name),
87+
tableName: event.name,
88+
data: state.data.setTable(state.table, state.tableName),
89+
));
90+
});
8491
}
8592

8693
Future<void> save() async {

app/lib/bloc/world/local.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,10 @@ final class SwitchCellOnMoveChanged extends LocalWorldEvent
4242

4343
SwitchCellOnMoveChanged(this.value);
4444
}
45+
46+
@MappableClass()
47+
final class TableSwitched extends LocalWorldEvent with TableSwitchedMappable {
48+
final String name;
49+
50+
TableSwitched([this.name = '']);
51+
}

app/lib/bloc/world/local.mapper.dart

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,118 @@ class _SwitchCellOnMoveChangedCopyWithImpl<$R, $Out>
493493
$chain<$R2, $Out2>(Then<$Out2, $R2> t) =>
494494
_SwitchCellOnMoveChangedCopyWithImpl($value, $cast, t);
495495
}
496+
497+
class TableSwitchedMapper extends SubClassMapperBase<TableSwitched> {
498+
TableSwitchedMapper._();
499+
500+
static TableSwitchedMapper? _instance;
501+
static TableSwitchedMapper ensureInitialized() {
502+
if (_instance == null) {
503+
MapperContainer.globals.use(_instance = TableSwitchedMapper._());
504+
LocalWorldEventMapper.ensureInitialized().addSubMapper(_instance!);
505+
}
506+
return _instance!;
507+
}
508+
509+
@override
510+
final String id = 'TableSwitched';
511+
512+
static String _$name(TableSwitched v) => v.name;
513+
static const Field<TableSwitched, String> _f$name =
514+
Field('name', _$name, opt: true, def: '');
515+
516+
@override
517+
final MappableFields<TableSwitched> fields = const {
518+
#name: _f$name,
519+
};
520+
521+
@override
522+
final String discriminatorKey = 'type';
523+
@override
524+
final dynamic discriminatorValue = 'TableSwitched';
525+
@override
526+
late final ClassMapperBase superMapper =
527+
LocalWorldEventMapper.ensureInitialized();
528+
529+
static TableSwitched _instantiate(DecodingData data) {
530+
return TableSwitched(data.dec(_f$name));
531+
}
532+
533+
@override
534+
final Function instantiate = _instantiate;
535+
536+
static TableSwitched fromMap(Map<String, dynamic> map) {
537+
return ensureInitialized().decodeMap<TableSwitched>(map);
538+
}
539+
540+
static TableSwitched fromJson(String json) {
541+
return ensureInitialized().decodeJson<TableSwitched>(json);
542+
}
543+
}
544+
545+
mixin TableSwitchedMappable {
546+
String toJson() {
547+
return TableSwitchedMapper.ensureInitialized()
548+
.encodeJson<TableSwitched>(this as TableSwitched);
549+
}
550+
551+
Map<String, dynamic> toMap() {
552+
return TableSwitchedMapper.ensureInitialized()
553+
.encodeMap<TableSwitched>(this as TableSwitched);
554+
}
555+
556+
TableSwitchedCopyWith<TableSwitched, TableSwitched, TableSwitched>
557+
get copyWith => _TableSwitchedCopyWithImpl(
558+
this as TableSwitched, $identity, $identity);
559+
@override
560+
String toString() {
561+
return TableSwitchedMapper.ensureInitialized()
562+
.stringifyValue(this as TableSwitched);
563+
}
564+
565+
@override
566+
bool operator ==(Object other) {
567+
return TableSwitchedMapper.ensureInitialized()
568+
.equalsValue(this as TableSwitched, other);
569+
}
570+
571+
@override
572+
int get hashCode {
573+
return TableSwitchedMapper.ensureInitialized()
574+
.hashValue(this as TableSwitched);
575+
}
576+
}
577+
578+
extension TableSwitchedValueCopy<$R, $Out>
579+
on ObjectCopyWith<$R, TableSwitched, $Out> {
580+
TableSwitchedCopyWith<$R, TableSwitched, $Out> get $asTableSwitched =>
581+
$base.as((v, t, t2) => _TableSwitchedCopyWithImpl(v, t, t2));
582+
}
583+
584+
abstract class TableSwitchedCopyWith<$R, $In extends TableSwitched, $Out>
585+
implements LocalWorldEventCopyWith<$R, $In, $Out> {
586+
@override
587+
$R call({String? name});
588+
TableSwitchedCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
589+
}
590+
591+
class _TableSwitchedCopyWithImpl<$R, $Out>
592+
extends ClassCopyWithBase<$R, TableSwitched, $Out>
593+
implements TableSwitchedCopyWith<$R, TableSwitched, $Out> {
594+
_TableSwitchedCopyWithImpl(super.value, super.then, super.then2);
595+
596+
@override
597+
late final ClassMapperBase<TableSwitched> $mapper =
598+
TableSwitchedMapper.ensureInitialized();
599+
@override
600+
$R call({String? name}) =>
601+
$apply(FieldCopyWithData({if (name != null) #name: name}));
602+
@override
603+
TableSwitched $make(CopyWithData data) =>
604+
TableSwitched(data.get(#name, or: $value.name));
605+
606+
@override
607+
TableSwitchedCopyWith<$R2, TableSwitched, $Out2> $chain<$R2, $Out2>(
608+
Then<$Out2, $R2> t) =>
609+
_TableSwitchedCopyWithImpl($value, $cast, t);
610+
}

app/lib/l10n/app_en.arb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,8 @@
142142
"switchCellOnMove": "Switch cell on move",
143143
"addPack": "Add pack",
144144
"removePack": "Remove pack",
145-
"noTemplates": "There are no templates available"
145+
"noTemplates": "There are no templates available",
146+
"table": "Table",
147+
"defaultTable": "Default table",
148+
"switchTable": "Switch table"
146149
}

app/lib/pages/game/drawer.dart

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,108 @@ class GameDrawer extends StatelessWidget {
133133
);
134134
},
135135
),
136+
BlocBuilder<WorldBloc, ClientWorldState>(
137+
buildWhen: (previous, current) =>
138+
previous.tableName != current.tableName,
139+
builder: (context, state) {
140+
final bloc = context.read<WorldBloc>();
141+
return ListTile(
142+
leading: const Icon(PhosphorIconsLight.gridFour),
143+
title: Text(AppLocalizations.of(context).table),
144+
subtitle: Text(state.tableName.isEmpty
145+
? AppLocalizations.of(context).defaultTable
146+
: state.tableName),
147+
onTap: () => showLeapBottomSheet(
148+
context: context,
149+
titleBuilder: (context) =>
150+
Text(AppLocalizations.of(context).table),
151+
actionsBuilder: (context) => [
152+
IconButton(
153+
icon: const Icon(
154+
PhosphorIconsLight.arrowsLeftRight),
155+
tooltip:
156+
AppLocalizations.of(context).switchTable,
157+
onPressed: () async {
158+
String name = '';
159+
final result = await showDialog<bool>(
160+
context: context,
161+
builder: (context) => AlertDialog(
162+
title: Text(AppLocalizations.of(context)
163+
.switchTable),
164+
content: TextField(
165+
decoration: InputDecoration(
166+
labelText:
167+
AppLocalizations.of(context).name,
168+
hintText: AppLocalizations.of(context)
169+
.enterName,
170+
filled: true,
171+
),
172+
onChanged: (value) => name = value,
173+
onSubmitted: (value) =>
174+
Navigator.of(context).pop(true),
175+
autofocus: true,
176+
),
177+
actions: [
178+
TextButton.icon(
179+
onPressed: () =>
180+
Navigator.of(context).pop(false),
181+
label: Text(
182+
AppLocalizations.of(context)
183+
.cancel),
184+
icon: const Icon(
185+
PhosphorIconsLight.prohibit),
186+
),
187+
ElevatedButton.icon(
188+
onPressed: () =>
189+
Navigator.of(context).pop(true),
190+
label: Text(
191+
AppLocalizations.of(context)
192+
.change),
193+
icon: const Icon(
194+
PhosphorIconsLight.check),
195+
),
196+
],
197+
),
198+
);
199+
if (!(result ?? false)) return;
200+
bloc.process(TableSwitched(name));
201+
},
202+
),
203+
],
204+
childrenBuilder: (context) => [
205+
BlocBuilder<WorldBloc, WorldState>(
206+
bloc: bloc,
207+
buildWhen: (previous, current) =>
208+
previous.tableName != current.tableName ||
209+
previous.data != current.data,
210+
builder: (context, state) {
211+
final other = {
212+
...state.data.getTables(),
213+
state.tableName
214+
}.where((e) => e.isNotEmpty).toList();
215+
return Column(
216+
children: [
217+
ListTile(
218+
title: Text(AppLocalizations.of(context)
219+
.defaultTable),
220+
selected: state.tableName == '',
221+
onTap: () =>
222+
bloc.process(TableSwitched()),
223+
),
224+
if (other.isNotEmpty) const Divider(),
225+
...other.map((e) => ListTile(
226+
title: Text(e),
227+
selected: state.tableName == e,
228+
onTap: () =>
229+
bloc.process(TableSwitched(e)),
230+
)),
231+
],
232+
);
233+
},
234+
)
235+
]));
236+
},
237+
),
136238
BlocBuilder<WorldBloc, ClientWorldState>(
137239
buildWhen: (previous, current) =>
138240
previous.table.background != current.table.background,
@@ -292,6 +394,7 @@ class GameDrawer extends StatelessWidget {
292394
content: TextField(
293395
decoration: InputDecoration(
294396
labelText: AppLocalizations.of(context).name,
397+
hintText: AppLocalizations.of(context).enterName,
295398
filled: true,
296399
),
297400
onChanged: (value) => name = value,
@@ -304,9 +407,7 @@ class GameDrawer extends StatelessWidget {
304407
child: Text(AppLocalizations.of(context).cancel),
305408
),
306409
ElevatedButton(
307-
onPressed: () {
308-
Navigator.of(context).pop(true);
309-
},
410+
onPressed: () => Navigator.of(context).pop(true),
310411
child: Text(AppLocalizations.of(context).save),
311412
),
312413
],

0 commit comments

Comments
 (0)