Skip to content

Commit

Permalink
Merge branch 'master' into fix/invite-bounty
Browse files Browse the repository at this point in the history
  • Loading branch information
octavioamu authored Jul 17, 2019
2 parents bcee552 + 7a5761d commit 0235146
Show file tree
Hide file tree
Showing 31 changed files with 437 additions and 227 deletions.
3 changes: 3 additions & 0 deletions app/app/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def preprocess(request):
'access_token': profile.access_token if profile else '',
'is_staff': request.user.is_staff if user_is_authenticated else False,
'is_moderator': profile.is_moderator if profile else False,
'persona_is_funder': profile.persona_is_funder if profile else False,
'persona_is_hunter': profile.persona_is_hunter if profile else False,

}
context['json_context'] = json.dumps(context)

Expand Down
2 changes: 2 additions & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
url(r'^actions/api/v0.1/', include(dbrouter.urls)), # same as active
url(r'^api/v0.1/users_search/', dashboard.views.get_users, name='users_search'),
url(r'^api/v0.1/kudos_search/', dashboard.views.get_kudos, name='kudos_search'),
url(r'^api/v0.1/choose_persona/', dashboard.views.choose_persona, name='choose_persona'),

# Health check endpoint
re_path(r'^health/', include('health_check.urls')),
re_path(r'^lbcheck/?', healthcheck.views.lbcheck, name='lbcheck'),
Expand Down
60 changes: 60 additions & 0 deletions app/assets/v2/images/modals/persona-choose.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
142 changes: 141 additions & 1 deletion app/assets/v2/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,60 @@ $(document).ready(function() {
}
}
});
attach_close_button();
});

const attach_close_button = function() {
$('body').delegate('.alert .closebtn', 'click', function(e) {
$(this).parents('.alert').remove();
$('.alert').each(function(index) {
if (index == 0) $(this).css('top', 0);
else {
let new_top = (index * 66) + 'px';

$(this).css('top', new_top);
}
});
});
};

const closeButton = function(msg) {
var html = (msg['closeButton'] === false ? '' : '<span class="closebtn" >&times;</span>');

return html;
};

const alertMessage = function(msg) {
var html = `<strong>${typeof msg['title'] !== 'undefined' ? msg['title'] : ''}</strong>${msg['message']}`;

return html;
};

const _alert = function(msg, _class) {
if (typeof msg == 'string') {
msg = {
'message': msg
};
}
var numAlertsAlready = $('.alert:visible').length;
var top = numAlertsAlready * 44;

var html = function() {
return (
`<div class="alert ${_class} g-font-muli" style="top: ${top}px">
<div class="message">
<div class="content">
${alertMessage(msg)}
</div>
</div>
${closeButton(msg)}
</div>`
);
};

$('body').append(html);
};


if ($('#is-authenticated').val() === 'True' && !localStorage['notify_policy_update']) {
localStorage['notify_policy_update'] = true;
Expand All @@ -171,7 +223,7 @@ if ($('#is-authenticated').val() === 'True' && !localStorage['notify_policy_upda
<a href="/legal/policy" target="_blank">${gettext('Read Our Updated Terms')}</a>
</div>
<div class="col-12 mt-4 mb-2 text-right font-caption">
<a rel="modal:close" href="javascript:void" aria-label="Close dialog" class="button button--primary">Ok</a>
<button type="button" class="button button--primary" data-dismiss="modal">ok</button>
</div>
</div>
</div>
Expand All @@ -180,3 +232,91 @@ if ($('#is-authenticated').val() === 'True' && !localStorage['notify_policy_upda
$(content).appendTo('body');
$('#notify_policy_update').bootstrapModal('show');
}

if (document.contxt.github_handle && !document.contxt.persona_is_funder && !document.contxt.persona_is_hunter) {

const content = $.parseHTML(
`<div id="persona_modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content px-4 py-3">
<div class="col-12">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="col-12 pt-2 pb-2 text-center">
<img src="${static_url}/v2/images/modals/persona-choose.svg" width="160" height="137">
<h2 class="font-title mt-4">${gettext('Are you a Funder or a Contributor?')}</h2>
</div>
<div class="col-12 pt-2 text-center">
<p>${gettext('Let us know so we could optimize the <br>best experience for you!')}</p>
</div>
<div class="col-12 my-4 d-flex justify-content-around">
<button type="button" class="btn btn-gc-blue col-5" data-persona="persona_is_funder">I'm a Funder</button>
<button type="button" class="btn btn-gc-blue col-5" data-persona="persona_is_hunter">I'm a Contributor</button>
</div>
</div>
</div>
</div>`);

$(content).appendTo('body');
$('#persona_modal').bootstrapModal('show');
}

$('body').on('click', '[data-persona]', function(e) {
sendPersonal($(this).data('persona'));
});

const sendPersonal = (persona) => {
let postPersona = fetchData('/api/v0.1/choose_persona/', 'POST',
{persona, 'access_token': document.contxt.access_token}
);

$.when(postPersona).then((response, status, statusCode) => {
if (statusCode.status != 200) {
return _alert(response.msg, 'error');
}

$('#persona_modal').bootstrapModal('hide');
const urls = [
{
url: document.location.href,
redirect: '/onboard/funder'
},
{
url: '/bounties/funder',
redirect: '/onboard/funder'
},
{
url: '/contributor',
redirect: '/onboard/contributor'
}
];

const checkUrl = (arr, val) => {
return arr.some(arrObj => {
if (val.indexOf(arrObj.url) >= 0) {
return true;
}
return false;
});
};

if (response.persona === 'persona_is_funder') {
if (checkUrl(urls, document.location.href)) {
window.location = '/onboard/funder';
} else {
return _alert(gettext('Thanks, you can read the guide <a href="/how/funder">here.</a>'), 'info');
}

} else if (response.persona === 'persona_is_hunter') {
if (checkUrl(urls, document.location.href)) {
window.location = '/onboard/contributor';
} else {
return _alert(gettext('Thanks, you can read the guide <a href="/how/contributor">here.</a>'), 'info');
}
}


});
};
114 changes: 75 additions & 39 deletions app/assets/v2/js/pages/new_bounty.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,13 +554,7 @@ $('#submitBounty').validate({
var isETH = tokenAddress == '0x0000000000000000000000000000000000000000';
var token_contract = web3.eth.contract(token_abi).at(tokenAddress);
var account = web3.eth.coinbase;

if (!isETH) {
check_balance_and_alert_user_if_not_enough(
tokenAddress,
amount,
'You do not have enough tokens to fund this bounty.');
}
let amountNoDecimal = amount;

amount = amount * decimalDivisor;
// Create the bounty object.
Expand Down Expand Up @@ -698,6 +692,7 @@ $('#submitBounty').validate({
indicateMetamaskPopup(true);
if (error) {
_alert({ message: gettext('Unable to pay bounty fee. Please try again.') }, 'error');
unloading_button($('.js-submit'));
} else {
deductBountyAmount(fee, txnId);
}
Expand Down Expand Up @@ -794,12 +789,69 @@ $('#submitBounty').validate({
});
};

if ($("input[type='radio'][name='repo_type']:checked").val() == 'private' && $('#issueNDA')[0].files[0]) {
uploadNDA();
} else if (data.featuredBounty) {
payFeaturedBounty();
function processBounty() {
if ($("input[type='radio'][name='repo_type']:checked").val() == 'private' && $('#issueNDA')[0].files[0]) {
uploadNDA();
} else if (data.featuredBounty) {
payFeaturedBounty();
} else {
do_bounty();
}
}

if (check_balance_and_alert_user_if_not_enough(tokenAddress, amountNoDecimal)) {
processBounty();
} else {
do_bounty();
return unloading_button($('.js-submit'));
}

function check_balance_and_alert_user_if_not_enough(tokenAddress, amount, msg) {
const token_contract = web3.eth.contract(token_abi).at(tokenAddress);
const from = web3.eth.coinbase;
const token_details = tokenAddressToDetails(tokenAddress);
const token_decimals = token_details['decimals'];
const token_name = token_details['name'];
let total = parseFloat(amount) +
parseFloat((parseFloat(amount) * FEE_PERCENTAGE).toFixed(4)) +
(data.featuredBounty ? ethFeaturedPrice : 0);

const checkBalance = (balance, total, token_name) => {

if (parseFloat(total) > balance) {
let isFeaturedToken = token_name !== 'ETH' && data.featuredBounty;

total = isFeaturedToken ? total - ethFeaturedPrice : total;
const balance_rounded = Math.round(balance * 10) / 10;
let msg = gettext('You do not have enough tokens to fund this bounty. You have ') +
balance_rounded + ' ' + token_name + ' ' + gettext(' but you need ') + total +
' ' + token_name;

if (isFeaturedToken) {
msg += ` + ${ethFeaturedPrice} ETH`;
}
_alert(msg, 'warning');
} else {
return processBounty();
}
};
var walletBalance;

if (tokenAddress == '0x0000000000000000000000000000000000000000') {
let ethBalance = getBalance(from);

ethBalance.then(
function(result) {
walletBalance = result.toNumber() / Math.pow(10, token_decimals);
return checkBalance(walletBalance, total, token_name);
}
);
} else {
token_contract.balanceOf.call(from, function(error, result) {
if (error) return;
walletBalance = result.toNumber() / Math.pow(10, token_decimals);
return checkBalance(walletBalance, total, token_name);
});
}
}
}
});
Expand All @@ -815,34 +867,18 @@ $('[name=permission_type]').on('change', function() {
}
});

/**
* Alerts funder if they don't have enough tokens while attempting to
* fund a bounty.
* @param {String} tokenAddress
* @param {Number} amount
*/
function check_balance_and_alert_user_if_not_enough(tokenAddress, amount) {
const token_contract = web3.eth.contract(token_abi).at(tokenAddress);
const from = web3.eth.coinbase;
const token_details = tokenAddressToDetails(tokenAddress);
const token_decimals = token_details['decimals'];
const token_name = token_details['name'];

token_contract.balanceOf.call(from, function(error, result) {
if (error) return;
const balance = result.toNumber() / Math.pow(10, token_decimals);
const balance_rounded = Math.round(balance * 10) / 10;
const total = parseFloat(amount) + parseFloat((parseFloat(amount) * FEE_PERCENTAGE).toFixed(4));

if (parseFloat(total) > balance) {
const msg = gettext('You do not have enough tokens to fund this bounty. You have ') +
balance_rounded + ' ' + token_name + ' ' + gettext(' but you need ') + amount +
' ' + token_name;

_alert(msg, 'warning');
}

var getBalance = (address) => {
return new Promise (function(resolve, reject) {
web3.eth.getBalance(address, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
};

let usdFeaturedPrice = $('.featured-price-usd').text();
let ethFeaturedPrice;
Expand Down
Loading

0 comments on commit 0235146

Please sign in to comment.