Browse Source

Merge pull request #776 from nextcloud/cleanup/relative_time

style(neon): make RelativeTime stateful
pull/790/head
Nikolas Rimikis 1 year ago committed by GitHub
parent
commit
7c61625252
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      packages/neon/neon/lib/src/utils/relative_time.dart
  2. 61
      packages/neon/neon/lib/src/widgets/relative_time.dart

36
packages/neon/neon/lib/src/utils/relative_time.dart

@ -0,0 +1,36 @@
import 'package:meta/meta.dart';
/// Extension for formating the differnce between two [DateTime]s.
@internal
extension RelativeTimeFormat on DateTime {
/// Format the relative time between this and [to].
///
/// If unspecified [DateTime.now] will be used.
String formatRelative([final DateTime? to]) {
final now = to ?? DateTime.now();
var diff = now.difference(toLocal());
final text = StringBuffer();
// Sometimes something can be messed up...
if (diff.isNegative) {
if (diff.inMinutes >= 1) {
text.write('-');
}
diff = Duration(microseconds: -diff.inMicroseconds);
}
if (diff.inMinutes < 1) {
text.write('now');
} else if (diff.inHours < 1) {
text.write('${diff.inMinutes}m');
} else if (diff.inDays < 1) {
text.write('${diff.inHours}h');
} else if (diff.inDays < 365) {
text.write('${diff.inDays}d');
} else {
text.write('${diff.inDays ~/ 365}y');
}
return text.toString();
}
}

61
packages/neon/neon/lib/src/widgets/relative_time.dart

@ -1,49 +1,52 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:neon/src/utils/relative_time.dart';
class RelativeTime extends StatelessWidget {
/// Shows the time elapsed since a [DateTime] and periodically updates itself.
class RelativeTime extends StatefulWidget {
/// Creates a new relative DateTime widget.
const RelativeTime({
required this.date,
this.style,
super.key,
});
/// The timestamp to be displayed.
final DateTime date;
/// The text style of the calculated time.
///
/// If not specified the nearest [TextStyle] will be used.
final TextStyle? style;
static String format(final DateTime date) {
final now = DateTime.now();
var diff = now.difference(date.toLocal());
final text = StringBuffer();
@override
State<RelativeTime> createState() => _RelativeTimeState();
}
// Sometimes something can be messed up...
if (diff.isNegative) {
if (diff.inMinutes >= 1) {
text.write('-');
}
diff = Duration(microseconds: -diff.inMicroseconds);
}
class _RelativeTimeState extends State<RelativeTime> {
late final Timer timer;
if (diff.inMinutes < 1) {
text.write('now');
} else if (diff.inHours < 1) {
text.write('${diff.inMinutes}m');
} else if (diff.inDays < 1) {
text.write('${diff.inHours}h');
} else if (diff.inDays < 365) {
text.write('${diff.inDays}d');
} else {
text.write('${diff.inDays ~/ 365}y');
@override
void initState() {
timer = Timer.periodic(
const Duration(minutes: 1),
(final _) => setState(() {}),
);
super.initState();
}
return text.toString();
@override
void dispose() {
timer.cancel();
super.dispose();
}
@override
Widget build(final BuildContext context) => StreamBuilder(
stream: Stream.periodic(const Duration(minutes: 1)),
builder: (final context, final _) => Text(
format(date),
style: style,
),
Widget build(final BuildContext context) => Text(
widget.date.formatRelative(),
style: widget.style,
);
}

Loading…
Cancel
Save