Skip to content

Commit

Permalink
feat: Add cancel token for darwin
Browse files Browse the repository at this point in the history
Signed-off-by: Caijinglong <cjl_spy@163.com>
  • Loading branch information
CaiJingLong committed Nov 28, 2024
1 parent f237252 commit 80ff5fb
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 38 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ To know more about breaking changes, see the [Migration Guide][].

*None.*

## 3.6.3
## 3.7.0

### Features

- Add `cancelToken` parameter to `AssetEntity.loadFile`.
- Add `cancelAllRequest` method to `PhotoManager`.
- The `getFile` and `getOriginBytes` methods are public.

### Improvements

Expand Down
19 changes: 19 additions & 0 deletions README-ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,25 @@ iCloud 文件只能在设备上的 Apple ID 正常登录时获取。
当账号要求重新输入密码验证时,未缓存在本地的 iCloud 文件将无法访问,
此时相关方法会抛出 `CloudPhotoLibraryErrorDomain` 错误。

**取消加载** (Since 3.7.0)

上述的 `AssetEntity` 方法均添加了 `cancelToken` 参数,
可以用于取消加载过程。

其他方法如果也添加了 `cancelToken` 参数,同样可以用于取消加载过程。

```dart
final PMCancelToken cancelToken = PMCancelToken();
final File? file = await yourAssetEntity.loadFile(cancelToken: cancelToken);
await cancelToken.cancel();
```

`PhotoManager` 也有一个方法可以取消所有加载:

```dart
await PhotoManager.cancelAllRequest();
```

#### 展示资源

从 v3.0.0 开始,插件不再提供任何 UI 组件。
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,23 @@ When the account requires to re-enter the password to verify, iCloud files that
locally available are not allowed to be fetched. The photo library will throws
`CloudPhotoLibraryErrorDomain` in this circumstance.

**Cancel loading** (Since 3.7.0)

The methods in `AssetEntity` to add `cancelToken` parameter,
which can be used to cancel the loading process.

```dart
final PMCancelToken cancelToken = PMCancelToken();
final File? file = await yourAssetEntity.loadFile(cancelToken: cancelToken);
await cancelToken.cancel();
```

The `PhotoManager` also has a method to cancel all loading:

```dart
await PhotoManager.cancelAllRequest();
```

#### Display assets

> Starts from v3.0.0, `AssetEntityImage` and `AssetEntityImageProvider`
Expand Down
1 change: 1 addition & 0 deletions lib/photo_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export 'src/managers/caching_manager.dart';
export 'src/managers/notify_manager.dart';
export 'src/managers/photo_manager.dart';

export 'src/types/cancel_token.dart';
export 'src/types/entity.dart';
export 'src/types/thumbnail.dart';
export 'src/types/types.dart';
Expand Down
3 changes: 2 additions & 1 deletion lib/src/internal/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class PMConstants {
static const String mGetAssetCount = 'getAssetCount';
static const String mGetAssetsByRange = 'getAssetsByRange';

static const String mCancelRequestWithCancelToken = 'cancelRequestWithCancelToken';
static const String mCancelRequestWithCancelToken =
'cancelRequestWithCancelToken';
static const String mCancelAllRequest = 'cancelAllRequest';

/// Constant value.
Expand Down
26 changes: 1 addition & 25 deletions lib/src/internal/plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:photo_manager/platform_utils.dart';
import '../filter/base_filter.dart';
import '../filter/classical/filter_option_group.dart';
import '../filter/path_filter.dart';
import '../types/cancel_token.dart';
import '../types/entity.dart';
import '../types/thumbnail.dart';
import '../types/types.dart';
Expand All @@ -22,31 +23,6 @@ import 'progress_handler.dart';

PhotoManagerPlugin plugin = PhotoManagerPlugin();

/// The cancel token is used to cancel the request.
class PMCancelToken {
PMCancelToken({this.debugLabel}) : index = getIndex();

static int _index = 0;

static int getIndex() {
final res = _index;
_index++;
return res;
}

final String? debugLabel;
final int index;

/// The key of cancel token, usually to use by [PhotoManagerPlugin.cancelRequest].
/// User don't need to use this.
String get key => _index.toString();

/// Cancel the request.
Future<void> cancelRequest() async {
await plugin.cancelRequest(this);
}
}

mixin BasePlugin {
MethodChannel _channel = const PMMethodChannel(PMConstants.channelPrefix);

Expand Down
9 changes: 9 additions & 0 deletions lib/src/managers/photo_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import '../filter/path_filter.dart';
import '../internal/editor.dart';
import '../internal/enums.dart';
import '../internal/plugin.dart' as base;
import '../internal/plugin.dart';
import '../types/cancel_token.dart';
import '../types/entity.dart';
import '../types/types.dart';
import 'notify_manager.dart';
Expand Down Expand Up @@ -289,4 +291,11 @@ class PhotoManager {
type: type,
);
}

/// Cancel the request with the given [cancelToken].
static Future<void> cancelRequest(PMCancelToken cancelToken) =>
plugin.cancelRequest(cancelToken);

/// Cancel all loading.
static Future<void> cancelAllRequest() => plugin.cancelAllRequest();
}
26 changes: 26 additions & 0 deletions lib/src/types/cancel_token.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import '../internal/plugin.dart';

/// The cancel token is used to cancel the request.
class PMCancelToken {
PMCancelToken({this.debugLabel}) : index = getIndex();

static int _index = 0;

static int getIndex() {
final res = _index;
_index++;
return res;
}

final String? debugLabel;
final int index;

/// The key of cancel token, usually to use by [PhotoManagerPlugin.cancelRequest].
/// User don't need to use this.
String get key => _index.toString();

/// Cancel the request.
Future<void> cancelRequest() async {
await plugin.cancelRequest(this);
}
}
41 changes: 31 additions & 10 deletions lib/src/types/entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import '../internal/enums.dart';
import '../internal/plugin.dart';
import '../internal/progress_handler.dart';
import '../utils/convert_utils.dart';
import 'cancel_token.dart';
import 'thumbnail.dart';
import 'types.dart';

Expand Down Expand Up @@ -528,7 +529,7 @@ class AssetEntity {
/// * [originFile] which can obtain the origin file.
/// * [originFileWithSubtype] which can obtain the origin file with subtype.
/// * [loadFile] which can obtain file with [PMProgressHandler].
Future<File?> get file => _getFile();
Future<File?> get file => getFile();

/// Obtain the compressed file of the asset with subtype.
///
Expand All @@ -539,7 +540,7 @@ class AssetEntity {
/// * [originFile] which can obtain the origin file.
/// * [originFileWithSubtype] which can obtain the origin file with subtype.
/// * [loadFile] which can obtain file with [PMProgressHandler].
Future<File?> get fileWithSubtype => _getFile(subtype: subtype);
Future<File?> get fileWithSubtype => getFile(subtype: subtype);

/// Obtain the original file that contain all EXIF information.
///
Expand All @@ -552,7 +553,7 @@ class AssetEntity {
/// * [fileWithSubtype] which can obtain the compressed file with subtype.
/// * [originFileWithSubtype] which can obtain the origin file with subtype.
/// * [loadFile] which can obtain file with [PMProgressHandler].
Future<File?> get originFile => _getFile(isOrigin: true);
Future<File?> get originFile => getFile(isOrigin: true);

/// Obtain the origin file with subtype.
///
Expand All @@ -563,9 +564,8 @@ class AssetEntity {
/// * [fileWithSubtype] which can obtain the compressed file with subtype.
/// * [originFile] which can obtain the origin file.
/// * [loadFile] which can obtain file with [PMProgressHandler].
Future<File?> get originFileWithSubtype {
return _getFile(isOrigin: true, subtype: subtype);
}
Future<File?> get originFileWithSubtype =>
getFile(isOrigin: true, subtype: subtype);

/// Obtain file of the asset with a [PMProgressHandler].
///
Expand All @@ -579,14 +579,15 @@ class AssetEntity {
/// * [fileWithSubtype] which can obtain the compressed file with subtype.
/// * [originFile] which can obtain the original file.
/// * [originFileWithSubtype] which can obtain the origin file with subtype.
/// * [cancelToken] is used to cancel the file loading process.
Future<File?> loadFile({
bool isOrigin = true,
bool withSubtype = false,
PMProgressHandler? progressHandler,
PMCancelToken? cancelToken,
PMDarwinAVFileType? darwinFileType,
}) {
return _getFile(
return getFile(
isOrigin: isOrigin,
subtype: withSubtype ? subtype : 0,
progressHandler: progressHandler,
Expand All @@ -599,7 +600,7 @@ class AssetEntity {
///
/// **Use it with cautious** since the original data might be epic large.
/// Generally use this method only for images.
Future<typed_data.Uint8List?> get originBytes => _getOriginBytes();
Future<typed_data.Uint8List?> get originBytes => getOriginBytes();

/// Obtain the thumbnail data with [PMConstants.vDefaultThumbnailSize]
/// size of the asset, typically use it for preview displays.
Expand All @@ -622,6 +623,7 @@ class AssetEntity {
/// See also:
/// * [thumbnailData] which obtain the thumbnail data with fixed size.
/// * [thumbnailDataWithOption] which accepts customized [ThumbnailOption].
/// * [cancelToken] is used to cancel the thumbnail loading process.
Future<typed_data.Uint8List?> thumbnailDataWithSize(
ThumbnailSize size, {
ThumbnailFormat format = ThumbnailFormat.jpeg,
Expand Down Expand Up @@ -670,6 +672,7 @@ class AssetEntity {
/// See also:
/// * [thumbnailData] which obtain the thumbnail data with fixed size.
/// * [thumbnailDataWithSize] which is a common method to obtain thumbnails.
/// * [cancelToken] is used to cancel the thumbnail loading process.
Future<typed_data.Uint8List?> thumbnailDataWithOption(
ThumbnailOption option, {
PMProgressHandler? progressHandler,
Expand Down Expand Up @@ -740,6 +743,9 @@ class AssetEntity {
/// * iOS/macOS: File URL. e.g.
/// `file:///var/mobile/Media/DCIM/118APPLE/IMG_8371.MOV`.
///
/// * [progressHandler] is used to handle the progress of the media URL loading process.
/// * [cancelToken] is used to cancel the media URL loading process.
///
/// See also:
/// * https://developer.android.com/reference/android/content/ContentUris
/// * https://developer.apple.com/documentation/avfoundation/avurlasset
Expand All @@ -760,7 +766,15 @@ class AssetEntity {
Platform.isAndroid ||
PlatformUtils.isOhos;

Future<File?> _getFile({
/// Obtain the file of the asset.
///
/// * [isOrigin] is used to obtain the origin file.
/// * [progressHandler] is used to handle the progress of the file loading process.
/// * [subtype] is used to obtain the file with subtype.
/// * [darwinFileType] will try to define the export format when
/// exporting assets, such as exporting a MOV file to MP4.
/// * [cancelToken] is used to cancel the file loading process.
Future<File?> getFile({
bool isOrigin = false,
PMProgressHandler? progressHandler,
int subtype = 0,
Expand Down Expand Up @@ -788,7 +802,14 @@ class AssetEntity {
return File(path);
}

Future<typed_data.Uint8List?> _getOriginBytes({
/// Obtain the raw data of the asset.
///
/// **Use it with cautious** since the original data might be epic large.
/// Generally use this method only for images.
///
/// * [progressHandler] is used to handle the progress of the raw data loading process.
/// * [cancelToken] is used to cancel the raw data loading process.
Future<typed_data.Uint8List?> getOriginBytes({
PMProgressHandler? progressHandler,
PMCancelToken? cancelToken,
}) async {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: photo_manager
description: A Flutter plugin that provides album assets abstraction management APIs on Android, iOS, macOS, and OpenHarmony.
repository: https://github.com/fluttercandies/flutter_photo_manager
version: 3.6.3
version: 3.7.0

environment:
sdk: ">=2.13.0 <4.0.0"
Expand Down

0 comments on commit 80ff5fb

Please sign in to comment.