Skip to content

Commit

Permalink
Keypad updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisreimann committed Nov 9, 2023
1 parent d030252 commit 9e4e059
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 30 deletions.
70 changes: 48 additions & 22 deletions BTCPayApp.UI/Components/Keypad.razor
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
@using Newtonsoft.Json.Linq
@using System.Text.RegularExpressions
@using System.Globalization
@inject IJSRuntime JS

<form class="d-flex flex-column gap-4" @onsubmit="Submit">
<div ref="display" class="d-flex flex-column align-items-center px-4 mb-auto">
<div class="d-flex flex-column align-items-center px-4 mb-auto" @ref="_keypadTop">
<div class="fw-semibold text-muted" id="Currency">@CurrencyCode</div>
<div class="fw-bold lh-sm" style="font-size:@(FontSize + "px")" id="Amount">@FormatCurrency(GetTotal(), false)</div>
<div class="fw-bold lh-sm" style="font-size:@($"{FontSize}px")" @ref="_keypadAmount">@FormatCurrency(GetTotal(), false)</div>
<div class="text-muted text-center mt-2" id="Calculation">@Calculation(Model)</div>
</div>
@if (IsDiscountEnabled || IsTipEnabled)
Expand All @@ -13,7 +16,7 @@
{
<div class="tab-pane fade px-2 @(Mode == InputMode.Discount ? "show active" : "")" role="tabpanel" aria-labelledby="ModeTablist-Discount">
<div class="h4 fw-semibold text-muted text-center" id="Discount">
<span class="h3 text-body me-1">@Model.DiscountPercent%</span> discount
<span class="h3 text-body me-1">@(Model.DiscountPercent ?? 0)%</span> discount
</div>
</div>
}
Expand Down Expand Up @@ -75,7 +78,7 @@
@if (IsSubmitting)
{
<div class="spinner-border spinner-border-sm" role="status">
<span class="sr-only">Loading...</span>
<span class="visually-hidden">Loading...</span>
</div>
}
else
Expand Down Expand Up @@ -112,11 +115,14 @@
Tip
}

private ElementReference _keypadTop;
private ElementReference _keypadAmount;

private InputMode Mode { get; set; } = InputMode.Amount;

public class KeypadModel
{
public List<decimal> Amounts { get; set; } = new ();
public List<decimal> Amounts { get; set; } = new () { 0 };
public int? DiscountPercent { get; set; }
public int? TipPercent { get; set; }
public decimal? Tip { get; set; }
Expand All @@ -129,7 +135,7 @@
IsSubmitting = true;
}

private void KeyPress(char key = '1')
private async Task KeyPress(char key)
{
if (Mode == InputMode.Amount) {
var lastIndex = Model.Amounts.Count - 1;
Expand All @@ -148,8 +154,9 @@
} else if (key == '+' && lastAmount != 0) {
Model.Amounts.Add(0);
} else { // Is a digit
Model.Amounts[lastIndex] = ApplyKeyToValue(key, lastAmount, CurrencyDivisibility);
Model.Amounts[lastIndex] = Math.Min(ApplyKeyToValue(key, lastAmount, CurrencyDivisibility), decimal.MaxValue / 10);
}
await UpdateFontSize();
} else {
if (key == 'C') {
if (Mode == InputMode.Tip)
Expand All @@ -165,37 +172,43 @@
var divisibility = Mode == InputMode.Tip ? CurrencyDivisibility : 0;
if (Mode == InputMode.Tip)
{
Model.Tip = ApplyKeyToValue(key, Model.Tip ?? 0, divisibility);
Model.Tip = Math.Min(ApplyKeyToValue(key, Model.Tip ?? 0, divisibility), decimal.MaxValue / 10);
Model.TipPercent = null;
}
else
{
Model.DiscountPercent = (int)ApplyKeyToValue(key, Model.DiscountPercent ?? 0, divisibility);
var num = (int)ApplyKeyToValue(key, Model.DiscountPercent ?? 0, divisibility);
Model.DiscountPercent = Math.Min(num, 100);
}
}
}
}

public decimal ApplyKeyToValue(char key, decimal value, int divisibility)
private decimal ApplyKeyToValue(char key, decimal value, int divisibility)
{
var val = value is 0 ? "" : Formatted(value, divisibility);
val = (val + key)
.Replace(".", "")
.PadLeft(divisibility, '0');
//.Replace(new Regex("(\\d*)(\\d{{divisibility}})", "\\1.\\2");
return decimal.Parse(val);
var str = value is 0 ? "" : Formatted(value, divisibility);
//var minDiv = str.Length < divisibility ? str.Length + 1 : divisibility;
str = (str + key).Replace(".", "");
if (divisibility > 0)
{
str = str.PadLeft(divisibility + 1, '0');
str = Regex.Replace(str, $"(\\d*)(\\d{{{divisibility}}})", "$1.$2");
}

return decimal.Parse(str, CultureInfo.InvariantCulture);
}

public void DoublePress(char key)
private void DoublePress(char key)
{
if (key == 'C') {
Clear();
}
}

public void Clear()
private void Clear()
{
Model.Amounts.Clear();
Model.Amounts.Add(0);
Model.DiscountPercent = null;
Model.TipPercent = null;
Model.Tip = null;
Expand Down Expand Up @@ -272,10 +285,10 @@
if (model.Amounts.Count < 2 && model.DiscountPercent is not > 0 && !model.Tip.HasValue) return null;
var calc = string.Join(" + ", model.Amounts.Select(amt => FormatCurrency(amt, true)));
var discount = GetDiscount();
if (discount > 0) calc += $" - {FormatCurrency(discount, true)} (${model.DiscountPercent}%)";
if (discount > 0) calc += $" - {FormatCurrency(discount, true)} ({model.DiscountPercent}%)";
var tip = GetTip();
if (model.Tip > 0) calc += $" + ${FormatCurrency(tip, true)}";
if (model.TipPercent > 0) calc += $" (${model.TipPercent}%)";
if (tip > 0) calc += $" + {FormatCurrency(tip, true)}";
if (model.TipPercent > 0) calc += $" ({model.TipPercent}%)";
return calc;
}

Expand All @@ -298,6 +311,19 @@
}

private string Formatted(decimal value, int divisibility) {
return string.Format($"{{0:0.{new string('0', divisibility)}}}", value);
return string.Format(CultureInfo.InvariantCulture, $"{{0:0.{new string('0', divisibility)}}}", value);
}

private async Task UpdateFontSize()
{
var top = await JS.InvokeAsync<decimal>("Interop.getWidth", new object[] { _keypadTop });
var amt = await JS.InvokeAsync<decimal>("Interop.getWidth", new object[] { _keypadAmount });
var gamma = top / amt;

FontSize = (int)(top < amt
? Math.Floor(FontSize * gamma)
: Math.Min(FontSize * gamma, DefaultFontSize));

StateHasChanged();
}
}
8 changes: 3 additions & 5 deletions BTCPayApp.UI/Layout/SimpleLayout.razor
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
@inherits Fluxor.Blazor.Web.Components.FluxorLayout

<div class="min-vh-100">
<main>
@Body
</main>
</div>
<main class="min-vh-100">
@Body
</main>
3 changes: 3 additions & 0 deletions BTCPayApp.UI/Pages/PointOfSalePage.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.public-page-wrap {
--wrap-max-width: 560px;
}
54 changes: 51 additions & 3 deletions BTCPayApp.UI/wwwroot/css/global.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@


::-moz-focus-inner {
::-moz-focus-inner {
padding: 0;
border-style: none;
}
Expand All @@ -17,6 +15,56 @@
transform: rotate(-180deg);
}

/* Layout */
.public-page-wrap {
--wrap-max-width: none;
--wrap-padding-vertical: var(--btcpay-space-l);
--wrap-padding-horizontal: var(--btcpay-space-m);

display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: var(--wrap-max-width);
margin: 0 auto;
padding: var(--wrap-padding-vertical) var(--wrap-padding-horizontal);
}

.min-vh-100,
.public-page-wrap {
min-height: -webkit-fill-available !important;
min-height: 100dvh !important;
}

.tile {
--section-padding: 1.5rem;
--section-border-radius: var(--btcpay-border-radius-l);

padding: var(--section-padding);
background: var(--btcpay-bg-tile);
border-radius: var(--section-border-radius);
box-shadow: var(--btcpay-box-shadow-lg);
}
.tile .buttons {
display: flex;
flex-direction: column;
gap: var(--btcpay-space-m);
}
.tile > :last-child {
margin-bottom: 0;
}

@media (max-width: 400px) {
.public-page-wrap {
padding-left: 0;
padding-right: 0;
--wrap-padding-horizontal: 0;
}
.tile {
--section-padding: 1rem;
--section-border-radius: none;
}
}

/* Badges */
.badge-new,
.badge-pending {
Expand Down
5 changes: 5 additions & 0 deletions BTCPayApp.UI/wwwroot/js/global.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Interop = {
getWidth(el) {
return el.clientWidth;
}
}

0 comments on commit 9e4e059

Please sign in to comment.