Skip to content

Commit

Permalink
feat(ui): animate the status color transition & add a new text when t…
Browse files Browse the repository at this point in the history
…he bridge is about to close
  • Loading branch information
vareversat committed Apr 16, 2023
1 parent 0eeed73 commit c57d08e
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 60 deletions.
17 changes: 10 additions & 7 deletions lib/bloc/chaban_bridge_forecast/chaban_bridge_forecast_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;

part 'chaban_bridge_forecast_event.dart';

part 'chaban_bridge_forecast_state.dart';

class ChabanBridgeForecastBloc
Expand All @@ -34,7 +33,8 @@ class ChabanBridgeForecastBloc
final currentStatus = _getCurrentStatus(state.chabanBridgeForecasts);
final previousStatus =
_getPreviousStatus(state.chabanBridgeForecasts, currentStatus);
if (currentStatus != state.currentChabanBridgeForecast) {
if (currentStatus != state.currentChabanBridgeForecast &&
currentStatus != previousStatus) {
emit(
state.copyWith(
currentChabanBridgeForecast: currentStatus,
Expand Down Expand Up @@ -93,11 +93,14 @@ class ChabanBridgeForecastBloc
return chabanBridgeForecast[middle];
}
if (chabanBridgeForecast.length == 2) {
return chabanBridgeForecast[0]
.circulationClosingDate
.isAfter(DateTime.now())
? chabanBridgeForecast[0]
: chabanBridgeForecast[1];
return chabanBridgeForecast[1]
.circulationClosingDate
.isAfter(DateTime.now()) &&
chabanBridgeForecast[0]
.circulationReOpeningDate
.isBefore(DateTime.now())
? chabanBridgeForecast[1]
: chabanBridgeForecast[0];
} else if (chabanBridgeForecast[middle]
.circulationClosingDate
.isAfter(DateTime.now())) {
Expand Down
30 changes: 14 additions & 16 deletions lib/bloc/chaban_bridge_status/chaban_bridge_status_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:chabo/bloc/chabo_event.dart';
import 'package:chabo/extensions/color_scheme_extension.dart';
import 'package:chabo/extensions/string_extension.dart';
import 'package:chabo/models/abstract_chaban_bridge_forecast.dart';
import 'package:equatable/equatable.dart';
Expand Down Expand Up @@ -57,34 +58,26 @@ class ChabanBridgeStatusBloc
final currentChabanBridgeForecast = state.currentChabanBridgeForecast;
if (currentChabanBridgeForecast != null) {
final isOpen = !currentChabanBridgeForecast.isCurrentlyClosed();
final differenceStartingPoint = currentChabanBridgeForecast
.circulationReOpeningDate
.difference(DateTime.now());
if (isOpen && differenceStartingPoint.inMinutes <= 120) {
return Theme.of(context).colorScheme.tertiaryContainer;
if (isOpen && state.durationUntilNextEvent.inMinutes < 120) {
return Theme.of(context).colorScheme.warningColor;
} else if (isOpen) {
return Colors.green;
} else {
return Theme.of(context).colorScheme.errorContainer;
return Theme.of(context).colorScheme.error;
}
} else {
return Colors.yellow;
return Colors.purple;
}
}

Color _getForegroundColor(BuildContext context) {
final currentChabanBridgeForecast = state.currentChabanBridgeForecast;
if (currentChabanBridgeForecast != null) {
final isOpen = !currentChabanBridgeForecast.isCurrentlyClosed();
final differenceStartingPoint = currentChabanBridgeForecast
.circulationReOpeningDate
.difference(DateTime.now());
if (isOpen && differenceStartingPoint.inMinutes <= 120) {
return Theme.of(context).colorScheme.onTertiaryContainer;
} else if (isOpen) {
if (isOpen || state.durationUntilNextEvent.inMinutes < 120) {
return Theme.of(context).colorScheme.background;
} else {
return Theme.of(context).colorScheme.onErrorContainer;
return Theme.of(context).colorScheme.onError;
}
} else {
return Colors.purple;
Expand All @@ -107,8 +100,13 @@ class ChabanBridgeStatusBloc
String _getMainStatus(BuildContext context) {
final currentChabanBridgeForecast = state.currentChabanBridgeForecast;
if (currentChabanBridgeForecast != null &&
!currentChabanBridgeForecast.isCurrentlyClosed()) {
!currentChabanBridgeForecast.isCurrentlyClosed() &&
state.durationUntilNextEvent.inMinutes >= 120) {
return '${_getGreetings(context)}, ${AppLocalizations.of(context)!.theBridgeIsCurrently} ${AppLocalizations.of(context)!.open}';
} else if (currentChabanBridgeForecast != null &&
!currentChabanBridgeForecast.isCurrentlyClosed() &&
state.durationUntilNextEvent.inMinutes < 120) {
return '${_getGreetings(context)}, ${AppLocalizations.of(context)!.theBridgeIsCurrently} ${AppLocalizations.of(context)!.aboutToClose}';
} else {
return '${_getGreetings(context)}, ${AppLocalizations.of(context)!.theBridgeIsCurrently} ${AppLocalizations.of(context)!.closed}';
}
Expand Down Expand Up @@ -154,7 +152,7 @@ class ChabanBridgeStatusBloc
(durationUntilNextEvent.inSeconds /
durationBetweenPreviousAndNextEvent.inSeconds);
} else {
return 1;
return -1;
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/extensions/color_scheme_extension.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'package:flutter/material.dart';

extension ColorSchemeExtension on ColorScheme {
MaterialColor get warningColor {
return brightness == Brightness.light ? Colors.orange : Colors.amber;
}

MaterialColor get timeColor {
return brightness == Brightness.light ? Colors.orange : Colors.amber;
}
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"open": "open",
"scheduledToOpen": "scheduled to open in",
"theBridgeIsCurrently": "the Chaban bridge is",
"aboutToClose": "about to close",
"settingsTitle": "Settings",
"notificationsTitle": "Notifications",
"information": "Information",
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"open": "abierto",
"scheduledToOpen": "programado para abrir en",
"theBridgeIsCurrently": "el puente Chaban está",
"aboutToClose": "a punto de cerrarse",
"settingsTitle": "Ajustes",
"notificationsTitle": "Notificaciónes",
"information": "Información",
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"open": "ouvert",
"scheduledToOpen": "ouverture prévue dans",
"theBridgeIsCurrently": "le pont Chaban est",
"aboutToClose": "sur le point de fermer",
"settingsTitle": "Paramètres",
"notificationsTitle": "Notifications",
"information": "Information",
Expand Down
83 changes: 46 additions & 37 deletions lib/widgets/chaban_bridge_status_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:chabo/custom_properties.dart';
import 'package:chabo/custom_widgets_state.dart';
import 'package:chabo/extensions/duration_extension.dart';
import 'package:chabo/widgets/chaban_bridge_forecast_list_item.dart';
import 'package:chabo/widgets/custom_progress_bar_indicator.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -52,7 +53,8 @@ class ChabanBridgeStatusWidgetState
horizontal: 30,
vertical: 10,
),
child: Container(
child: AnimatedContainer(
duration: const Duration(milliseconds: 500),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: state.backgroundColor,
Expand All @@ -62,18 +64,21 @@ class ChabanBridgeStatusWidgetState
),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
state.mainMessageStatus,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 40,
color: state.foregroundColor,
),
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 500),
transitionBuilder:
(Widget child, Animation<double> animation) {
return FadeTransition(opacity: animation, child: child);
},
child: Text(
state.mainMessageStatus,
key: ValueKey<String>(state.mainMessageStatus),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 40,
color: state.foregroundColor,
),
],
),
),
),
),
Expand All @@ -87,33 +92,37 @@ class ChabanBridgeStatusWidgetState
fontSize: 20,
),
),
Text(
state.durationUntilNextEvent.durationToString(context),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 5),
child: SizedBox(
height: 10,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(
CustomProperties.borderRadius,
!state.durationUntilNextEvent.isNegative
? Text(
state.durationUntilNextEvent
.durationToString(context),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
child: LinearProgressIndicator(
value: state.completionPercentage,
valueColor: AlwaysStoppedAnimation<Color>(
state.backgroundColor,
)
: const SizedBox.shrink(),
state.completionPercentage != -1
? Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 5),
child: SizedBox(
height: 10,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(
CustomProperties.borderRadius,
),
),
child: CustomProgressBarIndicator(
max: 1,
current: state.completionPercentage,
color: state.backgroundColor,
),
),
),
),
),
),
),
)
: const SizedBox.shrink(),
],
),
),
Expand Down
47 changes: 47 additions & 0 deletions lib/widgets/custom_progress_bar_indicator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';

class CustomProgressBarIndicator extends StatelessWidget {
final double max;
final double current;
final Color color;

const CustomProgressBarIndicator(
{Key? key, required this.max, required this.current, required this.color})
: super(key: key);

@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (_, boxConstraints) {
var x = boxConstraints.maxWidth;
var percent = (current / max) * x;
return Stack(
alignment: Alignment.centerLeft,
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: x,
height: 15,
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.inverseSurface,
width: 2,
),
borderRadius: BorderRadius.circular(35),
),
),
AnimatedContainer(
duration: const Duration(milliseconds: 500),
width: percent,
height: 10,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(35),
),
),
],
);
},
);
}
}

0 comments on commit c57d08e

Please sign in to comment.