update to satisfy null safety
This commit is contained in:
parent
7f3911d89b
commit
184b728f12
@ -10,78 +10,32 @@ project 'Runner', {
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
generated_key_values = {}
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) do |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
generated_key_values[podname] = podpath
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
generated_key_values
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
# Flutter Pod
|
||||
|
||||
copied_flutter_dir = File.join(__dir__, 'Flutter')
|
||||
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
|
||||
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
|
||||
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
|
||||
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
|
||||
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
|
||||
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
||||
|
||||
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
|
||||
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
|
||||
|
||||
unless File.exist?(copied_framework_path)
|
||||
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
|
||||
end
|
||||
unless File.exist?(copied_podspec_path)
|
||||
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod 'Flutter', :path => 'Flutter'
|
||||
|
||||
# Plugin Pods
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
system('rm -rf .symlinks')
|
||||
system('mkdir -p .symlinks/plugins')
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.each do |name, path|
|
||||
symlink = File.join('.symlinks', 'plugins', name)
|
||||
File.symlink(path, symlink)
|
||||
pod name, :path => File.join(symlink, 'ios')
|
||||
end
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
end
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
@ -1,20 +1,17 @@
|
||||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- "permission_handler (5.0.1+1)":
|
||||
- "permission_handler (5.1.0+2)":
|
||||
- Flutter
|
||||
- photo_gallery (0.0.1):
|
||||
- Flutter
|
||||
- video_player (0.0.1):
|
||||
- Flutter
|
||||
- video_player_web (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||
- photo_gallery (from `.symlinks/plugins/photo_gallery/ios`)
|
||||
- video_player (from `.symlinks/plugins/video_player/ios`)
|
||||
- video_player_web (from `.symlinks/plugins/video_player_web/ios`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
@ -25,16 +22,13 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/photo_gallery/ios"
|
||||
video_player:
|
||||
:path: ".symlinks/plugins/video_player/ios"
|
||||
video_player_web:
|
||||
:path: ".symlinks/plugins/video_player_web/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
|
||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
||||
photo_gallery: 9f95e57747cd22c10676ece3660d1ffe6c603ee5
|
||||
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e
|
||||
video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7
|
||||
|
||||
PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
|
||||
COCOAPODS: 1.9.3
|
||||
COCOAPODS: 1.10.1
|
||||
|
@ -261,17 +261,12 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/photo_gallery/photo_gallery.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/video_player/video_player.framework",
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_gallery.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player.framework",
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@ -314,7 +309,6 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
@ -391,7 +385,6 @@
|
||||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
@ -447,7 +440,6 @@
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
|
@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
@ -18,7 +18,7 @@ class MyApp extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
List<Album> _albums;
|
||||
List<Album>? _albums;
|
||||
bool _loading = false;
|
||||
|
||||
@override
|
||||
@ -150,7 +150,7 @@ class AlbumPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class AlbumPageState extends State<AlbumPage> {
|
||||
List<Medium> _media;
|
||||
List<Medium>? _media;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -213,7 +213,7 @@ class ViewerPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
DateTime date = medium.creationDate ?? medium.modifiedDate;
|
||||
DateTime? date = medium.creationDate ?? medium.modifiedDate;
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
@ -221,7 +221,7 @@ class ViewerPage extends StatelessWidget {
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
),
|
||||
title: Text(date?.toLocal().toString()),
|
||||
title: date != null ? Text(date.toLocal().toString()) : null,
|
||||
),
|
||||
body: Container(
|
||||
alignment: Alignment.center,
|
||||
@ -244,7 +244,7 @@ class VideoProvider extends StatefulWidget {
|
||||
final String mediumId;
|
||||
|
||||
const VideoProvider({
|
||||
@required this.mediumId,
|
||||
required this.mediumId,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -252,12 +252,12 @@ class VideoProvider extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _VideoProviderState extends State<VideoProvider> {
|
||||
VideoPlayerController _controller;
|
||||
File _file;
|
||||
VideoPlayerController? _controller;
|
||||
File? _file;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
initAsync();
|
||||
});
|
||||
super.initState();
|
||||
@ -266,8 +266,8 @@ class _VideoProviderState extends State<VideoProvider> {
|
||||
Future<void> initAsync() async {
|
||||
try {
|
||||
_file = await PhotoGallery.getFile(mediumId: widget.mediumId);
|
||||
_controller = VideoPlayerController.file(_file);
|
||||
_controller.initialize().then((_) {
|
||||
_controller = VideoPlayerController.file(_file!);
|
||||
_controller?.initialize().then((_) {
|
||||
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||
setState(() {});
|
||||
});
|
||||
@ -278,25 +278,25 @@ class _VideoProviderState extends State<VideoProvider> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _controller == null || !_controller.value.initialized
|
||||
return _controller == null || !_controller!.value.isInitialized
|
||||
? Container()
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
AspectRatio(
|
||||
aspectRatio: _controller.value.aspectRatio,
|
||||
child: VideoPlayer(_controller),
|
||||
aspectRatio: _controller!.value.aspectRatio,
|
||||
child: VideoPlayer(_controller!),
|
||||
),
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_controller.value.isPlaying
|
||||
? _controller.pause()
|
||||
: _controller.play();
|
||||
_controller!.value.isPlaying
|
||||
? _controller!.pause()
|
||||
: _controller!.play();
|
||||
});
|
||||
},
|
||||
child: Icon(
|
||||
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
|
||||
_controller!.value.isPlaying ? Icons.pause : Icons.play_arrow,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -6,7 +6,7 @@ description: Demonstrates how to use the photo_gallery plugin.
|
||||
# publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
@ -22,10 +22,10 @@ dependencies:
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.3
|
||||
transparent_image: ^1.0.0
|
||||
permission_handler: ^5.0.1+1
|
||||
video_player: ^0.10.12
|
||||
cupertino_icons: ^1.0.2
|
||||
transparent_image: ^2.0.0
|
||||
permission_handler: ^6.1.1
|
||||
video_player: ^2.1.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -67,7 +67,7 @@ class PhotoGallery {
|
||||
MediumType? mediumType,
|
||||
int? width,
|
||||
int? height,
|
||||
bool? highQuality,
|
||||
bool? highQuality = false,
|
||||
}) async {
|
||||
final bytes = await _channel.invokeMethod('getThumbnail', {
|
||||
'mediumId': mediumId,
|
||||
@ -76,7 +76,7 @@ class PhotoGallery {
|
||||
'height': height,
|
||||
'highQuality': highQuality,
|
||||
});
|
||||
return bytes;
|
||||
return new List<int>.from(bytes);
|
||||
}
|
||||
|
||||
/// Get album thumbnail by album id
|
||||
@ -85,7 +85,7 @@ class PhotoGallery {
|
||||
MediumType? mediumType,
|
||||
int? width,
|
||||
int? height,
|
||||
bool? highQuality,
|
||||
bool? highQuality = false,
|
||||
}) async {
|
||||
final bytes = await _channel.invokeMethod('getAlbumThumbnail', {
|
||||
'albumId': albumId,
|
||||
@ -94,7 +94,7 @@ class PhotoGallery {
|
||||
'height': height,
|
||||
'highQuality': highQuality,
|
||||
});
|
||||
return bytes;
|
||||
return new List<int>.from(bytes);
|
||||
}
|
||||
|
||||
/// get medium file by medium id
|
||||
|
@ -7,7 +7,7 @@ class ThumbnailProvider extends ImageProvider<ThumbnailProvider> {
|
||||
this.mediumType,
|
||||
this.height,
|
||||
this.width,
|
||||
this.highQuality,
|
||||
this.highQuality = false,
|
||||
});
|
||||
|
||||
final String mediumId;
|
||||
|
@ -37,6 +37,7 @@ void main() {
|
||||
MediaPage expected = Generator.generateMediaPage(
|
||||
album: allAlbum,
|
||||
mediumType: mediumType,
|
||||
total: allAlbum.count,
|
||||
skip: skip,
|
||||
take: take,
|
||||
);
|
||||
|
@ -3,7 +3,8 @@ import 'dart:io';
|
||||
import 'package:photo_gallery/photo_gallery.dart';
|
||||
|
||||
class Generator {
|
||||
static dynamic generateAlbumsJson({MediumType mediumType = MediumType.image}) {
|
||||
static dynamic generateAlbumsJson(
|
||||
{MediumType? mediumType = MediumType.image}) {
|
||||
return [
|
||||
{
|
||||
"id": "__ALL__",
|
||||
@ -20,7 +21,7 @@ class Generator {
|
||||
];
|
||||
}
|
||||
|
||||
static List<Album> generateAlbums({required MediumType mediumType}) {
|
||||
static List<Album> generateAlbums({MediumType? mediumType}) {
|
||||
return Generator.generateAlbumsJson(mediumType: mediumType)
|
||||
.map<Album>((x) => Album.fromJson(x))
|
||||
.toList();
|
||||
@ -28,8 +29,8 @@ class Generator {
|
||||
|
||||
static dynamic generateMediaPageJson({
|
||||
required String albumId,
|
||||
required MediumType mediumType,
|
||||
required int total,
|
||||
MediumType? mediumType,
|
||||
int total = 10,
|
||||
int? skip,
|
||||
int? take,
|
||||
}) {
|
||||
@ -53,7 +54,7 @@ class Generator {
|
||||
|
||||
static dynamic generateMediaJson({
|
||||
required String mediumId,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
}) {
|
||||
return {
|
||||
"id": mediumId,
|
||||
@ -69,14 +70,15 @@ class Generator {
|
||||
|
||||
static MediaPage generateMediaPage({
|
||||
required Album album,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
required int total,
|
||||
int? skip,
|
||||
int? take,
|
||||
}) {
|
||||
dynamic json = generateMediaPageJson(
|
||||
albumId: album.id,
|
||||
mediumType: mediumType,
|
||||
total: album.count,
|
||||
total: total,
|
||||
skip: skip,
|
||||
take: take,
|
||||
);
|
||||
@ -85,7 +87,7 @@ class Generator {
|
||||
|
||||
static Medium generateMedia({
|
||||
required String mediumId,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
}) {
|
||||
return Medium.fromJson(
|
||||
generateMediaJson(mediumId: mediumId, mediumType: mediumType),
|
||||
@ -94,7 +96,7 @@ class Generator {
|
||||
|
||||
static List<int> generateMockThumbnail({
|
||||
required String mediumId,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
}) {
|
||||
return [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
}
|
||||
@ -107,14 +109,14 @@ class Generator {
|
||||
|
||||
static String generateFilePath({
|
||||
required String mediumId,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
}) {
|
||||
return "/path/to/file";
|
||||
}
|
||||
|
||||
static File generateFile({
|
||||
required String mediumId,
|
||||
required MediumType mediumType,
|
||||
MediumType? mediumType,
|
||||
}) {
|
||||
return File(generateFilePath(mediumId: mediumId, mediumType: mediumType));
|
||||
}
|
||||
|
@ -6,32 +6,32 @@ import 'generator.dart';
|
||||
|
||||
Future<dynamic> mockMethodCallHandler(MethodCall call) async {
|
||||
if (call.method == "listAlbums") {
|
||||
MediumType mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
dynamic albums = Generator.generateAlbumsJson(mediumType: mediumType);
|
||||
return albums;
|
||||
} else if (call.method == "listMedia") {
|
||||
String albumId = call.arguments['albumId'];
|
||||
MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
int total = call.arguments['total'];
|
||||
int skip = call.arguments['skip'];
|
||||
int take = call.arguments['take'];
|
||||
int? total = call.arguments['total'];
|
||||
int? skip = call.arguments['skip'];
|
||||
int? take = call.arguments['take'];
|
||||
dynamic mediaPage = Generator.generateMediaPageJson(
|
||||
albumId: albumId,
|
||||
mediumType: mediumType,
|
||||
total: total,
|
||||
total: total ?? 10,
|
||||
skip: skip,
|
||||
take: take,
|
||||
);
|
||||
return mediaPage;
|
||||
} else if (call.method == "getMedium") {
|
||||
String mediumId = call.arguments['mediumId'];
|
||||
MediumType mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
dynamic media =
|
||||
Generator.generateMediaJson(mediumId: mediumId, mediumType: mediumType);
|
||||
return media;
|
||||
} else if (call.method == "getThumbnail") {
|
||||
String mediumId = call.arguments['mediumId'];
|
||||
MediumType mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
dynamic thumbnail = Generator.generateMockThumbnail(
|
||||
mediumId: mediumId, mediumType: mediumType);
|
||||
return thumbnail;
|
||||
@ -41,7 +41,7 @@ Future<dynamic> mockMethodCallHandler(MethodCall call) async {
|
||||
return thumbnail;
|
||||
} else if (call.method == "getFile") {
|
||||
String mediumId = call.arguments['mediumId'];
|
||||
MediumType mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
MediumType? mediumType = jsonToMediumType(call.arguments['mediumType']);
|
||||
dynamic path =
|
||||
Generator.generateFilePath(mediumId: mediumId, mediumType: mediumType);
|
||||
return path;
|
||||
|
Loading…
x
Reference in New Issue
Block a user