Browse Source

Preload auth pages stickers & pixel-perfect fixes & minor

master
morethanwords 4 years ago
parent
commit
8972c69a9a
  1. 1
      src/lib/lottie.ts
  2. 7
      src/lib/lottieLoader.ts
  3. 9
      src/pages/page.ts
  4. 61
      src/pages/pageAuthCode.ts
  5. 44
      src/pages/pageIm.ts
  6. 63
      src/pages/pagePassword.ts
  7. 4
      src/pages/pageSignIn.ts
  8. 9
      src/pages/pagesManager.ts
  9. 89
      src/scss/style.scss

1
src/lib/lottie.ts

@ -1,4 +1,5 @@
// @ts-ignore // @ts-ignore
import LottiePlayer from "lottie-web/build/player/lottie_canvas.min.js"; import LottiePlayer from "lottie-web/build/player/lottie_canvas.min.js";
//import LottiePlayer from "lottie-web/build/player/lottie_light.min.js";
(window as any).lottie = LottiePlayer; (window as any).lottie = LottiePlayer;

7
src/lib/lottieLoader.ts

@ -2,7 +2,7 @@ import { isElementInViewport, isInDOM } from "./utils";
import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie.d"; import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie.d";
class LottieLoader { class LottieLoader {
private lottie: /* any */ typeof LottiePlayer = null; public lottie: /* any */ typeof LottiePlayer = null;
private animations: { private animations: {
[group: string]: { [group: string]: {
animation: /* any */AnimationItem, animation: /* any */AnimationItem,
@ -91,13 +91,16 @@ class LottieLoader {
public async loadAnimation(params: /* any */AnimationConfigWithPath | AnimationConfigWithData, group = '') { public async loadAnimation(params: /* any */AnimationConfigWithPath | AnimationConfigWithData, group = '') {
//params.autoplay = false; //params.autoplay = false;
//if(group != 'auth') {
params.renderer = 'canvas'; params.renderer = 'canvas';
//}
params.rendererSettings = { params.rendererSettings = {
//context: context, // the canvas context //context: context, // the canvas context
//preserveAspectRatio: 'xMinYMin slice', // Supports the same options as the svg element's preserveAspectRatio property //preserveAspectRatio: 'xMinYMin slice', // Supports the same options as the svg element's preserveAspectRatio property
clearCanvas: true, clearCanvas: true,
progressiveLoad: true, // Boolean, only svg renderer, loads dom elements when needed. Might speed up initialization for large number of elements. progressiveLoad: true, // Boolean, only svg renderer, loads dom elements when needed. Might speed up initialization for large number of elements.
hideOnTransparent: true, //Boolean, only svg renderer, hides elements when opacity reaches 0 (defaults to true) hideOnTransparent: true, //Boolean, only svg renderer, hides elements when opacity reaches 0 (defaults to true),
}; };
if(!this.lottie) { if(!this.lottie) {

9
src/pages/page.ts

@ -4,11 +4,11 @@ export default class Page {
public pageEl: HTMLDivElement; public pageEl: HTMLDivElement;
private installed = false; private installed = false;
constructor(className: string, public isAuthPage: boolean, private onFirstMount?: (...args: any[]) => void, private onMount?: (...args: any[]) => void) { constructor(className: string, public isAuthPage: boolean, private onFirstMount?: (...args: any[]) => Promise<any> | void, private onMount?: (...args: any[]) => void) {
this.pageEl = document.body.getElementsByClassName(className)[0] as HTMLDivElement; this.pageEl = document.body.getElementsByClassName(className)[0] as HTMLDivElement;
} }
public mount(...args: any[]) { public async mount(...args: any[]) {
//this.pageEl.style.display = ''; //this.pageEl.style.display = '';
if(this.onMount) { if(this.onMount) {
@ -17,7 +17,10 @@ export default class Page {
if(!this.installed) { if(!this.installed) {
if(this.onFirstMount) { if(this.onFirstMount) {
this.onFirstMount(...args); let res = this.onFirstMount(...args);
if(res instanceof Promise) {
await res;
}
} }
this.installed = true; this.installed = true;

61
src/pages/pageAuthCode.ts

@ -24,40 +24,12 @@ const EDITONSAMEPAGE = false;
let headerElement: HTMLHeadElement = null; let headerElement: HTMLHeadElement = null;
let sentTypeElement: HTMLParagraphElement = null; let sentTypeElement: HTMLParagraphElement = null;
let onFirstMount = () => { let onFirstMount = (): Promise<any> => {
let needFrame = 0, lastLength = 0; let needFrame = 0, lastLength = 0;
let animation: /* AnimationItem */any = undefined; let animation: /* AnimationItem */any = undefined;
const CODELENGTH = authCode.type.length; const CODELENGTH = authCode.type.length;
fetch('assets/img/TwoFactorSetupMonkeyTracking.tgs')
.then(res => res.arrayBuffer())
.then(async(data) => {
let str = await CryptoWorker.gzipUncompress<string>(data, true);
animation = await LottieLoader.loadAnimation({
container: page.pageEl.querySelector('.auth-image'),
renderer: 'svg',
loop: false,
autoplay: false,
animationData: JSON.parse(str)
});
animation.setSpeed(1);
//console.log(animation.getDuration(), animation.getDuration(true));
animation.addEventListener('enterFrame', (e: any) => {
//console.log('enterFrame', e, needFrame);
let currentFrame = Math.round(e.currentTime);
if((e.direction == 1 && currentFrame >= needFrame) ||
(e.direction == -1 && currentFrame <= needFrame)) {
animation.setSpeed(1);
animation.pause();
}
});
});
const codeInput = page.pageEl.querySelector('#code') as HTMLInputElement; const codeInput = page.pageEl.querySelector('#code') as HTMLInputElement;
const codeInputLabel = codeInput.nextElementSibling as HTMLLabelElement; const codeInputLabel = codeInput.nextElementSibling as HTMLLabelElement;
const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement; const editButton = page.pageEl.querySelector('.phone-edit') as HTMLElement;
@ -242,6 +214,37 @@ let onFirstMount = () => {
/* animation.goToAndStop(15, true); */ /* animation.goToAndStop(15, true); */
//animation.goToAndStop(length / max * ); //animation.goToAndStop(length / max * );
}); });
return Promise.all([
LottieLoader.loadLottie(),
fetch('assets/img/TwoFactorSetupMonkeyTracking.tgs')
.then(res => res.arrayBuffer())
.then(data => CryptoWorker.gzipUncompress<string>(data, true))
.then(str => LottieLoader.loadAnimation({
container: page.pageEl.querySelector('.auth-image'),
renderer: 'svg',
loop: false,
autoplay: false,
animationData: JSON.parse(str)
}))
.then(_animation => {
animation = _animation;
animation.setSpeed(1);
//console.log(animation.getDuration(), animation.getDuration(true));
animation.addEventListener('enterFrame', (e: any) => {
//console.log('enterFrame', e, needFrame);
let currentFrame = Math.round(e.currentTime);
if((e.direction == 1 && currentFrame >= needFrame) ||
(e.direction == -1 && currentFrame <= needFrame)) {
animation.setSpeed(1);
animation.pause();
}
});
})
]);
}; };
const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => { const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof authCode) => {

44
src/pages/pageIm.ts

@ -1,52 +1,8 @@
import { openBtnMenu, ripple } from "../components/misc"; import { openBtnMenu, ripple } from "../components/misc";
//import {stackBlurImage} from '../lib/StackBlur'; //import {stackBlurImage} from '../lib/StackBlur';
import Page from "./page"; import Page from "./page";
//import appImManager from '../lib/appManagers/appImManager';
let onFirstMount = () => import('../lib/appManagers/appImManager').then(() => {//import('../lib/services').then(services => { let onFirstMount = () => import('../lib/appManagers/appImManager').then(() => {//import('../lib/services').then(services => {
//console.log('included services', services);
//export default () => {
/*
loadDialogs().then(result => {
//appImManager.setScroll(chatScroll);
});
return;
*/
/* function placeCaretAfterNode(node: HTMLElement) {
if (typeof window.getSelection != "undefined") {
var range = document.createRange();
range.setStartAfter(node);
range.collapse(true);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
}
messageInput.onclick = (e) => {
let target = e.target as HTMLElement;
if(target.classList.contains('emoji-inner')) {
placeCaretAfterNode(target.parentElement);
} else if(target.classList.contains('emoji-sizer')) {
placeCaretAfterNode(target);
}
console.log('lol', target);
}; */
/* window.addEventListener('click', function(this, e) {
// @ts-ignore
let isInput = e.target.tagName == 'INPUT';
if(!isInput && !window.getSelection().toString()) {
console.log('click');
messageInput.focus();
}
}); */
/* fetch('assets/img/camomile.jpg') /* fetch('assets/img/camomile.jpg')
.then(res => res.blob()) .then(res => res.blob())
.then(blob => { .then(blob => {

63
src/pages/pagePassword.ts

@ -7,43 +7,12 @@ import passwordManager from '../lib/mtproto/passwordManager';
import apiManager from '../lib/mtproto/apiManager'; import apiManager from '../lib/mtproto/apiManager';
import Page from './page'; import Page from './page';
let onFirstMount = () => { let onFirstMount = (): Promise<any> => {
let needFrame = 0; let needFrame = 0;
let animation: /* AnimationItem */any = undefined; let animation: /* AnimationItem */any = undefined;
let passwordVisible = false; let passwordVisible = false;
fetch('assets/img/TwoFactorSetupMonkeyClose.tgs')
.then(res => res.arrayBuffer())
.then(async(data) => {
let str = await CryptoWorker.gzipUncompress<string>(data, true);
animation = await LottieLoader.loadAnimation({
container: page.pageEl.querySelector('.auth-image'),
renderer: 'svg',
loop: false,
autoplay: false,
animationData: JSON.parse(str)
});
console.log(animation.getDuration(true));
//animation.goToAndStop(822);
animation.addEventListener('enterFrame', (e: any) => {
//console.log('enterFrame', e, needFrame);
let currentFrame = Math.round(e.currentTime);
if((e.direction == 1 && currentFrame >= needFrame) ||
(e.direction == -1 && currentFrame <= needFrame)) {
animation.setSpeed(1);
animation.pause();
}
});
needFrame = 49;
animation.play();
});
const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement; const btnNext = page.pageEl.querySelector('button') as HTMLButtonElement;
const passwordInput = document.getElementById('password') as HTMLInputElement; const passwordInput = document.getElementById('password') as HTMLInputElement;
//const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement; //const passwordInputLabel = passwordInput.nextElementSibling as HTMLLabelElement;
@ -124,6 +93,36 @@ let onFirstMount = () => {
/* passwordInput.addEventListener('input', function(this, e) { /* passwordInput.addEventListener('input', function(this, e) {
}); */ }); */
return Promise.all([
LottieLoader.loadLottie(),
fetch('assets/img/TwoFactorSetupMonkeyClose.tgs')
.then(res => res.arrayBuffer())
.then(data => CryptoWorker.gzipUncompress<string>(data, true))
.then(str => LottieLoader.loadAnimation({
container: page.pageEl.querySelector('.auth-image'),
renderer: 'svg',
loop: false,
autoplay: false,
animationData: JSON.parse(str)
}))
.then(_animation => {
animation = _animation;
animation.addEventListener('enterFrame', (e: any) => {
//console.log('enterFrame', e, needFrame);
let currentFrame = Math.round(e.currentTime);
if((e.direction == 1 && currentFrame >= needFrame) ||
(e.direction == -1 && currentFrame <= needFrame)) {
animation.setSpeed(1);
animation.pause();
}
});
needFrame = 49;
animation.play();
})
]);
}; };
const page = new Page('page-password', true, onFirstMount); const page = new Page('page-password', true, onFirstMount);

4
src/pages/pageSignIn.ts

@ -30,7 +30,7 @@ let onFirstMount = () => {
var parent = selectCountryCode.parentElement; var parent = selectCountryCode.parentElement;
var wrapper = document.createElement('div'); var wrapper = document.createElement('div');
wrapper.classList.add('select-wrapper', 'z-depth-4'); wrapper.classList.add('select-wrapper', 'z-depth-3');
var list = document.createElement('ul'); var list = document.createElement('ul');
wrapper.appendChild(list); wrapper.appendChild(list);
@ -100,7 +100,7 @@ let onFirstMount = () => {
parent.appendChild(wrapper); parent.appendChild(wrapper);
}/* , {once: true} */); }/* , {once: true} */);
selectCountryCode.addEventListener('blur', function(this: typeof selectCountryCode, e) { selectCountryCode.addEventListener('blur', function(this: typeof selectCountryCode, e) {
parent.removeChild(wrapper); //parent.removeChild(wrapper);
e.cancelBubble = true; e.cancelBubble = true;
}, {capture: true}); }, {capture: true});

9
src/pages/pagesManager.ts

@ -1,6 +1,7 @@
import Page from "./page"; import Page from "./page";
import { whichChild } from "../lib/utils"; import { whichChild } from "../lib/utils";
import { horizontalMenu } from "../components/misc"; import { horizontalMenu } from "../components/misc";
import lottieLoader from "../lib/lottieLoader";
class PagesManager { class PagesManager {
private pageID = -1; private pageID = -1;
@ -22,6 +23,14 @@ class PagesManager {
this.selectTab(id); this.selectTab(id);
// это нужно чтобы ресайзнуть канвас (из-за скрытого рендера будет 0х0)
if(this.pageID != -1) {
lottieLoader.loadLottie().then(() => {
// @ts-ignore
lottieLoader.lottie.resize();
});
}
this.pageID = id; this.pageID = id;
} else { } else {
this.pagesDiv.style.display = 'none'; this.pagesDiv.style.display = 'none';

89
src/scss/style.scss

@ -98,24 +98,17 @@ input {
line-height: 1.25; line-height: 1.25;
} }
.page-sign .input-wrapper,
.page-authCode .input-wrapper,
.page-signUp .input-wrapper,
.page-password .input-wrapper {
/* margin-top: 3rem; */
margin-top: 50px;
}
.page-authCode { .page-authCode {
.auth-image {
transform: translateY(12px);
}
.phone-wrapper { .phone-wrapper {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 1.52rem 0 0.912rem 0;
h4 { h4 {
margin: 0;
&[contenteditable="true"] { &[contenteditable="true"] {
padding: 0 1rem; padding: 0 1rem;
border: none; border: none;
@ -129,6 +122,10 @@ input {
border-color: $color-error!important; border-color: $color-error!important;
} }
} }
.subtitle {
margin-top: 0;
}
} }
.btn-icon { .btn-icon {
@ -500,33 +497,59 @@ input {
max-width: 720px; // 360 + 360 / 2 max-width: 720px; // 360 + 360 / 2
overflow: hidden; overflow: hidden;
.subtitle {
margin: 0;
}
.input-wrapper {
margin-top: 49px;
}
.tabs-container { .tabs-container {
height: 100%;
&.animated { &.animated {
transition: .42s transform; transition: .42s transform;
} }
> div { > div {
justify-content: center; /* justify-content: center; */
/* &.active { /* &.active {
flex-direction: row; flex-direction: row;
} */ } */
&:before, &:after {
content: " ";
flex: 1;
min-height: 3rem;
/* height: 105px; */
width: 100%;
}
> div { > div {
height: 810px;
padding: 0; padding: 0;
overflow: visible; flex: 1 1 auto;
/* display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; */
} }
} }
} }
@media (max-height: 858px) {
height: auto;
/* .tabs-container > div > div {
height: auto;
} */
}
} }
.page-sign { .page-sign, .page-signUp {
.auth-image { .auth-image {
width: 160px; width: 10rem;
height: 160px; height: 10rem;
margin-bottom: 45px; margin-bottom: 1.5rem;
} }
} }
@ -607,7 +630,7 @@ input {
input { input {
border: 1px solid #DADCE0; border: 1px solid #DADCE0;
border-radius: $border-radius-big; border-radius: $border-radius-medium;
padding: 0 1rem; padding: 0 1rem;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
@ -753,7 +776,7 @@ input {
} }
.select-wrapper { .select-wrapper {
max-height: 300px; max-height: 23.5rem;
/* height: auto; */ /* height: auto; */
position: absolute; position: absolute;
width: 100%; width: 100%;
@ -762,7 +785,7 @@ input {
overflow: hidden; overflow: hidden;
background-color: #fff; background-color: #fff;
z-index: 3; z-index: 3;
border-radius: $border-radius; border-radius: $border-radius-medium;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-wrap: wrap; flex-wrap: wrap;
@ -778,21 +801,22 @@ input {
justify-content: space-between; justify-content: space-between;
height: 3.5rem; height: 3.5rem;
cursor: pointer; cursor: pointer;
font-weight: 500; /* font-weight: 500; */
text-align: left; text-align: left;
display: grid; display: grid;
grid-template-columns: 15% 60% 25%; grid-template-columns: calc(26px + 2rem) 1fr 50px;
&:hover { &:hover {
background-color: rgba(112, 117, 121, .08); background-color: rgba(112, 117, 121, .08);
} }
} }
// +2 px bc of whitespace
.emoji { .emoji {
height: 24px; height: 26px;
width: 24px; width: 26px;
font-size: 24px; font-size: 26px;
line-height: 1; line-height: 1;
} }
@ -823,12 +847,11 @@ input:focus, button:focus {
outline: none; outline: none;
} }
// this dimensions will be used for monkey business
.auth-image { .auth-image {
width: 133px; width: 166px;
height: 133px; height: 166px;
margin-left: auto; margin: 0 auto 18px;
margin-right: auto;
margin-bottom: 1rem;
} }
/* .phone-wrapper { /* .phone-wrapper {
@ -878,7 +901,7 @@ input:focus, button:focus {
.btn-primary { .btn-primary {
background: $button-primary-background; background: $button-primary-background;
color: #fff; color: #fff;
border-radius: $border-radius; border-radius: $border-radius-medium;
width: 100%; width: 100%;
text-align: center; text-align: center;
height: 54px; height: 54px;

Loading…
Cancel
Save