Skip to content

Commit 7eef80c

Browse files
committed
push many changes in rentnerend and small in frontend
starting to create creator_window added ended flag to rentnerend and frontend added pause_timed to rentnerend and frontend new UI design in input_window many other things in rentnerend
1 parent 514bb50 commit 7eef80c

12 files changed

Lines changed: 870 additions & 286 deletions

File tree

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ Building and running:
4343
# TODO
4444

4545
## meta
46-
- Spiel 11 oder so final screen machen, dass 10 Spiel und finale Tabelle angezeit werden kann
4746
1. should requester gauge delay between request & response?
4847
2. should backend broadcast DATA_TIMESTAMP to everyone or only the requester?
4948
- rename rentnerend to controller
@@ -127,8 +126,7 @@ Building and running:
127126
- OBS Scene / replay situation
128127
### Infoend
129128
- know if boss is connected and if no, warn about incorrect info @backend
130-
- zeit als bar um den oval rum
131-
- FINAL Add Logo to Info Window
129+
- FINAL Add Logos to Info Window
132130

133131
## backend
134132
- FINAL loggt wie viele leute connecten (Info Window)

frontend/script.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ const GamePartTimedSchema = z.object({
7171
decider: z.boolean().default(false),
7272
sides_inverted: z.boolean().default(false),
7373
});
74+
const GamePartPausedTimedSchema = z.object({
75+
type: z.literal("pause_timed"),
76+
name: z.string(),
77+
length: z.number(),
78+
repeat: z.boolean().default(false),
79+
decider: z.boolean().default(false),
80+
sides_inverted: z.boolean().default(false),
81+
});
7482
const GamePartFormatSchema = z.object({
7583
type: z.literal("format"),
7684
format: z.string(),
@@ -88,6 +96,7 @@ const GamePartPenaltySchema = z.object({
8896
});
8997
const GamePartSchema = z.discriminatedUnion("type", [
9098
GamePartTimedSchema,
99+
GamePartPausedTimedSchema,
91100
GamePartFormatSchema,
92101
GamePartPenaltySchema
93102
]);
@@ -225,7 +234,8 @@ const FormatSchema = z.object({
225234
const MetaGameSchema = z.object({
226235
index: z.number().default(0),
227236
gamepart: z.number().default(0),
228-
sides_inverted: z.boolean().default(false)
237+
sides_inverted: z.boolean().default(false),
238+
ended: z.boolean().default(false)
229239
});
230240

231241
const MetaTimeSchema = z.object({
@@ -289,7 +299,8 @@ let md: Matchday = {
289299
game: {
290300
index: 0,
291301
gamepart: 0,
292-
sides_inverted: false
302+
sides_inverted: false,
303+
ended: false
293304
},
294305
time: {
295306
remaining: 0,
@@ -708,13 +719,14 @@ function write_livetable() {
708719
while (livetable.children.length > 2) livetable.removeChild(livetable.lastChild!);
709720

710721
let teams: LivetableLine[] = [];
722+
let last_index = md.meta.game.ended ? md.games.length : md.meta.game.index;
711723

712724
md.teams.forEach((t) => {
713725
teams.push({
714726
name: t.name.toString(),
715727
points: (() => {
716728
let p = 0;
717-
for (let j = 0; j < md.meta.game.index; j++) { // TODO Count the game right now?
729+
for (let j = 0; j < last_index; j++) {
718730
const g: Game = md.games[j];
719731
if (resolve_GameTeamSlot(g[1]) === t) {
720732
p += (get_scores(g)[0] - get_scores(g)[1] > 0) ? 3 : 0;
@@ -728,15 +740,15 @@ function write_livetable() {
728740
})(),
729741
played: (() => {
730742
let p = 0;
731-
for (let j = 0; j < md.meta.game.index; j++) {
743+
for (let j = 0; j < last_index; j++) {
732744
const g: Game = md.games[j];
733745
if (resolve_GameTeamSlot(g[1]) === t || resolve_GameTeamSlot(g[2]) === t) p++;
734746
}
735747
return p;
736748
})(),
737749
won: (() => {
738750
let p = 0;
739-
for (let j = 0; j < md.meta.game.index; j++) {
751+
for (let j = 0; j < last_index; j++) {
740752
const g: Game = md.games[j];
741753
if (resolve_GameTeamSlot(g[1]) === t)
742754
p += (get_scores(g)[0] - get_scores(g)[1] > 0) ? 1 : 0;
@@ -747,7 +759,7 @@ function write_livetable() {
747759
})(),
748760
tied: (() => {
749761
let p = 0;
750-
for (let j = 0; j < md.meta.game.index; j++) {
762+
for (let j = 0; j < last_index; j++) {
751763
const g: Game = md.games[j];
752764
if (resolve_GameTeamSlot(g[1]) === t)
753765
p += (get_scores(g)[0] - get_scores(g)[1] === 0) ? 1 : 0;
@@ -758,7 +770,7 @@ function write_livetable() {
758770
})(),
759771
lost: (() => {
760772
let p = 0;
761-
for (let j = 0; j < md.meta.game.index; j++) {
773+
for (let j = 0; j < last_index; j++) {
762774
const g: Game = md.games[j];
763775
if (resolve_GameTeamSlot(g[1]) === t)
764776
p += (get_scores(g)[0] - get_scores(g)[1] < 0) ? 1 : 0;
@@ -769,7 +781,7 @@ function write_livetable() {
769781
})(),
770782
goals: (() => {
771783
let p = 0;
772-
for (let j = 0; j < md.meta.game.index; j++) {
784+
for (let j = 0; j < last_index; j++) {
773785
const g: Game = md.games[j];
774786
if (resolve_GameTeamSlot(g[1]) === t) p += get_scores(g)[0];
775787
else if (resolve_GameTeamSlot(g[2]) === t) p += get_scores(g)[1];
@@ -778,7 +790,7 @@ function write_livetable() {
778790
})(),
779791
goals_taken: (() => {
780792
let p = 0;
781-
for (let j = 0; j < md.meta.game.index; j++) {
793+
for (let j = 0; j < last_index; j++) {
782794
const g: Game = md.games[j];
783795
if (resolve_GameTeamSlot(g[1]) === t) p += get_scores(g)[1];
784796
else if (resolve_GameTeamSlot(g[2]) === t) p += get_scores(g)[0];
@@ -870,7 +882,7 @@ function update_scoreboard_timer(rt: number) {
870882
if (md.meta.time.remaining <= 0 || rt <= 0) return;
871883

872884
const gp = cur_gamepart();
873-
if (gp?.type != "timed") return;
885+
if (gp?.type != "timed" && gp?.type != "pause_timed") return;
874886

875887
const bar_width = Math.min(100, Math.max(0, (rt / gp.length) * 100));
876888
scoreboard_time_bar.style.width = bar_width + "%";

rentnerend/lib/creator_window.dart

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import 'dart:async';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:auto_size_text/auto_size_text.dart';
5+
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
6+
import 'package:flutter_rentnerend/widgets/color_picker.dart';
7+
8+
import 'md.dart';
9+
import 'ws_client.dart';
10+
import 'lib.dart' as lib;
11+
12+
13+
class TeamRow extends StatefulWidget {
14+
final String? defaultName;
15+
final bool initialShowPlayers;
16+
final Function(String) onNameChanged;
17+
final Function(Color) onColorChanged;
18+
19+
const TeamRow({
20+
super.key,
21+
this.defaultName,
22+
required this.initialShowPlayers,
23+
required this.onNameChanged,
24+
required this.onColorChanged,
25+
});
26+
27+
@override
28+
State<TeamRow> createState() => _TeamRowState();
29+
}
30+
31+
class _TeamRowState extends State<TeamRow> {
32+
late TextEditingController _controller;
33+
bool _showPlayers = false;
34+
35+
@override
36+
void initState() {
37+
super.initState();
38+
_controller = TextEditingController(text: widget.defaultName);
39+
}
40+
41+
@override
42+
void dispose() {
43+
_controller.dispose();
44+
super.dispose();
45+
}
46+
47+
@override
48+
Widget build(BuildContext context) {
49+
return Column(children: [
50+
Row(children: [
51+
Expanded(flex: 5, child: lib.ToggleIconButton(
52+
value: widget.initialShowPlayers,
53+
onChanged: (v) => setState(() => _showPlayers = v),
54+
)),
55+
Expanded(flex: 80, child: Autocomplete<String>(
56+
optionsBuilder: (TextEditingValue textEditingValue) {
57+
const List<String> opts = ["TEAM A"];
58+
if (textEditingValue.text == '')
59+
return const Iterable<String>.empty();
60+
return opts.where((String opt) {
61+
return opt.contains(textEditingValue.text);
62+
});
63+
},
64+
onSelected: (String selection) {
65+
widget.onNameChanged(selection);
66+
},
67+
fieldViewBuilder: (context, controller, focusNode, onFieldSubmitted) {
68+
return TextField(
69+
controller: controller,
70+
focusNode: focusNode,
71+
textInputAction: TextInputAction.next,
72+
onSubmitted: (String value) => widget.onNameChanged(value),
73+
decoration: const InputDecoration(
74+
border: OutlineInputBorder(),
75+
hintText: "Team Name",
76+
//suffixIcon: Icon(Icons.arrow_drop_down),
77+
),
78+
);
79+
}
80+
)),
81+
Expanded(flex: 15, child:
82+
ColorPickerButton(
83+
initialColor: Colors.white,
84+
onColorChanged: widget.onColorChanged
85+
)
86+
),
87+
88+
]),
89+
//if (_showPlayers)
90+
// for(int i=0; i < md.teams.length; i++)
91+
// TeamRow(
92+
// defaultName: md.teams[i].name,
93+
// onNameChanged: (newName) {
94+
// List<Team> newTeams = List.from(md.teams);
95+
// newTeams[i] = md.teams[i].copyWith(name: newName);
96+
// mdl.value = md.copyWith(teams: newTeams);
97+
// },
98+
// onColorChanged: (color) {
99+
// List<Team> newTeams = List.from(md.teams);
100+
// newTeams[i] = md.teams[i].copyWith(color: color.toHexString(includeHashSign: true));
101+
// mdl.value = md.copyWith(teams: newTeams);
102+
// },
103+
// initialShowPlayers: false
104+
// ),
105+
// TeamRow(
106+
// onNameChanged: (newName) {
107+
// if (newName.trim().isNotEmpty) {
108+
// List<Team> newTeams = List.from(md.teams);
109+
// newTeams.add(Team(newName, "", "#ffffff", []));
110+
// mdl.value = md.copyWith(teams: newTeams);
111+
// }
112+
// },
113+
// onColorChanged: (color) {
114+
// List<Team> newTeams = List.from(md.teams);
115+
// newTeams.add(Team("", "", color.toHexString(includeHashSign: true), []));
116+
// mdl.value = md.copyWith(teams: newTeams);
117+
// },
118+
// initialShowPlayers: false
119+
// )
120+
]);
121+
}
122+
}
123+
124+
125+
class CreatorWindow extends StatefulWidget {
126+
const CreatorWindow({super.key});
127+
128+
@override
129+
State<CreatorWindow> createState() => _CreatorWindowState();
130+
}
131+
132+
class _CreatorWindowState extends State<CreatorWindow> {
133+
late ValueNotifier<Matchday> mdl;
134+
135+
@override
136+
void initState() {
137+
super.initState();
138+
139+
final Matchday md = Matchday(Meta(), [], [], [], []);
140+
mdl = ValueNotifier(md);
141+
}
142+
143+
@override
144+
void dispose() {
145+
mdl.dispose();
146+
147+
super.dispose();
148+
}
149+
150+
//final textGroup = AutoSizeGroup();
151+
152+
Widget generalBlock(Matchday md) {
153+
return SizedBox.shrink();
154+
}
155+
156+
Widget teamsBlock(Matchday md) {
157+
return Column(children: [
158+
for(int i=0; i < md.teams.length; i++)
159+
TeamRow(
160+
defaultName: md.teams[i].name,
161+
onNameChanged: (newName) {
162+
List<Team> newTeams = List.from(md.teams);
163+
newTeams[i] = md.teams[i].copyWith(name: newName);
164+
mdl.value = md.copyWith(teams: newTeams);
165+
},
166+
onColorChanged: (color) {
167+
List<Team> newTeams = List.from(md.teams);
168+
newTeams[i] = md.teams[i].copyWith(color: color.toHexString(includeHashSign: true));
169+
mdl.value = md.copyWith(teams: newTeams);
170+
},
171+
initialShowPlayers: false
172+
),
173+
TeamRow(
174+
onNameChanged: (newName) {
175+
if (newName.trim().isNotEmpty) {
176+
List<Team> newTeams = List.from(md.teams);
177+
newTeams.add(Team(newName, "", "#ffffff", []));
178+
mdl.value = md.copyWith(teams: newTeams);
179+
}
180+
},
181+
onColorChanged: (color) {
182+
List<Team> newTeams = List.from(md.teams);
183+
newTeams.add(Team("", "", color.toHexString(includeHashSign: true), []));
184+
mdl.value = md.copyWith(teams: newTeams);
185+
},
186+
initialShowPlayers: false
187+
)
188+
]);
189+
}
190+
191+
Widget gamesBlock(Matchday md) {
192+
return SizedBox.shrink();
193+
}
194+
195+
@override
196+
Widget build(BuildContext context) {
197+
//final secondBgColor = Theme.of(context).scaffoldBackgroundColor;
198+
199+
return PopScope(child:
200+
Scaffold(body:
201+
//body: SingleChildScrollView(child:
202+
ValueListenableBuilder<Matchday>(
203+
valueListenable: mdl,
204+
builder: (context, md, _) {
205+
return Column(
206+
//mainAxisSize: MainAxisSize.min,
207+
spacing: 20,
208+
children: [
209+
//generalBlock(md),
210+
teamsBlock(md),
211+
//gamesBlock(md)
212+
]
213+
);
214+
}
215+
)
216+
//)
217+
)
218+
);
219+
}
220+
}

0 commit comments

Comments
 (0)