Files
imajviewer/lib/services/image_manager.dart
Alhan 72c35a8a26
Some checks failed
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
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}