38 lines
1.3 KiB
Dart
38 lines
1.3 KiB
Dart
|
|
import "package:flutter/material.dart";
|
||
|
|
import "package:flutter/services.dart";
|
||
|
|
import "package:intl/intl.dart";
|
||
|
|
|
||
|
|
/// One path for all replies so the Re: rule lives once.
|
||
|
|
String replySubject(String subject) =>
|
||
|
|
subject.isEmpty || subject.startsWith("Re:") ? subject : "Re: $subject";
|
||
|
|
|
||
|
|
String formatTime(int? seconds) {
|
||
|
|
if (seconds == null) return "";
|
||
|
|
final date = DateTime.fromMillisecondsSinceEpoch(seconds * 1000, isUtc: true);
|
||
|
|
return DateFormat.yMMMMd().add_jm().format(date.toLocal());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// The full date is too wide for a list row's trailing slot — this is what
|
||
|
|
/// message_tile.dart shows instead: just a time for today, else a short date.
|
||
|
|
String formatShortTime(int? seconds) {
|
||
|
|
if (seconds == null) return "";
|
||
|
|
final date =
|
||
|
|
DateTime.fromMillisecondsSinceEpoch(seconds * 1000, isUtc: true).toLocal();
|
||
|
|
final now = DateTime.now();
|
||
|
|
if (date.year == now.year && date.month == now.month && date.day == now.day) {
|
||
|
|
return DateFormat.jm().format(date);
|
||
|
|
}
|
||
|
|
if (date.year == now.year) {
|
||
|
|
return DateFormat.MMMd().format(date);
|
||
|
|
}
|
||
|
|
return DateFormat.yMd().format(date);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> copyText(BuildContext context, String text) async {
|
||
|
|
await Clipboard.setData(ClipboardData(text: text));
|
||
|
|
if (context.mounted) {
|
||
|
|
ScaffoldMessenger.of(context)
|
||
|
|
.showSnackBar(const SnackBar(content: Text("Copied to clipboard")));
|
||
|
|
}
|
||
|
|
}
|