Merge pull request #1082 from yemel/feature/mobile-clipboard

Feature/mobile clipboard
This commit is contained in:
Matias Alejo Garcia 2014-08-15 16:06:31 -04:00
commit 352185e66c
9 changed files with 291 additions and 1 deletions

View File

@ -19,6 +19,12 @@ angular.module('copayApp.controllers').controller('AddressesController',
$scope.openAddressModal = function(address) {
var ModalInstanceCtrl = function ($scope, $modalInstance, address) {
$scope.address = address;
$scope.isMobile = !!window.cordova;
$scope.mobileCopy = function(address) {
window.cordova.plugins.clipboard.copy(address);
window.plugins.toast.showShortBottom('Copied to clipboard');
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');

View File

@ -20,6 +20,24 @@ module.exports = [
"clobbers": [
"navigator.splashscreen"
]
},
{
"file": "plugins/com.verso.cordova.clipboard/www/clipboard.js",
"id": "com.verso.cordova.clipboard.Clipboard",
"clobbers": [
"cordova.plugins.clipboard"
]
},
{
"file": "plugins/nl.x-services.plugins.toast/www/Toast.js",
"id": "nl.x-services.plugins.toast.Toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/nl.x-services.plugins.toast/test/tests.js",
"id": "nl.x-services.plugins.toast.tests"
}
];
module.exports.metadata =
@ -27,7 +45,9 @@ module.exports.metadata =
{
"de.appplant.cordova.plugin.email-composer": "0.8.2dev",
"com.phonegap.plugins.barcodescanner": "1.0.1",
"org.apache.cordova.splashscreen": "0.3.0"
"org.apache.cordova.splashscreen": "0.3.0",
"com.verso.cordova.clipboard": "0.1.0",
"nl.x-services.plugins.toast": "2.0"
}
// BOTTOM OF METADATA
});

View File

@ -0,0 +1,36 @@
cordova.define("com.verso.cordova.clipboard.Clipboard", function(require, exports, module) { var cordova = require('cordova');
/**
* Clipboard plugin for Cordova
*
* @constructor
*/
function Clipboard () {}
/**
* Sets the clipboard content
*
* @param {String} text The content to copy to the clipboard
* @param {Function} onSuccess The function to call in case of success (takes the copied text as argument)
* @param {Function} onFail The function to call in case of error
*/
Clipboard.prototype.copy = function (text, onSuccess, onFail) {
if (typeof text === "undefined" || text === null) text = "";
cordova.exec(onSuccess, onFail, "Clipboard", "copy", [text]);
};
/**
* Gets the clipboard content
*
* @param {Function} onSuccess The function to call in case of success
* @param {Function} onFail The function to call in case of error
*/
Clipboard.prototype.paste = function (onSuccess, onFail) {
cordova.exec(onSuccess, onFail, "Clipboard", "paste", []);
};
// Register the plugin
var clipboard = new Clipboard();
module.exports = clipboard;
});

View File

@ -0,0 +1,59 @@
cordova.define("nl.x-services.plugins.toast.tests", function(require, exports, module) { exports.defineAutoTests = function() {
var fail = function (done) {
expect(true).toBe(false);
done();
},
succeed = function (done) {
expect(true).toBe(true);
done();
};
describe('Plugin availability', function () {
it("window.plugins.toast should exist", function() {
expect(window.plugins.toast).toBeDefined();
});
});
describe('API functions', function () {
it("should define show", function() {
expect(window.plugins.toast.show).toBeDefined();
});
it("should define showShortTop", function() {
expect(window.plugins.toast.showShortTop).toBeDefined();
});
it("should define showShortCenter", function() {
expect(window.plugins.toast.showShortCenter).toBeDefined();
});
it("should define showShortBottom", function() {
expect(window.plugins.toast.showShortBottom).toBeDefined();
});
it("should define showLongTop", function() {
expect(window.plugins.toast.showLongTop).toBeDefined();
});
it("should define showLongCenter", function() {
expect(window.plugins.toast.showLongCenter).toBeDefined();
});
it("should define showLongBottom", function() {
expect(window.plugins.toast.showLongBottom).toBeDefined();
});
});
describe('Invalid usage', function () {
it("should fail due to an invalid position", function(done) {
window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
});
it("should fail due to an invalid duration", function(done) {
window.plugins.toast.show('hi', 'medium', 'top', fail.bind(null, done), succeed.bind(null, done));
});
});
};
});

View File

@ -0,0 +1,42 @@
cordova.define("nl.x-services.plugins.toast.Toast", function(require, exports, module) { function Toast() {
}
Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "Toast", "show", [message, duration, position]);
};
Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
this.show(message, "short", "top", successCallback, errorCallback);
};
Toast.prototype.showShortCenter = function (message, successCallback, errorCallback) {
this.show(message, "short", "center", successCallback, errorCallback);
};
Toast.prototype.showShortBottom = function (message, successCallback, errorCallback) {
this.show(message, "short", "bottom", successCallback, errorCallback);
};
Toast.prototype.showLongTop = function (message, successCallback, errorCallback) {
this.show(message, "long", "top", successCallback, errorCallback);
};
Toast.prototype.showLongCenter = function (message, successCallback, errorCallback) {
this.show(message, "long", "center", successCallback, errorCallback);
};
Toast.prototype.showLongBottom = function (message, successCallback, errorCallback) {
this.show(message, "long", "bottom", successCallback, errorCallback);
};
Toast.install = function () {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.toast = new Toast();
return window.plugins.toast;
};
cordova.addConstructor(Toast.install);
});

View File

@ -28,4 +28,10 @@
<feature name="SplashScreen">
<param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen" />
</feature>
<feature name="Clipboard">
<param name="android-package" value="com.verso.cordova.clipboard.Clipboard" />
</feature>
<feature name="Toast">
<param name="android-package" value="nl.xservices.plugins.Toast" />
</feature>
</widget>

View File

@ -0,0 +1,62 @@
package com.verso.cordova.clipboard;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
public class Clipboard extends CordovaPlugin {
private static final String actionCopy = "copy";
private static final String actionPaste = "paste";
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
ClipboardManager clipboard = (ClipboardManager) cordova.getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
if (action.equals(actionCopy)) {
try {
String text = args.getString(0);
ClipData clip = ClipData.newPlainText("Text", text);
clipboard.setPrimaryClip(clip);
callbackContext.success(text);
return true;
} catch (JSONException e) {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
} catch (Exception e) {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, e.toString()));
}
} else if (action.equals(actionPaste)) {
if (!clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.NO_RESULT));
}
try {
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
String text = item.getText().toString();
if (text == null) text = "";
callbackContext.success(text);
return true;
} catch (Exception e) {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, e.toString()));
}
}
return false;
}
}

View File

@ -0,0 +1,56 @@
package nl.xservices.plugins;
import android.view.Gravity;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
public class Toast extends CordovaPlugin {
private static final String ACTION_SHOW_EVENT = "show";
@Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if (ACTION_SHOW_EVENT.equals(action)) {
final String message = args.getString(0);
final String duration = args.getString(1);
final String position = args.getString(2);
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
android.widget.Toast toast = android.widget.Toast.makeText(webView.getContext(), message, 0);
if ("top".equals(position)) {
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 20);
} else if ("bottom".equals(position)) {
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 20);
} else if ("center".equals(position)) {
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
} else {
callbackContext.error("invalid position. valid options are 'top', 'center' and 'bottom'");
return;
}
if ("short".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_SHORT);
} else if ("long".equals(duration)) {
toast.setDuration(android.widget.Toast.LENGTH_LONG);
} else {
callbackContext.error("invalid duration. valid options are 'short' and 'long'");
return;
}
toast.show();
callbackContext.success();
}
});
return true;
} else {
callbackContext.error("toast." + action + " is not a supported function. Did you mean '" + ACTION_SHOW_EVENT + "'?");
return false;
}
}
}

View File

@ -11,6 +11,9 @@
</p>
<button class="m15t button secondary" open-external address="{{address.address}}">
<i class="fi-link">&nbsp;</i> Open in external application
</button><br><br>
<button class="m15t button secondary" ng-show="isMobile" ng-click="mobileCopy(address.address)">
<i class="fi-link">&nbsp;</i> Copy to clipboard
</button>
</div>
</div>