Skip to content

Commit

Permalink
add share schedule option
Browse files Browse the repository at this point in the history
  • Loading branch information
smart7even committed Aug 17, 2024
1 parent f40fede commit 4f2a2a4
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 58 deletions.
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
Expand All @@ -31,6 +33,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`)
- home_widget (from `.symlinks/plugins/home_widget/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)

Expand All @@ -45,6 +48,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/home_widget/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqlite3_flutter_libs:
Expand All @@ -54,6 +59,7 @@ SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqlite3: 19d8c26842078b45fa2deed63c4bbbe0c0e786ce
sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b
Expand Down
8 changes: 8 additions & 0 deletions lib/common/utils/string_utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
String capitalize(String s) {
return "${s[0].toUpperCase()}${s.substring(1).toLowerCase()}";
}

String trimSeparators(String s) {
final sWithoutNewLines = s.replaceAll('\n', ' ');

final splitted = sWithoutNewLines.split(' ').where((e) => e.isNotEmpty);

return splitted.map((e) => e.trim()).join(' ');
}
51 changes: 46 additions & 5 deletions lib/feature/schedule/bloc/schedule_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:l/l.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart' as bloc_concurrency;
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:uneconly/common/model/short_group_info.dart';
import 'package:uneconly/feature/schedule/data/schedule_repository.dart';
import 'package:uneconly/feature/schedule/domain/schedule_transformer.dart';
import 'package:uneconly/feature/schedule/model/schedule.dart';
import 'package:uneconly/feature/schedule/model/schedule_details.dart';
import 'package:uneconly/feature/select/data/group_repository.dart';
Expand Down Expand Up @@ -42,6 +44,10 @@ class ScheduleEvent with _$ScheduleEvent {
/// Delete
const factory ScheduleEvent.delete({required Schedule item}) =
DeleteScheduleEvent;

/// Share
const factory ScheduleEvent.share(ValueChanged<String> onShare) =
ShareScheduleEvent;
}

/* Schedule States */
Expand Down Expand Up @@ -98,6 +104,22 @@ class ScheduleState with _$ScheduleState {
/// Is in progress state
bool get isProcessing =>
maybeMap<bool>(orElse: () => true, idle: (_) => false);

ScheduleDetails? getSelectedScheduleDetails() {
if (selectedWeek == null) {
return null;
}

return data[selectedWeek];
}

ScheduleDetails? getCurrentScheduleDetails() {
if (currentWeek == null) {
return null;
}

return data[currentWeek];
}
}

/// Buisiness Logic Component ScheduleBLoC
Expand All @@ -122,17 +144,17 @@ class ScheduleBLoC extends Bloc<ScheduleEvent, ScheduleState>
on<ScheduleEvent>(
(event, emit) => event.map<Future<void>>(
fetch: (event) => _fetch(event, emit),
create: (value) {
create: (event) {
throw UnimplementedError();
},
update: (value) {
update: (event) {
throw UnimplementedError();
},
delete: (value) {
delete: (event) {
throw UnimplementedError();
},
changeGroup: (ChangeGroupScheduleEvent event) =>
_changeGroup(event, emit),
changeGroup: (event) => _changeGroup(event, emit),
share: (event) => _share(event, emit),
),
transformer: bloc_concurrency.sequential(),
);
Expand Down Expand Up @@ -358,4 +380,23 @@ class ScheduleBLoC extends Bloc<ScheduleEvent, ScheduleState>
);
}
}

Future<void> _share(
ShareScheduleEvent event,
Emitter<ScheduleState> emit,
) async {
final selectedScheduleDetails = state.getSelectedScheduleDetails();
final groupInfo = state.shortGroupInfo;

if (selectedScheduleDetails == null || groupInfo == null) {
return;
}

final content = ScheduleTransformer().transformScheduleToString(
selectedScheduleDetails.schedule,
groupInfo,
);

event.onShare(content);
}
}
57 changes: 57 additions & 0 deletions lib/feature/schedule/domain/schedule_transformer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:intl/intl.dart';
import 'package:uneconly/common/model/short_group_info.dart';
import 'package:uneconly/common/utils/string_utils.dart';
import 'package:uneconly/feature/schedule/model/schedule.dart';

class ScheduleTransformer {
String transformScheduleToString(
Schedule schedule,
ShortGroupInfo groupInfo,
) {
const space = ' ';
const newLine = '\n';
String result = '';

final groupName = groupInfo.groupName;

if (groupName != null) {
result += groupName;
result += newLine;
}

result += 'Неделя ${schedule.week}';
result += newLine;
result += newLine;

if (schedule.daySchedules.isEmpty) {
result += 'Нет расписания на эту неделю';
result += newLine;
}

for (final daySchedule in schedule.daySchedules) {
result += DateFormat('dd.MM.yyyy').format(daySchedule.day);
result += space;
result += DateFormat('EEE', 'ru').format(daySchedule.day);
result += newLine;

if (daySchedule.lessons.isEmpty) {
result += 'Нет пар';
result += newLine;
}

for (final lesson in daySchedule.lessons) {
result +=
'${DateFormat('HH:mm').format(lesson.start)} - ${DateFormat('HH:mm').format(lesson.end)}';
result += newLine;
result += lesson.name;
result += newLine;
result += trimSeparators(lesson.location);
result += newLine;
}

result += newLine;
}

return result;
}
}
57 changes: 57 additions & 0 deletions lib/feature/schedule/widget/schedule_actions_popup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';

enum ScheduleAction {
share,
favorite;
}

class ScheduleActionConfig {
final ScheduleAction action;
final VoidCallback onPressed;
final Widget child;

ScheduleActionConfig(
this.child, {
required this.action,
required this.onPressed,
});
}

class ScheduleActionsPopup extends StatelessWidget {
final List<ScheduleActionConfig> actions;

const ScheduleActionsPopup({
super.key,
required this.actions,
});

@override
Widget build(BuildContext context) {
return PopupMenuButton(
popUpAnimationStyle: AnimationStyle(
curve: Curves.easeIn,
duration: const Duration(milliseconds: 300),
),
offset: const Offset(0, 40),
onSelected: (value) {
for (final action in actions) {
if (action.action == value) {
action.onPressed();

return;
}
}
},
itemBuilder: (context) {
return actions
.map(
(e) => PopupMenuItem(
value: e.action,
child: e.child,
),
)
.toList();
},
);
}
} // _SchedulePageState
Loading

0 comments on commit 4f2a2a4

Please sign in to comment.