Skip to content

Commit

Permalink
Merge common widgets between homework dialog and event dialog. (#1322)
Browse files Browse the repository at this point in the history
Added `lib/sharezone_widgets/lib/src/creation_editing_dialog_widgets`
with:
* course_tile_base.dart
* description_field_base.dart
* location_base.dart
* send_notification_base.dart
* markdown_field.dart (moved from `sharezone_widgets/lib/src/markdown`)
* markdown_support.dart (moved from
`sharezone_widgets/lib/src/markdown`)

The send notification tile in the event dialog was using
`ListTileWithDescription`, the homework dialog was using a `ListTile`. I
changed it so that the shared `send_notification_base.dart` uses a
`ListTile`. As the description in the updated widget is too long I
shortened it.

This means the event dialog will be changed like this:

| Old | New |
|---|---|
| ![event_dialog_add_empty_dark_event
iphone11_masterImage](https://github.com/SharezoneApp/sharezone-app/assets/29028262/eda66581-665f-45ad-8bff-c572cd731dcc)
| ![event_dialog_add_empty_dark_event
iphone11_testImage](https://github.com/SharezoneApp/sharezone-app/assets/29028262/54e87e2d-56fe-4b84-9615-83e3607fda99)
|

---------

Co-authored-by: nilsreichardt <[email protected]>
  • Loading branch information
Jonas-Sander and nilsreichardt authored Mar 7, 2024
1 parent 0e939ec commit 2c15804
Show file tree
Hide file tree
Showing 86 changed files with 662 additions and 287 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/safe_app_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,14 @@ jobs:
flutter pub global activate --source path "$CI_CD_DART_SCRIPTS_PACKAGE_PATH"
echo $(pwd)/bin >> $GITHUB_PATH
# Running with -c 1 as using -c 4 would lead to to this dependency error:
# https://github.com/SharezoneApp/sharezone-app/pull/1322#issuecomment-1981410505
# We don't know why this happens.
# In the future please try to use a higher concurrency value again.
- name: Run tests via "sz test"
run: |
sz test \
-c 4 \
-c 1 \
--package-timeout-minutes 15 \
--only-goldens
Expand Down
1 change: 0 additions & 1 deletion app/lib/blackboard/blackboard_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import 'package:sharezone/filesharing/dialog/attach_file.dart';
import 'package:sharezone/filesharing/dialog/course_tile.dart';
import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/markdown/markdown_analytics.dart';
import 'package:sharezone/widgets/material/list_tile_with_description.dart';
import 'package:sharezone/widgets/material/save_button.dart';
import 'package:sharezone_common/api_errors.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';
Expand Down
33 changes: 1 addition & 32 deletions app/lib/filesharing/dialog/course_tile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import 'package:bloc_provider/bloc_provider.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:flutter/material.dart';
import 'package:group_domain_models/group_domain_models.dart';
import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/groups/group_join/group_join_page.dart';
import 'package:sharezone/groups/group_permission.dart';
import 'package:sharezone/groups/src/pages/course/create/course_template_page.dart';
import 'package:sharezone/homework/homework_dialog/homework_dialog.dart';
import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/util/api.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';

Expand Down Expand Up @@ -90,36 +89,6 @@ class CourseTile extends StatelessWidget {
}
}

class CourseTileBase extends StatelessWidget {
final String? courseName;
final String? errorText;

/// If null disables tile.
final VoidCallback? onTap;

const CourseTileBase({
required this.courseName,
required this.errorText,
required this.onTap,
super.key,
});

@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.book),
title: const Text("Kurs"),
subtitle: Text(
errorText ?? courseName ?? HwDialogErrorStrings.emptyCourse,
style: errorText != null ? const TextStyle(color: Colors.red) : null,
),
trailing: const Icon(Icons.keyboard_arrow_down),
enabled: onTap != null,
onTap: () => onTap!(),
);
}
}

class _CourseList extends StatelessWidget {
const _CourseList({
required this.courseList,
Expand Down
64 changes: 5 additions & 59 deletions app/lib/homework/homework_dialog/homework_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,8 @@ class _SendNotification extends StatelessWidget {
child: SafeArea(
top: false,
bottom: false,
child: _SendNotificationBase(
child: SendNotificationBase(
listTileKey: HwDialogKeys.notifyCourseMembersTile,
title:
"Kursmitglieder ${state.isEditing ? "über die Änderungen " : ""}benachrichtigen",
onChanged: (newValue) =>
Expand All @@ -977,35 +978,6 @@ class _SendNotification extends StatelessWidget {
}
}

class _SendNotificationBase extends StatelessWidget {
const _SendNotificationBase({
required this.title,
required this.sendNotification,
required this.onChanged,
this.description,
});

final String title;
final String? description;
final bool sendNotification;
final Function(bool) onChanged;

@override
Widget build(BuildContext context) {
return ListTile(
key: HwDialogKeys.notifyCourseMembersTile,
leading: const Icon(Icons.notifications_active),
title: Text(title),
trailing: Switch.adaptive(
onChanged: onChanged,
value: sendNotification,
),
onTap: () => onChanged(!sendNotification),
subtitle: description != null ? Text(description!) : null,
);
}
}

class _DescriptionField extends StatelessWidget {
const _DescriptionField({required this.state});

Expand All @@ -1014,42 +986,16 @@ class _DescriptionField extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bloc = bloc_lib.BlocProvider.of<HomeworkDialogBloc>(context);
return _DescriptionFieldBase(
return DescriptionFieldBase(
textFieldKey: HwDialogKeys.descriptionField,
hintText: 'Zusatzinformationen eingeben',
onChanged: (newDescription) =>
bloc.add(DescriptionChanged(newDescription)),
prefilledDescription: state.description,
);
}
}

class _DescriptionFieldBase extends StatelessWidget {
const _DescriptionFieldBase({
required this.onChanged,
required this.prefilledDescription,
});

final Function(String) onChanged;
final String? prefilledDescription;

@override
Widget build(BuildContext context) {
return MarkdownField(
textFieldKey: HwDialogKeys.descriptionField,
inputDecoration: const InputDecoration(
hintText: "Zusatzinformationen eingeben",
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
errorBorder: InputBorder.none,
fillColor: Colors.transparent,
),
onChanged: onChanged,
prefilledText: prefilledDescription,
icon: const Icon(Icons.subject),
);
}
}

class _AttachFile extends StatelessWidget {
const _AttachFile({required this.state});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import 'package:sharezone/settings/src/subpages/my_profile/change_password.dart'
import 'package:sharezone/settings/src/subpages/my_profile/change_state.dart';
import 'package:sharezone/settings/src/subpages/my_profile/change_type_of_user/change_type_of_user_page.dart';
import 'package:sharezone/settings/src/subpages/my_profile/my_profile_bloc.dart';
import 'package:sharezone/widgets/material/list_tile_with_description.dart';
import 'package:sharezone_common/api_errors.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
Expand Down
3 changes: 1 addition & 2 deletions app/lib/settings/src/subpages/notification.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
import 'package:bloc_provider/bloc_provider.dart';
import 'package:flutter/material.dart' hide TimePickerEntryMode;
import 'package:interval_time_picker/interval_time_picker.dart';
import 'package:platform_check/platform_check.dart';
import 'package:provider/provider.dart';
import 'package:sharezone/notifications/notifications_bloc.dart';
import 'package:sharezone/notifications/notifications_bloc_factory.dart';
import 'package:sharezone/sharezone_plus/page/sharezone_plus_page.dart';
import 'package:sharezone/sharezone_plus/subscription_service/subscription_service.dart';
import 'package:sharezone/timetable/src/edit_time.dart';
import 'package:sharezone/widgets/matching_type_of_user_builder.dart';
import 'package:sharezone/widgets/material/list_tile_with_description.dart';
import 'package:platform_check/platform_check.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';
import 'package:time/time.dart';
import 'package:user/user.dart';
Expand Down
129 changes: 21 additions & 108 deletions app/lib/timetable/timetable_add_event/timetable_add_event_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import 'package:sharezone/filesharing/dialog/course_tile.dart';
import 'package:sharezone/homework/homework_dialog/homework_dialog.dart';
import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/markdown/markdown_analytics.dart';
import 'package:sharezone/widgets/material/list_tile_with_description.dart';
import 'package:sharezone/widgets/material/save_button.dart';
import 'package:sharezone_widgets/sharezone_widgets.dart';
import 'package:time/time.dart';
Expand Down Expand Up @@ -135,18 +134,7 @@ class TimetableAddEventDialog extends StatelessWidget {
const _MobileDivider(),
const _DateAndTimePicker(),
const _MobileDivider(),
_DescriptionFieldBase(
textFieldKey: EventDialogKeys.descriptionTextField,
hintText: isExam
? 'Themen der Prüfung'
: 'Zusatzinformationen',
onChanged: (newDescription) {
Provider.of<AddEventDialogController>(context,
listen: false)
.description = newDescription;
},
prefilledDescription: '',
),
_DescriptionField(isExam: isExam),
const _MobileDivider(),
const _Location(),
const _MobileDivider(),
Expand Down Expand Up @@ -536,44 +524,23 @@ class _DateAndTimeTile extends StatelessWidget {
}
}

class _DescriptionFieldBase extends StatelessWidget {
const _DescriptionFieldBase({
required this.onChanged,
required this.prefilledDescription,
required this.hintText,
this.textFieldKey,
});

final Function(String) onChanged;
final String? prefilledDescription;
final String hintText;
class _DescriptionField extends StatelessWidget {
const _DescriptionField({required this.isExam});

/// Key for the [PrefilledTextField] (used for testing).
///
/// If the key is assigned to [_DescriptionFieldBase] from the outside via
/// this field to the [PrefilledTextField] then calling
/// `tester.enterText(Key('description'))` will fail because of "too many
/// elements" for the key. I don't really understand why this happens, but
/// assigning the key to the [PrefilledTextField] fixes the problem.
final Key? textFieldKey;
final bool isExam;

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 4),
child: MarkdownField(
textFieldKey: textFieldKey,
onChanged: onChanged,
icon: const Icon(Icons.subject),
prefilledText: prefilledDescription,
inputDecoration: InputDecoration(
hintText: hintText,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
errorBorder: InputBorder.none,
fillColor: Colors.transparent,
),
child: DescriptionFieldBase(
textFieldKey: EventDialogKeys.descriptionTextField,
hintText: isExam ? 'Themen der Prüfung' : 'Zusatzinformationen',
onChanged: (newDescription) {
Provider.of<AddEventDialogController>(context, listen: false)
.description = newDescription;
},
prefilledDescription: '',
),
);
}
Expand All @@ -585,38 +552,12 @@ class _Location extends StatelessWidget {
@override
Widget build(BuildContext context) {
final controller = Provider.of<AddEventDialogController>(context);
return MaxWidthConstraintBox(
child: SafeArea(
top: false,
bottom: false,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ListTile(
leading: const Icon(Icons.location_pin),
title: PrefilledTextField(
key: EventDialogKeys.locationField,
prefilledText: controller.location,
maxLines: null,
scrollPadding: const EdgeInsets.all(16.0),
keyboardType: TextInputType.text,
decoration: const InputDecoration(
hintText: "Ort/Raum",
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
errorBorder: InputBorder.none,
fillColor: Colors.transparent,
),
onChanged: (newLocation) {
controller.location = newLocation;
},
textCapitalization: TextCapitalization.sentences,
),
),
],
),
),
return LocationBase(
textFieldKey: EventDialogKeys.locationField,
prefilledText: controller.location,
onChanged: (newLocation) {
controller.location = newLocation;
},
);
}
}
Expand All @@ -633,49 +574,21 @@ class _SendNotification extends StatelessWidget {
child: SafeArea(
top: false,
bottom: false,
child: _SendNotificationBase(
child: SendNotificationBase(
switchKey: EventDialogKeys.notifyCourseMembersSwitch,
title: "Kursmitglieder benachrichtigen",
onChanged: (newValue) {
controller.notifyCourseMembers = newValue;
},
sendNotification: controller.notifyCourseMembers,
description:
"Sende eine Benachrichtigung an deine Kursmitglieder, dass du ${isExam ? 'eine neue Klausur' : 'einen neuen Termin'} erstellt hast.",
"Kursmitglieder über ${isExam ? 'neue Klausur' : 'neuen Termin'} benachrichtigen.",
),
),
);
}
}

class _SendNotificationBase extends StatelessWidget {
const _SendNotificationBase({
required this.title,
required this.sendNotification,
required this.onChanged,
this.description,
});

final String title;
final String? description;
final bool sendNotification;
final Function(bool) onChanged;

@override
Widget build(BuildContext context) {
return ListTileWithDescription(
leading: const Icon(Icons.notifications_active),
title: Text(title),
trailing: Switch.adaptive(
key: EventDialogKeys.notifyCourseMembersSwitch,
onChanged: onChanged,
value: sendNotification,
),
onTap: () => onChanged(!sendNotification),
description: description != null ? Text(description!) : null,
);
}
}

class EventDialogKeys {
static const Key saveButton = Key("save-button");
static const Key titleTextField = Key("title-field");
Expand Down
8 changes: 4 additions & 4 deletions app/pubspec.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2c15804

Please sign in to comment.