Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ To know more about breaking changes, see the [Migration Guide][].

### Features

- Add `AssetPathEntity.getParentPathList()` method for iOS/macOS to retrieve parent folders for user-created albums.
This enables navigation up the folder hierarchy, allowing users to browse nested album structures.
- Add `cancelToken` parameter to `AssetEntity.loadFile`.
- Add `cancelAllRequest` method to `PhotoManager`.
- The `AssetEntity.getFile` and `AssetEntity.getOriginBytes` methods are public.
Expand Down
11 changes: 11 additions & 0 deletions darwin/photo_manager/Sources/photo_manager/PMPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,17 @@ - (void)handleMethodResultHandler:(PMResultHandler *)handler manager:(PMManager
NSArray<PMAssetPathEntity *> *array = [manager getSubPathWithId:galleryId type:type albumType:albumType option:option];
NSDictionary *pathData = [PMConvertUtils convertPathToMap:array];

[handler reply:@{@"list": pathData}];
} else if ([@"getParentPath" isEqualToString:call.method]) {
NSString *galleryId = call.arguments[@"id"];
int type = [call.arguments[@"type"] intValue];
int albumType = [call.arguments[@"albumType"] intValue];
NSDictionary *optionMap = call.arguments[@"option"];
NSObject <PMBaseFilter> *option = [PMConvertUtils convertMapToOptionContainer:optionMap];

NSArray<PMAssetPathEntity *> *array = [manager getParentPathWithId:galleryId type:type albumType:albumType option:option];
NSDictionary *pathData = [PMConvertUtils convertPathToMap:array];

[handler reply:@{@"list": pathData}];
} else if ([@"copyAsset" isEqualToString:call.method]) {
NSString *assetId = call.arguments[@"assetId"];
Expand Down
2 changes: 2 additions & 0 deletions darwin/photo_manager/Sources/photo_manager/core/PMManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ typedef void (^AssetBlockResult)(PMAssetEntity *, NSObject *);

- (NSArray<PMAssetPathEntity *> *)getSubPathWithId:(NSString *)id type:(int)type albumType:(int)albumType option:(NSObject<PMBaseFilter> *)option;

- (NSArray<PMAssetPathEntity *> *)getParentPathWithId:(NSString *)id type:(int)type albumType:(int)albumType option:(NSObject<PMBaseFilter> *)option;

- (void)copyAssetWithId:(NSString *)id toGallery:(NSString *)gallery block:(AssetBlockResult)block;

- (void)createFolderWithName:(NSString *)name parentId:(NSString *)id block:(void (^)(NSString *newId, NSObject *error))block;
Expand Down
39 changes: 39 additions & 0 deletions darwin/photo_manager/Sources/photo_manager/core/PMManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -1593,6 +1593,45 @@ - (void)getMediaUrl:(NSString *)assetId
return [self convertPHCollectionToPMAssetPathArray:phCollectionArray option:options];
}

- (NSArray<PMAssetPathEntity *> *)getParentPathWithId:(NSString *)id type:(int)type albumType:(int)albumType option:(NSObject<PMBaseFilter> *)option {
PHFetchOptions *options = [self getAssetOptions:type filterOption:option];

// Recent/All Photos collection has no parent folders
if ([PMFolderUtils isRecentCollection:id]) {
return @[];
}

PHCollection *collection = nil;

// Try to fetch as an album (PHAssetCollection) first
PHFetchResult<PHAssetCollection *> *assetCollectionResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[id] options:nil];
if (assetCollectionResult && assetCollectionResult.count > 0) {
collection = assetCollectionResult.firstObject;
}

// If not found as an album, try to fetch as a folder (PHCollectionList)
if (!collection) {
PHFetchResult<PHCollectionList *> *collectionListResult = [PHCollectionList fetchCollectionListsWithLocalIdentifiers:@[id] options:nil];
if (collectionListResult && collectionListResult.count > 0) {
collection = collectionListResult.firstObject;
}
}

if (!collection) {
return @[];
}

// Fetch parent collection lists containing this collection
PHFetchResult<PHCollectionList *> *parentCollectionLists = [PHCollectionList fetchCollectionListsContainingCollection:collection options:nil];

NSMutableArray<PHCollection *> *parentArray = [NSMutableArray new];
for (PHCollectionList *parentList in parentCollectionLists) {
[parentArray addObject:parentList];
}

return [self convertPHCollectionToPMAssetPathArray:parentArray option:options];
}

- (NSArray<PMAssetPathEntity *> *)convertPHCollectionToPMAssetPathArray:(NSArray<PHCollection *> *)phArray
option:(PHFetchOptions *)option {
NSMutableArray<PMAssetPathEntity *> *result = [NSMutableArray new];
Expand Down
1 change: 1 addition & 0 deletions lib/src/internal/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PMConstants {
static const String mGetMimeTypeAsync = 'getMimeTypeAsync';
static const String mGetMediaUrl = 'getMediaUrl';
static const String mGetSubPath = 'getSubPath';
static const String mGetParentPath = 'getParentPath';
static const String mCopyAsset = 'copyAsset';
static const String mDeleteAlbum = 'deleteAlbum';
static const String mFavoriteAsset = 'favoriteAsset';
Expand Down
23 changes: 23 additions & 0 deletions lib/src/internal/plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,29 @@ class PhotoManagerPlugin with BasePlugin, IosPlugin, AndroidPlugin, OhosPlugin {
);
}

Future<List<AssetPathEntity>> getParentPathEntities(
AssetPathEntity pathEntity,
) async {
if (PlatformUtils.isOhos) {
return <AssetPathEntity>[];
}
final Map result = await _channel.invokeMethod(
PMConstants.mGetParentPath,
<String, dynamic>{
'id': pathEntity.id,
'type': pathEntity.type.value,
'albumType': pathEntity.albumType,
'option': pathEntity.filterOption?.toMap(),
},
);
final items = result['list'] as Map;
return ConvertUtils.convertToPathList(
items.cast(),
type: pathEntity.type,
filterOption: pathEntity.filterOption,
);
}

Future<AssetEntity> copyAssetToGallery(
AssetEntity asset,
AssetPathEntity pathEntity,
Expand Down
15 changes: 15 additions & 0 deletions lib/src/types/entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@ class AssetPathEntity {
return <AssetPathEntity>[];
}

/// Request parent folders for the album.
///
/// This method returns a list of parent folders (PHCollectionList) that
/// contain the current album or folder. It allows navigation up the
/// folder hierarchy for user-created albums and folders.
///
/// An empty list will always be returned on Android.
/// An empty list will be returned for system albums like "Recent" or "All Photos".
Future<List<AssetPathEntity>> getParentPathList() async {
if (Platform.isIOS || Platform.isMacOS) {
return plugin.getParentPathEntities(this);
}
return <AssetPathEntity>[];
}

/// Obtain a new [AssetPathEntity] from the current one
/// with refreshed properties.
Future<AssetPathEntity?> fetchPathProperties({
Expand Down
Loading