mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 06:21:44 +01:00
Checkout v2: Improve truncation of displayed addresses (#4924)
This commit is contained in:
parent
a0bb3ace61
commit
18e34b3cbe
7 changed files with 86 additions and 36 deletions
|
@ -64,9 +64,9 @@ namespace BTCPayServer.Tests
|
|||
var qrValue = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-qr-value");
|
||||
var address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-clipboard");
|
||||
var payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href");
|
||||
var copyAddress = s.Driver.FindElement(By.Id("Address_BTC")).GetAttribute("value");
|
||||
var copyAddress = s.Driver.FindElement(By.CssSelector("#Address_BTC .truncate-center-start")).Text;
|
||||
Assert.Equal($"bitcoin:{address}", payUrl);
|
||||
Assert.StartsWith("bcrt", s.Driver.FindElement(By.Id("Address_BTC")).GetAttribute("value"));
|
||||
Assert.StartsWith("bcrt", s.Driver.FindElement(By.CssSelector("#Address_BTC .truncate-center-start")).Text);
|
||||
Assert.DoesNotContain("lightning=", payUrl);
|
||||
Assert.Equal(address, copyAddress);
|
||||
Assert.Equal($"bitcoin:{address.ToUpperInvariant()}", qrValue);
|
||||
|
@ -86,7 +86,7 @@ namespace BTCPayServer.Tests
|
|||
{
|
||||
payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href");
|
||||
Assert.StartsWith("lightning:lnurl", payUrl);
|
||||
Assert.StartsWith("lnurl", s.Driver.WaitForElement(By.Id("Lightning_BTC")).GetAttribute("value"));
|
||||
Assert.StartsWith("lnurl", s.Driver.WaitForElement(By.CssSelector("#Lightning_BTC .truncate-center-start")).Text);
|
||||
s.Driver.ElementDoesNotExist(By.Id("Address_BTC"));
|
||||
});
|
||||
|
||||
|
@ -101,7 +101,7 @@ namespace BTCPayServer.Tests
|
|||
qrValue = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-qr-value");
|
||||
address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-clipboard");
|
||||
payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href");
|
||||
copyAddress = s.Driver.FindElement(By.Id("Lightning_BTC_LightningLike")).GetAttribute("value");
|
||||
copyAddress = s.Driver.FindElement(By.CssSelector("#Lightning_BTC_LightningLike .truncate-center-start")).Text;
|
||||
Assert.Equal($"lightning:{address}", payUrl);
|
||||
Assert.Equal(address, copyAddress);
|
||||
Assert.Equal($"lightning:{address.ToUpperInvariant()}", qrValue);
|
||||
|
@ -229,8 +229,8 @@ namespace BTCPayServer.Tests
|
|||
qrValue = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-qr-value");
|
||||
address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-clipboard");
|
||||
payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href");
|
||||
var copyAddressOnchain = s.Driver.FindElement(By.Id("Address_BTC")).GetAttribute("value");
|
||||
var copyAddressLightning = s.Driver.FindElement(By.Id("Lightning_BTC")).GetAttribute("value");
|
||||
var copyAddressOnchain = s.Driver.FindElement(By.CssSelector("#Address_BTC .truncate-center-start")).Text;
|
||||
var copyAddressLightning = s.Driver.FindElement(By.CssSelector("#Lightning_BTC .truncate-center-start")).Text;
|
||||
Assert.StartsWith($"bitcoin:{address}?amount=", payUrl);
|
||||
Assert.Contains("?amount=", payUrl);
|
||||
Assert.Contains("&lightning=", payUrl);
|
||||
|
@ -297,8 +297,8 @@ namespace BTCPayServer.Tests
|
|||
qrValue = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-qr-value");
|
||||
address = s.Driver.FindElement(By.CssSelector(".qr-container")).GetAttribute("data-clipboard");
|
||||
payUrl = s.Driver.FindElement(By.Id("PayInWallet")).GetAttribute("href");
|
||||
copyAddressOnchain = s.Driver.FindElement(By.Id("Address_BTC")).GetAttribute("value");
|
||||
copyAddressLightning = s.Driver.FindElement(By.Id("Lightning_BTC")).GetAttribute("value");
|
||||
copyAddressOnchain = s.Driver.FindElement(By.CssSelector("#Address_BTC .truncate-center-start")).Text;
|
||||
copyAddressLightning = s.Driver.FindElement(By.CssSelector("#Lightning_BTC .truncate-center-start")).Text;
|
||||
Assert.StartsWith($"bitcoin:{address}", payUrl);
|
||||
Assert.Contains("?lightning=lnurl", payUrl);
|
||||
Assert.DoesNotContain("amount=", payUrl);
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
@model BTCPayServer.Components.TruncateCenter.TruncateCenterViewModel
|
||||
<span class="truncate-center @Model.Classes">
|
||||
<span class="truncate-center-truncated" @(Model.Truncated != Model.Text ? $"data-bs-toggle=tooltip title={Model.Text}" : "")>@Model.Truncated</span>
|
||||
<span class="truncate-center-text">@Model.Text</span>
|
||||
@{
|
||||
var classes = string.IsNullOrEmpty(Model.Classes) ? string.Empty : Model.Classes.Trim();
|
||||
@if (Model.Copy) classes += " truncate-center--copy";
|
||||
@if (Model.Elastic) classes += " truncate-center--elastic";
|
||||
}
|
||||
<span class="truncate-center @classes">
|
||||
@if (Model.IsVue)
|
||||
{
|
||||
<span class="truncate-center-truncated" data-bs-toggle="tooltip" :title=@Safe.Json(Model.Text)>
|
||||
<span class="truncate-center-start" v-text=@Safe.Json(Model.Text)></span>
|
||||
<span class="truncate-center-end" v-text=@Safe.Json($"{Model.Text}.slice(-{Model.Padding})")></span>
|
||||
</span>
|
||||
<span class="truncate-center-text" v-text=@Safe.Json(Model.Text)></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="truncate-center-truncated" @(!string.IsNullOrEmpty(Model.Start) ? $"data-bs-toggle=tooltip title={Model.Text}" : "")>
|
||||
<span class="truncate-center-start">@(Model.Elastic ? Model.Text : $"{Model.Start}…")</span>
|
||||
<span class="truncate-center-end">@Model.End</span>
|
||||
</span>
|
||||
<span class="truncate-center-text">@Model.Text</span>
|
||||
}
|
||||
@if (Model.Copy)
|
||||
{
|
||||
<button type="button" class="btn btn-link p-0" data-clipboard="@Model.Text">
|
||||
<button type="button" class="btn btn-link p-0" @(Model.IsVue ? ":" : string.Empty)data-clipboard=@Safe.Json(Model.Text)>
|
||||
<vc:icon symbol="copy" />
|
||||
</button>
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BTCPayServer.Components.TruncateCenter;
|
|||
/// <returns>HTML with truncated string</returns>
|
||||
public class TruncateCenter : ViewComponent
|
||||
{
|
||||
public IViewComponentResult Invoke(string text, string link = null, string classes = null, int padding = 7, bool copy = true)
|
||||
public IViewComponentResult Invoke(string text, string link = null, string classes = null, int padding = 7, bool copy = true, bool elastic = false, bool isVue = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return new HtmlContentViewComponentResult(new StringHtmlContent(string.Empty));
|
||||
|
@ -23,11 +23,17 @@ public class TruncateCenter : ViewComponent
|
|||
{
|
||||
Classes = classes,
|
||||
Padding = padding,
|
||||
Elastic = elastic,
|
||||
IsVue = isVue,
|
||||
Copy = copy,
|
||||
Text = text,
|
||||
Link = link,
|
||||
Truncated = text.Length > 2 * padding ? $"{text[..padding]}…{text[^padding..]}" : text
|
||||
Link = link
|
||||
};
|
||||
if (!isVue && text.Length > 2 * padding)
|
||||
{
|
||||
vm.Start = text[..padding];
|
||||
vm.End = text[^padding..];
|
||||
}
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@ namespace BTCPayServer.Components.TruncateCenter
|
|||
public class TruncateCenterViewModel
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public string Truncated { get; set; }
|
||||
public string Start { get; set; }
|
||||
public string End { get; set; }
|
||||
public string Classes { get; set; }
|
||||
public string Link { get; set; }
|
||||
public int Padding { get; set; }
|
||||
public bool Copy { get; set; }
|
||||
public bool Elastic { get; set; }
|
||||
public bool IsVue { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
@using BTCPayServer.BIP78.Sender
|
||||
@using BTCPayServer.Components.TruncateCenter
|
||||
@using BTCPayServer.Abstractions.TagHelpers
|
||||
@model BTCPayServer.Models.InvoicingModels.PaymentModel
|
||||
|
||||
<template id="bitcoin-method-checkout-template">
|
||||
|
@ -11,22 +13,16 @@
|
|||
<img class="qr-icon" :src="model.cryptoImage" :alt="model.paymentMethodName"/>
|
||||
</div>
|
||||
<div v-if="model.btcAddress" class="input-group mt-3">
|
||||
<div class="form-floating">
|
||||
<input id="Address_@Model.PaymentMethodId" class="form-control-plaintext" readonly="readonly" :value="model.btcAddress">
|
||||
<label for="Address_@Model.PaymentMethodId" v-t="{ path: 'address', args: { paymentMethod: model.paymentMethodName }}"></label>
|
||||
<div class="form-floating" id="Address_@Model.PaymentMethodId">
|
||||
<vc:truncate-center text="model.btcAddress" is-vue="true" padding="15" elastic="true" classes="form-control-plaintext" />
|
||||
<label v-t="{ path: 'address', args: { paymentMethod: model.paymentMethodName }}"></label>
|
||||
</div>
|
||||
<button type="button" class="btn btn-link" data-clipboard-target="#Address_@Model.PaymentMethodId">
|
||||
<vc:icon symbol="copy" />
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="lightning" class="input-group mt-3">
|
||||
<div class="form-floating">
|
||||
<input id="Lightning_@Model.PaymentMethodId" class="form-control-plaintext" readonly="readonly" :value="lightning" />
|
||||
<label for="Lightning_@Model.PaymentMethodId" v-t="'lightning'"></label>
|
||||
<div class="form-floating" id="Lightning_@Model.PaymentMethodId">
|
||||
<vc:truncate-center text="lightning" is-vue="true" padding="15" elastic="true" classes="form-control-plaintext" />
|
||||
<label v-t="'lightning'"></label>
|
||||
</div>
|
||||
<button type="button" class="btn btn-link" data-clipboard-target="#Lightning_@Model.PaymentMethodId">
|
||||
<vc:icon symbol="copy" />
|
||||
</button>
|
||||
</div>
|
||||
<a v-if="model.invoiceBitcoinUrl && model.showPayInWalletButton" class="btn btn-primary rounded-pill w-100 mt-4" target="_top" id="PayInWallet"
|
||||
:href="model.invoiceBitcoinUrl" :title="$t(hasPayjoin ? 'BIP21 payment link with PayJoin support' : 'BIP21 payment link')" v-t="'pay_in_wallet'"></a>
|
||||
|
|
|
@ -10,13 +10,10 @@
|
|||
<img class="qr-icon" :src="model.cryptoImage" :alt="model.paymentMethodName"/>
|
||||
</div>
|
||||
<div v-if="model.btcAddress" class="input-group mt-3">
|
||||
<div class="form-floating">
|
||||
<input id="Lightning_@Model.PaymentMethodId" class="form-control-plaintext" readonly="readonly" :value="model.btcAddress">
|
||||
<label for="Lightning_@Model.PaymentMethodId" v-t="'lightning'"></label>
|
||||
<div class="form-floating" id="Lightning_@Model.PaymentMethodId">
|
||||
<vc:truncate-center text="model.btcAddress" is-vue="true" padding="15" elastic="true" classes="form-control-plaintext" />
|
||||
<label v-t="'lightning'"></label>
|
||||
</div>
|
||||
<button type="button" class="btn btn-link" data-clipboard-target="#Lightning_@Model.PaymentMethodId">
|
||||
<vc:icon symbol="copy" />
|
||||
</button>
|
||||
</div>
|
||||
<a v-if="model.invoiceBitcoinUrl && model.showPayInWalletButton" class="btn btn-primary rounded-pill w-100 mt-4" target="_top" id="PayInWallet"
|
||||
:href="model.invoiceBitcoinUrl" v-t="'pay_in_wallet'"></a>
|
||||
|
|
|
@ -928,6 +928,14 @@ input.ts-wrapper.form-control:not(.ts-hidden-accessible,.ts-inline) {
|
|||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--btcpay-space-s);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.truncate-center--elastic .truncate-center-start {
|
||||
flex: 0 1 auto;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.truncate-center-id {
|
||||
|
@ -941,15 +949,36 @@ input.ts-wrapper.form-control:not(.ts-hidden-accessible,.ts-inline) {
|
|||
}
|
||||
|
||||
.truncate-center a,
|
||||
.truncate-center button,
|
||||
.truncate-center-truncated {
|
||||
.truncate-center button {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.truncate-center-truncated {
|
||||
text-align: left;
|
||||
display: inline-flex;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.truncate-center button.btn .icon {
|
||||
--btn-icon-size: 1em;
|
||||
}
|
||||
|
||||
.truncate-center--elastic .truncate-center-truncated {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.truncate-center--elastic.truncate-center--copy .truncate-center-truncated {
|
||||
max-width: calc(100% - 2em);
|
||||
}
|
||||
|
||||
.truncate-center.form-control-plaintext {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.truncate-center.form-control-plaintext button.btn .icon {
|
||||
--btn-icon-size: 1.25em;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.truncate-center-id {
|
||||
background: var(--btcpay-neutral-100);
|
||||
|
|
Loading…
Add table
Reference in a new issue