├── index.html
├── src
├── ios
│ ├── CDVSpinnerDialog.h
│ └── CDVSpinnerDialog.m
├── android
│ ├── CallbackProgressDialog.java
│ └── SpinnerDialog.java
└── wp
│ └── SpinnerDialog.cs
├── LICENSE
├── www
└── spinner.js
├── package.json
├── plugin.xml
└── README.md
/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/ios/CDVSpinnerDialog.h:
--------------------------------------------------------------------------------
1 | //
2 | // CDVSpinnerDialog.h
3 | //
4 | // Created by Domonkos Pál on 2014.01.27..
5 | //
6 | //
7 |
8 | #import
9 |
10 | @interface CDVSpinnerDialog : CDVPlugin
11 |
12 | - (void)show:(CDVInvokedUrlCommand*)command;
13 | - (void)hide:(CDVInvokedUrlCommand*)command;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Domonkos Pal
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
--------------------------------------------------------------------------------
/www/spinner.js:
--------------------------------------------------------------------------------
1 | var exec = require('cordova/exec');
2 |
3 | module.exports = {
4 |
5 | show: function (title, message, cancelCallback, iosOptions) {
6 | if (cancelCallback == true && typeof cancelCallback !== "function") {
7 | cancelCallback = function () { };
8 | }
9 | var isPlatformIos = (navigator.userAgent.match(/iPad/i)) == "iPad" || (navigator.userAgent.match(/iPhone/i)) == "iPhone" ? true : false;
10 | var params = [title, message, !!cancelCallback];
11 | if (isPlatformIos) {
12 | if (typeof iosOptions != "object") {
13 | iosOptions = { overlayOpacity: 0.35, textColorRed: 1, textColorGreen: 1, textColorBlue: 1 }
14 | }
15 | params = params.concat([(iosOptions.overlayOpacity || 0.35), (iosOptions.textColorRed || 1), (iosOptions.textColorGreen || 1), (iosOptions.textColorBlue || 1)])
16 | }
17 | cordova.exec(cancelCallback, null, 'SpinnerDialog', 'show', params);
18 |
19 | },
20 | hide: function (success, fail) {
21 | cordova.exec(success, fail, 'SpinnerDialog', 'hide', ["", ""]);
22 | }
23 |
24 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-spinner-dialog",
3 | "version": "1.3.1",
4 | "description": "PhoneGap / Cordova waiting dialog (progress indicator) plugin with spinner for Android, iOS and Windows Phone 8. Maintained from original Paldom/SpinnerDialog repository.",
5 | "cordova": {
6 | "id": "cordova-plugin-spinner-dialog",
7 | "platforms": [
8 | "android",
9 | "ios",
10 | "wp8"
11 | ]
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/Paldom/SpinnerDialog.git"
16 | },
17 | "keywords": [
18 | "phonegap",
19 | "android",
20 | "ios",
21 | "wp8",
22 | "windows",
23 | "phone",
24 | "spinner",
25 | "dialog",
26 | "progress",
27 | "indicator",
28 | "ecosystem:cordova",
29 | "cordova-android",
30 | "cordova-ios",
31 | "cordova-wp8"
32 | ],
33 | "author": "Domonkos Pal (https://github.com/Paldom)",
34 | "license": "MIT",
35 | "bugs": {
36 | "url": "https://github.com/Paldom/SpinnerDialog/issues"
37 | },
38 | "homepage": "https://github.com/Paldom/SpinnerDialog#readme"
39 | }
40 |
--------------------------------------------------------------------------------
/src/android/CallbackProgressDialog.java:
--------------------------------------------------------------------------------
1 | package hu.dpal.phonegap.plugins;
2 |
3 | import org.apache.cordova.CallbackContext;
4 | import org.apache.cordova.PluginResult;
5 |
6 | import android.app.ProgressDialog;
7 | import android.content.Context;
8 | import android.view.MotionEvent;
9 |
10 | import android.graphics.Color;
11 | import android.graphics.drawable.ColorDrawable;
12 |
13 | public class CallbackProgressDialog extends ProgressDialog {
14 |
15 | public static CallbackContext callbackContext;
16 |
17 | public CallbackProgressDialog(Context context) {
18 | super(context);
19 | }
20 |
21 | public static CallbackProgressDialog show(Context context,
22 | CharSequence title, CharSequence message, boolean indeterminate,
23 | boolean cancelable, OnCancelListener cancelListener,
24 | CallbackContext callbackContext) {
25 | CallbackProgressDialog.callbackContext = callbackContext;
26 | CallbackProgressDialog dialog = new CallbackProgressDialog(context);
27 | dialog.setTitle(title);
28 | dialog.setMessage(message);
29 | dialog.setIndeterminate(indeterminate);
30 | dialog.setCancelable(cancelable);
31 | dialog.setOnCancelListener(cancelListener);
32 | dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
33 | dialog.show();
34 | return dialog;
35 | }
36 |
37 | private void sendCallback() {
38 | PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
39 | pluginResult.setKeepCallback(true);
40 | callbackContext.sendPluginResult(pluginResult);
41 | }
42 |
43 | @Override
44 | public void onBackPressed() {
45 | sendCallback();
46 | }
47 |
48 | @Override
49 | public boolean onTouchEvent(MotionEvent event) {
50 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
51 | sendCallback();
52 | return true;
53 | }
54 | return false;
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | SpinnerDialog
8 |
9 |
10 | PhoneGap waiting dialog (progress indicator) plugin with spinner for Android, iOS and Windows Phone 8.
11 |
12 | MIT
13 | phonegap,android,ios,wp8,windows,phone,spinner,dialog,progress,indicator
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/android/SpinnerDialog.java:
--------------------------------------------------------------------------------
1 | package hu.dpal.phonegap.plugins;
2 |
3 | import java.util.Stack;
4 |
5 | import org.apache.cordova.CallbackContext;
6 | import org.apache.cordova.CordovaInterface;
7 | import org.apache.cordova.CordovaPlugin;
8 | import org.json.JSONArray;
9 | import org.json.JSONException;
10 |
11 | import android.app.ProgressDialog;
12 | import android.content.DialogInterface;
13 | import android.widget.ProgressBar;
14 |
15 | public class SpinnerDialog extends CordovaPlugin {
16 |
17 | public Stack spinnerDialogStack = new Stack();
18 |
19 | public SpinnerDialog() {
20 | }
21 |
22 | public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
23 | if (action.equals("show")) {
24 |
25 | final String title = "null".equals(args.getString(0)) ? null : args.getString(0);
26 | final String message = "null".equals(args.getString(1)) ? null : args.getString(1);
27 | final boolean isFixed = args.getBoolean(2);
28 |
29 | final CordovaInterface cordova = this.cordova;
30 | Runnable runnable = new Runnable() {
31 | public void run() {
32 |
33 | DialogInterface.OnCancelListener onCancelListener = new DialogInterface.OnCancelListener() {
34 | public void onCancel(DialogInterface dialog) {
35 | if (!isFixed) {
36 | while (!SpinnerDialog.this.spinnerDialogStack.empty()) {
37 | SpinnerDialog.this.spinnerDialogStack.pop().dismiss();
38 | callbackContext.success();
39 | }
40 | }
41 | }
42 | };
43 |
44 | ProgressDialog dialog;
45 | if (isFixed) {
46 | dialog = CallbackProgressDialog.show(cordova.getActivity(), title, message, true, false, null, callbackContext);
47 | } else {
48 | dialog = ProgressDialog.show(cordova.getActivity(), title, message, true, true, onCancelListener);
49 | }
50 |
51 | if (title == null && message == null) {
52 | dialog.setContentView(new ProgressBar(cordova.getActivity()));
53 | }
54 |
55 | SpinnerDialog.this.spinnerDialogStack.push(dialog);
56 |
57 | }
58 | };
59 | this.cordova.getActivity().runOnUiThread(runnable);
60 |
61 | } else if (action.equals("hide")) {
62 |
63 | Runnable runnable = new Runnable() {
64 | public void run() {
65 |
66 | if (!SpinnerDialog.this.spinnerDialogStack.empty()) {
67 | SpinnerDialog.this.spinnerDialogStack.pop().dismiss();
68 | }
69 |
70 | }
71 | };
72 | this.cordova.getActivity().runOnUiThread(runnable);
73 |
74 | }
75 | return true;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/wp/SpinnerDialog.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Phone.Controls;
2 | using Microsoft.Phone.Shell;
3 | using System.Windows;
4 | using System.Windows.Input;
5 |
6 | namespace WPCordovaClassLib.Cordova.Commands
7 | {
8 | public class SpinnerDialog : BaseCommand
9 | {
10 |
11 | private static ProgressIndicator progressIndicator;
12 | private static PhoneApplicationPage page;
13 | private static bool sysTrayVisibilityDetermined;
14 | private static bool sysTrayVisible;
15 |
16 | public void show(string options)
17 | {
18 |
19 | string[] args = JSON.JsonHelper.Deserialize(options);
20 | string title = args[0];
21 | string message = args[1];
22 | string isFixed = args[2];
23 |
24 | if (message == null || "null".Equals(message))
25 | {
26 | if (title != null && !"null".Equals(title))
27 | {
28 | message = title;
29 | }
30 | }
31 |
32 | Deployment.Current.Dispatcher.BeginInvoke(() =>
33 | {
34 |
35 | if (progressIndicator == null)
36 | {
37 | progressIndicator = new ProgressIndicator() { IsIndeterminate = true };
38 | }
39 | progressIndicator.Text = message;
40 | progressIndicator.IsVisible = true;
41 |
42 | if (page == null)
43 | {
44 | page = (Application.Current.RootVisual as PhoneApplicationFrame).Content as PhoneApplicationPage;
45 | }
46 |
47 | if (isFixed == null || "false".Equals(isFixed))
48 | {
49 | page.MouseLeftButtonUp += ButtonEventHandler;
50 | }
51 |
52 | SystemTray.SetProgressIndicator(page, progressIndicator);
53 |
54 | // determine systray visibility on first visit
55 | if (!sysTrayVisibilityDetermined)
56 | {
57 | sysTrayVisible = SystemTray.IsVisible;
58 | sysTrayVisibilityDetermined = true;
59 | }
60 |
61 | // show the tray if it's not visible, otherwise the spinner won't show up
62 | if (!sysTrayVisible)
63 | {
64 | SystemTray.IsVisible = true;
65 | }
66 |
67 | });
68 |
69 | }
70 |
71 | private void ButtonEventHandler(object sender, MouseButtonEventArgs e)
72 | {
73 | hide(null);
74 | DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
75 | }
76 |
77 | public void hide(string options)
78 | {
79 |
80 | if (progressIndicator != null && page != null)
81 | {
82 | Deployment.Current.Dispatcher.BeginInvoke(() =>
83 | {
84 | if (!sysTrayVisible)
85 | {
86 | SystemTray.IsVisible = false;
87 | }
88 |
89 | SystemTray.SetProgressIndicator(page, null);
90 | page.MouseLeftButtonUp -= ButtonEventHandler;
91 | });
92 | }
93 |
94 | }
95 |
96 | }
97 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SpinnerDialog
2 | =============
3 |
4 | PhoneGap waiting dialog / progress dialog plugin with spinner for Android, iOS and Windows Phone 8.
5 |
6 | ## Installation
7 |
8 | Latest stable release: ```phonegap local plugin add cordova-plugin-spinner-dialog```
9 | or ```cordova plugin add cordova-plugin-spinner-dialog```
10 |
11 | Current state from git: ```phonegap local plugin add https://github.com/Paldom/SpinnerDialog.git```
12 | or ```cordova plugin add https://github.com/Paldom/SpinnerDialog.git```
13 |
14 | ## Installation - PhoneGap Build
15 |
16 | Add following to config.xml: ``````
17 |
18 | For older versions, use the following: ``````
19 | or ``````
20 |
21 | ## Methods
22 |
23 | - `window.plugins.spinnerDialog.show`
24 | - `window.plugins.spinnerDialog.hide`
25 |
26 | ## window.plugins.spinnerDialog.show
27 |
28 |
29 | window.plugins.spinnerDialog.show([title], [message], [cancelCallback])
30 |
31 | - __title__: Spinner title (Android only). Optional. _(String)_
32 | - __message__: Spinner message. Optional. _(String)_
33 | - __cancelCallback__: Callback to invoke when spinner cancel event fired (tap or Android hardware back button event). If set, spinner dialog will be fixed, you should explicitly call `window.plugins.spinnerDialog.hide`. Due to legacy reasons you can provide boolean value (true/false) to set spinner not cancelable. Optional, defaults to `false`. _(Function/Boolean)_
34 |
35 |
36 | ## Supported Platforms
37 |
38 | - Android
39 | - iOS
40 | - Windows Phone 8
41 |
42 | ## Usage
43 |
44 | // Show spinner dialog
45 | window.plugins.spinnerDialog.show();
46 |
47 | // Show spinner dialog with message
48 | // Note: spinner dialog is cancelable by default
49 | window.plugins.spinnerDialog.show(null, "message");
50 |
51 | // Set spinner dialog fixed
52 | window.plugins.spinnerDialog.show(null, null, true);
53 |
54 | // Set spinner dialog fixed with callback
55 | // Note: callback fires on tap events and Android hardware back button click event
56 | window.plugins.spinnerDialog.show(null, null, function () {console.log("callback");});
57 |
58 | // Show spinner dialog with title and message (Android only)
59 | window.plugins.spinnerDialog.show("title","message");
60 |
61 | // Set spinner dialog fixed (cannot be canceled with screen touch or Android hardware button)
62 | window.plugins.spinnerDialog.show("title","message", true);
63 |
64 | // Overlay opacity and text color options (IOS only)
65 | window.plugins.spinnerDialog.show(null,"Message",true, {overlayOpacity: 0.35, textColorRed: 1, textColorGreen: 1, textColorBlue: 1});
66 |
67 | // Change only overlay opacity (IOS only)
68 | window.plugins.spinnerDialog.show(null,"Message",true,{overlayOpacity:0.70});
69 |
70 | // Change only text color (IOS only)
71 | window.plugins.spinnerDialog.show(null,"message",true, { textColorRed: 0.1, textColorGreen: 0.1, textColorBlue: 1});
72 |
73 |
74 | // Hide spinner dialog
75 | window.plugins.spinnerDialog.hide();
76 |
77 |
78 |
79 | Note: on Android platform, multiple show calls builds up a stack (LIFO) which means hide will dismiss the last spinner added with show call.
80 |
81 | ## License
82 |
83 | MIT License
--------------------------------------------------------------------------------
/src/ios/CDVSpinnerDialog.m:
--------------------------------------------------------------------------------
1 | //
2 | // CDVSpinnerDialog.m
3 | //
4 | // Created by Domonkos Pál on 2014.01.27..
5 | //
6 | //
7 |
8 | #import "CDVSpinnerDialog.h"
9 |
10 | @interface CDVSpinnerDialog () {
11 | UIActivityIndicatorView *indicator;
12 | NSString *callbackId;
13 | NSString *title;
14 | NSString *message;
15 | NSNumber *isFixed;
16 | NSString *alpha;
17 | NSString *red;
18 | NSString *green;
19 | NSString *blue;
20 | }
21 |
22 | @property (nonatomic, retain) UIActivityIndicatorView *indicator;
23 | @property (nonatomic, retain) UIView *overlay;
24 | @property (nonatomic, retain) UILabel *messageView;
25 |
26 |
27 | @end
28 |
29 | @implementation CDVSpinnerDialog
30 |
31 | @synthesize indicator = _indicator;
32 | @synthesize overlay = _overlay;
33 | @synthesize messageView = _messageView;
34 |
35 | -(CGRect)rectForView {
36 | if ((NSFoundationVersionNumber <= 1047.25 /* 7.1 */) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
37 | return CGRectMake( 0.0f, 0.0f, [[UIScreen mainScreen]bounds].size.height, [UIScreen mainScreen].bounds.size.width);
38 | }
39 | return CGRectMake( 0.0f, 0.0f, [[UIScreen mainScreen]bounds].size.width, [UIScreen mainScreen].bounds.size.height);
40 | }
41 |
42 | - (void)handleTapGesture:(UITapGestureRecognizer *)gesture
43 | {
44 | CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
45 | [result setKeepCallbackAsBool:true];
46 | if (!isFixed.boolValue) {
47 | [result setKeepCallbackAsBool:false];
48 | [self hide];
49 | }
50 | [self.commandDelegate sendPluginResult:result callbackId:callbackId];
51 | }
52 |
53 | - (UIView *)overlay {
54 | if (!_overlay) {
55 | _overlay = [[UIView alloc] initWithFrame:self.rectForView];
56 | _overlay.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:[alpha floatValue]];
57 | _indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
58 | _indicator.center = _overlay.center;
59 | [_indicator startAnimating];
60 | [_overlay addSubview:_indicator];
61 |
62 | _messageView = [[UILabel alloc] initWithFrame: self.rectForView];
63 | [_messageView setText: message == nil ? title : message];
64 | [_messageView setTextColor: [UIColor colorWithRed:[red floatValue] green:[green floatValue] blue:[blue floatValue] alpha:0.85]];
65 | [_messageView setBackgroundColor: [UIColor colorWithRed:0 green:0 blue:0 alpha:0]];
66 | [_messageView setTextAlignment: NSTextAlignmentCenter];
67 | _messageView.center = (CGPoint){_overlay.center.x, _overlay.center.y + 40};
68 | [_overlay addSubview:_messageView];
69 |
70 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
71 | [_overlay addGestureRecognizer: tapRecognizer];
72 | }
73 | return _overlay;
74 | }
75 |
76 |
77 | - (void) show:(CDVInvokedUrlCommand*)command {
78 |
79 | callbackId = command.callbackId;
80 |
81 | title = [command argumentAtIndex:0];
82 | message = [command argumentAtIndex:1];
83 | isFixed = [command argumentAtIndex:2];
84 | alpha = [command argumentAtIndex:3];
85 | red = [command argumentAtIndex:4];
86 | green = [command argumentAtIndex:5];
87 | blue = [command argumentAtIndex:6];
88 |
89 | UIViewController *rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
90 |
91 | [rootViewController.view addSubview:self.overlay];
92 |
93 | }
94 |
95 | - (void) hide:(CDVInvokedUrlCommand*)command {
96 | [self hide];
97 | }
98 |
99 | - (void) hide {
100 | if (_overlay) {
101 | [self.indicator stopAnimating];
102 | [self.indicator removeFromSuperview];
103 | [self.messageView removeFromSuperview];
104 | [self.overlay removeFromSuperview];
105 | _indicator = nil;
106 | _messageView = nil;
107 | _overlay = nil;
108 | }
109 | }
110 |
111 | #pragma mark - PRIVATE METHODS
112 |
113 |
114 | @end
115 |
116 |
117 |
--------------------------------------------------------------------------------