Font changed to 16px; sign in page fixes; prepare auth animation
This commit is contained in:
parent
67aca5c877
commit
4c500ada12
6
package-lock.json
generated
6
package-lock.json
generated
@ -1312,6 +1312,12 @@
|
|||||||
"minimist": "^1.2.0"
|
"minimist": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@cryptography/aes": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@cryptography/aes/-/aes-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-PcYz4FDGblO6tM2kSC+VzhhK62vml6k6/YAkiWtyPvrgJVfnDRoHGDtKn5UiaRRUrvUTTocBpvc2rRgTCqxjsg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@cryptography/sha1": {
|
"@cryptography/sha1": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@cryptography/sha1/-/sha1-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@cryptography/sha1/-/sha1-0.1.0.tgz",
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack-dev-server --open --config webpack.dev.js",
|
"start": "webpack-dev-server --open --config webpack.dev.js",
|
||||||
"start-production": "webpack-dev-server --open --config webpack.prod.js",
|
"start-production": "webpack-dev-server --open --config webpack.prod.js",
|
||||||
"serve-serve": "webpack-serve --compress --port 9001 --host localhost --no-watch --static ./public --config webpack.prod.js",
|
"serve": "node server.js",
|
||||||
"build": "webpack --config webpack.prod.js",
|
"build": "webpack --config webpack.prod.js",
|
||||||
"test": "jest --config=jest.config.js",
|
"test": "jest --config=jest.config.js",
|
||||||
"profile": "webpack --profile --json > stats.json --config webpack.prod.js"
|
"profile": "webpack --profile --json > stats.json --config webpack.prod.js"
|
||||||
@ -21,6 +21,7 @@
|
|||||||
"@babel/core": "^7.9.0",
|
"@babel/core": "^7.9.0",
|
||||||
"@babel/preset-env": "^7.9.5",
|
"@babel/preset-env": "^7.9.5",
|
||||||
"@babel/preset-typescript": "^7.9.0",
|
"@babel/preset-typescript": "^7.9.0",
|
||||||
|
"@cryptography/aes": "^0.1.1",
|
||||||
"@cryptography/sha1": "^0.1.0",
|
"@cryptography/sha1": "^0.1.0",
|
||||||
"@cryptography/sha256": "^0.2.0",
|
"@cryptography/sha256": "^0.2.0",
|
||||||
"@types/aes-js": "^3.1.1",
|
"@types/aes-js": "^3.1.1",
|
||||||
|
@ -71,9 +71,9 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
|
|
||||||
if(menuScroll) {
|
if(menuScroll) {
|
||||||
if(i < heights.length - 4) {
|
if(i < heights.length - 4) {
|
||||||
menuScroll.container.scrollLeft = (i - 3) * 50;
|
menuScroll.container.scrollLeft = (i - 3) * 47;
|
||||||
} else {
|
} else {
|
||||||
menuScroll.container.scrollLeft = i * 50;
|
menuScroll.container.scrollLeft = i * 47;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let categories = ["Smileys & Emotion", "Animals & Nature", "Food & Drink", "Travel & Places", "Activities", "Objects", "Symbols", "Flags", "Skin Tones"];
|
let categories = ["Smileys & Emotion", "Animals & Nature", "Food & Drink", "Travel & Places", "Activities", "Objects", /* "Symbols", */"Flags", "Skin Tones"];
|
||||||
let divs: {
|
let divs: {
|
||||||
[category: string]: HTMLDivElement
|
[category: string]: HTMLDivElement
|
||||||
} = {};
|
} = {};
|
||||||
@ -100,12 +100,16 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
let details = Config.Emoji.emoji[unified];
|
let details = Config.Emoji.emoji[unified];
|
||||||
let category = details[keyCategory];
|
let category = details[keyCategory];
|
||||||
|
|
||||||
|
if(category == 'Symbols') category = 'Objects';
|
||||||
|
|
||||||
details.unified = unified;
|
details.unified = unified;
|
||||||
|
|
||||||
if(!sorted[category]) sorted[category] = [];
|
if(!sorted[category]) sorted[category] = [];
|
||||||
sorted[category][details.sort_order] = details;
|
sorted[category][details.sort_order] = details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//console.log('emoticons sorted:', sorted);
|
||||||
|
|
||||||
Object.keys(sorted).forEach(c => sorted[c].sort());
|
Object.keys(sorted).forEach(c => sorted[c].sort());
|
||||||
|
|
||||||
categories.pop();
|
categories.pop();
|
||||||
@ -143,20 +147,29 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
}
|
}
|
||||||
//console.timeEnd('emojiParse');
|
//console.timeEnd('emojiParse');
|
||||||
|
|
||||||
|
let contentEmojiDiv = document.getElementById('content-emoji') as HTMLDivElement;
|
||||||
let heights: number[] = [0];
|
let heights: number[] = [0];
|
||||||
|
|
||||||
let contentEmojiDiv = document.getElementById('content-emoji') as HTMLDivElement;
|
let prevCategoryIndex = 1;
|
||||||
categories.forEach(category => {
|
let menu = contentEmojiDiv.nextElementSibling as HTMLUListElement;
|
||||||
|
let emojiScroll = new Scrollable(contentEmojiDiv, 'y', 500, 'EMOJI', null);
|
||||||
|
emojiScroll.container.addEventListener('scroll', (e) => {
|
||||||
|
prevCategoryIndex = emoticonsContentOnScroll(menu, heights, prevCategoryIndex, emojiScroll.container);
|
||||||
|
});
|
||||||
|
//emojiScroll.setVirtualContainer(emojiScroll.container);
|
||||||
|
|
||||||
|
categories.map(category => {
|
||||||
let div = divs[category];
|
let div = divs[category];
|
||||||
|
|
||||||
if(!div) {
|
if(!div) {
|
||||||
console.error('no div by category:', category);
|
console.error('no div by category:', category);
|
||||||
}
|
}
|
||||||
|
|
||||||
contentEmojiDiv.append(div);
|
emojiScroll.append(div);
|
||||||
|
return div;
|
||||||
|
}).forEach(div => {
|
||||||
|
//console.log('emoji heights push: ', (heights[heights.length - 1] || 0) + div.scrollHeight, div, div.scrollHeight);
|
||||||
heights.push((heights[heights.length - 1] || 0) + div.scrollHeight);
|
heights.push((heights[heights.length - 1] || 0) + div.scrollHeight);
|
||||||
|
|
||||||
//console.log(div, div.scrollHeight);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
contentEmojiDiv.addEventListener('click', function(e) {
|
contentEmojiDiv.addEventListener('click', function(e) {
|
||||||
@ -184,14 +197,6 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
btnSend.classList.remove('tgico-microphone2');
|
btnSend.classList.remove('tgico-microphone2');
|
||||||
});
|
});
|
||||||
|
|
||||||
let prevCategoryIndex = 1;
|
|
||||||
let menu = contentEmojiDiv.nextElementSibling as HTMLUListElement;
|
|
||||||
let emojiScroll = new Scrollable(contentEmojiDiv, 'y', 500, 'EMOJI', contentEmojiDiv);
|
|
||||||
emojiScroll.container.addEventListener('scroll', (e) => {
|
|
||||||
prevCategoryIndex = emoticonsContentOnScroll(menu, heights, prevCategoryIndex, emojiScroll.container);
|
|
||||||
});
|
|
||||||
//emojiScroll.setVirtualContainer(emojiScroll.container);
|
|
||||||
|
|
||||||
emoticonsMenuOnClick(menu, heights, emojiScroll);
|
emoticonsMenuOnClick(menu, heights, emojiScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,13 +278,15 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
heightRAF = window.requestAnimationFrame(() => {
|
heightRAF = window.requestAnimationFrame(() => {
|
||||||
heightRAF = 0;
|
heightRAF = 0;
|
||||||
|
|
||||||
|
let paddingTop = parseInt(window.getComputedStyle(stickersScroll.container).getPropertyValue('padding-top')) || 0;
|
||||||
|
|
||||||
heights.length = 0;
|
heights.length = 0;
|
||||||
let concated = stickersScroll.hiddenElements.up.concat(stickersScroll.visibleElements, stickersScroll.hiddenElements.down);
|
let concated = stickersScroll.hiddenElements.up.concat(stickersScroll.visibleElements, stickersScroll.hiddenElements.down);
|
||||||
concated.forEach((el, i) => {
|
concated.forEach((el, i) => {
|
||||||
heights[i] = (heights[i - 1] || 0) + el.height;
|
heights[i] = (heights[i - 1] || 0) + el.height + (i == 0 ? paddingTop : 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('stickers concated', concated, heights);
|
//console.log('stickers concated', concated, heights);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Array.from(stickersDiv.children).forEach((div, i) => {
|
/* Array.from(stickersDiv.children).forEach((div, i) => {
|
||||||
@ -344,11 +351,12 @@ const initEmoticonsDropdown = (pageEl: HTMLDivElement,
|
|||||||
|
|
||||||
let stickerSet = await appStickersManager.getStickerSet(set);
|
let stickerSet = await appStickersManager.getStickerSet(set);
|
||||||
|
|
||||||
if(stickerSet.set.thumb) {
|
//console.log('got stickerSet', stickerSet, li);
|
||||||
let thumb = stickerSet.set.thumb;
|
|
||||||
|
|
||||||
|
if(stickerSet.set.thumb) {
|
||||||
appStickersManager.getStickerSetThumb(stickerSet.set).then((blob) => {
|
appStickersManager.getStickerSetThumb(stickerSet.set).then((blob) => {
|
||||||
if(thumb.w == 1 && thumb.h == 1) { // means animated
|
//console.log('setting thumb', stickerSet, blob);
|
||||||
|
if(stickerSet.set.pFlags.animated) { // means animated
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.addEventListener('loadend', async(e) => {
|
reader.addEventListener('loadend', async(e) => {
|
||||||
|
@ -38,7 +38,7 @@ export default () => {
|
|||||||
installed = true;
|
installed = true;
|
||||||
|
|
||||||
//const countries: Country[] = _countries.default.filter(c => c.emoji);
|
//const countries: Country[] = _countries.default.filter(c => c.emoji);
|
||||||
const countries: Country[] = Config.Countries.filter(c => c.emoji);
|
const countries: Country[] = Config.Countries.filter(c => c.emoji).sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
let lastCountrySelected = '';
|
let lastCountrySelected = '';
|
||||||
|
|
||||||
@ -174,9 +174,9 @@ export default () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(country && (this.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {
|
if(country && (this.value.length - 1) >= (country.pattern ? country.pattern.length : 9)) {
|
||||||
btnNext.style.display = '';
|
btnNext.style.visibility = '';
|
||||||
} else {
|
} else {
|
||||||
btnNext.style.display = 'none';
|
btnNext.style.visibility = 'hidden';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,6 +105,10 @@ export default class Scrollable {
|
|||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
this.container.classList.add('scrollable');
|
this.container.classList.add('scrollable');
|
||||||
|
|
||||||
|
if(!appendTo) {
|
||||||
|
this.appendTo = this.container;
|
||||||
|
}
|
||||||
|
|
||||||
this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''));
|
this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''));
|
||||||
|
|
||||||
this.measureMutex = deferredPromise<void>();
|
this.measureMutex = deferredPromise<void>();
|
||||||
@ -413,7 +417,7 @@ export default class Scrollable {
|
|||||||
let appendTo = this.splitUp || this.appendTo;
|
let appendTo = this.splitUp || this.appendTo;
|
||||||
|
|
||||||
clearTimeout(this.disableHoverTimeout);
|
clearTimeout(this.disableHoverTimeout);
|
||||||
if(this.el != this.appendTo) {
|
if(this.el != this.appendTo && this.appendTo != this.container) {
|
||||||
if(!appendTo.classList.contains('disable-hover')) {
|
if(!appendTo.classList.contains('disable-hover')) {
|
||||||
appendTo.classList.add('disable-hover');
|
appendTo.classList.add('disable-hover');
|
||||||
}
|
}
|
||||||
|
@ -543,7 +543,7 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
|
|||||||
if(doc.thumbs && !div.firstElementChild && (!doc.downloaded || stickerType == 2)) {
|
if(doc.thumbs && !div.firstElementChild && (!doc.downloaded || stickerType == 2)) {
|
||||||
let thumb = doc.thumbs[0];
|
let thumb = doc.thumbs[0];
|
||||||
|
|
||||||
console.log('wrap sticker', thumb, div);
|
//console.log('wrap sticker', thumb, div);
|
||||||
|
|
||||||
if(thumb.bytes) {
|
if(thumb.bytes) {
|
||||||
apiFileManager.saveSmallFile(thumb.location, thumb.bytes);
|
apiFileManager.saveSmallFile(thumb.location, thumb.bytes);
|
||||||
|
@ -1336,7 +1336,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
this.log('messageMediaDocument', doc, bubble);
|
this.log('messageMediaDocument', doc, bubble);
|
||||||
|
|
||||||
if(doc.sticker && doc.size <= 1e6) {
|
if(doc.sticker/* && doc.size <= 1e6 */) {
|
||||||
bubble.classList.add('sticker');
|
bubble.classList.add('sticker');
|
||||||
|
|
||||||
if(doc.animated) {
|
if(doc.animated) {
|
||||||
|
@ -8,6 +8,7 @@ import appMessagesIDsManager from "./appMessagesIDsManager";
|
|||||||
import appImManager from "./appImManager";
|
import appImManager from "./appImManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import { appPeersManager } from "../services";
|
import { appPeersManager } from "../services";
|
||||||
|
import apiManager from "../mtproto/apiManager";
|
||||||
|
|
||||||
let testScroll = false;
|
let testScroll = false;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ class AppSidebarLeft {
|
|||||||
private menuEl = this.toolsBtn.querySelector('.btn-menu');
|
private menuEl = this.toolsBtn.querySelector('.btn-menu');
|
||||||
private savedBtn = this.menuEl.querySelector('.menu-saved');
|
private savedBtn = this.menuEl.querySelector('.menu-saved');
|
||||||
private archivedBtn = this.menuEl.querySelector('.menu-archive');
|
private archivedBtn = this.menuEl.querySelector('.menu-archive');
|
||||||
|
private logOutBtn = this.menuEl.querySelector('.menu-logout');
|
||||||
public archivedCount = this.archivedBtn.querySelector('.archived-count') as HTMLSpanElement;
|
public archivedCount = this.archivedBtn.querySelector('.archived-count') as HTMLSpanElement;
|
||||||
|
|
||||||
private listsContainer: HTMLDivElement = null;
|
private listsContainer: HTMLDivElement = null;
|
||||||
@ -131,6 +133,10 @@ class AppSidebarLeft {
|
|||||||
//this.toolsBtn.classList.add('tgico-back');
|
//this.toolsBtn.classList.add('tgico-back');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.logOutBtn.addEventListener('click', (e) => {
|
||||||
|
apiManager.logOut();
|
||||||
|
});
|
||||||
|
|
||||||
if(testScroll) {
|
if(testScroll) {
|
||||||
for(let i = 0; i < 1000; ++i) {
|
for(let i = 0; i < 1000; ++i) {
|
||||||
let li = document.createElement('li');
|
let li = document.createElement('li');
|
||||||
|
@ -2,6 +2,7 @@ import AppStorage from '../storage';
|
|||||||
import { MTDocument } from '../../components/wrappers';
|
import { MTDocument } from '../../components/wrappers';
|
||||||
import apiManager from '../mtproto/apiManager';
|
import apiManager from '../mtproto/apiManager';
|
||||||
import apiFileManager from '../mtproto/apiFileManager';
|
import apiFileManager from '../mtproto/apiFileManager';
|
||||||
|
import appDocsManager from './appDocsManager';
|
||||||
|
|
||||||
export type MTStickerSet = {
|
export type MTStickerSet = {
|
||||||
_: 'stickerSet',
|
_: 'stickerSet',
|
||||||
@ -27,6 +28,9 @@ export type MTStickerSet = {
|
|||||||
h: number,
|
h: number,
|
||||||
size: number
|
size: number
|
||||||
},
|
},
|
||||||
|
pFlags: {
|
||||||
|
animated?: boolean
|
||||||
|
}
|
||||||
thumb_dc_id?: number,
|
thumb_dc_id?: number,
|
||||||
count: number,
|
count: number,
|
||||||
hash: number
|
hash: number
|
||||||
@ -52,12 +56,23 @@ class appStickersManager {
|
|||||||
[stickerSetID: string]: MTStickerSetFull
|
[stickerSetID: string]: MTStickerSetFull
|
||||||
}>('stickerSets').then((sets) => {
|
}>('stickerSets').then((sets) => {
|
||||||
if(sets) {
|
if(sets) {
|
||||||
|
for(let id in sets) {
|
||||||
|
let set = sets[id];
|
||||||
|
set.documents.forEach(doc => {
|
||||||
|
delete doc.downloaded;
|
||||||
|
delete doc.url;
|
||||||
|
|
||||||
|
this.saveSticker(doc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.stickerSets = sets;
|
this.stickerSets = sets;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveSticker(doc: MTDocument) {
|
public saveSticker(doc: MTDocument) {
|
||||||
|
if(this.documents[doc.id]) return this.documents[doc.id];
|
||||||
/* Object.keys(doc).forEach(key => {
|
/* Object.keys(doc).forEach(key => {
|
||||||
if(doc[key] instanceof Uint8Array) {
|
if(doc[key] instanceof Uint8Array) {
|
||||||
doc[key] = Array.from(doc[key]);
|
doc[key] = Array.from(doc[key]);
|
||||||
@ -66,7 +81,10 @@ class appStickersManager {
|
|||||||
|
|
||||||
doc.file_reference = Array.from(doc.file_reference);
|
doc.file_reference = Array.from(doc.file_reference);
|
||||||
|
|
||||||
|
appDocsManager.saveDoc(doc);
|
||||||
this.documents[doc.id] = doc;
|
this.documents[doc.id] = doc;
|
||||||
|
|
||||||
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSticker(fileID: string) {
|
public getSticker(fileID: string) {
|
||||||
|
@ -282,7 +282,7 @@ export function longToInts(sLong: string) {
|
|||||||
return [divRem[0].intValue(), divRem[1].intValue()];
|
return [divRem[0].intValue(), divRem[1].intValue()];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bytesFromWords(wordArray: any) {
|
export function bytesFromWords(wordArray: {words: number[] | Uint8Array | Uint32Array, sigBytes: number}) {
|
||||||
var words = wordArray.words;
|
var words = wordArray.words;
|
||||||
var sigBytes = wordArray.sigBytes;
|
var sigBytes = wordArray.sigBytes;
|
||||||
var bytes = [];
|
var bytes = [];
|
||||||
@ -294,6 +294,30 @@ export function bytesFromWords(wordArray: any) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function bytesFromWordss(input: Uint32Array) {
|
||||||
|
var o = [];
|
||||||
|
for(var i = 0; i < input.length * 4; i++) {
|
||||||
|
o.push((input[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bytesToWordss(input: ArrayBuffer | Uint8Array) {
|
||||||
|
let bytes: Uint8Array;
|
||||||
|
if(input instanceof ArrayBuffer) bytes = new Uint8Array(input);
|
||||||
|
else bytes = input;
|
||||||
|
|
||||||
|
var len = bytes.length;
|
||||||
|
var words: number[] = [];
|
||||||
|
var i;
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Uint32Array(words);
|
||||||
|
}
|
||||||
|
|
||||||
export function longToBytes(sLong: string) {
|
export function longToBytes(sLong: string) {
|
||||||
return bytesFromWords({words: longToInts(sLong), sigBytes: 8}).reverse();
|
return bytesFromWords({words: longToInts(sLong), sigBytes: 8}).reverse();
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
import sha1 from '@cryptography/sha1';
|
import sha1 from '@cryptography/sha1';
|
||||||
import sha256 from '@cryptography/sha256';
|
import sha256 from '@cryptography/sha256';
|
||||||
|
import {IGE} from '@cryptography/aes';
|
||||||
|
|
||||||
import {str2bigInt, bpe, equalsInt, greater,
|
import {str2bigInt, bpe, equalsInt, greater,
|
||||||
copy_, eGCD_, add_, rightShift_, sub_, copyInt_, isZero,
|
copy_, eGCD_, add_, rightShift_, sub_, copyInt_, isZero,
|
||||||
@ -9,43 +10,13 @@ import {str2bigInt, bpe, equalsInt, greater,
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import {BigInteger} from 'jsbn';
|
import {BigInteger} from 'jsbn';
|
||||||
|
|
||||||
import CryptoJS from './crypto.js';
|
import { addPadding, bytesToHex, bytesFromHex, nextRandomInt, bytesFromBigInt, dT, bytesFromWords, bytesToWordss, bytesFromWordss } from '../bin_utils';
|
||||||
import { addPadding, bytesToHex, bytesFromHex, nextRandomInt, bytesFromBigInt, dT, bytesFromWords } from '../bin_utils';
|
|
||||||
|
|
||||||
export function bytesFromLeemonBigInt(bigInt: BigInteger) {
|
export function bytesFromLeemonBigInt(bigInt: BigInteger) {
|
||||||
var str = bigInt2str(bigInt, 16);
|
var str = bigInt2str(bigInt, 16);
|
||||||
return bytesFromHex(str);
|
return bytesFromHex(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bytesToWordss(input: ArrayBuffer | Uint8Array) {
|
|
||||||
let bytes: Uint8Array;
|
|
||||||
if(input instanceof ArrayBuffer) bytes = new Uint8Array(input);
|
|
||||||
else bytes = input;
|
|
||||||
|
|
||||||
var len = bytes.length;
|
|
||||||
var words: number[] = [];
|
|
||||||
var i;
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Uint32Array(words);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function bytesToWords(bytes: any) {
|
|
||||||
if(bytes instanceof ArrayBuffer) {
|
|
||||||
bytes = new Uint8Array(bytes);
|
|
||||||
}
|
|
||||||
var len = bytes.length;
|
|
||||||
var words: any = [];
|
|
||||||
var i;
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CryptoJS.lib.WordArray.init(words, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function sha1HashSync(bytes: number[] | ArrayBuffer | Uint8Array) {
|
export function sha1HashSync(bytes: number[] | ArrayBuffer | Uint8Array) {
|
||||||
//console.trace(dT(), 'SHA-1 hash start', bytes);
|
//console.trace(dT(), 'SHA-1 hash start', bytes);
|
||||||
|
|
||||||
@ -68,54 +39,35 @@ export function sha256HashSync(bytes: Uint8Array | ArrayBuffer) {
|
|||||||
let words = bytesToWordss(bytes);
|
let words = bytesToWordss(bytes);
|
||||||
let hash = sha256(words);
|
let hash = sha256(words);
|
||||||
|
|
||||||
// bytesFromWords below
|
|
||||||
var o = [];
|
|
||||||
for(var i = 0; i < hash.length * 4; i++) {
|
|
||||||
o.push((hash[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log(dT(), 'SHA-256 hash finish');
|
//console.log(dT(), 'SHA-256 hash finish');
|
||||||
|
|
||||||
return o;
|
return bytesFromWordss(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function aesEncryptSync(bytes: any, keyBytes: any, ivBytes: any) {
|
export function aesEncryptSync(bytes: ArrayBuffer, keyBytes: ArrayBuffer, ivBytes: ArrayBuffer) {
|
||||||
// console.log(dT(), 'AES encrypt start', len/*, bytesToHex(keyBytes), bytesToHex(ivBytes)*/)
|
//console.log(dT(), 'AES encrypt start', bytes, keyBytes, ivBytes);
|
||||||
// console.log('aes before padding bytes:', bytesToHex(bytes));
|
// console.log('aes before padding bytes:', bytesToHex(bytes));
|
||||||
bytes = addPadding(bytes);
|
bytes = addPadding(bytes);
|
||||||
// console.log('aes after padding bytes:', bytesToHex(bytes));
|
// console.log('aes after padding bytes:', bytesToHex(bytes));
|
||||||
|
|
||||||
let mode = CryptoJS.mode.IGE;
|
const cipher = new IGE(bytesToWordss(keyBytes), bytesToWordss(ivBytes));
|
||||||
|
const encryptedBytes = cipher.encrypt(bytesToWordss(bytes));
|
||||||
|
//console.log(dT(), 'AES encrypt finish');
|
||||||
|
|
||||||
let encryptedWords = CryptoJS.AES.encrypt(bytesToWords(bytes), bytesToWords(keyBytes), {
|
return bytesFromWordss(encryptedBytes);
|
||||||
iv: bytesToWords(ivBytes),
|
|
||||||
padding: CryptoJS.pad.NoPadding,
|
|
||||||
mode//: CryptoJS.mode.IGE
|
|
||||||
}).ciphertext;
|
|
||||||
|
|
||||||
let encryptedBytes = bytesFromWords(encryptedWords);
|
|
||||||
// console.log(dT(), 'AES encrypt finish')
|
|
||||||
|
|
||||||
return encryptedBytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function aesDecryptSync(encryptedBytes: any, keyBytes: any, ivBytes: any) {
|
export function aesDecryptSync(bytes: Uint8Array, keyBytes: Uint8Array, ivBytes: Uint8Array) {
|
||||||
|
//console.log(dT(), 'AES decrypt start', bytes, keyBytes, ivBytes);
|
||||||
|
|
||||||
let mode = CryptoJS.mode.IGE;
|
const cipher = new IGE(bytesToWordss(keyBytes), bytesToWordss(ivBytes));
|
||||||
// console.log(dT(), 'AES decrypt start', encryptedBytes.length)
|
const decryptedBytes = cipher.decrypt(bytesToWordss(bytes));
|
||||||
var decryptedWords = CryptoJS.AES.decrypt({ciphertext: bytesToWords(encryptedBytes)}, bytesToWords(keyBytes), {
|
|
||||||
iv: bytesToWords(ivBytes),
|
|
||||||
padding: CryptoJS.pad.NoPadding,
|
|
||||||
mode//: CryptoJS.mode.IGE
|
|
||||||
});
|
|
||||||
|
|
||||||
var bytes = bytesFromWords(decryptedWords);
|
//console.log(dT(), 'AES decrypt finish');
|
||||||
// console.log(dT(), 'AES decrypt finish')
|
|
||||||
|
|
||||||
return bytes;
|
return bytesFromWordss(decryptedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function rsaEncrypt(publicKey: {modulus: string, exponent: string}, bytes: any): number[] {
|
export function rsaEncrypt(publicKey: {modulus: string, exponent: string}, bytes: any): number[] {
|
||||||
console.log(dT(), 'RSA encrypt start', publicKey, bytes);
|
console.log(dT(), 'RSA encrypt start', publicKey, bytes);
|
||||||
|
|
||||||
|
@ -88,36 +88,26 @@ class CryptoWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public sha1Hash(bytes: number[] | ArrayBuffer | Uint8Array): Promise<Uint8Array> {
|
public sha1Hash(bytes: number[] | ArrayBuffer | Uint8Array): Promise<Uint8Array> {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<Uint8Array>('sha1-hash', bytes);
|
||||||
return this.performTaskWorker<Uint8Array>('sha1-hash', bytes);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sha256Hash(bytes: any) {
|
public sha256Hash(bytes: any) {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<number[]>('sha256-hash', bytes);
|
||||||
return this.performTaskWorker<number[]>('sha256-hash', bytes);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public pbkdf2(buffer: Uint8Array, salt: Uint8Array, iterations: number) {
|
public pbkdf2(buffer: Uint8Array, salt: Uint8Array, iterations: number) {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<ArrayBuffer>('pbkdf2', buffer, salt, iterations);
|
||||||
return this.performTaskWorker<ArrayBuffer>('pbkdf2', buffer, salt, iterations);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public aesEncrypt(bytes: any, keyBytes: any, ivBytes: any) {
|
public aesEncrypt(bytes: any, keyBytes: any, ivBytes: any) {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<ArrayBuffer>('aes-encrypt', convertToArrayBuffer(bytes),
|
||||||
return this.performTaskWorker<ArrayBuffer>('aes-encrypt', convertToArrayBuffer(bytes),
|
convertToArrayBuffer(keyBytes), convertToArrayBuffer(ivBytes));
|
||||||
convertToArrayBuffer(keyBytes), convertToArrayBuffer(ivBytes));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public aesDecrypt(encryptedBytes: any, keyBytes: any, ivBytes: any): Promise<ArrayBuffer> {
|
public aesDecrypt(encryptedBytes: any, keyBytes: any, ivBytes: any): Promise<ArrayBuffer> {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<ArrayBuffer>('aes-decrypt',
|
||||||
return this.performTaskWorker<ArrayBuffer>('aes-decrypt',
|
encryptedBytes, keyBytes, ivBytes)
|
||||||
encryptedBytes, keyBytes, ivBytes)
|
.then(bytes => convertToArrayBuffer(bytes));
|
||||||
.then(bytes => convertToArrayBuffer(bytes));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public rsaEncrypt(publicKey: {modulus: string, exponent: string}, bytes: any): Promise<number[]> {
|
public rsaEncrypt(publicKey: {modulus: string, exponent: string}, bytes: any): Promise<number[]> {
|
||||||
@ -127,21 +117,15 @@ class CryptoWorker {
|
|||||||
public factorize(bytes: any) {
|
public factorize(bytes: any) {
|
||||||
bytes = convertToByteArray(bytes);
|
bytes = convertToByteArray(bytes);
|
||||||
|
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<[number[], number[], number]>('factorize', bytes);
|
||||||
return this.performTaskWorker<[number[], number[], number]>('factorize', bytes);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public modPow(x: any, y: any, m: any) {
|
public modPow(x: any, y: any, m: any) {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<number[]>('mod-pow', x, y, m);
|
||||||
return this.performTaskWorker<number[]>('mod-pow', x, y, m);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public gzipUncompress<T>(bytes: ArrayBuffer, toString?: boolean) {
|
public gzipUncompress<T>(bytes: ArrayBuffer, toString?: boolean) {
|
||||||
//if(this.webWorker) {
|
return this.performTaskWorker<T>('unzip', bytes, toString);
|
||||||
return this.performTaskWorker<T>('unzip', bytes, toString);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,14 +78,16 @@ export class ApiManager {
|
|||||||
AppStorage.remove('dc', 'user_auth', 'stickerSets');
|
AppStorage.remove('dc', 'user_auth', 'stickerSets');
|
||||||
this.baseDcID = 0;
|
this.baseDcID = 0;
|
||||||
this.telegramMeNotify(false);
|
this.telegramMeNotify(false);
|
||||||
return this.mtpClearStorage();
|
this.mtpClearStorage();
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
storageKeys.push('dc', 'user_auth', 'stickerSets');
|
storageKeys.push('dc', 'user_auth', 'stickerSets');
|
||||||
AppStorage.remove(storageKeys);
|
AppStorage.remove(storageKeys);
|
||||||
this.baseDcID = 0;
|
this.baseDcID = 0;
|
||||||
error.handled = true;
|
error.handled = true;
|
||||||
this.telegramMeNotify(false);
|
this.telegramMeNotify(false);
|
||||||
return this.mtpClearStorage();
|
this.mtpClearStorage();
|
||||||
|
}).then(() => {
|
||||||
|
location.pathname = '/';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,17 +226,7 @@ export class ApiManager {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if(!error.handled) {
|
if(!error.handled) {
|
||||||
if(error.code == 401) {
|
if(error.code == 401) {
|
||||||
// @ts-ignore WARNING!
|
this.logOut();
|
||||||
this.logOut().finally(() => {
|
|
||||||
if(location.protocol == 'http:' &&
|
|
||||||
!Config.Modes.http &&
|
|
||||||
Config.App.domains.indexOf(location.hostname) != -1) {
|
|
||||||
location.href = location.href.replace(/^http:/, 'https:');
|
|
||||||
} else {
|
|
||||||
location.hash = '/login';
|
|
||||||
// AppRuntimeManager.reload(); // WARNING
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// ErrorService.show({error: error}); // WARNING
|
// ErrorService.show({error: error}); // WARNING
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { bytesFromHex, addPadding } from "../../bin_utils";
|
//import { bytesFromHex, addPadding } from "../../bin_utils";
|
||||||
|
import { Codec } from "./codec";
|
||||||
|
|
||||||
class AbridgedPacketCodec {
|
class AbridgedPacketCodec implements Codec {
|
||||||
public tag = 0xef;
|
public tag = 0xef;
|
||||||
public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]);
|
public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]);
|
||||||
|
|
||||||
@ -9,12 +10,14 @@ class AbridgedPacketCodec {
|
|||||||
let header: Uint8Array;
|
let header: Uint8Array;
|
||||||
if(len < 127) {
|
if(len < 127) {
|
||||||
header = new Uint8Array([len]);
|
header = new Uint8Array([len]);
|
||||||
} else {
|
} else { // Length: payload length, divided by four, and encoded as 3 length bytes (little endian)
|
||||||
header = new Uint8Array([0x7f, ...addPadding(bytesFromHex(len.toString(16)).reverse(), 3, true)/* .reverse() */]);
|
//header = new Uint8Array([0x7f, ...addPadding(bytesFromHex(len.toString(16)).reverse(), 3, true)/* .reverse() */]);
|
||||||
|
header = new Uint8Array([0x7f, len & 0xFF, (len >> 8) & 0xFF, (len >> 16) & 0xFF]);
|
||||||
//console.log('got nobody cause im braindead', header, len);
|
//console.log('got nobody cause im braindead', header, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Uint8Array([...header, ...data]);
|
return header.concat(data);
|
||||||
|
//return new Uint8Array([...header, ...data]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public readPacket(data: Uint8Array) {
|
public readPacket(data: Uint8Array) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export interface Codec {
|
export interface Codec {
|
||||||
tag?: number;
|
tag: number;
|
||||||
obfuscateTag?: Uint8Array;
|
obfuscateTag: Uint8Array;
|
||||||
|
|
||||||
encodePacket: (data: Uint8Array) => Uint8Array;
|
encodePacket: (data: Uint8Array) => Uint8Array;
|
||||||
readPacket: (data: Uint8Array) => Uint8Array;
|
readPacket: (data: Uint8Array) => Uint8Array;
|
||||||
|
49
src/lib/mtproto/transports/intermediate.ts
Normal file
49
src/lib/mtproto/transports/intermediate.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { nextRandomInt } from "../../bin_utils";
|
||||||
|
import { Codec } from "./codec";
|
||||||
|
|
||||||
|
class IntermediatePacketCodec implements Codec {
|
||||||
|
public tag = 0xee;
|
||||||
|
public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]);
|
||||||
|
|
||||||
|
public encodePacket(data: Uint8Array) {
|
||||||
|
let len = data.byteLength;
|
||||||
|
let header = new Uint8Array(new Uint32Array([len]).buffer);
|
||||||
|
|
||||||
|
return header.concat(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public readPacket(data: Uint8Array) {
|
||||||
|
let length = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
||||||
|
|
||||||
|
return data.slice(4, 4 + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data packets are aligned to 4bytes. This codec adds random bytes of size
|
||||||
|
from 0 to 3 bytes, which are ignored by decoder. */
|
||||||
|
class PaddedIntermediatePacketCodec extends IntermediatePacketCodec {
|
||||||
|
public tag = 0xdd;
|
||||||
|
public obfuscateTag = new Uint8Array([this.tag, this.tag, this.tag, this.tag]);
|
||||||
|
|
||||||
|
public encodePacket(data: Uint8Array) {
|
||||||
|
let padding = new Uint8Array(nextRandomInt(3)).randomize();
|
||||||
|
let len = data.byteLength + padding.byteLength;
|
||||||
|
|
||||||
|
let header = new Uint8Array(new Uint32Array([len]).buffer);
|
||||||
|
console.log('encodePacket', padding, len, data, header);
|
||||||
|
|
||||||
|
return header.concat(data, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public readPacket(data: Uint8Array) {
|
||||||
|
let padLength = data.byteLength % 4;
|
||||||
|
if(padLength > 0) {
|
||||||
|
return data.slice(4, -padLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.slice(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new IntermediatePacketCodec();
|
||||||
|
//export default new PaddedIntermediatePacketCodec();
|
@ -1,15 +1,25 @@
|
|||||||
import MTTransport from './transport';
|
import MTTransport from './transport';
|
||||||
|
|
||||||
import aesjs from 'aes-js';
|
//import aesjs from 'aes-js';
|
||||||
import abridgetPacketCodec from './abridged';
|
import {CTR} from '@cryptography/aes';
|
||||||
|
//import abridgetPacketCodec from './abridged';
|
||||||
|
import intermediatePacketCodec from './intermediate';
|
||||||
import {MTPNetworker} from '../networker';
|
import {MTPNetworker} from '../networker';
|
||||||
import { logger } from '../../polyfill';
|
import { logger } from '../../polyfill';
|
||||||
|
import { bytesFromWordss } from '../../bin_utils';
|
||||||
|
import { Codec } from './codec';
|
||||||
|
|
||||||
|
/*
|
||||||
|
@cryptography/aes не работает с массивами которые не кратны 4, поэтому использую intermediate а не abridged
|
||||||
|
*/
|
||||||
export class Obfuscation {
|
export class Obfuscation {
|
||||||
public enc: aesjs.ModeOfOperation.ModeOfOperationCTR;
|
/* public enc: aesjs.ModeOfOperation.ModeOfOperationCTR;
|
||||||
public dec: aesjs.ModeOfOperation.ModeOfOperationCTR;
|
public dec: aesjs.ModeOfOperation.ModeOfOperationCTR; */
|
||||||
|
|
||||||
public init() {
|
public encNew: CTR;
|
||||||
|
public decNew: CTR;
|
||||||
|
|
||||||
|
public init(codec: Codec) {
|
||||||
const initPayload = new Uint8Array(64);
|
const initPayload = new Uint8Array(64);
|
||||||
initPayload.randomize();
|
initPayload.randomize();
|
||||||
|
|
||||||
@ -22,6 +32,7 @@ export class Obfuscation {
|
|||||||
val != 0x20544547 &&
|
val != 0x20544547 &&
|
||||||
val != 0x4954504f &&
|
val != 0x4954504f &&
|
||||||
val != 0xeeeeeeee &&
|
val != 0xeeeeeeee &&
|
||||||
|
val != 0xdddddddd &&
|
||||||
val2 != 0x00000000) {
|
val2 != 0x00000000) {
|
||||||
//initPayload[56] = initPayload[57] = initPayload[58] = initPayload[59] = transport;
|
//initPayload[56] = initPayload[57] = initPayload[58] = initPayload[59] = transport;
|
||||||
break;
|
break;
|
||||||
@ -38,10 +49,13 @@ export class Obfuscation {
|
|||||||
let decKey = reversedPayload.slice(8, 40);
|
let decKey = reversedPayload.slice(8, 40);
|
||||||
let decIv = reversedPayload.slice(40, 56);
|
let decIv = reversedPayload.slice(40, 56);
|
||||||
|
|
||||||
this.enc = new aesjs.ModeOfOperation.ctr(encKey, new aesjs.Counter(encIv as any));
|
/* this.enc = new aesjs.ModeOfOperation.ctr(encKey, new aesjs.Counter(encIv as any));
|
||||||
this.dec = new aesjs.ModeOfOperation.ctr(decKey, new aesjs.Counter(decIv as any));
|
this.dec = new aesjs.ModeOfOperation.ctr(decKey, new aesjs.Counter(decIv as any)); */
|
||||||
|
|
||||||
initPayload.set(abridgetPacketCodec.obfuscateTag, 56);
|
this.encNew = new CTR(encKey, encIv);
|
||||||
|
this.decNew = new CTR(decKey, decIv);
|
||||||
|
|
||||||
|
initPayload.set(intermediatePacketCodec.obfuscateTag, 56);
|
||||||
const encrypted = this.encode(initPayload);
|
const encrypted = this.encode(initPayload);
|
||||||
|
|
||||||
initPayload.set(encrypted.slice(56, 64), 56);
|
initPayload.set(encrypted.slice(56, 64), 56);
|
||||||
@ -49,12 +63,47 @@ export class Obfuscation {
|
|||||||
return initPayload;
|
return initPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public encode(payload: Uint8Array) {
|
/* public encode(payload: Uint8Array) {
|
||||||
return this.enc.encrypt(payload);
|
let res = this.enc.encrypt(payload);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let arr = this.encNew.encrypt(payload);
|
||||||
|
//let resNew = bytesFromWords({words: arr, sigBytes: arr.length});
|
||||||
|
let resNew = new Uint8Array(bytesFromWordss(arr));
|
||||||
|
console.log('Obfuscation: encode comparison:', res, arr, resNew, res.hex == resNew.hex);
|
||||||
|
} catch(err) {
|
||||||
|
console.error('Obfuscation: error:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public decode(data: Uint8Array) {
|
public decode(payload: Uint8Array) {
|
||||||
return this.dec.encrypt(data);
|
let res = this.dec.encrypt(payload);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let arr = this.decNew.decrypt(payload);
|
||||||
|
//let resNew = bytesFromWords({words: arr, sigBytes: arr.length});
|
||||||
|
let resNew = new Uint8Array(bytesFromWordss(arr));
|
||||||
|
console.log('Obfuscation: decode comparison:', res, arr, resNew, res.hex == resNew.hex);
|
||||||
|
} catch(err) {
|
||||||
|
console.error('Obfuscation: error:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
} */
|
||||||
|
public encode(payload: Uint8Array) {
|
||||||
|
let res = this.encNew.encrypt(payload);
|
||||||
|
let bytes = new Uint8Array(bytesFromWordss(res));
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public decode(payload: Uint8Array) {
|
||||||
|
let res = this.decNew.decrypt(payload);
|
||||||
|
let bytes = new Uint8Array(bytesFromWordss(res));
|
||||||
|
|
||||||
|
return bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +124,8 @@ export default class Socket extends MTTransport {
|
|||||||
|
|
||||||
debug = false;
|
debug = false;
|
||||||
|
|
||||||
|
codec = intermediatePacketCodec;
|
||||||
|
|
||||||
constructor(dcID: number, url: string) {
|
constructor(dcID: number, url: string) {
|
||||||
super(dcID, url);
|
super(dcID, url);
|
||||||
|
|
||||||
@ -103,7 +154,7 @@ export default class Socket extends MTTransport {
|
|||||||
handleOpen = () => {
|
handleOpen = () => {
|
||||||
this.log('opened');
|
this.log('opened');
|
||||||
|
|
||||||
this.ws.send(this.obfuscation.init());
|
this.ws.send(this.obfuscation.init(this.codec));
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
|
|
||||||
this.releasePending();
|
this.releasePending();
|
||||||
@ -126,7 +177,7 @@ export default class Socket extends MTTransport {
|
|||||||
this.debug && this.log('<-', 'handleMessage', event);
|
this.debug && this.log('<-', 'handleMessage', event);
|
||||||
|
|
||||||
let data = this.obfuscation.decode(new Uint8Array(event.data));
|
let data = this.obfuscation.decode(new Uint8Array(event.data));
|
||||||
data = abridgetPacketCodec.readPacket(data);
|
data = this.codec.readPacket(data);
|
||||||
|
|
||||||
if(this.networker) { // authenticated!
|
if(this.networker) { // authenticated!
|
||||||
//this.pending = this.pending.filter(p => p.body); // clear pending
|
//this.pending = this.pending.filter(p => p.body); // clear pending
|
||||||
@ -175,7 +226,7 @@ export default class Socket extends MTTransport {
|
|||||||
let pending = this.pending[i];
|
let pending = this.pending[i];
|
||||||
let {body} = pending;
|
let {body} = pending;
|
||||||
if(body) {
|
if(body) {
|
||||||
let toEncode = abridgetPacketCodec.encodePacket(body);
|
let toEncode = this.codec.encodePacket(body);
|
||||||
|
|
||||||
//console.log('send before obf:', /* body.hex, nonce.hex, */ toEncode.hex);
|
//console.log('send before obf:', /* body.hex, nonce.hex, */ toEncode.hex);
|
||||||
let enc = this.obfuscation.encode(toEncode);
|
let enc = this.obfuscation.encode(toEncode);
|
||||||
|
@ -80,6 +80,10 @@ Uint8Array.prototype.concat = function(...args: Array<Uint8Array | ArrayBuffer |
|
|||||||
return bufferConcats(this, ...args);
|
return bufferConcats(this, ...args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Uint8Array.prototype.toString = function() {
|
||||||
|
return String.fromCharCode.apply(null, [...this]);
|
||||||
|
};
|
||||||
|
|
||||||
Array.prototype.forEachReverse = function<T>(callback: (value: T, index?: number, array?: Array<T>) => void) {
|
Array.prototype.forEachReverse = function<T>(callback: (value: T, index?: number, array?: Array<T>) => void) {
|
||||||
let length = this.length;
|
let length = this.length;
|
||||||
for(var i = length - 1; i >= 0; --i) {
|
for(var i = length - 1; i >= 0; --i) {
|
||||||
@ -108,7 +112,8 @@ declare global {
|
|||||||
interface Uint8Array {
|
interface Uint8Array {
|
||||||
hex: string;
|
hex: string;
|
||||||
randomize: () => Uint8Array,
|
randomize: () => Uint8Array,
|
||||||
concat: (...args: Array<Uint8Array | ArrayBuffer | number[]>) => Uint8Array
|
concat: (...args: Array<Uint8Array | ArrayBuffer | number[]>) => Uint8Array,
|
||||||
|
toString: () => string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Array<T> {
|
interface Array<T> {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
$chat-max-width: 696px;
|
||||||
|
|
||||||
.chat-container {
|
.chat-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
// padding: 200px;
|
// padding: 200px;
|
||||||
@ -57,7 +59,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07);
|
box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07);
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 17px;
|
||||||
flex: 0 0 auto; /* Forces side columns to stay same width */
|
flex: 0 0 auto; /* Forces side columns to stay same width */
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
max-height: 60px;
|
max-height: 60px;
|
||||||
@ -71,8 +73,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding-left: 1rem;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
padding-left: 17px;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.person {
|
.person {
|
||||||
@ -93,7 +96,7 @@
|
|||||||
.bottom {
|
.bottom {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
color: $placeholder-color;
|
color: #707579;
|
||||||
|
|
||||||
.online {
|
.online {
|
||||||
color: $darkblue;
|
color: $darkblue;
|
||||||
@ -220,7 +223,7 @@
|
|||||||
.bubble {
|
.bubble {
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 700px 1fr;
|
grid-template-columns: 1fr $chat-max-width 1fr;
|
||||||
grid-row-gap: 0px;
|
grid-row-gap: 0px;
|
||||||
|
|
||||||
&:before, &:after {
|
&:before, &:after {
|
||||||
@ -1069,9 +1072,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 700px;
|
max-width: $chat-max-width;
|
||||||
padding-top: .35rem;
|
padding-top: .35rem;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 21px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex: 0 0 auto; /* Forces side columns to stay same width */
|
flex: 0 0 auto; /* Forces side columns to stay same width */
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -1080,8 +1083,8 @@
|
|||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: .5rem .5rem;
|
font-size: 16px;
|
||||||
font-size: .95rem;
|
padding: 10px 9px;
|
||||||
/* height: 100%; */
|
/* height: 100%; */
|
||||||
max-height: 30rem;
|
max-height: 30rem;
|
||||||
overflow-y: none;
|
overflow-y: none;
|
||||||
@ -1093,7 +1096,7 @@
|
|||||||
|
|
||||||
[contenteditable=true]:empty:before {
|
[contenteditable=true]:empty:before {
|
||||||
content: attr(data-placeholder);
|
content: attr(data-placeholder);
|
||||||
color: #9e9e9e;
|
color: #a2acb4;
|
||||||
display: block; /* For Firefox By Ariel Flesler */
|
display: block; /* For Firefox By Ariel Flesler */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,8 +1104,8 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
height: 3.25rem;
|
height: 54px;
|
||||||
width: 3.25rem;
|
width: 54px;
|
||||||
color: #9e9e9e;
|
color: #9e9e9e;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
@ -1130,7 +1133,7 @@
|
|||||||
margin-right: 9px;
|
margin-right: 9px;
|
||||||
padding: 4.5px .5rem;
|
padding: 4.5px .5rem;
|
||||||
/* padding: 3px .5rem 6px .5rem; */
|
/* padding: 3px .5rem 6px .5rem; */
|
||||||
min-height: 3.25rem;
|
min-height: 54px;
|
||||||
max-height: 30rem;
|
max-height: 30rem;
|
||||||
caret-color: $button-primary-background;
|
caret-color: $button-primary-background;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -1204,12 +1207,14 @@
|
|||||||
|
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
display: block;
|
display: block;
|
||||||
color: $placeholder-color;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
transition: .2s color;
|
transition: .2s color;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 10px 7px 9px 7.5px;
|
||||||
|
color: #8d969c;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: $blue;
|
color: $blue;
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,19 @@
|
|||||||
.input-search {
|
.input-search {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: 1rem;
|
margin-left: 22px;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
background-color: rgba(112, 117, 121, .08);
|
background-color: rgba(112, 117, 121, .08);
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
height: 3rem;
|
height: 44px;
|
||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 1.5rem 0 3rem;
|
padding: 0px 1.5rem 0 40px;
|
||||||
-webkit-transition: all .15s ease-out;
|
-webkit-transition: all .15s ease-out;
|
||||||
transition: all .15s ease-out;
|
transition: all .15s ease-out;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
background-color: rgba(112, 117, 121, 0);
|
background-color: rgba(112, 117, 121, 0);
|
||||||
@ -28,15 +29,19 @@
|
|||||||
|
|
||||||
.tgico {
|
.tgico {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 1rem;
|
left: 12px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.65rem;
|
font-size: 24px;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
-webkit-transition: all .15s ease-out;
|
-webkit-transition: all .15s ease-out;
|
||||||
transition: all .15s ease-out;
|
transition: all .15s ease-out;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +74,8 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 8px 8.5px;
|
padding: 7px 8.5px;
|
||||||
margin: 0 8.5px 0 8px;
|
margin: 0px 8px 2px 7px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -84,7 +89,7 @@
|
|||||||
|
|
||||||
.pinned-delimiter {
|
.pinned-delimiter {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 8px 0 4px;
|
padding: 6px 0 6px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -111,7 +116,9 @@
|
|||||||
/* span:not(.tgico-pinnedchat):not(.emoji):last-child { */
|
/* span:not(.tgico-pinnedchat):not(.emoji):last-child { */
|
||||||
.user-title + span {
|
.user-title + span {
|
||||||
/* font-size: .9rem; */
|
/* font-size: .9rem; */
|
||||||
font-size: .8rem;
|
//font-size: .8rem;
|
||||||
|
font-size: .75rem;
|
||||||
|
padding: 2px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-last-message + span:not(.tgico-pinnedchat) {
|
.user-last-message + span:not(.tgico-pinnedchat) {
|
||||||
@ -143,7 +150,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
padding-right: 6.5px;
|
padding-right: 3.5px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +216,7 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin-top: 1.5px;
|
margin-top: 1.5px;
|
||||||
|
margin-right: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unread, .unread-muted {
|
.unread, .unread-muted {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
height: 420px;
|
height: 420px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, 0.14);
|
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, 0.14);
|
||||||
border-radius: 12px;
|
border-radius: 10px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
/* display: none; */
|
/* display: none; */
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -25,7 +25,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> .menu-horizontal {
|
> .menu-horizontal {
|
||||||
padding: 0 3rem;
|
padding: 0px 58px 0px 58px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 2px;
|
||||||
|
|
||||||
|
> li.active:after {
|
||||||
|
left: 29px;
|
||||||
|
right: 28px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-container {
|
.emoji-container {
|
||||||
@ -35,6 +42,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
color: #8d969c;
|
||||||
|
}
|
||||||
|
|
||||||
.tabs-container {
|
.tabs-container {
|
||||||
/* width: 300%; */
|
/* width: 300%; */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -42,19 +53,27 @@
|
|||||||
.emoji-category {
|
.emoji-category {
|
||||||
font-size: 2.25rem;
|
font-size: 2.25rem;
|
||||||
line-height: 2.25rem;
|
line-height: 2.25rem;
|
||||||
margin-top: 1px;
|
padding-top: 1px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-column-gap: 2.44px;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px 5px;
|
padding: 4px 4px;
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
|
||||||
width: 44px;
|
width: 42px;
|
||||||
height: 44px;
|
height: 42px;
|
||||||
|
|
||||||
.emoji {
|
.emoji {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -72,7 +91,7 @@
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-category, .sticker-category {
|
.sticker-category {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -104,6 +123,7 @@
|
|||||||
padding: 1px 2.5px;
|
padding: 1px 2.5px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(112, 117, 121, 0.08);
|
background-color: rgba(112, 117, 121, 0.08);
|
||||||
@ -129,7 +149,7 @@
|
|||||||
> div:first-of-type {
|
> div:first-of-type {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 10px;
|
//padding-top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,9 +166,9 @@
|
|||||||
|
|
||||||
.emoji-padding, .stickers-padding {
|
.emoji-padding, .stickers-padding {
|
||||||
.menu-horizontal {
|
.menu-horizontal {
|
||||||
height: 50px;
|
height: 47px;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
padding: 0;
|
padding: 2px 2px 2px 2px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
@ -168,9 +188,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #content-stickers {
|
#content-stickers {
|
||||||
padding: 0;
|
.scrollable {
|
||||||
} */
|
padding: 15px 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.emoji-padding, .stickers-padding {
|
.emoji-padding, .stickers-padding {
|
||||||
.menu-horizontal > li {
|
.menu-horizontal > li {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: .5rem 1.25rem;
|
padding: 7.5px 20px 7.5px 15px;
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
|
|
||||||
.sidebar-title {
|
.sidebar-title {
|
||||||
|
@ -48,7 +48,7 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: 15px;
|
font-size: $text-size;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -83,8 +83,8 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: 2.28rem;
|
font-size: 2rem;
|
||||||
margin: 1.52rem 0 .912rem 0;
|
margin: 1.5rem 0 1rem 0;
|
||||||
line-height: 110%;
|
line-height: 110%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,6 @@ input {
|
|||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
/* font-weight: 500; */
|
/* font-weight: 500; */
|
||||||
font-size: 1rem;
|
|
||||||
color: $placeholder-color;
|
color: $placeholder-color;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
}
|
}
|
||||||
@ -103,7 +102,8 @@ input {
|
|||||||
.page-authCode .input-wrapper,
|
.page-authCode .input-wrapper,
|
||||||
.page-signUp .input-wrapper,
|
.page-signUp .input-wrapper,
|
||||||
.page-password .input-wrapper {
|
.page-password .input-wrapper {
|
||||||
margin-top: 3rem;
|
/* margin-top: 3rem; */
|
||||||
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-authCode {
|
.page-authCode {
|
||||||
@ -281,7 +281,7 @@ input {
|
|||||||
|
|
||||||
&[class*=" tgico-"] {
|
&[class*=" tgico-"] {
|
||||||
line-height: 52px;
|
line-height: 52px;
|
||||||
font-size: 1.5rem;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
path {
|
path {
|
||||||
@ -496,6 +496,14 @@ input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-sign {
|
||||||
|
.auth-image {
|
||||||
|
width: 160px;
|
||||||
|
height: 160px;
|
||||||
|
margin-bottom: 45px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.page-signUp {
|
.page-signUp {
|
||||||
.auth-image {
|
.auth-image {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -524,7 +532,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
width: 350px;
|
width: 360px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +544,7 @@ input {
|
|||||||
content: " ";
|
content: " ";
|
||||||
top: 50%;
|
top: 50%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 15px;
|
right: 21px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
height: 0;
|
height: 0;
|
||||||
@ -546,12 +554,12 @@ input {
|
|||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
border-width: 0 2px 2px 0;
|
border-width: 0 2px 2px 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px;
|
padding: 5px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
margin-top: -7px;
|
margin-top: -9px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
-webkit-transform: rotate(45deg);
|
-webkit-transform: rotate(45deg);
|
||||||
transition: .2s all;
|
transition: .2s all;
|
||||||
@ -560,13 +568,12 @@ input {
|
|||||||
label {
|
label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: $placeholder-color;
|
color: $placeholder-color;
|
||||||
left: 12.5px;
|
left: 1rem;
|
||||||
right: auto;
|
right: auto;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
font-size: 0.85rem;
|
|
||||||
transition: .2s all, .1s opacity;
|
transition: .2s all, .1s opacity;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
@ -574,12 +581,11 @@ input {
|
|||||||
|
|
||||||
input {
|
input {
|
||||||
border: 1px solid #DADCE0;
|
border: 1px solid #DADCE0;
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius-big;
|
||||||
padding: 0 12.5px;
|
padding: 0 1rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 0.85rem;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 45px;
|
height: 54px;
|
||||||
transition: .2s border-color;
|
transition: .2s border-color;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@ -587,8 +593,8 @@ input {
|
|||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border-color: $button-primary-background;
|
border-color: $button-primary-background;
|
||||||
border-width: 1.5px;
|
border-width: 2px;
|
||||||
padding: 0 12px;
|
padding: 0 calc(1rem - 1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@ -606,7 +612,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:focus ~ .arrow-down {
|
&:focus ~ .arrow-down {
|
||||||
margin-top: -2px;
|
margin-top: -4px;
|
||||||
transform: rotate(225deg);
|
transform: rotate(225deg);
|
||||||
-webkit-transform: rotate(225deg);
|
-webkit-transform: rotate(225deg);
|
||||||
border-color: $button-primary-background;
|
border-color: $button-primary-background;
|
||||||
@ -617,21 +623,21 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:focus + label, &:valid + label, &:disabled + label {
|
&:focus + label, &:valid + label, &:disabled + label {
|
||||||
top: -8.5px;
|
top: -.5rem;
|
||||||
transform: none;
|
transform: none;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
left: 7.5px;
|
left: .75rem;
|
||||||
font-size: 0.85rem!important;
|
font-size: 0.75rem!important;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-field {
|
.checkbox-field {
|
||||||
margin: 1rem 0;
|
margin: 1.25rem 0;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0 1rem;
|
padding: 0 19px;
|
||||||
/* font-weight: 500; */
|
/* font-weight: 500; */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@ -646,12 +652,11 @@ input {
|
|||||||
|
|
||||||
& + span {
|
& + span {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 35px;
|
padding-left: calc(18px + 2.25rem);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
font-size: 1rem;
|
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
@ -718,7 +723,7 @@ input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-wrapper > * ~ * {
|
.input-wrapper > * ~ * {
|
||||||
margin-top: 1.2rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-wrapper {
|
.select-wrapper {
|
||||||
@ -726,7 +731,7 @@ input {
|
|||||||
/* height: auto; */
|
/* height: auto; */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
top: calc(100% + 10px);
|
top: calc(100% + .5rem);
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@ -737,15 +742,15 @@ input {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
margin: 10px 0;
|
margin: .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
/* display: flex; */
|
/* display: flex; */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 12.5px;
|
padding: 0 1rem;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
height: 50px;
|
height: 3.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
@ -850,8 +855,7 @@ input:focus, button:focus {
|
|||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.85rem;
|
height: 54px;
|
||||||
height: 45px;
|
|
||||||
border: none;
|
border: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -1385,7 +1389,7 @@ div.scrollable::-webkit-scrollbar-thumb {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
font-size: 16px;
|
font-size: 1rem;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user