-
Notifications
You must be signed in to change notification settings - Fork 306
/
entity.dart
365 lines (305 loc) · 9.6 KB
/
entity.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
part of '../photo_manager.dart';
/// asset entity, for entity info.
class AssetPathEntity {
/// id
///
/// in ios is localIdentifier
///
/// in android is content provider database _id column
String id;
/// name
///
/// in android is path name
///
/// in ios is photos gallery name
String name;
/// gallery asset count
int assetCount;
/// In iOS: 1: album, 2: folder
///
/// In android: always 1.
int albumType;
/// path asset type.
RequestType _type;
final FilterOptionGroup filterOption;
/// The value used internally by the user.
/// Used to indicate the value that should be available inside the path.
RequestType get type => _type;
set type(RequestType type) {
_type = type;
typeInt = type.index;
}
/// Users should not edit this value.
///
/// This is a field used internally by the library.
int get typeInt => type.value;
/// Users should not edit this value.
///
/// This is a field used internally by the library.
set typeInt(int typeInt) {
_type = RequestType(typeInt);
}
/// This path is the path that contains all the assets.
bool isAll = false;
AssetPathEntity({this.id, this.name, this.filterOption});
Future<void> refreshPathProperties({DateTimeCond dateTimeCond}) async {
dateTimeCond ??=
this.filterOption.dateTimeCond.copyWith(max: DateTime.now());
final result = await PhotoManager.fetchPathProperties(this, dateTimeCond);
if (result != null) {
this.assetCount = result.assetCount;
this.name = result.name;
this.filterOption.dateTimeCond = dateTimeCond;
}
}
/// the image entity list with pagination
///
/// Doesn't support AssetPathEntity with only(Video/Image) flag.
/// Throws UnsupportedError
///
/// [page] is starting 0.
///
/// [pageSize] is item count of page.
///
Future<List<AssetEntity>> getAssetListPaged(int page, int pageSize) {
assert(this.albumType == 1, "Just album type can get asset.");
assert(pageSize > 0, "The pageSize must better than 0.");
return PhotoManager._getAssetListPaged(this, page, pageSize);
}
/// The [start] and [end] like the [String.substring].
Future<List<AssetEntity>> getAssetListRange({int start, int end}) async {
assert(this.albumType == 1, "Just album type can get asset.");
assert(start >= 0, "The start must better than 0.");
assert(end > start, "The end must better than start.");
return PhotoManager._getAssetWithRange(
entity: this, start: start, end: end);
}
/// all of asset, It is recommended to use the latest api (pagination) [getAssetListPaged].
Future<List<AssetEntity>> get assetList => getAssetListPaged(0, assetCount);
/// In android, always return empty list.
Future<List<AssetPathEntity>> getSubPathList() async {
if (!Platform.isIOS) {
return [];
}
return PhotoManager._getSubPath(this);
}
@override
bool operator ==(other) {
if (other is! AssetPathEntity) {
return false;
}
return this.id == other.id;
}
@override
int get hashCode {
return this.id.hashCode;
}
@override
String toString() {
return "AssetPathEntity{ name: $name, id:$id, length = $assetCount }";
}
}
/// Used to describe a picture or video
class AssetEntity {
/// Create from [AssetEntity.id].
static Future<AssetEntity> fromId(String id) async {
final entity = AssetEntity();
entity.id = id;
try {
final result = await entity.refreshProperties();
if (result == null) {
return null;
}
} catch (e) {
return null;
}
return entity;
}
/// in android is database _id column
///
/// in ios is local id
String id;
/// It is title `MediaStore.MediaColumns.DISPLAY_NAME` in MediaStore on android.
///
/// It is `PHAssetResource.filename` on iOS.
///
/// Nullable in iOS. If you must need it, See [FilterOption.needTitle] or use [titleAsync].
String title;
/// It is [title] in Android.
///
/// It is [PHAsset valueForKey:@"filename"] in iOS.
Future<String> get titleAsync => _plugin.getTitleAsync(this);
/// see [id]
AssetEntity({this.id});
/// the asset type
///
/// see [AssetType]
AssetType get type {
switch (typeInt) {
case 1:
return AssetType.image;
case 2:
return AssetType.video;
case 3:
return AssetType.audio;
default:
return AssetType.other;
}
}
/// Asset type int value.
///
/// see [type]
int typeInt;
/// Duration of video, unit is second.
///
/// If [type] is [AssetType.image], then it's value is 0.
///
/// Also see [videoDuration]
int duration;
/// width of asset.
int width;
/// height of asset.
int height;
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
double _latitude;
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
double get latitude => _latitude ?? 0;
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
set latitude(double latitude) {
_latitude = latitude;
}
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
double _longitude;
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
double get longitude => _longitude ?? 0;
/// Gps information when shooting, nullable.
///
/// When the device is android10 or above, always null.
set longitude(double longitude) {
_longitude = longitude;
}
/// Get latitude and longitude from MediaStore(android) / Photos(iOS).
///
/// except : In androidQ, the location info come from exif.
///
/// [LatLng.latitude] or [LatLng.longitude] maybe zero or null.
Future<LatLng> latlngAsync() {
return _plugin.getLatLngAsync(this);
}
/// if you need upload file ,then you can use the file, nullable.
Future<File> get file async => PhotoManager._getFileWithId(this.id);
/// This contains all the EXIF information, but in contrast, `Image` widget may not be able to display pictures.
///
/// Usually, you can use the [file] attribute
Future<File> get originFile async =>
PhotoManager._getFileWithId(id, isOrigin: true);
/// The asset's bytes.
///
/// Use [originBytes]
///
/// The property will be remove in 0.5.0.
@Deprecated("Use originBytes instead")
Future<Uint8List> get fullData => PhotoManager._getFullDataWithId(id);
/// The raw data stored in the device, the data may be large.
///
/// This property is not recommended for video types.
Future<Uint8List> get originBytes => PhotoManager._getOriginBytes(this);
/// thumb data , for display
Future<Uint8List> get thumbData => PhotoManager._getThumbDataWithId(id);
/// get thumb with size
Future<Uint8List> thumbDataWithSize(
int width,
int height, {
ThumbFormat format = ThumbFormat.jpeg,
int quality = 100,
}) {
assert(width > 0 && height > 0, "The width and height must better 0.");
assert(format != null, "The format must not be null.");
assert(quality > 0 && quality <= 100, "The qulity must between 0 and 100");
return PhotoManager._getThumbDataWithId(
id,
width: width,
height: height,
format: format,
quality: quality,
);
}
/// if not video ,duration is null
Duration get videoDuration => Duration(seconds: duration ?? 0);
/// nullable, if the manager is null.
Size get size => Size(width.toDouble(), height.toDouble());
/// unix timestamp of asset, milliseconds
int createDtSecond;
/// create time of asset
DateTime get createDateTime {
final sec = (createDtSecond ?? 0);
return DateTime.fromMillisecondsSinceEpoch(sec * 1000);
}
/// second of modified.
int modifiedDateSecond;
DateTime get modifiedDateTime {
final sec = modifiedDateSecond ?? 0;
return DateTime.fromMillisecondsSinceEpoch(sec * 1000);
}
/// If the asset is deleted, return false.
Future<bool> get exists => PhotoManager._assetExistsWithId(id);
/// The url is provided to some video player. Such as [flutter_ijkplayer](https://pub.dev/packages/flutter_ijkplayer)
///
/// It is such as `file:///var/mobile/Media/DCIM/118APPLE/IMG_8371.MOV` in iOS.
///
/// Android: `content://media/external/video/media/894857`
Future<String> getMediaUrl() {
if (type == AssetType.video || type == AssetType.audio) {
return PhotoManager._getMediaUrl(this);
}
return null;
}
/// Orientation of android MediaStore. See [ORIENTATION](https://developer.android.com/reference/android/provider/MediaStore.MediaColumns#ORIENTATION)
/// Example values for android: 0 90 180 270
///
/// The value always 0 in iOS.
int orientation;
/// Android does not have this field, so it is always false.
///
/// In iOS, it is consistent with PHAsset.isFavorite. to change it, Use `PhotoManager.editor.iOS.favoriteAsset`, See [IosEditor.favoriteAsset]
bool isFavorite;
/// In iOS, always null.
///
/// In androidQ or higher: it is `MediaStore.MediaColumns.RELATIVE_PATH`.
///
/// API 28 or lower: it is `MediaStore.MediaColumns.DATA` parent path.
String relativePath;
/// refreshProperties
Future<AssetEntity> refreshProperties() async {
return PhotoManager.refreshAssetProperties(this);
}
@override
int get hashCode {
return id.hashCode;
}
@override
bool operator ==(other) {
if (other is! AssetEntity) {
return false;
}
return this.id == other.id;
}
@override
String toString() {
return "AssetEntity{ id:$id , type: $type}";
}
}
class LatLng {
double longitude;
double latitude;
}