Files
clide/lib/widgets/src/clide_file_image.dart
T
jpmschweitzerandClaude Opus 4.8 6d0ebab721 chore: adopt Dart 3.9 toolchain — honest floor + tall-style reformat (T-353)
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>
2026-06-11 12:11:53 +02:00

38 lines
1.5 KiB
Dart

import 'dart:io';
import 'package:flutter/widgets.dart';
/// A [FileImage] whose cache key also folds in the file's modification time and
/// size — so re-showing a path whose bytes changed *in place* re-decodes
/// instead of returning Flutter's stale cached frame (T-312).
///
/// Plain `Image.file` / `FileImage` key the global `imageCache` by `(path,
/// scale)` only, so overwriting a file at the same path is invisible: the cache
/// hands back the previously decoded image. Hit live when re-exporting a
/// wireframe PNG in place kept showing the prior render. Folding mtime + size
/// into `==`/`hashCode` makes an overwrite a fresh key → a cache miss → a
/// re-read of the current bytes; an unchanged file still hits the cache.
class ClideFileImage extends FileImage {
ClideFileImage(String path, {double scale = 1.0}) : _stamp = _stampOf(path), super(File(path), scale: scale);
/// mtime ⊕ size — changes on any in-place overwrite (a write bumps mtime; a
/// different length bumps size even within one clock tick). 0 if the file
/// can't be stat'd, which falls back to plain path+scale keying.
final int _stamp;
static int _stampOf(String path) {
try {
final s = File(path).statSync();
return s.modified.millisecondsSinceEpoch ^ s.size;
} catch (_) {
return 0;
}
}
@override
bool operator ==(Object other) => other is ClideFileImage && other.file.path == file.path && other.scale == scale && other._stamp == _stamp;
@override
int get hashCode => Object.hash(file.path, scale, _stamp);
}