diff --git a/app/app/urls.py b/app/app/urls.py index 6fed6e05ef7..214d1a9bf56 100644 --- a/app/app/urls.py +++ b/app/app/urls.py @@ -66,28 +66,37 @@ url(r'^dashboard/?', dashboard.views.dashboard, name='dashboard'), url(r'^explorer/?', dashboard.views.dashboard, name='explorer'), + + # action URLs url(r'^bounty/new/?', dashboard.views.new_bounty, name='new_bounty'), url(r'^funding/new/?', dashboard.views.new_bounty, name='new_funding'), url(r'^new/?', dashboard.views.new_bounty, name='new_funding_short'), + re_path(r'^issue/fulfill/(?P.*)?', dashboard.views.fulfill_bounty, name='fulfill_bounty'), + re_path(r'^issue/accept/(?P.*)?', dashboard.views.accept_bounty, name='process_funding'), + re_path(r'^issue/increase/(?P.*)?', dashboard.views.increase_bounty, name='increase_bounty'), + re_path(r'^issue/cancel/(?P.*)?', dashboard.views.cancel_bounty, name='kill_bounty'), + + # Interests + path('actions/bounty//interest/new/', dashboard.views.new_interest, name='express-interest'), + path('actions/bounty//interest/remove/', dashboard.views.remove_interest, name='remove-interest'), + path('actions/bounty//interest//uninterested/', dashboard.views.uninterested, name='uninterested'), - url(r'^bounty/fulfill/?', dashboard.views.fulfill_bounty, name='fulfill_bounty'), - url(r'^funding/fulfill/?', dashboard.views.fulfill_bounty, name='fulfill_funding'), - url(r'^bounty/process/?', dashboard.views.process_bounty, name='process_bounty'), - url(r'^funding/process/?', dashboard.views.process_bounty, name='process_funding'), + # View Bounty url(r'^bounty/details/(?P.*)/(?P.*)/(?P.*)', dashboard.views.bounty_details, name='bounty_details_new'), url(r'^funding/details/(?P.*)/(?P.*)/(?P.*)', dashboard.views.bounty_details, name='funding_details_new'), url(r'^issue/(?P.*)/(?P.*)/(?P.*)/(?P.*)', dashboard.views.bounty_details, name='issue_details_new3'), url(r'^issue/(?P.*)/(?P.*)/(?P.*)', dashboard.views.bounty_details, name='issue_details_new2'), url(r'^bounty/details/?', dashboard.views.bounty_details, name='bounty_details'), url(r'^funding/details/?', dashboard.views.bounty_details, name='funding_details'), - url(r'^legacy/funding/details/?', dashboard.views.bounty_details, name='legacy_funding_details'), - url(r'^funding/increase/?', dashboard.views.increase_bounty, name='increase_bounty'), - url(r'^funding/kill/?', dashboard.views.kill_bounty, name='kill_bounty'), + + # Tips url(r'^tip/receive/?', dashboard.views.receive_tip, name='receive_tip'), url(r'^tip/send/2/?', dashboard.views.send_tip_2, name='send_tip_2'), url(r'^tip/send/?', dashboard.views.send_tip, name='send_tip'), url(r'^send/?', dashboard.views.send_tip, name='tip'), url(r'^tip/?', dashboard.views.send_tip, name='tip'), + + # Legal url(r'^legal/?', dashboard.views.terms, name='legal'), url(r'^terms/?', dashboard.views.terms, name='_terms'), url(r'^legal/terms/?', dashboard.views.terms, name='terms'), @@ -95,6 +104,8 @@ url(r'^legal/cookie/?', dashboard.views.cookie, name='cookie'), url(r'^legal/prirp/?', dashboard.views.prirp, name='prirp'), url(r'^legal/apitos/?', dashboard.views.apitos, name='apitos'), + + # Alpha functionality url(r'^profile/(.*)?', dashboard.views.profile, name='profile'), url(r'^toolbox/?', dashboard.views.toolbox, name='toolbox'), path('actions/tool//voteUp', dashboard.views.vote_tool_up, name='vote_tool_up'), @@ -113,6 +124,7 @@ url(r'^sync/get_amount?', dashboard.helpers.amount, name='helpers_amount'), url(r'^sync/get_issue_details?', dashboard.helpers.issue_details, name='helpers_issue_details'), url(r'^sync/search_save?', dashboard.views.save_search, name='save_search'), + # brochureware views url(r'^about/?', retail.views.about, name='about'), url(r'^mission/?', retail.views.mission, name='mission'), @@ -128,6 +140,7 @@ url(r'^extension/chrome?', retail.views.browser_extension_chrome, name='browser_extension_chrome'), url(r'^extension/firefox?', retail.views.browser_extension_firefox, name='browser_extension_firefox'), url(r'^extension/?', retail.views.browser_extension_chrome, name='browser_extension'), + # basic redirect retail views url(r'^press/?', retail.views.presskit, name='press'), url(r'^presskit/?', retail.views.presskit, name='presskit'), @@ -199,10 +212,6 @@ # for robots url(r'^robots.txt/?', retail.views.robotstxt, name='robotstxt'), url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'), - # Interests - path('actions/bounty//interest/new/', dashboard.views.new_interest, name='express-interest'), - path('actions/bounty//interest/remove/', dashboard.views.remove_interest, name='remove-interest'), - path('actions/bounty//interest//uninterested/', dashboard.views.uninterested, name='uninterested'), # Legacy Support path('legacy/', include('legacy.urls', namespace='legacy')), re_path(r'^logout/$', auth_views.logout, name='logout'), diff --git a/app/assets/v2/js/pages/bounty_details.js b/app/assets/v2/js/pages/bounty_details.js index 47ac055141b..46e7fbb25ba 100644 --- a/app/assets/v2/js/pages/bounty_details.js +++ b/app/assets/v2/js/pages/bounty_details.js @@ -370,7 +370,11 @@ var wait_for_tx_to_mine_and_then_ping_server = function() { // clear local data localStorage[document.issueURL] = ''; - document.location.href = document.location.href; + if (response['url']) { + document.location.href = response['url']; + } else { + document.location.href = document.location.href; + } } else { console.log('error from sync/web', response); error(response); @@ -491,7 +495,7 @@ var do_actions = function(result) { var enabled = submit_work_enabled; var _entry = { enabled: enabled, - href: '/funding/fulfill?source=' + result['github_url'], + href: result['action_urls']['fulfill'], text: gettext('Submit Work'), parent: 'right_actions', title: gettext('Submit work for the funder to review'), @@ -521,7 +525,7 @@ var do_actions = function(result) { var enabled = kill_bounty_enabled; var _entry = { enabled: enabled, - href: '/funding/kill?source=' + result['github_url'], + href: result['action_urls']['cancel'], text: gettext('Cancel Bounty'), parent: 'right_actions', title: gettext('Cancel bounty and reclaim funds for this issue') @@ -536,7 +540,7 @@ var do_actions = function(result) { var enabled = show_accept_submission; var _entry = { enabled: enabled, - href: '/funding/process?source=' + result['github_url'], + href: result['action_urls']['accept'], text: gettext('Accept Submission'), title: gettext('This will payout the bounty to the submitter.'), parent: 'right_actions', @@ -550,7 +554,7 @@ var do_actions = function(result) { var enabled = increase_bounty_enabled; var _entry = { enabled: enabled, - href: '/funding/increase?source=' + result['github_url'], + href: result['action_urls']['increase'], text: gettext('Add Contribution'), parent: 'right_actions', title: gettext('Increase the funding for this issue'), diff --git a/app/assets/v2/js/pages/fulfill_bounty.js b/app/assets/v2/js/pages/fulfill_bounty.js index c10e687fb2f..609d18c9a46 100644 --- a/app/assets/v2/js/pages/fulfill_bounty.js +++ b/app/assets/v2/js/pages/fulfill_bounty.js @@ -2,6 +2,7 @@ window.onload = function() { // a little time for web3 injection setTimeout(function() { + waitforWeb3(actions_page_warn_if_not_on_same_network); var account = web3.eth.accounts[0]; if (typeof localStorage['githubUsername'] != 'undefined') { @@ -144,7 +145,7 @@ window.onload = function() { }; // Get bountyId from the database - var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + document.web3network; + var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + $('input[name=network]').val() + '&standard_bounties_id=' + $('input[name=standard_bounties_id]').val(); $.get(uri, function(results, status) { results = sanitizeAPIResults(results); diff --git a/app/assets/v2/js/pages/increase_bounty.js b/app/assets/v2/js/pages/increase_bounty.js index bef726042de..8fe2cb78eb6 100644 --- a/app/assets/v2/js/pages/increase_bounty.js +++ b/app/assets/v2/js/pages/increase_bounty.js @@ -2,6 +2,8 @@ load_tokens(); // Wait until page is loaded, then run the function $(document).ready(function() { + waitforWeb3(actions_page_warn_if_not_on_same_network); + $('input[name=amount]').keyup(setUsdAmount); $('input[name=amount]').blur(setUsdAmount); $('select[name=deonomination]').change(setUsdAmount); diff --git a/app/assets/v2/js/pages/kill_bounty.js b/app/assets/v2/js/pages/kill_bounty.js index 3cdd88d8245..27d741d366f 100644 --- a/app/assets/v2/js/pages/kill_bounty.js +++ b/app/assets/v2/js/pages/kill_bounty.js @@ -2,6 +2,7 @@ window.onload = function() { // a little time for web3 injection setTimeout(function() { + waitforWeb3(actions_page_warn_if_not_on_same_network); var account = web3.eth.accounts[0]; if ( @@ -123,7 +124,7 @@ window.onload = function() { }; // Get bountyId from the database - var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + document.web3network; + var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + $('input[name=network]').val() + '&standard_bounties_id=' + $('input[name=standard_bounties_id]').val(); $.get(uri, apiCallback); } diff --git a/app/assets/v2/js/pages/new_bounty.js b/app/assets/v2/js/pages/new_bounty.js index 627984939e0..34c1a97eadf 100644 --- a/app/assets/v2/js/pages/new_bounty.js +++ b/app/assets/v2/js/pages/new_bounty.js @@ -305,41 +305,28 @@ $(document).ready(function() { web3Callback // callback for web3 ); } - // Check if the bounty already exists - var uri = '/api/v0.1/bounties/?github_url=' + issueURL; - $.get(uri, function(results, status) { - results = sanitizeAPIResults(results); - var result = results[0]; - - if (result != null) { - _alert({ message: 'A bounty already exists for that Github Issue.' }); - unloading_button($('.js-submit')); - return; - } + var approve_success_callback = function(callback) { + // Add data to IPFS and kick off all the callbacks. + ipfsBounty.payload.issuer.address = account; + ipfs.addJson(ipfsBounty, newIpfsCallback); + }; - var approve_success_callback = function(callback) { - // Add data to IPFS and kick off all the callbacks. - ipfsBounty.payload.issuer.address = account; - ipfs.addJson(ipfsBounty, newIpfsCallback); - }; - - if (isETH) { - // no approvals needed for ETH - approve_success_callback(); - } else { - token_contract.approve( - bounty_address(), - amount, - { - from: account, - value: 0, - gasPrice: web3.toHex($('#gasPrice').val() * Math.pow(10, 9)) - }, - approve_success_callback - ); - } - }); + if (isETH) { + // no approvals needed for ETH + approve_success_callback(); + } else { + token_contract.approve( + bounty_address(), + amount, + { + from: account, + value: 0, + gasPrice: web3.toHex($('#gasPrice').val() * Math.pow(10, 9)) + }, + approve_success_callback + ); + } } }); }); diff --git a/app/assets/v2/js/pages/process_bounty.js b/app/assets/v2/js/pages/process_bounty.js index 7ffac7de91b..30f54038c13 100644 --- a/app/assets/v2/js/pages/process_bounty.js +++ b/app/assets/v2/js/pages/process_bounty.js @@ -2,6 +2,7 @@ window.onload = function() { // a little time for web3 injection setTimeout(function() { + waitforWeb3(actions_page_warn_if_not_on_same_network); var account = web3.eth.accounts[0]; if (getParam('source')) { @@ -176,7 +177,7 @@ window.onload = function() { // Get bountyId from the database waitforWeb3(function() { - var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + document.web3network; + var uri = '/api/v0.1/bounties/?github_url=' + issueURL + '&network=' + $('input[name=network]').val() + '&standard_bounties_id=' + $('input[name=standard_bounties_id]').val(); $.get(uri, apiCallback); }); diff --git a/app/assets/v2/js/shared.js b/app/assets/v2/js/shared.js index 0226aae0f2e..462d7e6a0e4 100644 --- a/app/assets/v2/js/shared.js +++ b/app/assets/v2/js/shared.js @@ -706,6 +706,21 @@ var listen_for_web3_changes = function() { } }; +var actions_page_warn_if_not_on_same_network = function() { + var user_network = document.web3network; + + if (typeof user_network == 'undefined') { + user_network = 'no network'; + } + var bounty_network = $('input[name=network]').val(); + + if (bounty_network != user_network) { + var msg = 'Warning: You are on ' + user_network + ' and this bounty is on the ' + bounty_network + ' network. Please change your network to the ' + bounty_network + ' network.'; + + _alert({message: gettext(msg)}, 'error'); + } +}; + $(document).ready(function() { sidebar_redirect_triggers(); attach_change_element_type(); diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 70c6c9cbc5f..33f086733b2 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -600,6 +600,21 @@ def fetch_issue_comments(self, save=True): self.save() return comments + @property + def action_urls(self): + """Provide URLs for bounty related actions. + + Returns: + dict: A dictionary of action URLS for this bounty. + + """ + return { + 'fulfill': f"/issue/fulfill/{self.pk}", + 'increase': f"/issue/increase/{self.pk}", + 'accept': f"/issue/accept/{self.pk}", + 'cancel': f"/issue/cancel/{self.pk}", + } + class BountyFulfillmentQuerySet(models.QuerySet): """Handle the manager queryset for BountyFulfillments.""" diff --git a/app/dashboard/router.py b/app/dashboard/router.py index c5252de8aa1..aa02202857e 100644 --- a/app/dashboard/router.py +++ b/app/dashboard/router.py @@ -75,7 +75,7 @@ class Meta: 'standard_bounties_id', 'web3_type', 'can_submit_after_expiration_date', 'github_issue_number', 'github_org_name', 'github_repo_name', 'idx_status', 'token_value_time_peg', 'fulfillment_accepted_on', 'fulfillment_submitted_on', - 'fulfillment_started_on', 'canceled_on', + 'fulfillment_started_on', 'canceled_on', 'action_urls', ) def create(self, validated_data): diff --git a/app/dashboard/templates/fulfill_bounty.html b/app/dashboard/templates/fulfill_bounty.html index 9468feeac2c..56b39aa9c60 100644 --- a/app/dashboard/templates/fulfill_bounty.html +++ b/app/dashboard/templates/fulfill_bounty.html @@ -45,7 +45,7 @@

{% trans "Submit Work" %}

- +
{% include 'shared/github_username.html' %} {% include 'shared/notification_email.html' %} @@ -57,6 +57,7 @@

{% trans "Submit Work" %}

+ {% include 'shared/bounty_actions_hidden_vars.html' %} {% include 'shared/wallet_estimate.html' %}