mirror of https://github.com/procxx/kepka.git
				
				
				
			Choose document type in passport.
This commit is contained in:
		
							parent
							
								
									4e2a109a46
								
							
						
					
					
						commit
						62389f5ef7
					
				| 
						 | 
					@ -1512,10 +1512,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
"lng_passport_identity_title" = "Identity document";
 | 
					"lng_passport_identity_title" = "Identity document";
 | 
				
			||||||
"lng_passport_identity_description" = "Upload a scan of your passport or other ID";
 | 
					"lng_passport_identity_description" = "Upload a scan of your passport or other ID";
 | 
				
			||||||
"lng_passport_identity_passport" = "Passport";
 | 
					"lng_passport_identity_passport" = "Passport";
 | 
				
			||||||
 | 
					"lng_passport_identity_passport_upload" = "Upload a scan of your passport";
 | 
				
			||||||
"lng_passport_identity_card" = "Identity card";
 | 
					"lng_passport_identity_card" = "Identity card";
 | 
				
			||||||
 | 
					"lng_passport_identity_card_upload" = "Upload a scan of your identity card";
 | 
				
			||||||
"lng_passport_identity_license" = "Driver's license";
 | 
					"lng_passport_identity_license" = "Driver's license";
 | 
				
			||||||
 | 
					"lng_passport_identity_license_upload" = "Upload a scan of your driver's license";
 | 
				
			||||||
 | 
					"lng_passport_identity_about" = "Your document must contain your photograph, name and surname, date of birth, citizenship, document issue date and document number.";
 | 
				
			||||||
"lng_passport_address_title" = "Residential address";
 | 
					"lng_passport_address_title" = "Residential address";
 | 
				
			||||||
"lng_passport_address_description" = "Upload a proof of your address";
 | 
					"lng_passport_address_description" = "Upload a proof of your address";
 | 
				
			||||||
 | 
					"lng_passport_address_bill" = "Utility bill";
 | 
				
			||||||
 | 
					"lng_passport_address_bill_upload" = "Upload a scan of your utility bill";
 | 
				
			||||||
 | 
					"lng_passport_address_statement" = "Bank statement";
 | 
				
			||||||
 | 
					"lng_passport_address_statement_upload" = "Upload a scan of your bank statement";
 | 
				
			||||||
 | 
					"lng_passport_address_agreement" = "Tenancy agreement";
 | 
				
			||||||
 | 
					"lng_passport_address_agreement_upload" = "Upload a scan of your tenancy agreement";
 | 
				
			||||||
 | 
					"lng_passport_address_about" = "To confirm your address please upload a scan or photo of the selected document (all pages).";
 | 
				
			||||||
 | 
					"lng_passport_document_type" = "Please choose the type of your document:";
 | 
				
			||||||
 | 
					"lng_passport_upload_document" = "Upload document";
 | 
				
			||||||
"lng_passport_phone_title" = "Phone number";
 | 
					"lng_passport_phone_title" = "Phone number";
 | 
				
			||||||
"lng_passport_phone_description" = "Enter your phone number";
 | 
					"lng_passport_phone_description" = "Enter your phone number";
 | 
				
			||||||
"lng_passport_email_title" = "Email";
 | 
					"lng_passport_email_title" = "Email";
 | 
				
			||||||
| 
						 | 
					@ -1528,7 +1541,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
"lng_passport_save_value" = "Save";
 | 
					"lng_passport_save_value" = "Save";
 | 
				
			||||||
"lng_passport_saving" = "Saving...";
 | 
					"lng_passport_saving" = "Saving...";
 | 
				
			||||||
"lng_passport_uploading" = "Uploading...";
 | 
					"lng_passport_uploading" = "Uploading...";
 | 
				
			||||||
"lng_passport_upload_header" = "Scans";
 | 
					 | 
				
			||||||
"lng_passport_scan_index" = "Scan {index}";
 | 
					"lng_passport_scan_index" = "Scan {index}";
 | 
				
			||||||
"lng_passport_upload_scans" = "Upload scans";
 | 
					"lng_passport_upload_scans" = "Upload scans";
 | 
				
			||||||
"lng_passport_upload_more" = "Upload additional scans";
 | 
					"lng_passport_upload_more" = "Upload additional scans";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,7 +119,7 @@ passportFormUserpic: UserpicButton(passportPasswordUserpic) {
 | 
				
			||||||
passportFormUserpicPadding: margins(0px, 5px, 0px, 10px);
 | 
					passportFormUserpicPadding: margins(0px, 5px, 0px, 10px);
 | 
				
			||||||
passportFormDividerHeight: 13px;
 | 
					passportFormDividerHeight: 13px;
 | 
				
			||||||
passportFormLabel: FlatLabel(defaultFlatLabel) {
 | 
					passportFormLabel: FlatLabel(defaultFlatLabel) {
 | 
				
			||||||
	minWidth: 285px;
 | 
						minWidth: 245px;
 | 
				
			||||||
	align: align(topleft);
 | 
						align: align(topleft);
 | 
				
			||||||
	textFg: windowSubTextFg;
 | 
						textFg: windowSubTextFg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -194,3 +194,5 @@ passportContactField: InputField(defaultInputField) {
 | 
				
			||||||
passportDetailsFieldLeft: 116px;
 | 
					passportDetailsFieldLeft: 116px;
 | 
				
			||||||
passportDetailsFieldTop: 2px;
 | 
					passportDetailsFieldTop: 2px;
 | 
				
			||||||
passportDetailsFieldSkipMin: 12px;
 | 
					passportDetailsFieldSkipMin: 12px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					passportRequestTypeSkip: 16px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "lang/lang_keys.h"
 | 
					#include "lang/lang_keys.h"
 | 
				
			||||||
#include "passport/passport_panel_edit_document.h"
 | 
					#include "passport/passport_panel_edit_document.h"
 | 
				
			||||||
#include "passport/passport_panel_edit_contact.h"
 | 
					#include "passport/passport_panel_edit_contact.h"
 | 
				
			||||||
 | 
					#include "passport/passport_panel_edit_scans.h"
 | 
				
			||||||
#include "passport/passport_panel.h"
 | 
					#include "passport/passport_panel.h"
 | 
				
			||||||
#include "boxes/confirm_box.h"
 | 
					#include "boxes/confirm_box.h"
 | 
				
			||||||
#include "layout.h"
 | 
					#include "layout.h"
 | 
				
			||||||
| 
						 | 
					@ -17,7 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
namespace Passport {
 | 
					namespace Passport {
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
 | 
					PanelEditDocument::Scheme GetDocumentScheme(
 | 
				
			||||||
 | 
							Scope::Type type,
 | 
				
			||||||
 | 
							base::optional<Value::Type> scansType = base::none) {
 | 
				
			||||||
	using Scheme = PanelEditDocument::Scheme;
 | 
						using Scheme = PanelEditDocument::Scheme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto DontValidate = nullptr;
 | 
						const auto DontValidate = nullptr;
 | 
				
			||||||
| 
						 | 
					@ -43,6 +46,21 @@ PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
 | 
				
			||||||
	case Scope::Type::Identity: {
 | 
						case Scope::Type::Identity: {
 | 
				
			||||||
		auto result = Scheme();
 | 
							auto result = Scheme();
 | 
				
			||||||
		result.rowsHeader = lang(lng_passport_personal_details);
 | 
							result.rowsHeader = lang(lng_passport_personal_details);
 | 
				
			||||||
 | 
							if (scansType) {
 | 
				
			||||||
 | 
								switch (*scansType) {
 | 
				
			||||||
 | 
								case Value::Type::Passport:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_identity_passport);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Value::Type::DriverLicense:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_identity_license);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Value::Type::IdentityCard:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_identity_card);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									Unexpected("scansType in GetDocumentScheme:Identity.");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		result.rows = {
 | 
							result.rows = {
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Scheme::ValueType::Fields,
 | 
									Scheme::ValueType::Fields,
 | 
				
			||||||
| 
						 | 
					@ -93,6 +111,21 @@ PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
 | 
				
			||||||
	case Scope::Type::Address: {
 | 
						case Scope::Type::Address: {
 | 
				
			||||||
		auto result = Scheme();
 | 
							auto result = Scheme();
 | 
				
			||||||
		result.rowsHeader = lang(lng_passport_address);
 | 
							result.rowsHeader = lang(lng_passport_address);
 | 
				
			||||||
 | 
							if (scansType) {
 | 
				
			||||||
 | 
								switch (*scansType) {
 | 
				
			||||||
 | 
								case Value::Type::UtilityBill:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_address_bill);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Value::Type::BankStatement:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_address_statement);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Value::Type::RentalAgreement:
 | 
				
			||||||
 | 
									result.scansHeader = lang(lng_passport_address_agreement);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									Unexpected("scansType in GetDocumentScheme:Identity.");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		result.rows = {
 | 
							result.rows = {
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Scheme::ValueType::Fields,
 | 
									Scheme::ValueType::Fields,
 | 
				
			||||||
| 
						 | 
					@ -413,14 +446,121 @@ void PanelController::ensurePanelCreated() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int PanelController::findNonEmptyIndex(
 | 
				
			||||||
 | 
							const std::vector<not_null<const Value*>> &files) const {
 | 
				
			||||||
 | 
						const auto i = ranges::find_if(files, [](not_null<const Value*> file) {
 | 
				
			||||||
 | 
							return !file->files.empty();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						if (i != end(files)) {
 | 
				
			||||||
 | 
							return (i - begin(files));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Only an uploaded scan counts as non-empty value.
 | 
				
			||||||
 | 
						//const auto j = ranges::find_if(files, [](not_null<const Value*> file) {
 | 
				
			||||||
 | 
						//	return !file->data.parsed.fields.empty();
 | 
				
			||||||
 | 
						//});
 | 
				
			||||||
 | 
						//if (j != end(files)) {
 | 
				
			||||||
 | 
						//	return (j - begin(files));
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PanelController::editScope(int index) {
 | 
					void PanelController::editScope(int index) {
 | 
				
			||||||
	Expects(_panel != nullptr);
 | 
						Expects(_panel != nullptr);
 | 
				
			||||||
	Expects(index >= 0 && index < _scopes.size());
 | 
						Expects(index >= 0 && index < _scopes.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_editScope = &_scopes[index];
 | 
						if (_scopes[index].files.size() > 1) {
 | 
				
			||||||
 | 
							const auto filesIndex = findNonEmptyIndex(_scopes[index].files);
 | 
				
			||||||
 | 
							if (filesIndex >= 0) {
 | 
				
			||||||
 | 
								editScope(index, filesIndex);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								requestScopeFilesType(index);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (_scopes[index].files.empty()) {
 | 
				
			||||||
 | 
							editScope(index, -1);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							editWithUpload(index, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// #TODO select type for files index
 | 
					void PanelController::requestScopeFilesType(int index) {
 | 
				
			||||||
	_editScopeFilesIndex = _scopes[index].files.empty() ? -1 : 0;
 | 
						Expects(_panel != nullptr);
 | 
				
			||||||
 | 
						Expects(index >= 0 && index < _scopes.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto type = _scopes[index].type;
 | 
				
			||||||
 | 
						const auto box = std::make_shared<QPointer<BoxContent>>();
 | 
				
			||||||
 | 
						*box = [&] {
 | 
				
			||||||
 | 
							if (type == Scope::Type::Identity) {
 | 
				
			||||||
 | 
								return show(RequestIdentityType(
 | 
				
			||||||
 | 
									[=](int filesIndex) {
 | 
				
			||||||
 | 
										editWithUpload(index, filesIndex);
 | 
				
			||||||
 | 
										(*box)->closeBox();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									ranges::view::all(
 | 
				
			||||||
 | 
										_scopes[index].files
 | 
				
			||||||
 | 
									) | ranges::view::transform([](auto value) {
 | 
				
			||||||
 | 
										return value->type;
 | 
				
			||||||
 | 
									}) | ranges::view::transform([](Value::Type type) {
 | 
				
			||||||
 | 
										switch (type) {
 | 
				
			||||||
 | 
										case Value::Type::Passport:
 | 
				
			||||||
 | 
											return lang(lng_passport_identity_passport);
 | 
				
			||||||
 | 
										case Value::Type::IdentityCard:
 | 
				
			||||||
 | 
											return lang(lng_passport_identity_card);
 | 
				
			||||||
 | 
										case Value::Type::DriverLicense:
 | 
				
			||||||
 | 
											return lang(lng_passport_identity_license);
 | 
				
			||||||
 | 
										default:
 | 
				
			||||||
 | 
											Unexpected("IdentityType in requestScopeFilesType");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}) | ranges::to_vector));
 | 
				
			||||||
 | 
							} else if (type == Scope::Type::Address) {
 | 
				
			||||||
 | 
								return show(RequestAddressType(
 | 
				
			||||||
 | 
									[=](int filesIndex) {
 | 
				
			||||||
 | 
										editWithUpload(index, filesIndex);
 | 
				
			||||||
 | 
										(*box)->closeBox();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									ranges::view::all(
 | 
				
			||||||
 | 
										_scopes[index].files
 | 
				
			||||||
 | 
									) | ranges::view::transform([](auto value) {
 | 
				
			||||||
 | 
										return value->type;
 | 
				
			||||||
 | 
									}) | ranges::view::transform([](Value::Type type) {
 | 
				
			||||||
 | 
										switch (type) {
 | 
				
			||||||
 | 
										case Value::Type::UtilityBill:
 | 
				
			||||||
 | 
											return lang(lng_passport_address_bill);
 | 
				
			||||||
 | 
										case Value::Type::BankStatement:
 | 
				
			||||||
 | 
											return lang(lng_passport_address_statement);
 | 
				
			||||||
 | 
										case Value::Type::RentalAgreement:
 | 
				
			||||||
 | 
											return lang(lng_passport_address_agreement);
 | 
				
			||||||
 | 
										default:
 | 
				
			||||||
 | 
											Unexpected("AddressType in requestScopeFilesType");
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}) | ranges::to_vector));
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								Unexpected("Type in processVerificationNeeded.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PanelController::editWithUpload(int index, int filesIndex) {
 | 
				
			||||||
 | 
						Expects(_panel != nullptr);
 | 
				
			||||||
 | 
						Expects(index >= 0 && index < _scopes.size());
 | 
				
			||||||
 | 
						Expects(filesIndex >= 0 && filesIndex < _scopes[index].files.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EditScans::ChooseScan(
 | 
				
			||||||
 | 
							base::lambda_guarded(_panel.get(),
 | 
				
			||||||
 | 
							[=](QByteArray &&content) {
 | 
				
			||||||
 | 
								editScope(index, filesIndex);
 | 
				
			||||||
 | 
								uploadScan(std::move(content));
 | 
				
			||||||
 | 
							}));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PanelController::editScope(int index, int filesIndex) {
 | 
				
			||||||
 | 
						Expects(_panel != nullptr);
 | 
				
			||||||
 | 
						Expects(index >= 0 && index < _scopes.size());
 | 
				
			||||||
 | 
						Expects((filesIndex < 0)
 | 
				
			||||||
 | 
							|| (filesIndex >= 0 && filesIndex < _scopes[index].files.size()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_editScope = &_scopes[index];
 | 
				
			||||||
 | 
						_editScopeFilesIndex = filesIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_form->startValueEdit(_editScope->fields);
 | 
						_form->startValueEdit(_editScope->fields);
 | 
				
			||||||
	if (_editScopeFilesIndex >= 0) {
 | 
						if (_editScopeFilesIndex >= 0) {
 | 
				
			||||||
| 
						 | 
					@ -435,14 +575,16 @@ void PanelController::editScope(int index) {
 | 
				
			||||||
				? object_ptr<PanelEditDocument>(
 | 
									? object_ptr<PanelEditDocument>(
 | 
				
			||||||
					_panel.get(),
 | 
										_panel.get(),
 | 
				
			||||||
					this,
 | 
										this,
 | 
				
			||||||
					std::move(GetDocumentScheme(_editScope->type)),
 | 
										GetDocumentScheme(
 | 
				
			||||||
 | 
											_editScope->type,
 | 
				
			||||||
 | 
											_editScope->files[_editScopeFilesIndex]->type),
 | 
				
			||||||
					_editScope->fields->data.parsedInEdit,
 | 
										_editScope->fields->data.parsedInEdit,
 | 
				
			||||||
					_editScope->files[_editScopeFilesIndex]->data.parsedInEdit,
 | 
										_editScope->files[_editScopeFilesIndex]->data.parsedInEdit,
 | 
				
			||||||
					valueFiles(*_editScope->files[_editScopeFilesIndex]))
 | 
										valueFiles(*_editScope->files[_editScopeFilesIndex]))
 | 
				
			||||||
				: object_ptr<PanelEditDocument>(
 | 
									: object_ptr<PanelEditDocument>(
 | 
				
			||||||
					_panel.get(),
 | 
										_panel.get(),
 | 
				
			||||||
					this,
 | 
										this,
 | 
				
			||||||
					std::move(GetDocumentScheme(_editScope->type)),
 | 
										GetDocumentScheme(_editScope->type),
 | 
				
			||||||
					_editScope->fields->data.parsedInEdit);
 | 
										_editScope->fields->data.parsedInEdit);
 | 
				
			||||||
			const auto weak = make_weak(result.data());
 | 
								const auto weak = make_weak(result.data());
 | 
				
			||||||
			_panelHasUnsavedChanges = [=] {
 | 
								_panelHasUnsavedChanges = [=] {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,11 @@ public:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void ensurePanelCreated();
 | 
						void ensurePanelCreated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void editScope(int index, int filesIndex);
 | 
				
			||||||
 | 
						void editWithUpload(int index, int filesIndex);
 | 
				
			||||||
 | 
						int findNonEmptyIndex(
 | 
				
			||||||
 | 
							const std::vector<not_null<const Value*>> &files) const;
 | 
				
			||||||
 | 
						void requestScopeFilesType(int index);
 | 
				
			||||||
	void cancelValueEdit();
 | 
						void cancelValueEdit();
 | 
				
			||||||
	std::vector<ScanInfo> valueFiles(const Value &value) const;
 | 
						std::vector<ScanInfo> valueFiles(const Value &value) const;
 | 
				
			||||||
	void processValueSaveFinished(not_null<const Value*> value);
 | 
						void processValueSaveFinished(not_null<const Value*> value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ namespace {
 | 
				
			||||||
class VerifyBox : public BoxContent {
 | 
					class VerifyBox : public BoxContent {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	VerifyBox(
 | 
						VerifyBox(
 | 
				
			||||||
		QWidget *parent,
 | 
							QWidget*,
 | 
				
			||||||
		const QString &title,
 | 
							const QString &title,
 | 
				
			||||||
		const QString &text,
 | 
							const QString &text,
 | 
				
			||||||
		int codeLength,
 | 
							int codeLength,
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ private:
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VerifyBox::VerifyBox(
 | 
					VerifyBox::VerifyBox(
 | 
				
			||||||
	QWidget *parent,
 | 
						QWidget*,
 | 
				
			||||||
	const QString &title,
 | 
						const QString &title,
 | 
				
			||||||
	const QString &text,
 | 
						const QString &text,
 | 
				
			||||||
	int codeLength,
 | 
						int codeLength,
 | 
				
			||||||
| 
						 | 
					@ -124,6 +124,7 @@ void VerifyBox::setupControls(
 | 
				
			||||||
	waiter->resizeToWidth(innerWidth);
 | 
						waiter->resizeToWidth(innerWidth);
 | 
				
			||||||
	waiter->moveToLeft(st::boxPadding.left(), y);
 | 
						waiter->moveToLeft(st::boxPadding.left(), y);
 | 
				
			||||||
	y += waiter->height() + st::boxPadding.bottom();
 | 
						y += waiter->height() + st::boxPadding.bottom();
 | 
				
			||||||
 | 
						_height = y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_submit = [=] {
 | 
						_submit = [=] {
 | 
				
			||||||
		submit(_code->getLastText());
 | 
							submit(_code->getLastText());
 | 
				
			||||||
| 
						 | 
					@ -136,7 +137,6 @@ void VerifyBox::setupControls(
 | 
				
			||||||
	connect(_code, &SentCodeField::changed, [=] {
 | 
						connect(_code, &SentCodeField::changed, [=] {
 | 
				
			||||||
		problem->hide(anim::type::normal);
 | 
							problem->hide(anim::type::normal);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
	_height = y;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void VerifyBox::setInnerFocus() {
 | 
					void VerifyBox::setInnerFocus() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "ui/widgets/labels.h"
 | 
					#include "ui/widgets/labels.h"
 | 
				
			||||||
#include "ui/widgets/buttons.h"
 | 
					#include "ui/widgets/buttons.h"
 | 
				
			||||||
#include "ui/widgets/shadow.h"
 | 
					#include "ui/widgets/shadow.h"
 | 
				
			||||||
 | 
					#include "ui/widgets/checkbox.h"
 | 
				
			||||||
#include "ui/wrap/vertical_layout.h"
 | 
					#include "ui/wrap/vertical_layout.h"
 | 
				
			||||||
#include "ui/wrap/fade_wrap.h"
 | 
					#include "ui/wrap/fade_wrap.h"
 | 
				
			||||||
#include "boxes/abstract_box.h"
 | 
					#include "boxes/abstract_box.h"
 | 
				
			||||||
| 
						 | 
					@ -25,6 +26,103 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "styles/style_passport.h"
 | 
					#include "styles/style_passport.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passport {
 | 
					namespace Passport {
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RequestTypeBox : public BoxContent {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						RequestTypeBox(
 | 
				
			||||||
 | 
							QWidget*,
 | 
				
			||||||
 | 
							const QString &title,
 | 
				
			||||||
 | 
							const QString &about,
 | 
				
			||||||
 | 
							std::vector<QString> labels,
 | 
				
			||||||
 | 
							base::lambda<void(int index)> submit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						void prepare() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						void setupControls(
 | 
				
			||||||
 | 
							const QString &about,
 | 
				
			||||||
 | 
							std::vector<QString> labels,
 | 
				
			||||||
 | 
							base::lambda<void(int index)> submit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString _title;
 | 
				
			||||||
 | 
						base::lambda<void()> _submit;
 | 
				
			||||||
 | 
						int _height = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RequestTypeBox::RequestTypeBox(
 | 
				
			||||||
 | 
						QWidget*,
 | 
				
			||||||
 | 
						const QString &title,
 | 
				
			||||||
 | 
						const QString &about,
 | 
				
			||||||
 | 
						std::vector<QString> labels,
 | 
				
			||||||
 | 
						base::lambda<void(int index)> submit)
 | 
				
			||||||
 | 
					: _title(title) {
 | 
				
			||||||
 | 
						setupControls(about, std::move(labels), submit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RequestTypeBox::prepare() {
 | 
				
			||||||
 | 
						setTitle([=] { return _title; });
 | 
				
			||||||
 | 
						addButton(langFactory(lng_passport_upload_document), [=] { _submit(); });
 | 
				
			||||||
 | 
						addButton(langFactory(lng_cancel), [=] { closeBox(); });
 | 
				
			||||||
 | 
						setDimensions(st::boxWidth, _height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RequestTypeBox::setupControls(
 | 
				
			||||||
 | 
							const QString &about,
 | 
				
			||||||
 | 
							std::vector<QString> labels,
 | 
				
			||||||
 | 
							base::lambda<void(int index)> submit) {
 | 
				
			||||||
 | 
						const auto header = Ui::CreateChild<Ui::FlatLabel>(
 | 
				
			||||||
 | 
							this,
 | 
				
			||||||
 | 
							lang(lng_passport_document_type),
 | 
				
			||||||
 | 
							Ui::FlatLabel::InitType::Simple,
 | 
				
			||||||
 | 
							st::passportFormLabel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto group = std::make_shared<Ui::RadiobuttonGroup>(0);
 | 
				
			||||||
 | 
						auto buttons = std::vector<QPointer<Ui::Radiobutton>>();
 | 
				
			||||||
 | 
						auto index = 0;
 | 
				
			||||||
 | 
						for (const auto &label : labels) {
 | 
				
			||||||
 | 
							buttons.push_back(Ui::CreateChild<Ui::Radiobutton>(
 | 
				
			||||||
 | 
								this,
 | 
				
			||||||
 | 
								group,
 | 
				
			||||||
 | 
								index++,
 | 
				
			||||||
 | 
								label,
 | 
				
			||||||
 | 
								st::defaultBoxCheckbox));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto description = Ui::CreateChild<Ui::FlatLabel>(
 | 
				
			||||||
 | 
							this,
 | 
				
			||||||
 | 
							about,
 | 
				
			||||||
 | 
							Ui::FlatLabel::InitType::Simple,
 | 
				
			||||||
 | 
							st::passportFormLabel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto y = 0;
 | 
				
			||||||
 | 
						const auto innerWidth = st::boxWidth
 | 
				
			||||||
 | 
							- st::boxPadding.left()
 | 
				
			||||||
 | 
							- st::boxPadding.right();
 | 
				
			||||||
 | 
						header->resizeToWidth(innerWidth);
 | 
				
			||||||
 | 
						header->moveToLeft(st::boxPadding.left(), y);
 | 
				
			||||||
 | 
						y += header->height() + st::passportRequestTypeSkip;
 | 
				
			||||||
 | 
						for (const auto &button : buttons) {
 | 
				
			||||||
 | 
							button->resizeToNaturalWidth(innerWidth);
 | 
				
			||||||
 | 
							button->moveToLeft(st::boxPadding.left(), y);
 | 
				
			||||||
 | 
							y += button->heightNoMargins() + st::passportRequestTypeSkip;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						description->resizeToWidth(innerWidth);
 | 
				
			||||||
 | 
						description->moveToLeft(st::boxPadding.left(), y);
 | 
				
			||||||
 | 
						y += description->height() + st::passportRequestTypeSkip;
 | 
				
			||||||
 | 
						_height = y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_submit = [=] {
 | 
				
			||||||
 | 
							const auto value = group->hasValue() ? group->value() : -1;
 | 
				
			||||||
 | 
							if (value >= 0) {
 | 
				
			||||||
 | 
								submit(value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PanelEditDocument::Result {
 | 
					struct PanelEditDocument::Result {
 | 
				
			||||||
	ValueMap data;
 | 
						ValueMap data;
 | 
				
			||||||
| 
						 | 
					@ -97,7 +195,11 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (scanData) {
 | 
						if (scanData) {
 | 
				
			||||||
		_editScans = inner->add(
 | 
							_editScans = inner->add(
 | 
				
			||||||
			object_ptr<EditScans>(inner, _controller, std::move(files)));
 | 
								object_ptr<EditScans>(
 | 
				
			||||||
 | 
									inner,
 | 
				
			||||||
 | 
									_controller,
 | 
				
			||||||
 | 
									_scheme.scansHeader,
 | 
				
			||||||
 | 
									std::move(files)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inner->add(object_ptr<BoxContentDivider>(
 | 
						inner->add(object_ptr<BoxContentDivider>(
 | 
				
			||||||
| 
						 | 
					@ -187,4 +289,24 @@ void PanelEditDocument::save() {
 | 
				
			||||||
		std::move(result.filesData));
 | 
							std::move(result.filesData));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object_ptr<BoxContent> RequestIdentityType(
 | 
				
			||||||
 | 
							base::lambda<void(int index)> submit,
 | 
				
			||||||
 | 
							std::vector<QString> labels) {
 | 
				
			||||||
 | 
						return Box<RequestTypeBox>(
 | 
				
			||||||
 | 
							lang(lng_passport_identity_title),
 | 
				
			||||||
 | 
							lang(lng_passport_identity_about),
 | 
				
			||||||
 | 
							std::move(labels),
 | 
				
			||||||
 | 
							submit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object_ptr<BoxContent> RequestAddressType(
 | 
				
			||||||
 | 
							base::lambda<void(int index)> submit,
 | 
				
			||||||
 | 
							std::vector<QString> labels) {
 | 
				
			||||||
 | 
						return Box<RequestTypeBox>(
 | 
				
			||||||
 | 
							lang(lng_passport_address_title),
 | 
				
			||||||
 | 
							lang(lng_passport_address_about),
 | 
				
			||||||
 | 
							std::move(labels),
 | 
				
			||||||
 | 
							submit);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Passport
 | 
					} // namespace Passport
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@ public:
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		std::vector<Row> rows;
 | 
							std::vector<Row> rows;
 | 
				
			||||||
		QString rowsHeader;
 | 
							QString rowsHeader;
 | 
				
			||||||
 | 
							QString scansHeader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,4 +92,11 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object_ptr<BoxContent> RequestIdentityType(
 | 
				
			||||||
 | 
						base::lambda<void(int index)> submit,
 | 
				
			||||||
 | 
						std::vector<QString> labels);
 | 
				
			||||||
 | 
					object_ptr<BoxContent> RequestAddressType(
 | 
				
			||||||
 | 
						base::lambda<void(int index)> submit,
 | 
				
			||||||
 | 
						std::vector<QString> labels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Passport
 | 
					} // namespace Passport
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,15 +184,16 @@ void ScanButton::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
EditScans::EditScans(
 | 
					EditScans::EditScans(
 | 
				
			||||||
	QWidget *parent,
 | 
						QWidget *parent,
 | 
				
			||||||
	not_null<PanelController*> controller,
 | 
						not_null<PanelController*> controller,
 | 
				
			||||||
 | 
						const QString &header,
 | 
				
			||||||
	std::vector<ScanInfo> &&files)
 | 
						std::vector<ScanInfo> &&files)
 | 
				
			||||||
: RpWidget(parent)
 | 
					: RpWidget(parent)
 | 
				
			||||||
, _controller(controller)
 | 
					, _controller(controller)
 | 
				
			||||||
, _files(std::move(files))
 | 
					, _files(std::move(files))
 | 
				
			||||||
, _content(this) {
 | 
					, _content(this) {
 | 
				
			||||||
	setupContent();
 | 
						setupContent(header);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EditScans::setupContent() {
 | 
					void EditScans::setupContent(const QString &header) {
 | 
				
			||||||
	const auto inner = _content.data();
 | 
						const auto inner = _content.data();
 | 
				
			||||||
	inner->move(0, 0);
 | 
						inner->move(0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,7 +210,7 @@ void EditScans::setupContent() {
 | 
				
			||||||
			inner,
 | 
								inner,
 | 
				
			||||||
			object_ptr<Ui::FlatLabel>(
 | 
								object_ptr<Ui::FlatLabel>(
 | 
				
			||||||
				inner,
 | 
									inner,
 | 
				
			||||||
				lang(lng_passport_upload_header),
 | 
									header,
 | 
				
			||||||
				Ui::FlatLabel::InitType::Simple,
 | 
									Ui::FlatLabel::InitType::Simple,
 | 
				
			||||||
				st::passportFormHeader),
 | 
									st::passportFormHeader),
 | 
				
			||||||
			st::passportUploadHeaderPadding));
 | 
								st::passportUploadHeaderPadding));
 | 
				
			||||||
| 
						 | 
					@ -296,35 +297,36 @@ void EditScans::pushScan(const ScanInfo &info) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EditScans::chooseScan() {
 | 
					void EditScans::chooseScan() {
 | 
				
			||||||
 | 
						ChooseScan(base::lambda_guarded(this, [=](QByteArray &&content) {
 | 
				
			||||||
 | 
							_controller->uploadScan(std::move(content));
 | 
				
			||||||
 | 
						}));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EditScans::ChooseScan(base::lambda<void(QByteArray&&)> callback) {
 | 
				
			||||||
	const auto filter = FileDialog::AllFilesFilter()
 | 
						const auto filter = FileDialog::AllFilesFilter()
 | 
				
			||||||
		+ qsl(";;Image files (*")
 | 
							+ qsl(";;Image files (*")
 | 
				
			||||||
		+ cImgExtensions().join(qsl(" *"))
 | 
							+ cImgExtensions().join(qsl(" *"))
 | 
				
			||||||
		+ qsl(")");
 | 
							+ qsl(")");
 | 
				
			||||||
	const auto callback = [=](FileDialog::OpenResult &&result) {
 | 
						const auto processFile = [=](FileDialog::OpenResult &&result) {
 | 
				
			||||||
		if (result.paths.size() == 1) {
 | 
							if (result.paths.size() == 1) {
 | 
				
			||||||
			encryptScan(result.paths.front());
 | 
								auto content = [&] {
 | 
				
			||||||
 | 
									QFile f(result.paths.front());
 | 
				
			||||||
 | 
									if (!f.open(QIODevice::ReadOnly)) {
 | 
				
			||||||
 | 
										return QByteArray();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return f.readAll();
 | 
				
			||||||
 | 
								}();
 | 
				
			||||||
 | 
								if (!content.isEmpty()) {
 | 
				
			||||||
 | 
									callback(std::move(content));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else if (!result.remoteContent.isEmpty()) {
 | 
							} else if (!result.remoteContent.isEmpty()) {
 | 
				
			||||||
			encryptScanContent(std::move(result.remoteContent));
 | 
								callback(std::move(result.remoteContent));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	FileDialog::GetOpenPath(
 | 
						FileDialog::GetOpenPath(
 | 
				
			||||||
		lang(lng_passport_choose_image),
 | 
							lang(lng_passport_choose_image),
 | 
				
			||||||
		filter,
 | 
							filter,
 | 
				
			||||||
		base::lambda_guarded(this, callback));
 | 
							processFile);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void EditScans::encryptScan(const QString &path) {
 | 
					 | 
				
			||||||
	encryptScanContent([&] {
 | 
					 | 
				
			||||||
		QFile f(path);
 | 
					 | 
				
			||||||
		if (!f.open(QIODevice::ReadOnly)) {
 | 
					 | 
				
			||||||
			return QByteArray();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return f.readAll();
 | 
					 | 
				
			||||||
	}());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void EditScans::encryptScanContent(QByteArray &&content) {
 | 
					 | 
				
			||||||
	_controller->uploadScan(std::move(content));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rpl::producer<QString> EditScans::uploadButtonText() const {
 | 
					rpl::producer<QString> EditScans::uploadButtonText() const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,13 +35,14 @@ public:
 | 
				
			||||||
	EditScans(
 | 
						EditScans(
 | 
				
			||||||
		QWidget *parent,
 | 
							QWidget *parent,
 | 
				
			||||||
		not_null<PanelController*> controller,
 | 
							not_null<PanelController*> controller,
 | 
				
			||||||
 | 
							const QString &header,
 | 
				
			||||||
		std::vector<ScanInfo> &&files);
 | 
							std::vector<ScanInfo> &&files);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void ChooseScan(base::lambda<void(QByteArray&&)> callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void setupContent();
 | 
						void setupContent(const QString &header);
 | 
				
			||||||
	void chooseScan();
 | 
						void chooseScan();
 | 
				
			||||||
	void encryptScan(const QString &path);
 | 
					 | 
				
			||||||
	void encryptScanContent(QByteArray &&content);
 | 
					 | 
				
			||||||
	void updateScan(ScanInfo &&info);
 | 
						void updateScan(ScanInfo &&info);
 | 
				
			||||||
	void pushScan(const ScanInfo &info);
 | 
						void pushScan(const ScanInfo &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue