From 23aefccbe98d71ad45a5576c24f5f45ab309ce30 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Tue, 4 Aug 2020 11:21:16 +0900 Subject: [PATCH 01/46] Construct websocket uri for notification client side --- .../NotificationsNavItem.cshtml | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml b/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml index 3d005c68b..b4c1a78ef 100644 --- a/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml +++ b/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml @@ -1,12 +1,22 @@ -
+@inject LinkGenerator linkGenerator + +
@await Component.InvokeAsync("NotificationsDropdown") - + + + + + */ + +! function () { + "use strict"; + const pageElements = document.querySelector.bind(document), + insertElement = (document.querySelectorAll.bind(document), + (e, + n) => { + n.parentNode.insertBefore(e, + n.nextSibling) + }); + + let pageItems = {}, + pageheader = "Thank you!", + buttonElement = null; + + const setPageItems = () => { + pageItems = { + mainHeader: pageElements("#main-header"), + orderConfirmed: pageElements(".os-step__title"), + orderConfirmedDescription: pageElements(".os-step__description"), + continueButton: pageElements(".step__footer__continue-btn"), + checkMarkIcon: pageElements(".os-header__hanging-icon"), + orderStatus: pageElements(".os-header__title"), + paymentMethod: pageElements(".payment-method-list__item__info"), + price: pageElements(".payment-due__price"), + finalPrice: pageElements(".total-recap__final-price"), + orderNumber: pageElements(".os-order-number"), + } + } + + const orderPaid = () => { + pageItems.mainHeader.innerText = pageheader, + pageItems.orderConfirmed && (pageItems.orderConfirmed.style.display = "block"), + pageItems.orderConfirmedDescription && (pageItems.orderConfirmedDescription.style.display = "block"), + pageItems.continueButton && (pageItems.continueButton.style.visibility = "visible"), + pageItems.checkMarkIcon && (pageItems.checkMarkIcon.style.visibility = "visible"), + buttonElement && (buttonElement.style.display = "none"); + }; + + window.setOrderAsPaid = orderPaid, + window.openBtcPayShopify = function waitForPaymentMethod() { + if (setPageItems(), "Order canceled" === pageItems.orderStatus.innerText) { + return; + } + + const paymentMethod = pageItems.paymentMethod; + + if (null === paymentMethod) { + return void setTimeout(() => { + waitForPaymentMethod(); + }, 10); + } + + if (-1 === paymentMethod.innerText.toLowerCase().indexOf("bitcoin")) return; + + // If payment method is bitcoin, display instructions and payment button. + pageheader = pageItems.mainHeader.innerText, + pageItems.mainHeader && (pageItems.mainHeader.innerText = "Review and pay!"), + pageItems.continueButton && (pageItems.continueButton.style.visibility = "hidden"), + pageItems.checkMarkIcon && (pageItems.checkMarkIcon.style.visibility = "hidden"), + pageItems.orderConfirmed && (pageItems.orderConfirmed.style.display = "none"), + pageItems.orderConfirmedDescription && (pageItems.orderConfirmedDescription.style.display = "none"), + buttonElement = document.createElement("div"); + + const priceElement = pageItems.finalPrice || pageItems.price; + var price = priceElement.innerText.replace(DEFAULT_CURRENCY_SYMBOL, "").replace(THOUSAND_DELIMITER, ""); + if (THOUSAND_DELIMITER === ".") { + price = price.replace(",", "."); // 5.000,00 needs to become 5000.00 + } + const orderId = pageItems.orderNumber.innerText.replace("Order #", ""); + + const url = BTCPAYSERVER_URL + "/invoices" + "?storeId=" + STORE_ID + "&orderId=" + orderId + "&status=complete"; + + // Check if already paid. + fetch(url, { + method: "GET", + mode: "cors", // no-cors, cors, *same-origin, + headers: { + "Content-Type": "application/json", + "accept": "application/json", + }, + }) + .then(function (response) { + return response.json(); + }) + .then(function (json) { + return json.data; + }) + .then(function (data) { + if (data.length != 0) { + orderPaid(); + } + }); + + window.waitForPayment = function () { + BtcPayServerModal.show( + BTCPAYSERVER_URL, + STORE_ID, + { + price: price, + currency: DEFAULT_CURRENCY, + orderId: orderId + } + ) + .then(function (invoice) { + if (invoice != null) { + orderPaid(); + } + }); + } + + // Payment button that opens modal + buttonElement.innerHTML = `\n \n`, + insertElement(buttonElement, pageItems.orderConfirmed); + + } + + window.openBtcPayShopify(); +}(); From f73c912945cc61b3ded3681f609e76c0d37a6efb Mon Sep 17 00:00:00 2001 From: rockstardev Date: Sat, 8 Aug 2020 11:14:45 -0500 Subject: [PATCH 25/46] Simplifying script by getting variables from Shopify object --- .../wwwroot/shopify/btcpay-shopify-checkout.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js index c736b9315..a4d8c494c 100644 --- a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js +++ b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js @@ -8,9 +8,6 @@ @@ -19,6 +16,10 @@ */ ! function () { + // extracted from shopify initialized page + const shopify_price = Shopify.checkout.payment_due; + const shopify_currency = Shopify.checkout.currency; + "use strict"; const pageElements = document.querySelector.bind(document), insertElement = (document.querySelectorAll.bind(document), @@ -81,11 +82,6 @@ pageItems.orderConfirmedDescription && (pageItems.orderConfirmedDescription.style.display = "none"), buttonElement = document.createElement("div"); - const priceElement = pageItems.finalPrice || pageItems.price; - var price = priceElement.innerText.replace(DEFAULT_CURRENCY_SYMBOL, "").replace(THOUSAND_DELIMITER, ""); - if (THOUSAND_DELIMITER === ".") { - price = price.replace(",", "."); // 5.000,00 needs to become 5000.00 - } const orderId = pageItems.orderNumber.innerText.replace("Order #", ""); const url = BTCPAYSERVER_URL + "/invoices" + "?storeId=" + STORE_ID + "&orderId=" + orderId + "&status=complete"; @@ -116,8 +112,8 @@ BTCPAYSERVER_URL, STORE_ID, { - price: price, - currency: DEFAULT_CURRENCY, + price: shopify_price, + currency: shopify_currency, orderId: orderId } ) From c79e79a5b6cec678daa7f452078a15ba65975a24 Mon Sep 17 00:00:00 2001 From: rockstardev Date: Sat, 8 Aug 2020 11:22:59 -0500 Subject: [PATCH 26/46] Making js variables easier to select with double click --- .../wwwroot/shopify/btcpay-shopify-checkout.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js index a4d8c494c..11728eeed 100644 --- a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js +++ b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js @@ -6,12 +6,12 @@ 2. In Shopify Settings > Payment Providers > Manual Payment Methods add one which contains "Bitcoin" 3. In Shopify Settings > Checkout > Additional Scripts input the following script, with the details from your BTCPayServer instead of the placeholder values. - - - + + + */ From c6d72f0487604c5417b7412e63383611fb8292c1 Mon Sep 17 00:00:00 2001 From: rockstardev Date: Sun, 9 Aug 2020 07:18:00 -0500 Subject: [PATCH 27/46] Hiding pay button after click --- .../wwwroot/shopify/btcpay-shopify-checkout.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js index 11728eeed..3cb748ca9 100644 --- a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js +++ b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js @@ -79,8 +79,7 @@ pageItems.continueButton && (pageItems.continueButton.style.visibility = "hidden"), pageItems.checkMarkIcon && (pageItems.checkMarkIcon.style.visibility = "hidden"), pageItems.orderConfirmed && (pageItems.orderConfirmed.style.display = "none"), - pageItems.orderConfirmedDescription && (pageItems.orderConfirmedDescription.style.display = "none"), - buttonElement = document.createElement("div"); + pageItems.orderConfirmedDescription && (pageItems.orderConfirmedDescription.style.display = "none"); const orderId = pageItems.orderNumber.innerText.replace("Order #", ""); @@ -108,6 +107,7 @@ }); window.waitForPayment = function () { + buttonElement.innerHTML = "Loading Invoice..."; BtcPayServerModal.show( BTCPAYSERVER_URL, STORE_ID, @@ -118,6 +118,7 @@ } ) .then(function (invoice) { + buttonElement.innerHTML = payButtonHtml; if (invoice != null) { orderPaid(); } @@ -125,8 +126,11 @@ } // Payment button that opens modal - buttonElement.innerHTML = `\n \n`, - insertElement(buttonElement, pageItems.orderConfirmed); + const payButtonHtml = ''; + + buttonElement = document.createElement("div"); + buttonElement.innerHTML = payButtonHtml; + insertElement(buttonElement, pageItems.orderConfirmed); } From 0de8cbfd45936872febb38677c81e81a27cb5120 Mon Sep 17 00:00:00 2001 From: rockstardev Date: Sun, 9 Aug 2020 07:46:37 -0500 Subject: [PATCH 28/46] Final tweaking of UI for first version --- BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js index 3cb748ca9..54203f898 100644 --- a/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js +++ b/BTCPayServer/wwwroot/shopify/btcpay-shopify-checkout.js @@ -3,7 +3,7 @@ /* 1. In your BTCPayServer store you need to check "Allow anyone to create invoice" -2. In Shopify Settings > Payment Providers > Manual Payment Methods add one which contains "Bitcoin" +2. In Shopify Settings > Payment Providers > Manual Payment Methods add one which contains "Bitcoin with BTCPayServer" 3. In Shopify Settings > Checkout > Additional Scripts input the following script, with the details from your BTCPayServer instead of the placeholder values. diff --git a/BTCPayServer/Components/NotificationsDropdown/NoticationsDropdown.cs b/BTCPayServer/Components/NotificationsDropdown/NoticationsDropdown.cs new file mode 100644 index 000000000..3cff8e623 --- /dev/null +++ b/BTCPayServer/Components/NotificationsDropdown/NoticationsDropdown.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using BTCPayServer.Services.Notifications; +using Microsoft.AspNetCore.Mvc; + +namespace BTCPayServer.Components.NotificationsDropdown +{ + public class NotificationsDropdown : ViewComponent + { + private readonly NotificationManager _notificationManager; + + public NotificationsDropdown(NotificationManager notificationManager) + { + _notificationManager = notificationManager; + } + + public async Task InvokeAsync() + { + return View(await _notificationManager.GetSummaryNotifications(UserClaimsPrincipal)); + } + } +} diff --git a/BTCPayServer/Components/NotificationsDropdown/NotificationSummaryViewModel.cs b/BTCPayServer/Components/NotificationsDropdown/NotificationSummaryViewModel.cs new file mode 100644 index 000000000..41eaf556c --- /dev/null +++ b/BTCPayServer/Components/NotificationsDropdown/NotificationSummaryViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using BTCPayServer.Models.NotificationViewModels; + +namespace BTCPayServer.Components.NotificationsDropdown +{ + public class NotificationSummaryViewModel + { + public int UnseenCount { get; set; } + public List Last5 { get; set; } + } +} diff --git a/BTCPayServer/Views/Shared/_TableFooterPager.cshtml b/BTCPayServer/Components/Pager/Default.cshtml similarity index 100% rename from BTCPayServer/Views/Shared/_TableFooterPager.cshtml rename to BTCPayServer/Components/Pager/Default.cshtml diff --git a/BTCPayServer/Components/Pager/Pager.cs b/BTCPayServer/Components/Pager/Pager.cs new file mode 100644 index 000000000..9cb40cda5 --- /dev/null +++ b/BTCPayServer/Components/Pager/Pager.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using BTCPayServer.Models; +using Microsoft.AspNetCore.Mvc; + +namespace BTCPayServer.Components +{ + public class Pager : ViewComponent + { + public Pager() + { + } + public IViewComponentResult Invoke(BasePagingViewModel viewModel) + { + return View(viewModel); + } + } +} diff --git a/BTCPayServer/Controllers/NotificationsController.cs b/BTCPayServer/Controllers/NotificationsController.cs index 4a664d9e9..b8c01f687 100644 --- a/BTCPayServer/Controllers/NotificationsController.cs +++ b/BTCPayServer/Controllers/NotificationsController.cs @@ -15,22 +15,6 @@ using Microsoft.AspNetCore.Mvc; namespace BTCPayServer.Controllers { - - public class NotificationsDropdown : ViewComponent - { - private readonly NotificationManager _notificationManager; - - public NotificationsDropdown(NotificationManager notificationManager) - { - _notificationManager = notificationManager; - } - - public async Task InvokeAsync(int noOfEmployee) - { - return View(await _notificationManager.GetSummaryNotifications(UserClaimsPrincipal)); - } - } - [BitpayAPIConstraint(false)] [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] [Route("[controller]/[action]")] diff --git a/BTCPayServer/Hosting/Startup.cs b/BTCPayServer/Hosting/Startup.cs index ec7765212..dfe61389c 100644 --- a/BTCPayServer/Hosting/Startup.cs +++ b/BTCPayServer/Hosting/Startup.cs @@ -81,6 +81,12 @@ namespace BTCPayServer.Hosting return builtInFactory(context); }; }) + .AddRazorOptions(o => + { + // /Components/{View Component Name}/{View Name}.cshtml + o.ViewLocationFormats.Add("/{0}.cshtml"); + o.PageViewLocationFormats.Add("/{0}.cshtml"); + }) .AddNewtonsoftJson() #if RAZOR_RUNTIME_COMPILE .AddRazorRuntimeCompilation() diff --git a/BTCPayServer/Services/Notifications/NotificationManager.cs b/BTCPayServer/Services/Notifications/NotificationManager.cs index b3965d524..36379732a 100644 --- a/BTCPayServer/Services/Notifications/NotificationManager.cs +++ b/BTCPayServer/Services/Notifications/NotificationManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using BTCPayServer.Components.NotificationsDropdown; using BTCPayServer.Data; using BTCPayServer.Models.NotificationViewModels; using Microsoft.AspNetCore.Identity; @@ -124,10 +125,4 @@ namespace BTCPayServer.Services.Notifications throw new InvalidOperationException($"No INotificationHandler found for {blobType.Name}"); } } - - public class NotificationSummaryViewModel - { - public int UnseenCount { get; set; } - public List Last5 { get; set; } - } } diff --git a/BTCPayServer/Views/Invoice/ListInvoices.cshtml b/BTCPayServer/Views/Invoice/ListInvoices.cshtml index 3fd231d38..81bb2b967 100644 --- a/BTCPayServer/Views/Invoice/ListInvoices.cshtml +++ b/BTCPayServer/Views/Invoice/ListInvoices.cshtml @@ -5,16 +5,17 @@ @section HeadScripts { } + @Html.HiddenFor(a => a.Count)
@if (TempData.HasStatusMessage()) { -
-
- -
+
+
+
+
}
@@ -49,7 +50,7 @@
- +
@@ -99,7 +100,7 @@
- +