diff --git a/src/js/controllers/feedback/rateAppStore.js b/src/js/controllers/feedback/rateAppStore.js
new file mode 100644
index 000000000..b659fa516
--- /dev/null
+++ b/src/js/controllers/feedback/rateAppStore.js
@@ -0,0 +1,34 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('rateAppStoreController', function($scope, $state, $stateParams, externalLinkService, configService, gettextCatalog, platformInfo) {
+ $scope.score = parseInt($stateParams.score);
+ var isAndroid = platformInfo.isAndroid;
+ var isIOS = platformInfo.isIOS;
+ var isWP = platformInfo.isWP;
+ var config = configService.getSync();
+
+ $scope.skip = function() {
+ $state.go('feedback.thanks', {
+ score: $scope.score,
+ skipped: true
+ });
+ };
+
+ $scope.sendFeedback = function() {
+ $state.go('feedback.sendFeedback', {
+ score: $scope.score
+ });
+ };
+
+ $scope.goAppStore = function() {
+ var url;
+ if (isAndroid) url = config.rateApp.android;
+ if (isIOS) url = config.rateApp.ios;
+ // if (isWP) url = config.rateApp.ios; TODO
+ var title = gettextCatalog.getString('Rate the app');
+ var message = gettextCatalog.getString('You must go to the official website of the app to rate it');
+ var okText = gettextCatalog.getString('Go');
+ var cancelText = gettextCatalog.getString('Cancel');
+ externalLinkService.open(url, true, title, message, okText, cancelText);
+ };
+});
diff --git a/src/js/controllers/feedback/rateCard.js b/src/js/controllers/feedback/rateCard.js
new file mode 100644
index 000000000..8eaa98cfa
--- /dev/null
+++ b/src/js/controllers/feedback/rateCard.js
@@ -0,0 +1,61 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('rateCardController', function($scope, $state, $timeout, gettextCatalog, platformInfo, storageService) {
+
+ $scope.isCordova = platformInfo.isCordova;
+
+ $scope.goFeedbackFlow = function() {
+ if ($scope.isModal) {
+ $scope.rateModal.hide();
+ $scope.rateModal.remove();
+ }
+ if ($scope.isCordova && $scope.score == 5) {
+ $state.go('feedback.rateAppStore', {
+ score: $scope.score
+ });
+ } else {
+ $state.go('feedback.sendFeedback', {
+ score: $scope.score
+ });
+ }
+ };
+
+ $scope.setScore = function(score) {
+ $scope.score = score;
+ switch ($scope.score) {
+ case 1:
+ $scope.button_title = gettextCatalog.getString("I think this app is terrible");
+ break;
+ case 2:
+ $scope.button_title = gettextCatalog.getString("I don't like it");
+ break;
+ case 3:
+ $scope.button_title = gettextCatalog.getString("Meh - it's alright");
+ break;
+ case 4:
+ $scope.button_title = gettextCatalog.getString("I like the app");
+ break;
+ case 5:
+ $scope.button_title = gettextCatalog.getString("This app is fantastic");
+ break;
+ }
+ $timeout(function() {
+ $scope.$apply();
+ });
+ };
+
+ $scope.hideCard = function() {
+ if ($scope.isModal) {
+ $scope.rateModal.hide();
+ $scope.rateModal.remove();
+ } else {
+ storageService.setRateCardFlag('true', function() {
+ $scope.hideRateCard.value = true;
+ });
+ }
+ $timeout(function() {
+ $scope.$apply();
+ })
+ }
+
+});
diff --git a/src/js/controllers/feedback/sendFeedback.js b/src/js/controllers/feedback/sendFeedback.js
new file mode 100644
index 000000000..8899301c3
--- /dev/null
+++ b/src/js/controllers/feedback/sendFeedback.js
@@ -0,0 +1,52 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('sendFeedbackController', function($scope, $state, $log, $stateParams, gettextCatalog, popupService, configService, lodash, feedbackService, ongoingProcess) {
+ $scope.score = parseInt($stateParams.score);
+ switch ($scope.score) {
+ case 1:
+ $scope.reaction = gettextCatalog.getString("Ouch!");
+ $scope.comment = gettextCatalog.getString("There's obviously something we're doing wrong.");
+ break;
+ case 2:
+ $scope.reaction = gettextCatalog.getString("Oh no!");
+ $scope.comment = gettextCatalog.getString("There's obviously something we're doing wrong.");
+ break;
+ case 3:
+ $scope.reaction = gettextCatalog.getString("Thanks!");
+ $scope.comment = gettextCatalog.getString("We're always looking for ways to improve BitPay wallet.");
+ break;
+ case 4:
+ $scope.reaction = gettextCatalog.getString("Thanks!");
+ $scope.comment = gettextCatalog.getString("That's exciting to hear. We'd love to earn that fifth star from you.");
+ break;
+ case 5:
+ $scope.reaction = gettextCatalog.getString("Feedback!");
+ $scope.comment = gettextCatalog.getString("We're always looking for ways to improve BitPay wallet.");
+ break;
+ }
+
+ $scope.sendFeedback = function(feedback, skip) {
+
+ var config = configService.getSync();
+
+ var dataSrc = {
+ "Email": lodash.values(config.emailFor)[0] || ' ',
+ "Feedback": skip ? ' ' : feedback,
+ "Score": $stateParams.score
+ };
+
+ ongoingProcess.set('sendingFeedback', true);
+ feedbackService.send(dataSrc, function(err) {
+ ongoingProcess.set('sendingFeedback', false);
+ if (err) {
+ popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not send feedback'));
+ return;
+ }
+ $state.go('feedback.thanks', {
+ score: $stateParams.score,
+ skipped: skip
+ });
+ });
+ };
+
+});
diff --git a/src/js/controllers/feedback/thanks.js b/src/js/controllers/feedback/thanks.js
new file mode 100644
index 000000000..7aa84334f
--- /dev/null
+++ b/src/js/controllers/feedback/thanks.js
@@ -0,0 +1,76 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('thanksController', function($scope, $stateParams, $timeout, $log, platformInfo, configService, storageService) {
+ $scope.score = parseInt($stateParams.score);
+ $scope.skipped = $stateParams.skipped == 'false' ? false : true;
+ $scope.isCordova = platformInfo.isCordova;
+ var config = configService.getSync();
+
+ $scope.shareFacebook = function() {
+ window.plugins.socialsharing.shareViaFacebook(config.download.url, null, null, null);
+ };
+
+ $scope.shareTwitter = function() {
+ window.plugins.socialsharing.shareVia($scope.shareTwitterVia, config.download.url, null, null, null, null, null);
+ };
+
+ $scope.shareGooglePlus = function() {
+ window.plugins.socialsharing.shareVia($scope.shareGooglePlusVia, config.download.url, null, null, null);
+ };
+
+ $scope.shareEmail = function() {
+ window.plugins.socialsharing.shareViaEmail(config.download.url, null, null, null);
+ };
+
+ $scope.shareWhatsapp = function() {
+ window.plugins.socialsharing.shareViaWhatsApp(config.download.url, null, null, null);
+ };
+
+ $scope.shareMessage = function() {
+ window.plugins.socialsharing.shareViaSMS(config.download.url, null, null, null);
+ };
+
+ $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ storageService.setRateCardFlag('true', function() {});
+ if (!$scope.isCordova) return;
+
+ window.plugins.socialsharing.available(function(isAvailable) {
+ // the boolean is only false on iOS < 6
+ $scope.socialsharing = isAvailable;
+ if (isAvailable) {
+ window.plugins.socialsharing.canShareVia('com.apple.social.facebook', 'msg', null, null, null, function(e) {
+ $scope.facebook = true;
+ }, function(e) {
+ $log.debug('facebook error: ' + e);
+ $scope.facebook = false;
+ });
+ window.plugins.socialsharing.canShareVia('com.twitter.android', 'msg', null, null, null, function(e) {
+ $scope.shareTwitterVia = 'com.twitter.android';
+ $scope.twitter = true;
+ }, function(e) {
+ $log.debug('twitter error: ' + e);
+ $scope.twitter = false;
+ });
+ window.plugins.socialsharing.canShareVia('com.google.android.apps.plus', 'msg', null, null, null, function(e) {
+ $scope.shareGooglePlusVia = 'com.google.android.apps.plus';
+ $scope.googleplus = true;
+ }, function(e) {
+ $log.debug('googlePlus error: ' + e);
+ $scope.googleplus = false;
+ });
+ window.plugins.socialsharing.canShareViaEmail(function(e) {
+ $scope.email = true;
+ }, function(e) {
+ $log.debug('email error: ' + e);
+ $scope.email = false;
+ });
+ window.plugins.socialsharing.canShareVia('whatsapp', 'msg', null, null, null, function(e) {
+ $scope.whatsapp = true;
+ }, function(e) {
+ $log.debug('whatsapp error: ' + e);
+ $scope.whatsapp = false;
+ });
+ }
+ }, 100);
+ });
+});
diff --git a/src/js/controllers/onboarding/welcomeController.js b/src/js/controllers/onboarding/welcomeController.js
index 3a1651f75..3b74544a7 100644
--- a/src/js/controllers/onboarding/welcomeController.js
+++ b/src/js/controllers/onboarding/welcomeController.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $ionicConfig, $log, profileService, startupService) {
+angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $ionicConfig, $log, profileService, startupService, storageService) {
$ionicConfig.views.swipeBackEnabled(false);
@@ -19,7 +19,13 @@ angular.module('copayApp.controllers').controller('welcomeController', function(
$log.debug('Creating profile');
profileService.createProfile(function(err) {
if (err) $log.warn(err);
+ setProfileCreationTime();
});
};
+ function setProfileCreationTime() {
+ var now = moment().unix() * 1000 + 24 * 60 * 60 * 1000;
+ storageService.setProfileCreationTime(now, function() {});
+ };
+
});
diff --git a/src/js/controllers/tab-home.js b/src/js/controllers/tab-home.js
index 08d136573..bf8443081 100644
--- a/src/js/controllers/tab-home.js
+++ b/src/js/controllers/tab-home.js
@@ -13,27 +13,100 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.isCordova = platformInfo.isCordova;
$scope.isAndroid = platformInfo.isAndroid;
$scope.isNW = platformInfo.isNW;
+ $scope.hideRateCard = {};
$scope.$on("$ionicView.afterEnter", function() {
startupService.ready();
});
- if (!$scope.homeTip) {
- storageService.getHomeTipAccepted(function(error, value) {
- $scope.homeTip = (value == 'accepted') ? false : true;
- });
- }
+ $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ if (!$scope.homeTip) {
+ storageService.getHomeTipAccepted(function(error, value) {
+ $scope.homeTip = (value == 'accepted') ? false : true;
+ });
+ }
- if ($scope.isNW) {
- latestReleaseService.checkLatestRelease(function(err, newRelease) {
- if (err) {
- $log.warn(err);
- return;
- }
+ if ($scope.isNW) {
+ latestReleaseService.checkLatestRelease(function(err, newRelease) {
+ if (err) {
+ $log.warn(err);
+ return;
+ }
- if (newRelease) $scope.newRelease = true;
+ if (newRelease) $scope.newRelease = true;
+ });
+ }
+
+ storageService.getProfileCreationTime(function(error, time) {
+ var now = moment().unix() * 1000;
+ storageService.getRateCardFlag(function(error, value) {
+ $scope.hideRateCard.value = (value == 'true' || (time - now) > 0) ? true : false;
+ });
});
- }
+
+ });
+
+ $scope.$on("$ionicView.enter", function(event, data) {
+ updateAllWallets();
+
+ addressbookService.list(function(err, ab) {
+ if (err) $log.error(err);
+ $scope.addressbook = ab || {};
+ });
+
+ listeners = [
+ $rootScope.$on('bwsEvent', function(e, walletId, type, n) {
+ var wallet = profileService.getWallet(walletId);
+ updateWallet(wallet);
+ if ($scope.recentTransactionsEnabled) getNotifications();
+ }),
+ $rootScope.$on('Local/TxAction', function(e, walletId) {
+ $log.debug('Got action for wallet ' + walletId);
+ var wallet = profileService.getWallet(walletId);
+ updateWallet(wallet);
+ if ($scope.recentTransactionsEnabled) getNotifications();
+ })
+ ];
+
+ configService.whenAvailable(function() {
+ nextStep(function() {
+ var config = configService.getSync();
+ var isWindowsPhoneApp = platformInfo.isWP && platformInfo.isCordova;
+
+ $scope.glideraEnabled = config.glidera.enabled && !isWindowsPhoneApp;
+ $scope.coinbaseEnabled = config.coinbase.enabled && !isWindowsPhoneApp;
+ $scope.amazonEnabled = config.amazon.enabled;
+ $scope.bitpayCardEnabled = config.bitpayCard.enabled;
+
+ var buyAndSellEnabled = !$scope.externalServices.BuyAndSell && ($scope.glideraEnabled || $scope.coinbaseEnabled);
+ var amazonEnabled = !$scope.externalServices.AmazonGiftCards && $scope.amazonEnabled;
+ var bitpayCardEnabled = !$scope.externalServices.BitpayCard && $scope.bitpayCardEnabled;
+
+ $scope.nextStepEnabled = buyAndSellEnabled || amazonEnabled || bitpayCardEnabled;
+ $scope.recentTransactionsEnabled = config.recentTransactions.enabled;
+
+ if ($scope.recentTransactionsEnabled) getNotifications();
+
+ if ($scope.bitpayCardEnabled) bitpayCardCache();
+ $timeout(function() {
+ $ionicScrollDelegate.resize();
+ $scope.$apply();
+ }, 10);
+ });
+ });
+ });
+
+ $scope.$on("$ionicView.leave", function(event, data) {
+ lodash.each(listeners, function(x) {
+ x();
+ });
+ });
+
+ $scope.$on("$ionicView.leave", function(event, data) {
+ lodash.each(listeners, function(x) {
+ x();
+ });
+ });
$scope.openExternalLink = function(url, optIn, title, message, okText, cancelText) {
externalLinkService.open(url, optIn, title, message, okText, cancelText);
@@ -197,61 +270,4 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}, 300);
updateAllWallets();
};
-
- $scope.$on("$ionicView.beforeEnter", function(event, data) {
- updateAllWallets();
-
- addressbookService.list(function(err, ab) {
- if (err) $log.error(err);
- $scope.addressbook = ab || {};
- });
-
- listeners = [
- $rootScope.$on('bwsEvent', function(e, walletId, type, n) {
- var wallet = profileService.getWallet(walletId);
- updateWallet(wallet);
- if ($scope.recentTransactionsEnabled) getNotifications();
- }),
- $rootScope.$on('Local/TxAction', function(e, walletId) {
- $log.debug('Got action for wallet ' + walletId);
- var wallet = profileService.getWallet(walletId);
- updateWallet(wallet);
- if ($scope.recentTransactionsEnabled) getNotifications();
- })
- ];
-
- configService.whenAvailable(function() {
- nextStep(function() {
- var config = configService.getSync();
- var isWindowsPhoneApp = platformInfo.isWP && platformInfo.isCordova;
-
- $scope.glideraEnabled = config.glidera.enabled && !isWindowsPhoneApp;
- $scope.coinbaseEnabled = config.coinbase.enabled && !isWindowsPhoneApp;
- $scope.amazonEnabled = config.amazon.enabled;
- $scope.bitpayCardEnabled = config.bitpayCard.enabled;
-
- var buyAndSellEnabled = !$scope.externalServices.BuyAndSell && ($scope.glideraEnabled || $scope.coinbaseEnabled);
- var amazonEnabled = !$scope.externalServices.AmazonGiftCards && $scope.amazonEnabled;
- var bitpayCardEnabled = !$scope.externalServices.BitpayCard && $scope.bitpayCardEnabled;
-
- $scope.nextStepEnabled = buyAndSellEnabled || amazonEnabled || bitpayCardEnabled;
- $scope.recentTransactionsEnabled = config.recentTransactions.enabled;
-
- if ($scope.recentTransactionsEnabled) getNotifications();
-
- if ($scope.bitpayCardEnabled) bitpayCardCache();
- $timeout(function() {
- $ionicScrollDelegate.resize();
- $scope.$apply();
- }, 10);
- });
- });
- });
-
- $scope.$on("$ionicView.leave", function(event, data) {
- lodash.each(listeners, function(x) {
- x();
- });
- });
-
});
diff --git a/src/js/controllers/tab-settings.js b/src/js/controllers/tab-settings.js
index 773a6a5f3..13d482102 100644
--- a/src/js/controllers/tab-settings.js
+++ b/src/js/controllers/tab-settings.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabSettingsController', function($scope, $window, uxLanguage, platformInfo, profileService, feeService, configService, externalLinkService) {
+angular.module('copayApp.controllers').controller('tabSettingsController', function($scope, $window, $ionicModal, uxLanguage, platformInfo, profileService, feeService, configService, externalLinkService) {
var updateConfig = function() {
@@ -32,4 +32,15 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
updateConfig();
});
+ $scope.openRateModal = function() {
+ $scope.isModal = true;
+ $ionicModal.fromTemplateUrl('views/feedback/rateCard.html', {
+ scope: $scope,
+ backdropClickToClose: false,
+ hardwareBackButtonClose: false
+ }).then(function(modal) {
+ $scope.rateModal = modal;
+ $scope.rateModal.show();
+ });
+ }
});
diff --git a/src/js/routes.js b/src/js/routes.js
index 2b92f5af2..ee65083d3 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -720,13 +720,50 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
},
})
-
/*
*
- * Buy or Sell Bitcoin
+ * Feedback
*
*/
+ .state('feedback', {
+ url: '/feedback',
+ abstract: true,
+ template: '
+
+