diff --git a/src/components/sidebarLeft/tabs/2fa/email.ts b/src/components/sidebarLeft/tabs/2fa/email.ts index 5a6d3137..4632b1e5 100644 --- a/src/components/sidebarLeft/tabs/2fa/email.ts +++ b/src/components/sidebarLeft/tabs/2fa/email.ts @@ -5,11 +5,13 @@ import Button from "../../../button"; import SidebarSlider, { SliderSuperTab } from "../../../slider"; import { wrapSticker } from "../../../wrappers"; import InputField from "../../../inputField"; -import { attachClickEvent } from "../../../../helpers/dom"; +import { attachClickEvent, cancelEvent } from "../../../../helpers/dom"; import PopupConfirmAction from "../../../popups/confirmAction"; import { putPreloader } from "../../../misc"; import passwordManager from "../../../../lib/mtproto/passwordManager"; import AppTwoStepVerificationSetTab from "./passwordSet"; +import AppTwoStepVerificationEmailConfirmationTab from "./emailConfirmation"; +import RichTextProcessor from "../../../../lib/richtextprocessor"; export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { public inputField: InputField; @@ -60,7 +62,19 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { const inputField = this.inputField = new InputField({ name: 'recovery-email', - label: 'Recovery Email' + label: 'Recovery Email', + plainText: true + }); + + inputField.input.addEventListener('keypress', (e) => { + if(e.key === 'Enter') { + cancelEvent(e); + return btnContinue.click(); + } + }); + + inputField.input.addEventListener('input', (e) => { + inputField.input.classList.remove('error'); }); const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'}); @@ -70,6 +84,54 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { new AppTwoStepVerificationSetTab(this.slider).open(); }; + attachClickEvent(btnContinue, (e) => { + const email = inputField.value.trim(); + const match = RichTextProcessor.matchEmail(email); + if(!match || match[0].length !== email.length) { + inputField.input.classList.add('error'); + return; + } + + toggleButtons(true); + putPreloader(btnContinue); + + passwordManager.updateSettings({ + hint: this.hint, + currentPassword: this.plainPassword, + newPassword: this.newPassword, + email + }).then((value) => { + goNext(); + }, (err) => { + if(err.type.includes('EMAIL_UNCONFIRMED')) { + const symbols = +err.type.match(/^EMAIL_UNCONFIRMED_(\d+)/)[1]; + + const tab = new AppTwoStepVerificationEmailConfirmationTab(this.slider); + tab.state = this.state; + tab.newPassword = this.newPassword; + tab.plainPassword = this.plainPassword; + tab.hint = this.hint; + tab.email = email; + tab.length = symbols; + tab.open(); + } else { + console.log('password set error', err); + } + + toggleButtons(false); + }); + }); + + const toggleButtons = (freeze: boolean) => { + if(freeze) { + btnContinue.setAttribute('disabled', 'true'); + btnSkip.setAttribute('disabled', 'true'); + } else { + btnContinue.removeAttribute('disabled'); + btnSkip.removeAttribute('disabled'); + } + }; + attachClickEvent(btnSkip, (e) => { const popup = new PopupConfirmAction('popup-skip-email', [{ text: 'CANCEL', @@ -78,8 +140,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { text: 'SKIP', callback: () => { //inputContent.classList.add('sidebar-left-section-disabled'); - btnContinue.setAttribute('disabled', 'true'); - btnSkip.setAttribute('disabled', 'true'); + toggleButtons(true); putPreloader(btnSkip); passwordManager.updateSettings({ hint: this.hint, @@ -88,8 +149,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { }).then(() => { goNext(); }, (err) => { - btnContinue.removeAttribute('disabled'); - btnSkip.removeAttribute('disabled'); + toggleButtons(false); }); }, isDanger: true, diff --git a/src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts b/src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts new file mode 100644 index 00000000..e2163656 --- /dev/null +++ b/src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts @@ -0,0 +1,120 @@ +import { SettingSection } from "../.."; +import { AccountPassword } from "../../../../layer"; +import appStickersManager from "../../../../lib/appManagers/appStickersManager"; +import Button from "../../../button"; +import SidebarSlider, { SliderSuperTab } from "../../../slider"; +import { wrapSticker } from "../../../wrappers"; +import InputField from "../../../inputField"; +import { attachClickEvent } from "../../../../helpers/dom"; +import PopupConfirmAction from "../../../popups/confirmAction"; +import { putPreloader } from "../../../misc"; +import passwordManager from "../../../../lib/mtproto/passwordManager"; +import AppTwoStepVerificationSetTab from "./passwordSet"; + +export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSuperTab { + public inputField: InputField; + public state: AccountPassword; + public plainPassword: string; + public newPassword: string; + public hint: string; + public email: string; + public length: number; + + constructor(slider: SidebarSlider) { + super(slider, true); + } + + protected init() { + this.container.classList.add('two-step-verification', 'two-step-verification-email-confirmation'); + this.title.innerHTML = 'Recovery Email'; + + const section = new SettingSection({ + caption: ' ', + noDelimiter: true + }); + + const emoji = '📬'; + const doc = appStickersManager.getAnimatedEmojiSticker(emoji); + const stickerContainer = document.createElement('div'); + + if(doc) { + wrapSticker({ + doc, + div: stickerContainer, + loop: false, + play: true, + width: 160, + height: 160, + emoji + }).then(() => { + // this.animation = player; + }); + } else { + stickerContainer.classList.add('media-sticker-wrapper'); + } + + section.content.append(stickerContainer); + + const inputContent = section.generateContentElement(); + + const inputWrapper = document.createElement('div'); + inputWrapper.classList.add('input-wrapper'); + + const inputField = this.inputField = new InputField({ + name: 'recovery-email-code', + label: 'Code' + }); + + const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'}); + const btnSkip = Button('btn-primary btn-primary-transparent primary', {text: 'SKIP'}); + + const goNext = () => { + new AppTwoStepVerificationSetTab(this.slider).open(); + }; + + attachClickEvent(btnContinue, (e) => { + + }); + + attachClickEvent(btnSkip, (e) => { + const popup = new PopupConfirmAction('popup-skip-email', [{ + text: 'CANCEL', + isCancel: true + }, { + text: 'SKIP', + callback: () => { + //inputContent.classList.add('sidebar-left-section-disabled'); + btnContinue.setAttribute('disabled', 'true'); + btnSkip.setAttribute('disabled', 'true'); + putPreloader(btnSkip); + passwordManager.updateSettings({ + hint: this.hint, + currentPassword: this.plainPassword, + newPassword: this.newPassword + }).then(() => { + goNext(); + }, (err) => { + btnContinue.removeAttribute('disabled'); + btnSkip.removeAttribute('disabled'); + }); + }, + isDanger: true, + }], { + title: 'Warning', + text: 'No, seriously.

If you forget your password, you will lose access to your Telegram account. There will be no way to restore it.' + }); + + popup.show(); + }); + + inputWrapper.append(inputField.container, btnContinue, btnSkip); + + inputContent.append(inputWrapper); + + this.scrollable.container.append(section.container); + } + + onOpenAfterTimeout() { + this.inputField.input.focus(); + } +} diff --git a/src/components/sidebarLeft/tabs/2fa/passwordSet.ts b/src/components/sidebarLeft/tabs/2fa/passwordSet.ts index 88419395..a2ae3bfa 100644 --- a/src/components/sidebarLeft/tabs/2fa/passwordSet.ts +++ b/src/components/sidebarLeft/tabs/2fa/passwordSet.ts @@ -28,7 +28,7 @@ export default class AppTwoStepVerificationSetTab extends SliderSuperTab { wrapSticker({ doc, div: stickerContainer, - loop: false, + loop: true, play: true, width: 160, height: 160, diff --git a/src/lib/richtextprocessor.ts b/src/lib/richtextprocessor.ts index 8e0e0c48..89430732 100644 --- a/src/lib/richtextprocessor.ts +++ b/src/lib/richtextprocessor.ts @@ -725,6 +725,10 @@ namespace RichTextProcessor { return !text ? null : text.match(urlRegExp); } + export function matchEmail(text: string) { + return !text ? null : text.match(emailRegExp); + } + export function getAbbreviation(str: string, onlyFirst = false) { const splitted = str.trim().split(' '); if(!splitted[0]) return ''; diff --git a/src/scss/partials/_chatBubble.scss b/src/scss/partials/_chatBubble.scss index 01298551..6f6cee41 100644 --- a/src/scss/partials/_chatBubble.scss +++ b/src/scss/partials/_chatBubble.scss @@ -506,6 +506,7 @@ $bubble-margin: .25rem; &.sticker { .attachment { border-radius: 0; + z-index: 1; } .bubble-content {