Skip to content

Commit

Permalink
refactor: refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
koji-1009 committed Dec 22, 2023
1 parent edaf11f commit a72b3b3
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 151 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Taro

Taro is a Flutter library for loading data from various sources.
It provides a set of classes and methods for loading data from network and storage.
`Taro` is a library for loading data from network and saving it to storage to speed up data loading.
By using `TaroImage`, you can also use the memory cache by CacheImage of Flutter.

This library aims to be easy to use and maintain by reducing the amount of dependent libraries and code.

## Features

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:taro/src/taro_resizer.dart';

typedef StorageFile = ({
Uint8List bytes,
CacheInfo info,
});

/// `CacheInfo` is a class that manages the cache information for a `StorageFile`.
class CacheInfo {
/// Creates a new instance of `CacheInfo`.
/// The [expireAt] parameter sets the expiration date of the cache.
const CacheInfo({
/// The cache file information which saved in storage.
class CacheFileInfo {
const CacheFileInfo({
required this.contentType,
required this.expireAt,
required this.resizeMode,
Expand All @@ -35,11 +27,10 @@ class CacheInfo {
/// The maximum height of the cache.
final int? maxHeight;

/// Creates a new instance of `CacheInfo` from a JSON string.
factory CacheInfo.fromJson(String jsonStr) {
factory CacheFileInfo.fromJson(String jsonStr) {
final json = jsonDecode(jsonStr) as Map<String, dynamic>;

return CacheInfo(
return CacheFileInfo(
contentType: json['contentType'] as String,
expireAt: json['expireAt'] == null
? null
Expand All @@ -52,7 +43,6 @@ class CacheInfo {
);
}

/// Converts the `CacheInfo` object to a JSON string.
String toJson() => jsonEncode({
'contentType': contentType,
'expireAt': expireAt?.toUtc().toIso8601String(),
Expand Down
19 changes: 7 additions & 12 deletions lib/src/storage/native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import 'dart:typed_data';

import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:taro/src/loader/storage_file.dart';
import 'package:taro/src/storage/cache_file_info.dart';
import 'package:taro/src/taro_resizer.dart';

/// Loads a `StorageFile` with the provided filename.
Future<StorageFile?> load({
/// Load [Uint8List] from storage.
Future<Uint8List?> load({
required String filename,
required TaroResizeOption resizeOption,
}) async {
Expand All @@ -27,7 +27,7 @@ Future<StorageFile?> load({
}

final cacheInfoFileData = await cacheInfoFile.readAsString();
final cacheFileInfo = CacheInfo.fromJson(cacheInfoFileData);
final cacheFileInfo = CacheFileInfo.fromJson(cacheInfoFileData);

final now = DateTime.now();
if (cacheFileInfo.expireAt != null && cacheFileInfo.expireAt!.isBefore(now)) {
Expand All @@ -47,23 +47,18 @@ Future<StorageFile?> load({
}

final bytes = await cacheFile.readAsBytes();
return (
bytes: bytes,
info: cacheFileInfo,
);
return bytes;
}

/// Saves the provided bytes as a `StorageFile` with the provided filename and content type.
///
/// The [expireAt] parameter determines when the file should expire.
/// Save [Uint8List] to storage.
Future<void> save({
required String filename,
required Uint8List bytes,
required String contentType,
required DateTime? expireAt,
required TaroResizeOption resizeOption,
}) async {
final cacheFileInfo = CacheInfo(
final cacheFileInfo = CacheFileInfo(
contentType: contentType,
expireAt: expireAt,
resizeMode: resizeOption.mode,
Expand Down
11 changes: 3 additions & 8 deletions lib/src/storage/unsupported.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import 'dart:typed_data';

import 'package:taro/src/loader/storage_file.dart';
import 'package:taro/src/taro_resizer.dart';

/// Loads a `StorageFile` with the provided filename.
///
/// The [filename] parameter is the name of the file to load.
Future<StorageFile?> load({
/// Load [Uint8List] from storage.
Future<Uint8List?> load({
required String filename,
required TaroResizeOption resizeOption,
}) async =>
throw UnimplementedError();

/// Saves the provided bytes as a `StorageFile` with the provided filename and content type.
///
/// The [expireAt] parameter determines when the file should expire.
/// Save [Uint8List] to storage.
Future<void> save({
required String filename,
required Uint8List bytes,
Expand Down
19 changes: 7 additions & 12 deletions lib/src/storage/web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import 'dart:js_interop';
import 'dart:typed_data';

import 'package:js/js_util.dart' as js_util;
import 'package:taro/src/loader/storage_file.dart';
import 'package:taro/src/storage/cache_file_info.dart';
import 'package:taro/src/storage/web_cache.dart';
import 'package:taro/src/taro_resizer.dart';

/// Loads a `StorageFile` with the provided filename.
Future<StorageFile?> load({
/// Load [Uint8List] from storage.
Future<Uint8List?> load({
required String filename,
required TaroResizeOption resizeOption,
}) async {
Expand Down Expand Up @@ -44,7 +44,7 @@ Future<StorageFile?> load({
final cacheFileInfo = await js_util.promiseToFuture(
cacheFileInfoJs.text(),
);
final cacheInfo = CacheInfo.fromJson(cacheFileInfo);
final cacheInfo = CacheFileInfo.fromJson(cacheFileInfo);

final now = DateTime.now();
if (cacheInfo.expireAt != null && cacheInfo.expireAt!.isBefore(now)) {
Expand All @@ -62,23 +62,18 @@ Future<StorageFile?> load({
cacheFileJs.arrayBuffer(),
);
final bytes = Uint8List.view(bufferJs.toDart);
return (
bytes: bytes,
info: cacheInfo,
);
return bytes;
}

/// Saves the provided bytes as a `StorageFile` with the provided filename and content type.
///
/// The [expireAt] parameter determines when the file should expire.
/// Save [Uint8List] to storage.
Future<void> save({
required String filename,
required Uint8List bytes,
required String contentType,
required DateTime? expireAt,
required TaroResizeOption resizeOption,
}) async {
final cacheFileInfo = CacheInfo(
final cacheFileInfo = CacheFileInfo(
contentType: contentType,
expireAt: expireAt,
resizeMode: resizeOption.mode,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/storage/web_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Promise<T> {
@JS()
external Window get window;

/// see [https://developer.mozilla.org/en-US/docs/Web/API/Window]
@JS('Window')
@staticInterop
class Window {}
Expand All @@ -28,6 +29,7 @@ extension WindowExtension on Window {
external CacheStorage? get caches;
}

/// see [https://developer.mozilla.org/en-US/docs/Web/API/Cache]
@JS('Cache')
@staticInterop
class Cache {}
Expand All @@ -40,6 +42,7 @@ extension CacheExtension on Cache {
external Promise<void> delete(JSAny request);
}

/// see [https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage]
@JS('CacheStorage')
@staticInterop
class CacheStorage {}
Expand All @@ -48,6 +51,7 @@ extension CacheStorageExtension on CacheStorage {
external Promise<Cache> open(String cacheName);
}

/// see [https://developer.mozilla.org/en-US/docs/Web/API/Response]
@JS('Response')
@staticInterop
class Response {
Expand Down
43 changes: 20 additions & 23 deletions lib/src/taro.dart
Original file line number Diff line number Diff line change
@@ -1,65 +1,64 @@
import 'dart:typed_data';

import 'package:taro/src/loader/loader.dart';
import 'package:taro/src/loader/network_loader.dart';
import 'package:taro/src/loader/storage_loader.dart';
import 'package:taro/src/taro_image.dart';
import 'package:taro/src/taro_load_result.dart';
import 'package:taro/src/taro_loader.dart';
import 'package:taro/src/taro_loader_network.dart';
import 'package:taro/src/taro_loader_storage.dart';
import 'package:taro/src/taro_loader_type.dart';
import 'package:taro/src/taro_resizer.dart';

/// The default `TaroResizeOption` used by `Taro`.
/// The default [TaroResizeOption] used by [Taro].
const TaroResizeOption defaultResizeOption = (
mode: TaroResizeMode.skip,
maxWidth: null,
maxHeight: null,
);

/// Taro is a library for loading images. It uses three loaders: Storage, Memory, and Network.
/// [Taro] is a library for loading images. It uses two loaders: Storage and Network.
class Taro {
Taro._();

/// Creates a new instance of the `Taro` class.
/// Creates a new instance of the [Taro] class.
static final Taro _instance = Taro._();

/// Returns the singleton instance of the `Taro` class.
/// Returns the singleton instance of the [Taro] class.
static Taro get instance => _instance;

/// The `Loader` instance used to load data.
final _loader = Loader();
/// The [TaroLoader] instance used to load data.
final _loader = TaroLoader();

/// The `TaroResizeOption` used to resize images.
/// The [TaroResizeOption] used to resize images.
TaroResizeOption _resizeOption = defaultResizeOption;

/// The `TaroResizeOption` used to resize images.
/// The [TaroResizeOption] used to resize images.
/// Changing this option will affect all image loading.
set resizeOption(TaroResizeOption option) {
_resizeOption = option;
}

/// Changes the current `NetworkLoader` to the provided new loader.
set networkLoader(NetworkLoader newLoader) {
/// Changes the current [TaroNetworkLoader] to the provided new loader.
set networkLoader(TaroNetworkLoader newLoader) {
_loader.changeNetworkLoader(newLoader);
}

/// Changes the timeout of the current `NetworkLoader` to the provided duration.
/// Changes the timeout of the current [TaroNetworkLoader] to the provided duration.
/// The default timeout is 3 minutes.
set networkLoaderTimeout(Duration timeout) {
_loader.changeNetworkLoader(
NetworkLoader(
TaroNetworkLoader(
timeout: timeout,
),
);
}

/// Changes the current `StorageLoader` to the provided new loader.
set storageLoader(StorageLoader newLoader) {
/// Changes the current [TaroStorageLoader] to the provided new loader.
set storageLoader(TaroStorageLoader newLoader) {
_loader.changeStorageLoader(newLoader);
}

/// Loads an image from the provided URL and returns it as a [TaroImage].
/// The [headers] parameter is a map of request headers to send with the GET request.
/// If [checkMaxAgeIfExist] is true, the method checks the max age of the data.
/// Returns a Future that completes with the loaded `MemoryImage`.
/// The [resizeOption] parameter is used to resize the image. If it is not provided, the default resize option is used.
TaroImage loadImageProvider(
String url, {
Expand All @@ -79,7 +78,6 @@ class Taro {
/// Loads the data from the provided URL and returns it as a byte array.
/// The [headers] parameter is a map of request headers to send with the GET request.
/// If [checkMaxAgeIfExist] is true, the method checks the max age of the data.
/// Returns a Future that completes with the loaded byte array.
/// The [resizeOption] parameter is used to resize the image. If it is not provided, the default resize option is used.
Future<Uint8List> loadBytes(
String url, {
Expand All @@ -97,12 +95,11 @@ class Taro {
return result.bytes;
}

/// Loads the data from the provided URL and returns it as a `BytesWithType` object.
/// Loads the data from the provided URL and returns it as a [BytesWithType] object and the type of the load result.
/// The [headers] parameter is a map of request headers to send with the GET request.
/// If [checkMaxAgeIfExist] is true, the method checks the max age of the data.
/// Returns a Future that completes with the loaded `BytesWithType` object.
/// The [resizeOption] parameter is used to resize the image. If it is not provided, the default resize option is used.
Future<({Uint8List bytes, TaroLoadResultType type})> loadBytesWithType(
Future<({Uint8List bytes, TaroLoaderType type})> loadBytesWithType(
String url, {
Map<String, String> headers = const {},
bool checkMaxAgeIfExist = false,
Expand Down
18 changes: 9 additions & 9 deletions lib/src/taro_exception.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// `TaroException` is a base class for all exceptions in the Taro.
/// [TaroException] is a base class for all exceptions in the Taro.
sealed class TaroException implements Exception {
const TaroException();
}

/// `TaroLoadException` is thrown when there is an issue with loading data in the Taro library.
/// [TaroLoadException] is thrown when there is an issue with loading data in the Taro library.
final class TaroLoadException extends TaroException {
const TaroLoadException({
required this.message,
Expand All @@ -17,7 +17,7 @@ final class TaroLoadException extends TaroException {
}
}

/// `TaroMemoryException` is thrown when there is an issue with memory operations in the Taro library.
/// [TaroMemoryException] is thrown when there is an issue with memory operations in the Taro library.
/// It includes the maximum size of the memory and the original exception that caused the error.
final class TaroMemoryException extends TaroException {
const TaroMemoryException({
Expand All @@ -34,7 +34,7 @@ final class TaroMemoryException extends TaroException {
}
}

/// `TaroStorageException` is thrown when there is an issue with storage operations in the Taro library.
/// [TaroStorageException] is thrown when there is an issue with storage operations in the Taro library.
/// It includes the original exception that caused the error.
final class TaroStorageException extends TaroException {
const TaroStorageException({
Expand All @@ -49,7 +49,7 @@ final class TaroStorageException extends TaroException {
}
}

/// `TaroUriParseException` is thrown when there is an issue with parsing a URI in the Taro library.
/// [TaroUriParseException] is thrown when there is an issue with parsing a URI in the Taro library.
/// It includes the URL that was being parsed and the original FormatException that caused the error.
final class TaroUriParseException extends TaroException {
const TaroUriParseException({
Expand All @@ -66,7 +66,7 @@ final class TaroUriParseException extends TaroException {
}
}

/// `TaroNetworkException` is thrown when there is an issue with network operations in the Taro library.
/// [TaroNetworkException] is thrown when there is an issue with network operations in the Taro library.
/// It includes the URL that was being accessed and the original error that caused the issue.
final class TaroNetworkException extends TaroException {
const TaroNetworkException({
Expand All @@ -83,7 +83,7 @@ final class TaroNetworkException extends TaroException {
}
}

/// `TaroHttpResponseException` is thrown when there is an issue with the HTTP response in the Taro library.
/// [TaroHttpResponseException] is thrown when there is an issue with the HTTP response in the Taro library.
/// It includes the status code, reason phrase, content length, headers, and whether the response is a redirect.
/// This exception is thrown when the status code is not in the range 200-399.
final class TaroHttpResponseException extends TaroException {
Expand All @@ -107,7 +107,7 @@ final class TaroHttpResponseException extends TaroException {
}
}

/// `TaroEmptyResponseException` is thrown when there is an issue with the HTTP response in the Taro library.
/// [TaroEmptyResponseException] is thrown when there is an issue with the HTTP response in the Taro library.
/// It includes the URL that was being accessed.
/// This exception is thrown when the response body is empty.
final class TaroEmptyResponseException extends TaroException {
Expand All @@ -123,7 +123,7 @@ final class TaroEmptyResponseException extends TaroException {
}
}

/// `TaroResizeException` is thrown when there is an issue with resizing an image in the Taro library.
/// [TaroResizeException] is thrown when there is an issue with resizing an image in the Taro library.
/// It includes the original exception that caused the error.
/// This exception is thrown when the status code is not in the range 200-399.
/// Compare this snippet from lib/src/taro_exception.dart:
Expand Down
Loading

0 comments on commit a72b3b3

Please sign in to comment.