Skip to content

Commit c59b13f

Browse files
committed
Custom classrooms
1 parent e9c9402 commit c59b13f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+849
-375
lines changed

lib/interface/components/cupertino/elements/event.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,18 @@ extension LessonWidgetExtension on TimetableLesson {
808808
margin: EdgeInsets.only(left: 3, top: 5, bottom: 5),
809809
child: Opacity(
810810
opacity: 0.5,
811-
child: Text(classroom?.name ?? '',
812-
maxLines: 1, textAlign: TextAlign.end))))
811+
child: Text(
812+
Share.session.settings
813+
.customClassrooms[subject?.name ?? ''] ??
814+
classroom?.name ??
815+
'',
816+
maxLines: 1,
817+
textAlign: TextAlign.end))))
813818
],
814819
)),
815-
classroom?.name.isNotEmpty ?? false)
820+
Share.session.settings.customClassrooms[subject?.name ?? '']?.isNotEmpty ??
821+
classroom?.name.isNotEmpty ??
822+
false)
816823
.appendIf(
817824
AdaptiveCard(
818825
child: Row(
@@ -1021,7 +1028,9 @@ extension LessonWidgetExtension on TimetableLesson {
10211028
Icon(CupertinoIcons.question, color: CupertinoColors.inactiveGray)
10221029
})
10231030
: Text(
1024-
classroom?.name ?? '',
1031+
Share.session.settings.customClassrooms[subject?.name ?? ''] ??
1032+
classroom?.name ??
1033+
'',
10251034
style: TextStyle(
10261035
fontSize: 17,
10271036
fontStyle: (isCanceled || modifiedSchedule || markModified)

lib/interface/components/cupertino/widgets/entries_form.dart

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,38 @@ import 'package:flutter/cupertino.dart';
44
import 'package:flutter/material.dart';
55
import 'package:flutter/services.dart';
66
import 'package:flutter_swipe_action_cell/flutter_swipe_action_cell.dart';
7+
import 'package:oshi/interface/components/cupertino/widgets/options_form.dart';
8+
import 'package:oshi/interface/components/shim/modal_page.dart';
9+
import 'package:oshi/interface/components/shim/page_routes.dart';
710
import 'package:oshi/interface/shared/containers.dart';
11+
import 'package:oshi/interface/shared/input.dart';
812
import 'package:oshi/share/share.dart';
913

1014
class EntriesForm<T> extends StatefulWidget {
11-
const EntriesForm(
12-
{super.key,
13-
this.header = '',
14-
this.description = '',
15-
this.placeholder = 'Key',
16-
required this.update,
17-
required this.validate,
18-
this.maxKeyLength = 3,
19-
this.maxValueLength = 5});
15+
const EntriesForm({
16+
super.key,
17+
this.header = '',
18+
this.description = '',
19+
this.placeholder = 'Key',
20+
required this.update,
21+
required this.validate,
22+
this.maxKeyLength = 3,
23+
this.maxValueLength = 5,
24+
this.options,
25+
this.noOption = 'Select',
26+
});
2027

2128
final String header;
2229
final String description;
2330
final String placeholder;
31+
final String noOption;
2432

2533
final int maxKeyLength;
2634
final int maxValueLength;
2735

2836
final Map<String, T> Function<T>([Map<String, T>?]) update;
2937
final T? Function(String) validate;
38+
final List<String>? options;
3039

3140
@override
3241
State<EntriesForm> createState() => _EntriesFormState();
@@ -78,6 +87,7 @@ class _EntriesFormState<T> extends State<EntriesForm<T>> {
7887
// The 'add' menu
7988
.append(AdaptiveCard(
8089
regular: true,
90+
hideChevron: true,
8191
click: () {
8292
var result = widget.validate(_valueController.text);
8393
if (!(_keyController.text.isNotEmpty &&
@@ -115,31 +125,81 @@ class _EntriesFormState<T> extends State<EntriesForm<T>> {
115125
child: Row(
116126
mainAxisAlignment: MainAxisAlignment.spaceBetween,
117127
children: [
118-
ConstrainedBox(
119-
constraints: BoxConstraints(maxWidth: 50),
120-
child: Share.settings.appSettings.useCupertino
121-
? CupertinoTextField(
122-
onChanged: (value) => setState(() {}),
123-
controller: _keyController,
124-
expands: false,
125-
textAlign: TextAlign.start,
126-
maxLength: widget.maxKeyLength,
127-
maxLengthEnforcement: MaxLengthEnforcement.enforced)
128-
: TextFormField(
129-
onChanged: (value) => setState(() {}),
130-
controller: _keyController,
131-
expands: false,
132-
textAlign: TextAlign.start,
133-
maxLength: widget.maxKeyLength,
134-
maxLengthEnforcement: MaxLengthEnforcement.enforced,
135-
decoration: InputDecoration(
136-
counterText: "",
137-
errorBorder: InputBorder.none,
138-
disabledBorder: InputBorder.none,
139-
hintTextDirection: TextDirection.ltr,
140-
fillColor: Colors.transparent,
128+
if (widget.options?.isEmpty ?? true)
129+
ConstrainedBox(
130+
constraints: BoxConstraints(maxWidth: 50),
131+
child: Share.settings.appSettings.useCupertino
132+
? CupertinoTextField(
133+
onChanged: (value) => setState(() {}),
134+
controller: _keyController,
135+
expands: false,
136+
textAlign: TextAlign.start,
137+
maxLength: widget.maxKeyLength,
138+
maxLengthEnforcement: MaxLengthEnforcement.enforced)
139+
: TextFormField(
140+
onChanged: (value) => setState(() {}),
141+
controller: _keyController,
142+
expands: false,
143+
textAlign: TextAlign.start,
144+
maxLength: widget.maxKeyLength,
145+
maxLengthEnforcement: MaxLengthEnforcement.enforced,
146+
decoration: InputDecoration(
147+
counterText: "",
148+
errorBorder: InputBorder.none,
149+
disabledBorder: InputBorder.none,
150+
hintTextDirection: TextDirection.ltr,
151+
fillColor: Colors.transparent,
152+
),
153+
)),
154+
if (widget.options?.isNotEmpty ?? false)
155+
Share.settings.appSettings.useCupertino
156+
? CupertinoButton(
157+
padding: EdgeInsets.only(top: 5, bottom: 5, right: 10),
158+
child: ConstrainedBox(
159+
constraints: BoxConstraints(maxWidth: 150),
160+
child: Text(
161+
_keyController.text.isNotEmpty ? _keyController.text : widget.noOption,
162+
maxLines: 1,
163+
overflow: TextOverflow.ellipsis,
141164
),
142-
)),
165+
),
166+
onPressed: () => Navigator.push(
167+
context,
168+
AdaptivePageRoute(
169+
builder: (context) => ModalPageBase.adaptive(title: widget.noOption, children: [
170+
OptionsForm(
171+
selection: _keyController.text,
172+
options: widget.options!
173+
.select((x, _) => OptionEntry(name: x, value: x))
174+
.toList(),
175+
update: <T>(v) {
176+
_keyController.text = v;
177+
setState(() {});
178+
})
179+
]))))
180+
: ElevatedButton(
181+
style: ElevatedButton.styleFrom(
182+
backgroundColor: Theme.of(context).colorScheme.secondary,
183+
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 13)),
184+
onPressed: () => showOptionDialog(
185+
context: context,
186+
scrollable: true,
187+
title: widget.noOption,
188+
icon: Icons.list,
189+
selection: _keyController.text,
190+
options: widget.options!.select((x, _) => OptionEntry(name: x, value: x)).toList(),
191+
onChanged: (v) {
192+
_keyController.text = v;
193+
setState(() {});
194+
}),
195+
child: ConstrainedBox(
196+
constraints: BoxConstraints(maxWidth: 125),
197+
child: Text(_keyController.text.isNotEmpty ? _keyController.text : widget.noOption,
198+
maxLines: 1,
199+
overflow: TextOverflow.ellipsis,
200+
style: TextStyle(fontSize: 15, color: Theme.of(context).colorScheme.onSecondary)),
201+
),
202+
),
143203
ConstrainedBox(
144204
constraints: BoxConstraints(maxWidth: _valueController.text.isNotEmpty ? 70 : 100),
145205
child: Share.settings.appSettings.useCupertino

lib/interface/components/material/elements/event.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -697,9 +697,13 @@ extension LessonWidgetExtension on TimetableLesson {
697697
AdaptiveCard(
698698
child: 'AA2B9B71-49B6-45BD-A0FE-707D42A09EC5'.localized,
699699
regular: true,
700-
after: classroom?.name ?? '',
700+
after: Share.session.settings.customClassrooms[subject?.name ?? ''] ??
701+
classroom?.name ??
702+
'',
701703
),
702-
classroom?.name.isNotEmpty ?? false)
704+
Share.session.settings.customClassrooms[subject?.name ?? '']?.isNotEmpty ??
705+
classroom?.name.isNotEmpty ??
706+
false)
703707
.appendIf(
704708
AdaptiveCard(
705709
child: '4CCE58F6-2805-4D44-B97A-556679808477'.localized,
@@ -835,7 +839,9 @@ extension LessonWidgetExtension on TimetableLesson {
835839
Icon(CupertinoIcons.question, color: CupertinoColors.inactiveGray)
836840
})
837841
: Text(
838-
classroom?.name ?? '',
842+
Share.session.settings.customClassrooms[subject?.name ?? ''] ??
843+
classroom?.name ??
844+
'',
839845
style: TextStyle(
840846
fontSize: 17,
841847
fontStyle: (isCanceled || modifiedSchedule || markModified)

lib/interface/shared/input.dart

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:flutter/services.dart';
66
import 'package:format/format.dart';
77
import 'package:oshi/interface/components/cupertino/widgets/options_form.dart';
88
import 'package:oshi/interface/shared/containers.dart';
9+
import 'package:oshi/share/extensions.dart';
910
import 'package:oshi/share/share.dart';
1011
import 'package:oshi/share/translator.dart';
1112
import 'package:pull_down_button/pull_down_button.dart';
@@ -228,6 +229,7 @@ void showOptionDialog<T>(
228229
{required BuildContext context,
229230
required String title,
230231
IconData? icon,
232+
bool scrollable = false,
231233
required T selection,
232234
required List<OptionEntry<T>> options,
233235
required void Function(T) onChanged}) =>
@@ -248,27 +250,60 @@ void showOptionDialog<T>(
248250
padding: EdgeInsets.only(top: (icon != null) ? 20 : 30, bottom: 20.0),
249251
child: Text(title, style: TextStyle(fontSize: 27)),
250252
),
253+
if (scrollable)
254+
SizedBox(
255+
height: 265,
256+
child: SingleChildScrollView(
257+
child: Column(
258+
children: options
259+
.select((x, _) => Padding(
260+
padding: const EdgeInsets.only(left: 25, right: 25),
261+
child: ListTile(
262+
onTap: () => setState(() => group = x.value),
263+
contentPadding: EdgeInsets.only(left: 16.0, right: 5.0),
264+
shape:
265+
const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
266+
title: Table(
267+
columnWidths: x.decoration != null
268+
? const {0: FlexColumnWidth(2), 1: IntrinsicColumnWidth()}
269+
: null,
270+
children: [
271+
TableRow(children: [
272+
Text(x.name, style: TextStyle(fontSize: 17), overflow: TextOverflow.ellipsis),
273+
if (x.decoration != null) x.decoration!
274+
])
275+
]),
276+
trailing: Radio(
277+
value: x.value,
278+
groupValue: group,
279+
onChanged: (value) => setState(() => group = value),
280+
))))
281+
.toList()),
282+
),
283+
)
251284
]
252-
.appendAll(options.select((x, _) => Padding(
253-
padding: const EdgeInsets.only(left: 25, right: 25),
254-
child: ListTile(
255-
onTap: () => setState(() => group = x.value),
256-
contentPadding: EdgeInsets.only(left: 16.0, right: 5.0),
257-
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
258-
title: Table(
259-
columnWidths:
260-
x.decoration != null ? const {0: FlexColumnWidth(2), 1: IntrinsicColumnWidth()} : null,
261-
children: [
262-
TableRow(children: [
263-
Text(x.name, style: TextStyle(fontSize: 17), overflow: TextOverflow.ellipsis),
264-
if (x.decoration != null) x.decoration!
265-
])
266-
]),
267-
trailing: Radio(
268-
value: x.value,
269-
groupValue: group,
270-
onChanged: (value) => setState(() => group = value),
271-
)))))
285+
.appendAllIf(
286+
options.select((x, _) => Padding(
287+
padding: const EdgeInsets.only(left: 25, right: 25),
288+
child: ListTile(
289+
onTap: () => setState(() => group = x.value),
290+
contentPadding: EdgeInsets.only(left: 16.0, right: 5.0),
291+
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
292+
title: Table(
293+
columnWidths:
294+
x.decoration != null ? const {0: FlexColumnWidth(2), 1: IntrinsicColumnWidth()} : null,
295+
children: [
296+
TableRow(children: [
297+
Text(x.name, style: TextStyle(fontSize: 17), overflow: TextOverflow.ellipsis),
298+
if (x.decoration != null) x.decoration!
299+
])
300+
]),
301+
trailing: Radio(
302+
value: x.value,
303+
groupValue: group,
304+
onChanged: (value) => setState(() => group = value),
305+
)))),
306+
!scrollable)
272307
.append(Align(
273308
alignment: Alignment.bottomRight,
274309
child: Padding(

0 commit comments

Comments
 (0)