diff --git a/CHANGELOG.md b/CHANGELOG.md index 34b7811..2a1c931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,4 +44,41 @@ * Fixed an issue where a user not sharing their Bitmoji would cause an exception * Fixed Videos not working on Android Clients * Fixed an issue where some Videos wouldn't work despite meeting Snapchat's Video requirements -* Bug fixes & Code improvements \ No newline at end of file +* Bug fixes & Code improvements + +## 3.0.0 + +* **BREAKING CHANGE:** Upgraded Snap Kit on Android to 2.1.0. + When updating this plugin, please perform the following changes to your app: + * in `android/build.gradle`, remove the following: + + ```groovy + maven { + url "https://storage.googleapis.com/snap-kit-build/maven" + } + ``` + + * in `android/app/build.gradle`, remove the following: + + ```groovy + implementation([ + 'com.snapchat.kit.sdk:creative:1.10.0', + 'com.snapchat.kit.sdk:login:1.10.0', + 'com.snapchat.kit.sdk:bitmoji:1.10.0', + 'com.snapchat.kit.sdk:core:1.10.0' + ]) + ``` + + * in `android/app/src/main/AndroidManifest.xml`: + * change `com.snapchat.kit.sdk.clientId` to `com.snap.kit.clientId` + * change `com.snapchat.kit.sdk.redirectUrl` to `com.snap.kit.redirectUrl` + * change `com.snapchat.kit.sdk.scopes` to `com.snap.kit.scopes"` + * remove the following: + + ```xml + + + + ``` + +* Widened `http` support to >=0.13.3 <2.0.0 diff --git a/README.md b/README.md index 6443e0f..a1da9c8 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Snapkit [![Pub Package](https://img.shields.io/pub/v/snapkit.svg)](https://pub.dev/packages/snapkit) -[![Code Analysis](https://github.com/TimmyRB/snapkit/actions/workflows/code-analysis.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/code-analysis.yml) -[![Android Builds](https://github.com/TimmyRB/snapkit/actions/workflows/build-android.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/build-android.yml) -[![iOS Builds](https://github.com/TimmyRB/snapkit/actions/workflows/build-ios.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/build-ios.yml) +[![Code Analysis](https://github.com/TimmyRB/snapkit/actions/workflows/code-analysis.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/code-analysis.yml) +[![Android Builds](https://github.com/TimmyRB/snapkit/actions/workflows/build-android.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/build-android.yml) +[![iOS Builds](https://github.com/TimmyRB/snapkit/actions/workflows/build-ios.yml/badge.svg)](https://github.com/TimmyRB/snapkit/actions/workflows/build-ios.yml) A plugin that allows developers like you to integrate with Snapchat (using [SnapKit](https://kit.snapchat.com)) into your Flutter applications! @@ -14,11 +14,13 @@ Follow the [Wiki](https://github.com/TimmyRB/snapkit/wiki) for steps on how to g ## Usage ### Create new Instance + ```dart -Snapkit snapkit = new Snapkit(); +final snapkit = Snapkit(); ``` ### AuthState Stream + ```dart snapkit.onAuthStateChanged.listen((SnapchatUser? user) { // Do something with the returned SnapchatUser or null here @@ -26,10 +28,14 @@ snapkit.onAuthStateChanged.listen((SnapchatUser? user) { ``` ### AuthState Class + ```dart class MyAppState extends State implements SnapchatAuthStateListener { - - snapkit.addAuthStateListener(this); + @override + void initState() { + super.initState(); + _snapkit.addAuthStateListener(this); + } @override void onLogin(SnapchatUser user) { @@ -40,42 +46,41 @@ class MyAppState extends State implements SnapchatAuthStateListener { void onLogout() { // Do something on logout } - } ``` ### Login + ```dart await snapkit.login(); - -// or - -snapkit.login().then(user => {}); ``` ### Logout + ```dart await snapkit.logout(); - -// or - -snapkit.logout().then(() => {}); ``` ### Verify a Phone Number + Returns a `bool` if Snapchat has verified the phone number, throws -an error if there was a problem. Always returns `false` on Android +an error if there was a problem. Always returns `false` on Android. + ```dart -snapkit.verifyPhoneNumber('US', '1231234567') - .then(isVerified {}) - .catchError((error, StackTrace stacktrace) {}) +try { + final isVerified = await snapkit.verifyPhoneNumber('US', '1231234567'); +} catch (error, stackTrace) { + // Handle error +} ``` ## Share to Snapchat ### Share to LIVE + ```dart -snapkit.share(SnapchatMediaType.NONE, +snapkit.share( + SnapchatMediaType.NONE, sticker: SnapchatSticker?, caption: String?, attachmentUrl: String? @@ -83,29 +88,35 @@ snapkit.share(SnapchatMediaType.NONE, ``` ### Share with Background Photo + ```dart -snapkit.share(SnapchatMediaType.PHOTO, +snapkit.share( + SnapchatMediaType.PHOTO, image: ImageProvider, sticker: SnapchatSticker?, caption: String?, - attachmentUrl: String? + attachmentUrl: String?, ); ``` ### Share with Background Video -Currently unavailable on Android + +Currently unavailable on Android. + ```dart -snapkit.share(SnapchatMediaType.VIDEO, +snapkit.share( + SnapchatMediaType.VIDEO, videoUrl: String, sticker: SnapchatSticker?, caption: String?, - attachmentUrl: String? + attachmentUrl: String?, ); ``` ### SnapchatSticker + ```dart -new SnapchatSticker( - image: ImageProvider +SnapchatSticker( + image: ImageProvider, ); ``` diff --git a/android/build.gradle b/android/build.gradle index c94748f..5fd91b0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,28 +4,34 @@ version '1.0' buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.1' } } rootProject.allprojects { repositories { google() - jcenter() - maven { - url "https://storage.googleapis.com/snap-kit-build/maven" - } + mavenCentral() } } apply plugin: 'com.android.library' android { - compileSdkVersion 30 + if (project.android.hasProperty("namespace")) { + namespace 'com.jacobbrasil.snapkit' + } + + compileSdkVersion 33 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } defaultConfig { minSdkVersion 19 @@ -34,9 +40,7 @@ android { dependencies { implementation([ - 'com.snapchat.kit.sdk:creative:1.10.0', - 'com.snapchat.kit.sdk:login:1.10.0', - 'com.snapchat.kit.sdk:bitmoji:1.10.0', - 'com.snapchat.kit.sdk:core:1.10.0' + 'com.snap.creativekit:creativekit:2.1.0', + 'com.snap.loginkit:loginkit:2.1.0', ]) } diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c9d085..0e9a610 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index e1bae7f..2be0412 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,3 +1,6 @@ + + + diff --git a/android/src/main/java/com/jacobbrasil/snapkit/SnapkitPlugin.java b/android/src/main/java/com/jacobbrasil/snapkit/SnapkitPlugin.java index 7159187..0f5c68d 100644 --- a/android/src/main/java/com/jacobbrasil/snapkit/SnapkitPlugin.java +++ b/android/src/main/java/com/jacobbrasil/snapkit/SnapkitPlugin.java @@ -5,30 +5,39 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.snapchat.kit.sdk.SnapCreative; -import com.snapchat.kit.sdk.SnapLogin; -import com.snapchat.kit.sdk.core.controller.LoginStateController.OnLoginStateChangedListener; -import com.snapchat.kit.sdk.creative.api.SnapCreativeKitApi; -import com.snapchat.kit.sdk.creative.exceptions.SnapMediaSizeException; -import com.snapchat.kit.sdk.creative.exceptions.SnapStickerSizeException; -import com.snapchat.kit.sdk.creative.exceptions.SnapVideoLengthException; -import com.snapchat.kit.sdk.creative.media.SnapMediaFactory; -import com.snapchat.kit.sdk.creative.media.SnapPhotoFile; -import com.snapchat.kit.sdk.creative.media.SnapSticker; -import com.snapchat.kit.sdk.creative.media.SnapVideoFile; -import com.snapchat.kit.sdk.creative.models.SnapContent; -import com.snapchat.kit.sdk.creative.models.SnapLiveCameraContent; -import com.snapchat.kit.sdk.creative.models.SnapPhotoContent; -import com.snapchat.kit.sdk.creative.models.SnapVideoContent; -import com.snapchat.kit.sdk.login.models.MeData; -import com.snapchat.kit.sdk.login.models.UserDataResponse; -import com.snapchat.kit.sdk.login.networking.FetchUserDataCallback; -import com.snapchat.kit.sdk.util.SnapUtils; +import com.snap.corekit.utils.SnapUtils; +import com.snap.creativekit.SnapCreative; +import com.snap.creativekit.api.SnapCreativeKitApi; +import com.snap.creativekit.api.SnapCreativeKitCompletionCallback; +import com.snap.creativekit.api.SnapCreativeKitSendError; +import com.snap.creativekit.exceptions.SnapMediaSizeException; +import com.snap.creativekit.exceptions.SnapStickerSizeException; +import com.snap.creativekit.exceptions.SnapVideoLengthException; +import com.snap.creativekit.media.SnapMediaFactory; +import com.snap.creativekit.media.SnapPhotoFile; +import com.snap.creativekit.media.SnapSticker; +import com.snap.creativekit.media.SnapVideoFile; +import com.snap.creativekit.models.SnapContent; +import com.snap.creativekit.models.SnapLiveCameraContent; +import com.snap.creativekit.models.SnapPhotoContent; +import com.snap.creativekit.models.SnapVideoContent; +import com.snap.loginkit.BitmojiQuery; +import com.snap.loginkit.LoginStateCallback; +import com.snap.loginkit.SnapLogin; +import com.snap.loginkit.SnapLoginProvider; +import com.snap.loginkit.UserDataQuery; +import com.snap.loginkit.UserDataResultCallback; +import com.snap.loginkit.exceptions.LoginException; +import com.snap.loginkit.exceptions.UserDataException; +import com.snap.loginkit.models.BitmojiData; +import com.snap.loginkit.models.MeData; +import com.snap.loginkit.models.UserDataResult; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; @@ -41,16 +50,49 @@ /** * SnapkitPlugin */ -public class SnapkitPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, OnLoginStateChangedListener { +public class SnapkitPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { /// The MethodChannel that will the communication between Flutter and native Android /// /// This local reference serves to register the plugin with the Flutter Engine and unregister it /// when the Flutter Engine is detached from the Activity + @Nullable private MethodChannel channel; + + @Nullable private Activity _activity; - private MethodChannel.Result _result; - private SnapCreativeKitApi creativeKitApi; - private SnapMediaFactory mediaFactory; + + @NonNull + private Activity requireActivity() { + return Objects.requireNonNull(_activity, "Snapkit plugin is not attached to an activity."); + } + + @Nullable + private SnapCreativeKitApi snapCreativeKitApi; + + @NonNull + private SnapCreativeKitApi getSnapCreativeKitApi() { + if (snapCreativeKitApi == null) snapCreativeKitApi = SnapCreative.getApi(requireActivity()); + return snapCreativeKitApi; + } + + @Nullable + private SnapMediaFactory snapMediaFactory; + + @NonNull + private SnapMediaFactory getSnapMediaFactory() { + if (snapMediaFactory == null) + snapMediaFactory = SnapCreative.getMediaFactory(requireActivity()); + return snapMediaFactory; + } + + @Nullable + private SnapLogin snapLogin; + + @NonNull + private SnapLogin getSnapLogin() { + if (snapLogin == null) snapLogin = SnapLoginProvider.get(requireActivity()); + return snapLogin; + } @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { @@ -62,123 +104,39 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBindin public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) { switch (call.method) { case "callLogin": - SnapLogin.getLoginStateController(_activity).addOnLoginStateChangedListener(this); - SnapLogin.getAuthTokenManager(_activity).startTokenGrant(); - _result = result; + callLogin(result); break; case "getUser": - String query = "{me{externalId, displayName, bitmoji{selfie}}}"; - SnapLogin.fetchUserData(_activity, query, null, new FetchUserDataCallback() { - @Override - public void onSuccess(@Nullable UserDataResponse userDataResponse) { - if (userDataResponse == null || userDataResponse.getData() == null) { - return; - } - - MeData meData = userDataResponse.getData().getMe(); - if (meData == null) { - result.error("GetUserError", "Returned MeData was null", null); - return; - } - - List res = new ArrayList(); - res.add(meData.getExternalId()); - res.add(meData.getDisplayName()); - res.add(meData.getBitmojiData().getSelfie()); - - result.success(res); - } - - @Override - public void onFailure(boolean isNetworkError, int statusCode) { - if (isNetworkError) { - result.error("NetworkGetUserError", "Network Error", statusCode); - } else { - result.error("UnknownGetUserError", "Unknown Error", statusCode); - } - } - }); + getUser(result); break; case "sendMedia": - if (creativeKitApi == null) creativeKitApi = SnapCreative.getApi(_activity); - if (mediaFactory == null) mediaFactory = SnapCreative.getMediaFactory(_activity); - - SnapContent content; - switch ((String)call.argument("mediaType")) { - case "PHOTO": - try { - SnapPhotoFile photoFile = mediaFactory.getSnapPhotoFromFile(new File((String) call.argument("imagePath"))); - content = new SnapPhotoContent(photoFile); - } catch (SnapMediaSizeException e) { - result.error("SendMediaError", "Could not create SnapPhotoFile", e); - return; - } catch (NullPointerException e) { - result.error("SendMediaError", "Could not find Image file", e); - return; - } - - break; - case "VIDEO": - try { - SnapVideoFile videoFile = mediaFactory.getSnapVideoFromFile(new File((String) call.argument("videoPath"))); - content = new SnapVideoContent(videoFile); - } catch (SnapMediaSizeException | SnapVideoLengthException e) { - result.error("SendMediaError", "Could not create SnapVideoFile", e); - return; - } catch (NullPointerException e) { - result.error("SendMediaError", "Could not find Video file", e); - return; - } - - break; - default: - content = new SnapLiveCameraContent(); - break; - } - - content.setCaptionText((String)call.argument("caption")); - content.setAttachmentUrl((String)call.argument("attachmentUrl")); - - if (call.argument("sticker") != null) { - Map stickerMap = (Map) call.argument("sticker"); - SnapSticker sticker = null; - try { - sticker = mediaFactory.getSnapStickerFromFile(new File((String) stickerMap.get("imagePath"))); - } catch (SnapStickerSizeException e) { - result.error("SendMediaError", "Could not create SnapSticker", e); - return; - } catch (NullPointerException e) { - result.error("SendMediaError", "Could not find Sticker file", e); - return; - } - - if (sticker != null) { - sticker.setWidthDp(Float.parseFloat(stickerMap.get("width").toString())); - sticker.setHeightDp(Float.parseFloat(stickerMap.get("height").toString())); - - sticker.setPosX(Float.parseFloat(stickerMap.get("offsetX").toString())); - sticker.setPosY(Float.parseFloat(stickerMap.get("offsetY").toString())); - - sticker.setRotationDegreesClockwise(Float.parseFloat(stickerMap.get("rotation").toString())); - - content.setSnapSticker(sticker); - } - } - - creativeKitApi.send(content); + final String imagePath = call.argument("imagePath"); + final String videoPath = call.argument("videoPath"); + final Map sticker = call.argument("sticker"); + sendMedia( + Objects.requireNonNull(call.argument("mediaType")), + imagePath == null ? null : new File(imagePath), + videoPath == null ? null : new File(videoPath), + sticker == null ? null : StickerArguments.fromMap(sticker), + call.argument("caption"), + call.argument("attachmentUrl"), + result + ); break; case "verifyNumber": - List res = new ArrayList(); + List res = new ArrayList<>(); res.add(""); res.add(""); result.success(res); break; case "callLogout": - SnapLogin.getAuthTokenManager(_activity).clearToken(); - _result = result; + callLogout(result); break; case "isInstalled": - result.success(SnapUtils.isSnapchatInstalled(_activity.getPackageManager(), "com.snapchat.android")); + result.success(SnapUtils.isSnapchatInstalled( + requireActivity().getPackageManager(), + "com.snapchat.android" + )); break; case "getPlatformVersion": result.success("Android " + android.os.Build.VERSION.RELEASE); @@ -189,24 +147,9 @@ public void onFailure(boolean isNetworkError, int statusCode) { } } - @Override - public void onLoginSucceeded() { - _result.success("Login Success"); - } - - @Override - public void onLoginFailed() { - _result.error("LoginError", "Error Logging In", null); - } - - @Override - public void onLogout() { - _result.success("Logout Success"); - } - @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - channel.setMethodCallHandler(null); + Objects.requireNonNull(channel).setMethodCallHandler(null); } @Override @@ -226,6 +169,249 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin @Override public void onDetachedFromActivity() { + _activity = null; + } + + // Creative Kit: https://docs.snap.com/snap-kit/creative-kit/Tutorials/android + + void sendMedia( + @NonNull String mediaType, + @Nullable File imagePath, + @Nullable File videoPath, + @Nullable StickerArguments sticker, + @Nullable String caption, + @Nullable String attachmentUrl, + @NonNull MethodChannel.Result result + ) { + final SnapMediaFactory mediaFactory = getSnapMediaFactory(); + + SnapContent content; + switch (mediaType) { + case "PHOTO": + if (imagePath == null) { + result.error( + "SendMediaError", + "mediaType is set to photo but imagePath is null.", + null + ); + return; + } + + SnapPhotoFile photoFile; + try { + photoFile = mediaFactory.getSnapPhotoFromFile(imagePath); + } catch (SnapMediaSizeException e) { + result.error("SendMediaError", "Could not create SnapPhotoFile: " + e, null); + return; + } catch (NullPointerException e) { + result.error("SendMediaError", "Could not find image file: " + e, null); + return; + } + + content = new SnapPhotoContent(photoFile); + break; + case "VIDEO": + if (videoPath == null) { + result.error( + "SendMediaError", + "mediaType is set to video but videoPath is null.", + null + ); + return; + } + + SnapVideoFile videoFile; + try { + videoFile = mediaFactory.getSnapVideoFromFile(videoPath); + } catch (SnapMediaSizeException | SnapVideoLengthException e) { + result.error("SendMediaError", "Could not create SnapVideoFile: " + e, null); + return; + } catch (NullPointerException e) { + result.error("SendMediaError", "Could not find video file: " + e, null); + return; + } + + content = new SnapVideoContent(videoFile); + break; + default: + content = new SnapLiveCameraContent(); + break; + } + + content.setCaptionText(caption); + content.setAttachmentUrl(attachmentUrl); + + if (sticker != null) { + SnapSticker snapSticker; + try { + snapSticker = mediaFactory.getSnapStickerFromFile(sticker.image); + } catch (SnapStickerSizeException e) { + result.error("SendMediaError", "Could not create SnapSticker: " + e, null); + return; + } catch (NullPointerException e) { + result.error("SendMediaError", "Could not find sticker file: " + e, null); + return; + } + + snapSticker.setWidthDp(sticker.width); + snapSticker.setHeightDp(sticker.height); + snapSticker.setPosX(sticker.offsetX); + snapSticker.setPosY(sticker.offsetY); + snapSticker.setRotationDegreesClockwise(sticker.rotation); + content.setSnapSticker(snapSticker); + } + + final SnapCreativeKitCompletionCallback callback = new SnapCreativeKitCompletionCallback() { + @Override + public void onSendSuccess() { + result.success("SendMedia Success"); + } + + @Override + public void onSendFailed(SnapCreativeKitSendError snapCreativeKitSendError) { + result.error("SendMediaError", snapCreativeKitSendError.name(), null); + } + }; + getSnapCreativeKitApi().sendWithCompletionHandler(content, callback); + } + + static class StickerArguments { + @NonNull + File image; + float width; + float height; + float offsetX; + float offsetY; + float rotation; + + public StickerArguments( + @NonNull File image, + float width, + float height, + float offsetX, + float offsetY, + float rotation + ) { + this.image = image; + this.width = width; + this.height = height; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.rotation = rotation; + } + + static StickerArguments fromMap(Map map) { + return new StickerArguments( + new File((String) Objects.requireNonNull(map.get("imagePath"))), + ((Double) Objects.requireNonNull(map.get("width"))).floatValue(), + ((Double) Objects.requireNonNull(map.get("height"))).floatValue(), + ((Double) Objects.requireNonNull(map.get("offsetX"))).floatValue(), + ((Double) Objects.requireNonNull(map.get("offsetY"))).floatValue(), + ((Double) Objects.requireNonNull(map.get("rotation"))).floatValue() + ); + } + } + + // Login Kit: https://docs.snap.com/snap-kit/login-kit/Tutorials/android + + void callLogin(@NonNull MethodChannel.Result result) { + final SnapLogin snapLogin = getSnapLogin(); + final LoginStateCallback callback = new LoginStateCallback() { + @Override + public void onStart() { + } + + @Override + public void onSuccess(@NonNull String s) { + result.success("Login Success"); + snapLogin.removeLoginStateCallback(this); + } + + @Override + public void onFailure(@NonNull LoginException e) { + result.error("LoginError", "Error Logging In", e); + snapLogin.removeLoginStateCallback(this); + } + + @Override + public void onLogout() { + snapLogin.removeLoginStateCallback(this); + } + }; + snapLogin.addLoginStateCallback(callback); + snapLogin.startTokenGrant(); + } + + void getUser(@NonNull MethodChannel.Result result) { + final BitmojiQuery bitmojiQuery = BitmojiQuery.newBuilder() + .withTwoDAvatarUrl() + .build(); + final UserDataQuery userDataQuery = UserDataQuery.newBuilder() + .withExternalId() + .withDisplayName() + .withBitmoji(bitmojiQuery) + .build(); + getSnapLogin().fetchUserData(userDataQuery, new UserDataResultCallback() { + @Override + public void onSuccess(@NonNull UserDataResult userDataResult) { + if (userDataResult.getData() == null) + return; + + + final MeData meData = userDataResult.getData().getMeData(); + if (meData == null) { + result.error("GetUserError", "Returned MeData was null", null); + return; + } + final BitmojiData bitmojiData = meData.getBitmojiData(); + + List res = new ArrayList<>(); + res.add(meData.getExternalId()); + res.add(meData.getDisplayName()); + res.add(bitmojiData == null ? null : bitmojiData.getTwoDAvatarUrl()); + result.success(res); + } + + @Override + public void onFailure(@NonNull UserDataException e) { + UserDataException.Status status = null; + for (UserDataException.Status s : UserDataException.Status.values()) { + if (s.code == e.getStatusCode()) { + status = s; + break; + } + } + Objects.requireNonNull(status); + result.error("UnknownGetUserError", status.message, status.code); + } + }); + } + void callLogout(@NonNull MethodChannel.Result result) { + final SnapLogin snapLogin = getSnapLogin(); + LoginStateCallback callback = new LoginStateCallback() { + @Override + public void onStart() { + } + + @Override + public void onSuccess(@NonNull String s) { + snapLogin.removeLoginStateCallback(this); + } + + @Override + public void onFailure(@NonNull LoginException e) { + result.error("LogoutError", "Error Logging In: " + e, null); + snapLogin.removeLoginStateCallback(this); + } + + @Override + public void onLogout() { + result.success("Logout Success"); + snapLogin.removeLoginStateCallback(this); + } + }; + snapLogin.addLoginStateCallback(callback); + snapLogin.clearToken(); } } diff --git a/example/.metadata b/example/.metadata index 9f8c408..25d90ec 100644 --- a/example/.metadata +++ b/example/.metadata @@ -1,10 +1,30 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: 48c9d3e0e19e8fec84f1d316ce0559f26ca7277d - channel: beta + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 796c8ef79279f9c774545b3771238c3098dbefab + base_revision: 796c8ef79279f9c774545b3771238c3098dbefab + - platform: android + create_revision: 796c8ef79279f9c774545b3771238c3098dbefab + base_revision: 796c8ef79279f9c774545b3771238c3098dbefab + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/android/.gitignore b/example/android/.gitignore index 0a741cb..6f56801 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties +**/*.keystore +**/*.jks diff --git a/example/android/.project b/example/android/.project deleted file mode 100644 index 2c241ce..0000000 --- a/example/android/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - android - Project android created by Buildship. - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.buildship.core.gradleprojectnature - - - - 1613022023065 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/example/android/.settings/org.eclipse.buildship.core.prefs b/example/android/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 9bb9226..0000000 --- a/example/android/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments= -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.12.jdk/Contents/Home -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/example/android/app/.classpath b/example/android/app/.classpath deleted file mode 100644 index 4a04201..0000000 --- a/example/android/app/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/example/android/app/.project b/example/android/app/.project deleted file mode 100644 index 86579a0..0000000 --- a/example/android/app/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - app - Project app created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - - - 1613022023076 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/example/android/app/.settings/org.eclipse.buildship.core.prefs b/example/android/app/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index b1886ad..0000000 --- a/example/android/app/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -connection.project.dir=.. -eclipse.preferences.version=1 diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 0080986..574cc62 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -22,21 +22,34 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + namespace "com.jacobbrasil.snapkit_example" + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.jacobbrasil.snapkit_example" + // Snap Kit requires SDK version 19 or later, but `flutter.minSdkVersion` currently is 16. minSdkVersion 19 - targetSdkVersion 30 + targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName - ndk { - abiFilters 'armeabi-v7a', 'arm64-v8a' - } } buildTypes { @@ -46,15 +59,6 @@ android { signingConfig signingConfigs.debug } } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - dependenciesInfo { - includeInBundle true - includeInApk true - } - buildToolsVersion '29.0.2' } flutter { @@ -62,10 +66,5 @@ flutter { } dependencies { - implementation([ - 'com.snapchat.kit.sdk:creative:1.10.0', - 'com.snapchat.kit.sdk:login:1.10.0', - 'com.snapchat.kit.sdk:bitmoji:1.10.0', - 'com.snapchat.kit.sdk:core:1.10.0' - ]) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index f562f73..399f698 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 85fb440..316d637 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,51 +1,51 @@ - - + - - - - - + - + - - - - + - - - - + + + + + + + + + - - - - + + + + - - @@ -80,9 +71,4 @@ android:value="2" /> - - - - - diff --git a/example/android/app/src/main/java/com/jacobbrasil/snapkit_example/MainActivity.java b/example/android/app/src/main/java/com/jacobbrasil/snapkit_example/MainActivity.java deleted file mode 100644 index 588615a..0000000 --- a/example/android/app/src/main/java/com/jacobbrasil/snapkit_example/MainActivity.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.jacobbrasil.snapkit_example; - -import io.flutter.embedding.android.FlutterActivity; - -public class MainActivity extends FlutterActivity { -} diff --git a/example/android/app/src/main/kotlin/com/jacobbrasil/snapkit_example/MainActivity.kt b/example/android/app/src/main/kotlin/com/jacobbrasil/snapkit_example/MainActivity.kt new file mode 100644 index 0000000..e651ba9 --- /dev/null +++ b/example/android/app/src/main/kotlin/com/jacobbrasil/snapkit_example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.jacobbrasil.snapkit_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml index 449a9f9..06952be 100644 --- a/example/android/app/src/main/res/values-night/styles.xml +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -3,14 +3,14 @@