diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb57093 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +metadata.json +*.zip +*.xcworkspace/ +*.xcuserstate +xcuserdata/ +build/ +/android/dist diff --git a/README.md b/README.md index 98b6bda..a19b0cf 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ as a pre-packaged module for Titanium SDK 7.1.0 and later. ## Roadmap - [x] Find suitable module name -- [ ] Create both modules on the same namespace (right now [Ti.SafariDialog](https://github.com/appcelerator-modules/ti.safaridialog) vs [Ti.ChromeTabs](https://github.com/prashantsaini1/ti-chrometabs)) +- [x] Create both modules on the same namespace (right now [Ti.SafariDialog](https://github.com/appcelerator-modules/ti.safaridialog) vs [Ti.ChromeTabs](https://github.com/prashantsaini1/ti-chrometabs)) - [ ] Adjust existing docs from Ti.SafariDialog to support Android as well -- [ ] Write cross-platform example and tests +- [x] Write cross-platform example and tests - [ ] Pre-package in the SDK, release module ## License diff --git a/android/java-sources.txt b/android/java-sources.txt new file mode 100644 index 0000000..0e2290f --- /dev/null +++ b/android/java-sources.txt @@ -0,0 +1,10 @@ +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/src/ti/webdialog/Params.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/src/ti/webdialog/TitaniumWebDialogModule.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/src/ti/webdialog/Utils.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/java/ti/webdialog/TitaniumWebDialogBootstrap.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/android/support/compat/R.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/android/support/design/R.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/android/support/v7/appcompat/R.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/android/support/v7/cardview/R.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/ti/modules/titanium/ui/R.java" +"/Users/hknoechel/Documents/appcelerator_modules/titanium-web-dialog/android/build/generated/r/ti/webdialog/R.java" \ No newline at end of file diff --git a/android/lib/README b/android/lib/README deleted file mode 100644 index a54313f..0000000 --- a/android/lib/README +++ /dev/null @@ -1,2 +0,0 @@ -You can place any .jar dependencies in this directory and they will be included -when your module is being compiled. \ No newline at end of file diff --git a/android/lib/custom-tabs.jar b/android/lib/custom-tabs.jar new file mode 100755 index 0000000..b10e445 Binary files /dev/null and b/android/lib/custom-tabs.jar differ diff --git a/android/libs/arm64-v8a/libti.webdialog.so b/android/libs/arm64-v8a/libti.webdialog.so new file mode 100644 index 0000000..e16cf65 Binary files /dev/null and b/android/libs/arm64-v8a/libti.webdialog.so differ diff --git a/android/libs/armeabi-v7a/libti.webdialog.so b/android/libs/armeabi-v7a/libti.webdialog.so new file mode 100644 index 0000000..92733ce Binary files /dev/null and b/android/libs/armeabi-v7a/libti.webdialog.so differ diff --git a/android/libs/x86/libti.webdialog.so b/android/libs/x86/libti.webdialog.so new file mode 100644 index 0000000..5032eb3 Binary files /dev/null and b/android/libs/x86/libti.webdialog.so differ diff --git a/android/manifest b/android/manifest index ed1fa76..65288d2 100644 --- a/android/manifest +++ b/android/manifest @@ -6,13 +6,13 @@ version: 1.0.0 apiversion: 4 architectures: arm64-v8a armeabi-v7a x86 description: titanium-web-dialog -author: Hans Knoechel -license: Specify your license -copyright: Copyright (c) 2017 by Your Company +author: Prashant Saini +license: Apache 2.0 +copyright: Copyright (c) 2017 by Axway Appcelerator & Prashant Saini # these should not be edited name: titanium-web-dialog moduleid: ti.webdialog guid: 1f19cce1-0ad7-4e25-ab3b-0666f54a0a49 platform: android -minsdk: 7.0.0.v20171128203009 +minsdk: 7.0.0 diff --git a/android/src/ti/webdialog/ExampleProxy.java b/android/src/ti/webdialog/ExampleProxy.java deleted file mode 100644 index 418fb5c..0000000 --- a/android/src/ti/webdialog/ExampleProxy.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * This file was auto-generated by the Titanium Module SDK helper for Android - * Appcelerator Titanium Mobile - * Copyright (c) 2009-2017 by Appcelerator, Inc. All Rights Reserved. - * Licensed under the terms of the Apache Public License - * Please see the LICENSE included with this distribution for details. - * - */ -package ti.webdialog; - -import org.appcelerator.kroll.KrollDict; -import org.appcelerator.kroll.KrollProxy; -import org.appcelerator.kroll.annotations.Kroll; -import org.appcelerator.titanium.TiC; -import org.appcelerator.kroll.common.Log; -import org.appcelerator.kroll.common.TiConfig; -import org.appcelerator.titanium.util.TiConvert; -import org.appcelerator.titanium.proxy.TiViewProxy; -import org.appcelerator.titanium.view.TiCompositeLayout; -import org.appcelerator.titanium.view.TiCompositeLayout.LayoutArrangement; -import org.appcelerator.titanium.view.TiUIView; - -import android.app.Activity; - - -// This proxy can be created by calling TitaniumWebDialog.createExample({message: "hello world"}) -@Kroll.proxy(creatableInModule=TitaniumWebDialogModule.class) -public class ExampleProxy extends TiViewProxy -{ - // Standard Debugging variables - private static final String LCAT = "ExampleProxy"; - private static final boolean DBG = TiConfig.LOGD; - - private class ExampleView extends TiUIView - { - public ExampleView(TiViewProxy proxy) { - super(proxy); - LayoutArrangement arrangement = LayoutArrangement.DEFAULT; - - if (proxy.hasProperty(TiC.PROPERTY_LAYOUT)) { - String layoutProperty = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_LAYOUT)); - if (layoutProperty.equals(TiC.LAYOUT_HORIZONTAL)) { - arrangement = LayoutArrangement.HORIZONTAL; - } else if (layoutProperty.equals(TiC.LAYOUT_VERTICAL)) { - arrangement = LayoutArrangement.VERTICAL; - } - } - setNativeView(new TiCompositeLayout(proxy.getActivity(), arrangement)); - } - - @Override - public void processProperties(KrollDict d) - { - super.processProperties(d); - } - } - - - // Constructor - public ExampleProxy() - { - super(); - } - - @Override - public TiUIView createView(Activity activity) - { - TiUIView view = new ExampleView(this); - view.getLayoutParams().autoFillsHeight = true; - view.getLayoutParams().autoFillsWidth = true; - return view; - } - - // Handle creation options - @Override - public void handleCreationDict(KrollDict options) - { - super.handleCreationDict(options); - - if (options.containsKey("message")) { - Log.d(LCAT, "example created with message: " + options.get("message")); - } - } - - // Methods - @Kroll.method - public void printMessage(String message) - { - Log.d(LCAT, "printing message: " + message); - } - - - @Kroll.getProperty @Kroll.method - public String getMessage() - { - return "Hello World from my module"; - } - - @Kroll.setProperty @Kroll.method - public void setMessage(String message) - { - Log.d(LCAT, "Tried setting module message to: " + message); - } -} diff --git a/android/src/ti/webdialog/Params.java b/android/src/ti/webdialog/Params.java new file mode 100755 index 0000000..66c8257 --- /dev/null +++ b/android/src/ti/webdialog/Params.java @@ -0,0 +1,9 @@ +package ti.webdialog; + +public class Params { + public static final String LCAT = "TiChromeDialog"; + public static final String SHOW_TITLE = "showTitle"; + public static final String URL = "url"; + public static final String BAR_COLOR = "barColor"; + public static final String FADE_TRANSITION = "fadeTransition"; +} diff --git a/android/src/ti/webdialog/TitaniumWebDialogModule.java b/android/src/ti/webdialog/TitaniumWebDialogModule.java old mode 100644 new mode 100755 index 11e28c8..2766030 --- a/android/src/ti/webdialog/TitaniumWebDialogModule.java +++ b/android/src/ti/webdialog/TitaniumWebDialogModule.java @@ -1,65 +1,118 @@ /** * This file was auto-generated by the Titanium Module SDK helper for Android * Appcelerator Titanium Mobile - * Copyright (c) 2009-2017 by Appcelerator, Inc. All Rights Reserved. + * Copyright (c) 2009-present by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Apache Public License * Please see the LICENSE included with this distribution for details. * */ package ti.webdialog; +import java.util.ArrayList; +import java.util.List; + +import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.annotations.Kroll; - import org.appcelerator.titanium.TiApplication; import org.appcelerator.kroll.common.Log; -import org.appcelerator.kroll.common.TiConfig; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsService; @Kroll.module(name="TitaniumWebDialog", id="ti.webdialog") public class TitaniumWebDialogModule extends KrollModule { + // Standard Debugging variables + private static final String LCAT = "TiWebDialog"; + + private List getCustomTabBrowsers(Context context, List browsersList) { + List customTabBrowsers = new ArrayList(); + + for (ResolveInfo info : browsersList) { + String packageName = info.activityInfo.packageName; + + Intent intent = new Intent(); + intent.setAction(CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION); + intent.setPackage(packageName); + + if (context.getPackageManager().resolveService(intent, 0) != null) { + customTabBrowsers.add(packageName); + } + } + + return customTabBrowsers; + } + + private void openCustomTab(Context context, List customTabBrowsers, KrollDict options) { + String URL = options.getString(Params.URL); + URL = URL.toLowerCase(); + + if (!URL.startsWith("http")) { + URL = "http://" + URL; + } + + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + builder.setShowTitle(Utils.getBool(options, Params.SHOW_TITLE)); + + int barColor = Utils.getColor(options, Params.BAR_COLOR); + if (barColor != -1) { + builder.setToolbarColor(barColor); + } + + // set start and exit animations + if (Utils.getBool(options, Params.FADE_TRANSITION)) { + builder.setStartAnimations(context, android.R.anim.fade_in, android.R.anim.fade_out); + builder.setExitAnimations(context, android.R.anim.fade_in, android.R.anim.fade_out); + } + + CustomTabsIntent tabIntent = builder.build(); + + for(String s:customTabBrowsers) { + tabIntent.intent.setPackage(s); + } + + tabIntent.launchUrl(context, Uri.parse(URL)); + } + + @Kroll.method + public void open(KrollDict options) { + if ((options != null) && options.containsKeyAndNotNull(Params.URL)) { + Context context = TiApplication.getAppCurrentActivity(); + List browsersList = Utils.allBrowsers(context); + + if (!browsersList.isEmpty()) { + List customTabBrowsers = getCustomTabBrowsers(context, browsersList); + + // show supported browsers list or open directly if only 1 supported browser is available + openCustomTab(context, customTabBrowsers, options); + } else { + Log.i(Params.LCAT, "No browsers available in this device."); + } + } + } - // Standard Debugging variables - private static final String LCAT = "TitaniumWebDialogModule"; - private static final boolean DBG = TiConfig.LOGD; - - // You can define constants with @Kroll.constant, for example: - // @Kroll.constant public static final String EXTERNAL_NAME = value; - - public TitaniumWebDialogModule() - { - super(); - } - - @Kroll.onAppCreate - public static void onAppCreate(TiApplication app) - { - Log.d(LCAT, "inside onAppCreate"); - // put module init code that needs to run when the application is created - } - - // Methods - @Kroll.method - public String example() - { - Log.d(LCAT, "example called"); - return "hello world"; - } - - // Properties - @Kroll.getProperty - public String getExampleProp() - { - Log.d(LCAT, "get example property"); - return "hello world"; - } - - - @Kroll.setProperty - public void setExampleProp(String value) { - Log.d(LCAT, "set example property: " + value); - } - + @Kroll.method + public boolean isSupported() { + Context context = TiApplication.getAppCurrentActivity(); + List browsersList = Utils.allBrowsers(context); + + return !browsersList.isEmpty(); + } + + @Kroll.method + public void close(KrollDict options) { + Log.e(Params.LCAT, "The \"close\" method is not implemented, yet!"); + } + + @Kroll.method + public boolean isOpen(KrollDict options) { + Log.e(Params.LCAT, "The \"isOpen\" method is not implemented, yet!"); + return false; + } } - diff --git a/android/src/ti/webdialog/Utils.java b/android/src/ti/webdialog/Utils.java new file mode 100755 index 0000000..315cef9 --- /dev/null +++ b/android/src/ti/webdialog/Utils.java @@ -0,0 +1,63 @@ +package ti.webdialog; + +import java.lang.reflect.Field; +import java.util.List; + +import org.appcelerator.kroll.KrollDict; +import org.appcelerator.titanium.util.TiRHelper; +import org.appcelerator.titanium.util.TiConvert; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.net.Uri; + +public class Utils { + public static int getR(String path) { + try { + return TiRHelper.getResource(path); + + } catch (Exception exc) { + return -1; + } + } + + public static int[] getStyleableIntArray(String packageName, String name) { + try { + Field[] fields2 = Class.forName(packageName + ".R$styleable" ).getFields(); + + for (Field f : fields2) { + if ( f.getName().equals( name ) ) { + int[] ret = (int[])f.get( null ); + return ret; + } + } + } catch ( Throwable t ) {} + + return null; + } + + // return the list of all available & enabled browsers in device + public static List allBrowsers(Context context) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.testingurl.com")); + return context.getPackageManager().queryIntentActivities(intent, 0); + } + + public static String getString(KrollDict options, String key) { + String value = "" + (options.containsKeyAndNotNull(key) ? options.get(key) : ""); + return value.trim(); + } + + public static boolean getBool(KrollDict options, String key) { + return (Boolean) (options.containsKeyAndNotNull(key) ? options.get(key) : false); + } + + public static int getColor(KrollDict options, String key) { + if (options.containsKeyAndNotNull(key)) { + return TiConvert.toColor( (String) options.get(key)); + + } else { + return getR("color.colorPrimary"); + } + } +} diff --git a/android/timodule.xml b/android/timodule.xml old mode 100644 new mode 100755 index ae31597..1d7961d --- a/android/timodule.xml +++ b/android/timodule.xml @@ -2,10 +2,14 @@ + + + 1.7 + 1.7 diff --git a/apidoc/WebDialog.yml b/apidoc/WebDialog.yml index cb8166a..303c8c3 100644 --- a/apidoc/WebDialog.yml +++ b/apidoc/WebDialog.yml @@ -71,17 +71,14 @@ properties: methods: - name: isOpen summary: Indicates if the web dialog is open. - osver: {ios: {min: "9.0"}} returns: type: Boolean platforms: [iphone, ipad] - name: isSupported summary: Indicates if the web dialog is supported. - osver: {ios: {min: "9.0"}} returns: type: Boolean - platforms: [iphone, ipad] - name: open summary: Opens the web dialog with the options provided. @@ -94,7 +91,6 @@ methods: tintColor: 'red' }); } - osver: {ios: {min: "9.0"}} parameters: - name: params summary: Dictionary used to configure the web dialog. @@ -107,7 +103,6 @@ methods: if (dialog.isOpen()) { dialog.close(); } - osver: {ios: {min: "9.0"}} events: - name: open summary: | diff --git a/fixtures/sample.gif b/fixtures/sample.gif new file mode 100755 index 0000000..646bf14 Binary files /dev/null and b/fixtures/sample.gif differ diff --git a/fixtures/sample.png b/fixtures/sample.png new file mode 100755 index 0000000..c6f30e4 Binary files /dev/null and b/fixtures/sample.png differ diff --git a/ios/Classes/TiWebdialogModule.m b/ios/Classes/TiWebdialogModule.m index adecccf..6b10a63 100644 --- a/ios/Classes/TiWebdialogModule.m +++ b/ios/Classes/TiWebdialogModule.m @@ -156,7 +156,7 @@ - (void)open:(id)args if ([TiUtils isIOS10OrGreater]) { [safari setPreferredBarTintColor:[[TiUtils colorValue:@"barColor" properties:args] _color]]; } else { - NSLog(@"[ERROR] Ti.SafariDialog: The barColor property is only available in iOS 10 and later"); + NSLog(@"[ERROR] Ti.WebDialog: The barColor property is only available in iOS 10 and later"); } } @@ -165,7 +165,7 @@ - (void)open:(id)args if (@available(iOS 11.0, *)) { [safari setDismissButtonStyle:[TiUtils intValue:@"dismissButtonStyle" properties:args def:SFSafariViewControllerDismissButtonStyleDone]]; } else { - NSLog(@"[ERROR] Ti.SafariDialog: The dismissButtonStyle property is only available in iOS 11 and later"); + NSLog(@"[ERROR] Ti.WebDialog: The dismissButtonStyle property is only available in iOS 11 and later"); } } #endif