*Break changes:
• move "newest" parameter from "listMedia" to "listAlbums" API • move "newest" property from "MediaPage" to "Media" • add "newest" parameter of getAlbumThumbnail API • update album parameter of AlbumThumbnailProvider
This commit is contained in:
parent
7898c4bde3
commit
88e0ad714b
@ -138,12 +138,13 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
"getAlbumThumbnail" -> {
|
"getAlbumThumbnail" -> {
|
||||||
val albumId = call.argument<String>("albumId")
|
val albumId = call.argument<String>("albumId")
|
||||||
val mediumType = call.argument<String>("mediumType")
|
val mediumType = call.argument<String>("mediumType")
|
||||||
|
val newest = call.argument<Boolean>("newest")
|
||||||
val width = call.argument<Int>("width")
|
val width = call.argument<Int>("width")
|
||||||
val height = call.argument<Int>("height")
|
val height = call.argument<Int>("height")
|
||||||
val highQuality = call.argument<Boolean>("highQuality")
|
val highQuality = call.argument<Boolean>("highQuality")
|
||||||
executor.submit {
|
executor.submit {
|
||||||
result.success(
|
result.success(
|
||||||
getAlbumThumbnail(albumId!!, mediumType, width, height, highQuality)
|
getAlbumThumbnail(albumId!!, mediumType, newest!!, width, height, highQuality)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,7 +212,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
val folderName = cursor.getString(bucketColumn)
|
val folderName = cursor.getString(bucketColumn)
|
||||||
albumHashMap[bucketId] = hashMapOf(
|
albumHashMap[bucketId] = hashMapOf(
|
||||||
"id" to bucketId,
|
"id" to bucketId,
|
||||||
"mediumType" to imageType,
|
|
||||||
"name" to folderName,
|
"name" to folderName,
|
||||||
"count" to 1
|
"count" to 1
|
||||||
)
|
)
|
||||||
@ -228,7 +228,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
allAlbumId,
|
allAlbumId,
|
||||||
hashMapOf(
|
hashMapOf(
|
||||||
"id" to allAlbumId,
|
"id" to allAlbumId,
|
||||||
"mediumType" to imageType,
|
|
||||||
"name" to allAlbumName,
|
"name" to allAlbumName,
|
||||||
"count" to total
|
"count" to total
|
||||||
)
|
)
|
||||||
@ -267,7 +266,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
val folderName = cursor.getString(bucketColumn)
|
val folderName = cursor.getString(bucketColumn)
|
||||||
albumHashMap[bucketId] = hashMapOf(
|
albumHashMap[bucketId] = hashMapOf(
|
||||||
"id" to bucketId,
|
"id" to bucketId,
|
||||||
"mediumType" to videoType,
|
|
||||||
"name" to folderName,
|
"name" to folderName,
|
||||||
"count" to 1
|
"count" to 1
|
||||||
)
|
)
|
||||||
@ -284,7 +282,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
allAlbumId,
|
allAlbumId,
|
||||||
hashMapOf(
|
hashMapOf(
|
||||||
"id" to allAlbumId,
|
"id" to allAlbumId,
|
||||||
"mediumType" to videoType,
|
|
||||||
"name" to allAlbumName,
|
"name" to allAlbumName,
|
||||||
"count" to total
|
"count" to total
|
||||||
)
|
)
|
||||||
@ -300,7 +297,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
val albumMap = (imageMap.keys + videoMap.keys).associateWith {
|
val albumMap = (imageMap.keys + videoMap.keys).associateWith {
|
||||||
mapOf(
|
mapOf(
|
||||||
"id" to it,
|
"id" to it,
|
||||||
"mediumType" to null,
|
|
||||||
"name" to imageMap[it]?.get("name"),
|
"name" to imageMap[it]?.get("name"),
|
||||||
"count" to (imageMap[it]?.get("count") ?: 0) as Int + (videoMap[it]?.get("count") ?: 0) as Int,
|
"count" to (imageMap[it]?.get("count") ?: 0) as Int + (videoMap[it]?.get("count") ?: 0) as Int,
|
||||||
)
|
)
|
||||||
@ -330,7 +326,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
items = items.subList(start, end)
|
items = items.subList(start, end)
|
||||||
}
|
}
|
||||||
mapOf(
|
mapOf(
|
||||||
"newest" to newest,
|
|
||||||
"start" to (skip ?: 0),
|
"start" to (skip ?: 0),
|
||||||
"items" to items
|
"items" to items
|
||||||
)
|
)
|
||||||
@ -390,7 +385,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return mapOf(
|
return mapOf(
|
||||||
"newest" to newest,
|
|
||||||
"start" to skip,
|
"start" to skip,
|
||||||
"items" to media
|
"items" to media
|
||||||
)
|
)
|
||||||
@ -448,7 +442,6 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return mapOf(
|
return mapOf(
|
||||||
"newest" to newest,
|
|
||||||
"start" to skip,
|
"start" to skip,
|
||||||
"items" to media
|
"items" to media
|
||||||
)
|
)
|
||||||
@ -596,55 +589,25 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
return byteArray
|
return byteArray
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlbumThumbnail(albumId: String, mediumType: String?, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
private fun getAlbumThumbnail(albumId: String, mediumType: String?, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
||||||
return when (mediumType) {
|
return when (mediumType) {
|
||||||
imageType -> {
|
imageType -> {
|
||||||
getImageAlbumThumbnail(albumId, width, height, highQuality)
|
getImageAlbumThumbnail(albumId, newest, width, height, highQuality)
|
||||||
}
|
}
|
||||||
videoType -> {
|
videoType -> {
|
||||||
getVideoAlbumThumbnail(albumId, width, height, highQuality)
|
getVideoAlbumThumbnail(albumId, newest, width, height, highQuality)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
getImageAlbumThumbnail(albumId, width, height, highQuality)
|
getAllAlbumThumbnail(albumId, newest, width, height, highQuality)
|
||||||
?: getVideoAlbumThumbnail(albumId, width, height, highQuality)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getImageAlbumThumbnail(albumId: String, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
private fun getImageAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
||||||
return this.context.run {
|
return this.context.run {
|
||||||
val isSelection = albumId != allAlbumId
|
val projection = arrayOf(MediaStore.Images.Media._ID)
|
||||||
val selection = if (isSelection) "${MediaStore.Images.Media.BUCKET_ID} = ?" else null
|
|
||||||
val selectionArgs = if (isSelection) arrayOf(albumId) else null
|
|
||||||
val orderBy =
|
|
||||||
"${MediaStore.Images.Media.DATE_ADDED} DESC, ${MediaStore.Images.Media.DATE_MODIFIED} DESC"
|
|
||||||
|
|
||||||
val imageCursor: Cursor?
|
val imageCursor = getImageCursor(albumId, newest, projection)
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
|
||||||
imageCursor = this.contentResolver.query(
|
|
||||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
arrayOf(MediaStore.Images.Media._ID),
|
|
||||||
android.os.Bundle().apply {
|
|
||||||
// Selection
|
|
||||||
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
|
||||||
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
|
|
||||||
// Sort
|
|
||||||
putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, orderBy)
|
|
||||||
// Limit
|
|
||||||
putInt(ContentResolver.QUERY_ARG_LIMIT, 1)
|
|
||||||
},
|
|
||||||
null
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
imageCursor = this.contentResolver.query(
|
|
||||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
arrayOf(MediaStore.Images.Media._ID),
|
|
||||||
selection,
|
|
||||||
selectionArgs,
|
|
||||||
"$orderBy LIMIT 1"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
imageCursor?.use { cursor ->
|
imageCursor?.use { cursor ->
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
@ -658,20 +621,160 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getVideoAlbumThumbnail(albumId: String, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
private fun getVideoAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
||||||
return this.context.run {
|
return this.context.run {
|
||||||
|
val projection = arrayOf(MediaStore.Video.Media._ID)
|
||||||
|
|
||||||
|
val videoCursor = getVideoCursor(albumId, newest, projection)
|
||||||
|
|
||||||
|
videoCursor?.use { cursor ->
|
||||||
|
if (cursor.moveToNext()) {
|
||||||
|
val idColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID)
|
||||||
|
val id = cursor.getLong(idColumn)
|
||||||
|
return@run getVideoThumbnail(id.toString(), width, height, highQuality)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAllAlbumThumbnail(albumId: String, newest: Boolean, width: Int?, height: Int?, highQuality: Boolean?): ByteArray? {
|
||||||
|
return this.context.run {
|
||||||
|
val imageProjection = arrayOf(
|
||||||
|
MediaStore.Images.Media._ID,
|
||||||
|
MediaStore.Images.Media.DATE_ADDED,
|
||||||
|
MediaStore.Images.Media.DATE_MODIFIED,
|
||||||
|
)
|
||||||
|
|
||||||
|
val imageCursor = getImageCursor(albumId, newest, imageProjection)
|
||||||
|
|
||||||
|
var imageId: Long? = null
|
||||||
|
var imageDateAdded: Long? = null
|
||||||
|
var imageDateModified: Long? = null
|
||||||
|
imageCursor?.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
val idColumn = cursor.getColumnIndex(MediaStore.Images.Media._ID)
|
||||||
|
val dateAddedColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED)
|
||||||
|
val dateModifiedColumn =
|
||||||
|
cursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED)
|
||||||
|
imageId = cursor.getLong(idColumn)
|
||||||
|
imageDateAdded = cursor.getLong(dateAddedColumn) * 1000
|
||||||
|
imageDateModified = cursor.getLong(dateModifiedColumn) * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val videoProjection = arrayOf(
|
||||||
|
MediaStore.Video.Media._ID,
|
||||||
|
MediaStore.Video.Media.DATE_ADDED,
|
||||||
|
MediaStore.Video.Media.DATE_MODIFIED,
|
||||||
|
)
|
||||||
|
|
||||||
|
val videoCursor = getVideoCursor(albumId, newest, videoProjection)
|
||||||
|
|
||||||
|
var videoId: Long? = null
|
||||||
|
var videoDateAdded: Long? = null
|
||||||
|
var videoDateModified: Long? = null
|
||||||
|
videoCursor?.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
val idColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID)
|
||||||
|
val dateAddedColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED)
|
||||||
|
val dateModifiedColumn =
|
||||||
|
cursor.getColumnIndex(MediaStore.Video.Media.DATE_MODIFIED)
|
||||||
|
videoId = cursor.getLong(idColumn)
|
||||||
|
videoDateAdded = cursor.getLong(dateAddedColumn) * 1000
|
||||||
|
videoDateModified = cursor.getLong(dateModifiedColumn) * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageId != null && videoId != null) {
|
||||||
|
if (imageDateAdded != null && videoDateAdded != null) {
|
||||||
|
if (newest && imageDateAdded!! < videoDateAdded!! || !newest && imageDateAdded!! > videoDateAdded!!) {
|
||||||
|
return@run getVideoThumbnail(videoId.toString(), width, height, highQuality)
|
||||||
|
} else {
|
||||||
|
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imageDateModified != null && videoDateModified != null) {
|
||||||
|
if (newest && imageDateModified!! < videoDateModified!! || !newest && imageDateModified!! > videoDateModified!!) {
|
||||||
|
return@run getVideoThumbnail(videoId.toString(), width, height, highQuality)
|
||||||
|
} else {
|
||||||
|
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageId != null) {
|
||||||
|
return@run getImageThumbnail(imageId.toString(), width, height, highQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (videoId != null) {
|
||||||
|
return@run getVideoThumbnail(videoId.toString(), width, height, highQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
return@run null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImageCursor(albumId: String, newest: Boolean, projection: Array<String>): Cursor? {
|
||||||
|
this.context.run {
|
||||||
|
val isSelection = albumId != allAlbumId
|
||||||
|
val selection = if (isSelection) "${MediaStore.Images.Media.BUCKET_ID} = ?" else null
|
||||||
|
val selectionArgs = if (isSelection) arrayOf(albumId) else null
|
||||||
|
val orderBy = if (newest) {
|
||||||
|
"${MediaStore.Images.Media.DATE_ADDED} DESC, ${MediaStore.Images.Media.DATE_MODIFIED} DESC"
|
||||||
|
} else {
|
||||||
|
"${MediaStore.Images.Media.DATE_ADDED} ASC, ${MediaStore.Images.Media.DATE_MODIFIED} ASC"
|
||||||
|
}
|
||||||
|
|
||||||
|
val imageCursor: Cursor?
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
||||||
|
imageCursor = this.contentResolver.query(
|
||||||
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
projection,
|
||||||
|
android.os.Bundle().apply {
|
||||||
|
// Selection
|
||||||
|
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
||||||
|
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
|
||||||
|
// Sort
|
||||||
|
putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, orderBy)
|
||||||
|
// Limit
|
||||||
|
putInt(ContentResolver.QUERY_ARG_LIMIT, 1)
|
||||||
|
},
|
||||||
|
null
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
imageCursor = this.contentResolver.query(
|
||||||
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
projection,
|
||||||
|
selection,
|
||||||
|
selectionArgs,
|
||||||
|
"$orderBy LIMIT 1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageCursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVideoCursor(albumId: String, newest: Boolean, projection: Array<String>): Cursor? {
|
||||||
|
this.context.run {
|
||||||
val isSelection = albumId != allAlbumId
|
val isSelection = albumId != allAlbumId
|
||||||
val selection = if (isSelection) "${MediaStore.Video.Media.BUCKET_ID} = ?" else null
|
val selection = if (isSelection) "${MediaStore.Video.Media.BUCKET_ID} = ?" else null
|
||||||
val selectionArgs = if (isSelection) arrayOf(albumId) else null
|
val selectionArgs = if (isSelection) arrayOf(albumId) else null
|
||||||
val orderBy =
|
val orderBy = if (newest) {
|
||||||
"${MediaStore.Video.Media.DATE_ADDED} DESC, ${MediaStore.Video.Media.DATE_MODIFIED} DESC"
|
"${MediaStore.Video.Media.DATE_ADDED} DESC, ${MediaStore.Video.Media.DATE_MODIFIED} DESC"
|
||||||
|
} else {
|
||||||
|
"${MediaStore.Video.Media.DATE_ADDED} ASC, ${MediaStore.Video.Media.DATE_MODIFIED} ASC"
|
||||||
|
}
|
||||||
|
|
||||||
val videoCursor: Cursor?
|
val videoCursor: Cursor?
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
|
||||||
videoCursor = this.contentResolver.query(
|
videoCursor = this.contentResolver.query(
|
||||||
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||||
arrayOf(MediaStore.Video.Media._ID),
|
projection,
|
||||||
android.os.Bundle().apply {
|
android.os.Bundle().apply {
|
||||||
// Selection
|
// Selection
|
||||||
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
||||||
@ -686,22 +789,14 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
|
|||||||
} else {
|
} else {
|
||||||
videoCursor = this.contentResolver.query(
|
videoCursor = this.contentResolver.query(
|
||||||
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||||
arrayOf(MediaStore.Video.Media._ID),
|
projection,
|
||||||
selection,
|
selection,
|
||||||
selectionArgs,
|
selectionArgs,
|
||||||
"$orderBy LIMIT 1"
|
"$orderBy LIMIT 1"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
videoCursor?.use { cursor ->
|
return videoCursor
|
||||||
if (cursor.moveToNext()) {
|
|
||||||
val idColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID)
|
|
||||||
val id = cursor.getLong(idColumn)
|
|
||||||
return@run getVideoThumbnail(id.toString(), width, height, highQuality)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
placeholder:
|
placeholder:
|
||||||
MemoryImage(kTransparentImage),
|
MemoryImage(kTransparentImage),
|
||||||
image: AlbumThumbnailProvider(
|
image: AlbumThumbnailProvider(
|
||||||
albumId: album.id,
|
album: album,
|
||||||
mediumType: album.mediumType,
|
|
||||||
highQuality: true,
|
highQuality: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -55,12 +55,14 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
let arguments = call.arguments as! Dictionary<String, AnyObject>
|
let arguments = call.arguments as! Dictionary<String, AnyObject>
|
||||||
let albumId = arguments["albumId"] as! String
|
let albumId = arguments["albumId"] as! String
|
||||||
let mediumType = arguments["mediumType"] as? String
|
let mediumType = arguments["mediumType"] as? String
|
||||||
|
let newest = arguments["newest"] as! Bool
|
||||||
let width = arguments["width"] as? Int
|
let width = arguments["width"] as? Int
|
||||||
let height = arguments["height"] as? Int
|
let height = arguments["height"] as? Int
|
||||||
let highQuality = arguments["highQuality"] as? Bool
|
let highQuality = arguments["highQuality"] as? Bool
|
||||||
getAlbumThumbnail(
|
getAlbumThumbnail(
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
mediumType: mediumType,
|
mediumType: mediumType,
|
||||||
|
newest: newest,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
highQuality: highQuality,
|
highQuality: highQuality,
|
||||||
@ -113,7 +115,6 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
self.assetCollections.append(collection)
|
self.assetCollections.append(collection)
|
||||||
albums.append([
|
albums.append([
|
||||||
"id": collection.localIdentifier,
|
"id": collection.localIdentifier,
|
||||||
"mediumType": mediumType,
|
|
||||||
"name": collection.localizedTitle ?? "Unknown",
|
"name": collection.localizedTitle ?? "Unknown",
|
||||||
"count": count,
|
"count": count,
|
||||||
])
|
])
|
||||||
@ -150,7 +151,6 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
albums.insert([
|
albums.insert([
|
||||||
"id": "__ALL__",
|
"id": "__ALL__",
|
||||||
"mediumType": mediumType,
|
|
||||||
"name": "All",
|
"name": "All",
|
||||||
"count" : countMedia(collection: nil, mediumType: mediumType),
|
"count" : countMedia(collection: nil, mediumType: mediumType),
|
||||||
], at: 0)
|
], at: 0)
|
||||||
@ -193,7 +193,6 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"newest": newest,
|
|
||||||
"start": start,
|
"start": start,
|
||||||
"items": items,
|
"items": items,
|
||||||
]
|
]
|
||||||
@ -265,6 +264,7 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
private func getAlbumThumbnail(
|
private func getAlbumThumbnail(
|
||||||
albumId: String,
|
albumId: String,
|
||||||
mediumType: String?,
|
mediumType: String?,
|
||||||
|
newest: Bool,
|
||||||
width: Int?,
|
width: Int?,
|
||||||
height: Int?,
|
height: Int?,
|
||||||
highQuality: Bool?,
|
highQuality: Bool?,
|
||||||
@ -274,8 +274,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
|
|||||||
let fetchOptions = PHFetchOptions()
|
let fetchOptions = PHFetchOptions()
|
||||||
fetchOptions.predicate = self.predicateFromMediumType(mediumType: mediumType)
|
fetchOptions.predicate = self.predicateFromMediumType(mediumType: mediumType)
|
||||||
fetchOptions.sortDescriptors = [
|
fetchOptions.sortDescriptors = [
|
||||||
NSSortDescriptor(key: "creationDate", ascending: false),
|
NSSortDescriptor(key: "creationDate", ascending: !newest),
|
||||||
NSSortDescriptor(key: "modificationDate", ascending: false)
|
NSSortDescriptor(key: "modificationDate", ascending: !newest)
|
||||||
]
|
]
|
||||||
if #available(iOS 9, *) {
|
if #available(iOS 9, *) {
|
||||||
fetchOptions.fetchLimit = 1
|
fetchOptions.fetchLimit = 1
|
||||||
|
@ -23,26 +23,27 @@ class PhotoGallery {
|
|||||||
/// List all available gallery albums and counts number of items of [MediumType].
|
/// List all available gallery albums and counts number of items of [MediumType].
|
||||||
static Future<List<Album>> listAlbums({
|
static Future<List<Album>> listAlbums({
|
||||||
MediumType? mediumType,
|
MediumType? mediumType,
|
||||||
bool? hideIfEmpty = true,
|
bool newest = true,
|
||||||
|
bool hideIfEmpty = true,
|
||||||
}) async {
|
}) async {
|
||||||
final json = await _channel.invokeMethod('listAlbums', {
|
final json = await _channel.invokeMethod('listAlbums', {
|
||||||
'mediumType': mediumTypeToJson(mediumType),
|
'mediumType': mediumTypeToJson(mediumType),
|
||||||
|
'newest': newest,
|
||||||
'hideIfEmpty': hideIfEmpty,
|
'hideIfEmpty': hideIfEmpty,
|
||||||
});
|
});
|
||||||
return json.map<Album>((x) => Album.fromJson(x)).toList();
|
return json.map<Album>((album) => Album.fromJson(album, mediumType, newest)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all available media in a specific album, support pagination of media
|
/// List all available media in a specific album, support pagination of media
|
||||||
static Future<MediaPage> _listMedia({
|
static Future<MediaPage> _listMedia({
|
||||||
required Album album,
|
required Album album,
|
||||||
bool newest = true,
|
|
||||||
int? skip,
|
int? skip,
|
||||||
int? take,
|
int? take,
|
||||||
}) async {
|
}) async {
|
||||||
final json = await _channel.invokeMethod('listMedia', {
|
final json = await _channel.invokeMethod('listMedia', {
|
||||||
'albumId': album.id,
|
'albumId': album.id,
|
||||||
'mediumType': mediumTypeToJson(album.mediumType),
|
'mediumType': mediumTypeToJson(album.mediumType),
|
||||||
'newest': newest,
|
'newest': album.newest,
|
||||||
'skip': skip,
|
'skip': skip,
|
||||||
'take': take,
|
'take': take,
|
||||||
});
|
});
|
||||||
@ -84,6 +85,7 @@ class PhotoGallery {
|
|||||||
static Future<List<int>?> getAlbumThumbnail({
|
static Future<List<int>?> getAlbumThumbnail({
|
||||||
required String albumId,
|
required String albumId,
|
||||||
MediumType? mediumType,
|
MediumType? mediumType,
|
||||||
|
bool newest = true,
|
||||||
int? width,
|
int? width,
|
||||||
int? height,
|
int? height,
|
||||||
bool? highQuality = false,
|
bool? highQuality = false,
|
||||||
@ -91,6 +93,7 @@ class PhotoGallery {
|
|||||||
final bytes = await _channel.invokeMethod('getAlbumThumbnail', {
|
final bytes = await _channel.invokeMethod('getAlbumThumbnail', {
|
||||||
'albumId': albumId,
|
'albumId': albumId,
|
||||||
'mediumType': mediumTypeToJson(mediumType),
|
'mediumType': mediumTypeToJson(mediumType),
|
||||||
|
'newest': newest,
|
||||||
'width': width,
|
'width': width,
|
||||||
'height': height,
|
'height': height,
|
||||||
'highQuality': highQuality,
|
'highQuality': highQuality,
|
||||||
|
@ -3,15 +3,13 @@ part of photogallery;
|
|||||||
/// Fetches the given album thumbnail from the gallery.
|
/// Fetches the given album thumbnail from the gallery.
|
||||||
class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
|
class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
|
||||||
const AlbumThumbnailProvider({
|
const AlbumThumbnailProvider({
|
||||||
required this.albumId,
|
required this.album,
|
||||||
this.mediumType,
|
|
||||||
this.height,
|
this.height,
|
||||||
this.width,
|
this.width,
|
||||||
this.highQuality = false,
|
this.highQuality = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String albumId;
|
final Album album;
|
||||||
final MediumType? mediumType;
|
|
||||||
final int? height;
|
final int? height;
|
||||||
final int? width;
|
final int? width;
|
||||||
final bool? highQuality;
|
final bool? highQuality;
|
||||||
@ -22,7 +20,7 @@ class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
|
|||||||
codec: _loadAsync(key, decode),
|
codec: _loadAsync(key, decode),
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
informationCollector: () sync* {
|
informationCollector: () sync* {
|
||||||
yield ErrorDescription('Id: $albumId');
|
yield ErrorDescription('Id: ${album.id}');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -30,8 +28,9 @@ class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
|
|||||||
Future<ui.Codec> _loadAsync(AlbumThumbnailProvider key, DecoderBufferCallback decode) async {
|
Future<ui.Codec> _loadAsync(AlbumThumbnailProvider key, DecoderBufferCallback decode) async {
|
||||||
assert(key == this);
|
assert(key == this);
|
||||||
final data = await PhotoGallery.getAlbumThumbnail(
|
final data = await PhotoGallery.getAlbumThumbnail(
|
||||||
albumId: albumId,
|
albumId: album.id,
|
||||||
mediumType: mediumType,
|
mediumType: album.mediumType,
|
||||||
|
newest: album.newest,
|
||||||
height: height,
|
height: height,
|
||||||
width: width,
|
width: width,
|
||||||
highQuality: highQuality,
|
highQuality: highQuality,
|
||||||
@ -54,12 +53,12 @@ class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
|
|||||||
bool operator ==(dynamic other) {
|
bool operator ==(dynamic other) {
|
||||||
if (other.runtimeType != runtimeType) return false;
|
if (other.runtimeType != runtimeType) return false;
|
||||||
final AlbumThumbnailProvider typedOther = other;
|
final AlbumThumbnailProvider typedOther = other;
|
||||||
return albumId == typedOther.albumId;
|
return album.id == typedOther.album.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => albumId.hashCode;
|
int get hashCode => album.id.hashCode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$runtimeType("$albumId")';
|
String toString() => '$runtimeType("${album.id}")';
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ class Album {
|
|||||||
/// The [MediumType] of the album.
|
/// The [MediumType] of the album.
|
||||||
final MediumType? mediumType;
|
final MediumType? mediumType;
|
||||||
|
|
||||||
|
/// The sort direction is newest or not
|
||||||
|
final bool newest;
|
||||||
|
|
||||||
/// The name of the album.
|
/// The name of the album.
|
||||||
final String? name;
|
final String? name;
|
||||||
|
|
||||||
@ -19,9 +22,10 @@ class Album {
|
|||||||
bool get isAllAlbum => id == "__ALL__";
|
bool get isAllAlbum => id == "__ALL__";
|
||||||
|
|
||||||
/// Creates a album from platform channel protocol.
|
/// Creates a album from platform channel protocol.
|
||||||
Album.fromJson(dynamic json)
|
Album.fromJson(dynamic json, MediumType? mediumType, bool newest)
|
||||||
: id = json['id'],
|
: id = json['id'],
|
||||||
mediumType = jsonToMediumType(json['mediumType']),
|
mediumType = mediumType,
|
||||||
|
newest = newest,
|
||||||
name = json['name'],
|
name = json['name'],
|
||||||
count = json['count'];
|
count = json['count'];
|
||||||
|
|
||||||
@ -30,13 +34,11 @@ class Album {
|
|||||||
/// Pagination can be controlled out of [skip] (defaults to `0`) and
|
/// Pagination can be controlled out of [skip] (defaults to `0`) and
|
||||||
/// [take] (defaults to `<total>`).
|
/// [take] (defaults to `<total>`).
|
||||||
Future<MediaPage> listMedia({
|
Future<MediaPage> listMedia({
|
||||||
bool newest = true,
|
|
||||||
int? skip,
|
int? skip,
|
||||||
int? take,
|
int? take,
|
||||||
}) {
|
}) {
|
||||||
return PhotoGallery._listMedia(
|
return PhotoGallery._listMedia(
|
||||||
album: this,
|
album: this,
|
||||||
newest: newest,
|
|
||||||
skip: skip,
|
skip: skip,
|
||||||
take: take,
|
take: take,
|
||||||
);
|
);
|
||||||
|
@ -5,9 +5,6 @@ part of photogallery;
|
|||||||
class MediaPage {
|
class MediaPage {
|
||||||
final Album album;
|
final Album album;
|
||||||
|
|
||||||
/// The sort direction is newest or not
|
|
||||||
final bool newest;
|
|
||||||
|
|
||||||
/// The start offset for those media.
|
/// The start offset for those media.
|
||||||
final int start;
|
final int start;
|
||||||
|
|
||||||
@ -22,8 +19,7 @@ class MediaPage {
|
|||||||
|
|
||||||
/// Creates a range of media from platform channel protocol.
|
/// Creates a range of media from platform channel protocol.
|
||||||
MediaPage.fromJson(this.album, dynamic json)
|
MediaPage.fromJson(this.album, dynamic json)
|
||||||
: newest = json['newest'],
|
: start = json['start'],
|
||||||
start = json['start'],
|
|
||||||
items = json['items'].map<Medium>((x) => Medium.fromJson(x)).toList();
|
items = json['items'].map<Medium>((x) => Medium.fromJson(x)).toList();
|
||||||
|
|
||||||
/// Gets the next page of media in the album.
|
/// Gets the next page of media in the album.
|
||||||
@ -31,7 +27,6 @@ class MediaPage {
|
|||||||
assert(!isLast);
|
assert(!isLast);
|
||||||
return PhotoGallery._listMedia(
|
return PhotoGallery._listMedia(
|
||||||
album: album,
|
album: album,
|
||||||
newest: newest,
|
|
||||||
skip: end,
|
skip: end,
|
||||||
take: items.length,
|
take: items.length,
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user