Commit 70fd5331d1d73ab79fe2a582e08db677b76157e7
1 parent
18fc1d32
安卓、iOS不动,鸿蒙端用image_picker_ohos 代替 wechat_asset_picker
Showing
79 changed files
with
4711 additions
and
52 deletions
Too many changes to show.
To preserve performance only 79 of 79+ files are displayed.
| @@ -34,6 +34,12 @@ import './dispose.dart'; | @@ -34,6 +34,12 @@ import './dispose.dart'; | ||
| 34 | // import 'package:photo_manager/photo_manager.dart'; | 34 | // import 'package:photo_manager/photo_manager.dart'; |
| 35 | import 'package:flutter_native_image/flutter_native_image.dart'; | 35 | import 'package:flutter_native_image/flutter_native_image.dart'; |
| 36 | // import 'package:flutter_image_compress/flutter_image_compress.dart'; | 36 | // import 'package:flutter_image_compress/flutter_image_compress.dart'; |
| 37 | +import 'package:image_picker_ohos/image_picker_ohos.dart'; | ||
| 38 | +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; | ||
| 39 | + | ||
| 40 | +class MediaDN { | ||
| 41 | + File? file; | ||
| 42 | +} | ||
| 37 | 43 | ||
| 38 | typedef void OnPickImageCallback( | 44 | typedef void OnPickImageCallback( |
| 39 | double maxWidth, double maxHeight, int quality); | 45 | double maxWidth, double maxHeight, int quality); |
| @@ -84,6 +90,8 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | @@ -84,6 +90,8 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | ||
| 84 | final Storage storage = Storage(); | 90 | final Storage storage = Storage(); |
| 85 | // 控制器,可以用于取消任务、获取上述的状态,进度等信息 | 91 | // 控制器,可以用于取消任务、获取上述的状态,进度等信息 |
| 86 | // PutController putController = PutController(); | 92 | // PutController putController = PutController(); |
| 93 | + | ||
| 94 | + final ImagePickerPlatform _picker = new ImagePickerOhos(); | ||
| 87 | // 当前的任务状态 | 95 | // 当前的任务状态 |
| 88 | 96 | ||
| 89 | @override | 97 | @override |
| @@ -176,6 +184,182 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | @@ -176,6 +184,182 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | ||
| 176 | } | 184 | } |
| 177 | } | 185 | } |
| 178 | 186 | ||
| 187 | + // void _showPickedSnackBar(BuildContext context, List<XFile> files) { | ||
| 188 | + // ScaffoldMessenger.of(context).showSnackBar(SnackBar( | ||
| 189 | + // content: Text('Picked: ${files.map((XFile it) => it.name).join(',')}'), | ||
| 190 | + // duration: const Duration(seconds: 2), | ||
| 191 | + // )); | ||
| 192 | + // } | ||
| 193 | + | ||
| 194 | + // Future<void> _displayPickImageDialog( | ||
| 195 | + // BuildContext context, OnPickImageCallback onPick) async { | ||
| 196 | + // return showDialog( | ||
| 197 | + // context: context, | ||
| 198 | + // builder: (BuildContext context) { | ||
| 199 | + // return AlertDialog( | ||
| 200 | + // title: const Text('Add optional parameters'), | ||
| 201 | + // content: Column( | ||
| 202 | + // children: <Widget>[ | ||
| 203 | + // TextField( | ||
| 204 | + // controller: maxWidthController, | ||
| 205 | + // keyboardType: | ||
| 206 | + // const TextInputType.numberWithOptions(decimal: true), | ||
| 207 | + // decoration: const InputDecoration( | ||
| 208 | + // hintText: 'Enter maxWidth if desired'), | ||
| 209 | + // ), | ||
| 210 | + // TextField( | ||
| 211 | + // controller: maxHeightController, | ||
| 212 | + // keyboardType: | ||
| 213 | + // const TextInputType.numberWithOptions(decimal: true), | ||
| 214 | + // decoration: const InputDecoration( | ||
| 215 | + // hintText: 'Enter maxHeight if desired'), | ||
| 216 | + // ), | ||
| 217 | + // TextField( | ||
| 218 | + // controller: qualityController, | ||
| 219 | + // keyboardType: TextInputType.number, | ||
| 220 | + // decoration: const InputDecoration( | ||
| 221 | + // hintText: 'Enter quality if desired'), | ||
| 222 | + // ), | ||
| 223 | + // ], | ||
| 224 | + // ), | ||
| 225 | + // actions: <Widget>[ | ||
| 226 | + // TextButton( | ||
| 227 | + // child: const Text('CANCEL'), | ||
| 228 | + // onPressed: () { | ||
| 229 | + // Navigator.of(context).pop(); | ||
| 230 | + // }, | ||
| 231 | + // ), | ||
| 232 | + // TextButton( | ||
| 233 | + // child: const Text('PICK'), | ||
| 234 | + // onPressed: () { | ||
| 235 | + // final double? width = maxWidthController.text.isNotEmpty | ||
| 236 | + // ? double.parse(maxWidthController.text) | ||
| 237 | + // : null; | ||
| 238 | + // final double? height = maxHeightController.text.isNotEmpty | ||
| 239 | + // ? double.parse(maxHeightController.text) | ||
| 240 | + // : null; | ||
| 241 | + // final int? quality = qualityController.text.isNotEmpty | ||
| 242 | + // ? int.parse(qualityController.text) | ||
| 243 | + // : null; | ||
| 244 | + // onPick(width, height, quality); | ||
| 245 | + // Navigator.of(context).pop(); | ||
| 246 | + // }), | ||
| 247 | + // ], | ||
| 248 | + // ); | ||
| 249 | + // }); | ||
| 250 | + // } | ||
| 251 | + | ||
| 252 | + T? _firstOrNull<T>(List<T> list) { | ||
| 253 | + return list.isEmpty ? null : list.first; | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + Future<List<XFile>> _onImageButtonPressed( | ||
| 257 | + ImageSource source, { | ||
| 258 | + required BuildContext context, | ||
| 259 | + bool isMultiImage = false, | ||
| 260 | + bool isMedia = false, | ||
| 261 | + bool isVideo = false, | ||
| 262 | + }) async { | ||
| 263 | + // if (_controller != null) { | ||
| 264 | + // await _controller!.setVolume(0.0); | ||
| 265 | + // } | ||
| 266 | + if (context.mounted) { | ||
| 267 | + if (isVideo) { | ||
| 268 | + List<XFile> temp = []; | ||
| 269 | + final XFile? file = await _picker.getVideo( | ||
| 270 | + source: source, maxDuration: const Duration(seconds: 10)); | ||
| 271 | + if (file != null && context.mounted) { | ||
| 272 | + // _showPickedSnackBar(context, <XFile>[file]); | ||
| 273 | + temp.add(file as XFile); | ||
| 274 | + } | ||
| 275 | + return temp; | ||
| 276 | + } else if (isMultiImage) { | ||
| 277 | + double? maxWidth = 300.00; | ||
| 278 | + double? maxHeight = 500; | ||
| 279 | + int? quality = 90; | ||
| 280 | + | ||
| 281 | + try { | ||
| 282 | + final ImageOptions imageOptions = ImageOptions( | ||
| 283 | + maxWidth: maxWidth, | ||
| 284 | + maxHeight: maxHeight, | ||
| 285 | + imageQuality: quality, | ||
| 286 | + ); | ||
| 287 | + final List<XFile> pickedFileList = isMedia | ||
| 288 | + ? await _picker.getMedia( | ||
| 289 | + options: MediaOptions( | ||
| 290 | + allowMultiple: isMultiImage, imageOptions: imageOptions), | ||
| 291 | + ) | ||
| 292 | + : await _picker.getMultiImageWithOptions( | ||
| 293 | + options: MultiImagePickerOptions( | ||
| 294 | + imageOptions: imageOptions, | ||
| 295 | + ), | ||
| 296 | + ); | ||
| 297 | + | ||
| 298 | + if (pickedFileList.isNotEmpty && context.mounted) { | ||
| 299 | + return pickedFileList; | ||
| 300 | + } else { | ||
| 301 | + return []; | ||
| 302 | + } | ||
| 303 | + } catch (e) { | ||
| 304 | + print(e.toString()); | ||
| 305 | + } | ||
| 306 | + } else if (isMedia) { | ||
| 307 | + // double? maxWidth = 300.00; | ||
| 308 | + // double? maxHeight = 500; | ||
| 309 | + // int? quality = 90; | ||
| 310 | + | ||
| 311 | + try { | ||
| 312 | + final List<XFile> pickedFileList = <XFile>[]; | ||
| 313 | + final XFile? media = _firstOrNull(await _picker.getMedia( | ||
| 314 | + options: MediaOptions( | ||
| 315 | + allowMultiple: isMultiImage, | ||
| 316 | + // imageOptions: ImageOptions( | ||
| 317 | + // maxWidth: maxWidth, | ||
| 318 | + // maxHeight: maxHeight, | ||
| 319 | + // imageQuality: quality, | ||
| 320 | + // ) | ||
| 321 | + ), | ||
| 322 | + )); | ||
| 323 | + | ||
| 324 | + if (media != null) { | ||
| 325 | + pickedFileList.add(media); | ||
| 326 | + print(pickedFileList); | ||
| 327 | + return pickedFileList; | ||
| 328 | + } | ||
| 329 | + } catch (e) { | ||
| 330 | + print(e.toString()); | ||
| 331 | + } | ||
| 332 | + } else { | ||
| 333 | + double? maxWidth = 300.00; | ||
| 334 | + double? maxHeight = 500; | ||
| 335 | + int? quality = 90; | ||
| 336 | + | ||
| 337 | + try { | ||
| 338 | + final XFile? pickedFile = await _picker.getImageFromSource( | ||
| 339 | + source: source, | ||
| 340 | + options: ImagePickerOptions( | ||
| 341 | + maxWidth: maxWidth, | ||
| 342 | + maxHeight: maxHeight, | ||
| 343 | + imageQuality: quality, | ||
| 344 | + ), | ||
| 345 | + ); | ||
| 346 | + List<XFile> temp = []; | ||
| 347 | + if (pickedFile != null && context.mounted) { | ||
| 348 | + temp.add(pickedFile as XFile); | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + print(pickedFile); | ||
| 352 | + return temp; | ||
| 353 | + | ||
| 354 | + // <XFile>[pickedFile] | ||
| 355 | + } catch (e) { | ||
| 356 | + print(e); | ||
| 357 | + } | ||
| 358 | + } | ||
| 359 | + } | ||
| 360 | + return []; | ||
| 361 | + } | ||
| 362 | + | ||
| 179 | ///多图片选择 | 363 | ///多图片选择 |
| 180 | void pickAsset(RequestType type, {List<AssetPathEntity>? pathList}) async { | 364 | void pickAsset(RequestType type, {List<AssetPathEntity>? pathList}) async { |
| 181 | List<UploadImgModel>? temp = []; | 365 | List<UploadImgModel>? temp = []; |
| @@ -194,61 +378,40 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | @@ -194,61 +378,40 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | ||
| 194 | } else if (widget.uploadType == UploadType.RemarkImagesType) { | 378 | } else if (widget.uploadType == UploadType.RemarkImagesType) { |
| 195 | temp = widget.imageList; | 379 | temp = widget.imageList; |
| 196 | } | 380 | } |
| 197 | - List<AssetEntity>? imgList = await AssetPicker.pickAssets(context, | ||
| 198 | - pickerConfig: AssetPickerConfig( | ||
| 199 | - maxAssets: widget.maxImageNumber - temp!.length, | ||
| 200 | - // selectedAssets: assets, | ||
| 201 | - requestType: type, | ||
| 202 | - themeColor: MyColours.color_199095)); | ||
| 203 | - | ||
| 204 | - /// context is required, other params is optional. | ||
| 205 | - // List<AssetEntity> imgList = await PhotoPicker.pickAsset( | ||
| 206 | - // // BuildContext required | ||
| 207 | - // context: context, | ||
| 208 | - | ||
| 209 | - // /// The following are optional parameters. | ||
| 210 | - // themeColor: MyColours.color_199095, | ||
| 211 | - // // the title color and bottom color | ||
| 212 | - // textColor: Colors.white, | ||
| 213 | - // // text color | ||
| 214 | - // padding: 1.0, | ||
| 215 | - // // item padding | ||
| 216 | - // dividerColor: Colors.grey, | ||
| 217 | - // // divider color | ||
| 218 | - // disableColor: Colors.grey.shade300, | ||
| 219 | - // // the check box disable color | ||
| 220 | - // itemRadio: 0.88, | ||
| 221 | - // // the content item radio | ||
| 222 | - // maxSelected: widget.maxImageNumber - temp.length, | ||
| 223 | - // // max picker image count | ||
| 224 | - // // provider: I18nProvider.english, | ||
| 225 | - // provider: I18nProvider.chinese, | ||
| 226 | - // // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider() | ||
| 227 | - // rowCount: 3, | ||
| 228 | - // // item row count | ||
| 229 | - // thumbSize: 150, | ||
| 230 | - // // preview thumb size , default is 64 | ||
| 231 | - // sortDelegate: SortDelegate.common, | ||
| 232 | - // // default is common ,or you make custom delegate to sort your gallery | ||
| 233 | - // checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate( | ||
| 234 | - // activeColor: MyColours.color_353535, | ||
| 235 | - // unselectedColor: Colors.white, | ||
| 236 | - // checkColor: MyColours.color_199095, | ||
| 237 | - // ), | ||
| 238 | - // // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox | ||
| 239 | - // // loadingDelegate: this, | ||
| 240 | - // // if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart] | ||
| 241 | - // badgeDelegate: const DurationBadgeDelegate(), | ||
| 242 | - // // badgeDelegate to show badge widget | ||
| 243 | - // pickType: type, | ||
| 244 | - // photoPathList: pathList, | ||
| 245 | - // ); | ||
| 246 | - if (imgList == null || imgList.isEmpty) { | 381 | + |
| 382 | + List<MediaDN>? imgList = []; | ||
| 383 | + if (Platform.isAndroid || Platform.isIOS) { | ||
| 384 | + List<AssetEntity>? imagListTemp = await AssetPicker.pickAssets(context, | ||
| 385 | + pickerConfig: AssetPickerConfig( | ||
| 386 | + maxAssets: widget.maxImageNumber - temp!.length, | ||
| 387 | + // selectedAssets: assets, | ||
| 388 | + requestType: type, | ||
| 389 | + themeColor: MyColours.color_199095)); | ||
| 390 | + imagListTemp?.forEach((elenemt) async { | ||
| 391 | + MediaDN mediaDN = MediaDN(); | ||
| 392 | + mediaDN.file = await elenemt.file; | ||
| 393 | + imgList.add(mediaDN); | ||
| 394 | + }); | ||
| 395 | + } else if (Platform.isOhos) { | ||
| 396 | + List<XFile> imagListTemp = await _onImageButtonPressed( | ||
| 397 | + ImageSource.gallery, | ||
| 398 | + context: context, | ||
| 399 | + isMultiImage: true, | ||
| 400 | + isVideo: false); | ||
| 401 | + | ||
| 402 | + imagListTemp.forEach((elenemt) async { | ||
| 403 | + MediaDN mediaDN = MediaDN(); | ||
| 404 | + mediaDN.file = File(elenemt.path); | ||
| 405 | + imgList.add(mediaDN); | ||
| 406 | + }); | ||
| 407 | + } | ||
| 408 | + | ||
| 409 | + if (imgList.length == 0 || imgList.isEmpty) { | ||
| 247 | print("No pick item."); | 410 | print("No pick item."); |
| 248 | return; | 411 | return; |
| 249 | } else { | 412 | } else { |
| 250 | for (int i = 0; i < imgList.length; i++) { | 413 | for (int i = 0; i < imgList.length; i++) { |
| 251 | - var file = (await imgList[i].file)!; | 414 | + var file = (imgList[i].file)!; |
| 252 | //从相册选取照片后进行裁剪压缩 | 415 | //从相册选取照片后进行裁剪压缩 |
| 253 | File yourFile = file; | 416 | File yourFile = file; |
| 254 | Uint8List afterImg = await yourFile.readAsBytes(); | 417 | Uint8List afterImg = await yourFile.readAsBytes(); |
| @@ -283,7 +446,7 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | @@ -283,7 +446,7 @@ class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> { | ||
| 283 | if (need) { | 446 | if (need) { |
| 284 | file = File(path); | 447 | file = File(path); |
| 285 | } | 448 | } |
| 286 | - UploadImageUtil().startUpload(context, File(path), temp.length - 1, | 449 | + UploadImageUtil().startUpload(context, File(path), temp!.length - 1, |
| 287 | false, widget.model!, widget.uploadType, | 450 | false, widget.model!, widget.uploadType, |
| 288 | countAll: imgList.length, | 451 | countAll: imgList.length, |
| 289 | callback: widget.callback, | 452 | callback: widget.callback, |
| 1 | +<!-- Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +Use of this source code is governed by an Apache license | ||
| 3 | +that can be found in the LICENSE file. --> | ||
| 4 | + | ||
| 5 | +# Changelog | ||
| 6 | + | ||
| 7 | +> [!IMPORTANT] | ||
| 8 | +> See the [Migration Guide](guides/migration_guide.md) for the details of breaking changes between versions. | ||
| 9 | + | ||
| 10 | +## Unreleased | ||
| 11 | + | ||
| 12 | +*None.* | ||
| 13 | + | ||
| 14 | +## 9.8.0 | ||
| 15 | + | ||
| 16 | +> [!NOTE] | ||
| 17 | +> Be aware of potential minor theme changes since the base theme has taken place in the picker's theme. | ||
| 18 | + | ||
| 19 | +**Improvements** | ||
| 20 | + | ||
| 21 | +- Improve themes by inheriting the base theme rather than standalone constructors. | ||
| 22 | + | ||
| 23 | +**Fixes** | ||
| 24 | + | ||
| 25 | +- Enabling using the package on Flutter 3.35. | ||
| 26 | + | ||
| 27 | +## 9.7.0 | ||
| 28 | + | ||
| 29 | +**Improvements** | ||
| 30 | + | ||
| 31 | +- Allows specifying the fallback text delegate through `assetPickerTextDelegateFromLocale`. | ||
| 32 | + | ||
| 33 | +## 9.6.0 | ||
| 34 | + | ||
| 35 | +**New features** | ||
| 36 | + | ||
| 37 | +- Expose more route settings. | ||
| 38 | + Users will now be able to control the route settings for the picker and viewer. | ||
| 39 | +- Add Persian (Farsi) language support. (Thanks to @Ho3einTahan) | ||
| 40 | + | ||
| 41 | +**Improvements** | ||
| 42 | + | ||
| 43 | +- Improve how `MediaQuery` is being listened. | ||
| 44 | +- Stop enabling drag to select when `maxAssets == 1`. | ||
| 45 | +- Extract `DefaultAssetPickerProvider.init`. | ||
| 46 | + | ||
| 47 | +**Fixes** | ||
| 48 | + | ||
| 49 | +- Fix semantics with the close button. | ||
| 50 | +- Fix `selectPredicate` not being called when selecting the video asset under the WeChat Moment mode. | ||
| 51 | +- Manually dispose memory leak objects. | ||
| 52 | + | ||
| 53 | +## 9.5.1 | ||
| 54 | + | ||
| 55 | +**Improvements** | ||
| 56 | + | ||
| 57 | +- Allow `extended_image` v10. | ||
| 58 | + | ||
| 59 | +## 9.5.0 | ||
| 60 | + | ||
| 61 | +**New features** | ||
| 62 | + | ||
| 63 | +- Support drag to select. | ||
| 64 | + | ||
| 65 | +**Fixes** | ||
| 66 | + | ||
| 67 | +- Fixes semantics issues. | ||
| 68 | + | ||
| 69 | +## 9.4.2 | ||
| 70 | + | ||
| 71 | +**Improvements** | ||
| 72 | + | ||
| 73 | +- Add Traditional Chinese language text delegate. (Thanks to @Gasol) | ||
| 74 | +- Improves the default sort conditions on Android. | ||
| 75 | + | ||
| 76 | +## 9.4.1 | ||
| 77 | + | ||
| 78 | +**Improvements** | ||
| 79 | + | ||
| 80 | +- Improves the default sort conditions. | ||
| 81 | + | ||
| 82 | +**Fixes** | ||
| 83 | + | ||
| 84 | +- Fixes selecting when reached the max asset limit in the preview. | ||
| 85 | + | ||
| 86 | +## 9.4.0 | ||
| 87 | + | ||
| 88 | +**Improvements** | ||
| 89 | + | ||
| 90 | +- Allows `extended_image: ^9.0.0`. | ||
| 91 | + | ||
| 92 | +**Fixes** | ||
| 93 | + | ||
| 94 | +- Allows assets changing when no path previously. | ||
| 95 | + | ||
| 96 | +## 9.3.3 | ||
| 97 | + | ||
| 98 | +**Fixes** | ||
| 99 | + | ||
| 100 | +- Recovers the compatibility with Flutter 3.16. | ||
| 101 | + | ||
| 102 | +## 9.3.2 | ||
| 103 | + | ||
| 104 | +**Improvements** | ||
| 105 | + | ||
| 106 | +- Adapt the file type getter from the image provider to get a precise file type in grid. | ||
| 107 | +- Adds the identifier for grid item's semantics. | ||
| 108 | +- Improves preview page back button. | ||
| 109 | + | ||
| 110 | +## 9.3.1 | ||
| 111 | + | ||
| 112 | +**Improvements** | ||
| 113 | + | ||
| 114 | +- Do not mute the Live Photo during the preview. | ||
| 115 | + | ||
| 116 | +**Fixes** | ||
| 117 | + | ||
| 118 | +- Fix the GIF indicator's layout. | ||
| 119 | +- Fix the directionality with the reverted grid item. | ||
| 120 | + | ||
| 121 | +## 9.3.0 | ||
| 122 | + | ||
| 123 | +**New features** | ||
| 124 | + | ||
| 125 | +- Add explicit Live Photos indicator for assets. | ||
| 126 | + | ||
| 127 | +**Improvements** | ||
| 128 | + | ||
| 129 | +- Make Live Photos gesture consistent when scaling and panning. | ||
| 130 | +- Integrate `LocallyAvailableBuilder` with thumbnail options to improve the thumbnail loading speed. | ||
| 131 | +- Use `visibility_detector` and scroll observer to improve media playing experiences. | ||
| 132 | + | ||
| 133 | +**Fixes** | ||
| 134 | + | ||
| 135 | +- Fix the bottom actions bar display conditions. | ||
| 136 | + | ||
| 137 | +## 9.2.2 | ||
| 138 | + | ||
| 139 | +- Uses correct `isOriginal` for the `LocallyAvailableBuilder`. | ||
| 140 | + | ||
| 141 | +## 9.2.1 | ||
| 142 | + | ||
| 143 | +- Improve changes when limited on iOS. | ||
| 144 | +- Use `LocallyAvailableBuilder` in the grid to provide better user awareness. | ||
| 145 | + | ||
| 146 | +## 9.2.0 | ||
| 147 | + | ||
| 148 | +**New features** | ||
| 149 | + | ||
| 150 | +- Introduce `AssetsChangeCallback` and `AssetsChangeRefreshPredicate` | ||
| 151 | + to help users act according to asset changes. | ||
| 152 | +- Add `shouldAutoplayPreview` to the picker config. | ||
| 153 | + | ||
| 154 | +**Fixes** | ||
| 155 | + | ||
| 156 | +- Raise detailed negative range error. | ||
| 157 | +- Fix viewer confirm button predication. | ||
| 158 | +- Enlarge GIF gradients. | ||
| 159 | +- Fix potential paths assets count unexpected merging behaviors. | ||
| 160 | + | ||
| 161 | +## 9.1.0 | ||
| 162 | + | ||
| 163 | +**Improvements** | ||
| 164 | + | ||
| 165 | +- Support limited permission displays on Android. | ||
| 166 | +- Improves the limited overlay padding on Android. | ||
| 167 | +- Adds permission request lock for the picker state. | ||
| 168 | +- Speeding up by splitting asset loading into separate steps. | ||
| 169 | +- Speeding up using `AdvancedCustomFilter` rather than `FilterOptionGroup` by default. | ||
| 170 | + | ||
| 171 | +**Fixes** | ||
| 172 | + | ||
| 173 | +- Fix reverted index when previewing assets on Android. | ||
| 174 | +- Requests with the correct options with the picker. | ||
| 175 | + | ||
| 176 | +## 9.0.4 | ||
| 177 | + | ||
| 178 | +**Fixes** | ||
| 179 | + | ||
| 180 | +- Fix the app bar of the viewer that is not animating. | ||
| 181 | +- Fix loading when no assets are in the path. | ||
| 182 | +- Reset the has more to load flag between path switching. | ||
| 183 | + | ||
| 184 | +## 9.0.3 | ||
| 185 | + | ||
| 186 | +**Fixes** | ||
| 187 | + | ||
| 188 | +- Fix index reverting in `viewAsset`. | ||
| 189 | + | ||
| 190 | +## 9.0.2 | ||
| 191 | + | ||
| 192 | +**Fixes** | ||
| 193 | + | ||
| 194 | +- Fix the index with bottom items in the preview. | ||
| 195 | + | ||
| 196 | +## 9.0.1 | ||
| 197 | + | ||
| 198 | +**Fixes** | ||
| 199 | + | ||
| 200 | +- Fix the current asset in the picker viewer. | ||
| 201 | + | ||
| 202 | +**Improvements** | ||
| 203 | + | ||
| 204 | +- Improve code formatting. | ||
| 205 | + | ||
| 206 | +## 9.0.0 | ||
| 207 | + | ||
| 208 | +**Breaking changes** | ||
| 209 | + | ||
| 210 | +- Migrate to Flutter 3.16, and drop supports for previous Flutter versions. | ||
| 211 | +- Bump `photo_manager` to v3.x. | ||
| 212 | +- Export `photo_manager_image_provider`. | ||
| 213 | +- Integrate `PermissionRequestOption` for callers. | ||
| 214 | + | ||
| 215 | +**Improvements** | ||
| 216 | + | ||
| 217 | +- Adapt `ThemeData` usages. | ||
| 218 | +- Use `wechat_picker_library`. | ||
| 219 | +- Make the first asset count not blocking loads. | ||
| 220 | + | ||
| 221 | +**Fixes** | ||
| 222 | + | ||
| 223 | +- Fix unhandled child semantics with the app bar title. | ||
| 224 | +- Fix styles around the app bar and other widgets. | ||
| 225 | +- Fix previewing selected assets' behavior. | ||
| 226 | +- Use `PermissionRequestOption` as much as possible. | ||
| 227 | +- Raise more errors for non-synced paths. | ||
| 228 | +- Fix the experience with `shouldRevertGrid`. | ||
| 229 | + | ||
| 230 | +## 8.8.0 | ||
| 231 | + | ||
| 232 | +**New features** | ||
| 233 | + | ||
| 234 | +- Add Korean language support. (Thanks to @LIMMIHEE) | ||
| 235 | + | ||
| 236 | +**Improvements** | ||
| 237 | + | ||
| 238 | +- Use `viewAsset` in the preview button. | ||
| 239 | + | ||
| 240 | +**Fixes** | ||
| 241 | + | ||
| 242 | +- Fix disposed provider throwing error when fetching assets. (#493) | ||
| 243 | + | ||
| 244 | +## 8.7.1 | ||
| 245 | + | ||
| 246 | +**Improvements** | ||
| 247 | + | ||
| 248 | +- Improve README docs and add topics for pub. | ||
| 249 | + | ||
| 250 | +## 8.7.0 | ||
| 251 | + | ||
| 252 | +**Breaking changes** | ||
| 253 | + | ||
| 254 | +- Migrate to Flutter 3.13, and drop supports for previous Flutter versions. | ||
| 255 | + | ||
| 256 | +## 8.6.3 | ||
| 257 | + | ||
| 258 | +**Improvements** | ||
| 259 | + | ||
| 260 | +- Improve `AssetPickerProvider.paths`. | ||
| 261 | + | ||
| 262 | +## 8.6.2 | ||
| 263 | + | ||
| 264 | +**Improvements** | ||
| 265 | + | ||
| 266 | +- Add `appBarPreferredSize` in the picker delegate to help with padding calculations. | ||
| 267 | +- Improve the performance with `MediaQuery` callers. | ||
| 268 | + | ||
| 269 | +## 8.6.1 | ||
| 270 | + | ||
| 271 | +**Improvements** | ||
| 272 | + | ||
| 273 | +- Remove `needTitle` for image filter options. | ||
| 274 | + | ||
| 275 | +**Fixes** | ||
| 276 | + | ||
| 277 | +- Fix hit test when previewing videos. | ||
| 278 | + | ||
| 279 | +## 8.6.0 | ||
| 280 | + | ||
| 281 | +**Breaking changes** | ||
| 282 | + | ||
| 283 | +- Use `TargetPlatform` for the `isAppleOS` method in delegates, which relies on a `BuildContext`. | ||
| 284 | + | ||
| 285 | +**New features** | ||
| 286 | + | ||
| 287 | +- Sync all UI details from WeChat 8.3.x. (#458) | ||
| 288 | +- Add Turkish language text delegate. (Thanks to @cevheri). | ||
| 289 | +- Allow to confirm 0 assets if there are selected assets previously. (#461) | ||
| 290 | + | ||
| 291 | +**Improvements** | ||
| 292 | + | ||
| 293 | +- Silent part of thumbnail request exceptions. | ||
| 294 | + | ||
| 295 | +**Fixes** | ||
| 296 | + | ||
| 297 | +- Fix semantics interactions for video preview. (#458) | ||
| 298 | +- Be able to update the items builder page. (#417) | ||
| 299 | + | ||
| 300 | +## 8.5.0 | ||
| 301 | + | ||
| 302 | +**Breaking changes** | ||
| 303 | + | ||
| 304 | +- Migrate to Flutter 3.10, and drop supports for previous Flutter versions. | ||
| 305 | + | ||
| 306 | +## 8.4.3 | ||
| 307 | + | ||
| 308 | +**New features** | ||
| 309 | + | ||
| 310 | +- Add Vietnamese language text delegate. (Thanks to @nploi). | ||
| 311 | + | ||
| 312 | +**Improvements** | ||
| 313 | + | ||
| 314 | +- Expand `FilterOptionGroup` to `PMFilter`. (#436) | ||
| 315 | + | ||
| 316 | +## 8.4.2 | ||
| 317 | + | ||
| 318 | +**Fixes** | ||
| 319 | + | ||
| 320 | +- Avoid clearing selected assets when disposing the provider. (#428) | ||
| 321 | + | ||
| 322 | +## 8.4.1 | ||
| 323 | + | ||
| 324 | +**Fixes** | ||
| 325 | + | ||
| 326 | +- Call `AssetPickerProvider.dispose` when disposing the builder delegate. (#421) | ||
| 327 | + | ||
| 328 | +## 8.4.0 | ||
| 329 | + | ||
| 330 | +**Breaking changes** | ||
| 331 | + | ||
| 332 | +- Migrate to Flutter 3.7, and drop supports for previous Flutter versions. | ||
| 333 | + | ||
| 334 | +## 8.3.2+1 | ||
| 335 | + | ||
| 336 | +**Improvements** | ||
| 337 | + | ||
| 338 | +- Add more assertions. (#411) | ||
| 339 | + | ||
| 340 | +## 8.3.2 | ||
| 341 | + | ||
| 342 | +**Fixes** | ||
| 343 | + | ||
| 344 | +- Use `Completer` and more accurate conditions to avoid duplicate load assets | ||
| 345 | + when `AssetPickerConfig.pageSize` is smaller than a complete page. (#407) | ||
| 346 | + | ||
| 347 | +## 8.3.1+1 | ||
| 348 | + | ||
| 349 | +**Improvements** | ||
| 350 | + | ||
| 351 | +- Fix images and descriptions in `README`s. | ||
| 352 | + | ||
| 353 | +## 8.3.1 | ||
| 354 | + | ||
| 355 | +**New features** | ||
| 356 | + | ||
| 357 | +- Add `didUpdateViewer` and `initAnimations` in the `AssetPickerViewerBuilderDelegate`. (#403) | ||
| 358 | +- Add insta_assets_picker as a custom delegate example. (#403) | ||
| 359 | + | ||
| 360 | +## 8.3.0 | ||
| 361 | + | ||
| 362 | +**New features** | ||
| 363 | + | ||
| 364 | +- Add `index` argument to `selectAsset` in the `AssetPickerBuilderDelegate`. (#399) | ||
| 365 | + | ||
| 366 | +**Improvements** | ||
| 367 | + | ||
| 368 | +- Improve UI details in the `AssetPickerAppBar`. (#400) | ||
| 369 | + | ||
| 370 | +## 8.2.0 | ||
| 371 | + | ||
| 372 | +**New features** | ||
| 373 | + | ||
| 374 | +- Allow overrides `viewAsset` in the `AssetPickerBuilderDelegate`. (#391) | ||
| 375 | + | ||
| 376 | +**Fixes** | ||
| 377 | + | ||
| 378 | +- Correct behaviors when the access is limited on iOS. (#392) | ||
| 379 | + | ||
| 380 | +## 8.1.4 | ||
| 381 | + | ||
| 382 | +**Fixes** | ||
| 383 | + | ||
| 384 | +- Fix conditions with the confirm button on iOS. (#376) | ||
| 385 | + | ||
| 386 | +## 8.1.3 | ||
| 387 | + | ||
| 388 | +**Improvements** | ||
| 389 | + | ||
| 390 | +- Bump `photo_manager` to explicitly remove the requirements of `requiredLegacyExternalStorage`. | ||
| 391 | + | ||
| 392 | +## 8.1.2 | ||
| 393 | + | ||
| 394 | +**Fixes** | ||
| 395 | + | ||
| 396 | +- Fix conditions with the confirm button. (#371) | ||
| 397 | + | ||
| 398 | +## 8.1.1 | ||
| 399 | + | ||
| 400 | +**Fixes** | ||
| 401 | + | ||
| 402 | +- Fix conditions with the confirm button. (#367) | ||
| 403 | + | ||
| 404 | +## 8.1.0 | ||
| 405 | + | ||
| 406 | +**New features** | ||
| 407 | + | ||
| 408 | +- Upgrade `photo_manager` for Android 13. (#365) | ||
| 409 | + | ||
| 410 | +**Improvements** | ||
| 411 | + | ||
| 412 | +- Improve `BuildContext` usages to obtain the correct directionality for the assets grid. (#359) | ||
| 413 | +- Provide a better condition to the confirm button | ||
| 414 | + to make sure it displays correctly in all cases on iOS/macOS. (#359) | ||
| 415 | +- Improve `bottomActionBar` in `DefaultAssetPickerBuilderDelegate`. (#359) | ||
| 416 | + | ||
| 417 | +**Fixes** | ||
| 418 | + | ||
| 419 | +- Fix invalid path sort. (#364) | ||
| 420 | + | ||
| 421 | +## 8.0.2 | ||
| 422 | + | ||
| 423 | +**Improvements** | ||
| 424 | + | ||
| 425 | +- Adapt Flutter 3.3. (#354) | ||
| 426 | + | ||
| 427 | +## 8.0.1 | ||
| 428 | + | ||
| 429 | +**Fixes** | ||
| 430 | + | ||
| 431 | +- Fix not updated empty flag in `DefaultAssetPickerProvider`. (#353) | ||
| 432 | + | ||
| 433 | +## 8.0.0 | ||
| 434 | + | ||
| 435 | +To know more about breaking changes, see [Migration Guide][]. | ||
| 436 | + | ||
| 437 | +**New features** | ||
| 438 | + | ||
| 439 | +- Introduce `PathWrapper` in delegates to improve the overall loading speed. (#338) | ||
| 440 | +- Allow using `Key` during picking. (#339) | ||
| 441 | +- Add `initializeDelayDuration` for `DefaultAssetPickerProvider`. (#341) | ||
| 442 | +- Prevent race conditions with paths. (#342) | ||
| 443 | +- Expose `sortPathsByModifiedDate`. (#343) | ||
| 444 | + | ||
| 445 | +**Fixes** | ||
| 446 | + | ||
| 447 | +- Unify indicator usage to avoid accidental indicator switching. (#344) | ||
| 448 | + | ||
| 449 | +## 7.3.2 | ||
| 450 | + | ||
| 451 | +**Improvements** | ||
| 452 | + | ||
| 453 | +- Improve `onChangingSelected` in `AssetPickerViewerBuilderDelegate`. (#332) | ||
| 454 | +- Fix typo in `README.md`. (#333) | ||
| 455 | + | ||
| 456 | +**Fixes** | ||
| 457 | + | ||
| 458 | +- Fix behaviors when unselecting all assets in the viewer. (#335) | ||
| 459 | + | ||
| 460 | +## 7.3.1 | ||
| 461 | + | ||
| 462 | +**Improvements** | ||
| 463 | + | ||
| 464 | +- Improve selection callers between picker and viewer. (#327) | ||
| 465 | + | ||
| 466 | +## 7.3.0 | ||
| 467 | + | ||
| 468 | +**Breaking changes** | ||
| 469 | + | ||
| 470 | +- Migrate to Flutter 3, and drop supports for previous Flutter versions. | ||
| 471 | + | ||
| 472 | +## 7.2.0 | ||
| 473 | + | ||
| 474 | +**New features** | ||
| 475 | + | ||
| 476 | +- Separate `AssetPickerDelegate` (#315), | ||
| 477 | + which provides the ability to override methods within the `AssetPicker`. | ||
| 478 | + | ||
| 479 | +**Improvements** | ||
| 480 | + | ||
| 481 | +- Improve `specialItemBuilder`. (#314) | ||
| 482 | + | ||
| 483 | +## 7.1.2 | ||
| 484 | + | ||
| 485 | +**Fixes** | ||
| 486 | + | ||
| 487 | +- Fix context usages for inherited theme data. | ||
| 488 | +- Fix unlinked path name builder. | ||
| 489 | + | ||
| 490 | +**Improvements** | ||
| 491 | + | ||
| 492 | +- Update how paths get updated. (#312) | ||
| 493 | +- Expose `DefaultAssetPickerProvider.forTest`. | ||
| 494 | + | ||
| 495 | +## 7.1.1 | ||
| 496 | + | ||
| 497 | +**Fixes** | ||
| 498 | + | ||
| 499 | +- Fix `selectPredicate` with the viewer. (#307) | ||
| 500 | + | ||
| 501 | +## 7.1.0 | ||
| 502 | + | ||
| 503 | +**New features** | ||
| 504 | + | ||
| 505 | +- Add `PathNameBuilder`. (#303) | ||
| 506 | +- Add `LimitedPermissionOverlayPredicate`. (#287) | ||
| 507 | + | ||
| 508 | +## 7.0.5 | ||
| 509 | + | ||
| 510 | +**Improvements** | ||
| 511 | + | ||
| 512 | +- Support compile on the Web. (#273) | ||
| 513 | + | ||
| 514 | +## 7.0.4 | ||
| 515 | + | ||
| 516 | +**Improvements** | ||
| 517 | + | ||
| 518 | +- Make all text delegates const. | ||
| 519 | + | ||
| 520 | +## 7.0.3 | ||
| 521 | + | ||
| 522 | +**Fixes** | ||
| 523 | + | ||
| 524 | +- Fix the broken semantics on iOS/macOS. (#272) | ||
| 525 | + | ||
| 526 | +## 7.0.2 | ||
| 527 | + | ||
| 528 | +**Fixes** | ||
| 529 | + | ||
| 530 | +- Fix wrong conditions judging when obtaining path thumbnails. | ||
| 531 | + | ||
| 532 | +## 7.0.1 | ||
| 533 | + | ||
| 534 | +**Improvements** | ||
| 535 | + | ||
| 536 | +- Support semantics with Japanese text delegates. (#266). | ||
| 537 | + | ||
| 538 | +**Fixes** | ||
| 539 | + | ||
| 540 | +- Obtain the path thumbnail only when the asset is an image or video. | ||
| 541 | + | ||
| 542 | +## 7.0.0 | ||
| 543 | + | ||
| 544 | +To know more about breaking changes, see [Migration Guide][]. | ||
| 545 | + | ||
| 546 | +**New features** | ||
| 547 | + | ||
| 548 | +- Support predictable special item display. (#264) | ||
| 549 | +- Support Live-Photos display. (#251) | ||
| 550 | +- Expose `AssetPickerPageRoute` for customization. (#248) | ||
| 551 | +- Add full semantics support. (#232, #235, #240, #242, #243, #245, #254) | ||
| 552 | + | ||
| 553 | +**Improvements** | ||
| 554 | + | ||
| 555 | +- Improve scaling with select indicators and numbers. | ||
| 556 | +- Implement the default light theme. (#234) | ||
| 557 | + | ||
| 558 | +**Fixes** | ||
| 559 | + | ||
| 560 | +- Fix `LocallyAvailableBuilder` with more edge conditions. (#263) | ||
| 561 | +- Fix potential "No elements" error with thumbnails. | ||
| 562 | + | ||
| 563 | +## 6.3.1 | ||
| 564 | + | ||
| 565 | +- Improve image type determined when resolving image data. | ||
| 566 | + This mostly resolved the occasional HEIC loading issue when | ||
| 567 | + apps are running under the release mode. | ||
| 568 | + | ||
| 569 | +## 6.3.0 | ||
| 570 | + | ||
| 571 | +- Support for Flutter 2.8.0, also drop supports for Flutter below 2.8.0. | ||
| 572 | + | ||
| 573 | +## 6.2.4 | ||
| 574 | + | ||
| 575 | +- Improve audio item layout. | ||
| 576 | +- Improve workflows. | ||
| 577 | +- Indicate the path getter more precisely. | ||
| 578 | +- Improve Arabic text delegate. | ||
| 579 | + | ||
| 580 | +## 6.2.3 | ||
| 581 | + | ||
| 582 | +- Pass through `selectPredicate` to `AssetPickerViewer`. (#211) | ||
| 583 | +- Bump the `sdk` constraints (since 6.2.1). | ||
| 584 | + | ||
| 585 | +## 6.2.2 | ||
| 586 | + | ||
| 587 | +- Use `.contentUri` for video preview only on Android. | ||
| 588 | + | ||
| 589 | +## 6.2.1 | ||
| 590 | + | ||
| 591 | +- Migrate to `extended_image` 5.x. | ||
| 592 | +- Use `.contentUri` constructor for `VideoPlayerController`. | ||
| 593 | + | ||
| 594 | +## 6.2.0 | ||
| 595 | + | ||
| 596 | +- Introduce `shouldRevertGrid` to determine whether the assets grid should be reverted. | ||
| 597 | +- Upgrade `photo_manager` to resolve issues against `AssetEntity`s comparison. | ||
| 598 | + | ||
| 599 | +## 6.1.2 | ||
| 600 | + | ||
| 601 | +- Fix the limited resources refresh issue. | ||
| 602 | +- Update callers to avoid deprecated usage. | ||
| 603 | + | ||
| 604 | +## 6.1.1 | ||
| 605 | + | ||
| 606 | +- Handle iCloud video more gracefully. | ||
| 607 | + | ||
| 608 | +## 6.1.0 | ||
| 609 | + | ||
| 610 | +- Introduce `selectPredicate` to predicate asset when picking. | ||
| 611 | + | ||
| 612 | +## 6.0.6 | ||
| 613 | + | ||
| 614 | +- Use the correct index reference with `selectedBackdrop`. (#195) | ||
| 615 | + | ||
| 616 | +## 6.0.5 | ||
| 617 | + | ||
| 618 | +- Upgrade dependencies. | ||
| 619 | + | ||
| 620 | +## 6.0.4 | ||
| 621 | + | ||
| 622 | +- Add French language text delegate. (Thanks to @didiosn) | ||
| 623 | +- Export "Nothing here." as a field to text delegate. (#190) | ||
| 624 | +- Fix selected backdrop not synced all the time. | ||
| 625 | +- Improve the instructions for the example. | ||
| 626 | + | ||
| 627 | +## 6.0.3 | ||
| 628 | + | ||
| 629 | +- Fix path entity nullable issues with the asset grid. | ||
| 630 | +- Fix assets displaying conditions missing with the iOS layout. | ||
| 631 | + | ||
| 632 | +## 6.0.2 | ||
| 633 | + | ||
| 634 | +- Expose `shouldReversePreview` for `AssetPickerViewerBuilderDelegate`. | ||
| 635 | + | ||
| 636 | +## 6.0.1 | ||
| 637 | + | ||
| 638 | +- Improve total count calculation with `AssetPathEntity`. (#187) | ||
| 639 | +- Obtain `AssetPathEntity.isAll` fix from `photo_manager`. | ||
| 640 | +- Documents update. | ||
| 641 | + | ||
| 642 | +## 6.0.0 | ||
| 643 | + | ||
| 644 | +**New features** | ||
| 645 | + | ||
| 646 | +- Sync all UI details from WeChat 8.0.x. | ||
| 647 | +- Integrate iCloud progress overview in previews. | ||
| 648 | +- Change the permission from the app settings when it's limited. | ||
| 649 | +- Request more assets on iOS when the permission is limited. | ||
| 650 | +- Fit the assets' grid's layout as the iOS `Photos` app (reverted and started from the bottom). | ||
| 651 | +- Add Arabic language text delegate. | ||
| 652 | +- Allow using `AssetPicker` and `AssetPickerViewer` directly with delegates. | ||
| 653 | +- Add `keepScrollOffset` feature for the `AssetPickerBuilderDelegate`. | ||
| 654 | + | ||
| 655 | +**Improvements** | ||
| 656 | + | ||
| 657 | +- Items that are being banned from select (reached max assets or type conflict) | ||
| 658 | + will have a stronger color cover to indicate. | ||
| 659 | +- The video preview in the [SpecialPickerType.wechatMoment] is completely different from other previews. | ||
| 660 | +- Grid items have removed the fade builder for more straight feedback after it gets loaded. | ||
| 661 | +- Better interaction when jumping between previewing assets. | ||
| 662 | +- Path entities list layout structure performance & structure improved. | ||
| 663 | +- More precise thumbnail option for iOS. | ||
| 664 | +- Improve text scale handling. (#177) | ||
| 665 | +- Reduce font size for a couple of texts. | ||
| 666 | + | ||
| 667 | +To know more about breaking changes, see [Migration Guide][]. | ||
| 668 | + | ||
| 669 | +## 5.5.8 | ||
| 670 | + | ||
| 671 | +- Fix the viewer's select button issue with WeChat Moment on Android. | ||
| 672 | + | ||
| 673 | +## 5.5.7 | ||
| 674 | + | ||
| 675 | +- Make `switchPath` method in `AssetPickerProvider` async. | ||
| 676 | + | ||
| 677 | +## 5.5.6 | ||
| 678 | + | ||
| 679 | +- Add Japanese language text delegate. (Thanks to @KosukeSaigusa) | ||
| 680 | +- Fix video judge condition with WeChat Moment mode. | ||
| 681 | +- Fix the wrong position for the confirm button on iOS with WeChat Moment mode. | ||
| 682 | + | ||
| 683 | +## 5.5.5 | ||
| 684 | + | ||
| 685 | +- Migrate permissions check to the new API in `photo_manager`. | ||
| 686 | + | ||
| 687 | +## 5.5.4 | ||
| 688 | + | ||
| 689 | +- Fix assets reduced under the WeChat Moment mode when previewing. | ||
| 690 | + | ||
| 691 | +## 5.5.3+1 | ||
| 692 | + | ||
| 693 | +- Fix static analysis issue. | ||
| 694 | + | ||
| 695 | +## 5.5.3 | ||
| 696 | + | ||
| 697 | +- Use `SystemUiOverlayStyle` from the provided theme first. | ||
| 698 | + | ||
| 699 | +## 5.5.2 | ||
| 700 | + | ||
| 701 | +- Add German language text delegate. (Thanks to @Letalus) | ||
| 702 | +- Add Russian language text delegate. (Thanks to @greymag) | ||
| 703 | + | ||
| 704 | +## 5.5.1 | ||
| 705 | + | ||
| 706 | +- Implement `RenderToggleable` to support other channels of flutter (2.1.x - 2.3.x). (Thanks to @Letalus) | ||
| 707 | + | ||
| 708 | +## 5.5.0 | ||
| 709 | + | ||
| 710 | +- Add `findChildIndexBuilder` to indicate grid find reusable `RenderObject`. | ||
| 711 | +- Fix the padding issue for the assets' grid. | ||
| 712 | + | ||
| 713 | +## 5.4.3 | ||
| 714 | + | ||
| 715 | +- Fix the missing `ScrollController` in the scroll view. | ||
| 716 | + | ||
| 717 | +## 5.4.2 | ||
| 718 | + | ||
| 719 | +- Split `AssetGridItemBuidler` to solve the rebuild issue. | ||
| 720 | +- Fix the GIF indicator stretched issue. | ||
| 721 | + | ||
| 722 | +## 5.4.1 | ||
| 723 | + | ||
| 724 | +- Export `AssetPickerPageRoute`. | ||
| 725 | + | ||
| 726 | +## 5.4.0+1 | ||
| 727 | + | ||
| 728 | +- Fix the format that pub.dev suggests. | ||
| 729 | + | ||
| 730 | +## 5.4.0 | ||
| 731 | + | ||
| 732 | +- Fully support RTL languages. | ||
| 733 | +- Add control for root navigator. | ||
| 734 | +- Improve `AssetEntityImageProvider`'s constructor and decode. | ||
| 735 | +- Grab the iOS/macOS thumbnail's size fix from `photo_manager`. | ||
| 736 | + | ||
| 737 | +## 5.3.0 | ||
| 738 | + | ||
| 739 | +- Add `gridThumbSize` to control thumbnails in the select grid. | ||
| 740 | +- Applies a further fix to the WeChat Moment video preview. | ||
| 741 | +- Fix unlimited assets choose in preview mode. | ||
| 742 | + | ||
| 743 | +## 5.2.1 | ||
| 744 | + | ||
| 745 | +- Fix the WeChat Moment preview issue. | ||
| 746 | + | ||
| 747 | +## 5.2.0 | ||
| 748 | + | ||
| 749 | +- Add `SpecialPickerType.noPreview` to disable the preview when picking. (Thanks to @yanivshaked) | ||
| 750 | + | ||
| 751 | +## 5.1.4 | ||
| 752 | + | ||
| 753 | +- Add Hebrew language text delegate. (Thanks to @yanivshaked) | ||
| 754 | +- Fix the slide page route issue when integrated with the `get` package. | ||
| 755 | + | ||
| 756 | +## 5.1.3 | ||
| 757 | + | ||
| 758 | +- Fix not synced issue when the picker is under single pick mode. | ||
| 759 | + | ||
| 760 | +## 5.1.2 | ||
| 761 | + | ||
| 762 | +- Fix selected assets not syncing between thumbnail preview mode and grid view. | ||
| 763 | +- Fix the wrong index displays in thumbnail preview mode. | ||
| 764 | +- Dependencies upgrade roll. | ||
| 765 | + | ||
| 766 | +## 5.1.1 | ||
| 767 | + | ||
| 768 | +- Integrate `lastModified` to sort path entities by default. | ||
| 769 | + | ||
| 770 | +## 5.1.0 | ||
| 771 | + | ||
| 772 | +- Reset to the top for the asset grid view after switching paths. | ||
| 773 | +- Add the ability to select assets in any position of the picker. | ||
| 774 | +- Implement mime type for image type judgment. | ||
| 775 | +- Fix the disappeared GIFs indicator. | ||
| 776 | + | ||
| 777 | +## 5.0.5 | ||
| 778 | + | ||
| 779 | +- Fix force cast null type issue with WeChat moment special pick type. | ||
| 780 | +- Improve the app bar's type definition. | ||
| 781 | + | ||
| 782 | +## 5.0.4 | ||
| 783 | + | ||
| 784 | +- Fix path thumb data's display issue. | ||
| 785 | +- Fix the default preview thumb size issue with the image preview builder. | ||
| 786 | + | ||
| 787 | +## 5.0.3 | ||
| 788 | + | ||
| 789 | +- Remove required annotation for selected assets. | ||
| 790 | + | ||
| 791 | +## 5.0.2 | ||
| 792 | + | ||
| 793 | +- Fix the wrong viewer provider state. | ||
| 794 | +- Enhance page stream controller sink close. | ||
| 795 | +- Fix `dartdoc` generate issue for pub. | ||
| 796 | + | ||
| 797 | +## 5.0.1 | ||
| 798 | + | ||
| 799 | +- Fix the video indicator layout issue. | ||
| 800 | +- Prevent video selection in WeChat moment mode for edge cases. | ||
| 801 | +- Pickup fixes from `photo_manager`. | ||
| 802 | + | ||
| 803 | +## 5.0.0 | ||
| 804 | + | ||
| 805 | +- Add the ability to show the special item when the device has no assets. | ||
| 806 | +- Allow users to build their own picker with custom asset types. (See example for custom delegate.) | ||
| 807 | +- Slightly reduce performance consumption with layout. | ||
| 808 | + | ||
| 809 | +**Breaking changes** | ||
| 810 | + | ||
| 811 | +- Migrate to non-nullable by default. | ||
| 812 | +- `CustomItemBuilder` -> `SpecialItemBuilder`, `CustomItemPosition` -> `SpecialItemPosition`. | ||
| 813 | +- Abstract `AssetPickerBuilderDelegate<A, P>`, `AssetPickerViewerBuilderDelegate<A, P>`, | ||
| 814 | + `AssetPickerProvider<A, P>`, and minify the `AssetPickerViewerProvider<A>`. Support custom types by generic type. | ||
| 815 | +- The `assets` param in `AssetPickerViewer.pushToViewer` is now `previewAssets`. | ||
| 816 | + | ||
| 817 | +## 4.2.2 | ||
| 818 | + | ||
| 819 | +- Suppress deprecated usage for example. | ||
| 820 | +- Improve code format with dart format. | ||
| 821 | +- Raise the dependencies version. | ||
| 822 | + | ||
| 823 | +## 4.2.1 | ||
| 824 | + | ||
| 825 | +- Fix arguments judging condition with preview thumb size. | ||
| 826 | +- Remove common exports and split out constants. | ||
| 827 | + | ||
| 828 | +## 4.2.0 | ||
| 829 | + | ||
| 830 | +- Add `previewThumbSize` for the viewer. | ||
| 831 | + | ||
| 832 | +## 4.1.0+4 | ||
| 833 | + | ||
| 834 | +- Upgrade `extended_image`. | ||
| 835 | + | ||
| 836 | +## 4.1.0+3 | ||
| 837 | + | ||
| 838 | +- Make widgets constant. | ||
| 839 | +- Remove system UI overlays update. | ||
| 840 | +- Migrate files to compatible with Flutter `1.20.0`. | ||
| 841 | +- Sync analysis options. | ||
| 842 | + | ||
| 843 | +## 4.1.0+2 | ||
| 844 | + | ||
| 845 | +- Ignore size constraints for image assets. | ||
| 846 | +- Format code using `dartfmt`. | ||
| 847 | +- Upgrade `photo_manager`. | ||
| 848 | + | ||
| 849 | +## 4.1.0+1 | ||
| 850 | + | ||
| 851 | +- Adjust AppleOS layout. | ||
| 852 | + | ||
| 853 | +## 4.1.0 | ||
| 854 | + | ||
| 855 | +- Add a backdrop widget in the picker, which makes the picker more like the one in WeChat. | ||
| 856 | + | ||
| 857 | +## 4.0.0 | ||
| 858 | + | ||
| 859 | +- Drop `asset_audio_player`. | ||
| 860 | +- Experimenting status bar hidden on iOS. | ||
| 861 | +- Remove the video player listener before pausing. | ||
| 862 | + | ||
| 863 | +**Breaking changes** | ||
| 864 | + | ||
| 865 | +- `TextDelegate` -> `AssetsPickerTextDelegate`. | ||
| 866 | + | ||
| 867 | +## 3.0.0+1 | ||
| 868 | + | ||
| 869 | +- Constraint dependencies version. | ||
| 870 | + | ||
| 871 | +## 3.0.0 | ||
| 872 | + | ||
| 873 | +- Add `FilterOptionGroup`. (#41) | ||
| 874 | +- Add `SpecialPickerType`. (#37) | ||
| 875 | +- Add custom item build mode. (#39) | ||
| 876 | + | ||
| 877 | +## 2.2.1 | ||
| 878 | + | ||
| 879 | +- Introduce `ColorScheme` for theme details. (#32) | ||
| 880 | +- Enhance RTL compatibility. | ||
| 881 | +- Enlarge select indicator's size. (#33) | ||
| 882 | + | ||
| 883 | +## 2.2.0+2 | ||
| 884 | + | ||
| 885 | +- Remove path entity properties refresh. | ||
| 886 | + | ||
| 887 | +## 2.2.0+1 | ||
| 888 | + | ||
| 889 | +- Fix the preview widget for audio assets in the picker viewer. | ||
| 890 | + | ||
| 891 | +## 2.2.0 | ||
| 892 | + | ||
| 893 | +- A brand-new example. | ||
| 894 | +- Add `SortPathDelegate`. | ||
| 895 | +- Using `ZoomPageTransition` for viewers. | ||
| 896 | +- Slightly add padding to the viewer's assets list view. | ||
| 897 | +- Migrate elevation and color to material rendering. | ||
| 898 | +- Request thumb only when the request type is not audio. | ||
| 899 | +- Force request title for audio type asset. | ||
| 900 | +- Expose `AssetType` enum. | ||
| 901 | +- Fix the issue with the request type. | ||
| 902 | + | ||
| 903 | +## 2.1.0 | ||
| 904 | + | ||
| 905 | +- Add present English text delegate. | ||
| 906 | +- Refactored theme constructor and getter with theme capability. (#22) | ||
| 907 | +- Update color scheme usage for the assets grid. (#23) | ||
| 908 | +- Update picker viewer style for Apple OS. | ||
| 909 | +- Fix the bottom bar disappearing on Apple OS when it's single asset mode. | ||
| 910 | + | ||
| 911 | +## 2.0.2 | ||
| 912 | + | ||
| 913 | +- Fix audio paused accidentally when the app is launching on Android. (#18) | ||
| 914 | + | ||
| 915 | +## 2.0.1 | ||
| 916 | + | ||
| 917 | +- Expose observe register methods. | ||
| 918 | + | ||
| 919 | +## 2.0.0 | ||
| 920 | + | ||
| 921 | +- Support audio assets. | ||
| 922 | +- Support single asset mode. | ||
| 923 | +- Enlarge the preview button's detector area size. | ||
| 924 | +- Fix wrong properties' usage causing infinite build when the page reaches the end. | ||
| 925 | + | ||
| 926 | +**Breaking changes** | ||
| 927 | + | ||
| 928 | +- `videoIndicatorBuilder` -> `durationIndicatorBuilder`. | ||
| 929 | + | ||
| 930 | +## 1.7.0 | ||
| 931 | + | ||
| 932 | +- Hide detail display when the video starts to play. | ||
| 933 | +- Switch to `ExtendedImageGesturePageView`. (#16) | ||
| 934 | +- Add full theme support. | ||
| 935 | +- Add macOS support. | ||
| 936 | +- Add delay for the first init method to prevent stuck in page routing. (#13) | ||
| 937 | +- Update widgets style on iOS. (#14) | ||
| 938 | +- Fix the state of the example not updated after the result was returned without the input method activated. | ||
| 939 | + | ||
| 940 | +## 1.6.0 | ||
| 941 | + | ||
| 942 | +- Support HEIC/HEIF image type. | ||
| 943 | + | ||
| 944 | +## 1.5.0+1 | ||
| 945 | + | ||
| 946 | +- Upgrade `photo_manager` to `0.5.1`. | ||
| 947 | +- Replace deprecate `TextTheme.title` API usage. | ||
| 948 | +- Document (`dartdoc`) update. | ||
| 949 | + | ||
| 950 | +## 1.5.0 | ||
| 951 | + | ||
| 952 | +- Bumping flutter SDK minimum version to `1.17.0`. | ||
| 953 | +- Declare API stability and compatibility with 1.0.0 | ||
| 954 | + ( more details at: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 ). | ||
| 955 | + | ||
| 956 | +## 1.4.1 | ||
| 957 | + | ||
| 958 | +- Remove the loading indicator for the image widget. | ||
| 959 | +- Refactor the video page's initialization for ratio update. | ||
| 960 | +- Using constants to store text delegate. | ||
| 961 | +- Add error catching for main methods. | ||
| 962 | +- Update text delegate management. | ||
| 963 | + | ||
| 964 | +## 1.4.0+1 | ||
| 965 | + | ||
| 966 | +- Fix call on null with `currentlySelectedAssets`. | ||
| 967 | + | ||
| 968 | +## 1.4.0 | ||
| 969 | + | ||
| 970 | +- Support paging assets load. | ||
| 971 | +- Fix selected assets not synced with the picker provider. | ||
| 972 | +- Bump `photo_manager` to `0.5.1-dev.5` | ||
| 973 | + | ||
| 974 | +## 1.3.2 | ||
| 975 | + | ||
| 976 | +- Expose page transition curve and duration to a static method. | ||
| 977 | +- Fix theme color not passed to a static method. | ||
| 978 | + | ||
| 979 | +## 1.3.1+1 | ||
| 980 | + | ||
| 981 | +- Fix the `pageBuilder` null issue. | ||
| 982 | + | ||
| 983 | +## 1.3.1 | ||
| 984 | + | ||
| 985 | +- Add upwards slide page transition. | ||
| 986 | +- Add padding to the bottom action bar in the picker. | ||
| 987 | + | ||
| 988 | +## 1.3.0 | ||
| 989 | + | ||
| 990 | +- Add iOS style. | ||
| 991 | +- Add cancel field to text delegate. | ||
| 992 | +- `Set` -> `List`. | ||
| 993 | + | ||
| 994 | +## 1.2.1 | ||
| 995 | + | ||
| 996 | +- Fix the missing aspect ratio for the video player. | ||
| 997 | +- Using common request type in example. | ||
| 998 | + | ||
| 999 | +## 1.2.0 | ||
| 1000 | + | ||
| 1001 | +- Add text delegate support. (Also with i18n support using delegate). | ||
| 1002 | + | ||
| 1003 | +## 1.1.0 | ||
| 1004 | + | ||
| 1005 | +- Support video assets. You can use `requestType` to select video or video+image. | ||
| 1006 | +- Hide system ui overlays according to flag and system. | ||
| 1007 | +- Update the GIF indicator and add a video indicator. | ||
| 1008 | + | ||
| 1009 | +## 1.0.0 | ||
| 1010 | + | ||
| 1011 | +- Initial release. | ||
| 1012 | + | ||
| 1013 | +[Migration Guide]: guides/migration_guide.md |
| 1 | +* @AlexV525 @LeGoffMael |
library/wechat_assets_picker-9.8.0/LICENSE
0 → 100644
| 1 | + Apache License | ||
| 2 | + Version 2.0, January 2004 | ||
| 3 | + http://www.apache.org/licenses/ | ||
| 4 | + | ||
| 5 | + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
| 6 | + | ||
| 7 | + 1. Definitions. | ||
| 8 | + | ||
| 9 | + "License" shall mean the terms and conditions for use, reproduction, | ||
| 10 | + and distribution as defined by Sections 1 through 9 of this document. | ||
| 11 | + | ||
| 12 | + "Licensor" shall mean the copyright owner or entity authorized by | ||
| 13 | + the copyright owner that is granting the License. | ||
| 14 | + | ||
| 15 | + "Legal Entity" shall mean the union of the acting entity and all | ||
| 16 | + other entities that control, are controlled by, or are under common | ||
| 17 | + control with that entity. For the purposes of this definition, | ||
| 18 | + "control" means (i) the power, direct or indirect, to cause the | ||
| 19 | + direction or management of such entity, whether by contract or | ||
| 20 | + otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
| 21 | + outstanding shares, or (iii) beneficial ownership of such entity. | ||
| 22 | + | ||
| 23 | + "You" (or "Your") shall mean an individual or Legal Entity | ||
| 24 | + exercising permissions granted by this License. | ||
| 25 | + | ||
| 26 | + "Source" form shall mean the preferred form for making modifications, | ||
| 27 | + including but not limited to software source code, documentation | ||
| 28 | + source, and configuration files. | ||
| 29 | + | ||
| 30 | + "Object" form shall mean any form resulting from mechanical | ||
| 31 | + transformation or translation of a Source form, including but | ||
| 32 | + not limited to compiled object code, generated documentation, | ||
| 33 | + and conversions to other media types. | ||
| 34 | + | ||
| 35 | + "Work" shall mean the work of authorship, whether in Source or | ||
| 36 | + Object form, made available under the License, as indicated by a | ||
| 37 | + copyright notice that is included in or attached to the work | ||
| 38 | + (an example is provided in the Appendix below). | ||
| 39 | + | ||
| 40 | + "Derivative Works" shall mean any work, whether in Source or Object | ||
| 41 | + form, that is based on (or derived from) the Work and for which the | ||
| 42 | + editorial revisions, annotations, elaborations, or other modifications | ||
| 43 | + represent, as a whole, an original work of authorship. For the purposes | ||
| 44 | + of this License, Derivative Works shall not include works that remain | ||
| 45 | + separable from, or merely link (or bind by name) to the interfaces of, | ||
| 46 | + the Work and Derivative Works thereof. | ||
| 47 | + | ||
| 48 | + "Contribution" shall mean any work of authorship, including | ||
| 49 | + the original version of the Work and any modifications or additions | ||
| 50 | + to that Work or Derivative Works thereof, that is intentionally | ||
| 51 | + submitted to Licensor for inclusion in the Work by the copyright owner | ||
| 52 | + or by an individual or Legal Entity authorized to submit on behalf of | ||
| 53 | + the copyright owner. For the purposes of this definition, "submitted" | ||
| 54 | + means any form of electronic, verbal, or written communication sent | ||
| 55 | + to the Licensor or its representatives, including but not limited to | ||
| 56 | + communication on electronic mailing lists, source code control systems, | ||
| 57 | + and issue tracking systems that are managed by, or on behalf of, the | ||
| 58 | + Licensor for the purpose of discussing and improving the Work, but | ||
| 59 | + excluding communication that is conspicuously marked or otherwise | ||
| 60 | + designated in writing by the copyright owner as "Not a Contribution." | ||
| 61 | + | ||
| 62 | + "Contributor" shall mean Licensor and any individual or Legal Entity | ||
| 63 | + on behalf of whom a Contribution has been received by Licensor and | ||
| 64 | + subsequently incorporated within the Work. | ||
| 65 | + | ||
| 66 | + 2. Grant of Copyright License. Subject to the terms and conditions of | ||
| 67 | + this License, each Contributor hereby grants to You a perpetual, | ||
| 68 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| 69 | + copyright license to reproduce, prepare Derivative Works of, | ||
| 70 | + publicly display, publicly perform, sublicense, and distribute the | ||
| 71 | + Work and such Derivative Works in Source or Object form. | ||
| 72 | + | ||
| 73 | + 3. Grant of Patent License. Subject to the terms and conditions of | ||
| 74 | + this License, each Contributor hereby grants to You a perpetual, | ||
| 75 | + worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
| 76 | + (except as stated in this section) patent license to make, have made, | ||
| 77 | + use, offer to sell, sell, import, and otherwise transfer the Work, | ||
| 78 | + where such license applies only to those patent claims licensable | ||
| 79 | + by such Contributor that are necessarily infringed by their | ||
| 80 | + Contribution(s) alone or by combination of their Contribution(s) | ||
| 81 | + with the Work to which such Contribution(s) was submitted. If You | ||
| 82 | + institute patent litigation against any entity (including a | ||
| 83 | + cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
| 84 | + or a Contribution incorporated within the Work constitutes direct | ||
| 85 | + or contributory patent infringement, then any patent licenses | ||
| 86 | + granted to You under this License for that Work shall terminate | ||
| 87 | + as of the date such litigation is filed. | ||
| 88 | + | ||
| 89 | + 4. Redistribution. You may reproduce and distribute copies of the | ||
| 90 | + Work or Derivative Works thereof in any medium, with or without | ||
| 91 | + modifications, and in Source or Object form, provided that You | ||
| 92 | + meet the following conditions: | ||
| 93 | + | ||
| 94 | + (a) You must give any other recipients of the Work or | ||
| 95 | + Derivative Works a copy of this License; and | ||
| 96 | + | ||
| 97 | + (b) You must cause any modified files to carry prominent notices | ||
| 98 | + stating that You changed the files; and | ||
| 99 | + | ||
| 100 | + (c) You must retain, in the Source form of any Derivative Works | ||
| 101 | + that You distribute, all copyright, patent, trademark, and | ||
| 102 | + attribution notices from the Source form of the Work, | ||
| 103 | + excluding those notices that do not pertain to any part of | ||
| 104 | + the Derivative Works; and | ||
| 105 | + | ||
| 106 | + (d) If the Work includes a "NOTICE" text file as part of its | ||
| 107 | + distribution, then any Derivative Works that You distribute must | ||
| 108 | + include a readable copy of the attribution notices contained | ||
| 109 | + within such NOTICE file, excluding those notices that do not | ||
| 110 | + pertain to any part of the Derivative Works, in at least one | ||
| 111 | + of the following places: within a NOTICE text file distributed | ||
| 112 | + as part of the Derivative Works; within the Source form or | ||
| 113 | + documentation, if provided along with the Derivative Works; or, | ||
| 114 | + within a display generated by the Derivative Works, if and | ||
| 115 | + wherever such third-party notices normally appear. The contents | ||
| 116 | + of the NOTICE file are for informational purposes only and | ||
| 117 | + do not modify the License. You may add Your own attribution | ||
| 118 | + notices within Derivative Works that You distribute, alongside | ||
| 119 | + or as an addendum to the NOTICE text from the Work, provided | ||
| 120 | + that such additional attribution notices cannot be construed | ||
| 121 | + as modifying the License. | ||
| 122 | + | ||
| 123 | + You may add Your own copyright statement to Your modifications and | ||
| 124 | + may provide additional or different license terms and conditions | ||
| 125 | + for use, reproduction, or distribution of Your modifications, or | ||
| 126 | + for any such Derivative Works as a whole, provided Your use, | ||
| 127 | + reproduction, and distribution of the Work otherwise complies with | ||
| 128 | + the conditions stated in this License. | ||
| 129 | + | ||
| 130 | + 5. Submission of Contributions. Unless You explicitly state otherwise, | ||
| 131 | + any Contribution intentionally submitted for inclusion in the Work | ||
| 132 | + by You to the Licensor shall be under the terms and conditions of | ||
| 133 | + this License, without any additional terms or conditions. | ||
| 134 | + Notwithstanding the above, nothing herein shall supersede or modify | ||
| 135 | + the terms of any separate license agreement you may have executed | ||
| 136 | + with Licensor regarding such Contributions. | ||
| 137 | + | ||
| 138 | + 6. Trademarks. This License does not grant permission to use the trade | ||
| 139 | + names, trademarks, service marks, or product names of the Licensor, | ||
| 140 | + except as required for reasonable and customary use in describing the | ||
| 141 | + origin of the Work and reproducing the content of the NOTICE file. | ||
| 142 | + | ||
| 143 | + 7. Disclaimer of Warranty. Unless required by applicable law or | ||
| 144 | + agreed to in writing, Licensor provides the Work (and each | ||
| 145 | + Contributor provides its Contributions) on an "AS IS" BASIS, | ||
| 146 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
| 147 | + implied, including, without limitation, any warranties or conditions | ||
| 148 | + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
| 149 | + PARTICULAR PURPOSE. You are solely responsible for determining the | ||
| 150 | + appropriateness of using or redistributing the Work and assume any | ||
| 151 | + risks associated with Your exercise of permissions under this License. | ||
| 152 | + | ||
| 153 | + 8. Limitation of Liability. In no event and under no legal theory, | ||
| 154 | + whether in tort (including negligence), contract, or otherwise, | ||
| 155 | + unless required by applicable law (such as deliberate and grossly | ||
| 156 | + negligent acts) or agreed to in writing, shall any Contributor be | ||
| 157 | + liable to You for damages, including any direct, indirect, special, | ||
| 158 | + incidental, or consequential damages of any character arising as a | ||
| 159 | + result of this License or out of the use or inability to use the | ||
| 160 | + Work (including but not limited to damages for loss of goodwill, | ||
| 161 | + work stoppage, computer failure or malfunction, or any and all | ||
| 162 | + other commercial damages or losses), even if such Contributor | ||
| 163 | + has been advised of the possibility of such damages. | ||
| 164 | + | ||
| 165 | + 9. Accepting Warranty or Additional Liability. While redistributing | ||
| 166 | + the Work or Derivative Works thereof, You may choose to offer, | ||
| 167 | + and charge a fee for, acceptance of support, warranty, indemnity, | ||
| 168 | + or other liability obligations and/or rights consistent with this | ||
| 169 | + License. However, in accepting such obligations, You may act only | ||
| 170 | + on Your own behalf and on Your sole responsibility, not on behalf | ||
| 171 | + of any other Contributor, and only if You agree to indemnify, | ||
| 172 | + defend, and hold each Contributor harmless for any liability | ||
| 173 | + incurred by, or claims asserted against, such Contributor by reason | ||
| 174 | + of your accepting any such warranty or additional liability. | ||
| 175 | + | ||
| 176 | + END OF TERMS AND CONDITIONS | ||
| 177 | + | ||
| 178 | + APPENDIX: How to apply the Apache License to your work. | ||
| 179 | + | ||
| 180 | + To apply the Apache License to your work, attach the following | ||
| 181 | + boilerplate notice, with the fields enclosed by brackets "[]" | ||
| 182 | + replaced with your own identifying information. (Don't include | ||
| 183 | + the brackets!) The text should be enclosed in the appropriate | ||
| 184 | + comment syntax for the file format. We also recommend that a | ||
| 185 | + file or class name and description of purpose be included on the | ||
| 186 | + same "printed page" as the copyright notice for easier | ||
| 187 | + identification within third-party archives. | ||
| 188 | + | ||
| 189 | + Copyright [2019] [FlutterCandies] | ||
| 190 | + | ||
| 191 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 192 | + you may not use this file except in compliance with the License. | ||
| 193 | + You may obtain a copy of the License at | ||
| 194 | + | ||
| 195 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
| 196 | + | ||
| 197 | + Unless required by applicable law or agreed to in writing, software | ||
| 198 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
| 199 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 200 | + See the License for the specific language governing permissions and | ||
| 201 | + limitations under the License. |
| 1 | +<!-- Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +Use of this source code is governed by an Apache license | ||
| 3 | +that can be found in the LICENSE file. --> | ||
| 4 | + | ||
| 5 | +# Flutter WeChat Assets Picker | ||
| 6 | + | ||
| 7 | +[](https://pub.flutter-io.cn/packages/wechat_assets_picker) | ||
| 8 | +[](https://pub.flutter-io.cn/packages/wechat_assets_picker) | ||
| 9 | +[](https://www.codefactor.io/repository/github/fluttercandies/flutter_wechat_assets_picker) | ||
| 10 | + | ||
| 11 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/actions/workflows/runnable.yml) | ||
| 12 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/LICENSE) | ||
| 13 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/stargazers) | ||
| 14 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/network) | ||
| 15 | + | ||
| 16 | +[](https://github.com/Solido/awesome-flutter) | ||
| 17 | +<a href="https://qm.qq.com/q/ZyJbSVjfSU"><img src="https://img.shields.io/badge/dynamic/yaml?url=https%3A%2F%2Fraw.githubusercontent.com%2Ffluttercandies%2F.github%2Frefs%2Fheads%2Fmain%2Fdata.yml&query=%24.qq_group_number&label=QQ%E7%BE%A4&logo=qq&style=flat&color=1DACE8" /></a> | ||
| 18 | + | ||
| 19 | +Language: [English](README.md) | 中文 | ||
| 20 | + | ||
| 21 | +基于 **微信 UI** 的 Flutter **图片选择器(同时支持视频和音频)**。 | ||
| 22 | + | ||
| 23 | +当前的界面设计基于的微信版本:**8.0.51** | ||
| 24 | +界面更新将在微信版本更新后随时进行跟进。 | ||
| 25 | + | ||
| 26 | +如果你需要拍照及录制视频,请先查看示例的详细用法, | ||
| 27 | +并前往 [wechat_camera_picker][wechat_camera_picker pub]。 | ||
| 28 | +该插件是独立扩展,需要结合使用。 | ||
| 29 | + | ||
| 30 | +查看 [迁移指南][] 了解如何从破坏性改动中迁移为可用代码。 | ||
| 31 | + | ||
| 32 | +## 版本兼容 | ||
| 33 | + | ||
| 34 | +该插件仅保证能与 **stable 渠道的 Flutter SDK** 配合使用。 | ||
| 35 | +我们不会为其他渠道的 Flutter SDK 做实时支持。 | ||
| 36 | + | ||
| 37 | +| | 3.7 | 3.10 | 3.13 | 3.16 | 3.22 | | ||
| 38 | +|--------|:---:|:----:|:----:|:----:|:----:| | ||
| 39 | +| 9.5.0+ | ❌ | ❌ | ❌ | ❌ | ✅ | | ||
| 40 | +| 8.9.0+ | ❌ | ❌ | ❌ | ✅ | ❌ | | ||
| 41 | +| 8.7.0+ | ❌ | ❌ | ✅ | ❌ | ❌ | | ||
| 42 | +| 8.5.0+ | ❌ | ✅ | ❌ | ❌ | ❌ | | ||
| 43 | +| 8.4.0+ | ✅ | ❌ | ❌ | ❌ | ❌ | | ||
| 44 | + | ||
| 45 | +如果在 `flutter pub get` 时遇到了 `resolve conflict` 失败问题, | ||
| 46 | +请使用 `dependency_overrides` 解决。 | ||
| 47 | + | ||
| 48 | +## 主要使用的 package | ||
| 49 | + | ||
| 50 | +该插件基于这些优秀的 package 构建: | ||
| 51 | + | ||
| 52 | +| Name | Features | | ||
| 53 | +|:-------------------------------------|:--------------| | ||
| 54 | +| [photo_manager][photo_manager pub] | 资源的基础抽象和管理。 | | ||
| 55 | +| [extended_image][extended_image pub] | 以熟悉的操作预览所有资源。 | | ||
| 56 | +| [provider][provider pub] | 协助选择器管理器内部状态。 | | ||
| 57 | +| [video_player][video_player pub] | 播放对应的视频和音频。 | | ||
| 58 | + | ||
| 59 | +这些 package 在该插件中的实现已相对稳定。 | ||
| 60 | +如果你在使用中发现于它们相关的问题, | ||
| 61 | +请先在本插件的问题跟踪中报告相关问题。 | ||
| 62 | + | ||
| 63 | +<details> | ||
| 64 | + <summary>目录列表</summary> | ||
| 65 | + | ||
| 66 | +<!-- TOC --> | ||
| 67 | +* [Flutter WeChat Assets Picker](#flutter-wechat-assets-picker) | ||
| 68 | + * [版本兼容](#版本兼容) | ||
| 69 | + * [主要使用的 package](#主要使用的-package) | ||
| 70 | + * [特性 ✨](#特性-) | ||
| 71 | + * [特别提醒 📝](#特别提醒-) | ||
| 72 | + * [项目展柜 🖼️](#项目展柜-) | ||
| 73 | + * [截图 📸](#截图-) | ||
| 74 | + * [开始前的注意事项 ‼️](#开始前的注意事项-) | ||
| 75 | + * [准备工作 🍭](#准备工作-) | ||
| 76 | + * [Flutter](#flutter) | ||
| 77 | + * [Android](#android) | ||
| 78 | + * [权限](#权限) | ||
| 79 | + * [iOS](#ios) | ||
| 80 | + * [macOS](#macos) | ||
| 81 | + * [使用方法 📖](#使用方法-) | ||
| 82 | + * [国际化](#国际化) | ||
| 83 | + * [简单的使用方法](#简单的使用方法) | ||
| 84 | + * [更详细的使用方法](#更详细的使用方法) | ||
| 85 | + * [展示选中的资源](#展示选中的资源) | ||
| 86 | + * [注册资源变化回调](#注册资源变化回调) | ||
| 87 | + * [在表单数据中上传 `AssetEntity`](#在表单数据中上传-assetentity) | ||
| 88 | + * [使用 `http`](#使用-http) | ||
| 89 | + * [使用 `dio`](#使用-dio) | ||
| 90 | + * [自定义选择器](#自定义选择器) | ||
| 91 | + * [常见问题 ❔](#常见问题-) | ||
| 92 | + * [修改默认相册名称(将 `Recent` 改为其他)](#修改默认相册名称将-recent-改为其他) | ||
| 93 | + * [Execution failed for task ':photo_manager:compileDebugKotlin'](#execution-failed-for-task-photo_managercompiledebugkotlin) | ||
| 94 | + * [从 `File` 或 `Uint8List` 创建 `AssetEntity` 的方法](#从-file-或-uint8list-创建-assetentity-的方法) | ||
| 95 | + * [控制台提示 'Failed to find GeneratedAppGlideModule'](#控制台提示-failed-to-find-generatedappglidemodule) | ||
| 96 | + * [致谢](#致谢) | ||
| 97 | +<!-- TOC --> | ||
| 98 | +</details> | ||
| 99 | + | ||
| 100 | +## 特性 ✨ | ||
| 101 | + | ||
| 102 | +- ♿ 完整的无障碍支持,包括 **TalkBack** 和 **VoiceOver** | ||
| 103 | +- ♻️ 支持基于代理重载的全量自定义 | ||
| 104 | +- 🎏 完全可自定义的基于 `ThemeData` 的主题 | ||
| 105 | +- 💚 复刻微信风格(甚至优化了更多的细节) | ||
| 106 | +- ⚡️ 根据配置调节的性能优化 | ||
| 107 | +- 📷 图片资源支持 | ||
| 108 | + - 🔬 HEIF 格式图片支持 <a href="#特别提醒-"><sup>(1)</sup></a> | ||
| 109 | +- 🎥 视频资源支持 | ||
| 110 | +- 🎶 音频资源支持 <a href="#notes-"><sup>(2)</sup></a> | ||
| 111 | +- 1️⃣ 单选模式模式 | ||
| 112 | +- 💱 国际化 (i18n) 支持 | ||
| 113 | + - ⏪ RTL 语言支持 | ||
| 114 | +- ➕ 特殊 widget 构建支持 | ||
| 115 | +- 🗂 自定义路径排序支持 | ||
| 116 | +- 📝 自定义文本构建支持 | ||
| 117 | +- ⏳ 自定义筛选规则支持 | ||
| 118 | +- 💻 支持 MacOS | ||
| 119 | + | ||
| 120 | +### 特别提醒 📝 | ||
| 121 | + | ||
| 122 | +1. HEIF (HEIC) 图片支持获取和转换,但是它们的显示依托于 Flutter 的图片解析。 | ||
| 123 | + 在此 issue 中 [flutter/flutter#20522](https://github.com/flutter/flutter/issues/20522) 有所说明。 | ||
| 124 | + 若要用于显示,请使用 `entity.file` 或 `AssetEntityImage` 进行处理。 | ||
| 125 | +2. 由于 iOS 和 macOS 的系统限制,在获取音频时只能获取应用沙盒环境内的音频。 | ||
| 126 | + | ||
| 127 | +## 项目展柜 🖼️ | ||
| 128 | + | ||
| 129 | +| name | pub | github | | ||
| 130 | +|:--------------------|:---------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| | ||
| 131 | +| insta_assets_picker | [](https://pub.flutter-io.cn/packages/insta_assets_picker) | [](https://github.com/LeGoffMael/insta_assets_picker) | | ||
| 132 | + | ||
| 133 | +## 截图 📸 | ||
| 134 | + | ||
| 135 | +|  |  |  | | ||
| 136 | +|-----------------------------------|-----------------------------------|-----------------------------------| | ||
| 137 | +|  |  |  | | ||
| 138 | +|  |  |  | | ||
| 139 | +|  |  |  | | ||
| 140 | + | ||
| 141 | +## 开始前的注意事项 ‼️ | ||
| 142 | + | ||
| 143 | +在开始一切之前,请明确以下两点: | ||
| 144 | +- 由于理解差异和篇幅限制,并不是所有的内容都会明确地在文档中指出。 | ||
| 145 | + 当你遇到没有找到需求和无法理解的概念时,请先运行项目的示例 example, | ||
| 146 | + 它可以解决 90% 的常见需求。 | ||
| 147 | +- 该库与 [photo_manager][photo_manager pub] 有强关联性, | ||
| 148 | + 大部分方法的行为是由 photo_manager 进行控制的, | ||
| 149 | + 所以请尽可能地确保你了解以下两个类的概念: | ||
| 150 | + - 资源(图片/视频/音频) [`AssetEntity`](https://pub.flutter-io.cn/documentation/photo_manager/latest/photo_manager/AssetEntity-class.html) | ||
| 151 | + - 资源合集(相册或集合概念) [`AssetPathEntity`](https://pub.flutter-io.cn/documentation/photo_manager/latest/photo_manager/AssetPathEntity-class.html) | ||
| 152 | + | ||
| 153 | +当你有与相关的 API 和行为的疑问时,你可以查看 | ||
| 154 | +[photo_manager API 文档][] 了解更多细节。 | ||
| 155 | + | ||
| 156 | +众多使用场景都已包含在示例中。 | ||
| 157 | +在你提出任何问题之前,请仔细并完整地查看和使用示例。 | ||
| 158 | + | ||
| 159 | +## 准备工作 🍭 | ||
| 160 | + | ||
| 161 | +### Flutter | ||
| 162 | + | ||
| 163 | +执行 `flutter pub add wechat_assets_picker`, | ||
| 164 | +或者将 `wechat_assets_picker` 手动添加至 `pubspec.yaml` 引用。 | ||
| 165 | + | ||
| 166 | +```yaml | ||
| 167 | +dependencies: | ||
| 168 | + wechat_assets_picker: ^latest_version | ||
| 169 | +``` | ||
| 170 | + | ||
| 171 | +最新的 **稳定** 版本是: | ||
| 172 | +[](https://pub.flutter-io.cn/packages/wechat_assets_picker) | ||
| 173 | + | ||
| 174 | +最新的 **开发** 版本是: | ||
| 175 | +[](https://pub.flutter-io.cn/packages/wechat_assets_picker) | ||
| 176 | + | ||
| 177 | +在你的代码中导入: | ||
| 178 | + | ||
| 179 | +```dart | ||
| 180 | +import 'package:wechat_assets_picker/wechat_assets_picker.dart'; | ||
| 181 | +``` | ||
| 182 | + | ||
| 183 | +### Android | ||
| 184 | + | ||
| 185 | +在使用这个 package 时,请确保 | ||
| 186 | +`compileSdkVersion` 和 `targetSdkVersion` 升级到 `33`。 | ||
| 187 | +否则,在 Android 13 设备上将有可能无法加载任何资源。 | ||
| 188 | + | ||
| 189 | +#### 权限 | ||
| 190 | + | ||
| 191 | +| Name | 必需 | 已声明 | 最高 API 版本 | 其他 | | ||
| 192 | +|--------------------------|-----|-----|-----------|-------------| | ||
| 193 | +| `READ_EXTERNAL_STORAGE` | 是 | 是 | 32 | | | ||
| 194 | +| `WRITE_EXTERNAL_STORAGE` | 否 | 否 | 29 | | | ||
| 195 | +| `ACCESS_MEDIA_LOCATION` | 是* | 否 | N/A | 读取 EXIF 时必需 | | ||
| 196 | +| `READ_MEDIA_IMAGES` | 是* | 是 | N/A | 读取图片时必需 | | ||
| 197 | +| `READ_MEDIA_VIDEO` | 是* | 是 | N/A | 读取视频时必需 | | ||
| 198 | +| `READ_MEDIA_AUDIO` | 是* | 是 | N/A | 读取音频时必需 | | ||
| 199 | + | ||
| 200 | +如果你的目标 SDK 版本大于 33,且你不需要获取图片、视频或者音频, | ||
| 201 | +你可以考虑只声明需要的权限,具体如下: | ||
| 202 | + | ||
| 203 | +```xml | ||
| 204 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 205 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 206 | + package="com.your.app"> | ||
| 207 | + <!--请求图片和视频权限--> | ||
| 208 | + <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> | ||
| 209 | + <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> | ||
| 210 | + <!--如果不需要获取音频,移除或者注释 READ_MEDIA_AUDIO--> | ||
| 211 | + <!--<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />--> | ||
| 212 | +</manifest> | ||
| 213 | +``` | ||
| 214 | + | ||
| 215 | +### iOS | ||
| 216 | + | ||
| 217 | +1. 在 `ios/Podfile` 中指定最低构建版本至 **11.0**。 | ||
| 218 | + ```ruby | ||
| 219 | + platform :ios, '11.0' | ||
| 220 | + ``` | ||
| 221 | + 如果该行以 `#` (注释) 开头,请把 `#` 删除。 | ||
| 222 | +2. 将以下内容添加至 `Info.plist`。 | ||
| 223 | +``` | ||
| 224 | +<key>NSPhotoLibraryUsageDescription</key> | ||
| 225 | +<string>你的相册权限描述</string> | ||
| 226 | +``` | ||
| 227 | + | ||
| 228 | +### macOS | ||
| 229 | + | ||
| 230 | +1. 在 `macos/Podfile` 中指定最低构建版本至 **10.15**。 | ||
| 231 | + ```Podfile | ||
| 232 | + platform :osx, '10.15' | ||
| 233 | + ``` | ||
| 234 | + 如果该行以 `#` (注释) 开头,请把 `#` 删除。 | ||
| 235 | +2. 使用 **Xcode** 打开 `macos/Runner.xcworkspace`。 | ||
| 236 | + 接着将 macOS 的最低构建版本提升至 **10.15**。 | ||
| 237 | +3. 与 [iOS](#iOS) 一样,添加相同的内容到 `Info.plist` 里。 | ||
| 238 | + | ||
| 239 | +## 使用方法 📖 | ||
| 240 | + | ||
| 241 | +### 国际化 | ||
| 242 | + | ||
| 243 | +当你在选择资源的时候,package 会通过你的 `BuildContext` | ||
| 244 | +读取 `Locale?`,返回对应语言的文字代理实现。 | ||
| 245 | +请确保你可以通过 `BuildContext` 获取到 `Locale`,否则将会 **默认展示中文文字**。 | ||
| 246 | + | ||
| 247 | +内置的语言文字实现有: | ||
| 248 | +* 简体中文 (默认) | ||
| 249 | +* English | ||
| 250 | +* העברית | ||
| 251 | +* Deutsche | ||
| 252 | +* Локализация | ||
| 253 | +* 日本語 | ||
| 254 | +* مة العربية | ||
| 255 | +* Délégué | ||
| 256 | +* Tiếng Việt | ||
| 257 | +* Türkçe Yerelleştirme | ||
| 258 | + | ||
| 259 | +如果你想使用自定义或固定的文字实现,请通过 | ||
| 260 | +`AssetPickerConfig.textDelegate` 传递调用。 | ||
| 261 | + | ||
| 262 | +### 简单的使用方法 | ||
| 263 | + | ||
| 264 | +```dart | ||
| 265 | +final List<AssetEntity>? result = await AssetPicker.pickAssets(context); | ||
| 266 | +``` | ||
| 267 | + | ||
| 268 | +你可以使用 `AssetPickerConfig` 来调整选择时的行为。 | ||
| 269 | + | ||
| 270 | +```dart | ||
| 271 | +final List<AssetEntity>? result = await AssetPicker.pickAssets( | ||
| 272 | + context, | ||
| 273 | + pickerConfig: const AssetPickerConfig(), | ||
| 274 | +); | ||
| 275 | +``` | ||
| 276 | + | ||
| 277 | +`AssetPickerConfig` 的成员说明: | ||
| 278 | + | ||
| 279 | +| 参数名 | 类型 | 描述 | 默认值 | | ||
| 280 | +|-----------------------------------|--------------------------------------------------|------------------------------------------------------|-----------------------------| | ||
| 281 | +| selectedAssets | `List<AssetEntity>?` | 已选的资源。确保不重复选择。 | `null` | | ||
| 282 | +| maxAssets | `int` | 最多选择的图片数量 | 9 | | ||
| 283 | +| pageSize | `int` | 分页加载时每页加载的资源数量。**必须为网格数的倍数。 | 80 | | ||
| 284 | +| gridThumbnailSize | `ThumbnailSize` | 预览网格的缩略图大小 | `ThumbnailSize.square(200)` | | ||
| 285 | +| pathThumbnailSize | `ThumbnailSize` | 路径选择器的缩略图大小 | `ThumbnailSize.square(80)` | | ||
| 286 | +| previewThumbnailSize | `ThumbnailSize?` | 预览时图片的缩略图大小 | `null` | | ||
| 287 | +| requestType | `RequestType` | 选择器选择资源的类型 | `RequestType.common` | | ||
| 288 | +| specialPickerType | `SpecialPickerType?` | 提供一些特殊的选择器类型以整合非常规的选择行为 | `null` | | ||
| 289 | +| keepScrollOffset | `bool` | 选择器是否可以从同样的位置开始选择 | `null` | | ||
| 290 | +| sortPathDelegate | `SortPathDelegate<AssetPathEntity>?` | 资源路径的排序实现,可自定义路径排序方法 | `CommonSortPathDelegate` | | ||
| 291 | +| sortPathsByModifiedDate | `bool` | 是否结合 `FilterOptionGroup.containsPathModified` 进行路径排序 | `false` | | ||
| 292 | +| filterOptions | `PMFilter?` | 允许用户自定义资源过滤条件 | `null` | | ||
| 293 | +| gridCount | `int` | 选择器网格数量 | 4 | | ||
| 294 | +| themeColor | `Color?` | 选择器的主题色 | `Color(0xff00bc56)` | | ||
| 295 | +| pickerTheme | `ThemeData?` | 选择器的主题提供,包括查看器 | `null` | | ||
| 296 | +| textDelegate | `AssetPickerTextDelegate?` | 选择器的文本代理构建,用于自定义文本 | `AssetPickerTextDelegate()` | | ||
| 297 | +| specialItemPosition | `SpecialItemPosition` | 允许用户在选择器中添加一个自定义item,并指定位置。 | `SpecialPosition.none` | | ||
| 298 | +| specialItemBuilder | `SpecialItemBuilder?` | 自定义item的构造方法 | `null` | | ||
| 299 | +| loadingIndicatorBuilder | `IndicatorBuilder?` | 加载器的实现 | `null` | | ||
| 300 | +| selectPredicate | `AssetSelectPredicate` | 判断资源可否被选择 | `null` | | ||
| 301 | +| shouldRevertGrid | `bool?` | 判断资源网格是否需要倒序排列 | `null` | | ||
| 302 | +| limitedPermissionOverlayPredicate | `LimitedPermissionOverlayPredicate?` | 判断有限的权限情况下是否展示提示页面 | `null` | | ||
| 303 | +| pathNameBuilder | `PathNameBuilder<AssetPathEntity>?` | 基于路径(相册)构建自定义名称的方法 | `null` | | ||
| 304 | +| assetsChangeCallback | `AssetsChangeCallback<AssetPathEntity>?` | 当系统通知资源变化时将调用的回调 | `null` | | ||
| 305 | +| assetsChangeRefreshPredicate | `AssetsChangeRefreshPredicate<AssetPathEntity>?` | 判断资源变化是否根据 call 和当前选中的路径进行更新 | `null` | | ||
| 306 | +| shouldAutoplayPreview | `bool` | 预览是否应自动播放 | `false` | | ||
| 307 | +| dragToSelect | `bool` | 是否开启拖拽选择 | `true` | | ||
| 308 | + | ||
| 309 | +- 当 `maxAssets` 等于 `1`(即单选模式),搭配 | ||
| 310 | + `SpecialPickerType.noPreview` 使用会在用户点选资源换时立刻选中并返回。 | ||
| 311 | +- `limitedPermissionOverlayPredicate` 不是持久化的, | ||
| 312 | + 如果你需要在应用下次启动时不再显示权限受限的页面,请自主实现持久化的控制。 | ||
| 313 | + | ||
| 314 | +### 更详细的使用方法 | ||
| 315 | + | ||
| 316 | +我们已将常用的调用方法封装在 [example](example) 中。 | ||
| 317 | +你可以在 `example/lib/pages/multi_assets_page.dart` 和 | ||
| 318 | +`example/lib/pages/single_assets_page.dart` | ||
| 319 | +找到 `List<PickMethod> pickMethods`, | ||
| 320 | +它分别定义了多选和单选可用的选择模式。 | ||
| 321 | +在选择资源后,资源会暂存并展示在页面下方。 | ||
| 322 | + | ||
| 323 | +#### 展示选中的资源 | ||
| 324 | + | ||
| 325 | +`AssetEntityImage` 和 `AssetEntityImageProvider` | ||
| 326 | +可以为 **图片 & 视频** 展示缩略图,以及展示 **图片的原图**。 | ||
| 327 | +它的使用方法与常见的 `Image` 和 `ImageProvider` 一致。 | ||
| 328 | + | ||
| 329 | +```dart | ||
| 330 | +AssetEntityImage(asset, isOriginal: false); | ||
| 331 | +``` | ||
| 332 | + | ||
| 333 | +或: | ||
| 334 | + | ||
| 335 | +```dart | ||
| 336 | +/// AssetEntityImageProvider | ||
| 337 | +Image(image: AssetEntityImageProvider(asset, isOriginal: false)); | ||
| 338 | +``` | ||
| 339 | + | ||
| 340 | +#### 注册资源变化回调 | ||
| 341 | + | ||
| 342 | +```dart | ||
| 343 | +/// 注册回调 | ||
| 344 | +AssetPicker.registerObserve(); | ||
| 345 | + | ||
| 346 | +/// 取消注册回调 | ||
| 347 | +AssetPicker.unregisterObserve(); | ||
| 348 | +``` | ||
| 349 | + | ||
| 350 | +#### 在表单数据中上传 `AssetEntity` | ||
| 351 | + | ||
| 352 | +`AssetEntity` 包含有多种 I/O 相关的方法可以用于上传。 | ||
| 353 | +**请注意,I/O 相关的方法会消耗性能(通常是时间和内存),它们不应该被频繁调用。** | ||
| 354 | + | ||
| 355 | +##### 使用 `http` | ||
| 356 | + | ||
| 357 | +`http` package: https://pub.flutter-io.cn/packages/http | ||
| 358 | + | ||
| 359 | +`http` package 使用v | ||
| 360 | +[`MultipartFile`](https://pub.flutter-io.cn/documentation/http/latest/http/MultipartFile-class.html) | ||
| 361 | +来在请求中处理文件。 | ||
| 362 | + | ||
| 363 | +示例代码如下: | ||
| 364 | +```dart | ||
| 365 | +import 'package:http/http.dart' as http; | ||
| 366 | + | ||
| 367 | +Future<void> upload() async { | ||
| 368 | + final entity = await obtainYourEntity(); | ||
| 369 | + final uri = Uri.https('example.com', 'create'); | ||
| 370 | + final request = http.MultipartRequest('POST', uri) | ||
| 371 | + ..fields['test_field'] = 'test_value' | ||
| 372 | + ..files.add(await multipartFileFromAssetEntity(entity)); | ||
| 373 | + final response = await request.send(); | ||
| 374 | + if (response.statusCode == 200) { | ||
| 375 | + print('Uploaded!'); | ||
| 376 | + } | ||
| 377 | +} | ||
| 378 | + | ||
| 379 | +Future<http.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async { | ||
| 380 | + http.MultipartFile mf; | ||
| 381 | + // Using the file path. | ||
| 382 | + final file = await entity.file; | ||
| 383 | + if (file == null) { | ||
| 384 | + throw StateError('Unable to obtain file of the entity ${entity.id}.'); | ||
| 385 | + } | ||
| 386 | + mf = await http.MultipartFile.fromPath('test_file', file.path); | ||
| 387 | + // Using the bytes. | ||
| 388 | + final bytes = await entity.originBytes; | ||
| 389 | + if (bytes == null) { | ||
| 390 | + throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); | ||
| 391 | + } | ||
| 392 | + mf = http.MultipartFile.fromBytes('test_file', bytes); | ||
| 393 | + return mf; | ||
| 394 | +} | ||
| 395 | +``` | ||
| 396 | + | ||
| 397 | +##### 使用 `dio` | ||
| 398 | + | ||
| 399 | +`dio` package: https://pub.flutter-io.cn/packages/dio | ||
| 400 | + | ||
| 401 | +`dio` package 同样使用了 | ||
| 402 | +[`MultipartFile`](https://pub.flutter-io.cn/documentation/dio/latest/dio/MultipartFile-class.html) | ||
| 403 | +来在请求中处理文件。 | ||
| 404 | + | ||
| 405 | +示例代码: | ||
| 406 | +```dart | ||
| 407 | +import 'package:dio/dio.dart' as dio; | ||
| 408 | + | ||
| 409 | +Future<void> upload() async { | ||
| 410 | + final entity = await obtainYourEntity(); | ||
| 411 | + final uri = Uri.https('example.com', 'create'); | ||
| 412 | + final response = dio.Dio().requestUri( | ||
| 413 | + uri, | ||
| 414 | + data: dio.FormData.fromMap({ | ||
| 415 | + 'test_field': 'test_value', | ||
| 416 | + 'test_file': await multipartFileFromAssetEntity(entity), | ||
| 417 | + }), | ||
| 418 | + ); | ||
| 419 | + print('Uploaded!'); | ||
| 420 | +} | ||
| 421 | + | ||
| 422 | +Future<dio.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async { | ||
| 423 | + dio.MultipartFile mf; | ||
| 424 | + // Using the file path. | ||
| 425 | + final file = await entity.file; | ||
| 426 | + if (file == null) { | ||
| 427 | + throw StateError('Unable to obtain file of the entity ${entity.id}.'); | ||
| 428 | + } | ||
| 429 | + mf = await dio.MultipartFile.fromFile(file.path); | ||
| 430 | + // Using the bytes. | ||
| 431 | + final bytes = await entity.originBytes; | ||
| 432 | + if (bytes == null) { | ||
| 433 | + throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); | ||
| 434 | + } | ||
| 435 | + mf = dio.MultipartFile.fromBytes(bytes); | ||
| 436 | + return mf; | ||
| 437 | +} | ||
| 438 | +``` | ||
| 439 | + | ||
| 440 | +### 自定义选择器 | ||
| 441 | + | ||
| 442 | +`AssetPickerBuilderDelegate`、`AssetPickerViewerBuilderDelegate`、 | ||
| 443 | +`AssetPickerProvider` 及 `AssetPickerViewerProvider` 均已暴露且可重载。 | ||
| 444 | +使用者可以使用自定义的泛型类型 `<A: 资源, P: 路径>`, | ||
| 445 | +配合继承与重载,实现对应抽象类和类中的方法。 | ||
| 446 | +更多用法请查看示例中的 `Custom` 页面, | ||
| 447 | +该页面包含一个以 `<File, Directory>` 为类型基础的选择器。 | ||
| 448 | + | ||
| 449 | +想要了解如何完全自定义主题、widget 和布局,前往 [示例](example/lib/customs/pickers) | ||
| 450 | +查看已有的自定义选择器的实现。 | ||
| 451 | + | ||
| 452 | +如果你觉得你的实现有价值或能帮助到其他人,欢迎以 PR 的形式进行提交。 | ||
| 453 | +更多细节请阅读 [贡献自定义实现][]。 | ||
| 454 | + | ||
| 455 | +## 常见问题 ❔ | ||
| 456 | + | ||
| 457 | +### 修改默认相册名称(将 `Recent` 改为其他) | ||
| 458 | + | ||
| 459 | +在 Android 上 `Recent` 是总相册的默认名称, | ||
| 460 | +总相册是一个实际不存在的概念,它只是原始媒体数据的记录集合。 | ||
| 461 | + | ||
| 462 | +想要在 Android 上解决这个问题,你可以像这样使用 `pathNameBuilder`: | ||
| 463 | +```dart | ||
| 464 | +AssetPickerConfig( | ||
| 465 | + pathNameBuilder: (AssetPathEntity path) => switch (path) { | ||
| 466 | + final p when p.isAll => '最近', | ||
| 467 | + // 你也可以将类似的逻辑应用在其他常见的相册上。 | ||
| 468 | + _ => path.name, | ||
| 469 | + }, | ||
| 470 | +) | ||
| 471 | +``` | ||
| 472 | + | ||
| 473 | +其他相册或者其他平台 (iOS/macOS) 上的相册会根据系统语言和配置支持的语言来进行展示。 | ||
| 474 | +`pathNameBuilder` 可以用于任何的相册。 | ||
| 475 | + | ||
| 476 | +### Execution failed for task ':photo_manager:compileDebugKotlin' | ||
| 477 | + | ||
| 478 | +查看 [photo_manager#561][] 了解详细的解决方法。 | ||
| 479 | + | ||
| 480 | +### 从 `File` 或 `Uint8List` 创建 `AssetEntity` 的方法 | ||
| 481 | + | ||
| 482 | +如果需要使用此库结合一些拍照需求, | ||
| 483 | +可通过以下方法将 `File` 或 `Uint8List` 转为 `AssetEntity`。 | ||
| 484 | + | ||
| 485 | +```dart | ||
| 486 | +final File file = your_file; // 你的 File 对象 | ||
| 487 | +final String path = file.path; | ||
| 488 | +final AssetEntity fileEntity = await PhotoManager.editor.saveImageWithPath( | ||
| 489 | + path, | ||
| 490 | + title: basename(path), | ||
| 491 | +); // 存入手机并生成 AssetEntity | ||
| 492 | + | ||
| 493 | +final Uint8List data = your_data; // 你的 Uint8List 对象 | ||
| 494 | +final AssetEntity imageEntity = await PhotoManager.editor.saveImage( | ||
| 495 | + file.path, | ||
| 496 | + title: '带有后缀的名称.jpg', | ||
| 497 | +); // 存入手机并生成 AssetEntity | ||
| 498 | +``` | ||
| 499 | + | ||
| 500 | +**注意:如果不想保留文件,请尽量用 `File` 承载中间操作,** | ||
| 501 | +否则在调用 `AssetEntity` 的删除时,系统可能会触发弹窗: | ||
| 502 | + | ||
| 503 | +```dart | ||
| 504 | +final List<String> result = await PhotoManager.editor.deleteWithIds( | ||
| 505 | + <String>[entity.id], | ||
| 506 | +); | ||
| 507 | +``` | ||
| 508 | + | ||
| 509 | +你可以阅读 [photo_manager#from-raw-data][] | ||
| 510 | +和 [photo_manager#delete-entities][] | ||
| 511 | +了解更多细节。 | ||
| 512 | + | ||
| 513 | +### 控制台提示 'Failed to find GeneratedAppGlideModule' | ||
| 514 | + | ||
| 515 | +``` | ||
| 516 | +W/Glide (21133): Failed to find GeneratedAppGlideModule. | ||
| 517 | + You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler | ||
| 518 | + in you application ana a @GlideModule annotated AppGlideModule implementation | ||
| 519 | + or LibraryGlideModules will be silently ignored. | ||
| 520 | +``` | ||
| 521 | + | ||
| 522 | +`Glide` 通过注解来保证单例,防止单例或版本之间的冲突, | ||
| 523 | +而因为 `photo_manager` 使用了 `Glide` 提供部分图片功能, | ||
| 524 | +所以使用它的项目必须实现自己的 `AppGlideModule`。 | ||
| 525 | +请移步 [Glide Generated API 文档][] 了解如何实现。 | ||
| 526 | + | ||
| 527 | +## 致谢 | ||
| 528 | + | ||
| 529 | +> IntelliJ IDEA 的每个方面都旨在最大化开发者生产力。结合智能编码辅助与符合人体工程学的设计,让开发不仅高效,更成为一种享受。 | ||
| 530 | + | ||
| 531 | +感谢 [JetBrains](https://www.jetbrains.com/?from=fluttercandies) | ||
| 532 | +为开源项目提供免费的 | ||
| 533 | +[IntelliJ IDEA](https://www.jetbrains.com/idea/?from=fluttercandies) | ||
| 534 | +等 IDE 的授权。 | ||
| 535 | + | ||
| 536 | +[<img src="https://github.com/fluttercandies/flutter_wechat_assets_picker/raw/main/.github/jetbrains-variant.png" width="200"/>](https://www.jetbrains.com/?from=fluttercandies) | ||
| 537 | + | ||
| 538 | + | ||
| 539 | +[photo_manager pub]: https://pub.flutter-io.cn/packages/photo_manager | ||
| 540 | +[extended_image pub]: https://pub.flutter-io.cn/packages/extended_image | ||
| 541 | +[provider pub]: https://pub.flutter-io.cn/packages/provider | ||
| 542 | +[video_player pub]: https://pub.flutter-io.cn/packages/video_player | ||
| 543 | +[wechat_camera_picker pub]: https://pub.flutter-io.cn/packages/wechat_camera_picker | ||
| 544 | +[迁移指南]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/guides/migration_guide.md | ||
| 545 | +[photo_manager API 文档]: https://pub.flutter-io.cn/documentation/photo_manager/latest/ | ||
| 546 | +[Glide Generated API 文档]: https://muyangmin.github.io/glide-docs-cn/doc/generatedapi.html | ||
| 547 | +[贡献自定义实现]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/example/lib/customs/CONTRIBUTING.md | ||
| 548 | +[photo_manager#561]: https://github.com/fluttercandies/flutter_photo_manager/issues/561 | ||
| 549 | +[photo_manager#from-raw-data]: https://github.com/fluttercandies/flutter_photo_manager#from-raw-data | ||
| 550 | +[photo_manager#delete-entities]: https://github.com/fluttercandies/flutter_photo_manager#delete-entities |
library/wechat_assets_picker-9.8.0/README.md
0 → 100644
| 1 | +<!-- Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +Use of this source code is governed by an Apache license | ||
| 3 | +that can be found in the LICENSE file. --> | ||
| 4 | + | ||
| 5 | +# Flutter WeChat Assets Picker | ||
| 6 | + | ||
| 7 | +[](https://pub.dev/packages/wechat_assets_picker) | ||
| 8 | +[](https://pub.dev/packages/wechat_assets_picker) | ||
| 9 | +[](https://www.codefactor.io/repository/github/fluttercandies/flutter_wechat_assets_picker) | ||
| 10 | + | ||
| 11 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/actions/workflows/runnable.yml) | ||
| 12 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/LICENSE) | ||
| 13 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/stargazers) | ||
| 14 | +[](https://github.com/fluttercandies/flutter_wechat_assets_picker/network) | ||
| 15 | + | ||
| 16 | +[](https://github.com/Solido/awesome-flutter) | ||
| 17 | +<a href="https://qm.qq.com/q/ZyJbSVjfSU"><img src="https://img.shields.io/badge/dynamic/yaml?url=https%3A%2F%2Fraw.githubusercontent.com%2Ffluttercandies%2F.github%2Frefs%2Fheads%2Fmain%2Fdata.yml&query=%24.qq_group_number&label=QQ%E7%BE%A4&logo=qq&style=flat&color=1DACE8" /></a> | ||
| 18 | + | ||
| 19 | +Language: English | [中文](README-ZH.md) | ||
| 20 | + | ||
| 21 | +An **image picker (also with videos and audios)** | ||
| 22 | +for Flutter projects based on the WeChat's UI. | ||
| 23 | + | ||
| 24 | +Current WeChat version that UI based on: **8.0.51** | ||
| 25 | +UI designs will be updated following the WeChat update in anytime. | ||
| 26 | + | ||
| 27 | +To take a photo or a video for assets, | ||
| 28 | +please check the detailed usage in the example, | ||
| 29 | +and head over to [wechat_camera_picker][wechat_camera_picker pub]. | ||
| 30 | +The package is a standalone extension that can to be used with combination. | ||
| 31 | + | ||
| 32 | +See the [Migration Guide][] to learn how to migrate between breaking changes. | ||
| 33 | + | ||
| 34 | +## Versions compatibility | ||
| 35 | + | ||
| 36 | +The package only guarantees to be working on **the stable version of Flutter**. | ||
| 37 | +We won't update it in real-time to align with other channels of Flutter. | ||
| 38 | + | ||
| 39 | +| | 3.7 | 3.10 | 3.13 | 3.16 | 3.22 | | ||
| 40 | +|--------|:---:|:----:|:----:|:----:|:----:| | ||
| 41 | +| 9.5.0+ | ❌ | ❌ | ❌ | ❌ | ✅ | | ||
| 42 | +| 8.9.0+ | ❌ | ❌ | ❌ | ✅ | ❌ | | ||
| 43 | +| 8.7.0+ | ❌ | ❌ | ✅ | ❌ | ❌ | | ||
| 44 | +| 8.5.0+ | ❌ | ✅ | ❌ | ❌ | ❌ | | ||
| 45 | +| 8.4.0+ | ✅ | ❌ | ❌ | ❌ | ❌ | | ||
| 46 | + | ||
| 47 | +If you got a `resolve conflict` error when running `flutter pub get`, | ||
| 48 | +please use `dependency_overrides` to fix it. | ||
| 49 | + | ||
| 50 | +## Package credits | ||
| 51 | + | ||
| 52 | +The package is built from these wonderful packages. | ||
| 53 | + | ||
| 54 | +| Name | Features | | ||
| 55 | +|:-------------------------------------|:-----------------------------------------------------| | ||
| 56 | +| [photo_manager][photo_manager pub] | The basic abstractions and management for assets. | | ||
| 57 | +| [extended_image][extended_image pub] | Preview assets with expected behaviors. | | ||
| 58 | +| [provider][provider pub] | Helps to manage the interaction state of the picker. | | ||
| 59 | +| [video_player][video_player pub] | Plays videos and audios correspondingly. | | ||
| 60 | + | ||
| 61 | +Their implementation should be relatively stable in the package. | ||
| 62 | +If you've found any issues related to them when using the picker, | ||
| 63 | +submit issues to our issue tracker first. | ||
| 64 | + | ||
| 65 | +<details> | ||
| 66 | + <summary>Table of content</summary> | ||
| 67 | + | ||
| 68 | +<!-- TOC --> | ||
| 69 | +* [Flutter WeChat Assets Picker](#flutter-wechat-assets-picker) | ||
| 70 | + * [Versions compatibility](#versions-compatibility) | ||
| 71 | + * [Package credits](#package-credits) | ||
| 72 | + * [Features ✨](#features-) | ||
| 73 | + * [Notes 📝](#notes-) | ||
| 74 | + * [Projects using this plugin 🖼️](#projects-using-this-plugin-) | ||
| 75 | + * [Screenshots 📸](#screenshots-) | ||
| 76 | + * [READ THIS FIRST ‼️](#read-this-first-) | ||
| 77 | + * [Preparing for use 🍭](#preparing-for-use-) | ||
| 78 | + * [Flutter](#flutter) | ||
| 79 | + * [Android](#android) | ||
| 80 | + * [Permissions](#permissions) | ||
| 81 | + * [iOS](#ios) | ||
| 82 | + * [macOS](#macos) | ||
| 83 | + * [Usage 📖](#usage-) | ||
| 84 | + * [Localizations](#localizations) | ||
| 85 | + * [Simple usage](#simple-usage) | ||
| 86 | + * [Detailed usage](#detailed-usage) | ||
| 87 | + * [Display selected assets](#display-selected-assets) | ||
| 88 | + * [Register assets change observe callback](#register-assets-change-observe-callback) | ||
| 89 | + * [Upload an `AssetEntity` with a form data](#upload-an-assetentity-with-a-form-data) | ||
| 90 | + * [With `http`](#with-http) | ||
| 91 | + * [With `dio`](#with-dio) | ||
| 92 | + * [Custom pickers](#custom-pickers) | ||
| 93 | + * [Frequently asked question ❔](#frequently-asked-question-) | ||
| 94 | + * [Changing the default album name (`Recent` to others)](#changing-the-default-album-name-recent-to-others) | ||
| 95 | + * [Execution failed for task ':photo_manager:compileDebugKotlin'](#execution-failed-for-task-photo_managercompiledebugkotlin) | ||
| 96 | + * [Create `AssetEntity` from `File` or `Uint8List` (rawData)](#create-assetentity-from-file-or-uint8list-rawdata) | ||
| 97 | + * [Glide warning 'Failed to find GeneratedAppGlideModule'](#glide-warning-failed-to-find-generatedappglidemodule) | ||
| 98 | + * [Contributors ✨](#contributors-) | ||
| 99 | + * [Credits](#credits) | ||
| 100 | +<!-- TOC --> | ||
| 101 | +</details> | ||
| 102 | + | ||
| 103 | +## Features ✨ | ||
| 104 | + | ||
| 105 | +- ♿ Complete a11y support with _TalkBack_ and _VoiceOver_ | ||
| 106 | +- ♻️ Fully customizable with delegates override | ||
| 107 | +- 🎏 Fully customizable theme based on `ThemeData` | ||
| 108 | +- 💚 Completely WeChat style (even more) | ||
| 109 | +- ⚡️ Adjustable performance with different configurations | ||
| 110 | +- 📷 Image support | ||
| 111 | + - 🔬 HEIF Image type support <a href="#notes-"><sup>(1)</sup></a> | ||
| 112 | +- 🎥 Video support | ||
| 113 | +- 🎶 Audio support <a href="#notes-"><sup>(2)</sup></a> | ||
| 114 | +- 1️⃣ Single picking mode | ||
| 115 | +- 💱 Internationalization (i18n) support | ||
| 116 | + - ⏪ RTL language support | ||
| 117 | +- ➕ Special item builder support | ||
| 118 | +- 🗂 Custom sort path delegate support | ||
| 119 | +- 📝 Custom text delegate support | ||
| 120 | +- ⏳ Custom filter options support | ||
| 121 | +- 💻 macOS support | ||
| 122 | + | ||
| 123 | +### Notes 📝 | ||
| 124 | + | ||
| 125 | +1. HEIF (HEIC) images are support to obtain and conversion, | ||
| 126 | + but the display with them are based on Flutter's image decoder. | ||
| 127 | + See [flutter/flutter#20522](https://github.com/flutter/flutter/issues/20522). | ||
| 128 | + Use `entity.file` or `AssetEntityImage` for them when displays. | ||
| 129 | +2. Due to limitations on iOS and macOS, audio can only be fetched within the sandbox. | ||
| 130 | + | ||
| 131 | +## Projects using this plugin 🖼️ | ||
| 132 | + | ||
| 133 | +| name | pub | github | | ||
| 134 | +|:--------------------|:-----------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| | ||
| 135 | +| insta_assets_picker | [](https://pub.dev/packages/insta_assets_picker) | [](https://github.com/LeGoffMael/insta_assets_picker) | | ||
| 136 | + | ||
| 137 | +## Screenshots 📸 | ||
| 138 | + | ||
| 139 | +|  |  |  | | ||
| 140 | +|-----------------------------------|-----------------------------------|-----------------------------------| | ||
| 141 | +|  |  |  | | ||
| 142 | +|  |  |  | | ||
| 143 | +|  |  |  | | ||
| 144 | + | ||
| 145 | +## READ THIS FIRST ‼️ | ||
| 146 | + | ||
| 147 | +Be aware of below notices before you started anything: | ||
| 148 | +- Due to understanding differences and the limitation of a single document, | ||
| 149 | + documents will not cover all the contents. | ||
| 150 | + If you find nothing related to your expected features and cannot understand about concepts, | ||
| 151 | + run the example project and check every options first. | ||
| 152 | + It has covered 90% of regular requests with the package. | ||
| 153 | +- The package deeply integrates with the [photo_manager][photo_manager pub] plugin, | ||
| 154 | + make sure you understand these two concepts as much as possible: | ||
| 155 | + - Asset (photos/videos/audio) - [`AssetEntity`](https://pub.dev/documentation/photo_manager/latest/photo_manager/AssetEntity-class.html) | ||
| 156 | + - Assets collection (albums/libraries) - [`AssetPathEntity`](https://pub.dev/documentation/photo_manager/latest/photo_manager/AssetPathEntity-class.html) | ||
| 157 | + | ||
| 158 | +When you have questions about related APIs and behaviors, | ||
| 159 | +check [photo_manager's API docs][] for more details. | ||
| 160 | + | ||
| 161 | +Most usages are detailed covered by the [example](example). | ||
| 162 | +Please walk through the [example](example) carefully | ||
| 163 | +before you have any questions. | ||
| 164 | + | ||
| 165 | +## Preparing for use 🍭 | ||
| 166 | + | ||
| 167 | +### Flutter | ||
| 168 | + | ||
| 169 | +Run `flutter pub add wechat_assets_picker`, | ||
| 170 | +or add `wechat_assets_picker` to `pubspec.yaml` dependencies manually. | ||
| 171 | +```yaml | ||
| 172 | +dependencies: | ||
| 173 | + wechat_assets_picker: ^latest_version | ||
| 174 | +``` | ||
| 175 | + | ||
| 176 | +The latest **stable** version is: | ||
| 177 | +[](https://pub.dev/packages/wechat_assets_picker) | ||
| 178 | + | ||
| 179 | +The latest **dev** version is: | ||
| 180 | +[](https://pub.dev/packages/wechat_assets_picker) | ||
| 181 | + | ||
| 182 | +Then import the package in your code: | ||
| 183 | +```dart | ||
| 184 | +import 'package:wechat_assets_picker/wechat_assets_picker.dart'; | ||
| 185 | +``` | ||
| 186 | + | ||
| 187 | +### Android | ||
| 188 | + | ||
| 189 | +When using the package, please upgrade | ||
| 190 | +`targetSdkVersion` and `compileSdkVersion` to `33`. | ||
| 191 | +Otherwise, no assets can be fetched on Android 13. | ||
| 192 | + | ||
| 193 | +#### Permissions | ||
| 194 | + | ||
| 195 | +| Name | Required | Declared | Max API Level | Others | | ||
| 196 | +|--------------------------|----------|----------|---------------|------------------------------| | ||
| 197 | +| `READ_EXTERNAL_STORAGE` | YES | YES | 32 | | | ||
| 198 | +| `WRITE_EXTERNAL_STORAGE` | NO | NO | 29 | | | ||
| 199 | +| `ACCESS_MEDIA_LOCATION` | YES* | NO | N/A | Required when reading EXIF | | ||
| 200 | +| `READ_MEDIA_IMAGES` | YES* | YES | N/A | Required when reading images | | ||
| 201 | +| `READ_MEDIA_VIDEO` | YES* | YES | N/A | Required when reading videos | | ||
| 202 | +| `READ_MEDIA_AUDIO` | YES* | YES | N/A | Required when reading audios | | ||
| 203 | + | ||
| 204 | +If you're targeting Android SDK 33+, | ||
| 205 | +and you don't need to load photos, videos or audios, | ||
| 206 | +consider declare only relevant permission in your apps, more specifically: | ||
| 207 | + | ||
| 208 | +```xml | ||
| 209 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
| 210 | + xmlns:tools="http://schemas.android.com/tools" | ||
| 211 | + package="com.your.app"> | ||
| 212 | + <!--Requesting access to images and videos.--> | ||
| 213 | + <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> | ||
| 214 | + <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> | ||
| 215 | + <!--When your app has no need to access audio, remove it or comment it out.--> | ||
| 216 | + <!--<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />--> | ||
| 217 | +</manifest> | ||
| 218 | +``` | ||
| 219 | + | ||
| 220 | +### iOS | ||
| 221 | + | ||
| 222 | +1. Platform version has to be at least *11.0*. | ||
| 223 | + Modify `ios/Podfile` and update accordingly. | ||
| 224 | + ```Podfile | ||
| 225 | + platform :ios, '11.0' | ||
| 226 | + ``` | ||
| 227 | + Remove the `#` heading if the line starts with it. | ||
| 228 | +2. Add the following content to `Info.plist`. | ||
| 229 | +``` | ||
| 230 | +<key>NSPhotoLibraryUsageDescription</key> | ||
| 231 | +<string>Replace with your permission description.</string> | ||
| 232 | +``` | ||
| 233 | + | ||
| 234 | +### macOS | ||
| 235 | + | ||
| 236 | +1. Platform version has to be at least *10.15*. | ||
| 237 | + Modify `macos/Podfile` and update accordingly. | ||
| 238 | + ```ruby | ||
| 239 | + platform :osx, '10.15' | ||
| 240 | + ``` | ||
| 241 | + Remove the `#` heading if the line starts with it. | ||
| 242 | +2. Set the minimum deployment target of the macOS to *10.15*. | ||
| 243 | + Use XCode to open `macos/Runner.xcworkspace` . | ||
| 244 | +3. Follow the [iOS](#iOS) instructions and modify `Info.plist` accordingly. | ||
| 245 | + | ||
| 246 | +## Usage 📖 | ||
| 247 | + | ||
| 248 | +### Localizations | ||
| 249 | + | ||
| 250 | +When you're picking assets, the package will obtain the `Locale?` | ||
| 251 | +from your `BuildContext`, and return the corresponding text delegate | ||
| 252 | +of the current language. | ||
| 253 | +Make sure you have a valid `Locale` in your widget tree that can be accessed | ||
| 254 | +from the `BuildContext`. **Otherwise, the default Chinese delegate will be used.** | ||
| 255 | + | ||
| 256 | +Embedded text delegates languages are: | ||
| 257 | +* 简体中文 (default) | ||
| 258 | +* English | ||
| 259 | +* העברית | ||
| 260 | +* Deutsche | ||
| 261 | +* Локализация | ||
| 262 | +* 日本語 | ||
| 263 | +* مة العربية | ||
| 264 | +* Délégué | ||
| 265 | +* Tiếng Việt | ||
| 266 | +* Türkçe Yerelleştirme | ||
| 267 | + | ||
| 268 | +If you want to use a custom/fixed text delegate, pass it through the | ||
| 269 | +`AssetPickerConfig.textDelegate`. | ||
| 270 | + | ||
| 271 | +### Simple usage | ||
| 272 | + | ||
| 273 | +```dart | ||
| 274 | +final List<AssetEntity>? result = await AssetPicker.pickAssets(context); | ||
| 275 | +``` | ||
| 276 | + | ||
| 277 | +Use `AssetPickerConfig` for more picking behaviors. | ||
| 278 | + | ||
| 279 | +```dart | ||
| 280 | +final List<AssetEntity>? result = await AssetPicker.pickAssets( | ||
| 281 | + context, | ||
| 282 | + pickerConfig: const AssetPickerConfig(), | ||
| 283 | +); | ||
| 284 | +``` | ||
| 285 | + | ||
| 286 | +Fields in `AssetPickerConfig`: | ||
| 287 | + | ||
| 288 | +| Name | Type | Description | Default | | ||
| 289 | +|-----------------------------------|--------------------------------------------------|------------------------------------------------------------------------------------------------|-----------------------------| | ||
| 290 | +| selectedAssets | `List<AssetEntity>?` | Selected assets. Prevent duplicate selection. | `null` | | ||
| 291 | +| maxAssets | `int` | Maximum asset that the picker can pick. | 9 | | ||
| 292 | +| pageSize | `int?` | Number of assets per page. **Must be a multiple of `gridCount`**. | 80 | | ||
| 293 | +| gridThumbnailSize | `ThumbnailSize` | Thumbnail size for the grid's item. | `ThumbnailSize.square(200)` | | ||
| 294 | +| pathThumbnailSize | `ThumbnailSize` | Thumbnail size for the path selector. | `ThumbnailSize.square(80)` | | ||
| 295 | +| previewThumbnailSize | `ThumbnailSize?` | Preview thumbnail size in the viewer. | `null` | | ||
| 296 | +| requestType | `RequestType` | Request type for picker. | `RequestType.common` | | ||
| 297 | +| specialPickerType | `SpecialPickerType?` | Provides the option to integrate a custom picker type. | `null` | | ||
| 298 | +| keepScrollOffset | `bool` | Whether the picker should save the scroll offset between pushes and pops. | `null` | | ||
| 299 | +| sortPathDelegate | `SortPathDelegate<AssetPathEntity>?` | Path entities sort delegate for the picker, sort paths as you want. | `CommonSortPathDelegate` | | ||
| 300 | +| sortPathsByModifiedDate | `bool` | Whether to allow sort delegates to sort paths with `FilterOptionGroup.containsPathModified`. | `false` | | ||
| 301 | +| filterOptions | `PMFilter?` | Allow users to customize assets filter options. | `null` | | ||
| 302 | +| gridCount | `int` | Grid count in picker. | 4 | | ||
| 303 | +| themeColor | `Color?` | Main theme color for the picker. | `Color(0xff00bc56)` | | ||
| 304 | +| pickerTheme | `ThemeData?` | Theme data provider for the picker and the viewer. | `null` | | ||
| 305 | +| textDelegate | `AssetPickerTextDelegate?` | Text delegate for the picker, for customize the texts. | `AssetPickerTextDelegate()` | | ||
| 306 | +| specialItemPosition | `SpecialItemPosition` | Allow users set a special item in the picker with several positions. | `SpecialItemPosition.none` | | ||
| 307 | +| specialItemBuilder | `SpecialItemBuilder?` | The widget builder for the special item. | `null` | | ||
| 308 | +| loadingIndicatorBuilder | `IndicatorBuilder?` | Indicates the loading status for the builder. | `null` | | ||
| 309 | +| selectPredicate | `AssetSelectPredicate` | Predicate whether an asset can be selected or unselected. | `null` | | ||
| 310 | +| shouldRevertGrid | `bool?` | Whether the assets grid should revert. | `null` | | ||
| 311 | +| limitedPermissionOverlayPredicate | `LimitedPermissionOverlayPredicate?` | Predicate whether the limited permission overlay should be displayed. | `null` | | ||
| 312 | +| pathNameBuilder | `PathNameBuilder<AssetPathEntity>?` | Build customized path (album) name with the given path entity. | `null` | | ||
| 313 | +| assetsChangeCallback | `AssetsChangeCallback<AssetPathEntity>?` | The callback that will be called when the system notifies assets changes. | `null` | | ||
| 314 | +| assetsChangeRefreshPredicate | `AssetsChangeRefreshPredicate<AssetPathEntity>?` | Whether assets changing should call refresh with the given call and the current selected path. | `null` | | ||
| 315 | +| shouldAutoPlayPreview | `bool` | Whether the preview should auto play. | `false` | | ||
| 316 | +| dragToSelect | `bool` | Whether assets selection can be done with drag gestures. | `true` | | ||
| 317 | + | ||
| 318 | +- When `maxAssets` equals to `1` (a.k.a. single picking mode), | ||
| 319 | + use `SpecialPickerType.noPreview` will immediately select asset | ||
| 320 | + clicked (pressed) by the user and popped. | ||
| 321 | +- `limitedPermissionOverlayPredicate` lives without persistence, | ||
| 322 | + if you want to ignore the limited preview after restart, | ||
| 323 | + you'll need to integrate with your own saving methods. | ||
| 324 | + | ||
| 325 | +### Detailed usage | ||
| 326 | + | ||
| 327 | +We've put multiple common usage | ||
| 328 | +with the packages in the [example](example). | ||
| 329 | +You can both found `List<PickMethod> pickMethods` in | ||
| 330 | +[here](example/lib/pages/multi_assets_page.dart) | ||
| 331 | +and [here](example/lib/pages/single_assets_page.dart), | ||
| 332 | +which provide methods in multiple picking and single picking mode. | ||
| 333 | +Assets will be stored temporary and displayed at the below of the page. | ||
| 334 | + | ||
| 335 | +#### Display selected assets | ||
| 336 | + | ||
| 337 | +The `AssetEntityImage` and `AssetEntityImageProvider` | ||
| 338 | +can display the thumb image of _images & videos_, | ||
| 339 | +and the original data of _image_. | ||
| 340 | +Use it like a common `Image` and `ImageProvider`. | ||
| 341 | + | ||
| 342 | +```dart | ||
| 343 | +AssetEntityImage(asset, isOriginal: false); | ||
| 344 | +``` | ||
| 345 | + | ||
| 346 | +Or: | ||
| 347 | + | ||
| 348 | +```dart | ||
| 349 | +Image(image: AssetEntityImageProvider(asset, isOriginal: false)); | ||
| 350 | +``` | ||
| 351 | + | ||
| 352 | +#### Register assets change observe callback | ||
| 353 | + | ||
| 354 | +```dart | ||
| 355 | +// Register callback. | ||
| 356 | +AssetPicker.registerObserve(); | ||
| 357 | + | ||
| 358 | +// Unregister callback. | ||
| 359 | +AssetPicker.unregisterObserve(); | ||
| 360 | +``` | ||
| 361 | + | ||
| 362 | +#### Upload an `AssetEntity` with a form data | ||
| 363 | + | ||
| 364 | +There are multiple ways to upload an `AssetEntity` with I/O related methods. | ||
| 365 | +**Be aware, I/O related methods will consume performance | ||
| 366 | +(typically time and memory), they should not be called frequently.** | ||
| 367 | + | ||
| 368 | +##### With `http` | ||
| 369 | + | ||
| 370 | +`http` package: https://pub.dev/packages/http | ||
| 371 | + | ||
| 372 | +The `http` package uses | ||
| 373 | +[`MultipartFile`](https://pub.dev/documentation/http/latest/http/MultipartFile-class.html) | ||
| 374 | +to handle files in requests. | ||
| 375 | + | ||
| 376 | +Pseudo code: | ||
| 377 | +```dart | ||
| 378 | +import 'package:http/http.dart' as http; | ||
| 379 | + | ||
| 380 | +Future<void> upload() async { | ||
| 381 | + final entity = await obtainYourEntity(); | ||
| 382 | + final uri = Uri.https('example.com', 'create'); | ||
| 383 | + final request = http.MultipartRequest('POST', uri) | ||
| 384 | + ..fields['test_field'] = 'test_value' | ||
| 385 | + ..files.add(await multipartFileFromAssetEntity(entity)); | ||
| 386 | + final response = await request.send(); | ||
| 387 | + if (response.statusCode == 200) { | ||
| 388 | + print('Uploaded!'); | ||
| 389 | + } | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +Future<http.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async { | ||
| 393 | + http.MultipartFile mf; | ||
| 394 | + // Using the file path. | ||
| 395 | + final file = await entity.file; | ||
| 396 | + if (file == null) { | ||
| 397 | + throw StateError('Unable to obtain file of the entity ${entity.id}.'); | ||
| 398 | + } | ||
| 399 | + mf = await http.MultipartFile.fromPath('test_file', file.path); | ||
| 400 | + // Using the bytes. | ||
| 401 | + final bytes = await entity.originBytes; | ||
| 402 | + if (bytes == null) { | ||
| 403 | + throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); | ||
| 404 | + } | ||
| 405 | + mf = http.MultipartFile.fromBytes('test_file', bytes); | ||
| 406 | + return mf; | ||
| 407 | +} | ||
| 408 | +``` | ||
| 409 | + | ||
| 410 | +##### With `dio` | ||
| 411 | + | ||
| 412 | +`dio` package: https://pub.dev/packages/dio | ||
| 413 | + | ||
| 414 | +The `dio` package also uses | ||
| 415 | +[`MultipartFile`](https://pub.dev/documentation/dio/latest/dio/MultipartFile-class.html) | ||
| 416 | +to handle files in requests. | ||
| 417 | + | ||
| 418 | +Pseudo code: | ||
| 419 | +```dart | ||
| 420 | +import 'package:dio/dio.dart' as dio; | ||
| 421 | + | ||
| 422 | +Future<void> upload() async { | ||
| 423 | + final entity = await obtainYourEntity(); | ||
| 424 | + final uri = Uri.https('example.com', 'create'); | ||
| 425 | + final response = dio.Dio().requestUri( | ||
| 426 | + uri, | ||
| 427 | + data: dio.FormData.fromMap({ | ||
| 428 | + 'test_field': 'test_value', | ||
| 429 | + 'test_file': await multipartFileFromAssetEntity(entity), | ||
| 430 | + }), | ||
| 431 | + ); | ||
| 432 | + print('Uploaded!'); | ||
| 433 | +} | ||
| 434 | + | ||
| 435 | +Future<dio.MultipartFile> multipartFileFromAssetEntity(AssetEntity entity) async { | ||
| 436 | + dio.MultipartFile mf; | ||
| 437 | + // Using the file path. | ||
| 438 | + final file = await entity.file; | ||
| 439 | + if (file == null) { | ||
| 440 | + throw StateError('Unable to obtain file of the entity ${entity.id}.'); | ||
| 441 | + } | ||
| 442 | + mf = await dio.MultipartFile.fromFile(file.path); | ||
| 443 | + // Using the bytes. | ||
| 444 | + final bytes = await entity.originBytes; | ||
| 445 | + if (bytes == null) { | ||
| 446 | + throw StateError('Unable to obtain bytes of the entity ${entity.id}.'); | ||
| 447 | + } | ||
| 448 | + mf = dio.MultipartFile.fromBytes(bytes); | ||
| 449 | + return mf; | ||
| 450 | +} | ||
| 451 | +``` | ||
| 452 | + | ||
| 453 | +### Custom pickers | ||
| 454 | + | ||
| 455 | +`AssetPickerBuilderDelegate`, `AssetPickerViewerBuilderDelegate`, | ||
| 456 | +`AssetPickerProvider` and `AssetPickerViewerProvider` | ||
| 457 | +are all exposed and overridable. | ||
| 458 | +You can extend them and use your own | ||
| 459 | +type with generic type `<A: Asset, P: Path>`, | ||
| 460 | +then implement abstract methods. | ||
| 461 | + | ||
| 462 | +To know about how to fully customize themes, widgets or layouts. | ||
| 463 | +See how to customize delegates in the custom pickers page in the | ||
| 464 | +[example](example/lib/customs/pickers). | ||
| 465 | + | ||
| 466 | +You can submit PRs to create your own implementation | ||
| 467 | +if you found your implementation might be useful for others. | ||
| 468 | +See [Contribute custom implementations][] for more details. | ||
| 469 | + | ||
| 470 | +## Frequently asked question ❔ | ||
| 471 | + | ||
| 472 | +### Changing the default album name (`Recent` to others) | ||
| 473 | + | ||
| 474 | +`Recent` is the fix album name for the ALL assets on Android | ||
| 475 | +since the all assets' album is not an actual album, it only represents all media data records. | ||
| 476 | + | ||
| 477 | +To solve that on Android, use `pathNameBuilder`, for example: | ||
| 478 | +```dart | ||
| 479 | +AssetPickerConfig( | ||
| 480 | + pathNameBuilder: (AssetPathEntity path) => switch (path) { | ||
| 481 | + final p when p.isAll => '最近', | ||
| 482 | + // You can apply similar conditions to other common paths. | ||
| 483 | + _ => path.name, | ||
| 484 | + }, | ||
| 485 | +) | ||
| 486 | +``` | ||
| 487 | + | ||
| 488 | +Other albums or albums on other platforms (iOS/macOS) will follow | ||
| 489 | +the configured system localization and supported localizations. | ||
| 490 | +`pathNameBuilder` is available for all albums. | ||
| 491 | + | ||
| 492 | +### Execution failed for task ':photo_manager:compileDebugKotlin' | ||
| 493 | + | ||
| 494 | +See [photo_manager#561][] for more details. | ||
| 495 | + | ||
| 496 | +### Create `AssetEntity` from `File` or `Uint8List` (rawData) | ||
| 497 | + | ||
| 498 | +In order to combine this package with camera shooting or something related, | ||
| 499 | +there's a solution about how to create an `AssetEntity` | ||
| 500 | +with `File` or `Uint8List` object. | ||
| 501 | + | ||
| 502 | +```dart | ||
| 503 | +final File file = your_file; // Your `File` object | ||
| 504 | +final String path = file.path; | ||
| 505 | +final AssetEntity fileEntity = await PhotoManager.editor.saveImageWithPath( | ||
| 506 | + path, | ||
| 507 | + title: basename(path), | ||
| 508 | +); // Saved in the device then create an AssetEntity | ||
| 509 | + | ||
| 510 | +final Uint8List data = your_data; // Your `Uint8List` object | ||
| 511 | +final AssetEntity imageEntity = await PhotoManager.editor.saveImage( | ||
| 512 | + file.path, | ||
| 513 | + title: 'title_with_extension.jpg', | ||
| 514 | +); // Saved in the device then create an AssetEntity | ||
| 515 | +``` | ||
| 516 | + | ||
| 517 | +**Notice: If you don't want to keep the file in your device, | ||
| 518 | +use `File` for operations as much as possible.** | ||
| 519 | +Deleting an `AssetEntity` might cause system popups show: | ||
| 520 | + | ||
| 521 | +```dart | ||
| 522 | +final List<String> result = await PhotoManager.editor.deleteWithIds( | ||
| 523 | + <String>[entity.id], | ||
| 524 | +); | ||
| 525 | +``` | ||
| 526 | + | ||
| 527 | +See [photo_manager#from-raw-data][] | ||
| 528 | +and [photo_manager#delete-entities][] | ||
| 529 | +for more details. | ||
| 530 | + | ||
| 531 | +### Glide warning 'Failed to find GeneratedAppGlideModule' | ||
| 532 | + | ||
| 533 | +``` | ||
| 534 | +W/Glide (21133): Failed to find GeneratedAppGlideModule. | ||
| 535 | + You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler | ||
| 536 | + in you application ana a @GlideModule annotated AppGlideModule implementation | ||
| 537 | + or LibraryGlideModules will be silently ignored. | ||
| 538 | +``` | ||
| 539 | + | ||
| 540 | +`Glide` needs annotation to keep singleton, | ||
| 541 | +prevent conflict between instances and versions, | ||
| 542 | +so while the photo manager uses `Glide` to implement image features, | ||
| 543 | +the project which import this should define its own `AppGlideModule`. | ||
| 544 | +See [Glide Generated API docs][] for implementation. | ||
| 545 | + | ||
| 546 | +## Contributors ✨ | ||
| 547 | + | ||
| 548 | +Many thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): | ||
| 549 | +<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
| 550 | +<!-- prettier-ignore-start --> | ||
| 551 | +<!-- markdownlint-disable --> | ||
| 552 | +<table> | ||
| 553 | + <tbody> | ||
| 554 | + <tr> | ||
| 555 | + <td align="center" valign="top" width="14.28%"><a href="https://blog.alexv525.com"><img src="https://avatars1.githubusercontent.com/u/15884415?v=4?s=50" width="50px;" alt="Alex Li"/><br /><sub><b>Alex Li</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=AlexV525" title="Code">💻</a> <a href="#design-AlexV525" title="Design">🎨</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=AlexV525" title="Documentation">📖</a> <a href="#example-AlexV525" title="Examples">💡</a> <a href="#ideas-AlexV525" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-AlexV525" title="Maintenance">🚧</a> <a href="#question-AlexV525" title="Answering Questions">💬</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/pulls?q=is%3Apr+reviewed-by%3AAlexV525" title="Reviewed Pull Requests">👀</a> <a href="#a11y-AlexV525" title="Accessibility">️️️️♿️</a> <a href="#translation-AlexV525" title="Translation">🌍</a></td> | ||
| 556 | + <td align="center" valign="top" width="14.28%"><a href="https://www.kikt.top"><img src="https://avatars0.githubusercontent.com/u/14145407?v=4?s=50" width="50px;" alt="Caijinglong"/><br /><sub><b>Caijinglong</b></sub></a><br /><a href="#example-CaiJingLong" title="Examples">💡</a> <a href="#ideas-CaiJingLong" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
| 557 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/SchnMar"><img src="https://avatars3.githubusercontent.com/u/12902321?v=4?s=50" width="50px;" alt="Marcel Schneider"/><br /><sub><b>Marcel Schneider</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3ASchnMar" title="Bug reports">🐛</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=SchnMar" title="Code">💻</a> <a href="#ideas-SchnMar" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
| 558 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/ganlanshu0211"><img src="https://avatars0.githubusercontent.com/u/9670379?v=4?s=50" width="50px;" alt="ganlanshu0211"/><br /><sub><b>ganlanshu0211</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3Aganlanshu0211" title="Bug reports">🐛</a> <a href="#ideas-ganlanshu0211" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
| 559 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/JasonHezz"><img src="https://avatars3.githubusercontent.com/u/15358765?v=4?s=50" width="50px;" alt="JasonHezz"/><br /><sub><b>JasonHezz</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3AJasonHezz" title="Bug reports">🐛</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=JasonHezz" title="Code">💻</a></td> | ||
| 560 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/yanivshaked"><img src="https://avatars.githubusercontent.com/u/13107481?v=4?s=50" width="50px;" alt="Yaniv Shaked"/><br /><sub><b>Yaniv Shaked</b></sub></a><br /><a href="#translation-yanivshaked" title="Translation">🌍</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=yanivshaked" title="Code">💻</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3Ayanivshaked" title="Bug reports">🐛</a> <a href="#maintenance-yanivshaked" title="Maintenance">🚧</a></td> | ||
| 561 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/avi-yadav"><img src="https://avatars.githubusercontent.com/u/7314430?v=4?s=50" width="50px;" alt="avi-yadav"/><br /><sub><b>avi-yadav</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=avi-yadav" title="Code">💻</a></td> | ||
| 562 | + </tr> | ||
| 563 | + <tr> | ||
| 564 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/Letalus"><img src="https://avatars.githubusercontent.com/u/41230136?v=4?s=50" width="50px;" alt="Letalus"/><br /><sub><b>Letalus</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3ALetalus" title="Bug reports">🐛</a> <a href="#translation-Letalus" title="Translation">🌍</a></td> | ||
| 565 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/greymag"><img src="https://avatars.githubusercontent.com/u/1502131?v=4?s=50" width="50px;" alt="greymag"/><br /><sub><b>greymag</b></sub></a><br /><a href="#translation-greymag" title="Translation">🌍</a></td> | ||
| 566 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/NaikSoftware"><img src="https://avatars.githubusercontent.com/u/4218994?v=4?s=50" width="50px;" alt="Nickolay Savchenko"/><br /><sub><b>Nickolay Savchenko</b></sub></a><br /><a href="#design-NaikSoftware" title="Design">🎨</a></td> | ||
| 567 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/KosukeSaigusa"><img src="https://avatars.githubusercontent.com/u/13669049?v=4?s=50" width="50px;" alt="Kosuke Saigusa"/><br /><sub><b>Kosuke Saigusa</b></sub></a><br /><a href="#translation-KosukeSaigusa" title="Translation">🌍</a></td> | ||
| 568 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/Jon-Millent"><img src="https://avatars.githubusercontent.com/u/17584565?v=4?s=50" width="50px;" alt="三闻书店"/><br /><sub><b>三闻书店</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=Jon-Millent" title="Documentation">📖</a></td> | ||
| 569 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/didiosn"><img src="https://avatars.githubusercontent.com/u/15895051?v=4?s=50" width="50px;" alt="DidiosFaust"/><br /><sub><b>DidiosFaust</b></sub></a><br /><a href="#translation-didiosn" title="Translation">🌍</a></td> | ||
| 570 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/ConanXie"><img src="https://avatars.githubusercontent.com/u/10040846?v=4?s=50" width="50px;" alt="xiejie"/><br /><sub><b>xiejie</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3AConanXie" title="Bug reports">🐛</a></td> | ||
| 571 | + </tr> | ||
| 572 | + <tr> | ||
| 573 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/maxzod"><img src="https://avatars.githubusercontent.com/u/47630729?v=4?s=50" width="50px;" alt="Ahmed Masoud "/><br /><sub><b>Ahmed Masoud </b></sub></a><br /><a href="#translation-maxzod" title="Translation">🌍</a></td> | ||
| 574 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/luomo-pro"><img src="https://avatars.githubusercontent.com/u/41097395?v=4?s=50" width="50px;" alt="luomo-pro"/><br /><sub><b>luomo-pro</b></sub></a><br /><a href="#a11y-luomo-pro" title="Accessibility">️️️️♿️</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3Aluomo-pro" title="Bug reports">🐛</a></td> | ||
| 575 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/paigupai"><img src="https://avatars.githubusercontent.com/u/44311361?v=4?s=50" width="50px;" alt="paigupai"/><br /><sub><b>paigupai</b></sub></a><br /><a href="#translation-paigupai" title="Translation">🌍</a></td> | ||
| 576 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/taqiabdulaziz"><img src="https://avatars.githubusercontent.com/u/30410316?v=4?s=50" width="50px;" alt="Muhammad Taqi Abdul Aziz"/><br /><sub><b>Muhammad Taqi Abdul Aziz</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=taqiabdulaziz" title="Documentation">📖</a></td> | ||
| 577 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/hellohejinyu"><img src="https://avatars.githubusercontent.com/u/8766034?v=4?s=50" width="50px;" alt="何锦余"/><br /><sub><b>何锦余</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3Ahellohejinyu" title="Bug reports">🐛</a></td> | ||
| 578 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/leonpesdk"><img src="https://avatars.githubusercontent.com/u/57394644?v=4?s=50" width="50px;" alt="Leon Dudlik"/><br /><sub><b>Leon Dudlik</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3Aleonpesdk" title="Bug reports">🐛</a></td> | ||
| 579 | + <td align="center" valign="top" width="14.28%"><a href="https://www.legoffmael.fr"><img src="https://avatars.githubusercontent.com/u/22376981?v=4?s=50" width="50px;" alt="Maël"/><br /><sub><b>Maël</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=LeGoffMael" title="Code">💻</a> <a href="#maintenance-LeGoffMael" title="Maintenance">🚧</a></td> | ||
| 580 | + </tr> | ||
| 581 | + <tr> | ||
| 582 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/dddrop"><img src="https://avatars.githubusercontent.com/u/5361175?v=4?s=50" width="50px;" alt="dddrop"/><br /><sub><b>dddrop</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=dddrop" title="Code">💻</a></td> | ||
| 583 | + <td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/loinp"><img src="https://avatars.githubusercontent.com/u/34020090?v=4?s=50" width="50px;" alt="Nguyen Phuc Loi"/><br /><sub><b>Nguyen Phuc Loi</b></sub></a><br /><a href="#translation-nploi" title="Translation">🌍</a></td> | ||
| 584 | + <td align="center" valign="top" width="14.28%"><a href="https://sqlturk.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/12383547?v=4?s=50" width="50px;" alt="Cevheri"/><br /><sub><b>Cevheri</b></sub></a><br /><a href="#translation-cevheri" title="Translation">🌍</a></td> | ||
| 585 | + <td align="center" valign="top" width="14.28%"><a href="https://velog.io/@hee_mm_"><img src="https://avatars.githubusercontent.com/u/48482259?v=4?s=50" width="50px;" alt="mirimhee"/><br /><sub><b>mirimhee</b></sub></a><br /><a href="#translation-LIMMIHEE" title="Translation">🌍</a></td> | ||
| 586 | + <td align="center" valign="top" width="14.28%"><a href="https://amoshk.top"><img src="https://avatars.githubusercontent.com/u/32262985?v=4?s=50" width="50px;" alt="Amos"/><br /><sub><b>Amos</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/issues?q=author%3AAmosHuKe" title="Bug reports">🐛</a></td> | ||
| 587 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/Dimilkalathiya"><img src="https://avatars.githubusercontent.com/u/102401667?v=4?s=50" width="50px;" alt="Dimil Kalathiya"/><br /><sub><b>Dimil Kalathiya</b></sub></a><br /><a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=Dimilkalathiya" title="Code">💻</a></td> | ||
| 588 | + <td align="center" valign="top" width="14.28%"><a href="http://about.me/gasol"><img src="https://avatars.githubusercontent.com/u/108053?v=4?s=50" width="50px;" alt="Gasol Wu"/><br /><sub><b>Gasol Wu</b></sub></a><br /><a href="#translation-Gasol" title="Translation">🌍</a></td> | ||
| 589 | + </tr> | ||
| 590 | + <tr> | ||
| 591 | + <td align="center" valign="top" width="14.28%"><a href="https://github.com/WeiJun0507"><img src="https://avatars.githubusercontent.com/u/66726409?v=4?s=50" width="50px;" alt="Wei Jun"/><br /><sub><b>Wei Jun</b></sub></a><br /><a href="#business-WeiJun0507" title="Business development">💼</a> <a href="https://github.com/fluttercandies/flutter_wechat_assets_picker/commits?author=WeiJun0507" title="Code">💻</a> <a href="#ideas-WeiJun0507" title="Ideas, Planning, & Feedback">🤔</a></td> | ||
| 592 | + </tr> | ||
| 593 | + </tbody> | ||
| 594 | +</table> | ||
| 595 | + | ||
| 596 | +<!-- markdownlint-restore --> | ||
| 597 | +<!-- prettier-ignore-end --> | ||
| 598 | + | ||
| 599 | +<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
| 600 | +This project follows the | ||
| 601 | +[all-contributors](https://github.com/all-contributors/all-contributors) specification. | ||
| 602 | +Contributions of any kind welcomed!! | ||
| 603 | + | ||
| 604 | +## Credits | ||
| 605 | + | ||
| 606 | +> Every aspect of IntelliJ IDEA has been designed to maximize developer productivity. | ||
| 607 | +Together, intelligent coding assistance and ergonomic design make development not only productive but also enjoyable. | ||
| 608 | + | ||
| 609 | +Thanks to [JetBrains](https://www.jetbrains.com/?from=fluttercandies) | ||
| 610 | +for allocating free open-source licenses for IDEs | ||
| 611 | +such as [IntelliJ IDEA](https://www.jetbrains.com/idea/?from=fluttercandies). | ||
| 612 | + | ||
| 613 | +[<img src="https://github.com/fluttercandies/flutter_wechat_assets_picker/raw/main/.github/jetbrains-variant.png" width="200"/>](https://www.jetbrains.com/?from=fluttercandies) | ||
| 614 | + | ||
| 615 | + | ||
| 616 | +[photo_manager pub]: https://pub.dev/packages/photo_manager | ||
| 617 | +[extended_image pub]: https://pub.dev/packages/extended_image | ||
| 618 | +[provider pub]: https://pub.dev/packages/provider | ||
| 619 | +[video_player pub]: https://pub.dev/packages/video_player | ||
| 620 | +[wechat_camera_picker pub]: https://pub.dev/packages/wechat_camera_picker | ||
| 621 | +[Migration Guide]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/guides/migration_guide.md | ||
| 622 | +[photo_manager's API docs]: https://pub.dev/documentation/photo_manager/latest/ | ||
| 623 | +[Glide Generated API docs]: https://sjudd.github.io/glide/doc/generatedapi.html | ||
| 624 | +[Contribute custom implementations]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/example/lib/customs/CONTRIBUTING.md | ||
| 625 | +[photo_manager#561]: https://github.com/fluttercandies/flutter_photo_manager/issues/561 | ||
| 626 | +[photo_manager#from-raw-data]: https://github.com/fluttercandies/flutter_photo_manager#from-raw-data | ||
| 627 | +[photo_manager#delete-entities]: https://github.com/fluttercandies/flutter_photo_manager#delete-entities |
| 1 | +include: package:flutter_lints/flutter.yaml | ||
| 2 | + | ||
| 3 | +analyzer: | ||
| 4 | + errors: | ||
| 5 | + deprecated_member_use: ignore | ||
| 6 | + deprecated_member_use_from_same_package: ignore | ||
| 7 | + | ||
| 8 | +linter: | ||
| 9 | + rules: | ||
| 10 | + always_declare_return_types: true | ||
| 11 | + always_put_control_body_on_new_line: true | ||
| 12 | + avoid_print: true | ||
| 13 | + avoid_renaming_method_parameters: true | ||
| 14 | + avoid_unnecessary_containers: true | ||
| 15 | + avoid_void_async: true | ||
| 16 | + curly_braces_in_flow_control_structures: true | ||
| 17 | + directives_ordering: true | ||
| 18 | + flutter_style_todos: true | ||
| 19 | + library_private_types_in_public_api: false | ||
| 20 | + overridden_fields: false | ||
| 21 | + prefer_const_constructors: true | ||
| 22 | + prefer_const_constructors_in_immutables: false | ||
| 23 | + prefer_final_fields: true | ||
| 24 | + prefer_final_in_for_each: true | ||
| 25 | + prefer_final_locals: true | ||
| 26 | + prefer_single_quotes: true | ||
| 27 | + require_trailing_commas: true | ||
| 28 | + sort_child_properties_last: true | ||
| 29 | + sort_constructors_first: true | ||
| 30 | + sort_unnamed_constructors_first: true | ||
| 31 | + unnecessary_await_in_return: true | ||
| 32 | + unnecessary_breaks: true | ||
| 33 | + unnecessary_late: true | ||
| 34 | + unnecessary_parenthesis: true | ||
| 35 | + use_build_context_synchronously: false | ||
| 36 | + void_checks: true |
5.84 KB
| 1 | +<!-- Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +Use of this source code is governed by an Apache license | ||
| 3 | +that can be found in the LICENSE file. --> | ||
| 4 | + | ||
| 5 | +# WeChat Assets Picker example | ||
| 6 | + | ||
| 7 | +This is the example for the `wechat_assets_picker` package. | ||
| 8 | + | ||
| 9 | +We've put multiple common usage | ||
| 10 | +with the packages in the example. | ||
| 11 | +You can both found `List<PickMethod> pickMethods` in | ||
| 12 | +[here](lib/pages/multi_assets_page.dart) | ||
| 13 | +and [here](lib/pages/single_assets_page.dart), | ||
| 14 | +which provide methods in multiple picking and single picking mode. | ||
| 15 | +Assets will be stored temporary and displayed at the below of the page. |
| 1 | +plugins { | ||
| 2 | + id "com.android.application" | ||
| 3 | + id "kotlin-android" | ||
| 4 | + id "kotlin-kapt" | ||
| 5 | + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. | ||
| 6 | + id "dev.flutter.flutter-gradle-plugin" | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +def flutterVersionCode = null | ||
| 10 | +def flutterVersionName = null | ||
| 11 | +if (flutter.hasProperty('versionCode')) { | ||
| 12 | + flutterVersionCode = flutter.versionCode | ||
| 13 | +} | ||
| 14 | +if (flutter.hasProperty('versionName')) { | ||
| 15 | + flutterVersionName = flutter.versionName | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +if (flutterVersionCode == null || flutterVersionName == null) { | ||
| 19 | + def localProperties = new Properties() | ||
| 20 | + rootProject.file('local.properties').withReader('UTF-8') { reader -> | ||
| 21 | + localProperties.load(reader) | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + if (flutterVersionCode == null) { | ||
| 25 | + flutterVersionCode = localProperties.getProperty('flutter.versionCode') | ||
| 26 | + } | ||
| 27 | + if (flutterVersionName == null) { | ||
| 28 | + flutterVersionName = localProperties.getProperty('flutter.versionName') | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +android { | ||
| 33 | + namespace "com.fluttercandies.wechatAssetsPickerExample" | ||
| 34 | + compileSdk flutter.compileSdkVersion | ||
| 35 | + ndkVersion flutter.ndkVersion | ||
| 36 | + | ||
| 37 | + defaultConfig { | ||
| 38 | + applicationId = "com.fluttercandies.wechatAssetsPickerExample" | ||
| 39 | + minSdk 21 | ||
| 40 | + targetSdk flutter.targetSdkVersion | ||
| 41 | + versionCode flutterVersionCode.toInteger() | ||
| 42 | + versionName flutterVersionName | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + sourceSets { | ||
| 46 | + main.java.srcDirs += 'src/main/kotlin' | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + kotlinOptions { | ||
| 50 | + jvmTarget = '17' | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + compileOptions { | ||
| 54 | + // Sets Java compatibility to Java 17 | ||
| 55 | + sourceCompatibility JavaVersion.VERSION_17 | ||
| 56 | + targetCompatibility JavaVersion.VERSION_17 | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + signingConfigs { | ||
| 60 | + forAll { | ||
| 61 | + storeFile file("${rootDir.absolutePath}/key.jks") | ||
| 62 | + storePassword 'picker' | ||
| 63 | + keyAlias 'picker' | ||
| 64 | + keyPassword 'picker' | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + buildTypes { | ||
| 69 | + debug { | ||
| 70 | + signingConfig signingConfigs.forAll | ||
| 71 | + } | ||
| 72 | + profile { | ||
| 73 | + signingConfig signingConfigs.forAll | ||
| 74 | + } | ||
| 75 | + release { | ||
| 76 | + signingConfig signingConfigs.forAll | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +flutter { | ||
| 82 | + source '../..' | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +dependencies { | ||
| 86 | + implementation 'com.github.bumptech.glide:glide:4.15.0' | ||
| 87 | + kapt 'com.github.bumptech.glide:compiler:4.15.0' | ||
| 88 | +} |
| 1 | +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 2 | + <uses-permission android:name="android.permission.INTERNET" /> | ||
| 3 | + <uses-permission | ||
| 4 | + android:name="android.permission.WRITE_EXTERNAL_STORAGE" | ||
| 5 | + android:maxSdkVersion="28"/> | ||
| 6 | + | ||
| 7 | + <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> | ||
| 8 | + <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> | ||
| 9 | + <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> | ||
| 10 | + <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" /> | ||
| 11 | + | ||
| 12 | + <application | ||
| 13 | + android:label="Wechat Assets Picker Example" | ||
| 14 | + android:name="${applicationName}" | ||
| 15 | + android:icon="@mipmap/ic_launcher" | ||
| 16 | + android:allowBackup="false"> | ||
| 17 | + <activity | ||
| 18 | + android:name=".MainActivity" | ||
| 19 | + android:exported="true" | ||
| 20 | + android:launchMode="singleTop" | ||
| 21 | + android:theme="@style/LaunchTheme" | ||
| 22 | + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||
| 23 | + android:hardwareAccelerated="true" | ||
| 24 | + android:windowSoftInputMode="adjustResize"> | ||
| 25 | + <!-- Specifies an Android theme to apply to this Activity as soon as | ||
| 26 | + the Android process has started. This theme is visible to the user | ||
| 27 | + while the Flutter UI initializes. After that, this theme continues | ||
| 28 | + to determine the Window background behind the Flutter UI. --> | ||
| 29 | + <meta-data | ||
| 30 | + android:name="io.flutter.embedding.android.NormalTheme" | ||
| 31 | + android:resource="@style/NormalTheme" | ||
| 32 | + /> | ||
| 33 | + <intent-filter> | ||
| 34 | + <action android:name="android.intent.action.MAIN"/> | ||
| 35 | + <category android:name="android.intent.category.LAUNCHER"/> | ||
| 36 | + </intent-filter> | ||
| 37 | + </activity> | ||
| 38 | + <!-- Don't delete the meta-data below. | ||
| 39 | + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | ||
| 40 | + <meta-data | ||
| 41 | + android:name="flutterEmbedding" | ||
| 42 | + android:value="2" /> | ||
| 43 | + </application> | ||
| 44 | + <!-- Required to query activities that can process text, see: | ||
| 45 | + https://developer.android.com/training/package-visibility?hl=en and | ||
| 46 | + https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. | ||
| 47 | + | ||
| 48 | + In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> | ||
| 49 | + <queries> | ||
| 50 | + <intent> | ||
| 51 | + <action android:name="android.intent.action.PROCESS_TEXT"/> | ||
| 52 | + <data android:mimeType="text/plain"/> | ||
| 53 | + </intent> | ||
| 54 | + </queries> | ||
| 55 | +</manifest> |
| 1 | +package io.flutter.plugins; | ||
| 2 | + | ||
| 3 | +import androidx.annotation.Keep; | ||
| 4 | +import androidx.annotation.NonNull; | ||
| 5 | +import io.flutter.Log; | ||
| 6 | + | ||
| 7 | +import io.flutter.embedding.engine.FlutterEngine; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * Generated file. Do not edit. | ||
| 11 | + * This file is generated by the Flutter tool based on the | ||
| 12 | + * plugins that support the Android platform. | ||
| 13 | + */ | ||
| 14 | +@Keep | ||
| 15 | +public final class GeneratedPluginRegistrant { | ||
| 16 | + private static final String TAG = "GeneratedPluginRegistrant"; | ||
| 17 | + public static void registerWith(@NonNull FlutterEngine flutterEngine) { | ||
| 18 | + try { | ||
| 19 | + flutterEngine.getPlugins().add(new io.flutter.plugins.camera.CameraPlugin()); | ||
| 20 | + } catch (Exception e) { | ||
| 21 | + Log.e(TAG, "Error registering plugin camera_android, io.flutter.plugins.camera.CameraPlugin", e); | ||
| 22 | + } | ||
| 23 | + try { | ||
| 24 | + flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin()); | ||
| 25 | + } catch (Exception e) { | ||
| 26 | + Log.e(TAG, "Error registering plugin flutter_plugin_android_lifecycle, io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin", e); | ||
| 27 | + } | ||
| 28 | + try { | ||
| 29 | + flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.packageinfo.PackageInfoPlugin()); | ||
| 30 | + } catch (Exception e) { | ||
| 31 | + Log.e(TAG, "Error registering plugin package_info_plus, dev.fluttercommunity.plus.packageinfo.PackageInfoPlugin", e); | ||
| 32 | + } | ||
| 33 | + try { | ||
| 34 | + flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin()); | ||
| 35 | + } catch (Exception e) { | ||
| 36 | + Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e); | ||
| 37 | + } | ||
| 38 | + try { | ||
| 39 | + flutterEngine.getPlugins().add(new com.fluttercandies.photo_manager.PhotoManagerPlugin()); | ||
| 40 | + } catch (Exception e) { | ||
| 41 | + Log.e(TAG, "Error registering plugin photo_manager, com.fluttercandies.photo_manager.PhotoManagerPlugin", e); | ||
| 42 | + } | ||
| 43 | + try { | ||
| 44 | + flutterEngine.getPlugins().add(new dev.fluttercommunity.plus.sensors.SensorsPlugin()); | ||
| 45 | + } catch (Exception e) { | ||
| 46 | + Log.e(TAG, "Error registering plugin sensors_plus, dev.fluttercommunity.plus.sensors.SensorsPlugin", e); | ||
| 47 | + } | ||
| 48 | + try { | ||
| 49 | + flutterEngine.getPlugins().add(new io.flutter.plugins.videoplayer.VideoPlayerPlugin()); | ||
| 50 | + } catch (Exception e) { | ||
| 51 | + Log.e(TAG, "Error registering plugin video_player_android, io.flutter.plugins.videoplayer.VideoPlayerPlugin", e); | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | +} |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<!-- Modify this file to customize your launch splash screen --> | ||
| 3 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 4 | + <item android:drawable="?android:colorBackground" /> | ||
| 5 | + | ||
| 6 | + <!-- You can insert your own image assets here --> | ||
| 7 | + <!-- <item> | ||
| 8 | + <bitmap | ||
| 9 | + android:gravity="center" | ||
| 10 | + android:src="@mipmap/launch_image" /> | ||
| 11 | + </item> --> | ||
| 12 | +</layer-list> |
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/drawable/launch_background.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<!-- Modify this file to customize your launch splash screen --> | ||
| 3 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| 4 | + <item android:drawable="@android:color/white" /> | ||
| 5 | + | ||
| 6 | + <!-- You can insert your own image assets here --> | ||
| 7 | + <!-- <item> | ||
| 8 | + <bitmap | ||
| 9 | + android:gravity="center" | ||
| 10 | + android:src="@mipmap/launch_image" /> | ||
| 11 | + </item> --> | ||
| 12 | +</layer-list> |
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
0 → 100644
544 Bytes
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
0 → 100644
442 Bytes
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
0 → 100644
721 Bytes
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
0 → 100644
1.01 KB
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
0 → 100644
1.41 KB
library/wechat_assets_picker-9.8.0/example/android/app/src/main/res/values-night/styles.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<resources> | ||
| 3 | + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> | ||
| 4 | + <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||
| 5 | + <!-- Show a splash screen on the activity. Automatically removed when | ||
| 6 | + the Flutter engine draws its first frame --> | ||
| 7 | + <item name="android:windowBackground">@drawable/launch_background</item> | ||
| 8 | + </style> | ||
| 9 | + <!-- Theme applied to the Android Window as soon as the process has started. | ||
| 10 | + This theme determines the color of the Android Window while your | ||
| 11 | + Flutter UI initializes, as well as behind your Flutter UI while its | ||
| 12 | + running. | ||
| 13 | + | ||
| 14 | + This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||
| 15 | + <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||
| 16 | + <item name="android:windowBackground">?android:colorBackground</item> | ||
| 17 | + </style> | ||
| 18 | +</resources> |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | ||
| 2 | +<resources> | ||
| 3 | + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> | ||
| 4 | + <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||
| 5 | + <!-- Show a splash screen on the activity. Automatically removed when | ||
| 6 | + the Flutter engine draws its first frame --> | ||
| 7 | + <item name="android:windowBackground">@drawable/launch_background</item> | ||
| 8 | + </style> | ||
| 9 | + <!-- Theme applied to the Android Window as soon as the process has started. | ||
| 10 | + This theme determines the color of the Android Window while your | ||
| 11 | + Flutter UI initializes, as well as behind your Flutter UI while its | ||
| 12 | + running. | ||
| 13 | + | ||
| 14 | + This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||
| 15 | + <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||
| 16 | + <item name="android:windowBackground">?android:colorBackground</item> | ||
| 17 | + </style> | ||
| 18 | +</resources> |
| 1 | +allprojects { | ||
| 2 | + repositories { | ||
| 3 | + google() | ||
| 4 | + mavenCentral() | ||
| 5 | + } | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +rootProject.buildDir = '../build' | ||
| 9 | +subprojects { | ||
| 10 | + project.buildDir = "${rootProject.buildDir}/${project.name}" | ||
| 11 | +} | ||
| 12 | +subprojects { | ||
| 13 | + project.evaluationDependsOn(':app') | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +tasks.register("clean", Delete) { | ||
| 17 | + delete rootProject.buildDir | ||
| 18 | +} |
No preview for this file type
| 1 | +pluginManagement { | ||
| 2 | + def flutterSdkPath = { | ||
| 3 | + def properties = new Properties() | ||
| 4 | + file("local.properties").withInputStream { properties.load(it) } | ||
| 5 | + def flutterSdkPath = properties.getProperty("flutter.sdk") | ||
| 6 | + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" | ||
| 7 | + return flutterSdkPath | ||
| 8 | + }() | ||
| 9 | + | ||
| 10 | + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") | ||
| 11 | + | ||
| 12 | + repositories { | ||
| 13 | + google() | ||
| 14 | + mavenCentral() | ||
| 15 | + gradlePluginPortal() | ||
| 16 | + } | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +plugins { | ||
| 20 | + id "dev.flutter.flutter-plugin-loader" version "1.0.0" | ||
| 21 | + id "com.android.application" version "8.9.1" apply false | ||
| 22 | + id "com.android.library" version "8.9.1" apply false | ||
| 23 | + id "org.jetbrains.kotlin.android" version "2.1.20" apply false | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +include ":app" |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CFBundleDevelopmentRegion</key> | ||
| 6 | + <string>en</string> | ||
| 7 | + <key>CFBundleExecutable</key> | ||
| 8 | + <string>App</string> | ||
| 9 | + <key>CFBundleIdentifier</key> | ||
| 10 | + <string>io.flutter.flutter.app</string> | ||
| 11 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 12 | + <string>6.0</string> | ||
| 13 | + <key>CFBundleName</key> | ||
| 14 | + <string>App</string> | ||
| 15 | + <key>CFBundlePackageType</key> | ||
| 16 | + <string>FMWK</string> | ||
| 17 | + <key>CFBundleShortVersionString</key> | ||
| 18 | + <string>1.0</string> | ||
| 19 | + <key>CFBundleSignature</key> | ||
| 20 | + <string>????</string> | ||
| 21 | + <key>CFBundleVersion</key> | ||
| 22 | + <string>1.0</string> | ||
| 23 | + <key>MinimumOSVersion</key> | ||
| 24 | + <string>12.0</string> | ||
| 25 | +</dict> | ||
| 26 | +</plist> |
| 1 | +// This is a generated file; do not edit or check into version control. | ||
| 2 | +FLUTTER_ROOT=/Users/wangdongni/fvm/versions/custom_3.27.4-ohos-dev | ||
| 3 | +FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/wechat_assets_picker-9.8.0/example | ||
| 4 | +COCOAPODS_PARALLEL_CODE_SIGN=true | ||
| 5 | +FLUTTER_TARGET=lib/main.dart | ||
| 6 | +FLUTTER_BUILD_DIR=build | ||
| 7 | +FLUTTER_BUILD_NAME=9.8.0 | ||
| 8 | +FLUTTER_BUILD_NUMBER=69 | ||
| 9 | +EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 | ||
| 10 | +EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 | ||
| 11 | +DART_OBFUSCATION=false | ||
| 12 | +TRACK_WIDGET_CREATION=true | ||
| 13 | +TREE_SHAKE_ICONS=false | ||
| 14 | +PACKAGE_CONFIG=.dart_tool/package_config.json |
| 1 | +#!/bin/sh | ||
| 2 | +# This is a generated file; do not edit or check into version control. | ||
| 3 | +export "FLUTTER_ROOT=/Users/wangdongni/fvm/versions/custom_3.27.4-ohos-dev" | ||
| 4 | +export "FLUTTER_APPLICATION_PATH=/Users/wangdongni/Desktop/Flutter-ReserveApp/library/wechat_assets_picker-9.8.0/example" | ||
| 5 | +export "COCOAPODS_PARALLEL_CODE_SIGN=true" | ||
| 6 | +export "FLUTTER_TARGET=lib/main.dart" | ||
| 7 | +export "FLUTTER_BUILD_DIR=build" | ||
| 8 | +export "FLUTTER_BUILD_NAME=9.8.0" | ||
| 9 | +export "FLUTTER_BUILD_NUMBER=69" | ||
| 10 | +export "DART_OBFUSCATION=false" | ||
| 11 | +export "TRACK_WIDGET_CREATION=true" | ||
| 12 | +export "TREE_SHAKE_ICONS=false" | ||
| 13 | +export "PACKAGE_CONFIG=.dart_tool/package_config.json" |
| 1 | +# Uncomment this line to define a global platform for your project | ||
| 2 | +# platform :ios, '12.0' | ||
| 3 | + | ||
| 4 | +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. | ||
| 5 | +ENV['COCOAPODS_DISABLE_STATS'] = 'true' | ||
| 6 | + | ||
| 7 | +project 'Runner', { | ||
| 8 | + 'Debug' => :debug, | ||
| 9 | + 'Profile' => :release, | ||
| 10 | + 'Release' => :release, | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +def flutter_root | ||
| 14 | + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | ||
| 15 | + unless File.exist?(generated_xcode_build_settings_path) | ||
| 16 | + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + File.foreach(generated_xcode_build_settings_path) do |line| | ||
| 20 | + matches = line.match(/FLUTTER_ROOT\=(.*)/) | ||
| 21 | + return matches[1].strip if matches | ||
| 22 | + end | ||
| 23 | + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | ||
| 24 | +end | ||
| 25 | + | ||
| 26 | +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | ||
| 27 | + | ||
| 28 | +flutter_ios_podfile_setup | ||
| 29 | + | ||
| 30 | +target 'Runner' do | ||
| 31 | + use_frameworks! | ||
| 32 | + use_modular_headers! | ||
| 33 | + | ||
| 34 | + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | ||
| 35 | +end | ||
| 36 | + | ||
| 37 | +post_install do |installer| | ||
| 38 | + installer.pods_project.targets.each do |target| | ||
| 39 | + flutter_additional_ios_build_settings(target) | ||
| 40 | + end | ||
| 41 | +end |
| 1 | +// !$*UTF8*$! | ||
| 2 | +{ | ||
| 3 | + archiveVersion = 1; | ||
| 4 | + classes = { | ||
| 5 | + }; | ||
| 6 | + objectVersion = 54; | ||
| 7 | + objects = { | ||
| 8 | + | ||
| 9 | +/* Begin PBXBuildFile section */ | ||
| 10 | + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; | ||
| 11 | + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; | ||
| 12 | + 513FA762C8C9C7254396DC7C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65B67F314727E97056D6FB02 /* Pods_Runner.framework */; }; | ||
| 13 | + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; | ||
| 14 | + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | ||
| 15 | + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; | ||
| 16 | + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; | ||
| 17 | +/* End PBXBuildFile section */ | ||
| 18 | + | ||
| 19 | +/* Begin PBXCopyFilesBuildPhase section */ | ||
| 20 | + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { | ||
| 21 | + isa = PBXCopyFilesBuildPhase; | ||
| 22 | + buildActionMask = 2147483647; | ||
| 23 | + dstPath = ""; | ||
| 24 | + dstSubfolderSpec = 10; | ||
| 25 | + files = ( | ||
| 26 | + ); | ||
| 27 | + name = "Embed Frameworks"; | ||
| 28 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 29 | + }; | ||
| 30 | +/* End PBXCopyFilesBuildPhase section */ | ||
| 31 | + | ||
| 32 | +/* Begin PBXFileReference section */ | ||
| 33 | + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; | ||
| 34 | + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; | ||
| 35 | + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | ||
| 36 | + 65B67F314727E97056D6FB02 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 37 | + 6B0C8420452B45A5D1F1C0C7 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; | ||
| 38 | + 6C1693957F33351E0284D719 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; | ||
| 39 | + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | ||
| 40 | + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | ||
| 41 | + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; | ||
| 42 | + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; | ||
| 43 | + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; | ||
| 44 | + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 45 | + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; | ||
| 46 | + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | ||
| 47 | + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | ||
| 48 | + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||
| 49 | + FF5A0AA64F3B1C88D3552E39 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; | ||
| 50 | +/* End PBXFileReference section */ | ||
| 51 | + | ||
| 52 | +/* Begin PBXFrameworksBuildPhase section */ | ||
| 53 | + 97C146EB1CF9000F007C117D /* Frameworks */ = { | ||
| 54 | + isa = PBXFrameworksBuildPhase; | ||
| 55 | + buildActionMask = 2147483647; | ||
| 56 | + files = ( | ||
| 57 | + 513FA762C8C9C7254396DC7C /* Pods_Runner.framework in Frameworks */, | ||
| 58 | + ); | ||
| 59 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 60 | + }; | ||
| 61 | +/* End PBXFrameworksBuildPhase section */ | ||
| 62 | + | ||
| 63 | +/* Begin PBXGroup section */ | ||
| 64 | + 075E26373E1C2C8E97B8BDA5 /* Frameworks */ = { | ||
| 65 | + isa = PBXGroup; | ||
| 66 | + children = ( | ||
| 67 | + 65B67F314727E97056D6FB02 /* Pods_Runner.framework */, | ||
| 68 | + ); | ||
| 69 | + name = Frameworks; | ||
| 70 | + sourceTree = "<group>"; | ||
| 71 | + }; | ||
| 72 | + 9482DB91E3C799F148919200 /* Pods */ = { | ||
| 73 | + isa = PBXGroup; | ||
| 74 | + children = ( | ||
| 75 | + 6C1693957F33351E0284D719 /* Pods-Runner.debug.xcconfig */, | ||
| 76 | + FF5A0AA64F3B1C88D3552E39 /* Pods-Runner.release.xcconfig */, | ||
| 77 | + 6B0C8420452B45A5D1F1C0C7 /* Pods-Runner.profile.xcconfig */, | ||
| 78 | + ); | ||
| 79 | + path = Pods; | ||
| 80 | + sourceTree = "<group>"; | ||
| 81 | + }; | ||
| 82 | + 9740EEB11CF90186004384FC /* Flutter */ = { | ||
| 83 | + isa = PBXGroup; | ||
| 84 | + children = ( | ||
| 85 | + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, | ||
| 86 | + 9740EEB21CF90195004384FC /* Debug.xcconfig */, | ||
| 87 | + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, | ||
| 88 | + 9740EEB31CF90195004384FC /* Generated.xcconfig */, | ||
| 89 | + ); | ||
| 90 | + name = Flutter; | ||
| 91 | + sourceTree = "<group>"; | ||
| 92 | + }; | ||
| 93 | + 97C146E51CF9000F007C117D = { | ||
| 94 | + isa = PBXGroup; | ||
| 95 | + children = ( | ||
| 96 | + 9740EEB11CF90186004384FC /* Flutter */, | ||
| 97 | + 97C146F01CF9000F007C117D /* Runner */, | ||
| 98 | + 97C146EF1CF9000F007C117D /* Products */, | ||
| 99 | + 9482DB91E3C799F148919200 /* Pods */, | ||
| 100 | + 075E26373E1C2C8E97B8BDA5 /* Frameworks */, | ||
| 101 | + ); | ||
| 102 | + sourceTree = "<group>"; | ||
| 103 | + }; | ||
| 104 | + 97C146EF1CF9000F007C117D /* Products */ = { | ||
| 105 | + isa = PBXGroup; | ||
| 106 | + children = ( | ||
| 107 | + 97C146EE1CF9000F007C117D /* Runner.app */, | ||
| 108 | + ); | ||
| 109 | + name = Products; | ||
| 110 | + sourceTree = "<group>"; | ||
| 111 | + }; | ||
| 112 | + 97C146F01CF9000F007C117D /* Runner */ = { | ||
| 113 | + isa = PBXGroup; | ||
| 114 | + children = ( | ||
| 115 | + 97C146FA1CF9000F007C117D /* Main.storyboard */, | ||
| 116 | + 97C146FD1CF9000F007C117D /* Assets.xcassets */, | ||
| 117 | + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, | ||
| 118 | + 97C147021CF9000F007C117D /* Info.plist */, | ||
| 119 | + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | ||
| 120 | + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | ||
| 121 | + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, | ||
| 122 | + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, | ||
| 123 | + ); | ||
| 124 | + path = Runner; | ||
| 125 | + sourceTree = "<group>"; | ||
| 126 | + }; | ||
| 127 | +/* End PBXGroup section */ | ||
| 128 | + | ||
| 129 | +/* Begin PBXNativeTarget section */ | ||
| 130 | + 97C146ED1CF9000F007C117D /* Runner */ = { | ||
| 131 | + isa = PBXNativeTarget; | ||
| 132 | + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; | ||
| 133 | + buildPhases = ( | ||
| 134 | + 71ACE8DF3F7938AC5EF5C276 /* [CP] Check Pods Manifest.lock */, | ||
| 135 | + 9740EEB61CF901F6004384FC /* Run Script */, | ||
| 136 | + 97C146EA1CF9000F007C117D /* Sources */, | ||
| 137 | + 97C146EB1CF9000F007C117D /* Frameworks */, | ||
| 138 | + 97C146EC1CF9000F007C117D /* Resources */, | ||
| 139 | + 9705A1C41CF9048500538489 /* Embed Frameworks */, | ||
| 140 | + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, | ||
| 141 | + 950F336F7D4BCE35DBE7FE4C /* [CP] Embed Pods Frameworks */, | ||
| 142 | + ); | ||
| 143 | + buildRules = ( | ||
| 144 | + ); | ||
| 145 | + dependencies = ( | ||
| 146 | + ); | ||
| 147 | + name = Runner; | ||
| 148 | + productName = Runner; | ||
| 149 | + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; | ||
| 150 | + productType = "com.apple.product-type.application"; | ||
| 151 | + }; | ||
| 152 | +/* End PBXNativeTarget section */ | ||
| 153 | + | ||
| 154 | +/* Begin PBXProject section */ | ||
| 155 | + 97C146E61CF9000F007C117D /* Project object */ = { | ||
| 156 | + isa = PBXProject; | ||
| 157 | + attributes = { | ||
| 158 | + BuildIndependentTargetsInParallel = YES; | ||
| 159 | + LastUpgradeCheck = 1510; | ||
| 160 | + ORGANIZATIONNAME = ""; | ||
| 161 | + TargetAttributes = { | ||
| 162 | + 97C146ED1CF9000F007C117D = { | ||
| 163 | + CreatedOnToolsVersion = 7.3.1; | ||
| 164 | + LastSwiftMigration = 1100; | ||
| 165 | + }; | ||
| 166 | + }; | ||
| 167 | + }; | ||
| 168 | + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; | ||
| 169 | + compatibilityVersion = "Xcode 9.3"; | ||
| 170 | + developmentRegion = en; | ||
| 171 | + hasScannedForEncodings = 0; | ||
| 172 | + knownRegions = ( | ||
| 173 | + en, | ||
| 174 | + Base, | ||
| 175 | + ); | ||
| 176 | + mainGroup = 97C146E51CF9000F007C117D; | ||
| 177 | + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; | ||
| 178 | + projectDirPath = ""; | ||
| 179 | + projectRoot = ""; | ||
| 180 | + targets = ( | ||
| 181 | + 97C146ED1CF9000F007C117D /* Runner */, | ||
| 182 | + ); | ||
| 183 | + }; | ||
| 184 | +/* End PBXProject section */ | ||
| 185 | + | ||
| 186 | +/* Begin PBXResourcesBuildPhase section */ | ||
| 187 | + 97C146EC1CF9000F007C117D /* Resources */ = { | ||
| 188 | + isa = PBXResourcesBuildPhase; | ||
| 189 | + buildActionMask = 2147483647; | ||
| 190 | + files = ( | ||
| 191 | + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, | ||
| 192 | + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, | ||
| 193 | + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, | ||
| 194 | + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, | ||
| 195 | + ); | ||
| 196 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 197 | + }; | ||
| 198 | +/* End PBXResourcesBuildPhase section */ | ||
| 199 | + | ||
| 200 | +/* Begin PBXShellScriptBuildPhase section */ | ||
| 201 | + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { | ||
| 202 | + isa = PBXShellScriptBuildPhase; | ||
| 203 | + alwaysOutOfDate = 1; | ||
| 204 | + buildActionMask = 2147483647; | ||
| 205 | + files = ( | ||
| 206 | + ); | ||
| 207 | + inputPaths = ( | ||
| 208 | + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", | ||
| 209 | + ); | ||
| 210 | + name = "Thin Binary"; | ||
| 211 | + outputPaths = ( | ||
| 212 | + ); | ||
| 213 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 214 | + shellPath = /bin/sh; | ||
| 215 | + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; | ||
| 216 | + }; | ||
| 217 | + 71ACE8DF3F7938AC5EF5C276 /* [CP] Check Pods Manifest.lock */ = { | ||
| 218 | + isa = PBXShellScriptBuildPhase; | ||
| 219 | + buildActionMask = 2147483647; | ||
| 220 | + files = ( | ||
| 221 | + ); | ||
| 222 | + inputFileListPaths = ( | ||
| 223 | + ); | ||
| 224 | + inputPaths = ( | ||
| 225 | + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | ||
| 226 | + "${PODS_ROOT}/Manifest.lock", | ||
| 227 | + ); | ||
| 228 | + name = "[CP] Check Pods Manifest.lock"; | ||
| 229 | + outputFileListPaths = ( | ||
| 230 | + ); | ||
| 231 | + outputPaths = ( | ||
| 232 | + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", | ||
| 233 | + ); | ||
| 234 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 235 | + shellPath = /bin/sh; | ||
| 236 | + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | ||
| 237 | + showEnvVarsInLog = 0; | ||
| 238 | + }; | ||
| 239 | + 950F336F7D4BCE35DBE7FE4C /* [CP] Embed Pods Frameworks */ = { | ||
| 240 | + isa = PBXShellScriptBuildPhase; | ||
| 241 | + buildActionMask = 2147483647; | ||
| 242 | + files = ( | ||
| 243 | + ); | ||
| 244 | + inputFileListPaths = ( | ||
| 245 | + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", | ||
| 246 | + ); | ||
| 247 | + name = "[CP] Embed Pods Frameworks"; | ||
| 248 | + outputFileListPaths = ( | ||
| 249 | + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", | ||
| 250 | + ); | ||
| 251 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 252 | + shellPath = /bin/sh; | ||
| 253 | + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; | ||
| 254 | + showEnvVarsInLog = 0; | ||
| 255 | + }; | ||
| 256 | + 9740EEB61CF901F6004384FC /* Run Script */ = { | ||
| 257 | + isa = PBXShellScriptBuildPhase; | ||
| 258 | + alwaysOutOfDate = 1; | ||
| 259 | + buildActionMask = 2147483647; | ||
| 260 | + files = ( | ||
| 261 | + ); | ||
| 262 | + inputPaths = ( | ||
| 263 | + ); | ||
| 264 | + name = "Run Script"; | ||
| 265 | + outputPaths = ( | ||
| 266 | + ); | ||
| 267 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 268 | + shellPath = /bin/sh; | ||
| 269 | + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; | ||
| 270 | + }; | ||
| 271 | +/* End PBXShellScriptBuildPhase section */ | ||
| 272 | + | ||
| 273 | +/* Begin PBXSourcesBuildPhase section */ | ||
| 274 | + 97C146EA1CF9000F007C117D /* Sources */ = { | ||
| 275 | + isa = PBXSourcesBuildPhase; | ||
| 276 | + buildActionMask = 2147483647; | ||
| 277 | + files = ( | ||
| 278 | + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, | ||
| 279 | + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | ||
| 280 | + ); | ||
| 281 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 282 | + }; | ||
| 283 | +/* End PBXSourcesBuildPhase section */ | ||
| 284 | + | ||
| 285 | +/* Begin PBXVariantGroup section */ | ||
| 286 | + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { | ||
| 287 | + isa = PBXVariantGroup; | ||
| 288 | + children = ( | ||
| 289 | + 97C146FB1CF9000F007C117D /* Base */, | ||
| 290 | + ); | ||
| 291 | + name = Main.storyboard; | ||
| 292 | + sourceTree = "<group>"; | ||
| 293 | + }; | ||
| 294 | + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { | ||
| 295 | + isa = PBXVariantGroup; | ||
| 296 | + children = ( | ||
| 297 | + 97C147001CF9000F007C117D /* Base */, | ||
| 298 | + ); | ||
| 299 | + name = LaunchScreen.storyboard; | ||
| 300 | + sourceTree = "<group>"; | ||
| 301 | + }; | ||
| 302 | +/* End PBXVariantGroup section */ | ||
| 303 | + | ||
| 304 | +/* Begin XCBuildConfiguration section */ | ||
| 305 | + 249021D3217E4FDB00AE95B9 /* Profile */ = { | ||
| 306 | + isa = XCBuildConfiguration; | ||
| 307 | + buildSettings = { | ||
| 308 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 309 | + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||
| 310 | + CLANG_ANALYZER_NONNULL = YES; | ||
| 311 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 312 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 313 | + CLANG_ENABLE_MODULES = YES; | ||
| 314 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 315 | + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||
| 316 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 317 | + CLANG_WARN_COMMA = YES; | ||
| 318 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 319 | + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||
| 320 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 321 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 322 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 323 | + CLANG_WARN_INFINITE_RECURSION = YES; | ||
| 324 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 325 | + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||
| 326 | + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||
| 327 | + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||
| 328 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 329 | + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||
| 330 | + CLANG_WARN_STRICT_PROTOTYPES = YES; | ||
| 331 | + CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||
| 332 | + CLANG_WARN_UNREACHABLE_CODE = YES; | ||
| 333 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 334 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 335 | + COPY_PHASE_STRIP = NO; | ||
| 336 | + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||
| 337 | + ENABLE_NS_ASSERTIONS = NO; | ||
| 338 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | ||
| 339 | + ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||
| 340 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 341 | + GCC_NO_COMMON_BLOCKS = YES; | ||
| 342 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 343 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 344 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 345 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 346 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 347 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 348 | + IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||
| 349 | + MTL_ENABLE_DEBUG_INFO = NO; | ||
| 350 | + SDKROOT = iphoneos; | ||
| 351 | + SUPPORTED_PLATFORMS = iphoneos; | ||
| 352 | + TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 353 | + VALIDATE_PRODUCT = YES; | ||
| 354 | + }; | ||
| 355 | + name = Profile; | ||
| 356 | + }; | ||
| 357 | + 249021D4217E4FDB00AE95B9 /* Profile */ = { | ||
| 358 | + isa = XCBuildConfiguration; | ||
| 359 | + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||
| 360 | + buildSettings = { | ||
| 361 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 362 | + CLANG_ENABLE_MODULES = YES; | ||
| 363 | + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||
| 364 | + DEVELOPMENT_TEAM = 64MAFNBS88; | ||
| 365 | + ENABLE_BITCODE = NO; | ||
| 366 | + INFOPLIST_FILE = Runner/Info.plist; | ||
| 367 | + LD_RUNPATH_SEARCH_PATHS = ( | ||
| 368 | + "$(inherited)", | ||
| 369 | + "@executable_path/Frameworks", | ||
| 370 | + ); | ||
| 371 | + PRODUCT_BUNDLE_IDENTIFIER = com.fluttercandies.wechatAssetsPickerDemo; | ||
| 372 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 373 | + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| 374 | + SWIFT_VERSION = 5.0; | ||
| 375 | + VERSIONING_SYSTEM = "apple-generic"; | ||
| 376 | + }; | ||
| 377 | + name = Profile; | ||
| 378 | + }; | ||
| 379 | + 97C147031CF9000F007C117D /* Debug */ = { | ||
| 380 | + isa = XCBuildConfiguration; | ||
| 381 | + buildSettings = { | ||
| 382 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 383 | + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||
| 384 | + CLANG_ANALYZER_NONNULL = YES; | ||
| 385 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 386 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 387 | + CLANG_ENABLE_MODULES = YES; | ||
| 388 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 389 | + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||
| 390 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 391 | + CLANG_WARN_COMMA = YES; | ||
| 392 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 393 | + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||
| 394 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 395 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 396 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 397 | + CLANG_WARN_INFINITE_RECURSION = YES; | ||
| 398 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 399 | + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||
| 400 | + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||
| 401 | + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||
| 402 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 403 | + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||
| 404 | + CLANG_WARN_STRICT_PROTOTYPES = YES; | ||
| 405 | + CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||
| 406 | + CLANG_WARN_UNREACHABLE_CODE = YES; | ||
| 407 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 408 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 409 | + COPY_PHASE_STRIP = NO; | ||
| 410 | + DEBUG_INFORMATION_FORMAT = dwarf; | ||
| 411 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | ||
| 412 | + ENABLE_TESTABILITY = YES; | ||
| 413 | + ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||
| 414 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 415 | + GCC_DYNAMIC_NO_PIC = NO; | ||
| 416 | + GCC_NO_COMMON_BLOCKS = YES; | ||
| 417 | + GCC_OPTIMIZATION_LEVEL = 0; | ||
| 418 | + GCC_PREPROCESSOR_DEFINITIONS = ( | ||
| 419 | + "DEBUG=1", | ||
| 420 | + "$(inherited)", | ||
| 421 | + ); | ||
| 422 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 423 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 424 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 425 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 426 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 427 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 428 | + IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||
| 429 | + MTL_ENABLE_DEBUG_INFO = YES; | ||
| 430 | + ONLY_ACTIVE_ARCH = YES; | ||
| 431 | + SDKROOT = iphoneos; | ||
| 432 | + TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 433 | + }; | ||
| 434 | + name = Debug; | ||
| 435 | + }; | ||
| 436 | + 97C147041CF9000F007C117D /* Release */ = { | ||
| 437 | + isa = XCBuildConfiguration; | ||
| 438 | + buildSettings = { | ||
| 439 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 440 | + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||
| 441 | + CLANG_ANALYZER_NONNULL = YES; | ||
| 442 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 443 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 444 | + CLANG_ENABLE_MODULES = YES; | ||
| 445 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 446 | + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||
| 447 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 448 | + CLANG_WARN_COMMA = YES; | ||
| 449 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 450 | + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||
| 451 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 452 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 453 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 454 | + CLANG_WARN_INFINITE_RECURSION = YES; | ||
| 455 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 456 | + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||
| 457 | + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||
| 458 | + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||
| 459 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 460 | + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||
| 461 | + CLANG_WARN_STRICT_PROTOTYPES = YES; | ||
| 462 | + CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||
| 463 | + CLANG_WARN_UNREACHABLE_CODE = YES; | ||
| 464 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 465 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 466 | + COPY_PHASE_STRIP = NO; | ||
| 467 | + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||
| 468 | + ENABLE_NS_ASSERTIONS = NO; | ||
| 469 | + ENABLE_STRICT_OBJC_MSGSEND = YES; | ||
| 470 | + ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||
| 471 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 472 | + GCC_NO_COMMON_BLOCKS = YES; | ||
| 473 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 474 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 475 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 476 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 477 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 478 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 479 | + IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||
| 480 | + MTL_ENABLE_DEBUG_INFO = NO; | ||
| 481 | + SDKROOT = iphoneos; | ||
| 482 | + SUPPORTED_PLATFORMS = iphoneos; | ||
| 483 | + SWIFT_COMPILATION_MODE = wholemodule; | ||
| 484 | + SWIFT_OPTIMIZATION_LEVEL = "-O"; | ||
| 485 | + TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 486 | + VALIDATE_PRODUCT = YES; | ||
| 487 | + }; | ||
| 488 | + name = Release; | ||
| 489 | + }; | ||
| 490 | + 97C147061CF9000F007C117D /* Debug */ = { | ||
| 491 | + isa = XCBuildConfiguration; | ||
| 492 | + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; | ||
| 493 | + buildSettings = { | ||
| 494 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 495 | + CLANG_ENABLE_MODULES = YES; | ||
| 496 | + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||
| 497 | + DEVELOPMENT_TEAM = 64MAFNBS88; | ||
| 498 | + ENABLE_BITCODE = NO; | ||
| 499 | + INFOPLIST_FILE = Runner/Info.plist; | ||
| 500 | + LD_RUNPATH_SEARCH_PATHS = ( | ||
| 501 | + "$(inherited)", | ||
| 502 | + "@executable_path/Frameworks", | ||
| 503 | + ); | ||
| 504 | + PRODUCT_BUNDLE_IDENTIFIER = com.fluttercandies.wechatAssetsPickerDemo; | ||
| 505 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 506 | + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| 507 | + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | ||
| 508 | + SWIFT_VERSION = 5.0; | ||
| 509 | + VERSIONING_SYSTEM = "apple-generic"; | ||
| 510 | + }; | ||
| 511 | + name = Debug; | ||
| 512 | + }; | ||
| 513 | + 97C147071CF9000F007C117D /* Release */ = { | ||
| 514 | + isa = XCBuildConfiguration; | ||
| 515 | + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||
| 516 | + buildSettings = { | ||
| 517 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 518 | + CLANG_ENABLE_MODULES = YES; | ||
| 519 | + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||
| 520 | + DEVELOPMENT_TEAM = 64MAFNBS88; | ||
| 521 | + ENABLE_BITCODE = NO; | ||
| 522 | + INFOPLIST_FILE = Runner/Info.plist; | ||
| 523 | + LD_RUNPATH_SEARCH_PATHS = ( | ||
| 524 | + "$(inherited)", | ||
| 525 | + "@executable_path/Frameworks", | ||
| 526 | + ); | ||
| 527 | + PRODUCT_BUNDLE_IDENTIFIER = com.fluttercandies.wechatAssetsPickerDemo; | ||
| 528 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 529 | + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||
| 530 | + SWIFT_VERSION = 5.0; | ||
| 531 | + VERSIONING_SYSTEM = "apple-generic"; | ||
| 532 | + }; | ||
| 533 | + name = Release; | ||
| 534 | + }; | ||
| 535 | +/* End XCBuildConfiguration section */ | ||
| 536 | + | ||
| 537 | +/* Begin XCConfigurationList section */ | ||
| 538 | + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { | ||
| 539 | + isa = XCConfigurationList; | ||
| 540 | + buildConfigurations = ( | ||
| 541 | + 97C147031CF9000F007C117D /* Debug */, | ||
| 542 | + 97C147041CF9000F007C117D /* Release */, | ||
| 543 | + 249021D3217E4FDB00AE95B9 /* Profile */, | ||
| 544 | + ); | ||
| 545 | + defaultConfigurationIsVisible = 0; | ||
| 546 | + defaultConfigurationName = Release; | ||
| 547 | + }; | ||
| 548 | + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { | ||
| 549 | + isa = XCConfigurationList; | ||
| 550 | + buildConfigurations = ( | ||
| 551 | + 97C147061CF9000F007C117D /* Debug */, | ||
| 552 | + 97C147071CF9000F007C117D /* Release */, | ||
| 553 | + 249021D4217E4FDB00AE95B9 /* Profile */, | ||
| 554 | + ); | ||
| 555 | + defaultConfigurationIsVisible = 0; | ||
| 556 | + defaultConfigurationName = Release; | ||
| 557 | + }; | ||
| 558 | +/* End XCConfigurationList section */ | ||
| 559 | + }; | ||
| 560 | + rootObject = 97C146E61CF9000F007C117D /* Project object */; | ||
| 561 | +} |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<Scheme | ||
| 3 | + LastUpgradeVersion = "1510" | ||
| 4 | + version = "1.3"> | ||
| 5 | + <BuildAction | ||
| 6 | + parallelizeBuildables = "YES" | ||
| 7 | + buildImplicitDependencies = "YES"> | ||
| 8 | + <BuildActionEntries> | ||
| 9 | + <BuildActionEntry | ||
| 10 | + buildForTesting = "YES" | ||
| 11 | + buildForRunning = "YES" | ||
| 12 | + buildForProfiling = "YES" | ||
| 13 | + buildForArchiving = "YES" | ||
| 14 | + buildForAnalyzing = "YES"> | ||
| 15 | + <BuildableReference | ||
| 16 | + BuildableIdentifier = "primary" | ||
| 17 | + BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||
| 18 | + BuildableName = "Runner.app" | ||
| 19 | + BlueprintName = "Runner" | ||
| 20 | + ReferencedContainer = "container:Runner.xcodeproj"> | ||
| 21 | + </BuildableReference> | ||
| 22 | + </BuildActionEntry> | ||
| 23 | + </BuildActionEntries> | ||
| 24 | + </BuildAction> | ||
| 25 | + <TestAction | ||
| 26 | + buildConfiguration = "Debug" | ||
| 27 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 28 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 29 | + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" | ||
| 30 | + shouldUseLaunchSchemeArgsEnv = "YES"> | ||
| 31 | + <MacroExpansion> | ||
| 32 | + <BuildableReference | ||
| 33 | + BuildableIdentifier = "primary" | ||
| 34 | + BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||
| 35 | + BuildableName = "Runner.app" | ||
| 36 | + BlueprintName = "Runner" | ||
| 37 | + ReferencedContainer = "container:Runner.xcodeproj"> | ||
| 38 | + </BuildableReference> | ||
| 39 | + </MacroExpansion> | ||
| 40 | + <Testables> | ||
| 41 | + <TestableReference | ||
| 42 | + skipped = "NO" | ||
| 43 | + parallelizable = "YES"> | ||
| 44 | + <BuildableReference | ||
| 45 | + BuildableIdentifier = "primary" | ||
| 46 | + BlueprintIdentifier = "331C8080294A63A400263BE5" | ||
| 47 | + BuildableName = "RunnerTests.xctest" | ||
| 48 | + BlueprintName = "RunnerTests" | ||
| 49 | + ReferencedContainer = "container:Runner.xcodeproj"> | ||
| 50 | + </BuildableReference> | ||
| 51 | + </TestableReference> | ||
| 52 | + </Testables> | ||
| 53 | + </TestAction> | ||
| 54 | + <LaunchAction | ||
| 55 | + buildConfiguration = "Debug" | ||
| 56 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 57 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 58 | + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" | ||
| 59 | + launchStyle = "0" | ||
| 60 | + useCustomWorkingDirectory = "NO" | ||
| 61 | + ignoresPersistentStateOnLaunch = "NO" | ||
| 62 | + debugDocumentVersioning = "YES" | ||
| 63 | + debugServiceExtension = "internal" | ||
| 64 | + enableGPUValidationMode = "1" | ||
| 65 | + allowLocationSimulation = "YES"> | ||
| 66 | + <BuildableProductRunnable | ||
| 67 | + runnableDebuggingMode = "0"> | ||
| 68 | + <BuildableReference | ||
| 69 | + BuildableIdentifier = "primary" | ||
| 70 | + BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||
| 71 | + BuildableName = "Runner.app" | ||
| 72 | + BlueprintName = "Runner" | ||
| 73 | + ReferencedContainer = "container:Runner.xcodeproj"> | ||
| 74 | + </BuildableReference> | ||
| 75 | + </BuildableProductRunnable> | ||
| 76 | + </LaunchAction> | ||
| 77 | + <ProfileAction | ||
| 78 | + buildConfiguration = "Profile" | ||
| 79 | + shouldUseLaunchSchemeArgsEnv = "YES" | ||
| 80 | + savedToolIdentifier = "" | ||
| 81 | + useCustomWorkingDirectory = "NO" | ||
| 82 | + debugDocumentVersioning = "YES"> | ||
| 83 | + <BuildableProductRunnable | ||
| 84 | + runnableDebuggingMode = "0"> | ||
| 85 | + <BuildableReference | ||
| 86 | + BuildableIdentifier = "primary" | ||
| 87 | + BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||
| 88 | + BuildableName = "Runner.app" | ||
| 89 | + BlueprintName = "Runner" | ||
| 90 | + ReferencedContainer = "container:Runner.xcodeproj"> | ||
| 91 | + </BuildableReference> | ||
| 92 | + </BuildableProductRunnable> | ||
| 93 | + </ProfileAction> | ||
| 94 | + <AnalyzeAction | ||
| 95 | + buildConfiguration = "Debug"> | ||
| 96 | + </AnalyzeAction> | ||
| 97 | + <ArchiveAction | ||
| 98 | + buildConfiguration = "Release" | ||
| 99 | + revealArchiveInOrganizer = "YES"> | ||
| 100 | + </ArchiveAction> | ||
| 101 | +</Scheme> |
| 1 | +import UIKit | ||
| 2 | +import Flutter | ||
| 3 | + | ||
| 4 | +@main | ||
| 5 | +@objc class AppDelegate: FlutterAppDelegate { | ||
| 6 | + override func application( | ||
| 7 | + _ application: UIApplication, | ||
| 8 | + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||
| 9 | + ) -> Bool { | ||
| 10 | + GeneratedPluginRegistrant.register(with: self) | ||
| 11 | + return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||
| 12 | + } | ||
| 13 | +} |
| 1 | +{ | ||
| 2 | + "images":[ | ||
| 3 | + { | ||
| 4 | + "idiom":"iphone", | ||
| 5 | + "size":"20x20", | ||
| 6 | + "scale":"2x", | ||
| 7 | + "filename":"Icon-App-20x20@2x.png" | ||
| 8 | + }, | ||
| 9 | + { | ||
| 10 | + "idiom":"iphone", | ||
| 11 | + "size":"20x20", | ||
| 12 | + "scale":"3x", | ||
| 13 | + "filename":"Icon-App-20x20@3x.png" | ||
| 14 | + }, | ||
| 15 | + { | ||
| 16 | + "idiom":"iphone", | ||
| 17 | + "size":"29x29", | ||
| 18 | + "scale":"1x", | ||
| 19 | + "filename":"Icon-App-29x29@1x.png" | ||
| 20 | + }, | ||
| 21 | + { | ||
| 22 | + "idiom":"iphone", | ||
| 23 | + "size":"29x29", | ||
| 24 | + "scale":"2x", | ||
| 25 | + "filename":"Icon-App-29x29@2x.png" | ||
| 26 | + }, | ||
| 27 | + { | ||
| 28 | + "idiom":"iphone", | ||
| 29 | + "size":"29x29", | ||
| 30 | + "scale":"3x", | ||
| 31 | + "filename":"Icon-App-29x29@3x.png" | ||
| 32 | + }, | ||
| 33 | + { | ||
| 34 | + "idiom":"iphone", | ||
| 35 | + "size":"40x40", | ||
| 36 | + "scale":"2x", | ||
| 37 | + "filename":"Icon-App-40x40@2x.png" | ||
| 38 | + }, | ||
| 39 | + { | ||
| 40 | + "idiom":"iphone", | ||
| 41 | + "size":"40x40", | ||
| 42 | + "scale":"3x", | ||
| 43 | + "filename":"Icon-App-40x40@3x.png" | ||
| 44 | + }, | ||
| 45 | + { | ||
| 46 | + "idiom":"iphone", | ||
| 47 | + "size":"60x60", | ||
| 48 | + "scale":"2x", | ||
| 49 | + "filename":"Icon-App-60x60@2x.png" | ||
| 50 | + }, | ||
| 51 | + { | ||
| 52 | + "idiom":"iphone", | ||
| 53 | + "size":"60x60", | ||
| 54 | + "scale":"3x", | ||
| 55 | + "filename":"Icon-App-60x60@3x.png" | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + "idiom":"iphone", | ||
| 59 | + "size":"76x76", | ||
| 60 | + "scale":"2x", | ||
| 61 | + "filename":"Icon-App-76x76@2x.png" | ||
| 62 | + }, | ||
| 63 | + { | ||
| 64 | + "idiom":"ipad", | ||
| 65 | + "size":"20x20", | ||
| 66 | + "scale":"1x", | ||
| 67 | + "filename":"Icon-App-20x20@1x.png" | ||
| 68 | + }, | ||
| 69 | + { | ||
| 70 | + "idiom":"ipad", | ||
| 71 | + "size":"20x20", | ||
| 72 | + "scale":"2x", | ||
| 73 | + "filename":"Icon-App-20x20@2x.png" | ||
| 74 | + }, | ||
| 75 | + { | ||
| 76 | + "idiom":"ipad", | ||
| 77 | + "size":"29x29", | ||
| 78 | + "scale":"1x", | ||
| 79 | + "filename":"Icon-App-29x29@1x.png" | ||
| 80 | + }, | ||
| 81 | + { | ||
| 82 | + "idiom":"ipad", | ||
| 83 | + "size":"29x29", | ||
| 84 | + "scale":"2x", | ||
| 85 | + "filename":"Icon-App-29x29@2x.png" | ||
| 86 | + }, | ||
| 87 | + { | ||
| 88 | + "idiom":"ipad", | ||
| 89 | + "size":"40x40", | ||
| 90 | + "scale":"1x", | ||
| 91 | + "filename":"Icon-App-40x40@1x.png" | ||
| 92 | + }, | ||
| 93 | + { | ||
| 94 | + "idiom":"ipad", | ||
| 95 | + "size":"40x40", | ||
| 96 | + "scale":"2x", | ||
| 97 | + "filename":"Icon-App-40x40@2x.png" | ||
| 98 | + }, | ||
| 99 | + { | ||
| 100 | + "idiom":"ipad", | ||
| 101 | + "size":"76x76", | ||
| 102 | + "scale":"1x", | ||
| 103 | + "filename":"Icon-App-76x76@1x.png" | ||
| 104 | + }, | ||
| 105 | + { | ||
| 106 | + "idiom":"ipad", | ||
| 107 | + "size":"76x76", | ||
| 108 | + "scale":"2x", | ||
| 109 | + "filename":"Icon-App-76x76@2x.png" | ||
| 110 | + }, | ||
| 111 | + { | ||
| 112 | + "idiom":"ipad", | ||
| 113 | + "size":"83.5x83.5", | ||
| 114 | + "scale":"2x", | ||
| 115 | + "filename":"Icon-App-83.5x83.5@2x.png" | ||
| 116 | + }, | ||
| 117 | + { | ||
| 118 | + "size" : "1024x1024", | ||
| 119 | + "idiom" : "ios-marketing", | ||
| 120 | + "scale" : "1x", | ||
| 121 | + "filename" : "ItunesArtwork@2x.png" | ||
| 122 | + } | ||
| 123 | + ], | ||
| 124 | + "info":{ | ||
| 125 | + "version":1, | ||
| 126 | + "author":"makeappicon" | ||
| 127 | + } | ||
| 128 | +} |
81.4 KB
756 Bytes
1.72 KB
2.87 KB
1.19 KB
2.79 KB
4.57 KB
1.72 KB
4.11 KB
6.76 KB
6.76 KB
11.1 KB
3.77 KB
8.95 KB
10 KB
81.4 KB
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "LaunchImage.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "filename" : "LaunchImage@2x.png", | ||
| 11 | + "scale" : "2x" | ||
| 12 | + }, | ||
| 13 | + { | ||
| 14 | + "idiom" : "universal", | ||
| 15 | + "filename" : "LaunchImage@3x.png", | ||
| 16 | + "scale" : "3x" | ||
| 17 | + } | ||
| 18 | + ], | ||
| 19 | + "info" : { | ||
| 20 | + "version" : 1, | ||
| 21 | + "author" : "xcode" | ||
| 22 | + } | ||
| 23 | +} |
68 Bytes
68 Bytes
68 Bytes
library/wechat_assets_picker-9.8.0/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
0 → 100644
| 1 | +# Launch Screen Assets | ||
| 2 | + | ||
| 3 | +You can customize the launch screen with your own desired assets by replacing the image files in this directory. | ||
| 4 | + | ||
| 5 | +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. |
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||
| 3 | + <dependencies> | ||
| 4 | + <deployment identifier="iOS"/> | ||
| 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> | ||
| 6 | + </dependencies> | ||
| 7 | + <scenes> | ||
| 8 | + <!--View Controller--> | ||
| 9 | + <scene sceneID="EHf-IW-A2E"> | ||
| 10 | + <objects> | ||
| 11 | + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||
| 12 | + <layoutGuides> | ||
| 13 | + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> | ||
| 14 | + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> | ||
| 15 | + </layoutGuides> | ||
| 16 | + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||
| 17 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 18 | + <subviews> | ||
| 19 | + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> | ||
| 20 | + </imageView> | ||
| 21 | + </subviews> | ||
| 22 | + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||
| 23 | + <constraints> | ||
| 24 | + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> | ||
| 25 | + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> | ||
| 26 | + </constraints> | ||
| 27 | + </view> | ||
| 28 | + </viewController> | ||
| 29 | + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
| 30 | + </objects> | ||
| 31 | + <point key="canvasLocation" x="53" y="375"/> | ||
| 32 | + </scene> | ||
| 33 | + </scenes> | ||
| 34 | + <resources> | ||
| 35 | + <image name="LaunchImage" width="168" height="185"/> | ||
| 36 | + </resources> | ||
| 37 | +</document> |
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> | ||
| 3 | + <dependencies> | ||
| 4 | + <deployment identifier="iOS"/> | ||
| 5 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> | ||
| 6 | + </dependencies> | ||
| 7 | + <scenes> | ||
| 8 | + <!--Flutter View Controller--> | ||
| 9 | + <scene sceneID="tne-QT-ifu"> | ||
| 10 | + <objects> | ||
| 11 | + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> | ||
| 12 | + <layoutGuides> | ||
| 13 | + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> | ||
| 14 | + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> | ||
| 15 | + </layoutGuides> | ||
| 16 | + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | ||
| 17 | + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> | ||
| 18 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 19 | + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | ||
| 20 | + </view> | ||
| 21 | + </viewController> | ||
| 22 | + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | ||
| 23 | + </objects> | ||
| 24 | + </scene> | ||
| 25 | + </scenes> | ||
| 26 | +</document> |
| 1 | +// | ||
| 2 | +// Generated file. Do not edit. | ||
| 3 | +// | ||
| 4 | + | ||
| 5 | +// clang-format off | ||
| 6 | + | ||
| 7 | +#ifndef GeneratedPluginRegistrant_h | ||
| 8 | +#define GeneratedPluginRegistrant_h | ||
| 9 | + | ||
| 10 | +#import <Flutter/Flutter.h> | ||
| 11 | + | ||
| 12 | +NS_ASSUME_NONNULL_BEGIN | ||
| 13 | + | ||
| 14 | +@interface GeneratedPluginRegistrant : NSObject | ||
| 15 | ++ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry; | ||
| 16 | +@end | ||
| 17 | + | ||
| 18 | +NS_ASSUME_NONNULL_END | ||
| 19 | +#endif /* GeneratedPluginRegistrant_h */ |
| 1 | +// | ||
| 2 | +// Generated file. Do not edit. | ||
| 3 | +// | ||
| 4 | + | ||
| 5 | +// clang-format off | ||
| 6 | + | ||
| 7 | +#import "GeneratedPluginRegistrant.h" | ||
| 8 | + | ||
| 9 | +#if __has_include(<camera_avfoundation/CameraPlugin.h>) | ||
| 10 | +#import <camera_avfoundation/CameraPlugin.h> | ||
| 11 | +#else | ||
| 12 | +@import camera_avfoundation; | ||
| 13 | +#endif | ||
| 14 | + | ||
| 15 | +#if __has_include(<package_info_plus/FPPPackageInfoPlusPlugin.h>) | ||
| 16 | +#import <package_info_plus/FPPPackageInfoPlusPlugin.h> | ||
| 17 | +#else | ||
| 18 | +@import package_info_plus; | ||
| 19 | +#endif | ||
| 20 | + | ||
| 21 | +#if __has_include(<path_provider_foundation/PathProviderPlugin.h>) | ||
| 22 | +#import <path_provider_foundation/PathProviderPlugin.h> | ||
| 23 | +#else | ||
| 24 | +@import path_provider_foundation; | ||
| 25 | +#endif | ||
| 26 | + | ||
| 27 | +#if __has_include(<photo_manager/PhotoManagerPlugin.h>) | ||
| 28 | +#import <photo_manager/PhotoManagerPlugin.h> | ||
| 29 | +#else | ||
| 30 | +@import photo_manager; | ||
| 31 | +#endif | ||
| 32 | + | ||
| 33 | +#if __has_include(<sensors_plus/FPPSensorsPlusPlugin.h>) | ||
| 34 | +#import <sensors_plus/FPPSensorsPlusPlugin.h> | ||
| 35 | +#else | ||
| 36 | +@import sensors_plus; | ||
| 37 | +#endif | ||
| 38 | + | ||
| 39 | +#if __has_include(<video_player_avfoundation/FVPVideoPlayerPlugin.h>) | ||
| 40 | +#import <video_player_avfoundation/FVPVideoPlayerPlugin.h> | ||
| 41 | +#else | ||
| 42 | +@import video_player_avfoundation; | ||
| 43 | +#endif | ||
| 44 | + | ||
| 45 | +@implementation GeneratedPluginRegistrant | ||
| 46 | + | ||
| 47 | ++ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry { | ||
| 48 | + [CameraPlugin registerWithRegistrar:[registry registrarForPlugin:@"CameraPlugin"]]; | ||
| 49 | + [FPPPackageInfoPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FPPPackageInfoPlusPlugin"]]; | ||
| 50 | + [PathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"PathProviderPlugin"]]; | ||
| 51 | + [PhotoManagerPlugin registerWithRegistrar:[registry registrarForPlugin:@"PhotoManagerPlugin"]]; | ||
| 52 | + [FPPSensorsPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"FPPSensorsPlusPlugin"]]; | ||
| 53 | + [FVPVideoPlayerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FVPVideoPlayerPlugin"]]; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +@end |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CADisableMinimumFrameDurationOnPhone</key> | ||
| 6 | + <true/> | ||
| 7 | + <key>CFBundleDevelopmentRegion</key> | ||
| 8 | + <string>$(DEVELOPMENT_LANGUAGE)</string> | ||
| 9 | + <key>CFBundleDisplayName</key> | ||
| 10 | + <string>Wechat Assets Picker Example</string> | ||
| 11 | + <key>CFBundleExecutable</key> | ||
| 12 | + <string>$(EXECUTABLE_NAME)</string> | ||
| 13 | + <key>CFBundleIdentifier</key> | ||
| 14 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 15 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 16 | + <string>6.0</string> | ||
| 17 | + <key>CFBundleName</key> | ||
| 18 | + <string>flutter_wechat_assets_picker_example</string> | ||
| 19 | + <key>CFBundlePackageType</key> | ||
| 20 | + <string>APPL</string> | ||
| 21 | + <key>CFBundleShortVersionString</key> | ||
| 22 | + <string>$(FLUTTER_BUILD_NAME)</string> | ||
| 23 | + <key>CFBundleSignature</key> | ||
| 24 | + <string>????</string> | ||
| 25 | + <key>CFBundleVersion</key> | ||
| 26 | + <string>$(FLUTTER_BUILD_NUMBER)</string> | ||
| 27 | + <key>LSRequiresIPhoneOS</key> | ||
| 28 | + <true/> | ||
| 29 | + <key>NSCameraUsageDescription</key> | ||
| 30 | + <string>Take a photo for display</string> | ||
| 31 | + <key>NSMicrophoneUsageDescription</key> | ||
| 32 | + <string>Take a video for display</string> | ||
| 33 | + <key>NSPhotoLibraryUsageDescription</key> | ||
| 34 | + <string>Read your photos for display</string> | ||
| 35 | + <key>UIApplicationSupportsIndirectInputEvents</key> | ||
| 36 | + <true/> | ||
| 37 | + <key>UILaunchStoryboardName</key> | ||
| 38 | + <string>LaunchScreen</string> | ||
| 39 | + <key>UIMainStoryboardFile</key> | ||
| 40 | + <string>Main</string> | ||
| 41 | + <key>UISupportedInterfaceOrientations</key> | ||
| 42 | + <array> | ||
| 43 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 44 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 45 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 46 | + </array> | ||
| 47 | + <key>UISupportedInterfaceOrientations~ipad</key> | ||
| 48 | + <array> | ||
| 49 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 50 | + <string>UIInterfaceOrientationPortraitUpsideDown</string> | ||
| 51 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 52 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 53 | + </array> | ||
| 54 | +</dict> | ||
| 55 | +</plist> |
| 1 | +#import "GeneratedPluginRegistrant.h" |
| 1 | +// Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +// Use of this source code is governed by an Apache license that can be found | ||
| 3 | +// in the LICENSE file. | ||
| 4 | + | ||
| 5 | +import 'package:flutter/widgets.dart'; | ||
| 6 | + | ||
| 7 | +@immutable | ||
| 8 | +class CustomPickMethod { | ||
| 9 | + const CustomPickMethod({ | ||
| 10 | + required this.icon, | ||
| 11 | + required this.name, | ||
| 12 | + required this.description, | ||
| 13 | + required this.method, | ||
| 14 | + }); | ||
| 15 | + | ||
| 16 | + final String icon; | ||
| 17 | + final String name; | ||
| 18 | + final String description; | ||
| 19 | + final void Function(BuildContext context) method; | ||
| 20 | +} |
| 1 | +// Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +// Use of this source code is governed by an Apache license that can be found | ||
| 3 | +// in the LICENSE file. | ||
| 4 | + | ||
| 5 | +import 'package:flutter/material.dart'; | ||
| 6 | +import 'package:wechat_assets_picker_demo/l10n/gen/app_localizations.dart'; | ||
| 7 | + | ||
| 8 | +extension BuildContextExtension on BuildContext { | ||
| 9 | + AppLocalizations get l10n => AppLocalizations.of(this)!; | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +extension BrightnessExtension on Brightness { | ||
| 13 | + bool get isDark => this == Brightness.dark; | ||
| 14 | + | ||
| 15 | + bool get isLight => this == Brightness.light; | ||
| 16 | + | ||
| 17 | + Brightness get reverse => | ||
| 18 | + this == Brightness.light ? Brightness.dark : Brightness.light; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +extension ColorExtension on Color { | ||
| 22 | + MaterialColor get swatch => Colors.primaries.firstWhere( | ||
| 23 | + (Color c) => c.value == value, | ||
| 24 | + orElse: () => _swatch, | ||
| 25 | + ); | ||
| 26 | + | ||
| 27 | + Map<int, Color> get getMaterialColorValues => <int, Color>{ | ||
| 28 | + 50: _swatchShade(50), | ||
| 29 | + 100: _swatchShade(100), | ||
| 30 | + 200: _swatchShade(200), | ||
| 31 | + 300: _swatchShade(300), | ||
| 32 | + 400: _swatchShade(400), | ||
| 33 | + 500: _swatchShade(500), | ||
| 34 | + 600: _swatchShade(600), | ||
| 35 | + 700: _swatchShade(700), | ||
| 36 | + 800: _swatchShade(800), | ||
| 37 | + 900: _swatchShade(900), | ||
| 38 | + }; | ||
| 39 | + | ||
| 40 | + MaterialColor get _swatch => MaterialColor(value, getMaterialColorValues); | ||
| 41 | + | ||
| 42 | + Color _swatchShade(int swatchValue) => HSLColor.fromColor(this) | ||
| 43 | + .withLightness(1 - (swatchValue / 1000)) | ||
| 44 | + .toColor(); | ||
| 45 | +} |
| 1 | +// Copyright 2019 The FlutterCandies author. All rights reserved. | ||
| 2 | +// Use of this source code is governed by an Apache license that can be found | ||
| 3 | +// in the LICENSE file. | ||
| 4 | + | ||
| 5 | +import 'package:flutter/material.dart'; | ||
| 6 | +import 'package:wechat_assets_picker/wechat_assets_picker.dart'; | ||
| 7 | +import 'package:wechat_camera_picker/wechat_camera_picker.dart'; | ||
| 8 | + | ||
| 9 | +import 'extensions.dart'; | ||
| 10 | + | ||
| 11 | +Future<AssetEntity?> _pickFromCamera(BuildContext c) { | ||
| 12 | + return CameraPicker.pickFromCamera( | ||
| 13 | + c, | ||
| 14 | + pickerConfig: const CameraPickerConfig(enableRecording: true), | ||
| 15 | + ); | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +/// Define a regular pick method. | ||
| 19 | +class PickMethod { | ||
| 20 | + const PickMethod({ | ||
| 21 | + required this.icon, | ||
| 22 | + required this.name, | ||
| 23 | + required this.description, | ||
| 24 | + required this.method, | ||
| 25 | + this.onLongPress, | ||
| 26 | + }); | ||
| 27 | + | ||
| 28 | + factory PickMethod.common(BuildContext context, int maxAssetsCount) { | ||
| 29 | + return PickMethod( | ||
| 30 | + icon: '📹', | ||
| 31 | + name: context.l10n.pickMethodCommonName, | ||
| 32 | + description: context.l10n.pickMethodCommonDescription, | ||
| 33 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 34 | + return AssetPicker.pickAssets( | ||
| 35 | + context, | ||
| 36 | + pickerConfig: AssetPickerConfig( | ||
| 37 | + maxAssets: maxAssetsCount, | ||
| 38 | + selectedAssets: assets, | ||
| 39 | + ), | ||
| 40 | + ); | ||
| 41 | + }, | ||
| 42 | + ); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + factory PickMethod.image(BuildContext context, int maxAssetsCount) { | ||
| 46 | + return PickMethod( | ||
| 47 | + icon: '🖼️', | ||
| 48 | + name: context.l10n.pickMethodImageName, | ||
| 49 | + description: context.l10n.pickMethodImageDescription, | ||
| 50 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 51 | + return AssetPicker.pickAssets( | ||
| 52 | + context, | ||
| 53 | + pickerConfig: AssetPickerConfig( | ||
| 54 | + maxAssets: maxAssetsCount, | ||
| 55 | + selectedAssets: assets, | ||
| 56 | + requestType: RequestType.image, | ||
| 57 | + ), | ||
| 58 | + ); | ||
| 59 | + }, | ||
| 60 | + ); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + factory PickMethod.video(BuildContext context, int maxAssetsCount) { | ||
| 64 | + return PickMethod( | ||
| 65 | + icon: '🎞', | ||
| 66 | + name: context.l10n.pickMethodVideoName, | ||
| 67 | + description: context.l10n.pickMethodVideoDescription, | ||
| 68 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 69 | + return AssetPicker.pickAssets( | ||
| 70 | + context, | ||
| 71 | + pickerConfig: AssetPickerConfig( | ||
| 72 | + maxAssets: maxAssetsCount, | ||
| 73 | + selectedAssets: assets, | ||
| 74 | + requestType: RequestType.video, | ||
| 75 | + ), | ||
| 76 | + ); | ||
| 77 | + }, | ||
| 78 | + ); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + factory PickMethod.audio(BuildContext context, int maxAssetsCount) { | ||
| 82 | + return PickMethod( | ||
| 83 | + icon: '🎶', | ||
| 84 | + name: context.l10n.pickMethodAudioName, | ||
| 85 | + description: context.l10n.pickMethodAudioDescription, | ||
| 86 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 87 | + return AssetPicker.pickAssets( | ||
| 88 | + context, | ||
| 89 | + pickerConfig: AssetPickerConfig( | ||
| 90 | + maxAssets: maxAssetsCount, | ||
| 91 | + selectedAssets: assets, | ||
| 92 | + requestType: RequestType.audio, | ||
| 93 | + ), | ||
| 94 | + ); | ||
| 95 | + }, | ||
| 96 | + ); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + factory PickMethod.livePhoto(BuildContext context, int maxAssetsCount) { | ||
| 100 | + return PickMethod( | ||
| 101 | + icon: '🎬', | ||
| 102 | + name: context.l10n.pickMethodLivePhotoName, | ||
| 103 | + description: context.l10n.pickMethodLivePhotoDescription, | ||
| 104 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 105 | + return AssetPicker.pickAssets( | ||
| 106 | + context, | ||
| 107 | + pickerConfig: AssetPickerConfig( | ||
| 108 | + maxAssets: maxAssetsCount, | ||
| 109 | + selectedAssets: assets, | ||
| 110 | + requestType: RequestType.image, | ||
| 111 | + filterOptions: CustomFilter.sql( | ||
| 112 | + where: '${CustomColumns.base.mediaType} = 1' | ||
| 113 | + ' AND ' | ||
| 114 | + '${CustomColumns.darwin.mediaSubtypes} & (1 << 3) = (1 << 3)', | ||
| 115 | + ), | ||
| 116 | + ), | ||
| 117 | + ); | ||
| 118 | + }, | ||
| 119 | + ); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + factory PickMethod.camera({ | ||
| 123 | + required BuildContext context, | ||
| 124 | + required int maxAssetsCount, | ||
| 125 | + required Function(BuildContext, AssetEntity) handleResult, | ||
| 126 | + }) { | ||
| 127 | + return PickMethod( | ||
| 128 | + icon: '📷', | ||
| 129 | + name: context.l10n.pickMethodCameraName, | ||
| 130 | + description: context.l10n.pickMethodCameraDescription, | ||
| 131 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 132 | + const AssetPickerTextDelegate textDelegate = AssetPickerTextDelegate(); | ||
| 133 | + return AssetPicker.pickAssets( | ||
| 134 | + context, | ||
| 135 | + pickerConfig: AssetPickerConfig( | ||
| 136 | + maxAssets: maxAssetsCount, | ||
| 137 | + selectedAssets: assets, | ||
| 138 | + specialItemPosition: SpecialItemPosition.prepend, | ||
| 139 | + specialItemBuilder: ( | ||
| 140 | + BuildContext context, | ||
| 141 | + AssetPathEntity? path, | ||
| 142 | + int length, | ||
| 143 | + ) { | ||
| 144 | + if (path?.isAll != true) { | ||
| 145 | + return null; | ||
| 146 | + } | ||
| 147 | + return Semantics( | ||
| 148 | + label: textDelegate.sActionUseCameraHint, | ||
| 149 | + button: true, | ||
| 150 | + onTapHint: textDelegate.sActionUseCameraHint, | ||
| 151 | + child: GestureDetector( | ||
| 152 | + behavior: HitTestBehavior.opaque, | ||
| 153 | + onTap: () async { | ||
| 154 | + Feedback.forTap(context); | ||
| 155 | + final AssetEntity? result = await _pickFromCamera(context); | ||
| 156 | + if (result != null) { | ||
| 157 | + handleResult(context, result); | ||
| 158 | + } | ||
| 159 | + }, | ||
| 160 | + child: Container( | ||
| 161 | + padding: const EdgeInsets.all(28.0), | ||
| 162 | + color: Theme.of(context).dividerColor, | ||
| 163 | + child: const FittedBox( | ||
| 164 | + fit: BoxFit.fill, | ||
| 165 | + child: Icon(Icons.camera_enhance), | ||
| 166 | + ), | ||
| 167 | + ), | ||
| 168 | + ), | ||
| 169 | + ); | ||
| 170 | + }, | ||
| 171 | + ), | ||
| 172 | + ); | ||
| 173 | + }, | ||
| 174 | + ); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + factory PickMethod.cameraAndStay(BuildContext context, int maxAssetsCount) { | ||
| 178 | + return PickMethod( | ||
| 179 | + icon: '📸', | ||
| 180 | + name: context.l10n.pickMethodCameraAndStayName, | ||
| 181 | + description: context.l10n.pickMethodCameraAndStayDescription, | ||
| 182 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 183 | + const AssetPickerTextDelegate textDelegate = AssetPickerTextDelegate(); | ||
| 184 | + return AssetPicker.pickAssets( | ||
| 185 | + context, | ||
| 186 | + pickerConfig: AssetPickerConfig( | ||
| 187 | + maxAssets: maxAssetsCount, | ||
| 188 | + selectedAssets: assets, | ||
| 189 | + specialItemPosition: SpecialItemPosition.prepend, | ||
| 190 | + specialItemBuilder: ( | ||
| 191 | + BuildContext context, | ||
| 192 | + AssetPathEntity? path, | ||
| 193 | + int length, | ||
| 194 | + ) { | ||
| 195 | + if (path?.isAll != true) { | ||
| 196 | + return null; | ||
| 197 | + } | ||
| 198 | + return Semantics( | ||
| 199 | + label: textDelegate.sActionUseCameraHint, | ||
| 200 | + button: true, | ||
| 201 | + onTapHint: textDelegate.sActionUseCameraHint, | ||
| 202 | + child: GestureDetector( | ||
| 203 | + behavior: HitTestBehavior.opaque, | ||
| 204 | + onTap: () async { | ||
| 205 | + final AssetEntity? result = await _pickFromCamera(context); | ||
| 206 | + if (result == null) { | ||
| 207 | + return; | ||
| 208 | + } | ||
| 209 | + final picker = context.findAncestorWidgetOfExactType< | ||
| 210 | + AssetPicker<AssetEntity, AssetPathEntity>>()!; | ||
| 211 | + final builder = | ||
| 212 | + picker.builder as DefaultAssetPickerBuilderDelegate; | ||
| 213 | + final p = builder.provider; | ||
| 214 | + await p.switchPath( | ||
| 215 | + PathWrapper<AssetPathEntity>( | ||
| 216 | + path: | ||
| 217 | + await p.currentPath!.path.obtainForNewProperties(), | ||
| 218 | + ), | ||
| 219 | + ); | ||
| 220 | + p.selectAsset(result); | ||
| 221 | + }, | ||
| 222 | + child: Container( | ||
| 223 | + padding: const EdgeInsets.all(28.0), | ||
| 224 | + color: Theme.of(context).dividerColor, | ||
| 225 | + child: const FittedBox( | ||
| 226 | + fit: BoxFit.fill, | ||
| 227 | + child: Icon(Icons.camera_enhance), | ||
| 228 | + ), | ||
| 229 | + ), | ||
| 230 | + ), | ||
| 231 | + ); | ||
| 232 | + }, | ||
| 233 | + ), | ||
| 234 | + ); | ||
| 235 | + }, | ||
| 236 | + ); | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + factory PickMethod.threeItemsGrid(BuildContext context, int maxAssetsCount) { | ||
| 240 | + return PickMethod( | ||
| 241 | + icon: '🔲', | ||
| 242 | + name: context.l10n.pickMethodThreeItemsGridName, | ||
| 243 | + description: context.l10n.pickMethodThreeItemsGridDescription, | ||
| 244 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 245 | + return AssetPicker.pickAssets( | ||
| 246 | + context, | ||
| 247 | + pickerConfig: AssetPickerConfig( | ||
| 248 | + gridCount: 3, | ||
| 249 | + pageSize: 120, | ||
| 250 | + maxAssets: maxAssetsCount, | ||
| 251 | + selectedAssets: assets, | ||
| 252 | + requestType: RequestType.all, | ||
| 253 | + ), | ||
| 254 | + ); | ||
| 255 | + }, | ||
| 256 | + ); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + factory PickMethod.customFilterOptions( | ||
| 260 | + BuildContext context, | ||
| 261 | + int maxAssetsCount, | ||
| 262 | + ) { | ||
| 263 | + return PickMethod( | ||
| 264 | + icon: '⏳', | ||
| 265 | + name: context.l10n.pickMethodCustomFilterOptionsName, | ||
| 266 | + description: context.l10n.pickMethodCustomFilterOptionsDescription, | ||
| 267 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 268 | + return AssetPicker.pickAssets( | ||
| 269 | + context, | ||
| 270 | + pickerConfig: AssetPickerConfig( | ||
| 271 | + maxAssets: maxAssetsCount, | ||
| 272 | + selectedAssets: assets, | ||
| 273 | + requestType: RequestType.video, | ||
| 274 | + filterOptions: FilterOptionGroup( | ||
| 275 | + videoOption: const FilterOption( | ||
| 276 | + durationConstraint: DurationConstraint( | ||
| 277 | + max: Duration(minutes: 1), | ||
| 278 | + ), | ||
| 279 | + ), | ||
| 280 | + ), | ||
| 281 | + ), | ||
| 282 | + ); | ||
| 283 | + }, | ||
| 284 | + ); | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + factory PickMethod.prependItem(BuildContext context, int maxAssetsCount) { | ||
| 288 | + return PickMethod( | ||
| 289 | + icon: '➕', | ||
| 290 | + name: context.l10n.pickMethodPrependItemName, | ||
| 291 | + description: context.l10n.pickMethodPrependItemDescription, | ||
| 292 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 293 | + return AssetPicker.pickAssets( | ||
| 294 | + context, | ||
| 295 | + pickerConfig: AssetPickerConfig( | ||
| 296 | + maxAssets: maxAssetsCount, | ||
| 297 | + selectedAssets: assets, | ||
| 298 | + specialItemPosition: SpecialItemPosition.prepend, | ||
| 299 | + specialItemBuilder: ( | ||
| 300 | + BuildContext context, | ||
| 301 | + AssetPathEntity? path, | ||
| 302 | + int length, | ||
| 303 | + ) { | ||
| 304 | + return const Center( | ||
| 305 | + child: Text('Custom Widget', textAlign: TextAlign.center), | ||
| 306 | + ); | ||
| 307 | + }, | ||
| 308 | + ), | ||
| 309 | + ); | ||
| 310 | + }, | ||
| 311 | + ); | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + factory PickMethod.noPreview(BuildContext context, int maxAssetsCount) { | ||
| 315 | + return PickMethod( | ||
| 316 | + icon: '👁️🗨️', | ||
| 317 | + name: context.l10n.pickMethodNoPreviewName, | ||
| 318 | + description: context.l10n.pickMethodNoPreviewDescription, | ||
| 319 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 320 | + return AssetPicker.pickAssets( | ||
| 321 | + context, | ||
| 322 | + pickerConfig: AssetPickerConfig( | ||
| 323 | + maxAssets: maxAssetsCount, | ||
| 324 | + selectedAssets: assets, | ||
| 325 | + specialPickerType: SpecialPickerType.noPreview, | ||
| 326 | + ), | ||
| 327 | + ); | ||
| 328 | + }, | ||
| 329 | + ); | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + factory PickMethod.keepScrollOffset({ | ||
| 333 | + required BuildContext context, | ||
| 334 | + required DefaultAssetPickerBuilderDelegate Function() delegate, | ||
| 335 | + required Function(PermissionState state) onPermission, | ||
| 336 | + GestureLongPressCallback? onLongPress, | ||
| 337 | + }) { | ||
| 338 | + return PickMethod( | ||
| 339 | + icon: '💾', | ||
| 340 | + name: context.l10n.pickMethodKeepScrollOffsetName, | ||
| 341 | + description: context.l10n.pickMethodKeepScrollOffsetDescription, | ||
| 342 | + method: (BuildContext context, List<AssetEntity> assets) async { | ||
| 343 | + final PermissionState ps = await PhotoManager.requestPermissionExtend(); | ||
| 344 | + if (ps != PermissionState.authorized && ps != PermissionState.limited) { | ||
| 345 | + throw StateError('Permission state error with $ps.'); | ||
| 346 | + } | ||
| 347 | + onPermission(ps); | ||
| 348 | + return AssetPicker.pickAssetsWithDelegate( | ||
| 349 | + context, | ||
| 350 | + delegate: delegate(), | ||
| 351 | + ); | ||
| 352 | + }, | ||
| 353 | + onLongPress: onLongPress, | ||
| 354 | + ); | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | + factory PickMethod.changeLanguages(BuildContext context, int maxAssetsCount) { | ||
| 358 | + return PickMethod( | ||
| 359 | + icon: '🔤', | ||
| 360 | + name: context.l10n.pickMethodChangeLanguagesName, | ||
| 361 | + description: context.l10n.pickMethodChangeLanguagesDescription, | ||
| 362 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 363 | + return AssetPicker.pickAssets( | ||
| 364 | + context, | ||
| 365 | + pickerConfig: AssetPickerConfig( | ||
| 366 | + maxAssets: maxAssetsCount, | ||
| 367 | + selectedAssets: assets, | ||
| 368 | + textDelegate: const EnglishAssetPickerTextDelegate(), | ||
| 369 | + ), | ||
| 370 | + ); | ||
| 371 | + }, | ||
| 372 | + ); | ||
| 373 | + } | ||
| 374 | + | ||
| 375 | + factory PickMethod.preventGIFPicked( | ||
| 376 | + BuildContext context, | ||
| 377 | + int maxAssetsCount, | ||
| 378 | + ) { | ||
| 379 | + return PickMethod( | ||
| 380 | + icon: '🈲', | ||
| 381 | + name: context.l10n.pickMethodPreventGIFPickedName, | ||
| 382 | + description: context.l10n.pickMethodPreventGIFPickedDescription, | ||
| 383 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 384 | + return AssetPicker.pickAssets( | ||
| 385 | + context, | ||
| 386 | + pickerConfig: AssetPickerConfig( | ||
| 387 | + maxAssets: maxAssetsCount, | ||
| 388 | + selectedAssets: assets, | ||
| 389 | + selectPredicate: (BuildContext c, AssetEntity a, bool isSelected) { | ||
| 390 | + debugPrint('Asset title: ${a.title}'); | ||
| 391 | + return a.title?.endsWith('.gif') != true; | ||
| 392 | + }, | ||
| 393 | + ), | ||
| 394 | + ); | ||
| 395 | + }, | ||
| 396 | + ); | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + factory PickMethod.customizableTheme( | ||
| 400 | + BuildContext context, | ||
| 401 | + int maxAssetsCount, | ||
| 402 | + ) { | ||
| 403 | + return PickMethod( | ||
| 404 | + icon: '🎨', | ||
| 405 | + name: context.l10n.pickMethodCustomizableThemeName, | ||
| 406 | + description: context.l10n.pickMethodCustomizableThemeDescription, | ||
| 407 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 408 | + return AssetPicker.pickAssets( | ||
| 409 | + context, | ||
| 410 | + pickerConfig: AssetPickerConfig( | ||
| 411 | + maxAssets: maxAssetsCount, | ||
| 412 | + selectedAssets: assets, | ||
| 413 | + pickerTheme: AssetPicker.themeData( | ||
| 414 | + Colors.lightBlueAccent, | ||
| 415 | + light: true, | ||
| 416 | + ), | ||
| 417 | + ), | ||
| 418 | + ); | ||
| 419 | + }, | ||
| 420 | + ); | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + factory PickMethod.pathNameBuilder(BuildContext context, int maxAssetsCount) { | ||
| 424 | + return PickMethod( | ||
| 425 | + icon: '🈸', | ||
| 426 | + name: context.l10n.pickMethodPathNameBuilderName, | ||
| 427 | + description: context.l10n.pickMethodPathNameBuilderDescription, | ||
| 428 | + method: (BuildContext context, List<AssetEntity> assets) { | ||
| 429 | + return AssetPicker.pickAssets( | ||
| 430 | + context, | ||
| 431 | + pickerConfig: AssetPickerConfig( | ||
| 432 | + maxAssets: maxAssetsCount, | ||
| 433 | + selectedAssets: assets, | ||
| 434 | + pathNameBuilder: (AssetPathEntity path) => '${path.name}🍭', | ||
| 435 | + ), | ||
| 436 | + ); | ||
| 437 | + }, | ||
| 438 | + ); | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + final String icon; | ||
| 442 | + final String name; | ||
| 443 | + final String description; | ||
| 444 | + | ||
| 445 | + /// The core function that defines how to use the picker. | ||
| 446 | + final Future<List<AssetEntity>?> Function( | ||
| 447 | + BuildContext context, | ||
| 448 | + List<AssetEntity> selectedAssets, | ||
| 449 | + ) method; | ||
| 450 | + | ||
| 451 | + final GestureLongPressCallback? onLongPress; | ||
| 452 | +} |
| 1 | +# Contribute custom implementations | ||
| 2 | + | ||
| 3 | +This folder allows people to contribute their delegates, use case, or even a brand-new picker. | ||
| 4 | + | ||
| 5 | +To add your works, make sure you follow this instruction. | ||
| 6 | + | ||
| 7 | +## Ensure that your picker is worth to contribute | ||
| 8 | + | ||
| 9 | +People usually have their own apps to build, and the thing like the picker is not always the same between apps. | ||
| 10 | +However, some patterns can be consumed using arguments and fields override, without creating a new picker/delegate. | ||
| 11 | +Please think twice before you confirmed it should be pushed as a new implementation example. | ||
| 12 | + | ||
| 13 | +## Contribute steps | ||
| 14 | + | ||
| 15 | +1. Fork this project. | ||
| 16 | +2. Create a new branch named `custom-{write-your-implementation-name}`. | ||
| 17 | +3. Create a new picker dart file named `{your_implementation_name}_asset_picker.dart` in the `pickers` folder. | ||
| 18 | +4. Brought all your implementations into the file you've just created. | ||
| 19 | +5. Add a `CustomPickMethod` at the `custom_picker_page.dart` file in `pickMethods` | ||
| 20 | + in order to build an entrance to your picker. | ||
| 21 | +6. Submit your PR with proper explanations with how your picker works. |
-
Please register or login to post a comment