Merge branch 'master' of github.com:bitpay/copay into improveWalletDetails

This commit is contained in:
Marty Alcala 2016-11-11 13:52:47 -05:00
commit d02affadd1
29 changed files with 793 additions and 200 deletions

View file

@ -26,7 +26,10 @@ angular.module('copayApp.controllers').controller('activityController',
$scope.openNotificationModal = function(n) {
if (n.txid) {
openTxModal(n);
$state.transitionTo('tabs.wallet.tx-details', {
txid: n.txid,
walletId: n.walletId
});
} else {
var txp = lodash.find($scope.txps, {
id: n.txpId
@ -46,35 +49,4 @@ angular.module('copayApp.controllers').controller('activityController',
}
}
};
var openTxModal = function(n) {
var wallet = profileService.getWallet(n.walletId);
ongoingProcess.set('loadingTxInfo', true);
walletService.getTx(wallet, n.txid, function(err, tx) {
ongoingProcess.set('loadingTxInfo', false);
if (err) {
$log.error(err);
return popupService.showAlert(gettextCatalog.getString('Error'), err);
}
if (!tx) {
$log.warn('No tx found');
return popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Transaction not found'));
}
$scope.wallet = wallet;
$scope.btx = lodash.cloneDeep(tx);
$state.transitionTo('tabs.wallet.tx-details', {
txid: $scope.btx.txid,
walletId: $scope.walletId
});
walletService.getTxNote(wallet, n.txid, function(err, note) {
if (err) $log.warn('Could not fetch transaction note: ' + err);
$scope.btx.note = note;
});
});
};
});

View file

@ -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);
};
});

View file

@ -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();
})
}
});

View file

@ -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
});
});
};
});

View file

@ -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);
});
});

View file

@ -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() {});
};
});

View file

@ -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);
@ -43,7 +116,10 @@ angular.module('copayApp.controllers').controller('tabHomeController',
wallet = profileService.getWallet(n.walletId);
if (n.txid) {
openTxModal(n);
$state.transitionTo('tabs.wallet.tx-details', {
txid: n.txid,
walletId: n.walletId
});
} else {
var txp = lodash.find($scope.txps, {
id: n.txpId
@ -65,37 +141,6 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
};
var openTxModal = function(n) {
wallet = profileService.getWallet(n.walletId);
ongoingProcess.set('loadingTxInfo', true);
walletService.getTx(wallet, n.txid, function(err, tx) {
ongoingProcess.set('loadingTxInfo', false);
if (err) {
$log.error(err);
return popupService.showAlert(gettextCatalog.getString('Error'), err);
}
if (!tx) {
$log.warn('No tx found');
return popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Transaction not found'));
}
$scope.wallet = wallet;
$scope.btx = lodash.cloneDeep(tx);
$state.transitionTo('tabs.wallet.tx-details', {
txid: $scope.btx.txid,
walletId: $scope.walletId
});
walletService.getTxNote(wallet, n.txid, function(err, note) {
if (err) $log.warn('Could not fetch transaction note: ' + err);
$scope.btx.note = note;
});
});
};
$scope.openWallet = function(wallet) {
if (!wallet.isComplete()) {
return $state.go('tabs.copayers', {
@ -117,6 +162,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.txpsN = n;
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 100);
})
};
@ -141,25 +187,6 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
});
});
if (!$scope.recentTransactionsEnabled) return;
$scope.fetchingNotifications = true;
profileService.getNotifications({
limit: 3
}, function(err, n) {
if (err) {
$log.error(err);
return;
}
$scope.fetchingNotifications = false;
$scope.notifications = n;
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 100);
})
};
var updateWallet = function(wallet) {
@ -171,20 +198,22 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
wallet.status = status;
updateTxps();
});
};
if (!$scope.recentTransactionsEnabled) return;
$scope.fetchingNotifications = true;
profileService.getNotifications({
limit: 3
}, function(err, notifications) {
$scope.fetchingNotifications = false;
if (err) {
$log.error(err);
return;
}
$scope.notifications = notifications;
});
var getNotifications = function() {
profileService.getNotifications({
limit: 3
}, function(err, n) {
if (err) {
$log.error(err);
return;
}
$scope.notifications = n;
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 100);
});
};
@ -241,57 +270,4 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}, 300);
updateAllWallets();
};
$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);
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
$log.debug('Got action for wallet ' + walletId);
var wallet = profileService.getWallet(walletId);
updateWallet(wallet);
})
];
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.bitpayCardEnabled) bitpayCardCache();
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 10);
});
});
});
$scope.$on("$ionicView.leave", function(event, data) {
lodash.each(listeners, function(x) {
x();
});
});
});

View file

@ -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();
});
}
});

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('txDetailsController', function($log, $timeout, $ionicHistory, $scope, $stateParams, walletService, lodash, gettextCatalog, profileService, configService, externalLinkService, popupService) {
angular.module('copayApp.controllers').controller('txDetailsController', function($log, $ionicHistory, $scope, walletService, lodash, gettextCatalog, profileService, configService, externalLinkService, popupService, ongoingProcess) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.title = gettextCatalog.getString('Transaction');
@ -9,11 +9,13 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
$scope.copayerId = $scope.wallet.credentials.copayerId;
$scope.isShared = $scope.wallet.credentials.n > 1;
walletService.getTx($scope.wallet, $stateParams.txid, function(err, tx) {
ongoingProcess.set('loadingTxInfo', true);
walletService.getTx($scope.wallet, data.stateParams.txid, function(err, tx) {
ongoingProcess.set('loadingTxInfo', false);
if (err) {
$log.warn('Could not get tx');
$ionicHistory.goBack();
return;
return popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Transaction not found'));
}
$scope.btx = tx;
if ($scope.btx.action != 'invalid') {
@ -130,6 +132,27 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
return n.substring(0, 4);
};
$scope.getFiatRate = function() {
if ($scope.rateDate) return;
var alternativeIsoCode = $scope.wallet.status.alternativeIsoCode;
$scope.loadingRate = true;
$scope.wallet.getFiatRate({
code: alternativeIsoCode,
ts: $scope.btx.time * 1000
}, function(err, res) {
$scope.loadingRate = false;
if (err) {
$log.debug('Could not get historic rate');
return;
}
if (res && res.rate) {
$scope.rateDate = res.fetchedOn;
$scope.rateStr = res.rate + ' ' + alternativeIsoCode;
$scope.$apply();
}
});
};
$scope.cancel = function() {
$scope.txDetailsModal.hide();
};