Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions flutter_cache_manager/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ include: package:pedantic/analysis_options.1.8.0.yaml

analyzer:
strong-mode:
implicit-casts: false
implicit-casts: true
# implicit-dynamic: false
errors:
unused_import: warning
unused_local_variable: warning
dead_code: warning
invalid_override_of_non_virtual_member: error
enable-experiment:
- extension-methods

linter:
rules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Generated file. Do not edit.
//

// ignore_for_file: lines_longer_than_80_chars

import 'package:url_launcher_web/url_launcher_web.dart';

import 'package:flutter_web_plugins/flutter_web_plugins.dart';
Expand Down
61 changes: 31 additions & 30 deletions flutter_cache_manager/lib/src/cache_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,32 @@ class CacheManager implements BaseCacheManager {
/// The [fileService] can be used to customize how files are downloaded. For example
/// to edit the urls, add headers or use a proxy. You can also choose to supply
/// a CacheStore or WebHelper directly if you want more customization.
CacheManager(Config config) {
_config = config;
_store = CacheStore(config);
CacheManager(Config config)
: _config = config,
_store = CacheStore(config) {
_webHelper = WebHelper(_store, config.fileService);
}

@visibleForTesting
CacheManager.custom(
Config config, {
CacheStore cacheStore,
WebHelper webHelper,
}) {
_config = config;
_store = cacheStore ?? CacheStore(config);
CacheStore? cacheStore,
WebHelper? webHelper,
}) : _config = config,
_store = cacheStore ?? CacheStore(config) {
_webHelper = webHelper ?? WebHelper(_store, config.fileService);
}

Config _config;
final Config _config;

/// Store helper for cached files
CacheStore _store;
final CacheStore _store;

/// Get the underlying store helper
CacheStore get store => _store;

/// WebHelper to download and store files
WebHelper _webHelper;
late final WebHelper _webHelper;

/// Get the underlying web helper
WebHelper get webHelper => _webHelper;
Expand All @@ -74,13 +73,13 @@ class CacheManager implements BaseCacheManager {
@override
Future<File> getSingleFile(
String url, {
String key,
Map<String, String> headers,
String? key,
Map<String, String>? headers,
}) async {
key ??= url;
final cacheFile = await getFileFromCache(key);
if (cacheFile != null) {
if (cacheFile.validTill.isBefore(DateTime.now())) {
if (cacheFile.validTill!.isBefore(DateTime.now())) {
unawaited(downloadFile(url, key: key, authHeaders: headers));
}
return cacheFile.file;
Expand All @@ -95,12 +94,12 @@ class CacheManager implements BaseCacheManager {
@override
@Deprecated('Prefer to use the new getFileStream method')
Stream<FileInfo> getFile(String url,
{String key, Map<String, String> headers}) {
{String? key, Map<String, String>? headers}) {
return getFileStream(
url,
key: key,
withProgress: false,
).map((r) => r as FileInfo);
).where((r) => r is FileInfo).cast<FileInfo>();
}

/// Get the file from the cache and/or online, depending on availability and age.
Expand All @@ -116,18 +115,18 @@ class CacheManager implements BaseCacheManager {
/// might be outdated and a new file is being downloaded in the background.
@override
Stream<FileResponse> getFileStream(String url,
{String key, Map<String, String> headers, bool withProgress}) {
{String? key, Map<String, String>? headers, bool withProgress = false}) {
key ??= url;
final streamController = StreamController<FileResponse>();
_pushFileToStream(
streamController, url, key, headers, withProgress ?? false);
streamController, url, key, headers, withProgress);
return streamController.stream;
}

Future<void> _pushFileToStream(StreamController streamController, String url,
String key, Map<String, String> headers, bool withProgress) async {
String? key, Map<String, String>? headers, bool withProgress) async {
key ??= url;
FileInfo cacheFile;
FileInfo? cacheFile;
try {
cacheFile = await getFileFromCache(key);
if (cacheFile != null) {
Expand All @@ -138,7 +137,7 @@ class CacheManager implements BaseCacheManager {
print(
'CacheManager: Failed to load cached file for $url with error:\n$e');
}
if (cacheFile == null || cacheFile.validTill.isBefore(DateTime.now())) {
if (cacheFile == null || cacheFile.validTill!.isBefore(DateTime.now())) {
try {
await for (var response
in _webHelper.downloadFile(url, key: key, authHeaders: headers)) {
Expand Down Expand Up @@ -166,7 +165,9 @@ class CacheManager implements BaseCacheManager {
///Download the file and add to cache
@override
Future<FileInfo> downloadFile(String url,
{String key, Map<String, String> authHeaders, bool force = false}) async {
{String? key,
Map<String, String>? authHeaders,
bool force = false}) async {
key ??= url;
var fileResponse = await _webHelper
.downloadFile(
Expand All @@ -182,13 +183,13 @@ class CacheManager implements BaseCacheManager {
/// Get the file from the cache.
/// Specify [ignoreMemCache] to force a re-read from the database
@override
Future<FileInfo> getFileFromCache(String key,
Future<FileInfo?> getFileFromCache(String key,
{bool ignoreMemCache = false}) =>
_store.getFile(key, ignoreMemCache: ignoreMemCache);

///Returns the file from memory if it has already been fetched
@override
Future<FileInfo> getFileFromMemory(String key) =>
Future<FileInfo?> getFileFromMemory(String key) =>
_store.getFileFromMemory(key);

/// Put a file in the cache. It is recommended to specify the [eTag] and the
Expand All @@ -201,8 +202,8 @@ class CacheManager implements BaseCacheManager {
Future<File> putFile(
String url,
Uint8List fileBytes, {
String key,
String eTag,
String? key,
String? eTag,
Duration maxAge = const Duration(days: 30),
String fileExtension = 'file',
}) async {
Expand All @@ -216,7 +217,7 @@ class CacheManager implements BaseCacheManager {
eTag: eTag,
);

final file = await _config.fileSystem.createFile(cacheObject.relativePath);
final file = await _config.fileSystem.createFile(cacheObject.relativePath!);
await file.writeAsBytes(fileBytes);
unawaited(_store.putFile(cacheObject));
return file;
Expand All @@ -233,8 +234,8 @@ class CacheManager implements BaseCacheManager {
Future<File> putFileStream(
String url,
Stream<List<int>> source, {
String key,
String eTag,
String? key,
String? eTag,
Duration maxAge = const Duration(days: 30),
String fileExtension = 'file',
}) async {
Expand All @@ -250,7 +251,7 @@ class CacheManager implements BaseCacheManager {
eTag: eTag,
);

var file = await _config.fileSystem.createFile(cacheObject.relativePath);
var file = await _config.fileSystem.createFile(cacheObject.relativePath!);

// Always copy file
var sink = file.openWrite();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ abstract class BaseCacheManager {
/// returned from the cache there will be no progress given, although the file
/// might be outdated and a new file is being downloaded in the background.
Stream<FileResponse> getFileStream(String url,
{String key, Map<String, String> headers, bool withProgress});
{String? key, Map<String, String>? headers, bool withProgress});

///Download the file and add to cache
Future<FileInfo> downloadFile(String url,
{String key, Map<String, String> authHeaders, bool force = false});
{String? key, Map<String, String>? authHeaders, bool force = false});

/// Get the file from the cache.
/// Specify [ignoreMemCache] to force a re-read from the database
Future<FileInfo> getFileFromCache(String key, {bool ignoreMemCache = false});
Future<FileInfo?> getFileFromCache(String key, {bool ignoreMemCache = false});

///Returns the file from memory if it has already been fetched
Future<FileInfo> getFileFromMemory(String key);
Future<FileInfo?> getFileFromMemory(String key);

/// Put a file in the cache. It is recommended to specify the [eTag] and the
/// [maxAge]. When [maxAge] is passed and the eTag is not set the file will
Expand All @@ -61,8 +61,8 @@ abstract class BaseCacheManager {
Future<File> putFile(
String url,
Uint8List fileBytes, {
String key,
String eTag,
String? key,
String? eTag,
Duration maxAge = const Duration(days: 30),
String fileExtension = 'file',
});
Expand All @@ -77,8 +77,8 @@ abstract class BaseCacheManager {
Future<File> putFileStream(
String url,
Stream<List<int>> source, {
String key,
String eTag,
String? key,
String? eTag,
Duration maxAge = const Duration(days: 30),
String fileExtension = 'file',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import '../config/config.dart';
class DefaultCacheManager extends CacheManager with ImageCacheManager {
static const key = 'libCachedImageData';

static DefaultCacheManager _instance;
static late final DefaultCacheManager _instance = DefaultCacheManager._();
factory DefaultCacheManager() {
_instance ??= DefaultCacheManager._();
return _instance;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ mixin ImageCacheManager on BaseCacheManager {
/// and returned to the caller.
Stream<FileResponse> getImageFile(
String url, {
String key,
Map<String, String> headers,
bool withProgress,
int maxHeight,
int maxWidth,
String? key,
Map<String, String>? headers,
bool withProgress = false,
int? maxHeight,
int? maxWidth,
}) async* {
if (maxHeight == null && maxWidth == null) {
yield* getFileStream(url,
Expand All @@ -37,13 +37,14 @@ mixin ImageCacheManager on BaseCacheManager {
var fromCache = await getFileFromCache(resizedKey);
if (fromCache != null) {
yield fromCache;
if (fromCache.validTill.isAfter(DateTime.now())) {
if (fromCache.validTill!.isAfter(DateTime.now())) {
return;
}
withProgress = false;
}
if (!_runningResizes.containsKey(resizedKey)) {
_runningResizes[resizedKey] = _fetchedResizedFile(
var runningResize = _runningResizes[resizedKey];
if (runningResize == null) {
runningResize = _fetchedResizedFile(
url,
key,
resizedKey,
Expand All @@ -52,25 +53,26 @@ mixin ImageCacheManager on BaseCacheManager {
maxWidth: maxWidth,
maxHeight: maxHeight,
);
_runningResizes[resizedKey] = runningResize;
}
yield* _runningResizes[resizedKey];
yield* runningResize;
_runningResizes.remove(resizedKey);
}

final Map<String, Stream<FileResponse>> _runningResizes = {};
Future<FileInfo> _resizeImageFile(
FileInfo originalFile,
String key,
int maxWidth,
int maxHeight,
int? maxWidth,
int? maxHeight,
) async {
var originalFileName = originalFile.file.path;
var fileExtension = originalFileName.split('.').last;
if (!supportedFileNames.contains(fileExtension)) {
return originalFile;
}

var image = decodeImage(await originalFile.file.readAsBytes());
var image = decodeImage(await originalFile.file.readAsBytes())!;
if (maxWidth != null && maxHeight != null) {
var resizeFactorWidth = image.width / maxWidth;
var resizeFactorHeight = image.height / maxHeight;
Expand All @@ -81,8 +83,8 @@ mixin ImageCacheManager on BaseCacheManager {
}

var resized = copyResize(image, width: maxWidth, height: maxHeight);
var resizedFile = encodeNamedImage(resized, originalFileName);
var maxAge = originalFile.validTill.difference(DateTime.now());
var resizedFile = encodeNamedImage(resized, originalFileName)!;
var maxAge = originalFile.validTill!.difference(DateTime.now());

var file = await putFile(
originalFile.originalUrl,
Expand All @@ -104,10 +106,10 @@ mixin ImageCacheManager on BaseCacheManager {
String url,
String originalKey,
String resizedKey,
Map<String, String> headers,
Map<String, String>? headers,
bool withProgress, {
int maxWidth,
int maxHeight,
int? maxWidth,
int? maxHeight,
}) async* {
await for (var response in getFileStream(
url,
Expand Down
Loading