Skip to content

Commit e81a4b3

Browse files
committed
Finish deck editor page
1 parent a757e29 commit e81a4b3

File tree

6 files changed

+324
-7
lines changed

6 files changed

+324
-7
lines changed

app/lib/l10n/app_en.arb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,5 +222,8 @@
222222
"textures": "Textures",
223223
"texture": "Texture",
224224
"notSet": "Not set",
225-
"category": "Category"
225+
"category": "Category",
226+
"figure": "Figure",
227+
"variation": "Variation",
228+
"position": "Position"
226229
}

app/lib/pages/editor/decks.dart

Lines changed: 315 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
44
import 'package:material_leap/material_leap.dart';
55
import 'package:phosphor_flutter/phosphor_flutter.dart';
66
import 'package:setonix/bloc/editor.dart';
7+
import 'package:setonix/helpers/vector.dart';
78
import 'package:setonix_api/setonix_api.dart';
89

910
class DecksEditorPage extends StatelessWidget {
@@ -146,8 +147,126 @@ class _DeckEditorDialogState extends State<DeckEditorDialog> {
146147
),
147148
],
148149
),
149-
SizedBox(),
150-
SizedBox(),
150+
Stack(
151+
children: [
152+
ListView.builder(
153+
itemCount: value.figures.length,
154+
itemBuilder: (context, index) {
155+
final figure = value.figures[index];
156+
return ListTile(
157+
title: Text(figure.name),
158+
onTap: () async {
159+
final bloc = context.read<EditorCubit>();
160+
final result =
161+
await showDialog<FigureDeckDefinition>(
162+
context: context,
163+
builder: (context) => BlocProvider.value(
164+
value: bloc,
165+
child: _DeckFigureEditorDialog(
166+
value: figure,
167+
),
168+
),
169+
);
170+
if (result == null) return;
171+
setState(() {
172+
value.figures[index] = result;
173+
});
174+
},
175+
trailing: IconButton(
176+
icon: const Icon(PhosphorIconsLight.trash),
177+
onPressed: () {
178+
setState(() {
179+
value.figures.removeAt(index);
180+
});
181+
},
182+
),
183+
);
184+
},
185+
),
186+
Align(
187+
alignment: Alignment.bottomCenter,
188+
child: FloatingActionButton.extended(
189+
onPressed: () async {
190+
final bloc = context.read<EditorCubit>();
191+
final result =
192+
await showDialog<FigureDeckDefinition>(
193+
context: context,
194+
builder: (context) => BlocProvider.value(
195+
value: bloc,
196+
child: _DeckFigureEditorDialog(),
197+
),
198+
);
199+
if (result == null) return;
200+
setState(() {
201+
value.figures.add(result);
202+
});
203+
},
204+
icon: const Icon(PhosphorIconsLight.plus),
205+
label: Text(AppLocalizations.of(context).create),
206+
),
207+
),
208+
],
209+
),
210+
Stack(
211+
children: [
212+
ListView.builder(
213+
itemCount: value.boards.length,
214+
itemBuilder: (context, index) {
215+
final board = value.boards[index];
216+
return ListTile(
217+
title: Text(board.name),
218+
onTap: () async {
219+
final bloc = context.read<EditorCubit>();
220+
final result =
221+
await showDialog<BoardDeckDefinition>(
222+
context: context,
223+
builder: (context) => BlocProvider.value(
224+
value: bloc,
225+
child: _DeckBoardEditorDialog(
226+
value: board,
227+
),
228+
),
229+
);
230+
if (result == null) return;
231+
setState(() {
232+
value.boards[index] = result;
233+
});
234+
},
235+
trailing: IconButton(
236+
icon: const Icon(PhosphorIconsLight.trash),
237+
onPressed: () {
238+
setState(() {
239+
value.boards.removeAt(index);
240+
});
241+
},
242+
),
243+
);
244+
},
245+
),
246+
Align(
247+
alignment: Alignment.bottomCenter,
248+
child: FloatingActionButton.extended(
249+
onPressed: () async {
250+
final bloc = context.read<EditorCubit>();
251+
final result =
252+
await showDialog<BoardDeckDefinition>(
253+
context: context,
254+
builder: (context) => BlocProvider.value(
255+
value: bloc,
256+
child: _DeckBoardEditorDialog(),
257+
),
258+
);
259+
if (result == null) return;
260+
setState(() {
261+
value.boards.add(result);
262+
});
263+
},
264+
icon: const Icon(PhosphorIconsLight.plus),
265+
label: Text(AppLocalizations.of(context).create),
266+
),
267+
),
268+
],
269+
),
151270
],
152271
),
153272
),
@@ -172,3 +291,197 @@ class _DeckEditorDialogState extends State<DeckEditorDialog> {
172291
);
173292
}
174293
}
294+
295+
class _DeckFigureEditorDialog extends StatefulWidget {
296+
final FigureDeckDefinition? value;
297+
298+
const _DeckFigureEditorDialog({
299+
this.value,
300+
});
301+
302+
@override
303+
State<_DeckFigureEditorDialog> createState() =>
304+
__DeckFigureEditorDialogState();
305+
}
306+
307+
class __DeckFigureEditorDialogState extends State<_DeckFigureEditorDialog> {
308+
FigureDeckDefinition? _value;
309+
310+
@override
311+
void initState() {
312+
super.initState();
313+
_value = widget.value;
314+
}
315+
316+
@override
317+
Widget build(BuildContext context) {
318+
return ResponsiveAlertDialog(
319+
title: Text(AppLocalizations.of(context).figure),
320+
constraints: const BoxConstraints(maxWidth: LeapBreakpoints.compact),
321+
content: BlocBuilder<EditorCubit, SetonixData>(
322+
builder: (context, state) {
323+
final figure = _value == null ? null : state.getFigure(_value!.name);
324+
return ListView(
325+
shrinkWrap: true,
326+
children: [
327+
DropdownMenu<String>(
328+
dropdownMenuEntries: state.getFigures().map((e) {
329+
return DropdownMenuEntry(
330+
value: e,
331+
label: e,
332+
);
333+
}).toList(),
334+
label: Text(AppLocalizations.of(context).name),
335+
initialSelection: _value?.name,
336+
expandedInsets: EdgeInsets.all(8),
337+
onSelected: (value) {
338+
if (value == null) return;
339+
setState(() {
340+
_value = FigureDeckDefinition(name: value);
341+
});
342+
},
343+
),
344+
if (figure != null) ...[
345+
const SizedBox(height: 8),
346+
DropdownMenu<String>(
347+
initialSelection: _value?.variation,
348+
label: Text(AppLocalizations.of(context).variation),
349+
expandedInsets: EdgeInsets.all(8),
350+
dropdownMenuEntries: ['', ...figure.variations.keys].map((e) {
351+
return DropdownMenuEntry(
352+
value: e,
353+
label:
354+
e.isEmpty ? AppLocalizations.of(context).notSet : e,
355+
);
356+
}).toList(),
357+
onSelected: (value) {
358+
if (value == null) return;
359+
setState(() {
360+
_value = FigureDeckDefinition(
361+
name: _value!.name,
362+
variation: value,
363+
);
364+
});
365+
},
366+
),
367+
const SizedBox(height: 8),
368+
OffsetListTile(
369+
title: Text(AppLocalizations.of(context).position),
370+
value: _value!.position.toOffset(),
371+
onChanged: (value) {
372+
setState(() {
373+
_value = FigureDeckDefinition(
374+
name: _value!.name,
375+
variation: _value!.variation,
376+
position: value.toDefinition(),
377+
);
378+
});
379+
},
380+
),
381+
],
382+
],
383+
);
384+
},
385+
),
386+
actions: [
387+
TextButton(
388+
onPressed: () {
389+
Navigator.of(context).pop();
390+
},
391+
child: Text(AppLocalizations.of(context).cancel),
392+
),
393+
ElevatedButton(
394+
onPressed: () {
395+
Navigator.of(context).pop(_value);
396+
},
397+
child: Text(AppLocalizations.of(context).save),
398+
),
399+
],
400+
);
401+
}
402+
}
403+
404+
class _DeckBoardEditorDialog extends StatefulWidget {
405+
final BoardDeckDefinition? value;
406+
407+
const _DeckBoardEditorDialog({
408+
this.value,
409+
});
410+
411+
@override
412+
State<_DeckBoardEditorDialog> createState() => __DeckBoardEditorDialogState();
413+
}
414+
415+
class __DeckBoardEditorDialogState extends State<_DeckBoardEditorDialog> {
416+
BoardDeckDefinition? _value;
417+
418+
@override
419+
void initState() {
420+
super.initState();
421+
_value = widget.value;
422+
}
423+
424+
@override
425+
Widget build(BuildContext context) {
426+
return ResponsiveAlertDialog(
427+
title: Text(AppLocalizations.of(context).board),
428+
constraints: const BoxConstraints(maxWidth: LeapBreakpoints.compact),
429+
content: BlocBuilder<EditorCubit, SetonixData>(
430+
builder: (context, state) {
431+
final board = _value == null ? null : state.getBoard(_value!.name);
432+
return ListView(
433+
shrinkWrap: true,
434+
children: [
435+
DropdownMenu<String>(
436+
dropdownMenuEntries: state.getBoards().map((e) {
437+
return DropdownMenuEntry(
438+
value: e,
439+
label: e,
440+
);
441+
}).toList(),
442+
label: Text(AppLocalizations.of(context).name),
443+
initialSelection: _value?.name,
444+
expandedInsets: EdgeInsets.all(8),
445+
onSelected: (value) {
446+
if (value == null) return;
447+
setState(() {
448+
_value = BoardDeckDefinition(name: value);
449+
});
450+
},
451+
),
452+
if (board != null) ...[
453+
const SizedBox(height: 8),
454+
OffsetListTile(
455+
title: Text(AppLocalizations.of(context).position),
456+
value: _value!.position.toOffset(),
457+
onChanged: (value) {
458+
setState(() {
459+
_value = BoardDeckDefinition(
460+
name: _value!.name,
461+
position: value.toDefinition(),
462+
);
463+
});
464+
},
465+
),
466+
],
467+
],
468+
);
469+
},
470+
),
471+
actions: [
472+
TextButton(
473+
onPressed: () {
474+
Navigator.of(context).pop();
475+
},
476+
child: Text(AppLocalizations.of(context).cancel),
477+
),
478+
ElevatedButton(
479+
onPressed: () {
480+
Navigator.of(context).pop(_value);
481+
},
482+
child: Text(AppLocalizations.of(context).save),
483+
),
484+
],
485+
);
486+
}
487+
}

app/lib/pages/game/drawer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class GameDrawer extends StatelessWidget {
175175
),
176176
BlocBuilder<MultiplayerCubit, MultiplayerState>(
177177
builder: (context, state) {
178-
if (!state.isServer) return SizedBox.shrink();
178+
if (state.isClient) return SizedBox.shrink();
179179
return ListTile(
180180
leading: const Icon(PhosphorIconsLight.package),
181181
title: Text(AppLocalizations.of(context).packs),

metadata/en-US/changelogs/4.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
* Add editor
22
* Fix importing of packs
3+
* Fix packs not available on singleplayer
34
* Rework packs dialog
45
* Upgrade to flutter 3.27
56
* Use minSdkVersion 23 instead of 21 (The minimum version of android is 6.0 (Marshmallow))

tools/pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ packages:
6969
dependency: "direct main"
7070
description:
7171
path: "packages/generate_leap"
72-
ref: f29b1ae0e338ec155e1c5b0a204c399232904540
73-
resolved-ref: f29b1ae0e338ec155e1c5b0a204c399232904540
72+
ref: fe2aa465d3018a6a1d2dbfd8a9da38d2ee869852
73+
resolved-ref: fe2aa465d3018a6a1d2dbfd8a9da38d2ee869852
7474
url: "https://github.com/LinwoodDev/dart_pkgs"
7575
source: git
7676
version: "1.0.0"

tools/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ dependencies:
1515
generate_leap:
1616
git:
1717
url: https://github.com/LinwoodDev/dart_pkgs
18-
ref: f29b1ae0e338ec155e1c5b0a204c399232904540
18+
ref: fe2aa465d3018a6a1d2dbfd8a9da38d2ee869852
1919
path: packages/generate_leap

0 commit comments

Comments
 (0)