btcpayserver/BTCPayServer/wwwroot/pos/keypad.js
d11n 6d288271cd
Unify public page styles (#5462)
Based on #5413 and needs it to get merged first.

- Uses `--wrap-max-width` on `.public-page-wrap` rather than inner `.container` classes
- Applies `.tile` class to boxes and makes them connect to the edge of the screen below `400px` width.
2023-11-21 10:13:26 +01:00

131 lines
5.8 KiB
JavaScript

document.addEventListener("DOMContentLoaded",function () {
const displayFontSize = 64;
new Vue({
el: '#app',
mixins: [posCommon],
data () {
return {
mode: 'amounts',
fontSize: displayFontSize,
defaultFontSize: displayFontSize,
keys: ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', '0', '+'],
amounts: [null]
}
},
computed: {
modes () {
const modes = [{ title: 'Amount', type: 'amounts' }]
if (this.showDiscount) modes.push({ title: 'Discount', type: 'discount' })
if (this.enableTips) modes.push({ title: 'Tip', type: 'tip'})
return modes
},
keypadTarget () {
switch (this.mode) {
case 'amounts':
return 'amounts';
case 'discount':
return 'discountPercent';
case 'tip':
return 'tip';
}
},
calculation () {
if (!this.tipNumeric && !(this.discountNumeric > 0 || this.discountPercentNumeric > 0) && this.amounts.length < 2) return null
let calc = this.amounts.map(amt => this.formatCurrency(amt, true)).join(' + ')
if (this.discountNumeric > 0 || this.discountPercentNumeric > 0) calc += ` - ${this.formatCurrency(this.discountNumeric, true)} (${this.discountPercent}%)`
if (this.tipNumeric > 0) calc += ` + ${this.formatCurrency(this.tipNumeric, true)}`
if (this.tipPercent) calc += ` (${this.tipPercent}%)`
return calc
}
},
watch: {
total () {
// This must be timed out because the updated width is not available yet
this.$nextTick(function () {
const displayWidth = this.getWidth(this.$refs.display),
amountWidth = this.getWidth(this.$refs.amount),
gamma = displayWidth / amountWidth || 0,
isAmountWider = displayWidth < amountWidth;
if (isAmountWider) {
// Font size will get smaller
this.fontSize = Math.floor(this.fontSize * gamma);
} else if (!isAmountWider && this.fontSize < this.defaultFontSize) {
// Font size will get larger up to the max size
this.fontSize = Math.min(this.fontSize * gamma, this.defaultFontSize);
}
});
},
amounts (values) {
this.amount = values.reduce((total, current) => total + parseFloat(current || '0'), 0);
}
},
methods: {
getWidth(el) {
const styles = window.getComputedStyle(el),
width = parseFloat(el.clientWidth),
padL = parseFloat(styles.paddingLeft),
padR = parseFloat(styles.paddingRight);
return width - padL - padR;
},
clear() {
this.amounts = [null];
this.tip = this.discount = this.tipPercent = this.discountPercent = null;
this.mode = 'amounts';
},
applyKeyToValue(key, value, divisibility) {
if (!value || value === '0') value = '';
value = (value + key)
.replace('.', '')
.padStart(divisibility, '0')
.replace(new RegExp(`(\\d*)(\\d{${divisibility}})`), '$1.$2');
return parseFloat(value).toFixed(divisibility);
},
keyPressed (key) {
if (this.keypadTarget === 'amounts') {
const lastIndex = this.amounts.length - 1;
const lastAmount = this.amounts[lastIndex];
if (key === 'C') {
if (!lastAmount && lastIndex === 0) {
// clear completely
this.clear();
} else if (!lastAmount) {
// remove latest value
this.amounts.pop();
} else {
// clear latest value
Vue.set(this.amounts, lastIndex, null);
}
} else if (key === '+' && parseFloat(lastAmount || '0')) {
this.amounts.push(null);
} else { // Is a digit
const { divisibility } = this.currencyInfo;
const value = this.applyKeyToValue(key, lastAmount, divisibility);
Vue.set(this.amounts, lastIndex, value);
}
} else {
if (key === 'C') {
this[this.keypadTarget] = null;
} else {
const divisibility = this.keypadTarget === 'tip' ? this.currencyInfo.divisibility : 0;
this[this.keypadTarget] = this.applyKeyToValue(key, this[this.keypadTarget], divisibility);
}
}
},
doubleClick (key) {
if (key === 'C') {
// clear completely
this.clear();
}
}
},
created() {
/** We need to unset state in case user clicks the browser back button */
window.addEventListener('pagehide', this.unsetPayButtonLoading)
},
destroyed() {
window.removeEventListener('pagehide', this.unsetPayButtonLoading)
},
});
});