Skip to content

Commit

Permalink
show number of circle members when selecting circles #36
Browse files Browse the repository at this point in the history
  • Loading branch information
LGro committed Jun 16, 2024
1 parent af5bc81 commit 32f1db3
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 52 deletions.
8 changes: 6 additions & 2 deletions lib/data/repositories/contacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,16 @@ class ContactsRepository {

ProfileSharingSettings getProfileSharingSettings() => _profileSharingSettings;

List<(String, String, bool)> circlesWithMembership(String coagContactId) =>
List<(String, String, bool, int)> circlesWithMembership(
String coagContactId) =>
_circles
.map((id, label) => MapEntry(id, (
id,
label,
(_circleMemberships[coagContactId] ?? []).contains(id)
(_circleMemberships[coagContactId] ?? []).contains(id),
_circleMemberships.values
.where((circles) => circles.contains(id))
.length
)))
.values
.toList();
Expand Down
3 changes: 2 additions & 1 deletion lib/ui/locations/check_in/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class CheckInCubit extends Cubit<CheckInState> {
CheckInCubit(this.contactsRepository)
: super(CheckInState(
status: CheckInStatus.initial,
circles: contactsRepository.getCircles())) {
circles: contactsRepository.getCircles(),
circleMemberships: contactsRepository.getCircleMemberships())) {
unawaited(initialPermissionsCheck());
}

Expand Down
6 changes: 6 additions & 0 deletions lib/ui/locations/check_in/cubit.g.dart

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

16 changes: 12 additions & 4 deletions lib/ui/locations/check_in/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,29 @@ extension CheckInStatusX on CheckInStatus {

@JsonSerializable()
final class CheckInState extends Equatable {
const CheckInState({required this.status, required this.circles});
const CheckInState(
{required this.status,
required this.circles,
required this.circleMemberships});

factory CheckInState.fromJson(Map<String, dynamic> json) =>
_$CheckInStateFromJson(json);

final CheckInStatus status;
final Map<String, String> circles;
final Map<String, List<String>> circleMemberships;

Map<String, dynamic> toJson() => _$CheckInStateToJson(this);

CheckInState copyWith(
{CheckInStatus? status, Map<String, String>? circles}) =>
{CheckInStatus? status,
Map<String, String>? circles,
Map<String, List<String>>? circleMemberships}) =>
CheckInState(
status: status ?? this.status, circles: circles ?? this.circles);
status: status ?? this.status,
circles: circles ?? this.circles,
circleMemberships: circleMemberships ?? this.circleMemberships);

@override
List<Object?> get props => [status, circles];
List<Object?> get props => [status, circles, circleMemberships];
}
29 changes: 21 additions & 8 deletions lib/ui/locations/check_in/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import 'cubit.dart';

// TODO: Display check in form with location (from gps, from map picker, from address, from coordinates) circles to share with, optional duration, optional move away to check out constraint
class MyForm extends StatefulWidget {
const MyForm({required this.callback, super.key, this.circles = const {}});
const MyForm(
{required this.callback,
super.key,
this.circles = const {},
this.circleMemberships = const {}});

final Future<void> Function({
required String name,
Expand All @@ -21,6 +25,7 @@ class MyForm extends StatefulWidget {
}) callback;

final Map<String, String> circles;
final Map<String, List<String>> circleMemberships;

@override
State<MyForm> createState() => _MyFormState();
Expand Down Expand Up @@ -57,8 +62,8 @@ class _MyFormState extends State<MyForm> {
}

void _updateCircleSelection(int i, bool selected) {
final circles = List<(String, String, bool)>.from(_state.circles);
circles[i] = (circles[i].$1, circles[i].$2, selected);
final circles = List<(String, String, bool, int)>.from(_state.circles);
circles[i] = (circles[i].$1, circles[i].$2, selected, circles[i].$4);
setState(() {
_state = _state.copyWith(circles: circles);
});
Expand Down Expand Up @@ -119,7 +124,14 @@ class _MyFormState extends State<MyForm> {
super.initState();
_state = MyFormState(
circles: widget.circles
.map((id, label) => MapEntry(id, (id, label, false)))
.map((id, label) => MapEntry(id, (
id,
label,
false,
widget.circleMemberships.values
.where((circles) => circles.contains(id))
.length
)))
.values
.toList());
_titleController = TextEditingController(text: _state.title)
Expand Down Expand Up @@ -179,11 +191,11 @@ class _MyFormState extends State<MyForm> {
? FilledButton(
onPressed: () =>
_updateCircleSelection(i, false),
child: Text(c.$2))
child: Text('${c.$2} (${c.$4})'))
: OutlinedButton(
onPressed: () =>
_updateCircleSelection(i, true),
child: Text(c.$2))))
child: Text('${c.$2} (${c.$4})'))))
.values
.toList()),
const SizedBox(height: 16),
Expand Down Expand Up @@ -240,14 +252,14 @@ class MyFormState with FormzMixin {
final String details;
final int hours;
final int minutes;
final List<(String, String, bool)> circles;
final List<(String, String, bool, int)> circles;

MyFormState copyWith({
int? hours,
int? minutes,
String? title,
String? details,
List<(String, String, bool)>? circles,
List<(String, String, bool, int)>? circles,
FormzSubmissionStatus? status,
}) =>
MyFormState(
Expand Down Expand Up @@ -317,6 +329,7 @@ class CheckInWidget extends StatelessWidget {

return MyForm(
circles: state.circles,
circleMemberships: state.circleMemberships,
callback: context.read<CheckInCubit>().checkIn);
}));
}
4 changes: 3 additions & 1 deletion lib/ui/locations/schedule/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ part 'state.dart';
class ScheduleCubit extends Cubit<ScheduleState> {
ScheduleCubit(this.contactsRepository)
: super(ScheduleState(
checkingIn: false, circles: contactsRepository.getCircles()));
checkingIn: false,
circles: contactsRepository.getCircles(),
circleMemberships: contactsRepository.getCircleMemberships()));

final ContactsRepository contactsRepository;

Expand Down
6 changes: 6 additions & 0 deletions lib/ui/locations/schedule/cubit.g.dart

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

16 changes: 12 additions & 4 deletions lib/ui/locations/schedule/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@ part of 'cubit.dart';

@JsonSerializable()
final class ScheduleState extends Equatable {
const ScheduleState({required this.checkingIn, required this.circles});
const ScheduleState(
{required this.checkingIn,
required this.circles,
required this.circleMemberships});

factory ScheduleState.fromJson(Map<String, dynamic> json) =>
_$ScheduleStateFromJson(json);

final bool checkingIn;
final Map<String, String> circles;
final Map<String, List<String>> circleMemberships;

Map<String, dynamic> toJson() => _$ScheduleStateToJson(this);

ScheduleState copyWith({bool? checkingIn, Map<String, String>? circles}) =>
ScheduleState copyWith(
{bool? checkingIn,
Map<String, String>? circles,
Map<String, List<String>>? circleMemberships}) =>
ScheduleState(
checkingIn: checkingIn ?? this.checkingIn,
circles: circles ?? this.circles);
circles: circles ?? this.circles,
circleMemberships: circleMemberships ?? this.circleMemberships);

@override
List<Object?> get props => [checkingIn, circles];
List<Object?> get props => [checkingIn, circles, circleMemberships];
}
29 changes: 21 additions & 8 deletions lib/ui/locations/schedule/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import '../../../data/repositories/contacts.dart';
import 'cubit.dart';

class MyForm extends StatefulWidget {
const MyForm({required this.callback, super.key, this.circles = const {}});
const MyForm(
{required this.callback,
super.key,
this.circles = const {},
this.circleMemberships = const {}});

final Future<void> Function({
required String name,
Expand All @@ -25,6 +29,7 @@ class MyForm extends StatefulWidget {
}) callback;

final Map<String, String> circles;
final Map<String, List<String>> circleMemberships;

@override
State<MyForm> createState() => _MyFormState();
Expand Down Expand Up @@ -91,8 +96,8 @@ class _MyFormState extends State<MyForm> {
}

void _updateCircleSelection(int i, bool selected) {
final circles = List<(String, String, bool)>.from(_state.circles);
circles[i] = (circles[i].$1, circles[i].$2, selected);
final circles = List<(String, String, bool, int)>.from(_state.circles);
circles[i] = (circles[i].$1, circles[i].$2, selected, circles[i].$4);
setState(() {
_state = _state.copyWith(circles: circles);
});
Expand Down Expand Up @@ -140,7 +145,14 @@ class _MyFormState extends State<MyForm> {
super.initState();
_state = MyFormState(
circles: widget.circles
.map((id, label) => MapEntry(id, (id, label, false)))
.map((id, label) => MapEntry(id, (
id,
label,
false,
widget.circleMemberships.values
.where((circles) => circles.contains(id))
.length
)))
.values
.toList());
_titleController = TextEditingController(text: _state.title)
Expand Down Expand Up @@ -207,11 +219,11 @@ class _MyFormState extends State<MyForm> {
? FilledButton(
onPressed: () =>
_updateCircleSelection(i, false),
child: Text(c.$2))
child: Text('${c.$2} (${c.$4})'))
: OutlinedButton(
onPressed: () =>
_updateCircleSelection(i, true),
child: Text(c.$2))))
child: Text('${c.$2} (${c.$4})'))))
.values
.toList()),
const SizedBox(height: 16),
Expand Down Expand Up @@ -340,15 +352,15 @@ class MyFormState with FormzMixin {
final DateTime? start;
final DateTime? end;
final PickedData? location;
final List<(String, String, bool)> circles;
final List<(String, String, bool, int)> circles;

MyFormState copyWith({
DateTime? start,
DateTime? end,
PickedData? location,
String? title,
String? details,
List<(String, String, bool)>? circles,
List<(String, String, bool, int)>? circles,
FormzSubmissionStatus? status,
}) =>
MyFormState(
Expand Down Expand Up @@ -382,6 +394,7 @@ class ScheduleWidget extends StatelessWidget {
children: [
MyForm(
circles: state.circles,
circleMemberships: state.circleMemberships,
callback: context.read<ScheduleCubit>().schedule)
])))));
}
2 changes: 2 additions & 0 deletions lib/ui/profile/cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ProfileCubit extends Cubit<ProfileState> {
status: ProfileStatus.success,
profileContact: contact,
circles: contactsRepository.getCircles(),
circleMemberships: contactsRepository.getCircleMemberships(),
sharingSettings: contactsRepository.getProfileSharingSettings()));
}
});
Expand All @@ -36,6 +37,7 @@ class ProfileCubit extends Cubit<ProfileState> {
status: ProfileStatus.success,
profileContact: profileContact,
circles: contactsRepository.getCircles(),
circleMemberships: contactsRepository.getCircleMemberships(),
sharingSettings: contactsRepository.getProfileSharingSettings()));
}
// TODO: Check current state of permissions here in addition to listening to stream update
Expand Down
7 changes: 7 additions & 0 deletions lib/ui/profile/cubit.g.dart

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

Loading

0 comments on commit 32f1db3

Please sign in to comment.