From 047f892dc4781ad95671e75e84c1f03034121b52 Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Thu, 31 Mar 2022 16:54:47 +0200 Subject: [PATCH 1/7] Add conditionally colored PR timestamps Uses human-readable timestamps via timeago. --- app/lib/ui/colors.dart | 7 ++++++ app/lib/ui/pr_card.dart | 55 +++++++++++++++++++++++++++++------------ app/pubspec.lock | 16 +++++++++++- app/pubspec.yaml | 1 + 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/app/lib/ui/colors.dart b/app/lib/ui/colors.dart index 63ad060..a84bf1c 100644 --- a/app/lib/ui/colors.dart +++ b/app/lib/ui/colors.dart @@ -22,3 +22,10 @@ MaterialColor createMaterialColor(Color color) { } return MaterialColor(color.value, swatch); } + +extension CustomColorScheme on ColorScheme { + Color get fresh => brightness == Brightness.light? const Color.fromARGB(255, 193, 201, 236) : const Color.fromARGB(255, 50, 73, 173); + Color get waiting => brightness == Brightness.light? const Color.fromARGB(255, 214, 246, 201) : const Color.fromARGB(255, 48, 126, 17); + Color get stale => brightness == Brightness.light? const Color.fromARGB(255, 231, 200, 200) : const Color.fromARGB(255, 141, 41, 41); + Color get rotten => brightness == Brightness.light? const Color.fromARGB(255, 195, 178, 149) : const Color.fromARGB(255, 116, 80, 23); +} diff --git a/app/lib/ui/pr_card.dart b/app/lib/ui/pr_card.dart index a507e26..773dd52 100644 --- a/app/lib/ui/pr_card.dart +++ b/app/lib/ui/pr_card.dart @@ -4,9 +4,9 @@ import 'package:primate/services/pr.dart'; import 'package:primate/ui/colors.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:crypto/crypto.dart'; +import 'package:timeago/timeago.dart' as timeago; class PRCard extends StatefulWidget { final PR pr; @@ -93,23 +93,21 @@ List cardContentForSize(BuildContext context, PR pr) { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - pr.title, - overflow: TextOverflow.ellipsis, - style: const TextStyle(fontWeight: FontWeight.bold), + Row( + children: [ + conditionallyColoredDuration(context, pr.created), + Text( + pr.title, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ] ), Text( "${pr.sourceBranch} \u{2192} ${pr.targetBranch}", overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.overline, ), - Text( - DateFormat("dd MMM. yyyy").format(pr.created) + - " by " + - pr.user, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.overline, - ), ], ), ), @@ -156,10 +154,7 @@ List cardContentForSize(BuildContext context, PR pr) { ), Row( children: [ - Text( - DateFormat("dd MMM. yyyy").format(pr.created), - overflow: TextOverflow.ellipsis, - ), + conditionallyColoredDuration(context, pr.created), Padding( padding: const EdgeInsets.only(left: 5), child: Tooltip( @@ -193,3 +188,31 @@ IconData iconForPRStatus(String status) { return FontAwesomeIcons.codeBranch; } } + +Widget conditionallyColoredDuration(BuildContext context, DateTime created) { + DateTime now = DateTime.now(); + int ageInHours = now.difference(created).inHours; + Color color = Theme.of(context).colorScheme.rotten; + + if (ageInHours < 24*14) { + color = Theme.of(context).colorScheme.stale; + } + + if (ageInHours < 24*5) { + color = Theme.of(context).colorScheme.waiting; + } + + if (ageInHours < 8) { + color = Theme.of(context).colorScheme.fresh; + } + + return Container( + margin: const EdgeInsets.fromLTRB(0, 6, 6, 6), + padding: const EdgeInsets.fromLTRB(12, 4, 12, 4), + decoration: BoxDecoration( + color: color, + borderRadius: const BorderRadius.all(Radius.circular(20)) + ), + child: Text(timeago.format(created)), + ); +} diff --git a/app/pubspec.lock b/app/pubspec.lock index 542bfe4..0877086 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -219,6 +219,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -391,7 +398,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" + timeago: + dependency: "direct main" + description: + name: timeago + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.2" typed_data: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index fc37732..776618d 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -43,6 +43,7 @@ dependencies: intl: ^0.17.0 flutter_svg: ^1.0.0 google_fonts: ^2.2.0 + timeago: ^3.2.2 dev_dependencies: flutter_launcher_icons: ^0.9.2 From de2dbbe1391d3d44ac25d9e7771aa1560cf6afab Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Thu, 7 Apr 2022 15:13:27 +0200 Subject: [PATCH 2/7] Fix overflow issue in portrait orientation --- app/lib/ui/pr_card.dart | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/app/lib/ui/pr_card.dart b/app/lib/ui/pr_card.dart index 773dd52..3eedb5f 100644 --- a/app/lib/ui/pr_card.dart +++ b/app/lib/ui/pr_card.dart @@ -93,21 +93,17 @@ List cardContentForSize(BuildContext context, PR pr) { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - conditionallyColoredDuration(context, pr.created), - Text( - pr.title, - overflow: TextOverflow.ellipsis, - style: const TextStyle(fontWeight: FontWeight.bold), - ), - ] + Text( + pr.title, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontWeight: FontWeight.bold), ), Text( "${pr.sourceBranch} \u{2192} ${pr.targetBranch}", overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.overline, ), + conditionallyColoredDuration(context, pr.created) ], ), ), From 3e0d4fbb9453fbc0494508bb2e47e5051f8800e1 Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Thu, 7 Apr 2022 15:14:09 +0200 Subject: [PATCH 3/7] Change color scheme ever so slightly --- app/lib/ui/colors.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/lib/ui/colors.dart b/app/lib/ui/colors.dart index a84bf1c..9146123 100644 --- a/app/lib/ui/colors.dart +++ b/app/lib/ui/colors.dart @@ -24,8 +24,8 @@ MaterialColor createMaterialColor(Color color) { } extension CustomColorScheme on ColorScheme { - Color get fresh => brightness == Brightness.light? const Color.fromARGB(255, 193, 201, 236) : const Color.fromARGB(255, 50, 73, 173); - Color get waiting => brightness == Brightness.light? const Color.fromARGB(255, 214, 246, 201) : const Color.fromARGB(255, 48, 126, 17); - Color get stale => brightness == Brightness.light? const Color.fromARGB(255, 231, 200, 200) : const Color.fromARGB(255, 141, 41, 41); - Color get rotten => brightness == Brightness.light? const Color.fromARGB(255, 195, 178, 149) : const Color.fromARGB(255, 116, 80, 23); + Color get fresh => brightness == Brightness.light? const Color.fromARGB(255, 201, 211, 248) : const Color.fromARGB(255, 59, 96, 228); + Color get waiting => brightness == Brightness.light? const Color.fromARGB(255, 215, 234, 224) : const Color.fromARGB(255, 81, 152, 114); + Color get stale => brightness == Brightness.light? const Color.fromARGB(255, 244, 184, 194) : const Color.fromARGB(255, 114, 17, 33); + Color get rotten => brightness == Brightness.light? const Color.fromARGB(255, 235, 219, 193) : const Color.fromARGB(255, 86, 63, 27); } From 6305a974f3a49947b9f06542a663af380d9430af Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Tue, 12 Apr 2022 15:12:24 +0200 Subject: [PATCH 4/7] Adjust time scale for conditional colors --- app/lib/ui/pr_card.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/lib/ui/pr_card.dart b/app/lib/ui/pr_card.dart index 3eedb5f..72c707e 100644 --- a/app/lib/ui/pr_card.dart +++ b/app/lib/ui/pr_card.dart @@ -187,18 +187,18 @@ IconData iconForPRStatus(String status) { Widget conditionallyColoredDuration(BuildContext context, DateTime created) { DateTime now = DateTime.now(); - int ageInHours = now.difference(created).inHours; + int ageInHours = now.difference(created).inDays; Color color = Theme.of(context).colorScheme.rotten; - if (ageInHours < 24*14) { + if (ageInHours < 14) { color = Theme.of(context).colorScheme.stale; } - if (ageInHours < 24*5) { + if (ageInHours < 5) { color = Theme.of(context).colorScheme.waiting; } - if (ageInHours < 8) { + if (ageInHours < 1) { color = Theme.of(context).colorScheme.fresh; } From 5f80ec485f358e099e72a67db0c5c976f986dc6a Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Tue, 12 Apr 2022 15:12:59 +0200 Subject: [PATCH 5/7] Do not use colored timestamps in portrait mode --- app/lib/ui/pr_card.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/ui/pr_card.dart b/app/lib/ui/pr_card.dart index 72c707e..96820b9 100644 --- a/app/lib/ui/pr_card.dart +++ b/app/lib/ui/pr_card.dart @@ -103,7 +103,7 @@ List cardContentForSize(BuildContext context, PR pr) { overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.overline, ), - conditionallyColoredDuration(context, pr.created) + Text(timeago.format(pr.created)), ], ), ), From 19267e98e52f559f9c8770d17fcef37cee585292 Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Tue, 12 Apr 2022 15:16:14 +0200 Subject: [PATCH 6/7] Fix inconsistent variable naming --- app/lib/ui/pr_card.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/lib/ui/pr_card.dart b/app/lib/ui/pr_card.dart index 96820b9..0bcad76 100644 --- a/app/lib/ui/pr_card.dart +++ b/app/lib/ui/pr_card.dart @@ -187,18 +187,18 @@ IconData iconForPRStatus(String status) { Widget conditionallyColoredDuration(BuildContext context, DateTime created) { DateTime now = DateTime.now(); - int ageInHours = now.difference(created).inDays; + int ageInDays = now.difference(created).inDays; Color color = Theme.of(context).colorScheme.rotten; - if (ageInHours < 14) { + if (ageInDays < 14) { color = Theme.of(context).colorScheme.stale; } - if (ageInHours < 5) { + if (ageInDays < 5) { color = Theme.of(context).colorScheme.waiting; } - if (ageInHours < 1) { + if (ageInDays < 1) { color = Theme.of(context).colorScheme.fresh; } From b04b4207d072f68ec30471faa5ac9d088d37d8aa Mon Sep 17 00:00:00 2001 From: Simon Kienzler Date: Tue, 12 Apr 2022 15:18:11 +0200 Subject: [PATCH 7/7] Reformat color configuration Co-authored-by: Tobias Brumhard --- app/lib/ui/colors.dart | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/lib/ui/colors.dart b/app/lib/ui/colors.dart index 9146123..e3498eb 100644 --- a/app/lib/ui/colors.dart +++ b/app/lib/ui/colors.dart @@ -24,8 +24,16 @@ MaterialColor createMaterialColor(Color color) { } extension CustomColorScheme on ColorScheme { - Color get fresh => brightness == Brightness.light? const Color.fromARGB(255, 201, 211, 248) : const Color.fromARGB(255, 59, 96, 228); - Color get waiting => brightness == Brightness.light? const Color.fromARGB(255, 215, 234, 224) : const Color.fromARGB(255, 81, 152, 114); - Color get stale => brightness == Brightness.light? const Color.fromARGB(255, 244, 184, 194) : const Color.fromARGB(255, 114, 17, 33); - Color get rotten => brightness == Brightness.light? const Color.fromARGB(255, 235, 219, 193) : const Color.fromARGB(255, 86, 63, 27); + Color get fresh => brightness == Brightness.light + ? const Color(0xFFc9d3f8) + : const Color(0xFF3b60e4); + Color get waiting => brightness == Brightness.light + ? const Color(0xFFd7eae0) + : const Color(0xFF519872); + Color get stale => brightness == Brightness.light + ? const Color(0xFFf4b8c2) + : const Color(0xFF721121); + Color get rotten => brightness == Brightness.light + ? const Color(0xFFebdbc1) + : const Color(0xFF563f1b); }