diff --git a/assets/lang/en.json b/assets/lang/en.json new file mode 100644 index 0000000..91a8562 --- /dev/null +++ b/assets/lang/en.json @@ -0,0 +1,34 @@ +{ + "title": "Yahrtzeit Manager", + "upcoming": "Upcoming", + "manage": "Manage", + "groups": "Groups", + "settings": "Settings", + "language": "Language", + "sync_settings": "Sync Settings", + "notifications": "Notifications", + "upcoming_yahrtzeits": "Upcoming Yahrtzeits", + "manage_yahrzeits": "Manage Yahrtzeits", + "English Name":"English Name", + "Add Yahrtzeit":"Add Yahrtzeit", + "Hebrew Name":"Hebrew Name", + "Please enter English name":"Please enter English name", + "Please enter Hebrew name":"Please enter Hebrew name", + "Select Date":"Select Date", + "Save":"Save", + "Update":"Update", + "Edit Yahrtzeit":"Edit Yahrtzeit", + "Details":"Details", + "Groups":"Groups", + "Jewish Name":"Jewish Name", + "Full Name":"Full Name", + "days_before":"days_before", + "years":"years", + "jewish_language":"jewish_language", + "calendar_settings":"calendar_settings", + "Google Calendar":"Google Calendar", + "Device Calendar":"Device Calendar" + + + } + \ No newline at end of file diff --git a/assets/lang/he.json b/assets/lang/he.json new file mode 100644 index 0000000..7ad552e --- /dev/null +++ b/assets/lang/he.json @@ -0,0 +1,33 @@ +{ + "title": "מנהל יארצייט", + "upcoming": "קרובים", + "manage": "ניהול", + "groups": "קבוצות", + "settings": "הגדרות", + "language": "שפה", + "sync_settings": "הגדרות סנכרון", + "notifications": "התראות", + "upcoming_yahrtzeits": "יארצייט קרובים", + "manage_yahrzeits": "ניהול יארצייט", + "English Name":"שם באנגלית", + "Add Yahrtzeit":"הוסף יארצייט", + "Hebrew Name":"שם בעברית", + "Please enter English name":"נא להכניס שם באנגלית", + "Please enter Hebrew name":"נא להכניס שם בעברית", + "Select Date":"בחר תאריך", + "Save":"שמור ", + "Update":"עדכן", + "Edit Yahrtzeit":"עריכה", + "Details":"פרטים", + "Groups":"קבוצות", + "Jewish Name":"שם יהודי", + "Full Name":"שם מלא ", + "days_before":"מספר ימים לפני קבלת ההתראה", + "years":"שנים", + "jewish_language":"שפה יהודית", + "calendar_settings":"הגדרות לוח", + "Google Calendar":"לוח גוגל", + "Device Calendar":"יומן הפלאפון" + + } + \ No newline at end of file diff --git a/lib/home_page.dart b/lib/home_page.dart index 38092be..601c9e8 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -1,15 +1,122 @@ -import 'package:flutter/material.dart'; +// import 'package:flutter/material.dart'; +// import 'settings/settings.dart'; +// import 'views/groups_page.dart'; +// import 'views/manage_yahrtzeits.dart'; +// import 'views/upcoming_yahrtzeits.dart'; +// import '../localizations/app_localizations.dart'; + +// class HomePage extends StatefulWidget { +// bool syncSettings; +// bool notifications; +// String language; +// String jewishLanguage; +// String calendar; +// int years; +// int days; +// final VoidCallback toggleSyncSettings; +// final VoidCallback toggleNotifications; +// final Function(String) changeLanguage; +// final Function(String) changeJewishLanguage; +// final Function(String) changeCalendar; +// final Function(int) changeYears; +// final Function(int) changeDays; + +// HomePage({ +// required this.syncSettings, +// required this.notifications, +// required this.language, +// required this.jewishLanguage, +// required this.calendar, +// required this.years, +// required this.days, +// required this.toggleSyncSettings, +// required this.toggleNotifications, +// required this.changeLanguage, +// required this.changeJewishLanguage, +// required this.changeCalendar, +// required this.changeYears, +// required this.changeDays, +// }); + +// @override +// _HomePageState createState() => _HomePageState(); +// } + +// class _HomePageState extends State { +// int _selectedIndex = 0; + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// body: IndexedStack( +// index: _selectedIndex, +// children: [ +// UpcomingYahrtzeits(), +// ManageYahrtzeits(), +// GroupsPage(), +// SettingsPage( +// syncSettings: widget.syncSettings, +// notifications: widget.notifications, +// language: widget.language, +// jewishLanguage: widget.jewishLanguage, +// calendar: widget.calendar, +// years: widget.years, +// days: widget.days, +// toggleSyncSettings: widget.toggleSyncSettings, +// toggleNotifications: widget.toggleNotifications, +// changeLanguage: widget.changeLanguage, +// changeJewishLanguage: widget.changeJewishLanguage, +// changeCalendar: widget.changeCalendar, +// changeYears: widget.changeYears, +// changeDays: widget.changeDays, +// ), +// ], +// ), +// bottomNavigationBar: BottomNavigationBar( +// items: const [ +// BottomNavigationBarItem( +// icon: Icon(Icons.calendar_today), +// label:'Upcoming', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.manage_accounts), +// label: 'Manage', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.group), +// label: 'Groups', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.settings), +// label: 'Settings', +// ), +// ], +// currentIndex: _selectedIndex, +// selectedItemColor: Colors.blue, +// unselectedItemColor: Colors.grey, +// onTap: (index) { +// setState(() { +// _selectedIndex = index; +// }); +// }, +// ), +// ); +// } +// } +import 'package:flutter/material.dart'; import 'settings/settings.dart'; +import 'views/groups_page.dart'; import 'views/manage_yahrtzeits.dart'; import 'views/upcoming_yahrtzeits.dart'; +import '../localizations/app_localizations.dart'; class HomePage extends StatefulWidget { - bool syncSettings = true; - bool notifications = true; - String language = 'en'; - String jewishLanguage = 'he'; - String calendar = 'he'; + bool syncSettings; + bool notifications; + String language; + String jewishLanguage; + String calendar; int years; int days; final VoidCallback toggleSyncSettings; @@ -36,6 +143,7 @@ class HomePage extends StatefulWidget { required this.changeYears, required this.changeDays, }); + @override _HomePageState createState() => _HomePageState(); } @@ -43,24 +151,16 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { int _selectedIndex = 0; - static List _widgetOptions = [ - UpcomingYahrtzeits(), - ManageYahrtzeits(), - ManageYahrtzeits(), - //SettingsPage(), - ]; - - void _onItemTapped(int index) { - setState(() { - _selectedIndex = index; - }); - } - - void navigateToSettingsPage() { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SettingsPage( + @override + Widget build(BuildContext context) { + return Scaffold( + body: IndexedStack( + index: _selectedIndex, + children: [ + UpcomingYahrtzeits(), + ManageYahrtzeits(), + GroupsPage(), + SettingsPage( syncSettings: widget.syncSettings, notifications: widget.notifications, language: widget.language, @@ -76,38 +176,37 @@ class _HomePageState extends State { changeYears: widget.changeYears, changeDays: widget.changeDays, ), - )); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: IconButton( - icon: Icon(Icons.settings), - onPressed: navigateToSettingsPage, - ), + ], ), - body: _widgetOptions.elementAt(_selectedIndex), bottomNavigationBar: BottomNavigationBar( - items: const [ + items: [ BottomNavigationBarItem( icon: Icon(Icons.calendar_today), - label: 'Upcoming', + label: AppLocalizations.of(context)!.translate('upcoming'), ), BottomNavigationBarItem( icon: Icon(Icons.manage_accounts), - label: 'Manage', + label: AppLocalizations.of(context)!.translate('manage'), + ), + BottomNavigationBarItem( + icon: Icon(Icons.group), + label: AppLocalizations.of(context)!.translate('groups'), ), BottomNavigationBarItem( icon: Icon(Icons.settings), - label: 'Settings', + label: AppLocalizations.of(context)!.translate('settings'), ), ], currentIndex: _selectedIndex, selectedItemColor: Colors.blue, - onTap: _onItemTapped, + unselectedItemColor: Colors.grey, + onTap: (index) { + setState(() { + _selectedIndex = index; + }); + }, ), ); } } + diff --git a/lib/localizations/app_localizations.dart b/lib/localizations/app_localizations.dart new file mode 100644 index 0000000..4767a7c --- /dev/null +++ b/lib/localizations/app_localizations.dart @@ -0,0 +1,68 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class AppLocalizations { + final Locale locale; + late Map _localizedStrings; + + AppLocalizations(this.locale); + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + Future load() async { + String jsonString = await rootBundle.loadString('assets/lang/${locale.languageCode}.json'); + Map jsonMap = json.decode(jsonString); + _localizedStrings = jsonMap.map((key, value) => MapEntry(key, value.toString())); + } + + String translate(String key) { + return _localizedStrings[key] ?? key; + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + bool isSupported(Locale locale) { + return ['en', 'he'].contains(locale.languageCode); + } + + @override + Future load(Locale locale) async { + AppLocalizations localizations = AppLocalizations(locale); + await localizations.load(); + return localizations; + } + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +class LocaleProvider with ChangeNotifier { + Locale _locale = Locale('en'); + + Locale get locale => _locale; + + void setLocale(Locale locale) async { + _locale = locale; + notifyListeners(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString('languageCode', locale.languageCode); + } + + Future loadLocale() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? languageCode = prefs.getString('languageCode'); + if (languageCode != null) { + _locale = Locale(languageCode); + } + notifyListeners(); + } +} diff --git a/lib/localizations/global_material_localizations.dart b/lib/localizations/global_material_localizations.dart new file mode 100644 index 0000000..a90e0c1 --- /dev/null +++ b/lib/localizations/global_material_localizations.dart @@ -0,0 +1,38 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +class HebrewMaterialLocalizations extends DefaultMaterialLocalizations { + const HebrewMaterialLocalizations(); + + static const LocalizationsDelegate delegate = + _HebrewMaterialLocalizationsDelegate(); + + @override + String get moreButtonTooltip => 'עוד'; + + // ... ניתן להוסיף כאן תרגומים נוספים ... + + static const _localizedValues = { + 'he': HebrewMaterialLocalizations(), + }; + + @override + String get aboutListTileTitleRaw => r'אודות $applicationName'; +} + +class _HebrewMaterialLocalizationsDelegate + extends LocalizationsDelegate { + const _HebrewMaterialLocalizationsDelegate(); + + @override + bool isSupported(Locale locale) => locale.languageCode == 'he'; + + @override + Future load(Locale locale) async { + return SynchronousFuture( + HebrewMaterialLocalizations()); + } + + @override + bool shouldReload(_HebrewMaterialLocalizationsDelegate old) => false; +} diff --git a/lib/main.dart b/lib/main.dart index 9bdc57e..5abd5fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,24 +1,42 @@ import 'package:flutter/material.dart'; -import 'home_page.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'localizations/app_localizations.dart'; +import 'localizations/global_material_localizations.dart'; import 'settings/settings.dart'; import 'views/upcoming_yahrtzeits.dart'; import 'views/manage_yahrtzeits.dart'; +import 'views/groups_page.dart'; +import 'home_page.dart'; -void main() { - runApp(YahrtzeitManagerApp()); +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? languageCode = prefs.getString('languageCode') ?? 'en'; + runApp( + ChangeNotifierProvider( + create: (context) => LocaleProvider()..loadLocale(), + child: YahrtzeitManagerApp(initialLocale: Locale(languageCode)), + ), + ); } + class YahrtzeitManagerApp extends StatefulWidget { + + final Locale initialLocale; + + YahrtzeitManagerApp({required this.initialLocale}); + + - YahrtzeitManagerApp(); @override _YahrtzeitManagerAppState createState() => _YahrtzeitManagerAppState(); } class _YahrtzeitManagerAppState extends State { - - bool syncSettings = true; + bool syncSettings = true; bool notifications = true; String language = 'en'; String jewishLanguage = 'he'; @@ -68,20 +86,26 @@ class _YahrtzeitManagerAppState extends State { calendar = cal; }); } - + + +// class YahrtzeitManagerApp extends StatelessWidget { + + @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Yahrtzeit Manager', - theme: ThemeData( - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - textTheme: TextTheme( - bodyLarge: TextStyle(color: Colors.black87), - bodyMedium: TextStyle(color: Colors.black54), - ), - ), - home: HomePage( + return Consumer( + builder: (context, localeProvider, child) { + return MaterialApp( + title: 'Yahrtzeit Manager', + theme: ThemeData( + primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + textTheme: TextTheme( + bodyLarge: TextStyle(color: const Color.fromARGB(221, 179, 108, 108)), + bodyMedium: TextStyle(color: Colors.black54), + ), + ), + home: HomePage( syncSettings: syncSettings, notifications: notifications, language: language, @@ -97,7 +121,39 @@ class _YahrtzeitManagerAppState extends State { changeYears: changeYears, changeDays: changeDays, ), - debugShowCheckedModeBanner: false, + locale: localeProvider.locale, + supportedLocales: [ + Locale('en', 'US'), + Locale('he', 'IL'), + ], + localizationsDelegates: [ + AppLocalizations.delegate, + HebrewMaterialLocalizations.delegate, + ], + localeResolutionCallback: (locale, supportedLocales) { + if (locale != null) { + for (var supportedLocale in supportedLocales) { + if (supportedLocale.languageCode == locale.languageCode) { + return supportedLocale; + } + } + } + return supportedLocales.first; + }, + debugShowCheckedModeBanner: false, + builder: (context, child) { + return Directionality( + textDirection: localeProvider.locale.languageCode == 'he' + ? TextDirection.rtl + : TextDirection.ltr, + child: child!, + ); + }, + ); + }, ); } } + + + diff --git a/lib/models/group.dart b/lib/models/group.dart new file mode 100644 index 0000000..dc0f04a --- /dev/null +++ b/lib/models/group.dart @@ -0,0 +1,8 @@ +import 'yahrtzeit.dart'; + +class Group { + String name; + final List yahrtzeits; + + Group({required this.name, required this.yahrtzeits}); +} diff --git a/lib/models/yahrtzeit.dart b/lib/models/yahrtzeit.dart index c2fae83..64a82ae 100644 --- a/lib/models/yahrtzeit.dart +++ b/lib/models/yahrtzeit.dart @@ -5,6 +5,8 @@ class Yahrtzeit { final int month; final int year; final DateTime gregorianDate; // נוסיף את השדה הזה + bool selected = false; // Add this line + Yahrtzeit({ required this.englishName, diff --git a/lib/services/yahrtzeits_manager.dart b/lib/services/yahrtzeits_manager.dart index 17f346c..37c6969 100644 --- a/lib/services/yahrtzeits_manager.dart +++ b/lib/services/yahrtzeits_manager.dart @@ -1,12 +1,530 @@ +// import 'package:device_calendar/device_calendar.dart'; +// import 'package:flutter/services.dart'; +// import 'package:timezone/timezone.dart' as tz; +// import '../models/yahrtzeit.dart'; +// import '../models/yahrtzeit_date.dart'; +// import '../models/group.dart'; + +// class YahrtzeitsManager { +// static final YahrtzeitsManager _instance = YahrtzeitsManager._internal(); +// final List _yahrtzeits = []; // In-memory storage +// final List _groups = []; // In-memory storage for groups +// final DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin(); + +// factory YahrtzeitsManager() { +// return _instance; +// } + +// YahrtzeitsManager._internal(); + +// DeviceCalendarPlugin get deviceCalendarPlugin => _deviceCalendarPlugin; + +// Future syncWithCalendar() async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// _yahrtzeits.clear(); +// for (var calendar in calendarsResult!.data!) { +// final eventsResult = await _deviceCalendarPlugin.retrieveEvents( +// calendar.id!, +// RetrieveEventsParams( +// startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), +// endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), +// ), +// ); +// if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { +// for (var event in eventsResult!.data!) { +// if (event.description?.startsWith('Yahrtzeit for') == true) { +// final hebrewName = _extractHebrewName(event.description!); +// final yahrtzeit = Yahrtzeit( +// englishName: event.title ?? 'Unknown', +// hebrewName: hebrewName, +// day: event.start!.day, +// month: event.start!.month, +// year: event.start!.year, +// gregorianDate: event.start!, +// ); +// if (!_yahrtzeits.any((y) => +// y.englishName == yahrtzeit.englishName && +// y.hebrewName == y.hebrewName && +// y.gregorianDate == y.gregorianDate)) { +// _yahrtzeits.add(yahrtzeit); +// } +// } +// } +// } +// } +// } + +// await _loadGroupsFromCalendar(calendarsResult!.data!); +// } on PlatformException catch (e) { +// print('Error syncing with calendar: $e'); +// } +// } + +// Future _loadGroupsFromCalendar(List calendars) async { +// try { +// _groups.clear(); +// for (var calendar in calendars) { +// final eventsResult = await _deviceCalendarPlugin.retrieveEvents( +// calendar.id!, +// RetrieveEventsParams( +// startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), +// endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), +// ), +// ); +// if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { +// final groupsMap = >{}; +// for (var event in eventsResult!.data!) { +// if (event.description?.startsWith('Group Yahrtzeit for') == true) { +// final groupName = event.title ?? 'Unknown Group'; +// final yahrtzeit = Yahrtzeit( +// englishName: _extractEnglishName(event.description!), +// hebrewName: _extractHebrewName(event.description!), +// day: event.start!.day, +// month: event.start!.month, +// year: event.start!.year, +// gregorianDate: event.start!, +// ); +// if (groupsMap.containsKey(groupName)) { +// groupsMap[groupName]!.add(yahrtzeit); +// } else { +// groupsMap[groupName] = [yahrtzeit]; +// } +// } +// } +// for (var entry in groupsMap.entries) { +// _groups.add(Group(name: entry.key, yahrtzeits: entry.value)); +// } +// } +// } +// } on PlatformException catch (e) { +// print('Error loading groups from calendar: $e'); +// } +// } + +// Future addYahrtzeit(Yahrtzeit yahrtzeit) async { +// if (!_yahrtzeits.any((y) => +// y.englishName == yahrtzeit.englishName && +// y.hebrewName == y.hebrewName && +// y.gregorianDate == y.gregorianDate)) { +// _yahrtzeits.add(yahrtzeit); +// await _addToCalendar(yahrtzeit); +// } +// } + +// Future deleteYahrtzeit(Yahrtzeit yahrtzeit) async { +// _yahrtzeits.removeWhere((y) => +// y.englishName == yahrtzeit.englishName && +// y.hebrewName == y.hebrewName && +// y.gregorianDate == y.gregorianDate); +// await _deleteFromCalendar(yahrtzeit); +// } + +// Future updateYahrtzeit(Yahrtzeit oldYahrtzeit, Yahrtzeit newYahrtzeit) async { +// final index = _yahrtzeits.indexWhere((y) => +// y.englishName == oldYahrtzeit.englishName && +// y.hebrewName == oldYahrtzeit.hebrewName && +// y.gregorianDate == oldYahrtzeit.gregorianDate); +// if (index != -1) { +// _yahrtzeits[index] = newYahrtzeit; +// await _deleteFromCalendar(oldYahrtzeit); +// await _addToCalendar(newYahrtzeit); +// } +// } + +// Future> getAllYahrtzeits() async { +// await syncWithCalendar(); +// return _yahrtzeits; +// } + +// Future> getUpcomingYahrtzeits({int days = 10}) async { +// final allYahrtzeits = await getAllYahrtzeits(); +// final now = tz.TZDateTime.now(tz.local); +// final upcomingYahrtzeits = allYahrtzeits.where((yahrtzeit) { +// final yahrtzeitDate = tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local); +// return yahrtzeitDate.isAfter(now) && yahrtzeitDate.isBefore(now.add(Duration(days: days))); +// }).toList(); +// return upcomingYahrtzeits; +// } + +// Future _addToCalendar(Yahrtzeit yahrtzeit) async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// for (var calendar in calendarsResult!.data!) { +// final event = Event( +// calendar.id!, +// title: yahrtzeit.englishName, +// description: 'Yahrtzeit for ${yahrtzeit.englishName} (${yahrtzeit.hebrewName})', +// start: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local), +// end: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local).add(Duration(hours: 1)), +// ); +// final result = await _deviceCalendarPlugin.createOrUpdateEvent(event); +// if (result?.isSuccess == false) { +// print('Error creating or updating event for ${calendar.name}: ${result?.data}'); +// } +// } +// } +// } on PlatformException catch (e) { +// print('Error adding event to calendar: $e'); +// } +// } + +// Future _deleteFromCalendar(Yahrtzeit yahrtzeit) async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// for (var calendar in calendarsResult!.data!) { +// final eventsResult = await _deviceCalendarPlugin.retrieveEvents( +// calendar.id!, +// RetrieveEventsParams( +// startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), +// endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), +// ), +// ); +// if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { +// for (var event in eventsResult!.data!) { +// if (event.title == yahrtzeit.englishName) { +// final result = await _deviceCalendarPlugin.deleteEvent(calendar.id!, event.eventId!); +// if (result?.isSuccess == false) { +// print('Error deleting event for ${calendar.name}: ${result?.data}'); +// } +// } +// } +// } +// } +// } +// } on PlatformException catch (e) { +// print('Error deleting event from calendar: $e'); +// } +// } + +// Future createGroup(String name, List yahrtzeits) async { +// final existingGroup = _groups.firstWhere( +// (group) => group.name == name && _compareYahrtzeitLists(group.yahrtzeits, yahrtzeits), +// orElse: () => Group(name: '', yahrtzeits: []), +// ); + +// if (existingGroup.name == '' && existingGroup.yahrtzeits.isEmpty) { +// final newGroup = Group(name: name, yahrtzeits: yahrtzeits); +// _groups.add(newGroup); +// await _addGroupToCalendar(newGroup); +// } +// } + + +// Future updateGroup(String oldName, String newName, List yahrtzeits) async { +// final group = _groups.firstWhere((group) => group.name == oldName); +// group.name = newName; +// group.yahrtzeits.clear(); +// group.yahrtzeits.addAll(yahrtzeits); +// await _addGroupToCalendar(group); +// } + +// Future deleteGroup(String name) async { +// final group = _groups.firstWhere((group) => group.name == name); +// _groups.remove(group); +// await _deleteGroupFromCalendar(group); +// } + +// Future _addGroupToCalendar(Group group) async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// for (var calendar in calendarsResult!.data!) { +// for (var yahrtzeit in group.yahrtzeits) { +// final event = Event( +// calendar.id!, +// title: group.name, +// description: 'Group Yahrtzeit for ${yahrtzeit.englishName} (${yahrtzeit.hebrewName})', +// start: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local), +// end: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local).add(Duration(hours: 1)), +// ); +// final result = await _deviceCalendarPlugin.createOrUpdateEvent(event); +// if (result?.isSuccess == false) { +// print('Error creating or updating event for ${calendar.name}: ${result?.data}'); +// } +// } +// } +// } +// } on PlatformException catch (e) { +// print('Error adding group to calendar: $e'); +// } +// } + +// Future _deleteGroupFromCalendar(Group group) async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// for (var calendar in calendarsResult!.data!) { +// final eventsResult = await _deviceCalendarPlugin.retrieveEvents( +// calendar.id!, +// RetrieveEventsParams( +// startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), +// endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), +// ), +// ); +// if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { +// for (var event in eventsResult!.data!) { +// if (event.title == group.name) { +// final result = await _deviceCalendarPlugin.deleteEvent(calendar.id!, event.eventId!); +// if (result?.isSuccess == false) { +// print('Error deleting event for ${calendar.name}: ${result?.data}'); +// } +// } +// } +// } +// } +// } +// } on PlatformException catch (e) { +// print('Error deleting group from calendar: $e'); +// } +// } + +// Future> getGroups() async { +// await syncWithCalendar(); +// return _groups; +// } + +// List nextMultiple(List yahrtzeits) { +// final dates = yahrtzeits.map((yahrtzeit) => YahrtzeitDate.fromYahrtzeit(yahrtzeit)).toList(); +// dates.sort((a, b) => a.gregorianDate.compareTo(b.gregorianDate)); +// return dates; +// } + +// String _extractHebrewName(String description) { +// final regex = RegExp(r'\((.*?)\)'); +// final match = regex.firstMatch(description); +// return match != null ? match.group(1)! : 'Unknown'; +// } + +// String _extractEnglishName(String description) { +// final regex = RegExp(r'Group Yahrtzeit for (.*?) \('); +// final match = regex.firstMatch(description); +// return match != null ? match.group(1)! : 'Unknown'; +// } + +// bool _compareYahrtzeitLists(List list1, List list2) { +// if (list1.length != list2.length) { +// return false; +// } +// for (var yahrtzeit in list1) { +// if (!list2.any((element) => element.englishName == yahrtzeit.englishName && element.hebrewName == yahrtzeit.hebrewName && element.gregorianDate == yahrtzeit.gregorianDate)) { +// return false; +// } +// } +// return true; +// } + +// } + + +// import 'package:device_calendar/device_calendar.dart'; +// import 'package:flutter/services.dart'; +// import 'package:timezone/timezone.dart' as tz; +// import '../models/yahrtzeit.dart'; +// import '../models/yahrtzeit_date.dart'; + +// class YahrtzeitsManager { +// static final YahrtzeitsManager _instance = YahrtzeitsManager._internal(); +// final List _yahrtzeits = []; // In-memory storage +// final DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin(); + +// factory YahrtzeitsManager() { +// return _instance; +// } + +// YahrtzeitsManager._internal(); + +// DeviceCalendarPlugin get deviceCalendarPlugin => _deviceCalendarPlugin; + +// Future syncWithCalendar() async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// print('Permissions Granted: $permissionsGranted'); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// print('Requested Permissions: $permissionsGranted'); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// print('Calendar permissions not granted'); +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// print('Calendars Result: $calendarsResult'); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// _yahrtzeits.clear(); +// for (var calendar in calendarsResult!.data!) { +// print('Retrieving events from calendar: ${calendar.name}'); +// final eventsResult = await _deviceCalendarPlugin.retrieveEvents( +// calendar.id!, +// RetrieveEventsParams( +// startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), +// endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), +// ), +// ); +// if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { +// for (var event in eventsResult!.data!) { +// if (event.description?.startsWith('Yahrtzeit for') == true) { +// final hebrewName = _extractHebrewName(event.description!); +// final yahrtzeit = Yahrtzeit( +// englishName: event.title ?? 'Unknown', +// hebrewName: hebrewName, +// day: event.start!.day, +// month: event.start!.month, +// year: event.start!.year, +// gregorianDate: event.start!, +// ); +// if (!_yahrtzeits.any((y) => +// y.englishName == yahrtzeit.englishName && +// y.hebrewName == yahrtzeit.hebrewName && +// y.gregorianDate == yahrtzeit.gregorianDate)) { +// _yahrtzeits.add(yahrtzeit); +// } +// } +// } +// } +// } +// } else { +// print('No calendars available or failed to retrieve calendars'); +// } +// } on PlatformException catch (e) { +// print('Error syncing with calendar: $e'); +// } +// } + +// Future addYahrtzeit(Yahrtzeit yahrtzeit) async { +// if (!_yahrtzeits.any((y) => +// y.englishName == yahrtzeit.englishName && +// y.hebrewName == yahrtzeit.hebrewName && +// y.gregorianDate == yahrtzeit.gregorianDate)) { +// _yahrtzeits.add(yahrtzeit); +// await _addToCalendar(yahrtzeit); +// } +// } + +// Future> getAllYahrtzeits() async { +// await syncWithCalendar(); +// return _yahrtzeits; +// } + +// Future> getUpcomingYahrtzeits({int days = 10}) async { +// final allYahrtzeits = await getAllYahrtzeits(); +// final now = tz.TZDateTime.now(tz.local); +// final upcomingYahrtzeits = allYahrtzeits.where((yahrtzeit) { +// final yahrtzeitDate = tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local); +// return yahrtzeitDate.isAfter(now) && yahrtzeitDate.isBefore(now.add(Duration(days: days))); +// }).toList(); +// return upcomingYahrtzeits; +// } + +// Future _addToCalendar(Yahrtzeit yahrtzeit) async { +// try { +// var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); +// print('Permissions Granted: $permissionsGranted'); +// if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { +// permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); +// print('Requested Permissions: $permissionsGranted'); +// if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { +// print('Calendar permissions not granted'); +// return; +// } +// } + +// final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); +// print('Calendars Result: $calendarsResult'); +// if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { +// for (var calendar in calendarsResult!.data!) { +// print('Adding event to calendar: ${calendar.name}'); +// final event = Event( +// calendar.id!, +// title: yahrtzeit.englishName, +// description: 'Yahrtzeit for ${yahrtzeit.englishName} (${yahrtzeit.hebrewName})', +// start: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local), +// end: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local).add(Duration(hours: 1)), +// ); +// print('Event Details: ${event.title}, ${event.description}, ${event.start}, ${event.end}'); +// final result = await _deviceCalendarPlugin.createOrUpdateEvent(event); +// print('Create or Update Event Result for ${calendar.name}: ${result?.data}'); +// if (result?.isSuccess == false) { +// print('Error creating or updating event for ${calendar.name}: ${result?.data}'); +// } +// } +// } else { +// print('No calendars available or failed to retrieve calendars'); +// } +// } on PlatformException catch (e) { +// print('Error adding event to calendar: $e'); +// } +// } + +// List nextMultiple(List yahrtzeits) { +// final dates = yahrtzeits.map((yahrtzeit) => YahrtzeitDate.fromYahrtzeit(yahrtzeit)).toList(); +// dates.sort((a, b) => a.gregorianDate.compareTo(b.gregorianDate)); +// return dates; +// } + +// String _extractHebrewName(String description) { +// final regex = RegExp(r'\((.*?)\)'); +// final match = regex.firstMatch(description); +// return match != null ? match.group(1)! : 'Unknown'; +// } +// } + + import 'package:device_calendar/device_calendar.dart'; import 'package:flutter/services.dart'; import 'package:timezone/timezone.dart' as tz; import '../models/yahrtzeit.dart'; import '../models/yahrtzeit_date.dart'; +import '../models/group.dart'; class YahrtzeitsManager { static final YahrtzeitsManager _instance = YahrtzeitsManager._internal(); final List _yahrtzeits = []; // In-memory storage + final List _groups = []; // In-memory storage for groups final DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin(); factory YahrtzeitsManager() { @@ -17,25 +535,71 @@ class YahrtzeitsManager { DeviceCalendarPlugin get deviceCalendarPlugin => _deviceCalendarPlugin; + // Future syncWithCalendar() async { + // try { + // var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); + // if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { + // permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); + // if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { + // return; + // } + // } + + // final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); + // if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { + // _yahrtzeits.clear(); + // for (var calendar in calendarsResult!.data!) { + // final eventsResult = await _deviceCalendarPlugin.retrieveEvents( + // calendar.id!, + // RetrieveEventsParams( + // startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), + // endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), + // ), + // ); + // if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { + // for (var event in eventsResult!.data!) { + // if (event.description?.startsWith('Yahrtzeit for') == true) { + // final hebrewName = _extractHebrewName(event.description!); + // final yahrtzeit = Yahrtzeit( + // englishName: event.title ?? 'Unknown', + // hebrewName: hebrewName, + // day: event.start!.day, + // month: event.start!.month, + // year: event.start!.year, + // gregorianDate: event.start!, + // ); + // if (!_yahrtzeits.any((y) => + // y.englishName == yahrtzeit.englishName && + // y.hebrewName == y.hebrewName && + // y.gregorianDate == y.gregorianDate)) { + // _yahrtzeits.add(yahrtzeit); + // } + // } + // } + // } + // } + // } + + // await _loadGroupsFromCalendar(calendarsResult!.data!); + // } on PlatformException catch (e) { + // print('Error syncing with calendar: $e'); + // } + // } + Future syncWithCalendar() async { try { var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); - print('Permissions Granted: $permissionsGranted'); if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); - print('Requested Permissions: $permissionsGranted'); if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { - print('Calendar permissions not granted'); return; } } final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); - print('Calendars Result: $calendarsResult'); if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { _yahrtzeits.clear(); for (var calendar in calendarsResult!.data!) { - print('Retrieving events from calendar: ${calendar.name}'); final eventsResult = await _deviceCalendarPlugin.retrieveEvents( calendar.id!, RetrieveEventsParams( @@ -65,37 +629,118 @@ class YahrtzeitsManager { } } } - } else { - print('No calendars available or failed to retrieve calendars'); } - } on PlatformException catch (e) { + } catch (e) { print('Error syncing with calendar: $e'); } } - Future addYahrtzeit(Yahrtzeit yahrtzeit) async { - if (!_yahrtzeits.any((y) => - y.englishName == yahrtzeit.englishName && - y.hebrewName == yahrtzeit.hebrewName && - y.gregorianDate == yahrtzeit.gregorianDate)) { - _yahrtzeits.add(yahrtzeit); - await _addToCalendar(yahrtzeit); + + + + + + + + + + + + + Future _loadGroupsFromCalendar(List calendars) async { + try { + _groups.clear(); + for (var calendar in calendars) { + final eventsResult = await _deviceCalendarPlugin.retrieveEvents( + calendar.id!, + RetrieveEventsParams( + startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), + endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), + ), + ); + if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { + final groupsMap = >{}; + for (var event in eventsResult!.data!) { + if (event.description?.startsWith('Group Yahrtzeit for') == true) { + final groupName = event.title ?? 'Unknown Group'; + final yahrtzeit = Yahrtzeit( + englishName: _extractEnglishName(event.description!), + hebrewName: _extractHebrewName(event.description!), + day: event.start!.day, + month: event.start!.month, + year: event.start!.year, + gregorianDate: event.start!, + ); + if (groupsMap.containsKey(groupName)) { + groupsMap[groupName]!.add(yahrtzeit); + } else { + groupsMap[groupName] = [yahrtzeit]; + } + } + } + for (var entry in groupsMap.entries) { + _groups.add(Group(name: entry.key, yahrtzeits: entry.value)); + } + } + } + } on PlatformException catch (e) { + print('Error loading groups from calendar: $e'); } } - Future updateYahrtzeit(Yahrtzeit oldYahrtzeit, Yahrtzeit newYahrtzeit) async { - await deleteYahrtzeit(oldYahrtzeit); - await addYahrtzeit(newYahrtzeit); + // Future addYahrtzeit(Yahrtzeit yahrtzeit) async { + // if (!_yahrtzeits.any((y) => + // y.englishName == yahrtzeit.englishName && + // y.hebrewName == y.hebrewName && + // y.gregorianDate == y.gregorianDate)) { + // _yahrtzeits.add(yahrtzeit); + // await _addToCalendar(yahrtzeit); + // } + // } + + Future addYahrtzeit(Yahrtzeit yahrtzeit) async { + _yahrtzeits.add(yahrtzeit); } + + + + + + + + + + + + + + + + + + + Future deleteYahrtzeit(Yahrtzeit yahrtzeit) async { _yahrtzeits.removeWhere((y) => y.englishName == yahrtzeit.englishName && - y.hebrewName == yahrtzeit.hebrewName && - y.gregorianDate == yahrtzeit.gregorianDate); + y.hebrewName == y.hebrewName && + y.gregorianDate == y.gregorianDate); await _deleteFromCalendar(yahrtzeit); } + Future updateYahrtzeit(Yahrtzeit oldYahrtzeit, Yahrtzeit newYahrtzeit) async { + final index = _yahrtzeits.indexWhere((y) => + y.englishName == oldYahrtzeit.englishName && + y.hebrewName == oldYahrtzeit.hebrewName && + y.gregorianDate == oldYahrtzeit.gregorianDate); + if (index != -1) { + _yahrtzeits[index] = newYahrtzeit; + await _deleteFromCalendar(oldYahrtzeit); + await _addToCalendar(newYahrtzeit); + } + } + Future> getAllYahrtzeits() async { await syncWithCalendar(); return _yahrtzeits; @@ -114,21 +759,16 @@ class YahrtzeitsManager { Future _addToCalendar(Yahrtzeit yahrtzeit) async { try { var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); - print('Permissions Granted: $permissionsGranted'); if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); - print('Requested Permissions: $permissionsGranted'); if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { - print('Calendar permissions not granted'); return; } } final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); - print('Calendars Result: $calendarsResult'); if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { for (var calendar in calendarsResult!.data!) { - print('Adding event to calendar: ${calendar.name}'); final event = Event( calendar.id!, title: yahrtzeit.englishName, @@ -136,15 +776,11 @@ class YahrtzeitsManager { start: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local), end: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local).add(Duration(hours: 1)), ); - print('Event Details: ${event.title}, ${event.description}, ${event.start}, ${event.end}'); final result = await _deviceCalendarPlugin.createOrUpdateEvent(event); - print('Create or Update Event Result for ${calendar.name}: ${result?.data}'); if (result?.isSuccess == false) { print('Error creating or updating event for ${calendar.name}: ${result?.data}'); } } - } else { - print('No calendars available or failed to retrieve calendars'); } } on PlatformException catch (e) { print('Error adding event to calendar: $e'); @@ -153,6 +789,14 @@ class YahrtzeitsManager { Future _deleteFromCalendar(Yahrtzeit yahrtzeit) async { try { + var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); + if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { + permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); + if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { + return; + } + } + final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { for (var calendar in calendarsResult!.data!) { @@ -165,8 +809,11 @@ class YahrtzeitsManager { ); if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { for (var event in eventsResult!.data!) { - if (event.description?.startsWith('Yahrtzeit for ${yahrtzeit.englishName} (${yahrtzeit.hebrewName})') == true) { - await _deviceCalendarPlugin.deleteEvent(calendar.id!, event.eventId!); + if (event.title == yahrtzeit.englishName) { + final result = await _deviceCalendarPlugin.deleteEvent(calendar.id!, event.eventId!); + if (result?.isSuccess == false) { + print('Error deleting event for ${calendar.name}: ${result?.data}'); + } } } } @@ -177,6 +824,113 @@ class YahrtzeitsManager { } } +// Future createGroup(String name, List yahrtzeits) async { +// final existingGroup = _groups.firstWhere( +// (group) => group.name == name && _compareYahrtzeitLists(group.yahrtzeits, yahrtzeits), +// orElse: () => Group(name: '', yahrtzeits: []), +// ); + +// if (existingGroup.name == '' && existingGroup.yahrtzeits.isEmpty) { +// final newGroup = Group(name: name, yahrtzeits: yahrtzeits); +// _groups.add(newGroup); +// await _addGroupToCalendar(newGroup); +// } +// } + + Future createGroup(String groupName, List yahrtzeits) async { + final group = Group(name: groupName, yahrtzeits: yahrtzeits); + _groups.add(group); + } + + + Future updateGroup(String oldName, String newName, List yahrtzeits) async { + final index = _groups.indexWhere((g) => g.name == oldName); + if (index != -1) { + _groups[index] = Group(name: newName, yahrtzeits: yahrtzeits); + } + } + + Future deleteGroup(String name) async { + final group = _groups.firstWhere((group) => group.name == name); + _groups.remove(group); + await _deleteGroupFromCalendar(group); + } + + Future _addGroupToCalendar(Group group) async { + try { + var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); + if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { + permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); + if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { + return; + } + } + + final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); + if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { + for (var calendar in calendarsResult!.data!) { + for (var yahrtzeit in group.yahrtzeits) { + final event = Event( + calendar.id!, + title: group.name, + description: 'Group Yahrtzeit for ${yahrtzeit.englishName} (${yahrtzeit.hebrewName})', + start: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local), + end: tz.TZDateTime.from(yahrtzeit.getGregorianDate(), tz.local).add(Duration(hours: 1)), + ); + final result = await _deviceCalendarPlugin.createOrUpdateEvent(event); + if (result?.isSuccess == false) { + print('Error creating or updating event for ${calendar.name}: ${result?.data}'); + } + } + } + } + } on PlatformException catch (e) { + print('Error adding group to calendar: $e'); + } + } + + Future _deleteGroupFromCalendar(Group group) async { + try { + var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); + if (permissionsGranted?.isSuccess == true && permissionsGranted?.data == false) { + permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); + if (permissionsGranted?.isSuccess == false || permissionsGranted?.data == false) { + return; + } + } + + final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); + if (calendarsResult?.isSuccess == true && calendarsResult?.data!.isNotEmpty == true) { + for (var calendar in calendarsResult!.data!) { + final eventsResult = await _deviceCalendarPlugin.retrieveEvents( + calendar.id!, + RetrieveEventsParams( + startDate: tz.TZDateTime.now(tz.local).subtract(Duration(days: 365)), + endDate: tz.TZDateTime.now(tz.local).add(Duration(days: 365)), + ), + ); + if (eventsResult?.isSuccess == true && eventsResult?.data!.isNotEmpty == true) { + for (var event in eventsResult!.data!) { + if (event.title == group.name) { + final result = await _deviceCalendarPlugin.deleteEvent(calendar.id!, event.eventId!); + if (result?.isSuccess == false) { + print('Error deleting event for ${calendar.name}: ${result?.data}'); + } + } + } + } + } + } + } on PlatformException catch (e) { + print('Error deleting group from calendar: $e'); + } + } + + Future> getGroups() async { + await syncWithCalendar(); + return _groups; + } + List nextMultiple(List yahrtzeits) { final dates = yahrtzeits.map((yahrtzeit) => YahrtzeitDate.fromYahrtzeit(yahrtzeit)).toList(); dates.sort((a, b) => a.gregorianDate.compareTo(b.gregorianDate)); @@ -188,4 +942,23 @@ class YahrtzeitsManager { final match = regex.firstMatch(description); return match != null ? match.group(1)! : 'Unknown'; } + + String _extractEnglishName(String description) { + final regex = RegExp(r'Group Yahrtzeit for (.*?) \('); + final match = regex.firstMatch(description); + return match != null ? match.group(1)! : 'Unknown'; + } + +bool _compareYahrtzeitLists(List list1, List list2) { + if (list1.length != list2.length) { + return false; + } + for (var yahrtzeit in list1) { + if (!list2.any((element) => element.englishName == yahrtzeit.englishName && element.hebrewName == yahrtzeit.hebrewName && element.gregorianDate == yahrtzeit.gregorianDate)) { + return false; + } + } + return true; } + +} \ No newline at end of file diff --git a/lib/settings/settings.dart b/lib/settings/settings.dart index 5352bc4..de94be8 100644 --- a/lib/settings/settings.dart +++ b/lib/settings/settings.dart @@ -1,3 +1,67 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import '../localizations/app_localizations.dart'; +// import '../main.dart'; + +// class SettingsPage extends StatelessWidget { +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text(AppLocalizations.of(context)!.translate('settings'), style: TextStyle(color: Colors.white)), + // backgroundColor: Color.fromARGB(255, 50, 4, 129), + // centerTitle: true, + // ), + // body: ListView( + // children: [ + // ListTile( + // title: Text(AppLocalizations.of(context)!.translate('language')), + // trailing: DropdownButton( + // value: Localizations.localeOf(context), + // items: [ + // DropdownMenuItem( + // value: Locale('en', 'US'), + // child: Text('English'), + // ), + // DropdownMenuItem( + // value: Locale('he', 'IL'), + // child: Text('עברית'), + // ), + // ], + // onChanged: (Locale? newValue) { + // if (newValue != null) { + // Provider.of(context, listen: false).setLocale(newValue); + // } + // }, + // ), + // ), +// ListTile( +// title: Text(AppLocalizations.of(context)!.translate('sync_settings')), +// trailing: Switch( +// value: true, +// onChanged: (value) { +// // עדכן את הגדרות הסנכרון +// }, +// ), +// ), +// ListTile( +// title: Text(AppLocalizations.of(context)!.translate('notifications')), +// trailing: Switch( +// value: true, +// onChanged: (value) { +// // עדכן את הגדרות ההתראות +// }, +// ), +// ), +// ], +// ), +// ); +// } +// } + +//sheli!!!!! + + // import 'package:flutter/material.dart'; // class SettingsPage extends StatefulWidget { @@ -207,8 +271,261 @@ // } // } +////racheli +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import '../localizations/app_localizations.dart'; +// import '../main.dart'; + + +// class SettingsPage extends StatefulWidget { +// final bool syncSettings; +// final bool notifications; +// final String language; +// final String jewishLanguage; +// final String calendar; +// final int years; +// final int days; +// final VoidCallback toggleSyncSettings; +// final VoidCallback toggleNotifications; +// final Function(String) changeLanguage; +// final Function(String) changeJewishLanguage; +// final Function(String) changeCalendar; +// final Function(int) changeYears; +// final Function(int) changeDays; + +// SettingsPage({ +// required this.syncSettings, +// required this.notifications, +// required this.language, +// required this.jewishLanguage, +// required this.calendar, +// required this.years, +// required this.days, +// required this.toggleSyncSettings, +// required this.toggleNotifications, +// required this.changeLanguage, +// required this.changeJewishLanguage, +// required this.changeCalendar, +// required this.changeYears, +// required this.changeDays, +// }); + +// @override +// _SettingsPageState createState() => _SettingsPageState(); +// } + +// class _SettingsPageState extends State { +// String? _language; +// String? _jewishLanguage; +// String? _calendar; +// int? _years; +// int? _days; + +// @override +// void initState() { +// super.initState(); +// // Initialize the local state with the values passed in +// _language = widget.language; +// _jewishLanguage = widget.jewishLanguage; +// _calendar = widget.calendar; +// _years = widget.years; +// _days = widget.days; +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// // title: Text('Settings'), + + +// ), +// body: ListView( +// children: [ +// ListTile( +// title: Text( +// 'Language Settings', +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), +// ), +// ), +// ListTile( +// title: Text('Language'), +// trailing: DropdownButton( +// value: _language, +// items: [ +// DropdownMenuItem( +// value: 'en', +// child: Text('English'), +// ), +// DropdownMenuItem( +// value: 'he', +// child: Text('Hebrew'), +// ), +// DropdownMenuItem( +// value: 'es', +// child: Text('Spanish'), +// ), +// ], +// onChanged: (value) { +// setState(() { +// _language = value; +// }); +// if (value != null) { +// widget.changeLanguage(value); +// } +// }, +// ), +// ), +// ListTile( +// title: Text('Jewish Language'), +// trailing: DropdownButton( +// value: _jewishLanguage, +// items: [ +// DropdownMenuItem( +// value: 'en', +// child: Text('English'), +// ), +// DropdownMenuItem( +// value: 'he', +// child: Text('Hebrew'), +// ), +// DropdownMenuItem( +// value: 'es', +// child: Text('Spanish'), +// ), +// ], +// onChanged: (value) { +// setState(() { +// _jewishLanguage = value; +// }); +// if (value != null) { +// widget.changeJewishLanguage(value); +// } +// }, +// ), +// ), +// ListTile( +// title: Text( +// 'Sync Settings', +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), +// ), +// ), +// ListTile( +// title: Text(widget.syncSettings ? 'On' : 'Off'), +// trailing: Switch( +// value: widget.syncSettings, +// onChanged: (value) { +// widget.toggleSyncSettings(); +// }, +// activeColor: Colors.white, +// activeTrackColor: Colors.grey[600], +// inactiveThumbColor: Colors.grey[600], +// inactiveTrackColor: Colors.grey[300], +// ), +// ), +// ListTile( +// title: Text('Years'), +// trailing: DropdownButton( +// value: _years, +// items: List.generate(10, (index) => index + 1).map((int value) { +// return DropdownMenuItem( +// value: value, +// child: Text(value.toString()), +// ); +// }).toList(), +// onChanged: (value) { +// setState(() { +// _years = value; +// }); +// if (value != null) { +// widget.changeYears(value); +// } +// }, +// ), +// ), +// ListTile( +// title: Text( +// 'Notifications Settings', +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), +// ), +// ), +// ListTile( +// title: Text(widget.notifications ? 'On' : 'Off'), +// trailing: Switch( +// value: widget.notifications, +// onChanged: (value) { +// widget.toggleNotifications(); +// }, +// activeColor: Colors.white, +// activeTrackColor: Colors.grey[600], +// inactiveThumbColor: Colors.grey[600], +// inactiveTrackColor: Colors.grey[300], +// ), +// ), +// ListTile( +// title: Text('Days Before'), +// trailing: DropdownButton( +// value: _days, +// items: List.generate(15, (index) => index + 1).map((int value) { +// return DropdownMenuItem( +// value: value, +// child: Text(value.toString()), +// ); +// }).toList(), +// onChanged: (value) { +// setState(() { +// _days = value; +// }); +// if (value != null) { +// widget.changeDays(value); +// } +// }, +// ), +// ), +// ListTile( +// title: Text( +// 'Calendar Settings', +// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), +// ), +// ), +// ListTile( +// title: Text('Default calendar'), +// trailing: DropdownButton( +// value: _calendar, +// items: [ +// DropdownMenuItem( +// value: 'google', +// child: Text('Google Calendar'), +// ), +// DropdownMenuItem( +// value: 'device', +// child: Text('Device Calendar'), +// ), +// ], +// onChanged: (value) { +// setState(() { +// _calendar = value; +// }); +// if (value != null) { +// widget.changeCalendar(value); +// } +// }, +// ), +// ), +// ], +// ), +// ); +// } +// } + + + import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../localizations/app_localizations.dart'; +import '../main.dart'; class SettingsPage extends StatefulWidget { final bool syncSettings; @@ -269,48 +586,35 @@ class _SettingsPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Settings', style: TextStyle(color: Colors.white),), + title: Text(AppLocalizations.of(context)!.translate('settings'), style: TextStyle(color: Colors.white)), backgroundColor: Color.fromARGB(255, 50, 4, 129), centerTitle: true, ), body: ListView( children: [ ListTile( - title: Text( - 'Language Settings', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), - ), - ), - ListTile( - title: Text('Language'), - trailing: DropdownButton( - value: _language, + title: Text(AppLocalizations.of(context)!.translate('language')), + trailing: DropdownButton( + value: Localizations.localeOf(context), items: [ DropdownMenuItem( - value: 'en', + value: Locale('en', 'US'), child: Text('English'), ), DropdownMenuItem( - value: 'he', - child: Text('Hebrew'), - ), - DropdownMenuItem( - value: 'es', - child: Text('Spanish'), + value: Locale('he', 'IL'), + child: Text('עברית'), ), ], - onChanged: (value) { - setState(() { - _language = value; - }); - if (value != null) { - widget.changeLanguage(value); + onChanged: (Locale? newValue) { + if (newValue != null) { + Provider.of(context, listen: false).setLocale(newValue); } }, ), ), ListTile( - title: Text('Jewish Language'), + title: Text(AppLocalizations.of(context)!.translate('jewish_language')), trailing: DropdownButton( value: _jewishLanguage, items: [ @@ -338,13 +642,7 @@ class _SettingsPageState extends State { ), ), ListTile( - title: Text( - 'Sync Settings', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), - ), - ), - ListTile( - title: Text(widget.syncSettings ? 'On' : 'Off'), + title: Text(AppLocalizations.of(context)!.translate('sync_settings')), trailing: Switch( value: widget.syncSettings, onChanged: (value) { @@ -357,7 +655,7 @@ class _SettingsPageState extends State { ), ), ListTile( - title: Text('Years'), + title: Text(AppLocalizations.of(context)!.translate('years')), trailing: DropdownButton( value: _years, items: List.generate(10, (index) => index + 1).map((int value) { @@ -377,13 +675,7 @@ class _SettingsPageState extends State { ), ), ListTile( - title: Text( - 'Notifications Settings', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), - ), - ), - ListTile( - title: Text(widget.notifications ? 'On' : 'Off'), + title: Text(AppLocalizations.of(context)!.translate('notifications')), trailing: Switch( value: widget.notifications, onChanged: (value) { @@ -396,7 +688,7 @@ class _SettingsPageState extends State { ), ), ListTile( - title: Text('Days Before'), + title: Text(AppLocalizations.of(context)!.translate('days_before')), trailing: DropdownButton( value: _days, items: List.generate(15, (index) => index + 1).map((int value) { @@ -416,23 +708,17 @@ class _SettingsPageState extends State { ), ), ListTile( - title: Text( - 'Calendar Settings', - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24), - ), - ), - ListTile( - title: Text('Default calendar'), + title: Text(AppLocalizations.of(context)!.translate('calendar_settings')), trailing: DropdownButton( value: _calendar, items: [ DropdownMenuItem( value: 'google', - child: Text('Google Calendar'), + child: Text(AppLocalizations.of(context)!.translate('Google Calendar')), ), DropdownMenuItem( value: 'device', - child: Text('Device Calendar'), + child: Text(AppLocalizations.of(context)!.translate('Device Calendar')), ), ], onChanged: (value) { diff --git a/lib/views/add_yahrtzeit.dart b/lib/views/add_yahrtzeit.dart index 46667d8..189ff1c 100644 --- a/lib/views/add_yahrtzeit.dart +++ b/lib/views/add_yahrtzeit.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import '../localizations/app_localizations.dart'; import '../models/yahrtzeit.dart'; import '../services/yahrtzeits_manager.dart'; @@ -33,7 +34,8 @@ class _AddYahrtzeitPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(widget.isEditing ? 'Edit Yahrtzeit' : 'Add Yahrtzeit'), + // title: Text(widget.isEditing ? 'Edit Yahrtzeit' : 'Add Yahrtzeit'), + title: Text(widget.isEditing ? AppLocalizations.of(context)!.translate('Edit Yahrtzeit') : AppLocalizations.of(context)!.translate('Add Yahrtzeit')), ), body: Padding( padding: const EdgeInsets.all(16.0), @@ -43,20 +45,24 @@ class _AddYahrtzeitPageState extends State { children: [ TextFormField( controller: _englishNameController, - decoration: InputDecoration(labelText: 'English Name'), + // decoration: InputDecoration(labelText: 'English Name'), + // title: Text(AppLocalizations.of(context)!.translate('settings'), style: TextStyle(color: Colors.white)), + decoration: InputDecoration( labelText: (AppLocalizations.of(context)!.translate('Jewish Name'))), + + validator: (value) { if (value == null || value.isEmpty) { - return 'Please enter English name'; + return (AppLocalizations.of(context)!.translate('Please enter English name')); } return null; }, ), TextFormField( controller: _hebrewNameController, - decoration: InputDecoration(labelText: 'Hebrew Name'), + decoration: InputDecoration( labelText: (AppLocalizations.of(context)!.translate('Full Name'))), validator: (value) { if (value == null || value.isEmpty) { - return 'Please enter Hebrew name'; + return (AppLocalizations.of(context)!.translate('Please enter Hebrew name')); } return null; }, @@ -64,8 +70,9 @@ class _AddYahrtzeitPageState extends State { ListTile( title: Text( _selectedDate == null - ? 'Select Date' - : 'Selected Date: ${_selectedDate!.toLocal()}'.split(' ')[0], + ? (AppLocalizations.of(context)!.translate('Select Date')) + :(AppLocalizations.of(context)!.translate('Select Date:${_selectedDate!.toLocal()}')) + .split(' ')[0], ), trailing: Icon(Icons.calendar_today), onTap: _pickDate, @@ -73,7 +80,7 @@ class _AddYahrtzeitPageState extends State { SizedBox(height: 20), ElevatedButton( onPressed: _saveYahrtzeit, - child: Text(widget.isEditing ? 'Update' : 'Save'), + child: Text(widget.isEditing ? (AppLocalizations.of(context)!.translate('Update')) :(AppLocalizations.of(context)!.translate('Save')) ), ), ], ), diff --git a/lib/views/create_group.dart b/lib/views/create_group.dart new file mode 100644 index 0000000..3ba59fb --- /dev/null +++ b/lib/views/create_group.dart @@ -0,0 +1,153 @@ +// import 'package:flutter/material.dart'; +// import '../models/yahrtzeit.dart'; +// import '../models/group.dart'; // Import the Group class +// import '../services/yahrtzeits_manager.dart'; + +// class GroupsPage extends StatefulWidget { +// @override +// _GroupsPageState createState() => _GroupsPageState(); +// } + +// class _GroupsPageState extends State { +// final YahrtzeitsManager manager = YahrtzeitsManager(); +// List groups = []; + +// @override +// void initState() { +// super.initState(); +// fetchGroups(); +// } + +// Future fetchGroups() async { +// final fetchedGroups = await manager.getGroups(); +// setState(() { +// groups = fetchedGroups; +// }); +// } + +// void _createGroup() async { +// String groupName = ''; +// final selectedYahrtzeits = await manager.getAllYahrtzeits(); +// showDialog( +// context: context, +// builder: (context) { +// return StatefulBuilder( +// builder: (context, setState) { +// return AlertDialog( +// title: Text('Create New Group'), +// content: SingleChildScrollView( +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// TextField( +// onChanged: (value) { +// groupName = value; +// }, +// decoration: InputDecoration(labelText: 'Group Name'), +// ), +// ListView.builder( +// shrinkWrap: true, +// itemCount: selectedYahrtzeits.length, +// itemBuilder: (context, index) { +// final yahrtzeit = selectedYahrtzeits[index]; +// return CheckboxListTile( +// title: Text(yahrtzeit.englishName), +// subtitle: Text(yahrtzeit.hebrewName), +// value: yahrtzeit.selected, +// onChanged: (bool? value) { +// setState(() { +// yahrtzeit.selected = value ?? false; +// }); +// }, +// ); +// }, +// ), +// ], +// ), +// ), +// actions: [ +// TextButton( +// onPressed: () { +// Navigator.pop(context); +// }, +// child: Text('Cancel'), +// ), +// ElevatedButton( +// onPressed: () async { +// await manager.createGroup(groupName, selectedYahrtzeits.where((y) => y.selected).toList()); +// fetchGroups(); +// Navigator.pop(context); +// }, +// child: Text('Create Group'), +// ), +// ], +// ); +// }, +// ); +// }, +// ); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text('Groups'), +// actions: [ +// IconButton( +// icon: Icon(Icons.add), +// onPressed: _createGroup, +// ), +// ], +// ), +// body: groups.isEmpty +// ? Center(child: Text('No groups created yet.')) +// : ListView.builder( +// itemCount: groups.length, +// itemBuilder: (context, index) { +// final group = groups[index]; +// return Card( +// elevation: 5, +// margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), +// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), +// child: ListTile( +// title: Text(group.name), +// subtitle: Text('${group.yahrtzeits.length} yahrtzeits'), +// onTap: () { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => GroupDetailsPage(group: group)), +// ); +// }, +// ), +// ); +// }, +// ), +// ); +// } +// } + +// class GroupDetailsPage extends StatelessWidget { +// final Group group; + +// GroupDetailsPage({required this.group}); + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text(group.name), +// ), +// body: ListView.builder( +// itemCount: group.yahrtzeits.length, +// itemBuilder: (context, index) { +// final yahrtzeit = group.yahrtzeits[index]; +// return ListTile( +// title: Text(yahrtzeit.englishName), +// subtitle: Text(yahrtzeit.hebrewName), +// ); +// }, +// ), +// ); +// } +// } diff --git a/lib/views/groups_page.dart b/lib/views/groups_page.dart new file mode 100644 index 0000000..6493efb --- /dev/null +++ b/lib/views/groups_page.dart @@ -0,0 +1,531 @@ +// import 'package:flutter/material.dart'; +// import '../localizations/app_localizations.dart'; +// import '../models/yahrtzeit.dart'; +// import '../models/group.dart'; +// import '../services/yahrtzeits_manager.dart'; + +// class GroupsPage extends StatefulWidget { +// @override +// _GroupsPageState createState() => _GroupsPageState(); +// } + +// class _GroupsPageState extends State { +// final YahrtzeitsManager manager = YahrtzeitsManager(); +// List groups = []; + +// @override +// void initState() { +// super.initState(); +// fetchGroups(); +// } + +// Future fetchGroups() async { +// final fetchedGroups = await manager.getGroups(); +// setState(() { +// groups = fetchedGroups; +// }); +// } + +// void _createGroup() async { +// String groupName = ''; +// final selectedYahrtzeits = await manager.getAllYahrtzeits(); +// showDialog( +// context: context, +// builder: (context) { +// return StatefulBuilder( +// builder: (context, setState) { +// return AlertDialog( +// title: Text('Create New Group'), +// content: Container( +// width: double.maxFinite, +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// TextField( +// onChanged: (value) { +// groupName = value; +// }, +// decoration: InputDecoration(labelText: 'Group Name'), +// ), +// Expanded( +// child: ListView.builder( +// itemCount: selectedYahrtzeits.length, +// itemBuilder: (context, index) { +// final yahrtzeit = selectedYahrtzeits[index]; +// return CheckboxListTile( +// title: Text(yahrtzeit.englishName), +// subtitle: Text(yahrtzeit.hebrewName), +// value: yahrtzeit.selected, +// onChanged: (bool? value) { +// setState(() { +// yahrtzeit.selected = value ?? false; +// }); +// }, +// ); +// }, +// ), +// ), +// ], +// ), +// ), +// actions: [ +// TextButton( +// onPressed: () { +// Navigator.pop(context); +// }, +// child: Text('Cancel'), +// ), +// ElevatedButton( +// onPressed: () async { +// await manager.createGroup(groupName, selectedYahrtzeits.where((y) => y.selected).toList()); +// fetchGroups(); +// Navigator.pop(context); +// }, +// child: Text('Create Group'), +// ), +// ], +// ); +// }, +// ); +// }, +// ); +// } + +// void _editGroup(Group group) async { +// String groupName = group.name; +// final selectedYahrtzeits = List.from(group.yahrtzeits); +// showDialog( +// context: context, +// builder: (context) { +// return StatefulBuilder( +// builder: (context, setState) { +// return AlertDialog( +// title: Text('Edit Group'), +// content: Container( +// width: double.maxFinite, +// child: Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// TextField( +// onChanged: (value) { +// groupName = value; +// }, +// decoration: InputDecoration(labelText: 'Group Name', hintText: group.name), +// ), +// Expanded( +// child: ListView.builder( +// itemCount: selectedYahrtzeits.length, +// itemBuilder: (context, index) { +// final yahrtzeit = selectedYahrtzeits[index]; +// return CheckboxListTile( +// title: Text(yahrtzeit.englishName), +// subtitle: Text(yahrtzeit.hebrewName), +// value: yahrtzeit.selected, +// onChanged: (bool? value) { +// setState(() { +// yahrtzeit.selected = value ?? false; +// }); +// }, +// ); +// }, +// ), +// ), +// ], +// ), +// ), +// actions: [ +// TextButton( +// onPressed: () { +// Navigator.pop(context); +// }, +// child: Text('Cancel'), +// ), +// ElevatedButton( +// onPressed: () async { +// await manager.updateGroup(group.name, groupName, selectedYahrtzeits.where((y) => y.selected).toList()); +// fetchGroups(); +// Navigator.pop(context); +// }, +// child: Text('Save Changes'), +// ), +// ], +// ); +// }, +// ); +// }, +// ); +// } + +// void _deleteGroup(Group group) async { +// await manager.deleteGroup(group.name); +// fetchGroups(); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text(AppLocalizations.of(context)!.translate('Groups')), +// actions: [ +// IconButton( +// icon: Icon(Icons.add), +// onPressed: _createGroup, +// ), +// ], +// ), +// body: groups.isEmpty +// ? Center(child: Text('No groups created yet.')) +// : ListView.builder( +// itemCount: groups.length, +// itemBuilder: (context, index) { +// final group = groups[index]; +// return Card( +// elevation: 5, +// margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), +// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), +// child: ListTile( +// title: Text(group.name), +// subtitle: Text('${group.yahrtzeits.length} yahrtzeits'), +// onTap: () { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => GroupDetailsPage(group: group)), +// ); +// }, +// trailing: Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// IconButton( +// icon: Icon(Icons.edit), +// onPressed: () { +// _editGroup(group); +// }, +// ), +// IconButton( +// icon: Icon(Icons.delete), +// onPressed: () { +// _deleteGroup(group); +// }, +// ), +// ], +// ), +// ), +// ); +// }, +// ), +// ); +// } +// } + +// class GroupDetailsPage extends StatelessWidget { +// final Group group; + +// GroupDetailsPage({required this.group}); + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text(group.name), +// ), +// body: ListView.builder( +// itemCount: group.yahrtzeits.length, +// itemBuilder: (context, index) { +// final yahrtzeit = group.yahrtzeits[index]; +// return ListTile( +// title: Text(yahrtzeit.englishName), +// subtitle: Text(yahrtzeit.hebrewName), +// ); +// }, +// ), +// ); +// } +// } + +import 'package:flutter/material.dart'; +import '../localizations/app_localizations.dart'; +import '../models/yahrtzeit.dart'; +import '../models/group.dart'; +import '../services/yahrtzeits_manager.dart'; + +class GroupsPage extends StatefulWidget { + @override + _GroupsPageState createState() => _GroupsPageState(); +} + +class _GroupsPageState extends State { + final YahrtzeitsManager manager = YahrtzeitsManager(); + List groups = []; + + @override + void initState() { + super.initState(); + fetchGroups(); + } + + Future fetchGroups() async { + final fetchedGroups = await manager.getGroups(); + setState(() { + groups = fetchedGroups; + }); + } + + void _createGroup() async { + String groupName = ''; + final selectedYahrtzeits = await manager.getAllYahrtzeits(); + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text('Create New Group'), + content: Container( + width: double.maxFinite, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + onChanged: (value) { + groupName = value; + }, + decoration: InputDecoration(labelText: 'Group Name'), + ), + Expanded( + child: ListView.builder( + itemCount: selectedYahrtzeits.length, + itemBuilder: (context, index) { + final yahrtzeit = selectedYahrtzeits[index]; + return CheckboxListTile( + title: Text(yahrtzeit.englishName), + subtitle: Text(yahrtzeit.hebrewName), + value: yahrtzeit.selected, + onChanged: (bool? value) { + setState(() { + yahrtzeit.selected = value ?? false; + }); + }, + ); + }, + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () async { + await manager.createGroup(groupName, selectedYahrtzeits.where((y) => y.selected).toList()); + fetchGroups(); + Navigator.pop(context); + }, + child: Text('Create Group'), + ), + ], + ); + }, + ); + }, + ); + } + + + + void _editGroup(Group group) async { + String groupName = group.name; + final selectedYahrtzeits = List.from(group.yahrtzeits); + + // Get all Yahrtzeits that are not in the group + final allYahrtzeits = await manager.getAllYahrtzeits(); + final notInGroup = allYahrtzeits.where((y) => + !selectedYahrtzeits.any((groupYahrtzeit) => + groupYahrtzeit.englishName == y.englishName && + groupYahrtzeit.hebrewName == y.hebrewName + ) + ).toList(); + + showDialog( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Text('Edit Group'), + content: Container( + width: double.maxFinite, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + onChanged: (value) { + groupName = value; + }, + decoration: InputDecoration(labelText: 'Group Name', hintText: group.name), + ), + Expanded( + child: Column( + children: [ + // Yahrtzeits already in the group + Expanded( + child: ListView.builder( + itemCount: selectedYahrtzeits.length, + itemBuilder: (context, index) { + final yahrtzeit = selectedYahrtzeits[index]; + return CheckboxListTile( + title: Text(yahrtzeit.englishName), + subtitle: Text(yahrtzeit.hebrewName), + value: yahrtzeit.selected, + onChanged: (bool? value) { + setState(() { + yahrtzeit.selected = value ?? false; + }); + }, + ); + }, + ), + ), + // Divider to separate the lists + Divider(), + // Yahrtzeits not in the group + Expanded( + child: ListView.builder( + itemCount: notInGroup.length, + itemBuilder: (context, index) { + final yahrtzeit = notInGroup[index]; + return CheckboxListTile( + title: Text(yahrtzeit.englishName), + subtitle: Text(yahrtzeit.hebrewName), + value: yahrtzeit.selected, + onChanged: (bool? value) { + setState(() { + yahrtzeit.selected = value ?? false; + }); + }, + ); + }, + ), + ), + ], + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () async { + final selected = selectedYahrtzeits.where((y) => y.selected).toList(); + final notInGroupSelected = notInGroup.where((y) => y.selected).toList(); + await manager.updateGroup(group.name, groupName, selected + notInGroupSelected); + fetchGroups(); + Navigator.pop(context); + }, + child: Text('Save Changes'), + ), + ], + ); + }, + ); + }, + ); +} + + + + void _deleteGroup(Group group) async { + await manager.deleteGroup(group.name); + fetchGroups(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.translate('Groups')), + actions: [ + IconButton( + icon: Icon(Icons.add), + onPressed: _createGroup, + ), + ], + ), + body: groups.isEmpty + ? Center(child: Text('No groups created yet.')) + : ListView.builder( + itemCount: groups.length, + itemBuilder: (context, index) { + final group = groups[index]; + return Card( + elevation: 5, + margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + child: ListTile( + title: Text(group.name), + subtitle: Text('${group.yahrtzeits.length} yahrtzeits'), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => GroupDetailsPage(group: group)), + ); + }, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + _editGroup(group); + }, + ), + IconButton( + icon: Icon(Icons.delete), + onPressed: () { + _deleteGroup(group); + }, + ), + ], + ), + ), + ); + }, + ), + ); + } +} + +class GroupDetailsPage extends StatelessWidget { + final Group group; + + GroupDetailsPage({required this.group}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(group.name), + ), + body: ListView.builder( + itemCount: group.yahrtzeits.length, + itemBuilder: (context, index) { + final yahrtzeit = group.yahrtzeits[index]; + return ListTile( + title: Text(yahrtzeit.englishName), + subtitle: Text(yahrtzeit.hebrewName), + ); + }, + ), + ); + } +} diff --git a/lib/views/manage_yahrtzeits.dart b/lib/views/manage_yahrtzeits.dart index 46706a5..030d0d1 100644 --- a/lib/views/manage_yahrtzeits.dart +++ b/lib/views/manage_yahrtzeits.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import '../localizations/app_localizations.dart'; import '../models/yahrtzeit.dart'; import '../services/yahrtzeits_manager.dart'; import 'add_yahrtzeit.dart'; @@ -49,7 +50,7 @@ class _ManageYahrtzeitsState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Manage Yahrtzeits', style: TextStyle(color: Colors.white, fontSize: 22)), + title: Text(AppLocalizations.of(context)!.translate('manage_yahrzeits'), style: TextStyle(color: Colors.white)), centerTitle: true, backgroundColor: Color.fromARGB(255, 50, 4, 129), elevation: 0, diff --git a/lib/views/upcoming_yahrtzeits.dart b/lib/views/upcoming_yahrtzeits.dart index fc00333..4cc0f0c 100644 --- a/lib/views/upcoming_yahrtzeits.dart +++ b/lib/views/upcoming_yahrtzeits.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import '../localizations/app_localizations.dart'; import '../models/yahrtzeit.dart'; import '../models/yahrtzeit_date.dart'; import '../services/yahrtzeits_manager.dart'; @@ -35,7 +36,7 @@ class _UpcomingYahrtzeitsState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Upcoming Yahrtzeits', style: TextStyle(color: Colors.white, fontSize: 22)), + title: Text(AppLocalizations.of(context)!.translate('upcoming_yahrtzeits'), style: TextStyle(color: Colors.white)), centerTitle: true, backgroundColor: Color.fromARGB(255, 50, 4, 129), elevation: 0, diff --git a/lib/views/yahrtzeit_details.dart b/lib/views/yahrtzeit_details.dart index 1a1b7e8..5295604 100644 --- a/lib/views/yahrtzeit_details.dart +++ b/lib/views/yahrtzeit_details.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:kosher_dart/kosher_dart.dart'; import 'package:share/share.dart'; +import '../localizations/app_localizations.dart'; import '../models/yahrtzeit_date.dart'; import 'package:intl/intl.dart'; @@ -18,13 +19,16 @@ class YahrtzeitDetailsPage extends StatelessWidget { return Scaffold( appBar: AppBar( - title: Text('${yahrtzeitDate.yahrtzeit.englishName} Details'), + title: Text(AppLocalizations.of(context)! + .translate('${yahrtzeitDate.yahrtzeit.englishName} Details')), actions: [ IconButton( icon: Icon(Icons.share), onPressed: () { Share.share( 'Yahrtzeit Details:\n\n' + // (AppLocalizations.of(context)!.translate('Yahrtzeit Details:\n\n')) + 'English Name: ${yahrtzeitDate.yahrtzeit.englishName}\n' 'Hebrew Name: ${yahrtzeitDate.yahrtzeit.hebrewName}\n' 'Gregorian Date: ${gregorianFormatter.format(yahrtzeitDate.gregorianDate)}\n' @@ -38,16 +42,21 @@ class YahrtzeitDetailsPage extends StatelessWidget { padding: const EdgeInsets.all(16.0), child: Card( elevation: 5, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildDetailRow('English Name', yahrtzeitDate.yahrtzeit.englishName), - _buildDetailRow('Hebrew Name', yahrtzeitDate.yahrtzeit.hebrewName), - _buildDetailRow('Gregorian Date', gregorianFormatter.format(yahrtzeitDate.gregorianDate)), - _buildDetailRow('Hebrew Date', hebrewFormatter.format(yahrtzeitDate.hebrewDate)), + _buildDetailRow( + 'English Name', yahrtzeitDate.yahrtzeit.englishName), + _buildDetailRow( + 'Hebrew Name', yahrtzeitDate.yahrtzeit.hebrewName), + _buildDetailRow('Gregorian Date', + gregorianFormatter.format(yahrtzeitDate.gregorianDate)), + _buildDetailRow('Hebrew Date', + hebrewFormatter.format(yahrtzeitDate.hebrewDate)), ], ), ), diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 4251079..61ff451 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,8 +7,10 @@ import Foundation import flutter_local_notifications import path_provider_foundation +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 83c16ec..5616e02 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,22 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" - url: "https://pub.dev" - source: hosted - version: "67.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" - url: "https://pub.dev" - source: hosted - version: "6.4.1" args: dependency: transitive description: @@ -41,70 +25,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" - build: - dependency: transitive - description: - name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - build_config: - dependency: transitive - description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 - url: "https://pub.dev" - source: hosted - version: "1.1.1" - build_daemon: - dependency: transitive - description: - name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - build_runner: - dependency: "direct dev" - description: - name: build_runner - sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" - url: "https://pub.dev" - source: hosted - version: "2.4.11" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe - url: "https://pub.dev" - source: hosted - version: "7.3.1" - built_collection: - dependency: transitive - description: - name: built_collection - sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb - url: "https://pub.dev" - source: hosted - version: "8.9.2" characters: dependency: transitive description: @@ -113,14 +33,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff - url: "https://pub.dev" - source: hosted - version: "2.0.3" clock: dependency: transitive description: @@ -129,14 +41,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 - url: "https://pub.dev" - source: hosted - version: "4.10.0" collection: dependency: transitive description: @@ -145,22 +49,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - crypto: - dependency: transitive - description: - name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab - url: "https://pub.dev" - source: hosted - version: "3.0.3" cupertino_icons: dependency: "direct main" description: @@ -169,14 +57,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" - url: "https://pub.dev" - source: hosted - version: "2.3.6" dbus: dependency: transitive description: @@ -217,14 +97,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -262,107 +134,24 @@ packages: url: "https://pub.dev" source: hosted version: "7.2.0" - flutter_riverpod: - dependency: "direct main" - description: - name: flutter_riverpod - sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" - url: "https://pub.dev" - source: hosted - version: "2.5.1" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - frontend_server_client: + flutter_web_plugins: dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" - source: hosted - version: "4.0.0" - glob: - dependency: transitive - description: - name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - graphs: - dependency: transitive - description: - name: graphs - sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - http: - dependency: "direct main" - description: - name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 - url: "https://pub.dev" - source: hosted - version: "1.2.2" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" + description: flutter + source: sdk + version: "0.0.0" intl: - dependency: transitive + dependency: "direct main" description: name: intl sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted version: "0.18.1" - io: - dependency: transitive - description: - name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" - url: "https://pub.dev" - source: hosted - version: "1.0.4" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" - source: hosted - version: "0.7.1" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b - url: "https://pub.dev" - source: hosted - version: "6.8.0" kosher_dart: dependency: "direct main" description: @@ -403,14 +192,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - logging: - dependency: transitive - description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" - url: "https://pub.dev" - source: hosted - version: "1.2.0" matcher: dependency: transitive description: @@ -443,14 +224,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - package_config: + nested: dependency: transitive description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "1.0.0" path: dependency: transitive description: @@ -539,83 +320,83 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" - pool: - dependency: transitive + provider: + dependency: "direct main" description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c url: "https://pub.dev" source: hosted - version: "1.5.1" - pub_semver: - dependency: transitive + version: "6.1.2" + share: + dependency: "direct main" description: - name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + name: share + sha256: "97e6403f564ed1051a01534c2fc919cb6e40ea55e60a18ec23cee6e0ce19f4be" url: "https://pub.dev" source: hosted - version: "2.1.4" - pubspec_parse: - dependency: transitive + version: "2.0.4" + shared_preferences: + dependency: "direct main" description: - name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + name: shared_preferences + sha256: c3f888ba2d659f3e75f4686112cc1e71f46177f74452d40d8307edc332296ead url: "https://pub.dev" source: hosted - version: "1.3.0" - riverpod: - dependency: "direct main" + version: "2.3.0" + shared_preferences_android: + dependency: transitive description: - name: riverpod - sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d + name: shared_preferences_android + sha256: "041be4d9d2dc6079cf342bc8b761b03787e3b71192d658220a56cac9c04a0294" url: "https://pub.dev" source: hosted - version: "2.5.1" - share: - dependency: "direct main" + version: "2.3.0" + shared_preferences_foundation: + dependency: transitive description: - name: share - sha256: "97e6403f564ed1051a01534c2fc919cb6e40ea55e60a18ec23cee6e0ce19f4be" + name: shared_preferences_foundation + sha256: "671e7a931f55a08aa45be2a13fe7247f2a41237897df434b30d2012388191833" url: "https://pub.dev" source: hosted - version: "2.0.4" - shelf: + version: "2.5.0" + shared_preferences_linux: dependency: transitive description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + name: shared_preferences_linux + sha256: "2ba0510d3017f91655b7543e9ee46d48619de2a2af38e5c790423f7007c7ccc1" url: "https://pub.dev" source: hosted - version: "1.4.1" - shelf_web_socket: + version: "2.4.0" + shared_preferences_platform_interface: dependency: transitive description: - name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.0.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: + version: "2.4.1" + shared_preferences_web: dependency: transitive description: - name: source_gen - sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + name: shared_preferences_web + sha256: "3a293170d4d9403c3254ee05b84e62e8a9b3c5808ebd17de6a33fe9ea6457936" url: "https://pub.dev" source: hosted - version: "1.5.0" - source_helper: + version: "2.4.0" + shared_preferences_windows: dependency: transitive description: - name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + name: shared_preferences_windows + sha256: "398084b47b7f92110683cac45c6dc4aae853db47e470e5ddcd52cab7f7196ab2" url: "https://pub.dev" source: hosted - version: "1.3.4" + version: "2.4.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" source_span: dependency: transitive description: @@ -640,14 +421,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.1" - state_notifier: - dependency: transitive - description: - name: state_notifier - sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289" - url: "https://pub.dev" - source: hosted - version: "0.7.2+1" stream_channel: dependency: transitive description: @@ -656,14 +429,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" - url: "https://pub.dev" - source: hosted - version: "2.1.0" string_scanner: dependency: transitive description: @@ -688,14 +453,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.0" - time_machine: - dependency: "direct main" - description: - name: time_machine - sha256: b39511bf66cc8553d86c1242c43dbf67a17c594d5d7124727c1fdbf331e3989d - url: "https://pub.dev" - source: hosted - version: "0.9.17" timezone: dependency: "direct main" description: @@ -704,22 +461,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.4" - timing: - dependency: transitive - description: - name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c - url: "https://pub.dev" - source: hosted - version: "1.3.2" vector_math: dependency: transitive description: @@ -736,14 +477,6 @@ packages: url: "https://pub.dev" source: hosted version: "14.2.1" - watcher: - dependency: transitive - description: - name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" - url: "https://pub.dev" - source: hosted - version: "1.1.0" web: dependency: transitive description: @@ -752,22 +485,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" - web_socket: - dependency: transitive - description: - name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" - url: "https://pub.dev" - source: hosted - version: "0.1.6" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" - url: "https://pub.dev" - source: hosted - version: "3.0.1" xdg_directories: dependency: transitive description: @@ -784,14 +501,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.5.0" - yaml: - dependency: transitive - description: - name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" - url: "https://pub.dev" - source: hosted - version: "3.1.2" sdks: dart: ">=3.4.3 <3.5.0" flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index eeee443..b47e345 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,4 +1,4 @@ -name: yahrtzeit_manager +name: cambium_project description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. @@ -37,14 +37,16 @@ dependencies: cupertino_icons: ^1.0.6 kosher_dart: ^2.0.16 device_calendar: ^4.0.0 + # timezone: ^0.8.0 flutter_local_notifications: ^17.2.1+2 share: ^2.0.4 timezone: ^0.9.4 - time_machine: ^0.9.17 path_provider: ^2.0.9 - riverpod: 2.5.1 - flutter_riverpod: ^2.0.0 - http: 1.2.2 + shared_preferences: ^2.3.0 + provider: ^6.1.2 + intl: ^0.18.1 + + dev_dependencies: flutter_test: @@ -56,8 +58,6 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^3.0.0 - build_runner: ^2.1.7 - json_serializable: ^6.1.4 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -71,8 +71,9 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - #assets: - # - lib/images/ + assets: + - assets/lang/en.json + - assets/lang/he.json # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware