Skip to content
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ xcuserdata/
build/
/android/dist
ios/titanium-web-dialog.xcodeproj/project.xcworkspace/xcuserdata
android/libs
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Titanium Web Dialog

Use the SFSafariViewController (iOS) and Chrome Pages (Android) together.
Use the native `SFSafariViewController` (iOS) and `Chrome Pages` (Android) within Axway Titanium.

<img src="./fixtures/DQM57Q7X4AAF8yR.jpg" width="890" alt="Titanium Web Dialog" />

Expand All @@ -9,13 +9,10 @@ Use the SFSafariViewController (iOS) and Chrome Pages (Android) together.
- Titanium SDK 7.0.0 or later (or use the [SDK-6-compatibility](https://github.com/appcelerator-modules/titanium-web-dialog/tree/SDK-6-compatibility) Titanium SDK 6.x)
- iOS 9+ and Android 4.1+

## Roadmap
## iOS Note

- [x] Find suitable module name
- [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))
- [x] Adjust existing docs from Ti.SafariDialog to support Android as well
- [x] Write cross-platform example and tests
- [x] Release module
The iOS part of this module is based on Ti.SafariDialog, which has been deprecated for a cross-platform solution. All API's of Ti.SafariDialog
still work here and have been extended by more features over time.

## Android Legacy Support

Expand All @@ -33,7 +30,7 @@ If you want to use this module in Titanium SDK 6.x, please use the [this version
* `barColor` (String)
* `animated` (Boolean, iOS only)
* `entersReaderIfAvailable` (Boolean, iOS only)
* `barCollapsingEnabled` (Boolean, iOS only)
* `barCollapsingEnabled` (Boolean)
* `title` (String, iOS only)
* `tintColor` (String, iOS only)
   * `dismissButtonStyle` (`DISMISS_BUTTON_STYLE_*`, iOS only)
Expand All @@ -52,6 +49,13 @@ If you want to use this module in Titanium SDK 6.x, please use the [this version
* `DISMISS_BUTTON_STYLE_CLOSE` (iOS only)
* `DISMISS_BUTTON_STYLE_CANCEL` (iOS only)

#### Events

* `open` -> `success` (Boolean), `url` (String)
* `close` -> `success` (Boolean), `url` (String) - iOS only
* `load` -> `success` (Boolean), `url` (String) - iOS only
* `redirect` -> `url` (String) - iOS only

### `AuthenticationSession` (iOS only)

## License
Expand Down
26 changes: 26 additions & 0 deletions android/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
Language: Java
AccessModifierOffset: -4
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
# class, constructor, method should be next line
BreakBeforeBraces: Linux
# Keep '=' at end of line when wrapping, but move things like '&&', '||' to beginning of newline
BreakBeforeBinaryOperators: NonAssignment
# FIXME: break for brace after synchronized block, anonymous class declarations
BreakAfterJavaFieldAnnotations: true
ColumnLimit: 120
IndentCaseLabels: true
IndentWidth: 4
MaxEmptyLinesToKeep: 1
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpacesInParentheses: false
TabWidth: 4
UseTab: ForContinuationAndIndentation
SpaceAfterCStyleCast: true
# Spaces inside {} for array literals, i.e. "new Object[] { args }"
Cpp11BracedListStyle: false
ReflowComments: false
Binary file removed android/libs/arm64-v8a/libti.webdialog.so
Binary file not shown.
Binary file removed android/libs/armeabi-v7a/libti.webdialog.so
Binary file not shown.
Binary file removed android/libs/x86/libti.webdialog.so
Binary file not shown.
2 changes: 1 addition & 1 deletion android/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
version: 1.0.0
version: 1.1.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86
description: titanium-web-dialog
Expand Down
4 changes: 3 additions & 1 deletion android/src/ti/webdialog/Params.java
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package ti.webdialog;

public class Params {
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";
public static final String ENABLE_SHARING = "enableSharing";
public static final String CLOSE_ICON = "closeIcon";
public static final String BAR_COLLAPSING_ENABLED = "barCollapsingEnabled";
}
270 changes: 144 additions & 126 deletions android/src/ti/webdialog/TitaniumWebDialogModule.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -34,132 +34,150 @@
import android.support.customtabs.CustomTabsService;
import android.util.DisplayMetrics;


@Kroll.module(name="TitaniumWebDialog", id="ti.webdialog")
@Kroll.module(name = "TitaniumWebDialog", id = "ti.webdialog")
public class TitaniumWebDialogModule extends KrollModule
{
// Standard Debugging variables
private static final String LCAT = "TiWebDialog";

private List<String> getCustomTabBrowsers(Context context, List<ResolveInfo> browsersList) {
List<String> customTabBrowsers = new ArrayList<String>();

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<String> customTabBrowsers, KrollDict options) {
String URL = options.getString(Params.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);
}

//enable Share link option
if (Utils.getBool(options, Params.ENABLE_SHARING)) {
builder.addDefaultShareMenuItem();
}

String closeIcon = Utils.getString(options, Params.CLOSE_ICON);
if (!closeIcon.isEmpty()) {
builder.setCloseButtonIcon( getIcon(closeIcon) );
}

CustomTabsIntent tabIntent = builder.build();

for(String s:customTabBrowsers) {
tabIntent.intent.setPackage(s);
}

tabIntent.launchUrl(context, Uri.parse(URL));
}


private Bitmap getIcon(String path) {
Bitmap resultBitmap = null;

if (path != null && !path.trim().equalsIgnoreCase("")) {
String resourceIcon = path.replaceAll(".png", "");
resourceIcon = "drawable." + resourceIcon;

int resource = Utils.getR(resourceIcon);

if (resource == 0) {
TiUrl imageUrl = new TiUrl(path);
TiFileHelper tfh = new TiFileHelper(TiApplication.getInstance());
Drawable d = tfh.loadDrawable(imageUrl.resolve(), false);

resultBitmap = ((BitmapDrawable) d).getBitmap();

} else {
resultBitmap = BitmapFactory.decodeResource(TiApplication.getAppRootOrCurrentActivity().getResources(), resource);
}
}

// important step to show close icon
// rescale bitmap to 24dp(Height) x 48dp(Width) as mentioned here, otherwise it won't work
// https://developer.chrome.com/multidevice/android/customtabs#choosing-an icon for the action button
if (resultBitmap != null) {
resultBitmap = Utils.rescaleBitmap(TiApplication.getAppRootOrCurrentActivity(), resultBitmap, 24, 48);
}

return resultBitmap;
}


@Kroll.method
public void open(KrollDict options) {
if ((options != null) && options.containsKeyAndNotNull(Params.URL)) {
Context context = TiApplication.getAppCurrentActivity();
List<ResolveInfo> browsersList = Utils.allBrowsers(context);

if (!browsersList.isEmpty()) {
List<String> 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.");
}
}
}

@Kroll.method
public boolean isSupported() {
Context context = TiApplication.getAppCurrentActivity();
List<ResolveInfo> 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;
}
// Standard Debugging variables
private static final String LCAT = "TiWebDialog";

private List<String> getCustomTabBrowsers(Context context, List<ResolveInfo> browsersList)
{
List<String> customTabBrowsers = new ArrayList<String>();

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<String> customTabBrowsers, KrollDict options)
{
String URL = options.getString(Params.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);
}

// hide navigation bar on scroll
if (Utils.getBool(options, Params.BAR_COLLAPSING_ENABLED)) {
builder.enableUrlBarHiding();
}

//enable Share link option
if (Utils.getBool(options, Params.ENABLE_SHARING)) {
builder.addDefaultShareMenuItem();
}

String closeIcon = Utils.getString(options, Params.CLOSE_ICON);
if (!closeIcon.isEmpty()) {
builder.setCloseButtonIcon(getIcon(closeIcon));
}

CustomTabsIntent tabIntent = builder.build();

for (String s : customTabBrowsers) {
tabIntent.intent.setPackage(s);
}

tabIntent.launchUrl(context, Uri.parse(URL));
}

private Bitmap getIcon(String path)
{
Bitmap resultBitmap = null;

if (path != null && !path.trim().equalsIgnoreCase("")) {
String resourceIcon = path.replaceAll(".png", "");
resourceIcon = "drawable." + resourceIcon;

int resource = Utils.getR(resourceIcon);

if (resource == 0) {
TiUrl imageUrl = new TiUrl(path);
TiFileHelper tfh = new TiFileHelper(TiApplication.getInstance());
Drawable d = tfh.loadDrawable(imageUrl.resolve(), false);

resultBitmap = ((BitmapDrawable) d).getBitmap();

} else {
resultBitmap =
BitmapFactory.decodeResource(TiApplication.getAppRootOrCurrentActivity().getResources(), resource);
}
}

// important step to show close icon
// rescale bitmap to 24dp(Height) x 48dp(Width) as mentioned here, otherwise it won't work
// https://developer.chrome.com/multidevice/android/customtabs#choosing-an icon for the action button
if (resultBitmap != null) {
resultBitmap = Utils.rescaleBitmap(TiApplication.getAppRootOrCurrentActivity(), resultBitmap, 24, 48);
}

return resultBitmap;
}

@Kroll.method
public void open(KrollDict options)
{
if ((options != null) && options.containsKeyAndNotNull(Params.URL)) {
Context context = TiApplication.getAppCurrentActivity();
List<ResolveInfo> browsersList = Utils.allBrowsers(context);

KrollDict event = new KrollDict();

event.put("success", !browsersList.isEmpty());
event.put("url", options.getString(Params.URL));

if (!browsersList.isEmpty()) {
List<String> 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.");
}

fireEvent("open", event);
}
}

@Kroll.method
public boolean isSupported()
{
Context context = TiApplication.getAppCurrentActivity();
List<ResolveInfo> browsersList = Utils.allBrowsers(context);

return !browsersList.isEmpty();
}

@Kroll.method
public void close(KrollDict options)
{
Log.e(Params.LCAT, "The \"close\" method is not implemented on Android, yet!");
}

@Kroll.method
public boolean isOpen(KrollDict options)
{
Log.e(Params.LCAT, "The \"isOpen\" method is not implemented on Android, yet!");
return false;
}
}
Loading