Raise the declared minimums in pubspec.yaml to what our deps already require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist 0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is the binding floor. Pin the exact build toolchain in .fvmrc (Flutter 3.44.1). Moving to the Dart 3.9 language level switches `dart format` to the new "tall" style and enables two new lints. This commit is the resulting mechanical churn, isolated from any behaviour change: - whole-tree `dart format` reformat (tall style) - `dart fix` for unnecessary_underscores + use_null_aware_elements No runtime behaviour change; `make test` green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
53 lines
1.8 KiB
Dart
53 lines
1.8 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart' as flutter_services;
|
|
|
|
/// Typed, per-content-kind clipboard with a plaintext fallback.
|
|
///
|
|
/// Extensions write typed values (`write<GitHunk>(hunk)`) and read in
|
|
/// the same type (`readAs<GitHunk>()`). Anything with a `toPlain`
|
|
/// callback also syncs to the OS clipboard so external apps see
|
|
/// reasonable text. The history ring keeps the last [historyLimit]
|
|
/// entries per type for quick recall.
|
|
class ClideClipboard {
|
|
ClideClipboard({this.historyLimit = 16});
|
|
|
|
final int historyLimit;
|
|
final Map<Type, List<Object>> _history = {};
|
|
|
|
Future<void> write<T extends Object>(T value, {String Function(T)? toPlain}) async {
|
|
final bucket = _history.putIfAbsent(T, () => <Object>[]);
|
|
bucket.insert(0, value);
|
|
if (bucket.length > historyLimit) bucket.removeLast();
|
|
if (toPlain != null) {
|
|
await flutter_services.Clipboard.setData(flutter_services.ClipboardData(text: toPlain(value)));
|
|
}
|
|
}
|
|
|
|
T? readAs<T extends Object>() {
|
|
final bucket = _history[T];
|
|
if (bucket == null || bucket.isEmpty) return null;
|
|
return bucket.first as T;
|
|
}
|
|
|
|
List<T> historyOf<T extends Object>() {
|
|
final bucket = _history[T];
|
|
if (bucket == null) return const [];
|
|
return bucket.cast<T>().toList(growable: false);
|
|
}
|
|
|
|
Future<String?> readPlain() async {
|
|
final d = await flutter_services.Clipboard.getData('text/plain');
|
|
return d?.text;
|
|
}
|
|
|
|
Future<void> writePlain(String text) async {
|
|
await flutter_services.Clipboard.setData(flutter_services.ClipboardData(text: text));
|
|
final bucket = _history.putIfAbsent(String, () => <Object>[]);
|
|
bucket.insert(0, text);
|
|
if (bucket.length > historyLimit) bucket.removeLast();
|
|
}
|
|
|
|
@visibleForTesting
|
|
void clear() => _history.clear();
|
|
}
|