feedback feature

This commit is contained in:
Gabriel Bazán 2016-11-01 14:21:35 -03:00
parent aa887dfc5e
commit b64e80478e
14 changed files with 344 additions and 3 deletions

View File

@ -0,0 +1,22 @@
'use strict';
angular.module('copayApp.controllers').controller('rateAppStoreController', function($scope, $state, $stateParams) {
$scope.score = parseInt($stateParams.score);
$scope.skip = function() {
$state.go('feedback.thanks', {
score: $scope.score,
skip: true
});
};
$scope.sendFeedback = function() {
$state.go('feedback.sendFeedback', {
score: $scope.score
});
};
$scope.goAppStore = function() {
};
});

View File

@ -0,0 +1,42 @@
'use strict';
angular.module('copayApp.controllers').controller('sendFeedbackController', function($scope, $state, $timeout, $stateParams, gettextCatalog) {
$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. Is there anything we could do to improve your experience?");
break;
case 2:
$scope.reaction = gettextCatalog.getString("Oh no!");
$scope.comment = gettextCatalog.getString("There's obviously something we're doing wrong. Is there anything we could do to improve your experience?");
break;
case 3:
$scope.reaction = gettextCatalog.getString("Thanks!");
$scope.comment = gettextCatalog.getString("We're always looking for ways to improve BitPay wallet. Is there anything we could do to improve your experience?");
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 - how could we improve your experience?");
break;
case 5:
$scope.reaction = gettextCatalog.getString("Feedback!");
$scope.comment = gettextCatalog.getString("We're always looking for ways to improve BitPay wallet. Is there anything we could do to improve your experience?");
break;
}
$scope.sendFeedback = function() {
//Feedback entered in feedback flow should be sent to BWS, and BWS should send a plain-text email to feedback@bitpay.com with a reply-to going to the user's email address. (From the onboarding process)
$state.go('feedback.thanks', {
score: $stateParams.score
});
};
$scope.skip = function() {
$state.go('feedback.thanks', {
score: $scope.score,
skip: true
});
};
});

View File

@ -0,0 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('thanksController', function($scope, $state, $stateParams) {
$scope.score = parseInt($stateParams.score);
$scope.skip = $stateParams.skip && $scope.score == 5;
});

View File

@ -39,6 +39,41 @@ angular.module('copayApp.controllers').controller('tabHomeController',
externalLinkService.open(url, optIn, title, message, okText, cancelText);
};
$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.goFeedbackFlow = function() {
if ($scope.score != 5)
$state.go('feedback.sendFeedback', {
score: $scope.score
});
else
$state.go('feedback.rateAppStore', {
score: $scope.score
});
};
$scope.openNotificationModal = function(n) {
wallet = profileService.getWallet(n.walletId);

View File

@ -720,13 +720,50 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
},
})
/*
*
* Buy or Sell Bitcoin
* Feedback
*
*/
.state('feedback', {
url: '/feedback',
abstract: true,
template: '<ion-nav-view name="feedback"></ion-nav-view>'
})
.state('feedback.sendFeedback', {
url: '/sendFeedback/:score',
views: {
'feedback': {
controller: 'sendFeedbackController',
templateUrl: 'views/feedback/sendFeedback.html'
}
}
})
.state('feedback.thanks', {
url: '/thanks/:score/:skip',
views: {
'feedback': {
controller: 'thanksController',
templateUrl: 'views/feedback/thanks.html'
}
}
})
.state('feedback.rateAppStore', {
url: '/rateAppStore/:score',
views: {
'feedback': {
controller: 'rateAppStoreController',
templateUrl: 'views/feedback/rateAppStore.html'
}
}
})
/*
*
* Buy or Sell Bitcoin
*
*/
.state('tabs.buyandsell', {
url: '/buyandsell',
views: {
@ -992,7 +1029,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
profileService.storeProfileIfDirty();
$log.debug('Profile loaded ... Starting UX.');
scannerService.gentleInitialize();
$state.go('tabs.home');
// $state.go('tabs.home');
}
// After everything have been loaded, initialize handler URL

View File

@ -0,0 +1,12 @@
#rate-app-store {
.title {
font-size: 20px;
font-weight: bold;
color: $dark-gray;
margin: 20px 10px;
text-align: center;
}
.subtitle {
padding: 10px 30px 20px 40px;
}
}

View File

@ -0,0 +1,33 @@
#send-feedback {
background-color: #fff;
.title {
font-size: 20px;
font-weight: bold;
color: $dark-gray;
margin: 20px 10px;
}
.star {
margin: 20px 0px;
}
a {
font-size: 25px;
padding: 12px;
.gold {
color: #ffd700 !important;
}
.grey {
color: #667 !important;
}
}
.comment {
padding: 20px;
font-size: 1rem;
line-height: 1.5em;
font-weight: 300;
color: $dark-gray;
}
textarea {
padding: 10px;
width: 100%;
}
}

View File

@ -0,0 +1,12 @@
#thanks-feedback {
.title {
font-size: 20px;
font-weight: bold;
color: $dark-gray;
margin: 20px 10px;
text-align: center;
}
.subtitle {
padding: 10px 30px 20px 40px;
}
}

View File

@ -116,6 +116,23 @@
font-size: 20px;
margin-left: 10px;
position: absolute;
}
}
.starts {
display: flex;
border-bottom: none;
.button {
background-color: #fff;
width: 100%;
}
.gold {
color: #ffd700 !important;
}
.grey {
color: #667 !important;
}
}
.continue-button {
padding: 20px;
}
}

View File

@ -17,6 +17,9 @@
@import "wallet-backup-phrase";
@import "zero-state";
@import "onboarding/onboarding";
@import "feedback/sendFeedback";
@import "feedback/thanks";
@import "feedback/rateAppStore";
@import "includes/actionSheet";
@import "export";
@import "import";

View File

@ -0,0 +1,33 @@
<ion-view id="rate-app-store">
<ion-nav-bar class="bar-royal">
<ion-nav-buttons side="secondary">
<button class="button button-button-clear" ng-click="skip()" translate>
Skip
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content scroll="false">
<div class="title">
<span translate>Thank you!</span>
<div>
<i class="icon zero-state-icon">
<img src="img/address-book-add.svg"/>
</i>
</div>
</div>
<div class="subtitle">
<span translate>5-star ratings help us get BitPay Wallet into more hands, and more users means more resoucers can be committed to the app!</span>
</div>
<div class="subtitle">
<span translate>Would you be willing to rate BitPay Wallet in the app store?</span>
</div>
<div>
<button type="submit" class="button button-standard button-primary" ng-click="goAppStore()">
<span translate>Rate on the app store</span>
</button>
<button type="submit" class="button button-standard button-primary" ng-click="sendFeedback()">
<span translate>Send us feedback instead</span>
</button>
</div>
</ion-content>
</ion-view>

View File

@ -0,0 +1,34 @@
<ion-view id="send-feedback">
<ion-nav-bar class="bar-royal">
<ion-nav-buttons side="secondary">
<button class="button button-back button-clear" ng-click="skip()">
Skip
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content scroll="false">
<div class="row">
<div class="col col-50 title">
<span>{{reaction}}</span>
</div>
<div class="col col-50 star">
<a><i ng-class="{'gold': 1 <= score, 'grey': 1 > score}" class="icon ion-android-star"></i></a>
<a><i ng-class="{'gold': 2 <= score, 'grey': 2 > score}" class="icon ion-android-star"></i></a>
<a><i ng-class="{'gold': 3 <= score, 'grey': 3 > score}" class="icon ion-android-star"></i></a>
<a><i ng-class="{'gold': 4 <= score, 'grey': 4 > score}" class="icon ion-android-star"></i></a>
<a><i ng-class="{'gold': 5 == score, 'grey': 5 > score}" class="icon ion-android-star"></i></a>
</div>
</div>
<div class="row comment">
<span translate>{{comment}}</span>
</div>
<div>
<textarea row="40"></textarea>
</div>
<div class="padding">
<button type="submit" class="button button-full button-primary" ng-click="sendFeedback()" translate>
Send
</button>
</div>
</ion-content>
</ion-view>

View File

@ -0,0 +1,37 @@
<ion-view id="thanks-feedback">
<ion-nav-bar class="bar-royal">
<ion-nav-buttons side="secondary">
<button class="button icon ion-ios-close-empty " ui-sref="tabs.home">
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content scroll="false">
<div ng-if="!skip">
<div class="title">
<span translate>Thank you!</span>
</div>
<div class="subtitle">
<span translate>A member of the team will review your feedback as soon as possible.</span>
</div>
<div class="subtitle" ng-if="score < 4">
<span translate>If you have additional feedback, please let us know by tapping the "Send feedback" option in the Settings tab.</span>
<div>
<i class="icon zero-state-icon">
<img src="img/address-book-add.svg"/>
</i>
</div>
</div>
</div>
<div ng-if="skip" class="title">
<span translate>Invite friends to BitPay Wallet!</span>
<div>
<i class="icon zero-state-icon">
<img src="img/address-book-add.svg"/>
</i>
</div>
</div>
<div class="text-center" ng-if="score >= 4">
<span translate>Share the love by inviting your friends.</span>
</div>
</ion-content>
</ion-view>

View File

@ -13,6 +13,24 @@
<div class="release" ng-show="newRelease" ng-click="openExternalLink('https://github.com/bitpay/copay/releases/latest', true, 'Update Available', 'An update to this app is available. For your security, please update to the latest version.', 'View Update', 'Go Back')">
<span translate>An update to this app is available</span><span><i class="icon bp-arrow-right"></i></span>
</div>
<div class="list card">
<div class="item item-icon-right item-heading">
<span translate>How do you like BitPay Wallet?</span>
<a><i class="icon ion-ios-close-empty close-home-tip"></i></a>
</div>
<div class="starts item item-sub">
<button class="button icon ion-android-star" ng-click="setScore(1)" ng-class="{'gold': 1 <= score, 'grey': 1 > score}"></button>
<button class="button icon ion-android-star" ng-click="setScore(2)" ng-class="{'gold': 2 <= score, 'grey': 2 > score}"></button>
<button class="button icon ion-android-star" ng-click="setScore(3)" ng-class="{'gold': 3 <= score, 'grey': 3 > score}"></button>
<button class="button icon ion-android-star" ng-click="setScore(4)" ng-class="{'gold': 4 <= score, 'grey': 4 > score}"></button>
<button class="button icon ion-android-star" ng-click="setScore(5)" ng-class="{'gold': 5 == score, 'grey': 5 > score}"></button>
</div>
<div class="continue-button" ng-if="button_title">
<button type="submit" class="button button-standard button-primary" ng-click="goFeedbackFlow()">
<span>{{button_title}}</span>
</button>
</div>
</div>
<div class="list card homeTip" ng-if="homeTip">
<div class="item item-icon-right item-heading">
<a ng-click="hideHomeTip()"><i class="icon ion-ios-close-empty close-home-tip"></i></a>