Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
8.1 KiB
225 lines
8.1 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import PopupElement from '.'; |
|
import placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd'; |
|
import {InputInvoice, PaymentRequestedInfo, PaymentsPaymentForm, PaymentsValidatedRequestedInfo} from '../../layer'; |
|
import matchEmail from '../../lib/richTextProcessor/matchEmail'; |
|
import CheckboxField from '../checkboxField'; |
|
import CountryInputField from '../countryInputField'; |
|
import InputField from '../inputField'; |
|
import Row from '../row'; |
|
import SettingSection from '../settingSection'; |
|
import TelInputField from '../telInputField'; |
|
import {PaymentButton} from './payment'; |
|
import {createCountryZipFields, handleInputFieldsOnChange, InputFieldCorrected} from './paymentCard'; |
|
|
|
export type PaymentShippingAddress = PaymentRequestedInfo; |
|
|
|
type ShippingFocusField = 'name' | 'email' | 'phone'; |
|
|
|
export default class PopupPaymentShipping extends PopupElement<{ |
|
finish: (o: {shippingAddress: PaymentShippingAddress, requestedInfo: PaymentsValidatedRequestedInfo}) => void |
|
}> { |
|
constructor( |
|
private paymentForm: PaymentsPaymentForm, |
|
private inputInvoice: InputInvoice, |
|
private focus?: ShippingFocusField |
|
) { |
|
super('popup-payment popup-payment-shipping', { |
|
closable: true, |
|
overlayClosable: true, |
|
body: true, |
|
scrollable: true, |
|
title: 'PaymentShippingInfo' |
|
}); |
|
|
|
this.d(); |
|
} |
|
|
|
private d() { |
|
const paymentForm = this.paymentForm; |
|
const invoice = paymentForm.invoice; |
|
const savedInfo = this.paymentForm.saved_info; |
|
|
|
let addressSection: SettingSection, |
|
address1InputField: InputField, |
|
address2InputField: InputField, |
|
cityInputField: InputField, |
|
stateInputField: InputField, |
|
countryInputField: CountryInputField, |
|
postcodeInputField: InputFieldCorrected; |
|
if(invoice.pFlags.shipping_address_requested) { |
|
addressSection = new SettingSection({name: 'PaymentShippingAddress', noDelimiter: true, noShadow: true}); |
|
address1InputField = new InputField({label: 'PaymentShippingAddress1Placeholder', maxLength: 64, required: true}); |
|
address2InputField = new InputField({label: 'PaymentShippingAddress2Placeholder', maxLength: 64}); |
|
cityInputField = new InputField({label: 'PaymentShippingCityPlaceholder', maxLength: 64, required: true}); |
|
stateInputField = new InputField({label: 'PaymentShippingStatePlaceholder', maxLength: 64}); |
|
const res = createCountryZipFields(true, true); |
|
countryInputField = res.countryInputField; |
|
postcodeInputField = res.postcodeInputField; |
|
|
|
addressSection.content.append(...[ |
|
address1InputField, |
|
address2InputField, |
|
cityInputField, |
|
stateInputField, |
|
countryInputField, |
|
postcodeInputField |
|
].filter(Boolean).map((inputField) => inputField.container)); |
|
} |
|
|
|
let receiverSection: SettingSection; |
|
let nameInputField: InputField, emailInputField: InputField, telInputField: TelInputField; |
|
if([invoice.pFlags.name_requested, invoice.pFlags.email_requested, invoice.pFlags.phone_requested].includes(true)) { |
|
receiverSection = new SettingSection({name: 'PaymentShippingReceiver', noDelimiter: true, noShadow: true}); |
|
|
|
const validateEmail = () => { |
|
const value = emailInputField.value; |
|
const match = matchEmail(value); |
|
if(!match || match[0].length !== value.length) { |
|
return false; |
|
} |
|
|
|
return true; |
|
}; |
|
|
|
const validatePhone = () => { |
|
return !!telInputField.value.match(/\d/); |
|
}; |
|
|
|
if(invoice.pFlags.name_requested) nameInputField = new InputField({label: 'PaymentShippingName', maxLength: 256, required: true}); |
|
if(invoice.pFlags.email_requested) emailInputField = new InputField({label: 'PaymentShippingEmailPlaceholder', maxLength: 64, required: true, validate: validateEmail}); |
|
if(invoice.pFlags.phone_requested) telInputField = new TelInputField({required: true, validate: validatePhone}); |
|
|
|
receiverSection.content.append(...[ |
|
nameInputField, |
|
emailInputField, |
|
telInputField |
|
].filter(Boolean).map((inputField) => inputField.container)); |
|
} |
|
|
|
const saveCheckboxField = new CheckboxField({ |
|
text: 'PaymentShippingSave', |
|
checked: true |
|
}); |
|
const saveRow = new Row({ |
|
checkboxField: saveCheckboxField, |
|
subtitleLangKey: 'PaymentShippingSaveInfo' |
|
}); |
|
|
|
(receiverSection || addressSection).content.append(saveRow.container); |
|
|
|
this.scrollable.append(...[addressSection, receiverSection].filter(Boolean).map((section) => section.container)); |
|
|
|
const payButton = PaymentButton({ |
|
key: 'PaymentInfo.Done', |
|
onClick: async() => { |
|
const selectedCountry = countryInputField && countryInputField.getSelected().country; |
|
const data: PaymentShippingAddress = { |
|
_: 'paymentRequestedInfo', |
|
shipping_address: selectedCountry && { |
|
_: 'postAddress', |
|
street_line1: address1InputField.value, |
|
street_line2: address2InputField.value, |
|
city: cityInputField.value, |
|
state: stateInputField.value, |
|
// country: countryInputField.value, |
|
country_iso2: selectedCountry?.iso2, |
|
post_code: postcodeInputField.value |
|
}, |
|
name: nameInputField?.value, |
|
email: emailInputField?.value, |
|
phone: telInputField?.value |
|
}; |
|
|
|
try { |
|
const requestedInfo = await this.managers.appPaymentsManager.validateRequestedInfo(this.inputInvoice, data, saveCheckboxField?.checked); |
|
|
|
this.dispatchEvent('finish', { |
|
shippingAddress: data, |
|
requestedInfo |
|
}); |
|
|
|
this.hide(); |
|
} catch(err: any) { |
|
const errorMap: {[err: string]: InputField} = { |
|
ADDRESS_STREET_LINE1_INVALID: address1InputField, |
|
ADDRESS_STREET_LINE2_INVALID: address2InputField, |
|
ADDRESS_COUNTRY_INVALID: countryInputField, |
|
ADDRESS_CITY_INVALID: cityInputField, |
|
ADDRESS_STATE_INVALID: stateInputField, |
|
ADDRESS_POSTCODE_INVALID: postcodeInputField, |
|
|
|
REQ_INFO_NAME_INVALID: nameInputField, |
|
REQ_INFO_EMAIL_INVALID: emailInputField, |
|
REQ_INFO_PHONE_INVALID: telInputField |
|
}; |
|
|
|
const inputField = errorMap[(err as ApiError).type]; |
|
if(inputField) { |
|
inputField.setError(); |
|
(err as any).handled = true; |
|
} |
|
|
|
throw err; |
|
} |
|
} |
|
}); |
|
this.body.append(this.btnConfirmOnEnter = payButton); |
|
|
|
if(savedInfo) { |
|
const shippingAddress = savedInfo.shipping_address; |
|
if(shippingAddress) { |
|
address1InputField.value = shippingAddress.street_line1; |
|
address2InputField.value = shippingAddress.street_line2; |
|
cityInputField.value = shippingAddress.city; |
|
stateInputField.value = shippingAddress.state; |
|
countryInputField.selectCountryByIso2(shippingAddress.country_iso2); |
|
postcodeInputField.value = shippingAddress.post_code; |
|
} |
|
|
|
savedInfo.name && nameInputField && (nameInputField.value = savedInfo.name); |
|
savedInfo.email && emailInputField && (emailInputField.value = savedInfo.email); |
|
savedInfo.phone && telInputField && (telInputField.value = savedInfo.phone); |
|
} |
|
|
|
const {validate} = handleInputFieldsOnChange([ |
|
address1InputField, |
|
address2InputField, |
|
cityInputField, |
|
stateInputField, |
|
countryInputField, |
|
postcodeInputField, |
|
nameInputField, |
|
emailInputField, |
|
telInputField |
|
].filter(Boolean), (valid) => { |
|
payButton.disabled = !valid; |
|
}); |
|
|
|
validate(); |
|
|
|
this.show(); |
|
|
|
let focusField: InputField; |
|
if(this.focus) { |
|
const focusMap: {[field in ShippingFocusField]?: InputField} = { |
|
name: nameInputField, |
|
email: emailInputField, |
|
phone: telInputField |
|
}; |
|
|
|
focusField = focusMap[this.focus]; |
|
} else { |
|
focusField = address1InputField; |
|
} |
|
|
|
if(focusField) { |
|
placeCaretAtEnd(focusField.input); |
|
} |
|
} |
|
}
|
|
|