mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Display Forez presence
This commit is contained in:
		
							
								
								
									
										76
									
								
								lib/helpers/forez_presence_helper.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								lib/helpers/forez_presence_helper.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/websocket_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/lists/forez_presences_set.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/forez_presence.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Presence helper
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int _cachedGroup;
 | 
				
			||||||
 | 
					PresenceSet _cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ForezPresenceHelper {
 | 
				
			||||||
 | 
					  /// Refresh presence cache
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case of failure
 | 
				
			||||||
 | 
					  static Future<void> refreshCache(int groupID) async {
 | 
				
			||||||
 | 
					    final response = await ws("forez_presence/list", {"group": groupID});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final list = response
 | 
				
			||||||
 | 
					        .cast<String>()
 | 
				
			||||||
 | 
					        .map((element) {
 | 
				
			||||||
 | 
					          final cut = element.split(",").map((e) => int.parse(e)).toList();
 | 
				
			||||||
 | 
					          assert(cut.length == 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return Presence(
 | 
				
			||||||
 | 
					              userID: cut[0], year: cut[1], month: cut[2], day: cut[3]);
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .toList()
 | 
				
			||||||
 | 
					        .cast<Presence>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _cachedGroup = groupID;
 | 
				
			||||||
 | 
					    _cache = PresenceSet()..addAll(list);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Initialize cache if required
 | 
				
			||||||
 | 
					  static Future<void> _checkCache(int groupID) async {
 | 
				
			||||||
 | 
					    if (_cache == null || _cachedGroup != groupID) await refreshCache(groupID);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Get the presences of a given user
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case of failure
 | 
				
			||||||
 | 
					  static Future<PresenceSet> getForUser(int groupID, int userID) async {
 | 
				
			||||||
 | 
					    await _checkCache(groupID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return _cache.getForUser(userID);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Get all the available presences
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case of failure
 | 
				
			||||||
 | 
					  static Future<PresenceSet> getAll(int groupID) async {
 | 
				
			||||||
 | 
					    await _checkCache(groupID);
 | 
				
			||||||
 | 
					    return _cache;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Add a new day of presence
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case of failure
 | 
				
			||||||
 | 
					  static Future<void> addDay(DateTime dt) async =>
 | 
				
			||||||
 | 
					      await ws("forez_presence/add_day", {
 | 
				
			||||||
 | 
					        "year": dt.year,
 | 
				
			||||||
 | 
					        "month": dt.month,
 | 
				
			||||||
 | 
					        "day": dt.day,
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Remove a new day of presence
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// Throws in case of failure
 | 
				
			||||||
 | 
					  static Future<void> delDay(DateTime dt) async =>
 | 
				
			||||||
 | 
					      await ws("forez_presence/del_day", {
 | 
				
			||||||
 | 
					        "year": dt.year,
 | 
				
			||||||
 | 
					        "month": dt.month,
 | 
				
			||||||
 | 
					        "day": dt.day,
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								lib/lists/base_set.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								lib/lists/base_set.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import 'dart:collection';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Base set
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseSet<T> extends SetBase<T> {
 | 
				
			||||||
 | 
					  final _set = new Set<T>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool add(T value) => _set.add(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool contains(Object element) => _set.contains(element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Iterator<T> get iterator => _set.iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  int get length => _set.length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  T lookup(Object element) => _set.lookup(element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool remove(Object value) => _set.remove(value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Set<T> toSet() => _set.toSet();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								lib/lists/forez_presences_set.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								lib/lists/forez_presences_set.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/lists/base_set.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/forez_presence.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Forez presence set
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PresenceSet extends BaseSet<Presence> {
 | 
				
			||||||
 | 
					  /// Get the presence of a specific user
 | 
				
			||||||
 | 
					  PresenceSet getForUser(int userID) =>
 | 
				
			||||||
 | 
					      PresenceSet()..addAll(where((element) => element.userID == userID));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool containsDate(DateTime dt) => any(
 | 
				
			||||||
 | 
					        (element) =>
 | 
				
			||||||
 | 
					            element.year == dt.year &&
 | 
				
			||||||
 | 
					            element.month == dt.month &&
 | 
				
			||||||
 | 
					            element.day == dt.day,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void removeDate(DateTime dt) => removeWhere(
 | 
				
			||||||
 | 
					        (element) =>
 | 
				
			||||||
 | 
					            element.year == dt.year &&
 | 
				
			||||||
 | 
					            element.month == dt.month &&
 | 
				
			||||||
 | 
					            element.day == dt.day,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void toggleDate(DateTime dt, int userID) {
 | 
				
			||||||
 | 
					    if (containsDate(dt))
 | 
				
			||||||
 | 
					      removeDate(dt);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      add(Presence.fromDateTime(dt, userID));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int countAtDate(DateTime dt) => where(
 | 
				
			||||||
 | 
					        (element) =>
 | 
				
			||||||
 | 
					            element.year == dt.year &&
 | 
				
			||||||
 | 
					            element.month == dt.month &&
 | 
				
			||||||
 | 
					            element.day == dt.day,
 | 
				
			||||||
 | 
					      ).length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Get the list of users present at a specified date
 | 
				
			||||||
 | 
					  List<int> getUsersAtDate(DateTime dt) => where(
 | 
				
			||||||
 | 
					        (element) =>
 | 
				
			||||||
 | 
					            element.year == dt.year &&
 | 
				
			||||||
 | 
					            element.month == dt.month &&
 | 
				
			||||||
 | 
					            element.day == dt.day,
 | 
				
			||||||
 | 
					      ).map((e) => e.userID).toList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Get the ID of all the users referenced in this set
 | 
				
			||||||
 | 
					  Set<int> get usersID => map((element) => element.userID).toSet();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								lib/models/forez_presence.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/models/forez_presence.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Single presence information
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Presence {
 | 
				
			||||||
 | 
					  final int userID;
 | 
				
			||||||
 | 
					  final int year;
 | 
				
			||||||
 | 
					  final int month;
 | 
				
			||||||
 | 
					  final int day;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const Presence({
 | 
				
			||||||
 | 
					    @required this.userID,
 | 
				
			||||||
 | 
					    @required this.year,
 | 
				
			||||||
 | 
					    @required this.month,
 | 
				
			||||||
 | 
					    @required this.day,
 | 
				
			||||||
 | 
					  })  : assert(userID != null),
 | 
				
			||||||
 | 
					        assert(year != null),
 | 
				
			||||||
 | 
					        assert(month != null),
 | 
				
			||||||
 | 
					        assert(day != null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Presence.fromDateTime(DateTime dt, this.userID)
 | 
				
			||||||
 | 
					      : assert(dt != null),
 | 
				
			||||||
 | 
					        year = dt.year,
 | 
				
			||||||
 | 
					        month = dt.month,
 | 
				
			||||||
 | 
					        day = dt.day,
 | 
				
			||||||
 | 
					        assert(userID != null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -60,7 +60,7 @@ class _AuthorizedGroupPageScreenState
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Forez presence tab
 | 
					        // Forez presence tab
 | 
				
			||||||
        _GroupPageTab(
 | 
					        _GroupPageTab(
 | 
				
			||||||
          widget: (c) => ForezPresenceSection(),
 | 
					          widget: (c) => ForezPresenceSection(groupID: _group.id),
 | 
				
			||||||
          label: tr("Presence"),
 | 
					          label: tr("Presence"),
 | 
				
			||||||
          visible: _group.isForezGroup,
 | 
					          visible: _group.isForezGroup,
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,10 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/forez_presence_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/helpers/users_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/lists/forez_presences_set.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/lists/users_list.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/account_image_widget.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/forez_presence_calendar_widget.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Forez presence section
 | 
					/// Forez presence section
 | 
				
			||||||
@@ -5,13 +12,77 @@ import 'package:flutter/material.dart';
 | 
				
			|||||||
/// @author Pierre Hubert
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ForezPresenceSection extends StatefulWidget {
 | 
					class ForezPresenceSection extends StatefulWidget {
 | 
				
			||||||
 | 
					  final int groupID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ForezPresenceSection({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.groupID,
 | 
				
			||||||
 | 
					  })  : assert(groupID != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  _ForezPresenceSectionState createState() => _ForezPresenceSectionState();
 | 
					  _ForezPresenceSectionState createState() => _ForezPresenceSectionState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _ForezPresenceSectionState extends State<ForezPresenceSection> {
 | 
					class _ForezPresenceSectionState extends State<ForezPresenceSection> {
 | 
				
			||||||
 | 
					  PresenceSet _presences;
 | 
				
			||||||
 | 
					  UsersList _users;
 | 
				
			||||||
 | 
					  DateTime _currentDay = DateTime.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  List<int> get _currentListOfUsers => _presences.getUsersAtDate(_currentDay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Future<void> _refresh() async {
 | 
				
			||||||
 | 
					    await ForezPresenceHelper.refreshCache(widget.groupID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _presences = await ForezPresenceHelper.getAll(widget.groupID);
 | 
				
			||||||
 | 
					    _users = await UsersHelper().getList(_presences.usersID);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Container();
 | 
					    return Stack(
 | 
				
			||||||
 | 
					      children: <Widget>[
 | 
				
			||||||
 | 
					        AsyncScreenWidget(
 | 
				
			||||||
 | 
					          onReload: _refresh,
 | 
				
			||||||
 | 
					          onBuild: _buildList,
 | 
				
			||||||
 | 
					          errorMessage: "Erreur lors du chargement des présences !",
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        Positioned(
 | 
				
			||||||
 | 
					          right: 10,
 | 
				
			||||||
 | 
					          bottom: 10,
 | 
				
			||||||
 | 
					          child: FloatingActionButton(
 | 
				
			||||||
 | 
					            backgroundColor: Colors.green,
 | 
				
			||||||
 | 
					            onPressed: () {},
 | 
				
			||||||
 | 
					            child: Icon(Icons.edit),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildList() {
 | 
				
			||||||
 | 
					    final currentList = _currentListOfUsers;
 | 
				
			||||||
 | 
					    return ListView.builder(
 | 
				
			||||||
 | 
					      itemCount: currentList.length + 1,
 | 
				
			||||||
 | 
					      itemBuilder: (c, i) =>
 | 
				
			||||||
 | 
					          i == 0 ? _buildCalendar() : _buildUser(currentList[i - 1]),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildCalendar() => PresenceCalendarWidget(
 | 
				
			||||||
 | 
					        presenceSet: _presences,
 | 
				
			||||||
 | 
					        mode: CalendarDisplayMode.MULTIPLE_USERS,
 | 
				
			||||||
 | 
					        selectedDay: _currentDay,
 | 
				
			||||||
 | 
					        onDayClicked: _selectDay,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _selectDay(DateTime dt) => setState(() => _currentDay = dt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildUser(int userID) {
 | 
				
			||||||
 | 
					    final user = _users.getUser(userID);
 | 
				
			||||||
 | 
					    return ListTile(
 | 
				
			||||||
 | 
					      leading: AccountImageWidget(user: user),
 | 
				
			||||||
 | 
					      title: Text(user.fullName),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										165
									
								
								lib/ui/widgets/forez_presence_calendar_widget.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								lib/ui/widgets/forez_presence_calendar_widget.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/lists/forez_presences_set.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/date_utils.dart' as date_utils;
 | 
				
			||||||
 | 
					/// Forez presence calendar widget
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This widget is used only by Forez groups
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:table_calendar/table_calendar.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum CalendarDisplayMode { SINGLE_USER, MULTIPLE_USERS }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension DateOnlyCompare on DateTime {
 | 
				
			||||||
 | 
					  bool isSameDate(DateTime other) => date_utils.isSameDate(this, other);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PresenceCalendarWidget extends StatefulWidget {
 | 
				
			||||||
 | 
					  final PresenceSet presenceSet;
 | 
				
			||||||
 | 
					  final void Function(DateTime) onDayClicked;
 | 
				
			||||||
 | 
					  final CalendarDisplayMode mode;
 | 
				
			||||||
 | 
					  final DateTime selectedDay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const PresenceCalendarWidget({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.presenceSet,
 | 
				
			||||||
 | 
					    this.onDayClicked,
 | 
				
			||||||
 | 
					    this.mode = CalendarDisplayMode.SINGLE_USER,
 | 
				
			||||||
 | 
					    this.selectedDay,
 | 
				
			||||||
 | 
					  })  : assert(presenceSet != null),
 | 
				
			||||||
 | 
					        assert(mode != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  _PresenceCalendarWidgetState createState() => _PresenceCalendarWidgetState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _PresenceCalendarWidgetState extends State<PresenceCalendarWidget> {
 | 
				
			||||||
 | 
					  CalendarController _calendarController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void initState() {
 | 
				
			||||||
 | 
					    super.initState();
 | 
				
			||||||
 | 
					    _calendarController = CalendarController();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void dispose() {
 | 
				
			||||||
 | 
					    _calendarController.dispose();
 | 
				
			||||||
 | 
					    super.dispose();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return TableCalendar(
 | 
				
			||||||
 | 
					      calendarController: _calendarController,
 | 
				
			||||||
 | 
					      locale: "fr_FR",
 | 
				
			||||||
 | 
					      weekendDays: [],
 | 
				
			||||||
 | 
					      onHeaderTapped: _pickDate,
 | 
				
			||||||
 | 
					      builders: CalendarBuilders(dayBuilder: _dayBuilder),
 | 
				
			||||||
 | 
					      onDaySelected: _selectedDay,
 | 
				
			||||||
 | 
					      availableCalendarFormats: const {CalendarFormat.month: "Mois"},
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _pickDate(DateTime date) async {
 | 
				
			||||||
 | 
					    final pickedDate = await showDatePicker(
 | 
				
			||||||
 | 
					      context: context,
 | 
				
			||||||
 | 
					      initialDate: date,
 | 
				
			||||||
 | 
					      firstDate: DateTime.now().subtract(Duration(days: 20)),
 | 
				
			||||||
 | 
					      lastDate: DateTime.now().add(Duration(days: 365 * 5)),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pickedDate != null) {
 | 
				
			||||||
 | 
					      _calendarController.setSelectedDay(pickedDate, animate: true);
 | 
				
			||||||
 | 
					      setState(() {});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _dayBuilder(
 | 
				
			||||||
 | 
					      BuildContext context, DateTime date, List<dynamic> events) {
 | 
				
			||||||
 | 
					    if (widget.presenceSet.containsDate(date)) {
 | 
				
			||||||
 | 
					      // Show the number of users who are present
 | 
				
			||||||
 | 
					      if (widget.mode == CalendarDisplayMode.MULTIPLE_USERS)
 | 
				
			||||||
 | 
					        return Stack(
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					            CellWidget(
 | 
				
			||||||
 | 
					              text: date.day.toString(),
 | 
				
			||||||
 | 
					              color: Colors.green,
 | 
				
			||||||
 | 
					              textColor: Colors.white,
 | 
				
			||||||
 | 
					              circle: false,
 | 
				
			||||||
 | 
					              selected: date.isSameDate(widget.selectedDay),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Positioned(
 | 
				
			||||||
 | 
					              child: Material(
 | 
				
			||||||
 | 
					                child: Padding(
 | 
				
			||||||
 | 
					                  padding: const EdgeInsets.all(2.0),
 | 
				
			||||||
 | 
					                  child: Text(widget.presenceSet.countAtDate(date).toString()),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                textStyle: TextStyle(color: Colors.white),
 | 
				
			||||||
 | 
					                color: Colors.red,
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              bottom: 4,
 | 
				
			||||||
 | 
					              right: 4,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Only show green circle
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        return CellWidget(
 | 
				
			||||||
 | 
					          text: date.day.toString(),
 | 
				
			||||||
 | 
					          color: Colors.green,
 | 
				
			||||||
 | 
					          textColor: Colors.white,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CellWidget(
 | 
				
			||||||
 | 
					      text: date.day.toString(),
 | 
				
			||||||
 | 
					      selected: date.isSameDate(widget.selectedDay),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _selectedDay(
 | 
				
			||||||
 | 
					      DateTime day, List<dynamic> events, List<dynamic> holidays) {
 | 
				
			||||||
 | 
					    if (widget.onDayClicked != null) widget.onDayClicked(day);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CellWidget extends StatelessWidget {
 | 
				
			||||||
 | 
					  final String text;
 | 
				
			||||||
 | 
					  final Color color;
 | 
				
			||||||
 | 
					  final Color textColor;
 | 
				
			||||||
 | 
					  final bool circle;
 | 
				
			||||||
 | 
					  final bool selected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const CellWidget({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.text,
 | 
				
			||||||
 | 
					    this.color,
 | 
				
			||||||
 | 
					    this.textColor,
 | 
				
			||||||
 | 
					    this.circle = true,
 | 
				
			||||||
 | 
					    this.selected,
 | 
				
			||||||
 | 
					  })  : assert(text != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return AnimatedContainer(
 | 
				
			||||||
 | 
					      duration: const Duration(milliseconds: 250),
 | 
				
			||||||
 | 
					      decoration: _buildCellDecoration(),
 | 
				
			||||||
 | 
					      margin: const EdgeInsets.all(6.0),
 | 
				
			||||||
 | 
					      alignment: Alignment.center,
 | 
				
			||||||
 | 
					      child: Text(
 | 
				
			||||||
 | 
					        text,
 | 
				
			||||||
 | 
					        textAlign: TextAlign.center,
 | 
				
			||||||
 | 
					        style: TextStyle(color: selected ?? false ? Colors.white : textColor),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Decoration _buildCellDecoration() => BoxDecoration(
 | 
				
			||||||
 | 
					        shape: circle ? BoxShape.circle : BoxShape.rectangle,
 | 
				
			||||||
 | 
					        color: selected ?? false ? Colors.deepPurple : color,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -555,6 +555,13 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dartlang.org"
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "0.1.2+7"
 | 
					    version: "0.1.2+7"
 | 
				
			||||||
 | 
					  simple_gesture_detector:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: simple_gesture_detector
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "0.1.6"
 | 
				
			||||||
  sky_engine:
 | 
					  sky_engine:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description: flutter
 | 
					    description: flutter
 | 
				
			||||||
@@ -609,6 +616,13 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dartlang.org"
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "3.0.0"
 | 
					    version: "3.0.0"
 | 
				
			||||||
 | 
					  table_calendar:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: table_calendar
 | 
				
			||||||
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "2.3.3"
 | 
				
			||||||
  term_glyph:
 | 
					  term_glyph:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ description: Comunic client
 | 
				
			|||||||
version: 1.1.5+9
 | 
					version: 1.1.5+9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ">=2.1.0 <3.0.0"
 | 
					  sdk: ">=2.7.0 <3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependencies:
 | 
					dependencies:
 | 
				
			||||||
  flutter:
 | 
					  flutter:
 | 
				
			||||||
@@ -130,6 +130,9 @@ dependencies:
 | 
				
			|||||||
  firebase_core: ^1.0.1
 | 
					  firebase_core: ^1.0.1
 | 
				
			||||||
  firebase_messaging: ^9.0.0
 | 
					  firebase_messaging: ^9.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Forez presence
 | 
				
			||||||
 | 
					  table_calendar: ^2.3.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
    sdk: flutter
 | 
					    sdk: flutter
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user