Skip to content

Commit

Permalink
feature(recipients_app): add pull to refresh (#715)
Browse files Browse the repository at this point in the history
* added pull to refresh

* added pull to refresh to payments page

* - fixed analyze issues

* - fixed scrollview in dashboard

* cleanup

* Adjust paddings on dashboard page

* Add pull to refresh for surveys page

* Make sure payment list is scrolled as one

* Fix next payment day calculation, make it based on date only without time

---------

Co-authored-by: Mikolaj <[email protected]>
  • Loading branch information
novas1r1 and MDikkii authored Feb 27, 2024
1 parent 2b22e20 commit bf7295b
Show file tree
Hide file tree
Showing 55 changed files with 641 additions and 684 deletions.
10 changes: 5 additions & 5 deletions recipients_app/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ linter:
use_decorated_box: false
prefer_double_quotes: true
prefer_const_constructors: true
prefer_const_constructors_in_immutables:
trues
prefer_const_constructors_in_immutables: true

# avoid_print: false # Uncomment to disable the `avoid_print` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
dart_code_metrics:
exclude: ["lib/**/*.g.dart"]
rules:
prefer-single-widget-per-file: false
24 changes: 12 additions & 12 deletions recipients_app/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PODS:
- AppCheckCore (10.18.0):
- GoogleUtilities/Environment (~> 7.11)
- PromisesObjC (~> 2.3)
- cloud_firestore (4.13.6):
- cloud_firestore (4.14.0):
- Firebase/Firestore (= 10.18.0)
- firebase_core
- Flutter
Expand All @@ -26,18 +26,18 @@ PODS:
- firebase_core
- FirebaseAppCheck (~> 10.18.0-beta)
- Flutter
- firebase_auth (4.15.3):
- firebase_auth (4.16.0):
- Firebase/Auth (= 10.18.0)
- firebase_core
- Flutter
- firebase_core (2.24.2):
- Firebase/CoreOnly (= 10.18.0)
- Flutter
- firebase_crashlytics (3.4.8):
- firebase_crashlytics (3.4.9):
- Firebase/Crashlytics (= 10.18.0)
- firebase_core
- Flutter
- firebase_messaging (14.7.9):
- firebase_messaging (14.7.10):
- Firebase/Messaging (= 10.18.0)
- firebase_core
- Flutter
Expand Down Expand Up @@ -225,25 +225,25 @@ CHECKOUT OPTIONS:

SPEC CHECKSUMS:
AppCheckCore: 4687c03428947d5b26a6bf9bb5566b39f5473bf1
cloud_firestore: c29d4c2e96fe31374d9dab458a99d7a488d3a735
cloud_firestore: 73eece22ce25a0565238c283ee9990f1618d8063
Firebase: 414ad272f8d02dfbf12662a9d43f4bba9bec2a06
firebase_app_check: 375d2482bc2219ef06df67f2ad659c377b2c1075
firebase_auth: df44e14f8a93e8a9869d91695bd3f8e53d2c9f5a
firebase_auth: 8e9ec02991ca4659111cc671c84d0c010b6bfb26
firebase_core: 0af4a2b24f62071f9bf283691c0ee41556dcb3f5
firebase_crashlytics: 55714f63ae0973c54b3a721c451ae5f815086c1f
firebase_messaging: 875385354f623750aa03204a028d640108bc3412
firebase_crashlytics: 4b91b8ad60ee7c168fe88979f84c9573a729de7a
firebase_messaging: 90e8a6db84b6e1e876cebce4f30f01dc495e7014
FirebaseAppCheck: f34226df40cf6057dc54916ab5a5d461bb51ee68
FirebaseAppCheckInterop: 3cd914842ba46f4304050874cd284de82f154ffd
FirebaseAuth: 12314b438fa76048540c8fb86d6cfc9e08595176
FirebaseCore: 2322423314d92f946219c8791674d2f3345b598f
FirebaseCoreExtension: 62b201498aa10535801cdf3448c7f4db5e24ed80
FirebaseCoreInternal: 8eb002e564b533bdcf1ba011f33f2b5c10e2ed4a
FirebaseCrashlytics: 86d5bce01f42fa1db265f87ff1d591f04db610ec
FirebaseFirestore: 584e3f563142f63d20e9ec9c505370d674d44eba
FirebaseFirestore: 3f48a8b2aca4c247d92b7e25bee69bbafed775c8
FirebaseInstallations: e842042ec6ac1fd2e37d7706363ebe7f662afea4
FirebaseMessaging: 9bc34a98d2e0237e1b121915120d4d48ddcf301e
FirebaseSessions: f90fe9212ee2818641eda051c0835c9c4e30d9ae
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe
GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34
Expand All @@ -255,8 +255,8 @@ SPEC CHECKSUMS:
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
PromisesSwift: 28dca69a9c40779916ac2d6985a0192a5cb4a265
RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21
url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b
webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
webview_flutter_wkwebview: 4f3e50f7273d31e5500066ed267e3ae4309c5ae4

PODFILE CHECKSUM: a5318ac81fd9f11d0765e3e99e1734c2091b9426

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import "package:app/core/cubits/auth/auth_cubit.dart";
import "package:app/view/widgets/account/dashboard_card.dart";
import "package:app/data/repositories/repositories.dart";
import "package:bloc/bloc.dart";
import "package:app/view/widgets/account/dashboard_card.dart";
import "package:equatable/equatable.dart";
import "package:flutter_bloc/flutter_bloc.dart";

part "dashboard_card_manager_state.dart";

Expand All @@ -25,7 +25,7 @@ class DashboardCardManagerCubit extends Cubit<DashboardCardManagerState> {

if (recipient == null) return;

List<DashboardCard> cards = [];
final List<DashboardCard> cards = [];

try {
// TODO: currently payment phone number is used for login, we need to switch that
Expand Down
30 changes: 14 additions & 16 deletions recipients_app/lib/core/cubits/payment/payments_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "package:app/data/models/recipient.dart";
import "package:app/data/repositories/repositories.dart";
import "package:collection/collection.dart";
import "package:equatable/equatable.dart";
import "package:flutter/material.dart";
import "package:flutter_bloc/flutter_bloc.dart";

part "payments_state.dart";
Expand Down Expand Up @@ -131,34 +132,28 @@ class PaymentsCubit extends Cubit<PaymentsState> {
switch (currentPayment.status) {
case PaymentStatus.created:
paymentUiStatus = PaymentUiStatus.toBePaid;
break;
case PaymentStatus.paid:
final isRecent = _isRecent(currentPayment);
paymentUiStatus = isRecent
? PaymentUiStatus.recentToReview
: PaymentUiStatus.toReview;
paymentUiStatus = isRecent ? PaymentUiStatus.recentToReview : PaymentUiStatus.toReview;
unconfirmedPaymentsCount++;
break;
case PaymentStatus.confirmed:
paymentUiStatus = PaymentUiStatus.confirmed;
confirmedPaymentsCount++;
break;
case PaymentStatus.contested:
paymentUiStatus = PaymentUiStatus.contested;
break;
// TODO: check what to show in case of those statuses
case null:
case PaymentStatus.failed:
case PaymentStatus.other:
paymentUiStatus = PaymentUiStatus.empty;
break;
}

if (_kOnHoldCandidateStates.contains(previousState) &&
_kOnHoldCandidateStates.contains(currentPayment.status) &&
!_isRecent(currentPayment)) {
mappedPayments[i - 1] = mappedPayments[i - 1].copyWith(
uiStatus: _getOnHoldStatus(mappedPayments[i - 1].payment));
uiStatus: _getOnHoldStatus(mappedPayments[i - 1].payment),
);
paymentUiStatus = _getOnHoldStatus(currentPayment);
}

Expand Down Expand Up @@ -191,9 +186,11 @@ class PaymentsCubit extends Cubit<PaymentsState> {
int unconfirmedPaymentsCount,
) {
BalanceCardStatus balanceCardStatus = BalanceCardStatus.allConfirmed;
if (mappedPayments.any((element) =>
element.uiStatus == PaymentUiStatus.onHoldContested ||
element.uiStatus == PaymentUiStatus.onHoldToReview)) {
if (mappedPayments.any(
(element) =>
element.uiStatus == PaymentUiStatus.onHoldContested ||
element.uiStatus == PaymentUiStatus.onHoldToReview,
)) {
balanceCardStatus = BalanceCardStatus.onHold;
} else if (unconfirmedPaymentsCount == 1 &&
mappedPayments.any(
Expand All @@ -211,8 +208,7 @@ class PaymentsCubit extends Cubit<PaymentsState> {
final paymentDate = payment?.paymentAt?.toDate();

// checks if days between payment date and now are less than 5
return ((paymentDate?.difference(DateTime.now()).inDays ?? 0) * -1) <
kMaxReviewDays;
return ((paymentDate?.difference(DateTime.now()).inDays ?? 0) * -1) < kMaxReviewDays;
}

NextPaymentData _getNextPaymentData(
Expand All @@ -236,7 +232,9 @@ class PaymentsCubit extends Cubit<PaymentsState> {
(previousPaymentDate?.month ?? 1) + 1,
previousPaymentDate?.day ?? 15,
);
final daysToPayment = nextPaymentDate.difference(DateTime.now()).inDays;
final daysToPayment = DateUtils.dateOnly(nextPaymentDate)
.difference(DateUtils.dateOnly(DateTime.now()))
.inDays;

return NextPaymentData(
amount: nextPayment?.payment.amount ?? kCurrentPaymentAmount,
Expand All @@ -257,7 +255,7 @@ class PaymentsCubit extends Cubit<PaymentsState> {

MappedPayment? _getLastPaidPayment(List<MappedPayment> payments) {
final MappedPayment? lastPaidPayment;
var lastPayment = payments.firstOrNull;
final lastPayment = payments.firstOrNull;
if (lastPayment == null) {
lastPaidPayment = null;
} else if (lastPayment.uiStatus != PaymentUiStatus.toBePaid) {
Expand Down
6 changes: 2 additions & 4 deletions recipients_app/lib/core/cubits/settings/settings_cubit.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "package:app/data/repositories/repositories.dart";
import "package:bloc/bloc.dart";
import "package:equatable/equatable.dart";
import "package:flutter/material.dart";
import "package:flutter_bloc/flutter_bloc.dart";

part "settings_state.dart";

Expand All @@ -26,9 +26,7 @@ class SettingsCubit extends Cubit<SettingsState> {

/// Currently english = en and krio = kri are supported
void changeLanguage(String languageString) {
final locale = languageString == "kri"
? const Locale("kri")
: const Locale("en", "US");
final locale = languageString == "kri" ? const Locale("kri") : const Locale("en", "US");

// check whats the current language
// if its the same as the new language, do nothing
Expand Down
27 changes: 12 additions & 15 deletions recipients_app/lib/core/cubits/survey/survey_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class SurveyCubit extends Cubit<SurveyState> {
try {
final mappedSurveys = await _getSurveys();

final dashboardSurveys = mappedSurveys
.where((element) => _shouldShowSurveyCard(element.survey))
.toList();
final dashboardSurveys =
mappedSurveys.where((element) => _shouldShowSurveyCard(element.survey)).toList();

emit(
SurveyState(
Expand All @@ -50,8 +49,7 @@ class SurveyCubit extends Cubit<SurveyState> {
}

Future<List<MappedSurvey>> _getSurveys() async {
final surveys =
await surveyRepository.fetchSurveys(recipientId: recipient.userId);
final surveys = await surveyRepository.fetchSurveys(recipientId: recipient.userId);

final mappedSurveys = surveys
.map(
Expand All @@ -76,7 +74,7 @@ class SurveyCubit extends Cubit<SurveyState> {
String _getSurveyUrl(Survey survey, String recipientId) {
final params = {
"email": survey.accessEmail,
"pw": survey.accessPassword!,
"pw": survey.accessPassword,
};

final uri = Uri.https(
Expand All @@ -88,27 +86,25 @@ class SurveyCubit extends Cubit<SurveyState> {
}

bool _shouldShowSurveyCard(Survey survey) {
var dateDifferenceInDays = _getSurveyDueDateAndNowDifferenceInDays(survey);
final dateDifferenceInDays = _getSurveyDueDateAndNowDifferenceInDays(survey);
if (dateDifferenceInDays == null) {
return false;
}

var shouldShowSurveyCard = dateDifferenceInDays > _kNewSurveyDay &&
dateDifferenceInDays < _kEndOfDisplaySurveyDay;
final shouldShowSurveyCard =
dateDifferenceInDays > _kNewSurveyDay && dateDifferenceInDays < _kEndOfDisplaySurveyDay;
return shouldShowSurveyCard;
}

SurveyCardStatus _getSurveyCardStatus(Survey survey) {
if (survey.status != SurveyServerStatus.completed &&
survey.status != SurveyServerStatus.missed) {
var dateDifferenceInDays =
_getSurveyDueDateAndNowDifferenceInDays(survey);
final dateDifferenceInDays = _getSurveyDueDateAndNowDifferenceInDays(survey);
if (dateDifferenceInDays == null) {
return SurveyCardStatus.newSurvey;
}

if (dateDifferenceInDays >= _kNewSurveyDay &&
dateDifferenceInDays < _kNormalSurveyStartDay) {
if (dateDifferenceInDays >= _kNewSurveyDay && dateDifferenceInDays < _kNormalSurveyStartDay) {
return SurveyCardStatus.newSurvey;
} else if (dateDifferenceInDays >= _kNormalSurveyStartDay &&
dateDifferenceInDays < _kNormalSurveyEndDay) {
Expand All @@ -134,8 +130,9 @@ class SurveyCubit extends Cubit<SurveyState> {
String _getReadableName(String surveyId) {
return surveyId
.split("-")
.map((element) =>
"${element[0].toUpperCase()}${element.substring(1).toLowerCase()}")
.map(
(element) => "${element[0].toUpperCase()}${element.substring(1).toLowerCase()}",
)
.join(" ");
}

Expand Down
2 changes: 1 addition & 1 deletion recipients_app/lib/core/helpers/flushbar_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ abstract class FlushbarHelper {
flushbarPosition: FlushbarPosition.TOP,
titleColor: _getFontColor(type),
messageColor: _getFontColor(type),
)..show(context);
).show(context);
}

static Color _getBackgroundColor(FlushbarType type) {
Expand Down
8 changes: 3 additions & 5 deletions recipients_app/lib/data/models/payment/payments_ui_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class PaymentsUiState extends Equatable {
required this.confirmedPaymentsCount,
required this.unconfirmedPaymentsCount,
required this.nextPayment,
this.lastPaidPayment = null,
this.lastPaidPayment,
});

@override
Expand All @@ -41,10 +41,8 @@ class PaymentsUiState extends Equatable {
return PaymentsUiState(
status: status ?? this.status,
payments: payments ?? this.payments,
confirmedPaymentsCount:
confirmedPaymentsCount ?? this.confirmedPaymentsCount,
unconfirmedPaymentsCount:
unconfirmedPaymentsCount ?? this.unconfirmedPaymentsCount,
confirmedPaymentsCount: confirmedPaymentsCount ?? this.confirmedPaymentsCount,
unconfirmedPaymentsCount: unconfirmedPaymentsCount ?? this.unconfirmedPaymentsCount,
nextPayment: nextPayment ?? this.nextPayment,
lastPaidPayment: lastPaidPayment ?? this.lastPaidPayment,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class OrganizationRepository {
Future<Organization?> fetchOrganization(
DocumentReference organizationRef,
) async {
final organization = await organizationRef.withConverter(
final organization = organizationRef.withConverter(
fromFirestore: (snapshot, _) {
final data = snapshot.data()!;
return Organization.fromJson(data);
Expand Down
4 changes: 2 additions & 2 deletions recipients_app/lib/data/repositories/payment_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class PaymentRepository {
}) async {
final updatedPayment = payment.copyWith(
status: PaymentStatus.confirmed,
updatedBy: "${recipient.userId}",
updatedBy: recipient.userId,
);

await firestore
Expand All @@ -63,7 +63,7 @@ class PaymentRepository {
final updatedPayment = payment.copyWith(
status: PaymentStatus.contested,
comments: contestReason,
updatedBy: "${recipient.userId}",
updatedBy: recipient.userId,
);

await firestore
Expand Down
4 changes: 2 additions & 2 deletions recipients_app/lib/data/repositories/survey_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class SurveyRepository {
Future<List<Survey>> fetchSurveys({
required String recipientId,
}) async {
final List<Survey> surveys = <Survey>[];
final surveys = <Survey>[];

final surveysDocs = await firestore
.collection(recipientCollection)
Expand All @@ -27,7 +27,7 @@ class SurveyRepository {
final survey = Survey.fromJson(surveyDoc.data());

surveys.add(
survey.copyWith(id: surveyDoc.id)
survey.copyWith(id: surveyDoc.id),
);
}

Expand Down
Loading

0 comments on commit bf7295b

Please sign in to comment.