Upgrade to null safety

This commit is contained in:
Richard Bushnell 2021-03-18 12:00:31 +00:00
parent 68e63e3b93
commit eaa1cf2e25
10 changed files with 85 additions and 97 deletions

View File

@ -2,6 +2,7 @@ library photogallery;
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -23,9 +24,8 @@ class PhotoGallery {
/// List all available gallery albums and counts number of items of [MediumType]. /// List all available gallery albums and counts number of items of [MediumType].
static Future<List<Album>> listAlbums({ static Future<List<Album>> listAlbums({
@required MediumType mediumType, required MediumType mediumType,
}) async { }) async {
assert(mediumType != null);
final json = await _channel.invokeMethod('listAlbums', { final json = await _channel.invokeMethod('listAlbums', {
'mediumType': mediumTypeToJson(mediumType), 'mediumType': mediumTypeToJson(mediumType),
}); });
@ -34,12 +34,11 @@ class PhotoGallery {
/// List all available media in a specific album, support pagination of media /// List all available media in a specific album, support pagination of media
static Future<MediaPage> _listMedia({ static Future<MediaPage> _listMedia({
@required Album album, required Album album,
@required int total, required int total,
int skip, int? skip,
int take, int? take,
}) async { }) async {
assert(album.id != null);
final json = await _channel.invokeMethod('listMedia', { final json = await _channel.invokeMethod('listMedia', {
'albumId': album.id, 'albumId': album.id,
'mediumType': mediumTypeToJson(album.mediumType), 'mediumType': mediumTypeToJson(album.mediumType),
@ -52,10 +51,9 @@ class PhotoGallery {
/// Get medium metadata by medium id /// Get medium metadata by medium id
static Future<Medium> getMedium({ static Future<Medium> getMedium({
@required String mediumId, required String mediumId,
MediumType mediumType, MediumType? mediumType,
}) async { }) async {
assert(mediumId != null);
final json = await _channel.invokeMethod('getMedium', { final json = await _channel.invokeMethod('getMedium', {
'mediumId': mediumId, 'mediumId': mediumId,
'mediumType': mediumTypeToJson(mediumType), 'mediumType': mediumTypeToJson(mediumType),
@ -64,14 +62,13 @@ class PhotoGallery {
} }
/// Get medium thumbnail by medium id /// Get medium thumbnail by medium id
static Future<List<dynamic>> getThumbnail({ static Future<List<int>> getThumbnail({
@required String mediumId, required String mediumId,
MediumType mediumType, MediumType? mediumType,
int width, int? width,
int height, int? height,
bool highQuality, bool? highQuality,
}) async { }) async {
assert(mediumId != null);
final bytes = await _channel.invokeMethod('getThumbnail', { final bytes = await _channel.invokeMethod('getThumbnail', {
'mediumId': mediumId, 'mediumId': mediumId,
'mediumType': mediumTypeToJson(mediumType), 'mediumType': mediumTypeToJson(mediumType),
@ -83,14 +80,13 @@ class PhotoGallery {
} }
/// Get album thumbnail by album id /// Get album thumbnail by album id
static Future<List<dynamic>> getAlbumThumbnail({ static Future<List<int>> getAlbumThumbnail({
@required String albumId, required String albumId,
MediumType mediumType, MediumType? mediumType,
int width, int? width,
int height, int? height,
bool highQuality, bool? highQuality,
}) async { }) async {
assert(albumId != null);
final bytes = await _channel.invokeMethod('getAlbumThumbnail', { final bytes = await _channel.invokeMethod('getAlbumThumbnail', {
'albumId': albumId, 'albumId': albumId,
'mediumType': mediumTypeToJson(mediumType), 'mediumType': mediumTypeToJson(mediumType),
@ -103,10 +99,9 @@ class PhotoGallery {
/// get medium file by medium id /// get medium file by medium id
static Future<File> getFile({ static Future<File> getFile({
@required String mediumId, required String mediumId,
MediumType mediumType, MediumType? mediumType,
}) async { }) async {
assert(mediumId != null);
final path = await _channel.invokeMethod('getFile', { final path = await _channel.invokeMethod('getFile', {
'mediumId': mediumId, 'mediumId': mediumId,
'mediumType': mediumTypeToJson(mediumType), 'mediumType': mediumTypeToJson(mediumType),

View File

@ -6,7 +6,7 @@ enum MediumType {
video, video,
} }
String mediumTypeToJson(MediumType value) { String? mediumTypeToJson(MediumType? value) {
switch (value) { switch (value) {
case MediumType.image: case MediumType.image:
return 'image'; return 'image';
@ -17,7 +17,7 @@ String mediumTypeToJson(MediumType value) {
} }
} }
MediumType jsonToMediumType(String value) { MediumType? jsonToMediumType(String? value) {
switch (value) { switch (value) {
case 'image': case 'image':
return MediumType.image; return MediumType.image;

View File

@ -3,18 +3,18 @@ part of photogallery;
/// Fetches the given album thumbnail from the gallery. /// Fetches the given album thumbnail from the gallery.
class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> { class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
const AlbumThumbnailProvider({ const AlbumThumbnailProvider({
@required this.albumId, required this.albumId,
this.mediumType, this.mediumType,
this.height, this.height,
this.width, this.width,
this.highQuality = false, this.highQuality = false,
}) : assert(albumId != null); });
final String albumId; final String albumId;
final MediumType mediumType; final MediumType? mediumType;
final int height; final int? height;
final int width; final int? width;
final bool highQuality; final bool? highQuality;
@override @override
ImageStreamCompleter load(key, decode) { ImageStreamCompleter load(key, decode) {
@ -37,9 +37,7 @@ class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
width: width, width: width,
highQuality: highQuality, highQuality: highQuality,
); );
if (bytes == null || bytes.length == 0) return null; return await decode(Uint8List.fromList(bytes));
return await decode(bytes);
} }
@override @override
@ -55,7 +53,7 @@ class AlbumThumbnailProvider extends ImageProvider<AlbumThumbnailProvider> {
} }
@override @override
int get hashCode => albumId?.hashCode ?? 0; int get hashCode => albumId.hashCode;
@override @override
String toString() => '$runtimeType("$albumId")'; String toString() => '$runtimeType("$albumId")';

View File

@ -3,8 +3,8 @@ part of photogallery;
/// Fetches the given image from the gallery. /// Fetches the given image from the gallery.
class PhotoProvider extends ImageProvider<PhotoProvider> { class PhotoProvider extends ImageProvider<PhotoProvider> {
PhotoProvider({ PhotoProvider({
@required this.mediumId, required this.mediumId,
}) : assert(mediumId != null); });
final String mediumId; final String mediumId;
@ -23,10 +23,8 @@ class PhotoProvider extends ImageProvider<PhotoProvider> {
assert(key == this); assert(key == this);
final file = await PhotoGallery.getFile( final file = await PhotoGallery.getFile(
mediumId: mediumId, mediumType: MediumType.image); mediumId: mediumId, mediumType: MediumType.image);
if (file == null) return null;
final bytes = await file.readAsBytes(); final bytes = await file.readAsBytes();
if (bytes.lengthInBytes == 0) return null;
return await decode(bytes); return await decode(bytes);
} }
@ -44,7 +42,7 @@ class PhotoProvider extends ImageProvider<PhotoProvider> {
} }
@override @override
int get hashCode => mediumId?.hashCode ?? 0; int get hashCode => mediumId.hashCode;
@override @override
String toString() => '$runtimeType("$mediumId")'; String toString() => '$runtimeType("$mediumId")';

View File

@ -3,18 +3,18 @@ part of photogallery;
/// Fetches the given medium thumbnail from the gallery. /// Fetches the given medium thumbnail from the gallery.
class ThumbnailProvider extends ImageProvider<ThumbnailProvider> { class ThumbnailProvider extends ImageProvider<ThumbnailProvider> {
const ThumbnailProvider({ const ThumbnailProvider({
@required this.mediumId, required this.mediumId,
this.mediumType, this.mediumType,
this.height, this.height,
this.width, this.width,
this.highQuality, this.highQuality,
}) : assert(mediumId != null); });
final String mediumId; final String mediumId;
final MediumType mediumType; final MediumType? mediumType;
final int height; final int? height;
final int width; final int? width;
final bool highQuality; final bool? highQuality;
@override @override
ImageStreamCompleter load(key, decode) { ImageStreamCompleter load(key, decode) {
@ -37,9 +37,7 @@ class ThumbnailProvider extends ImageProvider<ThumbnailProvider> {
width: width, width: width,
highQuality: highQuality, highQuality: highQuality,
); );
if (bytes.length == 0) return null; return await decode(Uint8List.fromList(bytes));
return await decode(bytes);
} }
@override @override
@ -55,7 +53,7 @@ class ThumbnailProvider extends ImageProvider<ThumbnailProvider> {
} }
@override @override
int get hashCode => mediumId?.hashCode ?? 0; int get hashCode => mediumId.hashCode;
@override @override
String toString() => '$runtimeType("$mediumId")'; String toString() => '$runtimeType("$mediumId")';

View File

@ -7,7 +7,7 @@ class Album {
final String id; final String id;
/// The [MediumType] of the album. /// The [MediumType] of the album.
final MediumType mediumType; final MediumType? mediumType;
/// The name of the album. /// The name of the album.
final String name; final String name;
@ -30,8 +30,8 @@ class Album {
/// Pagination can be controlled out of [skip] (defaults to `0`) and /// Pagination can be controlled out of [skip] (defaults to `0`) and
/// [take] (defaults to `<total>`). /// [take] (defaults to `<total>`).
Future<MediaPage> listMedia({ Future<MediaPage> listMedia({
int skip, int? skip,
int take, int? take,
}) { }) {
return PhotoGallery._listMedia( return PhotoGallery._listMedia(
album: this, album: this,
@ -45,9 +45,9 @@ class Album {
/// ///
/// It will display the lastly taken medium thumbnail. /// It will display the lastly taken medium thumbnail.
Future<List<int>> getThumbnail({ Future<List<int>> getThumbnail({
int width, int? width,
int height, int? height,
bool highQuality = false, bool? highQuality = false,
}) { }) {
return PhotoGallery.getAlbumThumbnail( return PhotoGallery.getAlbumThumbnail(
albumId: id, albumId: id,

View File

@ -9,33 +9,33 @@ class Medium {
final String id; final String id;
/// The medium type. /// The medium type.
final MediumType mediumType; final MediumType? mediumType;
/// The medium width. /// The medium width.
final int width; final int? width;
/// The medium height. /// The medium height.
final int height; final int? height;
/// The medium mimeType. /// The medium mimeType.
final String mimeType; final String? mimeType;
/// The duration of video /// The duration of video
final int duration; final int duration;
/// The date at which the photo or video was taken. /// The date at which the photo or video was taken.
final DateTime creationDate; final DateTime? creationDate;
/// The date at which the photo or video was modified. /// The date at which the photo or video was modified.
final DateTime modifiedDate; final DateTime? modifiedDate;
Medium({ Medium({
this.id, required this.id,
this.mediumType, this.mediumType,
this.width, this.width,
this.height, this.height,
this.mimeType, this.mimeType,
this.duration, this.duration = 0,
this.creationDate, this.creationDate,
this.modifiedDate, this.modifiedDate,
}); });
@ -81,9 +81,9 @@ class Medium {
/// Get a JPEG thumbnail's data for this medium. /// Get a JPEG thumbnail's data for this medium.
Future<List<int>> getThumbnail({ Future<List<int>> getThumbnail({
int width, int? width,
int height, int? height,
bool highQuality = false, bool? highQuality = false,
}) { }) {
return PhotoGallery.getThumbnail( return PhotoGallery.getThumbnail(
mediumId: id, mediumId: id,

View File

@ -1,10 +1,10 @@
name: photo_gallery name: photo_gallery
description: A Flutter plugin that retrieves images and videos from mobile native gallery. description: A Flutter plugin that retrieves images and videos from mobile native gallery.
version: 0.4.0 version: 0.4.0-nullsafety.0
repository: https://github.com/Firelands128/photo_gallery repository: https://github.com/Firelands128/photo_gallery
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.10.0" flutter: ">=1.10.0"
dependencies: dependencies:

View File

@ -3,8 +3,7 @@ import 'dart:io';
import 'package:photo_gallery/photo_gallery.dart'; import 'package:photo_gallery/photo_gallery.dart';
class Generator { class Generator {
static dynamic generateAlbumsJson({MediumType mediumType}) { static dynamic generateAlbumsJson({MediumType mediumType = MediumType.image}) {
mediumType = mediumType ?? MediumType.image;
return [ return [
{ {
"id": "__ALL__", "id": "__ALL__",
@ -21,18 +20,18 @@ class Generator {
]; ];
} }
static List<Album> generateAlbums({MediumType mediumType}) { static List<Album> generateAlbums({required MediumType mediumType}) {
return Generator.generateAlbumsJson(mediumType: mediumType) return Generator.generateAlbumsJson(mediumType: mediumType)
.map<Album>((x) => Album.fromJson(x)) .map<Album>((x) => Album.fromJson(x))
.toList(); .toList();
} }
static dynamic generateMediaPageJson({ static dynamic generateMediaPageJson({
String albumId, required String albumId,
MediumType mediumType, required MediumType mediumType,
int total, required int total,
int skip, int? skip,
int take, int? take,
}) { }) {
skip = skip ?? 0; skip = skip ?? 0;
take = take ?? (total - skip); take = take ?? (total - skip);
@ -53,8 +52,8 @@ class Generator {
} }
static dynamic generateMediaJson({ static dynamic generateMediaJson({
String mediumId, required String mediumId,
MediumType mediumType, required MediumType mediumType,
}) { }) {
return { return {
"id": mediumId, "id": mediumId,
@ -69,10 +68,10 @@ class Generator {
} }
static MediaPage generateMediaPage({ static MediaPage generateMediaPage({
Album album, required Album album,
MediumType mediumType, required MediumType mediumType,
int skip, int? skip,
int take, int? take,
}) { }) {
dynamic json = generateMediaPageJson( dynamic json = generateMediaPageJson(
albumId: album.id, albumId: album.id,
@ -85,8 +84,8 @@ class Generator {
} }
static Medium generateMedia({ static Medium generateMedia({
String mediumId, required String mediumId,
MediumType mediumType, required MediumType mediumType,
}) { }) {
return Medium.fromJson( return Medium.fromJson(
generateMediaJson(mediumId: mediumId, mediumType: mediumType), generateMediaJson(mediumId: mediumId, mediumType: mediumType),
@ -94,28 +93,28 @@ class Generator {
} }
static List<int> generateMockThumbnail({ static List<int> generateMockThumbnail({
String mediumId, required String mediumId,
MediumType mediumType, required MediumType mediumType,
}) { }) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9]; return [1, 2, 3, 4, 5, 6, 7, 8, 9];
} }
static List<int> generateMockAlbumThumbnail({ static List<int> generateMockAlbumThumbnail({
String albumId, required String albumId,
}) { }) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9]; return [1, 2, 3, 4, 5, 6, 7, 8, 9];
} }
static String generateFilePath({ static String generateFilePath({
String mediumId, required String mediumId,
MediumType mediumType, required MediumType mediumType,
}) { }) {
return "/path/to/file"; return "/path/to/file";
} }
static File generateFile({ static File generateFile({
String mediumId, required String mediumId,
MediumType mediumType, required MediumType mediumType,
}) { }) {
return File(generateFilePath(mediumId: mediumId, mediumType: mediumType)); return File(generateFilePath(mediumId: mediumId, mediumType: mediumType));
} }

View File

@ -11,7 +11,7 @@ Future<dynamic> mockMethodCallHandler(MethodCall call) async {
return albums; return albums;
} else if (call.method == "listMedia") { } else if (call.method == "listMedia") {
String albumId = call.arguments['albumId']; String albumId = call.arguments['albumId'];
MediumType mediumType = jsonToMediumType(call.arguments['mediumType']); MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
int total = call.arguments['total']; int total = call.arguments['total'];
int skip = call.arguments['skip']; int skip = call.arguments['skip'];
int take = call.arguments['take']; int take = call.arguments['take'];