Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[How to use] Sort result like Camera Roll in iOS #1162

Closed
dodatw opened this issue Jul 16, 2024 · 9 comments
Closed

[How to use] Sort result like Camera Roll in iOS #1162

dodatw opened this issue Jul 16, 2024 · 9 comments

Comments

@dodatw
Copy link

dodatw commented Jul 16, 2024

Platforms

iOS

Description

Is there any way that can get sort result like iOS camera roll (Recent)?

My code

I tried createDate and modifiedDate. but result is not same with Camera roll.

CustomFilter.sql(
        where:
            '${CustomColumns.base.mediaType} = 2',
        orderBy: [
          OrderByItem(CustomColumns.base.createDate, false),
        ],
      )

Can I get sort result like Camera Roll ? it is no issue before photo_manager 3.1.1

@dodatw
Copy link
Author

dodatw commented Jul 17, 2024

This issue is side effct when I want to upgrade photo_manager for 2.x to 3.2.
#1150

Because this behavior change, I need to add orderby for CustomFilter.sql

CustomFilter.sql(
        where:
            '${CustomColumns.base.mediaType} = 2 OR ${CustomColumns.darwin.mediaSubtypes} & 8 = 8',
        orderBy: [
          OrderByItem(CustomColumns.base.createDate, false),
        ],
      )

in photo_manager 2.8. I just use FilterOptionGroup(), the result is what I want. (same with camera roll)

@ycwu0609
Copy link

I face the same issue.

The result is still unexpected after adding the OrderByItem(CustomColumns.base.createDate, false).
(So as OrderByItem(CustomColumns.base.modifiedDate, false))

Process ran to getAssetListPaged would get the results with wrong order.

(NSArray<PMAssetEntity *> *)getAssetListPaged:(NSString *)id type:(int)type page:(NSUInteger)page size:(NSUInteger)size filterOption:(NSObject<PMBaseFilter> *)filterOption {
    NSMutableArray<PMAssetEntity *> *result = [NSMutableArray new];

    PHFetchOptions *options = [PHFetchOptions new];

    PHFetchResult<PHAssetCollection *> *fetchResult =
    [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[id]
                                                         options:options];
    if (fetchResult && fetchResult.count == 0) {
        return result;
    }

    PHAssetCollection *collection = fetchResult.firstObject;
    PHFetchOptions *assetOptions = [self getAssetOptions:type filterOption:filterOption];
    PHFetchResult<PHAsset *> *assetArray = [PHAsset fetchAssetsInAssetCollection:collection
                                                                         options:assetOptions];
    NSLog(@"assetOption: %@", assetOptions);
    NSLog(@"assetArray: %lu", (unsigned long)[collection obtainAssetCount:assetOptions]);

    if (assetArray.count == 0) {
        return result;
    }

    NSUInteger startIndex = page * size;
    NSUInteger endIndex = startIndex + size - 1;

    NSUInteger count = assetArray.count;
    if (endIndex >= count) {
        endIndex = count - 1;
    }

    BOOL imageNeedTitle = filterOption.needTitle;
    BOOL videoNeedTitle = filterOption.needTitle;

    for (NSUInteger i = startIndex; i <= endIndex; i++) {
        NSUInteger index = i;
        if (assetOptions.sortDescriptors == nil) {
            index = count - i - 1;
        }
        PHAsset *asset = assetArray[index];
        BOOL needTitle = NO;
        if ([asset isVideo]) {
            needTitle = videoNeedTitle;
        } else if ([asset isImage]) {
            needTitle = imageNeedTitle;
        }
        PMAssetEntity *entity = [self convertPHAssetToAssetEntity:asset needTitle:needTitle];
        [result addObject:entity];
        [cacheContainer putAssetEntity:entity];
    }

    return result;
}

It seems that getAssetOptions will return different statement.
Maybe the change causes the wrong order.

@CaiJingLong
Copy link
Member

image

Use the none option. (The where is empty and the filter is empty).

To add a log for next patch:
changes.patch
git apply changes.patch

diff --git a/example/lib/page/custom_filter/path_list.dart b/example/lib/page/custom_filter/path_list.dart
index fc08122..8fd621e 100644
--- a/example/lib/page/custom_filter/path_list.dart
+++ b/example/lib/page/custom_filter/path_list.dart
@@ -59,6 +59,9 @@ class PathList extends StatelessWidget {
                 position: ToastPosition.bottom,
               );
             });
+            for (final asset in path.filterOption.toMap().entries) {
+              print('${asset.key}: ${asset.value}');
+            }
             Navigator.push(
               context,
               MaterialPageRoute(

I get next log:

{where: , orderBy: [], needTitle: false, containsPathModified: false}


I use the example of the library:

Kapture.2024-07-30.at.10.52.13.mp4

@dodatw
Copy link
Author

dodatw commented Jul 30, 2024

@CaiJingLong thanks your reply.
The problem is, aftrer photo_manager 3.2, it I want "Video + livePhoto"
I need to use where to filter content. (#1150).

Is there anyway support this case?
"Video + Live Photo", order is same with cameraRoll, (order is descend).

I can get this kind result in photo_manager 3.1, but not in 3.2.
(My current solution is rollback to 3.1)

Thanks.

@dodatw
Copy link
Author

dodatw commented Aug 7, 2024

@CaiJingLong is it possiable ?
I'm currently using photo_manager 3.1. I'm worried that one day I'll need to upgrade to flutter 3.2+, but I can't get the results I need. XD

@dodatw dodatw changed the title [How to use] Sort resultike Camera Roll in iOS [How to use] Sort result like Camera Roll in iOS Aug 28, 2024
@ycwu0609
Copy link

I've tried Photo Manager 3.4.0, but I've noticed that photos and videos received through AirDrop appear in a different order compared to the Camera Roll.
In the Camera Roll, newly received AirDrop media appears at the top. However, in the search results of Photo Manager 3.4.0, the media is sorted by creation time.

@dodatw
Copy link
Author

dodatw commented Sep 24, 2024

@CaiJingLong
I want a video picker that include all video + livePhoto, and sort like "Recent in Camera Roll",
Finally I found a combination that met my requirements

  1. set request tyoe to RequestType.common (include all videos and photos)
  2. set filteroption to FilterOptionGroup(onlyLivePhotos: true); (filter non-live photo)

The result is what I want.

But, it have assert here

'Filtering only Live Photos is only supported '

      assert(
        type == RequestType.image || !filterOption.onlyLivePhotos,
        'Filtering only Live Photos is only supported '
        'when the request type contains image.',
      );

Is it possiable change code to

      assert(
        type.containsImage() || !filterOption.onlyLivePhotos,
        'Filtering only Live Photos is only supported '
        'when the request type contains image.',
      );

@AlexV525
Copy link
Member

The assertion has been removed in v3.5.0.

In my opinion, the filter options group applies more conditions to the query. Simply set breakpoints in the native debugging can easily find out the core condition to produce the natural album order.

@AlexV525
Copy link
Member

Having some time playing iOS Gallery. Here is the conclusion:

  1. The "Library" (All Photos Library) uses the creation date in descending order.
  2. The "Recents" album uses the modified data in descending order.

In iOS 18, these two entries are combined and the sort options are provided.

So choose the fitting order according to your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants