Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Plugin platform interface #180

Merged
merged 7 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions lib/src/gal.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:gal/src/gal_exception.dart';
import 'package:gal/src/gal_platform.dart';
import 'package:gal/src/gal_platform_interface.dart';

/// Main class of gal.
///
Expand All @@ -20,7 +20,7 @@ final class Gal {
/// if an error occurs during saving.
/// See: [Formats](https://github.com/natsuk4ze/gal/wiki/Formats)
static Future<void> putVideo(String path, {String? album}) async =>
GalPlatform.putVideo(path, album: album);
GalPlatform.instance.putVideo(path, album: album);

/// Save a image to the gallery from file [path].
///
Expand All @@ -33,7 +33,7 @@ final class Gal {
/// if an error occurs during saving.
/// See: [Formats](https://github.com/natsuk4ze/gal/wiki/Formats)
static Future<void> putImage(String path, {String? album}) async =>
GalPlatform.putImage(path, album: album);
GalPlatform.instance.putImage(path, album: album);

/// Save a image to the gallery from [Uint8List].
///
Expand All @@ -42,20 +42,20 @@ final class Gal {
/// if an error occurs during saving.
/// See: [Formats](https://github.com/natsuk4ze/gal/wiki/Formats)
static Future<void> putImageBytes(Uint8List bytes, {String? album}) async =>
GalPlatform.putImageBytes(bytes, album: album);
GalPlatform.instance.putImageBytes(bytes, album: album);

/// Open gallery app.
///
/// If there are multiple gallery apps, App selection sheet may be displayed.
static Future<void> open() async => GalPlatform.open();
static Future<void> open() async => GalPlatform.instance.open();

/// Check if the app has access permissions.
///
/// Use the [toAlbum] for additional permissions to save to an album.
/// If you want to save to an album other than the one created by your app
/// See: [Permissions](https://github.com/natsuk4ze/gal/wiki/Permissions)
static Future<bool> hasAccess({bool toAlbum = false}) async =>
GalPlatform.hasAccess(toAlbum: toAlbum);
GalPlatform.instance.hasAccess(toAlbum: toAlbum);

/// Request access permissions.
///
Expand All @@ -65,5 +65,5 @@ final class Gal {
/// If you want to save to an album other than the one created by your app
/// See: [Permissions](https://github.com/natsuk4ze/gal/wiki/Permissions)
static Future<bool> requestAccess({bool toAlbum = false}) async =>
GalPlatform.requestAccess(toAlbum: toAlbum);
GalPlatform.instance.requestAccess(toAlbum: toAlbum);
}
36 changes: 22 additions & 14 deletions lib/src/gal_platform.dart → lib/src/gal_method_channel.dart
Original file line number Diff line number Diff line change
@@ -1,49 +1,57 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:gal/gal.dart';
import 'package:gal/src/gal_exception.dart';

const _channel = MethodChannel('gal');
import 'gal_platform_interface.dart';

/// Plugin Communication
@immutable
final class GalPlatform {
const GalPlatform._();
final class MethodChannelGal extends GalPlatform {
final _methodChannel = const MethodChannel('gal');

static Future<T?> _invokeMethod<T>(
String method, Map<String, dynamic> args) async {
Future<T?> _invokeMethod<T>(String method, Map<String, dynamic> args) async {
try {
return await _channel.invokeMethod<T>(method, args);
return await _methodChannel.invokeMethod<T>(method, args);
} on PlatformException catch (error, stackTrace) {
throw GalException.fromCode(
code: error.code, platformException: error, stackTrace: stackTrace);
code: error.code,
platformException: error,
stackTrace: stackTrace,
);
}
}

static Future<void> putVideo(String path, {String? album}) async {
@override
Future<void> putVideo(String path, {String? album}) async {
await requestAccess(toAlbum: album != null);
await _invokeMethod<void>('putVideo', {'path': path, 'album': album});
}

static Future<void> putImage(String path, {String? album}) async {
@override
Future<void> putImage(String path, {String? album}) async {
await requestAccess(toAlbum: album != null);
await _invokeMethod<void>('putImage', {'path': path, 'album': album});
}

static Future<void> putImageBytes(Uint8List bytes, {String? album}) async {
@override
Future<void> putImageBytes(Uint8List bytes, {String? album}) async {
await requestAccess(toAlbum: album != null);
await _invokeMethod<void>(
'putImageBytes', {'bytes': bytes, 'album': album});
}

static Future<void> open() async => _invokeMethod<void>('open', {});
@override
Future<void> open() async => _invokeMethod<void>('open', {});

static Future<bool> hasAccess({bool toAlbum = false}) async {
@override
Future<bool> hasAccess({bool toAlbum = false}) async {
final hasAccess =
await _invokeMethod<bool>('hasAccess', {'toAlbum': toAlbum});
return hasAccess ?? false;
}

static Future<bool> requestAccess({bool toAlbum = false}) async {
@override
Future<bool> requestAccess({bool toAlbum = false}) async {
final granted =
await _invokeMethod<bool>('requestAccess', {'toAlbum': toAlbum});
return granted ?? false;
Expand Down
39 changes: 39 additions & 0 deletions lib/src/gal_platform_interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'dart:typed_data';

import 'gal_method_channel.dart';

/// Plugin Platform Interface
base class GalPlatform {
const GalPlatform();
static GalPlatform instance = MethodChannelGal();

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [putVideo].
Future<void> putVideo(String path, {String? album}) =>
throw UnimplementedError('putVideo() has not been implemented.');

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [putImage].
Future<void> putImage(String path, {String? album}) =>
throw UnimplementedError('putImage() has not been implemented.');

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [putImageBytes].
Future<void> putImageBytes(Uint8List bytes, {String? album}) =>
throw UnimplementedError('putImageBytes() has not been implemented.');

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [open].
Future<void> open() =>
throw UnimplementedError('open() has not been implemented.');

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [hasAccess].
Future<bool> hasAccess({bool toAlbum = false}) =>
throw UnimplementedError('hasAccess() has not been implemented.');

/// throw [UnimplementedError] when Plugin [MethodChannelGal] did not
/// define [requestAccess].
Future<bool> requestAccess({bool toAlbum = false}) =>
throw UnimplementedError('requestAccess() has not been implemented.');
}