Add app source and tests

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
alvocool
2026-10-11 10:15:30 +03:00
parent 7e246255c2
commit 38881d1fe1
135 changed files with 21057 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
/// Shared formatting helpers. Anything a screen would otherwise write inline
/// to render a value belongs here, so the same quantity reads the same way
/// everywhere in the app.
library;
/// Human-friendly "time ago" formatting.
String timeAgo(DateTime t) {
final d = DateTime.now().difference(t);
if (d.inSeconds < 45) return 'just now';
if (d.inMinutes < 60) return '${d.inMinutes}m ago';
if (d.inHours < 24) return '${d.inHours}h ago';
if (d.inDays < 7) return '${d.inDays}d ago';
String two(int n) => n.toString().padLeft(2, '0');
return '${t.year}-${two(t.month)}-${two(t.day)}';
}
/// Byte count as B / KB / MB / GB.
String formatBytes(int bytes) {
if (bytes < 1024) return '$bytes B';
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
if (bytes < 1024 * 1024 * 1024) {
return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
}
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB';
}
/// An integer with thousands separators — offsets and message counts are
/// unreadable without them.
String formatCount(int value) {
final digits = value.abs().toString();
final out = StringBuffer(value < 0 ? '-' : '');
for (var i = 0; i < digits.length; i++) {
if (i > 0 && (digits.length - i) % 3 == 0) out.write(',');
out.write(digits[i]);
}
return out.toString();
}
/// `HH:MM` for a timestamp.
String formatClock(DateTime t) {
String two(int n) => n.toString().padLeft(2, '0');
return '${two(t.hour)}:${two(t.minute)}';
}
/// The last segment of a path, accepting either separator and ignoring a
/// trailing slash.
String baseName(String path) {
final normalised = path.replaceAll('\\', '/').replaceAll(RegExp(r'/+$'), '');
final i = normalised.lastIndexOf('/');
return i >= 0 ? normalised.substring(i + 1) : normalised;
}
/// Joins a POSIX directory and a child name without doubling the separator.
String joinRemote(String base, String name) {
final trimmed = base.endsWith('/')
? base.substring(0, base.length - 1)
: base;
return '$trimmed/$name';
}
/// The parent of a POSIX path, bottoming out at `/`.
String parentRemote(String path) {
final trimmed = path.endsWith('/') && path.length > 1
? path.substring(0, path.length - 1)
: path;
final i = trimmed.lastIndexOf('/');
if (i <= 0) return '/';
return trimmed.substring(0, i);
}