Files
imajviewer/lib/services/image_manager.dart
T
Alhan 72c35a8a26
Build & Release / build-linux (push) Has been cancelled
Build & Release / build-windows (push) Has been cancelled
Build & Release / create-release (push) Has been cancelled
fix: image_canvas correctness + RAM fixes (v1.3.0)
- _imageSize reset on image switch (wrong swap threshold on nav)
- downsample caps both dims (tall images no longer full-res decode)
- single _readImageSize instead of leaking loadingBuilder listeners
- evict old downsample provider on full-res swap
- remove imageCache.clear() that dropped live image (gallery flash)
2026-08-14 21:54:34 +03:00

115 lines
3.1 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
class ImageManager extends ChangeNotifier {
static final ImageManager _instance = ImageManager._();
static ImageManager get instance => _instance;
ImageManager._();
static const _supportedExtensions = [
'png', 'jpg', 'jpeg', 'jfif', 'jpe', 'webp', 'bmp', 'gif', 'wbmp',
];
final List<String> _images = [];
int _currentIndex = 0;
bool _sortByName = false;
List<String> get images => List.unmodifiable(_images);
int get currentIndex => _currentIndex;
int get imageCount => _images.length;
bool get sortByName => _sortByName;
String get currentImagePath {
if (_images.isEmpty) return '';
return _images[_currentIndex];
}
/// Açılan resmin bulunduğu klasörü galeri olarak kurar (en yeni önce).
void setGalleryFromPaths(List<String> paths) {
String? anchor;
for (final p in paths) {
final ext = p.toLowerCase().split('.').last;
if (_supportedExtensions.contains(ext) && File(p).existsSync()) {
anchor = p;
break;
}
}
if (anchor == null) return;
final dir = File(anchor).parent;
if (!dir.existsSync()) return;
final List<(String, DateTime)> entries = [];
for (final entity in dir.listSync()) {
if (entity is! File) continue;
final p = entity.path;
final ext = p.toLowerCase().split('.').last;
if (!_supportedExtensions.contains(ext)) continue;
try {
entries.add((p, entity.lastModifiedSync()));
} catch (_) {}
}
entries.sort((a, b) {
if (_sortByName) {
return a.$1.toLowerCase().compareTo(b.$1.toLowerCase());
}
final byDate = b.$2.compareTo(a.$2);
return byDate != 0 ? byDate : a.$1.compareTo(b.$1);
});
_images
..clear()
..addAll(entries.map((e) => e.$1));
_currentIndex = _images.indexOf(anchor);
if (_currentIndex < 0) {
final base = anchor.split(Platform.pathSeparator).last;
_currentIndex = _images
.indexWhere((p) => p.split(Platform.pathSeparator).last == base);
}
if (_currentIndex < 0) _currentIndex = 0;
notifyListeners();
}
void setSortByName(bool value) {
if (_sortByName == value) return;
_sortByName = value;
if (_images.isNotEmpty) {
setGalleryFromPaths([_images[_currentIndex]]);
} else {
notifyListeners();
}
}
void setCurrentIndex(int index) {
if (index < 0 || index >= _images.length) return;
_currentIndex = index;
notifyListeners();
}
void previousImage() {
if (_images.isEmpty) return;
_currentIndex = (_currentIndex - 1 + _images.length) % _images.length;
notifyListeners();
}
void nextImage() {
if (_images.isEmpty) return;
_currentIndex = (_currentIndex + 1) % _images.length;
notifyListeners();
}
/// Configure image cache for high-res images
static void configureCache() {
PaintingBinding.instance.imageCache.maximumSize = 16;
PaintingBinding.instance.imageCache.maximumSizeBytes = 256 * 1024 * 1024; // 256 MB
}
void clear() {
_images.clear();
_currentIndex = 0;
notifyListeners();
}
}