Merge pull request 'haroon_dev' (#195) from haroon_dev into master
Reviewed-on: https://34.17.182.140/Haroon6138/HMG_Patient_App_New/pulls/195master
commit
cdbba6f270
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.76629 0.292994C8.94577 0.52652 8.97196 0.843482 8.83323 1.10329C8.24927 2.19693 7.91792 3.4461 7.91792 4.77489C7.91792 9.0867 11.4133 12.5821 15.7251 12.5821C17.0539 12.5821 18.3031 12.2508 19.3967 11.6668C19.6565 11.5281 19.9735 11.5543 20.207 11.7337C20.4406 11.9132 20.5474 12.2128 20.4802 12.4995C19.4056 17.085 15.2909 20.5 10.3769 20.5C4.64589 20.5 0 15.8541 0 10.1232C0 5.20909 3.41505 1.09448 8.0005 0.0198166C8.28726 -0.0473898 8.58681 0.0594678 8.76629 0.292994Z" fill="#8F9AA3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 610 B |
@ -1,316 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:device_calendar/device_calendar.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_reminder_view.dart';
|
||||
import 'package:hmg_patient_app_new/services/dialog_service.dart';
|
||||
import 'package:hmg_patient_app_new/services/permission_service.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:manage_calendar_events/manage_calendar_events.dart' as ios;
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:timezone/data/latest.dart' as tzl;
|
||||
|
||||
final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin();
|
||||
final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin();
|
||||
|
||||
class CalendarUtils {
|
||||
static Completer<CalendarUtils>? _completer;
|
||||
|
||||
dynamic get writableCalendars => calendars.firstWhere((c) => !c.isReadOnly!);
|
||||
dynamic calendars;
|
||||
|
||||
CalendarUtils._(this.calendars);
|
||||
|
||||
// static Future<CalendarUtils> getInstance() async {
|
||||
// if (_completer == null) {
|
||||
// _completer = Completer<CalendarUtils>();
|
||||
// print(_completer!.isCompleted);
|
||||
// try {
|
||||
// final dynamic calendarsResult;
|
||||
// if (Platform.isIOS) {
|
||||
// calendarsResult = await _myPlugin.getCalendars();
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer?.complete(CalendarUtils._(await calendarsResult!));
|
||||
// }
|
||||
// } else {
|
||||
// calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer?.complete(CalendarUtils._(await calendarsResult.data!));
|
||||
// }
|
||||
// }
|
||||
// } on Exception catch (e) {
|
||||
// if (!_completer!.isCompleted) {
|
||||
// _completer!.completeError(e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return _completer!.future;
|
||||
// }
|
||||
|
||||
static Future<CalendarUtils> getInstance() async {
|
||||
tzl.initializeTimeZones();
|
||||
if (_completer != null) {
|
||||
return _completer!.future;
|
||||
}
|
||||
_completer = Completer<CalendarUtils>();
|
||||
try {
|
||||
final dynamic calendarsResult;
|
||||
if (Platform.isIOS) {
|
||||
calendarsResult = await _myPlugin.getCalendars();
|
||||
_completer!.complete(CalendarUtils._(calendarsResult));
|
||||
} else {
|
||||
calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
|
||||
_completer!.complete(CalendarUtils._(calendarsResult.data));
|
||||
}
|
||||
} catch (e) {
|
||||
_completer!.completeError(e);
|
||||
}
|
||||
|
||||
return _completer!.future;
|
||||
}
|
||||
|
||||
Future createOrUpdateEvents({List<DateTime>? scheduleList, String? title, String? description, List<DateTime>? scheduleDateTime, List<DayOfWeek>? daysOfWeek}) async {
|
||||
tzl.initializeTimeZones();
|
||||
List<Event> events = [];
|
||||
Location _currentLocation;
|
||||
if (DateTime.now().timeZoneName == "+04")
|
||||
_currentLocation = getLocation('Asia/Dubai');
|
||||
else
|
||||
_currentLocation = getLocation('Asia/Riyadh');
|
||||
|
||||
scheduleDateTime!.forEach((element) {
|
||||
RecurrenceRule recurrenceRule = RecurrenceRule(
|
||||
// RecurrenceFrequency.Daily,
|
||||
// daysOfWeek: daysOfWeek,
|
||||
// endDate: element,
|
||||
until: element, frequency: Frequency.daily,
|
||||
);
|
||||
//added byAamir Tz Time
|
||||
Event event = Event(writableCalendars!.id,
|
||||
recurrenceRule: recurrenceRule,
|
||||
start: TZDateTime.from(element, _currentLocation),
|
||||
end: TZDateTime.from(element.add(Duration(minutes: 30)), _currentLocation),
|
||||
title: title,
|
||||
description: description);
|
||||
events.add(event);
|
||||
});
|
||||
|
||||
events.forEach((element) {
|
||||
deviceCalendarPlugin.createOrUpdateEvent(element);
|
||||
});
|
||||
}
|
||||
|
||||
Future createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId}) async {
|
||||
RecurrenceRule recurrenceRule = RecurrenceRule(
|
||||
// RecurrenceFrequency.Daily,
|
||||
// daysOfWeek: daysOfWeek,
|
||||
// endDate: scheduleDateTime,
|
||||
until: scheduleDateTime, frequency: Frequency.daily,
|
||||
);
|
||||
|
||||
Location _currentLocation;
|
||||
// if (DateTime.now().timeZoneName == "+04")
|
||||
// _currentLocation = getLocation('Asia/Dubai');
|
||||
// else
|
||||
_currentLocation = getLocation('Asia/Riyadh');
|
||||
|
||||
TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation);
|
||||
|
||||
print("writableCalendars-name: " + writableCalendars.name);
|
||||
print("writableCalendars-Id: " + writableCalendars.id);
|
||||
print("writableCalendarsToString: " + writableCalendars.toString());
|
||||
print("writableCalendarsToString: " + writableCalendars!.id!);
|
||||
Event event = Event(
|
||||
writableCalendars!.id,
|
||||
start: scheduleDateTimeUTZ,
|
||||
end: scheduleDateTimeUTZ.add(Duration(minutes: 30)),
|
||||
title: title,
|
||||
description: description,
|
||||
);
|
||||
|
||||
ios.CalendarEvent iosCalEvent =
|
||||
ios.CalendarEvent(location: location, startDate: scheduleDateTimeUTZ, endDate: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description, isAllDay: false);
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
Result<bool> result = await deviceCalendarPlugin.hasPermissions();
|
||||
print(result);
|
||||
await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) {
|
||||
print("catchError " + e.toString());
|
||||
}).whenComplete(() {
|
||||
print("whenComplete Calender ID " + eventId!);
|
||||
});
|
||||
} else {
|
||||
await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) {
|
||||
print("catchError " + e.toString());
|
||||
}).whenComplete(() {
|
||||
print("whenComplete Calender ID iOS " + eventId!);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteEvent(String _calendarId, String _eventId) async {
|
||||
if (Platform.isIOS) {
|
||||
await _myPlugin.deleteEvent(calendarId: _calendarId, eventId: _eventId);
|
||||
} else {
|
||||
await deviceCalendarPlugin.deleteEvent(_calendarId, _eventId);
|
||||
}
|
||||
}
|
||||
|
||||
Future retrieveEvents(
|
||||
String calendarId,
|
||||
RetrieveEventsParams retrieveEventsParams,
|
||||
) async {
|
||||
if (Platform.isIOS) {
|
||||
return await _myPlugin.getEvents(calendarId: calendarId);
|
||||
} else {
|
||||
return await deviceCalendarPlugin.retrieveEvents(calendarId, retrieveEventsParams);
|
||||
}
|
||||
}
|
||||
|
||||
Future createCalendar(
|
||||
String calendarName, {
|
||||
Color? calendarColor,
|
||||
String? localAccountName,
|
||||
}) async {
|
||||
return await deviceCalendarPlugin.createCalendar(calendarName, calendarColor: calendarColor, localAccountName: localAccountName);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<Permission, PermissionStatus>> requestPermissions() async {
|
||||
var permissionResults = [Permission.calendarFullAccess].request();
|
||||
return permissionResults;
|
||||
}
|
||||
|
||||
showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
|
||||
{required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async {
|
||||
if (Platform.isAndroid) {
|
||||
if (await PermissionService.isCalendarPermissionEnabled()) {
|
||||
_showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
} else {
|
||||
// Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async {
|
||||
// if (await Permission.calendarFullAccess.request().isGranted) {
|
||||
// _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
// onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
} else {
|
||||
if (await Permission.calendarWriteOnly.request().isGranted) {
|
||||
if (await Permission.calendarFullAccess.request().isGranted) {
|
||||
_showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
|
||||
onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
|
||||
{required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async {
|
||||
showCommonBottomSheetWithoutHeight(providedContext, title: "Set the timer of reminder", child: PrescriptionReminderView(
|
||||
setReminder: (int value) async {
|
||||
if (!isMultiAllowed!) {
|
||||
if (onMultiDateSuccess == null) {
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
await calendarUtils.createOrUpdateEvent(
|
||||
title: title ?? "You have appointment with Dr. $doctorName",
|
||||
description: description ?? "At $appoDateFormatted $appoTimeFormatted",
|
||||
scheduleDateTime: dateTime,
|
||||
eventId: eventId,
|
||||
location: '');
|
||||
onSuccess();
|
||||
}
|
||||
} else {
|
||||
onMultiDateSuccess!(value);
|
||||
}
|
||||
},
|
||||
), callBackFunc: () {}, isFullScreen: false);
|
||||
}
|
||||
|
||||
setCalender(BuildContext context,
|
||||
{required String eventId, required int selectedMinutes, int? frequencyNumber, required int days, required String orderDate, required String itemDescriptionN, required String route}) async {
|
||||
DateTime actualDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0);
|
||||
frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2
|
||||
|
||||
int remainingDays = days - (Jiffy.parseFromDateTime(DateTime.now()).diff(Jiffy.parseFromDateTime(DateUtil.convertStringToDate(orderDate)), unit: Unit.day) as int);
|
||||
if (remainingDays.isNegative) {
|
||||
getIt.get<DialogService>().showErrorBottomSheet(message: "Prescription date has been already passed you can not add a reminder for this prescription.");
|
||||
return;
|
||||
}
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
|
||||
try {
|
||||
for (int i = 0; i < remainingDays; i++) {
|
||||
//event for number of days.
|
||||
for (int j = 0; j < frequencyNumber; j++) {
|
||||
// event for number of times per day.
|
||||
if (j != 0) {
|
||||
actualDate.add(new Duration(hours: 8)); // 8 hours addition for daily dose.
|
||||
}
|
||||
//Time subtraction from actual reminder time. like before 30, or 1 hour.
|
||||
|
||||
actualDate = Jiffy.parseFromDateTime(actualDate).subtract(minutes: selectedMinutes).dateTime;
|
||||
|
||||
calendarUtils.createOrUpdateEvent(
|
||||
title: "$itemDescriptionN} Prescription Reminder",
|
||||
description: "$itemDescriptionN $frequencyNumber $route ",
|
||||
scheduleDateTime: actualDate,
|
||||
eventId: eventId + (i.toString() + j.toString()),
|
||||
location: '', //event id with varitions
|
||||
);
|
||||
print("Creating event #$j for day $i → $actualDate");
|
||||
actualDate = DateTime(actualDate.year, actualDate.month, actualDate.day, 8, 0);
|
||||
}
|
||||
actualDate = Jiffy.parseFromDateTime(actualDate).add(days: 1).dateTime;
|
||||
}
|
||||
} catch (ex) {
|
||||
getIt.get<DialogService>().showErrorBottomSheet(message: "catch:$ex");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkAndRemove(hasReminder, {bool delete = false, String itemDescriptionN = ""}) async {
|
||||
final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin();
|
||||
CalendarUtils calendarUtils = await CalendarUtils.getInstance();
|
||||
DateTime startEventsDate = Jiffy.parseFromDateTime(DateTime.now()).subtract(days: 30).dateTime;
|
||||
DateTime endEventsDate = Jiffy.parseFromDateTime(DateTime.now()).add(days: 120).dateTime;
|
||||
RetrieveEventsParams params = RetrieveEventsParams(startDate: startEventsDate, endDate: endEventsDate);
|
||||
|
||||
if (calendarUtils.calendars != null) {
|
||||
if (Platform.isAndroid) {
|
||||
await processEvents(calendarUtils.calendars, calendarUtils, params, delete, itemDescriptionN, hasReminder);
|
||||
} else {
|
||||
List<ios.Calendar>? iosCalendars = await _myPlugin.getCalendars();
|
||||
if (iosCalendars != null) {
|
||||
await processEvents(iosCalendars.map((cal) => Calendar(id: cal.id, name: cal.name, accountName: cal.accountName)).toList(), calendarUtils, params, delete, itemDescriptionN, hasReminder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> processEvents(List<Calendar> calendars, calendarUtils, params, delete, String itemDescriptionN, hasReminder) async {
|
||||
for (var calendar in calendars) {
|
||||
Result<UnmodifiableListView<Event>> events = await calendarUtils.retrieveEvents(calendar.id!, params);
|
||||
for (var event in events.data!) {
|
||||
if (event.title!.contains(itemDescriptionN)) {
|
||||
if (delete) {
|
||||
await calendarUtils.deleteEvent(calendar, event);
|
||||
// AppToast.showSuccessToast(message: TranslationBase.of(context).reminderCancelSuccess);
|
||||
hasReminder = false;
|
||||
} else {
|
||||
hasReminder = false;
|
||||
// setState(() {
|
||||
// hasReminder = true;
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,36 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hmg_patient_app_new/services/cache_service.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class ProfileSettingsViewModel extends ChangeNotifier {
|
||||
static const String _darkModeKey = 'is_dark_mode';
|
||||
|
||||
void notify(){
|
||||
final CacheService _cacheService;
|
||||
|
||||
bool _isDarkMode = false;
|
||||
|
||||
bool get isDarkMode => _isDarkMode;
|
||||
|
||||
ProfileSettingsViewModel({required CacheService cacheService})
|
||||
: _cacheService = cacheService;
|
||||
|
||||
/// Call once at app startup (before the first frame) to restore the
|
||||
/// persisted dark-mode preference.
|
||||
void loadDarkMode() {
|
||||
final saved = _cacheService.getBool(key: _darkModeKey);
|
||||
_isDarkMode = saved ?? false;
|
||||
AppColors.isDarkMode = _isDarkMode;
|
||||
// No notifyListeners() here — we are called before build.
|
||||
}
|
||||
|
||||
void toggleDarkMode(bool value) {
|
||||
_isDarkMode = value;
|
||||
AppColors.isDarkMode = value;
|
||||
_cacheService.saveBool(key: _darkModeKey, value: value);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void notify() {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue