Translated 2FA
Fix blinking QR Preload monkeys in filters and 2FA
This commit is contained in:
parent
081ce3e316
commit
a720439b6f
@ -12,7 +12,8 @@ export type CheckboxFieldOptions = {
|
||||
disabled?: boolean,
|
||||
checked?: boolean,
|
||||
restriction?: boolean,
|
||||
withRipple?: boolean
|
||||
withRipple?: boolean,
|
||||
withHover?: boolean,
|
||||
};
|
||||
export default class CheckboxField {
|
||||
public input: HTMLInputElement;
|
||||
@ -92,6 +93,8 @@ export default class CheckboxField {
|
||||
if(options.withRipple) {
|
||||
label.classList.add('checkbox-ripple', 'hover-effect');
|
||||
ripple(label, undefined, undefined, true);
|
||||
} else if(options.withHover) {
|
||||
label.classList.add('hover-effect');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ export default class CodeInputField extends InputField {
|
||||
let lastLength = 0;
|
||||
this.input.addEventListener('input', (e) => {
|
||||
this.input.classList.remove('error');
|
||||
this.label.innerText = options.label;
|
||||
this.setLabel();
|
||||
|
||||
const value = this.value.replace(/\D/g, '').slice(0, options.length);
|
||||
this.setValueSilently(value);
|
||||
|
@ -62,6 +62,7 @@ export type InputFieldOptions = {
|
||||
placeholder?: LangPackKey,
|
||||
label?: LangPackKey,
|
||||
labelOptions?: any[],
|
||||
labelText?: string,
|
||||
name?: string,
|
||||
maxLength?: number,
|
||||
showLengthOn?: number,
|
||||
@ -89,7 +90,9 @@ class InputField {
|
||||
options.showLengthOn = Math.round(options.maxLength / 3);
|
||||
}
|
||||
|
||||
const {placeholder, label, maxLength, showLengthOn, name, plainText} = options;
|
||||
const {placeholder, maxLength, showLengthOn, name, plainText} = options;
|
||||
|
||||
let label = options.label || options.labelText;
|
||||
|
||||
let input: HTMLElement;
|
||||
if(!plainText) {
|
||||
@ -148,7 +151,7 @@ class InputField {
|
||||
|
||||
if(label) {
|
||||
this.label = document.createElement('label');
|
||||
this.label.append(i18n(label, options.labelOptions));
|
||||
this.setLabel();
|
||||
this.container.append(this.label);
|
||||
}
|
||||
|
||||
@ -168,12 +171,11 @@ class InputField {
|
||||
//this.onLengthChange && this.onLengthChange(inputLength, isError);
|
||||
|
||||
if(isError || diff <= showLengthOn) {
|
||||
labelEl.innerHTML = '';
|
||||
labelEl.append(i18n(label, options.labelOptions), ` (${maxLength - inputLength})`);
|
||||
this.setLabel();
|
||||
labelEl.append(` (${maxLength - inputLength})`);
|
||||
if(!showingLength) showingLength = true;
|
||||
} else if((wasError && !isError) || showingLength) {
|
||||
labelEl.innerHTML = '';
|
||||
labelEl.append(i18n(label, options.labelOptions));
|
||||
this.setLabel();
|
||||
showingLength = false;
|
||||
}
|
||||
};
|
||||
@ -184,6 +186,15 @@ class InputField {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public setLabel() {
|
||||
this.label.textContent = '';
|
||||
if(this.options.labelText) {
|
||||
this.label.innerHTML = this.options.labelText;
|
||||
} else {
|
||||
this.label.append(i18n(this.options.label, this.options.labelOptions));
|
||||
}
|
||||
}
|
||||
|
||||
public onFakeInput() {
|
||||
const {scrollHeight, clientHeight} = this.inputFake;
|
||||
if(this.wasInputFakeClientHeight && this.wasInputFakeClientHeight !== clientHeight) {
|
||||
|
@ -73,7 +73,7 @@ export function putPreloader(elem: Element, returnDiv = false): HTMLElement {
|
||||
return div;
|
||||
}
|
||||
|
||||
elem.innerHTML += html;
|
||||
elem.insertAdjacentHTML('beforeend', html);
|
||||
return elem.lastElementChild as HTMLElement;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ export default class PasswordMonkey {
|
||||
public container: HTMLElement;
|
||||
public animation: RLottiePlayer;
|
||||
public needFrame = 0;
|
||||
protected loadPromise: Promise<any>;
|
||||
protected loadPromise: Promise<void>;
|
||||
|
||||
constructor(protected passwordInputField: PasswordInputField, protected size: number) {
|
||||
this.container = document.createElement('div');
|
||||
@ -48,6 +48,8 @@ export default class PasswordMonkey {
|
||||
this.animation.play();
|
||||
}
|
||||
};
|
||||
|
||||
return lottieLoader.waitForFirstFrame(_animation);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,8 @@ export default class TrackingMonkey {
|
||||
if(!this.inputField.value.length) {
|
||||
animation.play();
|
||||
}
|
||||
|
||||
return lottieLoader.waitForFirstFrame(animation);
|
||||
}),
|
||||
|
||||
lottieLoader.loadAnimationFromURL({
|
||||
@ -131,6 +133,8 @@ export default class TrackingMonkey {
|
||||
}
|
||||
});
|
||||
//console.log(animation.getDuration(), animation.getDuration(true));
|
||||
|
||||
return lottieLoader.waitForFirstFrame(_animation);
|
||||
})
|
||||
]);
|
||||
}
|
||||
@ -139,6 +143,4 @@ export default class TrackingMonkey {
|
||||
if(this.animation) this.animation.remove();
|
||||
if(this.idleAnimation) this.idleAnimation.remove();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -8,7 +8,8 @@ export default class PasswordInputField extends InputField {
|
||||
|
||||
constructor(options: {
|
||||
label?: string,
|
||||
name?: string
|
||||
name?: string,
|
||||
labelText?: string,
|
||||
} = {}) {
|
||||
super({
|
||||
plainText: true,
|
||||
|
@ -23,7 +23,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-email');
|
||||
this.title.innerHTML = 'Recovery Email';
|
||||
this.setTitle('RecoveryEmailTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: '',
|
||||
@ -59,7 +59,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
|
||||
const inputField = this.inputField = new InputField({
|
||||
name: 'recovery-email',
|
||||
label: 'Recovery Email',
|
||||
label: 'RecoveryEmail',
|
||||
plainText: true
|
||||
});
|
||||
|
||||
@ -74,8 +74,8 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
inputField.input.classList.remove('error');
|
||||
});
|
||||
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'});
|
||||
const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'SKIP'});
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});
|
||||
const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'YourEmailSkip'});
|
||||
|
||||
const goNext = () => {
|
||||
new AppTwoStepVerificationSetTab(this.slider).open();
|
||||
@ -131,10 +131,10 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
attachClickEvent(btnSkip, (e) => {
|
||||
const popup = new PopupPeer('popup-skip-email', {
|
||||
buttons: [{
|
||||
text: 'CANCEL',
|
||||
langKey: 'Cancel',
|
||||
isCancel: true
|
||||
}, {
|
||||
text: 'SKIP',
|
||||
langKey: 'YourEmailSkip',
|
||||
callback: () => {
|
||||
//inputContent.classList.add('sidebar-left-section-disabled');
|
||||
toggleButtons(true);
|
||||
@ -152,8 +152,8 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
},
|
||||
isDanger: true,
|
||||
}],
|
||||
titleLangKey: 'Warning',
|
||||
descriptionLangKey: 'No, seriously.<br/><br/>If you forget your password, you will lose access to your Telegram account. There will be no way to restore it.'
|
||||
titleLangKey: 'YourEmailSkipWarning',
|
||||
descriptionLangKey: 'YourEmailSkipWarningText'
|
||||
});
|
||||
|
||||
popup.show();
|
||||
|
@ -4,12 +4,13 @@ import appStickersManager from "../../../../lib/appManagers/appStickersManager";
|
||||
import Button from "../../../button";
|
||||
import { SliderSuperTab } from "../../../slider";
|
||||
import { wrapSticker } from "../../../wrappers";
|
||||
import { attachClickEvent, canFocus, toggleDisability } from "../../../../helpers/dom";
|
||||
import { attachClickEvent, canFocus, replaceContent, toggleDisability } from "../../../../helpers/dom";
|
||||
import passwordManager from "../../../../lib/mtproto/passwordManager";
|
||||
import AppTwoStepVerificationSetTab from "./passwordSet";
|
||||
import CodeInputField from "../../../codeInputField";
|
||||
import AppTwoStepVerificationEmailTab from "./email";
|
||||
import { putPreloader } from "../../../misc";
|
||||
import { i18n, _i18n } from "../../../../lib/langPack";
|
||||
|
||||
export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSuperTab {
|
||||
public codeInputField: CodeInputField;
|
||||
@ -20,14 +21,14 @@ export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSu
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-email-confirmation');
|
||||
this.title.innerHTML = 'Recovery Email';
|
||||
this.setTitle('TwoStepAuth.RecoveryTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: 'Please enter code we\'ve just emailed at <b></b>',
|
||||
caption: true,
|
||||
noDelimiter: true
|
||||
});
|
||||
|
||||
(section.caption.lastElementChild as HTMLElement).innerText = this.email;
|
||||
_i18n(section.caption, 'TwoStepAuth.ConfirmEmailCodeDesc', [this.email]);
|
||||
|
||||
const emoji = '📬';
|
||||
const doc = appStickersManager.getAnimatedEmojiSticker(emoji);
|
||||
@ -58,7 +59,7 @@ export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSu
|
||||
|
||||
const inputField = this.codeInputField = new CodeInputField({
|
||||
name: 'recovery-email-code',
|
||||
label: 'Code',
|
||||
label: 'TwoStepAuth.RecoveryCode',
|
||||
length: this.length,
|
||||
onFill: (code) => {
|
||||
freeze(true);
|
||||
@ -75,7 +76,12 @@ export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSu
|
||||
switch(err.type) {
|
||||
case 'CODE_INVALID':
|
||||
inputField.input.classList.add('error');
|
||||
inputField.label.innerText = 'Invalid Code';
|
||||
replaceContent(inputField.label, i18n('TwoStepAuth.RecoveryCodeInvalid'));
|
||||
break;
|
||||
|
||||
case 'EMAIL_HASH_EXPIRED':
|
||||
inputField.input.classList.add('error');
|
||||
replaceContent(inputField.label, i18n('TwoStepAuth.RecoveryCodeExpired'));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -88,8 +94,8 @@ export default class AppTwoStepVerificationEmailConfirmationTab extends SliderSu
|
||||
}
|
||||
});
|
||||
|
||||
const btnChange = Button('btn-primary btn-primary-transparent primary', {text: 'CHANGE EMAIL'});
|
||||
const btnResend = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'RE-SEND CODE'});
|
||||
const btnChange = Button('btn-primary btn-primary-transparent primary', {text: 'TwoStepAuth.EmailCodeChangeEmail'});
|
||||
const btnResend = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'ResendCode'});
|
||||
|
||||
const goNext = () => {
|
||||
new AppTwoStepVerificationSetTab(this.slider).open();
|
||||
|
@ -1,14 +1,14 @@
|
||||
import AppTwoStepVerificationTab from ".";
|
||||
import { SettingSection } from "../..";
|
||||
import { attachClickEvent, cancelEvent, canFocus } from "../../../../helpers/dom";
|
||||
import { attachClickEvent, cancelEvent, canFocus, replaceContent } from "../../../../helpers/dom";
|
||||
import { AccountPassword } from "../../../../layer";
|
||||
import I18n, { i18n } from "../../../../lib/langPack";
|
||||
import passwordManager from "../../../../lib/mtproto/passwordManager";
|
||||
import RichTextProcessor from "../../../../lib/richtextprocessor";
|
||||
import Button from "../../../button";
|
||||
import { putPreloader } from "../../../misc";
|
||||
import PasswordMonkey from "../../../monkeys/password";
|
||||
import PasswordInputField from "../../../passwordInputField";
|
||||
import { ripple } from "../../../ripple";
|
||||
import { SliderSuperTab } from "../../../slider";
|
||||
import AppTwoStepVerificationReEnterPasswordTab from "./reEnterPassword";
|
||||
|
||||
@ -21,7 +21,7 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
protected init() {
|
||||
const isNew = !this.state.pFlags.has_password || this.plainPassword;
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-enter-password');
|
||||
this.title.innerHTML = isNew ? 'Enter a Password' : 'Enter your Password';
|
||||
this.setTitle(isNew ? 'PleaseEnterFirstPassword' : 'PleaseEnterCurrentPassword');
|
||||
|
||||
const section = new SettingSection({
|
||||
noDelimiter: true
|
||||
@ -32,13 +32,16 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
|
||||
const passwordInputField = this.passwordInputField = new PasswordInputField({
|
||||
name: 'enter-password',
|
||||
label: isNew ? 'Enter a Password' : (this.state.hint ?? 'Password')
|
||||
label: isNew ? 'PleaseEnterFirstPassword' : (this.state.hint ? undefined : 'LoginPassword'),
|
||||
labelText: !isNew && this.state.hint ? RichTextProcessor.wrapEmojiText(this.state.hint) : undefined
|
||||
});
|
||||
|
||||
const monkey = new PasswordMonkey(passwordInputField, 157);
|
||||
monkey.load();
|
||||
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'});
|
||||
const btnContinue = Button('btn-primary btn-color-primary');
|
||||
const textEl = new I18n.IntlElement({key: 'Continue'});
|
||||
|
||||
btnContinue.append(textEl.element);
|
||||
|
||||
inputWrapper.append(passwordInputField.container, btnContinue);
|
||||
section.content.append(monkey.container, inputWrapper);
|
||||
@ -48,8 +51,8 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
passwordInputField.input.addEventListener('keypress', (e) => {
|
||||
if(passwordInputField.input.classList.contains('error')) {
|
||||
passwordInputField.input.classList.remove('error');
|
||||
btnContinue.innerText = 'CONTINUE';
|
||||
ripple(btnContinue);
|
||||
textEl.key = 'Continue';
|
||||
textEl.update();
|
||||
}
|
||||
|
||||
if(e.key === 'Enter') {
|
||||
@ -79,7 +82,11 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
return passwordManager.getState().then(_state => {
|
||||
this.state = _state;
|
||||
|
||||
passwordInputField.label.innerHTML = this.state.hint ? RichTextProcessor.wrapEmojiText(this.state.hint) : 'Password';
|
||||
if(this.state.hint) {
|
||||
passwordInputField.label.innerHTML = RichTextProcessor.wrapEmojiText(this.state.hint);
|
||||
} else {
|
||||
replaceContent(passwordInputField.label, i18n('LoginPassword'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -90,8 +97,9 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
}
|
||||
|
||||
btnContinue.setAttribute('disabled', 'true');
|
||||
btnContinue.textContent = 'PLEASE WAIT...';
|
||||
putPreloader(btnContinue);
|
||||
textEl.key = 'PleaseWait';
|
||||
textEl.update();
|
||||
const preloader = putPreloader(btnContinue);
|
||||
|
||||
const plainPassword = passwordInputField.value;
|
||||
passwordManager.check(passwordInputField.value, this.state).then(auth => {
|
||||
@ -113,7 +121,9 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
switch(err.type) {
|
||||
default:
|
||||
//btnContinue.innerText = err.type;
|
||||
btnContinue.innerText = 'INVALID PASSWORD';
|
||||
textEl.key = 'TwoStepAuth.InvalidPassword';
|
||||
textEl.update();
|
||||
preloader.remove();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -141,6 +151,8 @@ export default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperT
|
||||
}
|
||||
|
||||
attachClickEvent(btnContinue, onContinueClick);
|
||||
|
||||
return monkey.load();
|
||||
}
|
||||
|
||||
onOpenAfterTimeout() {
|
||||
|
@ -8,6 +8,7 @@ import InputField from "../../../inputField";
|
||||
import AppTwoStepVerificationEmailTab from "./email";
|
||||
import { attachClickEvent, cancelEvent } from "../../../../helpers/dom";
|
||||
import { toast } from "../../../toast";
|
||||
import I18n from "../../../../lib/langPack";
|
||||
|
||||
export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
|
||||
public inputField: InputField;
|
||||
@ -17,7 +18,7 @@ export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-hint');
|
||||
this.title.innerHTML = 'Password Hint';
|
||||
this.setTitle('TwoStepAuth.SetupHintTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
noDelimiter: true
|
||||
@ -50,7 +51,7 @@ export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
|
||||
|
||||
const inputField = this.inputField = new InputField({
|
||||
name: 'hint',
|
||||
label: 'Hint'
|
||||
label: 'TwoStepAuth.SetupHintPlaceholder'
|
||||
});
|
||||
|
||||
inputField.input.addEventListener('keypress', (e) => {
|
||||
@ -67,7 +68,7 @@ export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
|
||||
|
||||
const hint = saveHint ? inputField.value : undefined;
|
||||
if(hint && this.newPassword === hint) {
|
||||
toast('Hint must be different from your password');
|
||||
toast(I18n.format('PasswordAsHintError', true));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,8 +81,8 @@ export default class AppTwoStepVerificationHintTab extends SliderSuperTab {
|
||||
tab.open();
|
||||
};
|
||||
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'});
|
||||
const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'SKIP'});
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});
|
||||
const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'YourEmailSkip'});
|
||||
|
||||
const onContinueClick = (e?: Event) => goNext(e, true);
|
||||
const onSkipClick = (e?: Event) => goNext(e, false);
|
||||
|
@ -2,6 +2,7 @@ import { SettingSection } from "../..";
|
||||
import { attachClickEvent } from "../../../../helpers/dom";
|
||||
import { AccountPassword } from "../../../../layer";
|
||||
import appStickersManager from "../../../../lib/appManagers/appStickersManager";
|
||||
import { _i18n } from "../../../../lib/langPack";
|
||||
import passwordManager from "../../../../lib/mtproto/passwordManager";
|
||||
import Button from "../../../button";
|
||||
import PopupPeer from "../../../popups/peer";
|
||||
@ -17,7 +18,7 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-main');
|
||||
this.title.innerHTML = 'Two-Step Verification';
|
||||
this.setTitle('TwoStepVerificationTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: ' ',
|
||||
@ -48,11 +49,11 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
|
||||
const c = section.generateContentElement();
|
||||
if(this.state.pFlags.has_password) {
|
||||
section.caption.innerHTML = 'You have enabled Two-Step verification.<br/>You\'ll need the password you set up here to log in to your Telegram account.';
|
||||
_i18n(section.caption, 'TwoStepAuth.GenericHelp');
|
||||
|
||||
const btnChangePassword = Button('btn-primary btn-transparent', {icon: 'edit', text: 'Change Password'});
|
||||
const btnDisablePassword = Button('btn-primary btn-transparent', {icon: 'passwordoff', text: 'Turn Password Off'});
|
||||
const btnSetRecoveryEmail = Button('btn-primary btn-transparent', {icon: 'email', text: this.state.pFlags.has_recovery ? 'Change Recovery Email' : 'Set Recovery Email'});
|
||||
const btnChangePassword = Button('btn-primary btn-transparent', {icon: 'edit', text: 'TwoStepAuth.ChangePassword'});
|
||||
const btnDisablePassword = Button('btn-primary btn-transparent', {icon: 'passwordoff', text: 'TwoStepAuth.RemovePassword'});
|
||||
const btnSetRecoveryEmail = Button('btn-primary btn-transparent', {icon: 'email', text: this.state.pFlags.has_recovery ? 'TwoStepAuth.ChangeEmail' : 'TwoStepAuth.SetupEmail'});
|
||||
|
||||
attachClickEvent(btnChangePassword, () => {
|
||||
const tab = new AppTwoStepVerificationEnterPasswordTab(this.slider);
|
||||
@ -64,7 +65,7 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
attachClickEvent(btnDisablePassword, () => {
|
||||
const popup = new PopupPeer('popup-disable-password', {
|
||||
buttons: [{
|
||||
text: 'DISABLE',
|
||||
langKey: 'Disable',
|
||||
callback: () => {
|
||||
passwordManager.updateSettings({currentPassword: this.plainPassword}).then(() => {
|
||||
this.slider.sliceTabsUntilTab(AppSettingsTab, this);
|
||||
@ -73,8 +74,8 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
},
|
||||
isDanger: true,
|
||||
}],
|
||||
titleLangKey: 'Warning',
|
||||
descriptionLangKey: 'Are you sure you want to disable<br/>your password?'
|
||||
titleLangKey: 'TurnPasswordOffQuestionTitle',
|
||||
descriptionLangKey: 'TurnPasswordOffQuestion'
|
||||
});
|
||||
|
||||
popup.show();
|
||||
@ -92,12 +93,12 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
|
||||
c.append(btnChangePassword, btnDisablePassword, btnSetRecoveryEmail);
|
||||
} else {
|
||||
section.caption.innerHTML = 'You can set a password that will be required when you log in on a new device in addition to the code you get in the SMS.';
|
||||
_i18n(section.caption, 'TwoStepAuth.SetPasswordHelp');
|
||||
|
||||
const inputWrapper = document.createElement('div');
|
||||
inputWrapper.classList.add('input-wrapper');
|
||||
|
||||
const btnSetPassword = Button('btn-primary btn-color-primary', {text: 'SET PASSWORD'});
|
||||
const btnSetPassword = Button('btn-primary btn-color-primary', {text: 'TwoStepVerificationSetPassword'});
|
||||
|
||||
inputWrapper.append(btnSetPassword);
|
||||
c.append(inputWrapper);
|
||||
|
@ -2,17 +2,17 @@ import { SettingSection } from "../..";
|
||||
import { attachClickEvent } from "../../../../helpers/dom";
|
||||
import appStickersManager from "../../../../lib/appManagers/appStickersManager";
|
||||
import Button from "../../../button";
|
||||
import SidebarSlider, { SliderSuperTab } from "../../../slider";
|
||||
import { SliderSuperTab } from "../../../slider";
|
||||
import { wrapSticker } from "../../../wrappers";
|
||||
import AppSettingsTab from "../settings";
|
||||
|
||||
export default class AppTwoStepVerificationSetTab extends SliderSuperTab {
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-set');
|
||||
this.title.innerHTML = 'Password Set!';
|
||||
this.setTitle('TwoStepVerificationPasswordSet');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: 'This password will be required when you log in on a new device in addition to the code you get via SMS.',
|
||||
caption: 'TwoStepVerificationPasswordSetInfo',
|
||||
noDelimiter: true
|
||||
});
|
||||
|
||||
@ -42,7 +42,7 @@ export default class AppTwoStepVerificationSetTab extends SliderSuperTab {
|
||||
const inputWrapper = document.createElement('div');
|
||||
inputWrapper.classList.add('input-wrapper');
|
||||
|
||||
const btnReturn = Button('btn-primary btn-color-primary', {text: 'RETURN TO SETTINGS'});
|
||||
const btnReturn = Button('btn-primary btn-color-primary', {text: 'TwoStepVerificationPasswordReturnSettings'});
|
||||
|
||||
attachClickEvent(btnReturn, (e) => {
|
||||
this.close();
|
||||
|
@ -3,10 +3,10 @@ import { attachClickEvent, cancelEvent } from "../../../../helpers/dom";
|
||||
import { AccountPassword } from "../../../../layer";
|
||||
import Button from "../../../button";
|
||||
import PasswordInputField from "../../../passwordInputField";
|
||||
import { ripple } from "../../../ripple";
|
||||
import { SliderSuperTab } from "../../../slider";
|
||||
import TrackingMonkey from "../../../monkeys/tracking";
|
||||
import AppTwoStepVerificationHintTab from "./hint";
|
||||
import { InputState } from "../../../inputField";
|
||||
|
||||
export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSuperTab {
|
||||
public state: AccountPassword;
|
||||
@ -16,7 +16,7 @@ export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSupe
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('two-step-verification', 'two-step-verification-enter-password', 'two-step-verification-re-enter-password');
|
||||
this.title.innerHTML = 'Re-Enter your Password';
|
||||
this.setTitle('PleaseReEnterPassword');
|
||||
|
||||
const section = new SettingSection({
|
||||
noDelimiter: true
|
||||
@ -27,13 +27,12 @@ export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSupe
|
||||
|
||||
const passwordInputField = this.passwordInputField = new PasswordInputField({
|
||||
name: 're-enter-password',
|
||||
label: 'Re-Enter your Password'
|
||||
label: 'PleaseReEnterPassword'
|
||||
});
|
||||
|
||||
const monkey = new TrackingMonkey(passwordInputField, 157);
|
||||
monkey.load();
|
||||
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'CONTINUE'});
|
||||
const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});
|
||||
|
||||
inputWrapper.append(passwordInputField.container, btnContinue);
|
||||
section.content.append(monkey.container, inputWrapper);
|
||||
@ -42,9 +41,7 @@ export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSupe
|
||||
|
||||
passwordInputField.input.addEventListener('keypress', (e) => {
|
||||
if(passwordInputField.input.classList.contains('error')) {
|
||||
passwordInputField.input.classList.remove('error');
|
||||
btnContinue.innerText = 'CONTINUE';
|
||||
ripple(btnContinue);
|
||||
passwordInputField.setState(InputState.Neutral);
|
||||
}
|
||||
|
||||
if(e.key === 'Enter') {
|
||||
@ -54,7 +51,7 @@ export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSupe
|
||||
|
||||
const verifyInput = () => {
|
||||
if(this.newPassword !== passwordInputField.value) {
|
||||
passwordInputField.input.classList.add('error');
|
||||
passwordInputField.setError();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -75,6 +72,8 @@ export default class AppTwoStepVerificationReEnterPasswordTab extends SliderSupe
|
||||
tab.open();
|
||||
};
|
||||
attachClickEvent(btnContinue, onContinueClick);
|
||||
|
||||
return monkey.load();
|
||||
}
|
||||
|
||||
onOpenAfterTimeout() {
|
||||
|
@ -25,6 +25,7 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||
private animation: RLottiePlayer;
|
||||
|
||||
private filtersRendered: {[filterId: number]: HTMLElement} = {};
|
||||
private loadAnimationPromise: Promise<void>;
|
||||
|
||||
private renderFolder(dialogFilter: DialogFilterSuggested | DialogFilter | MyDialogFilter, container?: HTMLElement, div?: HTMLElement) {
|
||||
let filter: DialogFilter | MyDialogFilter;
|
||||
@ -101,7 +102,7 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||
return div;
|
||||
}
|
||||
|
||||
protected init() {
|
||||
protected async init() {
|
||||
this.container.classList.add('chat-folders-container');
|
||||
this.setTitle('ChatList.Filter.List.Title');
|
||||
|
||||
@ -139,16 +140,6 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||
}
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
|
||||
lottieLoader.loadAnimationFromURL({
|
||||
container: this.stickerContainer,
|
||||
loop: false,
|
||||
autoplay: true,
|
||||
width: 86,
|
||||
height: 86
|
||||
}, 'assets/img/Folders_1.tgs').then(player => {
|
||||
this.animation = player;
|
||||
});
|
||||
|
||||
const onFiltersContainerUpdate = () => {
|
||||
this.foldersSection.container.style.display = Object.keys(this.filtersRendered).length ? '' : 'none';
|
||||
};
|
||||
@ -200,6 +191,25 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||
});
|
||||
|
||||
this.getSuggestedFilters();
|
||||
|
||||
return this.loadAnimationPromise = lottieLoader.loadAnimationFromURL({
|
||||
container: this.stickerContainer,
|
||||
loop: false,
|
||||
autoplay: false,
|
||||
width: 86,
|
||||
height: 86
|
||||
}, 'assets/img/Folders_1.tgs').then(player => {
|
||||
this.animation = player;
|
||||
|
||||
return lottieLoader.waitForFirstFrame(player);
|
||||
});
|
||||
}
|
||||
|
||||
onOpenAfterTimeout() {
|
||||
this.loadAnimationPromise.then(() => {
|
||||
this.animation.autoplay = true;
|
||||
this.animation.play();
|
||||
});
|
||||
}
|
||||
|
||||
private getSuggestedFilters() {
|
||||
@ -234,10 +244,4 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
if(this.animation) {
|
||||
this.animation.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
||||
private originalFilter: DialogFilter;
|
||||
|
||||
private type: 'edit' | 'create';
|
||||
private loadAnimationPromise: Promise<void>;
|
||||
|
||||
protected init() {
|
||||
this.container.classList.add('edit-folder-container');
|
||||
@ -160,16 +161,6 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
||||
new AppIncludedChatsTab(this.slider).open(this.filter, 'excluded', this);
|
||||
});
|
||||
|
||||
lottieLoader.loadAnimationFromURL({
|
||||
container: this.stickerContainer,
|
||||
loop: false,
|
||||
autoplay: true,
|
||||
width: 86,
|
||||
height: 86
|
||||
}, 'assets/img/Folders_2.tgs').then(player => {
|
||||
this.animation = player;
|
||||
});
|
||||
|
||||
this.confirmBtn.addEventListener('click', () => {
|
||||
if(this.nameInputField.input.classList.contains('error')) {
|
||||
return;
|
||||
@ -216,12 +207,25 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
||||
this.filter.title = this.nameInputField.value;
|
||||
this.editCheckForChange();
|
||||
});
|
||||
|
||||
return this.loadAnimationPromise = lottieLoader.loadAnimationFromURL({
|
||||
container: this.stickerContainer,
|
||||
loop: false,
|
||||
autoplay: false,
|
||||
width: 86,
|
||||
height: 86
|
||||
}, 'assets/img/Folders_2.tgs').then(player => {
|
||||
this.animation = player;
|
||||
|
||||
return lottieLoader.waitForFirstFrame(player);
|
||||
});
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
if(this.animation) {
|
||||
this.animation.restart();
|
||||
}
|
||||
onOpenAfterTimeout() {
|
||||
this.loadAnimationPromise.then(() => {
|
||||
this.animation.autoplay = true;
|
||||
this.animation.play();
|
||||
});
|
||||
}
|
||||
|
||||
private onCreateOpen() {
|
||||
|
@ -11,6 +11,7 @@ import AppChatFoldersTab from "./chatFolders";
|
||||
import AppNotificationsTab from "./notifications";
|
||||
import PeerTitle from "../../peerTitle";
|
||||
import AppLanguageTab from "./language";
|
||||
import lottieLoader from "../../../lib/lottieLoader";
|
||||
//import AppMediaViewer from "../../appMediaViewerNew";
|
||||
|
||||
export default class AppSettingsTab extends SliderSuperTab {
|
||||
@ -27,7 +28,7 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
language: HTMLButtonElement
|
||||
} = {} as any;
|
||||
|
||||
init() {
|
||||
protected init() {
|
||||
this.container.classList.add('settings-container');
|
||||
this.setTitle('Settings');
|
||||
|
||||
@ -135,6 +136,10 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
this.buttons.language.addEventListener('click', () => {
|
||||
new AppLanguageTab(this.slider).open();
|
||||
});
|
||||
|
||||
lottieLoader.loadLottieWorkers();
|
||||
|
||||
this.fillElements();
|
||||
}
|
||||
|
||||
public fillElements() {
|
||||
@ -144,13 +149,4 @@ export default class AppSettingsTab extends SliderSuperTab {
|
||||
this.nameDiv.append(new PeerTitle({peerId: user.id}).element);
|
||||
this.phoneDiv.innerHTML = user.rPhone || '';
|
||||
}
|
||||
|
||||
public onOpen() {
|
||||
if(this.init) {
|
||||
this.init();
|
||||
this.init = null;
|
||||
}
|
||||
|
||||
this.fillElements();
|
||||
}
|
||||
}
|
||||
|
@ -71,8 +71,13 @@ export default class SliderSuperTab implements SliderTab {
|
||||
if(this.init) {
|
||||
const result = this.init();
|
||||
this.init = null;
|
||||
|
||||
if(result instanceof Promise) {
|
||||
try {
|
||||
await result;
|
||||
} catch(err) {
|
||||
console.error('open tab error', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ const App = {
|
||||
hash: '452b0359b988148995f22ff0f4229750',
|
||||
version: '0.4.0',
|
||||
langPackVersion: '0.0.5',
|
||||
langPack: 'macos',
|
||||
domains: [] as string[],
|
||||
baseDcId: 2
|
||||
};
|
||||
|
@ -105,7 +105,7 @@ function runNow(fn: NoneToVoidFunction) {
|
||||
fn();
|
||||
} */
|
||||
|
||||
export const pause = (ms: number) => new Promise((resolve) => {
|
||||
export const pause = (ms: number) => new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
||||
</div>
|
||||
<h4>Scan from mobile Telegram</h4>
|
||||
<p class="qr-description">1. Open Telegram on your phone<br>2. Go to settings > Devices > Scan QR<br>3. Scan this image to Log in</p>
|
||||
<div class="qr"><a href="#" class="a-qr">Or log in using your phone number</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-authCode">
|
||||
|
39
src/lang.ts
39
src/lang.ts
@ -87,6 +87,9 @@ const lang = {
|
||||
"Popup.Unpin.HideTitle": "Hide pinned messages",
|
||||
"Popup.Unpin.HideDescription": "Do you want to hide the pinned message bar? It wil stay hidden until a new message is pinned.",
|
||||
"Popup.Unpin.Hide": "Hide",
|
||||
"TwoStepAuth.InvalidPassword": "Invalid password",
|
||||
"TwoStepAuth.EmailCodeChangeEmail": "Change Email",
|
||||
"PleaseWait": "Please wait...",
|
||||
|
||||
// * android
|
||||
"ActionCreateChannel": "Channel created",
|
||||
@ -197,6 +200,7 @@ const lang = {
|
||||
"BlockedUsersInfo": "Blocked users will not be able to contact you and will not see your Last Seen time.",
|
||||
"BlockedEmpty": "None",
|
||||
"TwoStepVerification": "Two-Step Verification",
|
||||
"TwoStepVerificationTitle": "Two-Step Verification",
|
||||
"PinnedMessage": "Pinned Message",
|
||||
"PinnedMessagesCount": {
|
||||
"one_value": "Pinned Message",
|
||||
@ -352,6 +356,25 @@ const lang = {
|
||||
"ChannelLeaveAlertWithName": "Are you sure you want to leave **%1$s**?",
|
||||
"LeaveMegaMenu": "Leave group",
|
||||
"DeleteChatUser": "Delete chat",
|
||||
"PleaseEnterCurrentPassword": "Enter your password",
|
||||
"PleaseEnterFirstPassword": "Enter a password",
|
||||
"PleaseReEnterPassword": "Re-enter your password",
|
||||
"LoginPassword": "Password",
|
||||
"Continue": "Continue",
|
||||
"YourEmailSkip": "Skip",
|
||||
"YourEmailSkipWarning": "Warning",
|
||||
"YourEmailSkipWarningText": "No, seriously.\n\nIf you forget your password, you will lose access to your Telegram account. There will be no way to restore it.",
|
||||
"TurnPasswordOffQuestionTitle": "Disable password",
|
||||
"TurnPasswordOffQuestion": "Are you sure you want to disable your password?",
|
||||
"Disable": "Disable",
|
||||
"TwoStepVerificationSetPassword": "Set Password",
|
||||
"TwoStepVerificationPasswordSet": "Password Set!",
|
||||
"TwoStepVerificationPasswordSetInfo": "This password will be required when you log in on a new device in addition to the code you get in the SMS.",
|
||||
"TwoStepVerificationPasswordReturnSettings": "Return to Settings",
|
||||
"RecoveryEmail": "Recovery email",
|
||||
"RecoveryEmailTitle": "Recovery Email",
|
||||
"ResendCode": "Resend code",
|
||||
"PasswordAsHintError": "Hint must be different from your password",
|
||||
|
||||
// * macos
|
||||
"AccountSettings.Filters": "Chat Folders",
|
||||
@ -563,7 +586,21 @@ const lang = {
|
||||
"GroupPermission.Delete": "Delete Exception",
|
||||
"Schedule.SendToday": "Send today at %@",
|
||||
"Schedule.SendDate": "Send on %@ at %@",
|
||||
//"Schedule.SendWhenOnline": "Send When Online"
|
||||
//"Schedule.SendWhenOnline": "Send When Online",
|
||||
"TwoStepAuth.SetPasswordHelp": "You can set a password that will be required when you log in on a new device in addition to the code you get in the SMS.",
|
||||
"TwoStepAuth.GenericHelp": "You have enabled Two-Step verification.\nYou'll need the password you set up here to log in to your Telegram account.",
|
||||
"TwoStepAuth.ChangePassword": "Change Password",
|
||||
"TwoStepAuth.RemovePassword": "Turn Password Off",
|
||||
"TwoStepAuth.SetupEmail": "Set Recovery Email",
|
||||
"TwoStepAuth.ChangeEmail": "Change Recovery Email",
|
||||
"TwoStepAuth.ConfirmEmailCodeDesc": "Please enter the code we've just emailed to %@.",
|
||||
"TwoStepAuth.RecoveryTitle": "Email Code",
|
||||
"TwoStepAuth.RecoveryCode": "Code",
|
||||
"TwoStepAuth.RecoveryCodeInvalid": "Invalid code. Please try again.",
|
||||
"TwoStepAuth.RecoveryCodeExpired": "Code Expired",
|
||||
"TwoStepAuth.SetupHintTitle": "Password Hint",
|
||||
"TwoStepAuth.SetupHintPlaceholder": "Hint",
|
||||
"PHONE_CODE_INVALID": "Invalid code",
|
||||
};
|
||||
|
||||
export default lang;
|
||||
|
@ -4,6 +4,7 @@ import { MOUNT_CLASS_TO } from '../config/debug';
|
||||
import EventListenerBase from "../helpers/eventListenerBase";
|
||||
import mediaSizes from "../helpers/mediaSizes";
|
||||
import { clamp } from '../helpers/number';
|
||||
import { pause } from '../helpers/schedulers';
|
||||
import { isAndroid, isApple, isAppleMobile, isSafari } from "../helpers/userAgent";
|
||||
import { logger, LogLevels } from "./logger";
|
||||
import apiManager from "./mtproto/mtprotoworker";
|
||||
@ -501,7 +502,8 @@ class QueryableWorker extends EventListenerBase<any> {
|
||||
}
|
||||
|
||||
class LottieLoader {
|
||||
public loadPromise: Promise<void>;
|
||||
public isWebAssemblySupported = typeof(WebAssembly) !== 'undefined';
|
||||
public loadPromise: Promise<void> = !this.isWebAssemblySupported ? Promise.reject() : undefined;
|
||||
public loaded = false;
|
||||
|
||||
// https://github.com/telegramdesktop/tdesktop/blob/97d8ee75d51874fcb74a9bfadc79f835c82be54a/Telegram/SourceFiles/chat_helpers/stickers_emoji_pack.cpp#L46
|
||||
@ -569,9 +571,9 @@ class LottieLoader {
|
||||
}
|
||||
|
||||
public loadLottieWorkers() {
|
||||
if(typeof(WebAssembly) === 'undefined') return Promise.reject();
|
||||
|
||||
if(this.loadPromise) return this.loadPromise;
|
||||
if(this.loadPromise) {
|
||||
return this.loadPromise;
|
||||
}
|
||||
|
||||
return this.loadPromise = new Promise((resolve, reject) => {
|
||||
let remain = this.workersLimit;
|
||||
@ -633,7 +635,11 @@ class LottieLoader {
|
||||
}
|
||||
}
|
||||
|
||||
public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string) {
|
||||
public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string): Promise<RLottiePlayer> {
|
||||
if(!this.isWebAssemblySupported) {
|
||||
return this.loadPromise as any;
|
||||
}
|
||||
|
||||
if(!this.loaded) {
|
||||
this.loadLottieWorkers();
|
||||
}
|
||||
@ -641,12 +647,27 @@ class LottieLoader {
|
||||
return fetch(url)
|
||||
.then(res => res.arrayBuffer())
|
||||
.then(data => apiManager.gzipUncompress<string>(data, true))
|
||||
/* .then(str => {
|
||||
return new Promise<string>((resolve) => setTimeout(() => resolve(str), 2e3));
|
||||
}) */
|
||||
.then(str => {
|
||||
return this.loadAnimationWorker(Object.assign(params, {animationData: str/* JSON.parse(str) */, needUpscale: true}));
|
||||
});
|
||||
}
|
||||
|
||||
public async loadAnimationWorker(params: RLottieOptions, group = '', toneIndex = -1) {
|
||||
public waitForFirstFrame(player: RLottiePlayer): Promise<void> {
|
||||
return Promise.race([
|
||||
new Promise<void>((resolve) => {
|
||||
player.addEventListener('firstFrame', resolve, true);
|
||||
}),
|
||||
pause(2500)
|
||||
]);
|
||||
}
|
||||
|
||||
public async loadAnimationWorker(params: RLottieOptions, group = '', toneIndex = -1): Promise<RLottiePlayer> {
|
||||
if(!this.isWebAssemblySupported) {
|
||||
return this.loadPromise as any;
|
||||
}
|
||||
//params.autoplay = true;
|
||||
|
||||
if(toneIndex >= 1 && toneIndex <= 5) {
|
||||
|
@ -293,7 +293,7 @@ export default class MTPNetworker {
|
||||
serializer.storeString(navigator.platform || 'Unknown Platform', 'system_version');
|
||||
serializer.storeString(App.version, 'app_version');
|
||||
serializer.storeString(navigator.language || 'en', 'system_lang_code');
|
||||
serializer.storeString('', 'lang_pack');
|
||||
serializer.storeString(App.langPack, 'lang_pack');
|
||||
serializer.storeString(navigator.language || 'en', 'lang_code');
|
||||
//serializer.storeInt(0x0, 'proxy');
|
||||
/* serializer.storeMethod('initConnection', {
|
||||
|
@ -4,10 +4,9 @@ import Countries, { Country as _Country } from "../countries";
|
||||
import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import apiManager from "../lib/mtproto/mtprotoworker";
|
||||
import { RichTextProcessor } from '../lib/richtextprocessor';
|
||||
import { findUpTag, findUpClassName } from "../helpers/dom";
|
||||
import { findUpTag } from "../helpers/dom";
|
||||
import Page from "./page";
|
||||
import pageAuthCode from "./pageAuthCode";
|
||||
import pageSignQR from './pageSignQR';
|
||||
import InputField from "../components/inputField";
|
||||
import CheckboxField from "../components/checkboxField";
|
||||
import Button from "../components/button";
|
||||
@ -301,7 +300,8 @@ let onFirstMount = () => {
|
||||
|
||||
const signedCheckboxField = new CheckboxField({
|
||||
text: 'Keep me signed in',
|
||||
name: 'keepSession'
|
||||
name: 'keepSession',
|
||||
withRipple: true
|
||||
});
|
||||
signedCheckboxField.input.checked = true;
|
||||
|
||||
@ -347,21 +347,15 @@ let onFirstMount = () => {
|
||||
});
|
||||
});
|
||||
|
||||
const qrDiv = document.createElement('div');
|
||||
qrDiv.classList.add('qr');
|
||||
const btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Quick log in using QR code'});
|
||||
|
||||
const qrLink = document.createElement('a');
|
||||
qrLink.href = '#';
|
||||
qrLink.classList.add('a-qr');
|
||||
qrLink.innerText = 'Quick log in using QR code';
|
||||
|
||||
qrDiv.append(qrLink);
|
||||
|
||||
qrLink.addEventListener('click', () => {
|
||||
pageSignQR.mount();
|
||||
btnQr.addEventListener('click', () => {
|
||||
import('./pageSignQR').then(module => {
|
||||
module.default.mount();
|
||||
});
|
||||
});
|
||||
|
||||
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, qrDiv);
|
||||
inputWrapper.append(countryInputField.container, telInputField.container, signedCheckboxField.label, btnNext, btnQr);
|
||||
|
||||
page.pageEl.querySelector('.container').append(inputWrapper);
|
||||
|
||||
|
@ -9,12 +9,20 @@ import { AuthAuthorization, AuthLoginToken } from '../layer';
|
||||
import { bytesCmp, bytesToBase64 } from '../helpers/bytes';
|
||||
import { pause } from '../helpers/schedulers';
|
||||
import App from '../config/app';
|
||||
import Button from '../components/button';
|
||||
|
||||
let onFirstMount = async() => {
|
||||
const pageElement = page.pageEl;
|
||||
const imageDiv = pageElement.querySelector('.auth-image') as HTMLDivElement;
|
||||
|
||||
page.pageEl.querySelector('.a-qr').addEventListener('click', () => {
|
||||
const inputWrapper = document.createElement('div');
|
||||
inputWrapper.classList.add('input-wrapper');
|
||||
|
||||
const btnBack = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Or log in using your phone number'});
|
||||
inputWrapper.append(btnBack);
|
||||
imageDiv.parentElement.append(inputWrapper);
|
||||
|
||||
btnBack.addEventListener('click', () => {
|
||||
pageSignIn.mount();
|
||||
stop = true;
|
||||
});
|
||||
@ -77,10 +85,9 @@ let onFirstMount = async() => {
|
||||
let encoded = bytesToBase64(loginToken.token);
|
||||
let url = "tg://login?token=" + encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/\=+$/, "");
|
||||
|
||||
imageDiv.innerHTML = '';
|
||||
const qrCode = new QRCodeStyling({
|
||||
width: 166,
|
||||
height: 166,
|
||||
width: 166 * window.devicePixelRatio,
|
||||
height: 166 * window.devicePixelRatio,
|
||||
data: url,
|
||||
image: "assets/img/logo_padded.svg",
|
||||
dotsOptions: {
|
||||
@ -97,7 +104,16 @@ let onFirstMount = async() => {
|
||||
errorCorrectionLevel: "L"
|
||||
}
|
||||
});
|
||||
|
||||
qrCode.append(imageDiv);
|
||||
(imageDiv.lastChild as HTMLCanvasElement).classList.add('qr-canvas');
|
||||
|
||||
// * это костыль, но библиотека не предоставляет никаких событий
|
||||
qrCode._drawingPromise.then(() => {
|
||||
Array.from(imageDiv.children).slice(0, -1).forEach(el => {
|
||||
el.remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let timestamp = Date.now() / 1000;
|
||||
|
@ -139,6 +139,10 @@ Utility Classes
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* .flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
@ -363,6 +363,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary:not(:first-child) {
|
||||
margin-top: .5rem !important;
|
||||
}
|
||||
|
||||
.btn-color-primary {
|
||||
background: $color-blue;
|
||||
color: #fff;
|
||||
|
@ -90,6 +90,19 @@
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.hover-effect {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 3.5rem;
|
||||
padding: 0 1.1875rem;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
|
||||
.checkbox-box {
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-ripple {
|
||||
|
@ -908,8 +908,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
margin-top: .5rem !important;
|
||||
.btn-primary:not(.btn-transparent) {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.media-sticker-wrapper {
|
||||
|
@ -116,6 +116,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.page-sign {
|
||||
.checkbox-field {
|
||||
margin-top: .5rem;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.page-sign, .page-signUp {
|
||||
.auth-image {
|
||||
width: 7.5rem;
|
||||
@ -142,6 +149,10 @@
|
||||
}
|
||||
|
||||
.page-sign, .page-signQR {
|
||||
.btn-secondary {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.qr {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
@ -161,9 +172,18 @@
|
||||
width: 166px;
|
||||
height: 166px;
|
||||
}
|
||||
|
||||
.qr-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
h4, .qr-description, .qr {
|
||||
.input-wrapper {
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
||||
h4 {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user