Merge pull request #516 from Kukks/feature/crowdfund

Crowdfund Bug fixes
This commit is contained in:
Nicolas Dorier 2019-01-15 23:57:29 +09:00 committed by GitHub
commit 8f896de794
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 150 additions and 90 deletions

View file

@ -5,6 +5,7 @@ using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Controllers; using BTCPayServer.Controllers;
using BTCPayServer.Crowdfund;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events; using BTCPayServer.Events;
using BTCPayServer.Hubs; using BTCPayServer.Hubs;

View file

@ -6,6 +6,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Crowdfund;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Filters; using BTCPayServer.Filters;
using BTCPayServer.Hubs; using BTCPayServer.Hubs;

View file

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Controllers; using BTCPayServer.Controllers;
using BTCPayServer.Models.AppViewModels; using BTCPayServer.Models.AppViewModels;
@ -35,7 +36,11 @@ namespace BTCPayServer.Hubs
{ {
model.RedirectToCheckout = false; model.RedirectToCheckout = false;
_AppsPublicController.ControllerContext.HttpContext = Context.GetHttpContext(); _AppsPublicController.ControllerContext.HttpContext = Context.GetHttpContext();
var result = await _AppsPublicController.ContributeToCrowdfund(Context.Items["app"].ToString(), model); try
{
var result =
await _AppsPublicController.ContributeToCrowdfund(Context.Items["app"].ToString(), model);
switch (result) switch (result)
{ {
case OkObjectResult okObjectResult: case OkObjectResult okObjectResult:
@ -48,6 +53,12 @@ namespace BTCPayServer.Hubs
await Clients.Caller.SendCoreAsync(InvoiceError, System.Array.Empty<object>()); await Clients.Caller.SendCoreAsync(InvoiceError, System.Array.Empty<object>());
break; break;
} }
}
catch (Exception)
{
await Clients.Caller.SendCoreAsync(InvoiceError, System.Array.Empty<object>());
}
} }

View file

@ -2,11 +2,11 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Controllers; using BTCPayServer.Controllers;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events; using BTCPayServer.Events;
using BTCPayServer.Hubs;
using BTCPayServer.Models.AppViewModels; using BTCPayServer.Models.AppViewModels;
using BTCPayServer.Payments; using BTCPayServer.Payments;
using BTCPayServer.Rating; using BTCPayServer.Rating;
@ -16,14 +16,11 @@ using BTCPayServer.Services.Rates;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using NBitcoin; using NBitcoin;
using YamlDotNet.Core;
namespace BTCPayServer.Hubs namespace BTCPayServer.Crowdfund
{ {
public class public class CrowdfundHubStreamer: IDisposable
CrowdfundHubStreamer
{ {
public const string CrowdfundInvoiceOrderIdPrefix = "crowdfund-app_"; public const string CrowdfundInvoiceOrderIdPrefix = "crowdfund-app_";
private readonly EventAggregator _EventAggregator; private readonly EventAggregator _EventAggregator;
@ -38,6 +35,8 @@ namespace BTCPayServer.Hubs
private readonly ConcurrentDictionary<string,(string appId, bool useAllStoreInvoices,bool useInvoiceAmount)> _QuickAppInvoiceLookup = private readonly ConcurrentDictionary<string,(string appId, bool useAllStoreInvoices,bool useInvoiceAmount)> _QuickAppInvoiceLookup =
new ConcurrentDictionary<string, (string appId, bool useAllStoreInvoices, bool useInvoiceAmount)>(); new ConcurrentDictionary<string, (string appId, bool useAllStoreInvoices, bool useInvoiceAmount)>();
private List<IEventAggregatorSubscription> _Subscriptions;
public CrowdfundHubStreamer(EventAggregator eventAggregator, public CrowdfundHubStreamer(EventAggregator eventAggregator,
IHubContext<CrowdfundHub> hubContext, IHubContext<CrowdfundHub> hubContext,
IMemoryCache memoryCache, IMemoryCache memoryCache,
@ -116,13 +115,15 @@ namespace BTCPayServer.Hubs
private void SubscribeToEvents() private void SubscribeToEvents()
{ {
_Subscriptions = new List<IEventAggregatorSubscription>()
_EventAggregator.Subscribe<InvoiceEvent>(OnInvoiceEvent); {
_EventAggregator.Subscribe<InvoiceEvent>(OnInvoiceEvent),
_EventAggregator.Subscribe<AppsController.CrowdfundAppUpdated>(updated => _EventAggregator.Subscribe<AppsController.CrowdfundAppUpdated>(updated =>
{ {
UpdateLookup(updated.AppId, updated.StoreId, updated.Settings); UpdateLookup(updated.AppId, updated.StoreId, updated.Settings);
InvalidateCacheForApp(updated.AppId); InvalidateCacheForApp(updated.AppId);
}); })
};
} }
private string GetCacheKey(string appId) private string GetCacheKey(string appId)
@ -152,7 +153,7 @@ namespace BTCPayServer.Hubs
Enum.GetName(typeof(PaymentTypes), Enum.GetName(typeof(PaymentTypes),
invoiceEvent.Payment.GetPaymentMethodId().PaymentType) invoiceEvent.Payment.GetPaymentMethodId().PaymentType)
} ); } );
_Logger.LogInformation($"App {quickLookup.appId}: Received Payment");
InvalidateCacheForApp(quickLookup.appId); InvalidateCacheForApp(quickLookup.appId);
break; break;
case InvoiceEvent.Created: case InvoiceEvent.Created:
@ -361,5 +362,10 @@ namespace BTCPayServer.Hubs
StartDate = startDate StartDate = startDate
}); });
} }
public void Dispose()
{
_Subscriptions.ForEach(subscription => subscription.Dispose());
}
} }
} }

View file

@ -38,6 +38,7 @@ using BTCPayServer.Logging;
using BTCPayServer.HostedServices; using BTCPayServer.HostedServices;
using Meziantou.AspNetCore.BundleTagHelpers; using Meziantou.AspNetCore.BundleTagHelpers;
using System.Security.Claims; using System.Security.Claims;
using BTCPayServer.Crowdfund;
using BTCPayServer.Hubs; using BTCPayServer.Hubs;
using BTCPayServer.Payments.Changelly; using BTCPayServer.Payments.Changelly;
using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.Lightning;

View file

@ -1,4 +1,5 @@
@using BTCPayServer.Hubs @using BTCPayServer.Crowdfund
@using BTCPayServer.Hubs
@addTagHelper *, Meziantou.AspNetCore.BundleTagHelpers @addTagHelper *, Meziantou.AspNetCore.BundleTagHelpers
@model UpdateCrowdfundViewModel @model UpdateCrowdfundViewModel
@{ @{

View file

@ -1,41 +1,48 @@
<div class="container p-0" id="app" v-cloak> <div class="container p-0" id="app" v-cloak>
<div class="row h-100 w-100 py-sm-0 py-md-4 mx-0"> <div class="row h-100 w-100 py-sm-0 py-md-4 mx-0">
<div class="card w-100 p-0 mx-0"> <div class="card w-100 p-0 mx-0">
<img class="card-img-top" :src="srvModel.mainImageUrl" v-if="srvModel.mainImageUrl"> <img class="card-img-top" :src="srvModel.mainImageUrl" v-if="srvModel.mainImageUrl" id="crowdfund-main-image">
<div class="d-flex justify-content-between px-2"> <div class="d-flex justify-content-between px-2" id="crowdfund-header-container">
<h1> <h1>
{{srvModel.title}} {{srvModel.title}}
<span class="h6 text-muted" v-if="!started && srvModel.startDate" v-b-tooltip :title="startDate"> <span class="h6 text-muted" v-if="!started && srvModel.startDate" v-b-tooltip :title="startDate" id="crowdfund-header-start-date">
Starts {{startDateRelativeTime}} Starts {{startDateRelativeTime}}
</span> </span>
<span class="h6 text-muted" v-else-if="started && !ended && srvModel.endDate" v-b-tooltip :title="endDate"> <span class="h6 text-muted" v-else-if="started && !ended && srvModel.endDate" v-b-tooltip :title="endDate" id="crowdfund-header-end-date">
Ends {{endDateRelativeTime}} Ends {{endDateRelativeTime}}
</span> </span>
<span class="h6 text-muted" v-else-if="started && !ended && !srvModel.endDate" v-b-tooltip title="No set end date"> <span class="h6 text-muted" v-else-if="started && !ended && !srvModel.endDate" v-b-tooltip title="No set end date" id="crowdfund-header-active">
Currently Active! Currently Active!
</span> </span>
</h1> </h1>
<span v-if="srvModel.targetAmount" class="mt-3"> <span v-if="srvModel.targetAmount" class="mt-3" id="crowdfund-header-target">
<span class="h5">{{srvModel.targetAmount}} {{targetCurrency}}</span> <span class="h5" id="crowdfund-header-target-amount">{{srvModel.targetAmount}} {{targetCurrency}}</span>
<span v-if="srvModel.resetEvery !== 'Never'" v-b-tooltip <span v-if="srvModel.resetEvery !== 'Never'"
id="crowdfund-header-target-dynamic"
v-b-tooltip
:title="'Goal resets every ' + srvModel.resetEveryAmount + ' ' + srvModel.resetEvery + ((srvModel.resetEveryAmount>1)?'s': '')" >Dynamic </span> :title="'Goal resets every ' + srvModel.resetEveryAmount + ' ' + srvModel.resetEvery + ((srvModel.resetEveryAmount>1)?'s': '')" >Dynamic </span>
<span v-if="srvModel.enforceTargetAmount">Hardcap Goal <span class="fa fa-question-circle" v-b-tooltip title="No contributions allowed after the goal has been reached"></span></span> <span v-if="srvModel.enforceTargetAmount"
<span v-else>Softcap Goal <span class="fa fa-question-circle" v-b-tooltip title="Contributions allowed even after goal is reached"></span> </span> id="crowdfund-header-target-softcap">Hardcap Goal <span class="fa fa-question-circle" v-b-tooltip title="No contributions allowed after the goal has been reached"></span></span>
<span v-else
id="crowdfund-header-target-hardcap">Softcap Goal <span class="fa fa-question-circle" v-b-tooltip title="Contributions allowed even after goal is reached"></span> </span>
</span> </span>
</div> </div>
<div class="progress w-100 rounded-0 " v-if="srvModel.targetAmount"> <div class="progress w-100 rounded-0 " v-if="srvModel.targetAmount"
id="crowdfund-progress-bar">
<div class="progress-bar" role="progressbar" <div class="progress-bar" role="progressbar"
:aria-valuenow="srvModel.info.progressPercentage" :aria-valuenow="srvModel.info.progressPercentage"
v-bind:style="{ width: srvModel.info.progressPercentage + '%' }" v-bind:style="{ width: srvModel.info.progressPercentage + '%' }"
aria-valuemin="0" aria-valuemin="0"
id="crowdfund-progress-bar-confirmed-bar"
v-b-tooltip :title="parseFloat(srvModel.info.progressPercentage).toFixed(2) + '% contributions'" v-b-tooltip :title="parseFloat(srvModel.info.progressPercentage).toFixed(2) + '% contributions'"
aria-valuemax="100"> aria-valuemax="100">
</div> </div>
<div class="progress-bar bg-warning" role="progressbar" <div class="progress-bar bg-warning" role="progressbar"
id="crowdfund-progress-bar-pending-bar"
:aria-valuenow="srvModel.info.pendingProgressPercentage" :aria-valuenow="srvModel.info.pendingProgressPercentage"
v-bind:style="{ width: srvModel.info.pendingProgressPercentage + '%' }" v-bind:style="{ width: srvModel.info.pendingProgressPercentage + '%' }"
v-b-tooltip :title="parseFloat(srvModel.info.pendingProgressPercentage).toFixed(2) + '% contributions pending confirmation'" v-b-tooltip :title="parseFloat(srvModel.info.pendingProgressPercentage).toFixed(2) + '% contributions pending confirmation'"
@ -45,29 +52,27 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row py-2 text-center"> <div class="row py-2 text-center">
<div class="col-sm border-right" id="raised-amount"> <div class="col-sm border-right" id="crowdfund-body-raised-amount">
<h5>{{ raisedAmount }} {{targetCurrency}} </h5> <h5>{{ raisedAmount }} {{targetCurrency}} </h5>
<h5 class="text-muted">Raised</h5> <h5 class="text-muted">Raised</h5>
</div> </div>
<div class="col-sm border-right" id="goal-raised"> <div class="col-sm border-right" id="crowdfund-body-goal-raised">
<h5>{{ percentageRaisedAmount }}%</h5> <h5>{{ percentageRaisedAmount }}%</h5>
<h5 class="text-muted">Of Goal</h5> <h5 class="text-muted">Of Goal</h5>
</div> </div>
<div class="col-sm border-right"> <div class="col-sm border-right" id="crowdfund-body-total-contributors">
<h5> <h5>
{{srvModel.info.totalContributors}} {{srvModel.info.totalContributors}}
</h5> </h5>
<h5 class="text-muted">Contributors</h5> <h5 class="text-muted">Contributors</h5>
</div> </div>
<div class="col-sm" v-if="endDiff" id="campaign-dates-started"> <div class="col-sm" v-if="endDiff" id="crowdfund-body-campaign-dates-started">
<h5> <h5>
{{endDiff}} {{endDiff}}
</h5> </h5>
<h5 class="text-muted">Left</h5> <h5 class="text-muted">Left</h5>
<b-tooltip target="campaign-dates-started" > <b-tooltip target="crowdfund-body-campaign-dates-started" >
<ul class="p-0"> <ul class="p-0">
<li v-if="startDate" class="list-unstyled"> <li v-if="startDate" class="list-unstyled">
{{started? "Started" : "Starts"}} {{startDate}} {{started? "Started" : "Starts"}} {{startDate}}
@ -78,13 +83,13 @@
</ul> </ul>
</b-tooltip> </b-tooltip>
</div> </div>
<div class="col-sm" v-if="startDiff" id="campaign-dates-not-started"> <div class="col-sm" v-if="startDiff" id="crowdfund-body-campaign-dates-not-started">
<h5> <h5>
{{startDiff}} {{startDiff}}
</h5> </h5>
<h5 class="text-muted">Left to start</h5> <h5 class="text-muted">Left to start</h5>
<b-tooltip target="campaign-dates-ended" > <b-tooltip target="crowdfund-body-campaign-dates-not-started" >
<ul class="p-0"> <ul class="p-0">
<li v-if="startDate" class="list-unstyled"> <li v-if="startDate" class="list-unstyled">
{{started? "Started" : "Starts"}} {{startDate}} {{started? "Started" : "Starts"}} {{startDate}}
@ -95,13 +100,13 @@
</ul> </ul>
</b-tooltip> </b-tooltip>
</div> </div>
<div class="col-sm" v-if="ended" id="campaign-dates-ended"> <div class="col-sm" v-if="ended" id="crowdfund-body-campaign-dates-not-active">
<h5> <h5>
Campaign Campaign
</h5> </h5>
<h5 >not active</h5> <h5 >not active</h5>
<b-tooltip target="campaign-dates-not-started" > <b-tooltip target="crowdfund-body-campaign-dates-not-active" >
<ul class="p-0"> <ul class="p-0">
<li v-if="startDate" class="list-unstyled"> <li v-if="startDate" class="list-unstyled">
{{started? "Started" : "Starts"}} {{startDate}} {{started? "Started" : "Starts"}} {{startDate}}
@ -111,14 +116,10 @@
</li> </li>
</ul> </ul>
</b-tooltip> </b-tooltip>
</div> </div>
</div> </div>
<b-tooltip target="raised-amount" v-if="paymentStats && paymentStats.length > 0"> <b-tooltip target="crowdfund-body-raised-amount" v-if="paymentStats && paymentStats.length > 0">
<ul class="p-0 text-uppercase"> <ul class="p-0 text-uppercase">
<li v-for="stat of paymentStats" class="list-unstyled"> <li v-for="stat of paymentStats" class="list-unstyled">
@ -126,37 +127,34 @@
</li> </li>
</ul> </ul>
</b-tooltip> </b-tooltip>
<b-tooltip target="goal-raised" v-if="srvModel.resetEvery !== 'Never'"> <b-tooltip target="crowdfund-body-goal-raised" v-if="srvModel.resetEvery !== 'Never'">
Goal resets every {{srvModel.resetEveryAmount}} {{srvModel.resetEvery}} {{srvModel.resetEveryAmount>1?'s': ''}} Goal resets every {{srvModel.resetEveryAmount}} {{srvModel.resetEvery}} {{srvModel.resetEveryAmount>1?'s': ''}}
</b-tooltip> </b-tooltip>
<div class="card-title"> <div class="card-title" id="crowdfund-body-header">
<div class="row"> <div class="row">
<div class="col-sm-12 col-md-8 col-lg-9"> <div class="col-sm-12 col-md-8 col-lg-9" id="crowdfund-body-header-tagline-container">
<h2 class="text-muted" v-if="srvModel.tagline" id="crowdfund-body-header-tagline">{{srvModel.tagline}}</h2>
<h2 class="text-muted" v-if="srvModel.tagline">{{srvModel.tagline}}</h2>
</div> </div>
<div class="col-sm-12 col-md-4 col-lg-3"> <div class="col-sm-12 col-md-4 col-lg-3" id="crowdfund-body-header-cta-container">
<button v-if="active" class="btn btn-lg btn-primary w-100 font-weight-bold" v-on:click="contributeModalOpen = true">Contribute</button> <button v-if="active" id="crowdfund-body-header-cta" class="btn btn-lg btn-primary w-100 font-weight-bold" v-on:click="contributeModalOpen = true">Contribute</button>
</div> </div>
</div> </div>
</div> </div>
<template v-if="srvModel.disqusEnabled"> <template v-if="srvModel.disqusEnabled">
<b-tabs> <b-tabs>
<b-tab title="Details"active> <b-tab title="Details"active>
<div class="row "> <div class="row mt-2">
<div class="col-md-8 col-sm-12"> <div class="col-md-8 col-sm-12" id="crowdfund-body-description-container">
<div class="card-text overflow-hidden" v-html="srvModel.description"></div> <div class="card-text overflow-hidden" v-html="srvModel.description" id="crowdfund-body-description"></div>
</div> </div>
<div class="col-md-4 col-sm-12"> <div class="col-md-4 col-sm-12" id="crowdfund-body-contribution-container">
<contribute :target-currency="srvModel.targetCurrency" <contribute :target-currency="srvModel.targetCurrency"
:display-perks-ranking="srvModel.displayPerksRanking" :display-perks-ranking="srvModel.displayPerksRanking"
:active="active" :active="active"
:loading="loading"
:in-modal="false" :in-modal="false"
:perks="perks"> :perks="perks">
@ -173,11 +171,12 @@
<template v-else> <template v-else>
<hr/> <hr/>
<div class="row mt-2"> <div class="row mt-2">
<div class="col-md-8 col-sm-12"> <div class="col-md-8 col-sm-12" id="crowdfund-body-description-container">
<div class="card-text overflow-hidden" v-html="srvModel.description"></div> <div class="card-text overflow-hidden" v-html="srvModel.description" id="crowdfund-body-description"></div>
</div> </div>
<div class="col-md-4 col-sm-12"> <div class="col-md-4 col-sm-12" id="crowdfund-body-contribution-container">
<contribute :target-currency="srvModel.targetCurrency" <contribute :target-currency="srvModel.targetCurrency"
:loading="loading"
:display-perks-ranking="srvModel.displayPerksRanking" :display-perks-ranking="srvModel.displayPerksRanking"
:active="active" :active="active"
:in-modal="false" :in-modal="false"
@ -207,11 +206,11 @@
</div> </div>
</div> </div>
<b-modal title="Contribute" v-model="contributeModalOpen" size="lg" ok-only="true" ok-variant="secondary" ok-title="Close" ref="modalContribute"> <b-modal title="Contribute" v-model="contributeModalOpen" size="lg" ok-only="true" ok-variant="secondary" ok-title="Close" ref="modalContribute">
<contribute v-if="contributeModalOpen" <contribute v-if="contributeModalOpen"
:target-currency="srvModel.targetCurrency" :target-currency="srvModel.targetCurrency"
:active="active" :active="active"
:perks="srvModel.perks" :perks="srvModel.perks"
:loading="loading"
:in-modal="true"> :in-modal="true">
</contribute> </contribute>
</b-modal> </b-modal>
@ -219,11 +218,20 @@
</div> </div>
<script type="text/x-template" id="perks-template"> <script type="text/x-template" id="perks-template">
<div> <div class="perks-container">
<perk v-if="!perks || perks.length ===0" :perk="{title: 'Donate Custom Amount', price: { value: null}, custom: true}" :target-currency="targetCurrency" :active="active" <perk v-if="!perks || perks.length ===0"
:perk="{title: 'Donate Custom Amount', price: { value: null}, custom: true}"
:target-currency="targetCurrency"
:active="active"
:loading="loading"
:in-modal="inModal"> :in-modal="inModal">
</perk> </perk>
<perk v-for="(perk, index) in perks" :perk="perk" :target-currency="targetCurrency" :active="active" :display-perks-ranking="displayPerksRanking" :index="index" <perk v-for="(perk, index) in perks" :perk="perk" :key="perk.id"
:target-currency="targetCurrency"
:active="active"
:display-perks-ranking="displayPerksRanking"
:index="index"
:loading="loading"
:in-modal="inModal"> :in-modal="inModal">
</perk> </perk>
</div> </div>
@ -276,8 +284,12 @@
<span class='input-group-text'>{{targetCurrency}}</span> <span class='input-group-text'>{{targetCurrency}}</span>
<button <button
class="btn btn-primary" class="btn btn-primary"
:disabled="!active" v-bind:class="{ 'btn-disabled': loading}"
:disabled="!active || loading"
type="submit"> type="submit">
<div v-if="loading" class="spinner-grow spinner-grow-sm" role="status">
<span class="sr-only">Loading...</span>
</div>
Continue Continue
</button> </button>
</div> </div>
@ -297,6 +309,7 @@
<h3 v-if="!inModal" class="mb-3">Contribute</h3> <h3 v-if="!inModal" class="mb-3">Contribute</h3>
<perks <perks
:perks="perks" :perks="perks"
:loading="loading"
:in-modal="inModal" :in-modal="inModal"
:display-perks-ranking="displayPerksRanking" :display-perks-ranking="displayPerksRanking"
:target-currency="targetCurrency" :target-currency="targetCurrency"

View file

@ -18,17 +18,17 @@ addLoadEvent(function (ev) {
Vue.use(Toasted); Vue.use(Toasted);
Vue.component('contribute', { Vue.component('contribute', {
props: ["targetCurrency", "active", "perks", "inModal", "displayPerksRanking"], props: ["targetCurrency", "active", "perks", "inModal", "displayPerksRanking", "loading"],
template: "#contribute-template" template: "#contribute-template"
}); });
Vue.component('perks', { Vue.component('perks', {
props: ["perks", "targetCurrency", "active", "inModal","displayPerksRanking"], props: ["perks", "targetCurrency", "active", "inModal","displayPerksRanking", "loading"],
template: "#perks-template" template: "#perks-template"
}); });
Vue.component('perk', { Vue.component('perk', {
props: ["perk", "targetCurrency", "active", "inModal", "displayPerksRanking", "index"], props: ["perk", "targetCurrency", "active", "inModal", "displayPerksRanking", "index", "loading"],
template: "#perk-template", template: "#perk-template",
data: function () { data: function () {
return { return {
@ -46,24 +46,35 @@ addLoadEvent(function (ev) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
if(!this.active){ if(!this.active || this.loading){
return; return;
} }
eventAggregator.$emit("contribute", {amount: this.amount, choiceKey: this.perk.id}); eventAggregator.$emit("contribute", {amount: parseFloat(this.amount), choiceKey: this.perk.id});
}, },
expand: function(){ expand: function(){
if(this.canExpand){ if(this.canExpand){
this.expanded = true; this.expanded = true;
} }
},
setAmount: function (amount) {
this.amount = (amount || 0).noExponents();
this.expanded = false;
} }
}, },
mounted: function () { mounted: function () {
this.amount = this.perk.price.value; this.setAmount(this.perk.price.value);
},
watch: {
perk: function (newValue, oldValue) {
if (newValue.price.value != oldValue.price.value) {
this.setAmount(newValue.price.value);
} }
}
}
}); });
app = new Vue({ app = new Vue({
@ -84,8 +95,9 @@ addLoadEvent(function (ev) {
active: true, active: true,
animation: true, animation: true,
sound: true, sound: true,
lastUpdated:"" lastUpdated:"",
loading: false,
timeoutState: 0
} }
}, },
computed: { computed: {
@ -191,9 +203,11 @@ addLoadEvent(function (ev) {
this.active = this.started && !this.ended; this.active = this.started && !this.ended;
setTimeout(this.updateComputed, 1000); setTimeout(this.updateComputed, 1000);
}, },
submitModalContribute: function(e){ setLoading: function(val){
debugger; this.loading = val;
this.$refs.modalContribute.onContributeFormSubmit(e); if(this.timeoutState){
clearTimeout(this.timeoutState);
}
} }
}, },
mounted: function () { mounted: function () {
@ -207,8 +221,19 @@ addLoadEvent(function (ev) {
btcpay.showFrame(); btcpay.showFrame();
self.contributeModalOpen = false; self.contributeModalOpen = false;
self.setLoading(false);
});
eventAggregator.$on("contribute", function () {
self.setLoading(true);
self.timeoutState = setTimeout(function(){
self.setLoading(false);
},5000);
}); });
eventAggregator.$on("invoice-error", function(error){ eventAggregator.$on("invoice-error", function(error){
self.setLoading(false);
var msg = ""; var msg = "";
if(typeof error === "string"){ if(typeof error === "string"){
msg = error; msg = error;

View file

@ -52,4 +52,5 @@ canvas#fireworks {
left: -15px; left: -15px;
top: -15px; top: -15px;
padding-top: 5px; padding-top: 5px;
z-index: 1
} }