Language improvements
This commit is contained in:
parent
b4b0ced131
commit
fc8861027b
@ -11,7 +11,7 @@ import { logger } from "../lib/logger";
|
||||
import VideoPlayer from "../lib/mediaPlayer";
|
||||
import { RichTextProcessor } from "../lib/richtextprocessor";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { cancelEvent, fillPropertyValue, findUpClassName, generatePathData } from "../helpers/dom";
|
||||
import { cancelEvent, fillPropertyValue, generatePathData } from "../helpers/dom";
|
||||
import animationIntersector from "./animationIntersector";
|
||||
import appMediaPlaybackController from "./appMediaPlaybackController";
|
||||
import AvatarElement from "./avatar";
|
||||
@ -19,7 +19,6 @@ import ButtonIcon from "./buttonIcon";
|
||||
import { ButtonMenuItemOptions } from "./buttonMenu";
|
||||
import ButtonMenuToggle from "./buttonMenuToggle";
|
||||
import { LazyLoadQueueBase } from "./lazyLoadQueue";
|
||||
import { renderImageFromUrl } from "./misc";
|
||||
import PopupForward from "./popups/forward";
|
||||
import ProgressivePreloader from "./preloader";
|
||||
import Scrollable from "./scrollable";
|
||||
@ -32,6 +31,8 @@ import appNavigationController from "./appNavigationController";
|
||||
import { Message } from "../layer";
|
||||
import { forEachReverse } from "../helpers/array";
|
||||
import AppSharedMediaTab from "./sidebarRight/tabs/sharedMedia";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
|
||||
|
||||
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
||||
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
||||
@ -1199,7 +1200,7 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
onClick: this.onForwardClick
|
||||
}, {
|
||||
icon: 'download',
|
||||
text: 'Download',
|
||||
text: 'MediaViewer.Context.Download',
|
||||
onClick: this.onDownloadClick
|
||||
}, {
|
||||
icon: 'delete danger btn-disabled',
|
||||
@ -1436,7 +1437,7 @@ export class AppMediaViewerAvatar extends AppMediaViewerBase<'', 'delete', AppMe
|
||||
|
||||
this.setBtnMenuToggle([{
|
||||
icon: 'download',
|
||||
text: 'Download',
|
||||
text: 'MediaViewer.Context.Download',
|
||||
onClick: this.onDownloadClick
|
||||
}, {
|
||||
icon: 'delete danger btn-disabled',
|
||||
|
@ -11,7 +11,7 @@ import { logger } from "../lib/logger";
|
||||
import VideoPlayer from "../lib/mediaPlayer";
|
||||
import { RichTextProcessor } from "../lib/richtextprocessor";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { cancelEvent, fillPropertyValue, findUpClassName, generatePathData } from "../helpers/dom";
|
||||
import { cancelEvent, fillPropertyValue, generatePathData } from "../helpers/dom";
|
||||
import animationIntersector from "./animationIntersector";
|
||||
import appMediaPlaybackController from "./appMediaPlaybackController";
|
||||
import AvatarElement from "./avatar";
|
||||
@ -19,7 +19,6 @@ import ButtonIcon from "./buttonIcon";
|
||||
import { ButtonMenuItemOptions } from "./buttonMenu";
|
||||
import ButtonMenuToggle from "./buttonMenuToggle";
|
||||
import { LazyLoadQueueBase } from "./lazyLoadQueue";
|
||||
import { renderImageFromUrl } from "./misc";
|
||||
import PopupForward from "./popups/forward";
|
||||
import ProgressivePreloader from "./preloader";
|
||||
import Scrollable from "./scrollable";
|
||||
@ -30,6 +29,8 @@ import { SearchSuperContext } from "./appSearchSuper.";
|
||||
import { Message, PhotoSize } from "../layer";
|
||||
import { forEachReverse } from "../helpers/array";
|
||||
import AppSharedMediaTab from "./sidebarRight/tabs/sharedMedia";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
|
||||
|
||||
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
||||
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
||||
@ -1101,7 +1102,7 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
||||
onClick: this.onForwardClick
|
||||
}, {
|
||||
icon: 'download',
|
||||
text: 'Download',
|
||||
text: 'MediaViewer.Context.Download',
|
||||
onClick: this.onDownloadClick
|
||||
}, {
|
||||
icon: 'delete danger btn-disabled',
|
||||
@ -1338,7 +1339,7 @@ export class AppMediaViewerAvatar extends AppMediaViewerBase<'', 'delete', AppMe
|
||||
|
||||
this.setBtnMenuToggle([{
|
||||
icon: 'download',
|
||||
text: 'Download',
|
||||
text: 'MediaViewer.Context.Download',
|
||||
onClick: this.onDownloadClick
|
||||
}, {
|
||||
icon: 'delete danger btn-disabled',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { formatDateAccordingToToday, months } from "../helpers/date";
|
||||
import { findUpClassName, positionElementByIndex } from "../helpers/dom";
|
||||
import { positionElementByIndex } from "../helpers/dom";
|
||||
import { copy, getObjectKeysAndSort } from "../helpers/object";
|
||||
import { escapeRegExp, limitSymbols } from "../helpers/string";
|
||||
import appChatsManager from "../lib/appManagers/appChatsManager";
|
||||
@ -17,13 +17,15 @@ import AppMediaViewer from "./appMediaViewer";
|
||||
import { SearchGroup, SearchGroupType } from "./appSearch";
|
||||
import { horizontalMenu } from "./horizontalMenu";
|
||||
import LazyLoadQueue from "./lazyLoadQueue";
|
||||
import { renderImageFromUrl, putPreloader, formatPhoneNumber } from "./misc";
|
||||
import { putPreloader, formatPhoneNumber } from "./misc";
|
||||
import { ripple } from "./ripple";
|
||||
import Scrollable, { ScrollableX } from "./scrollable";
|
||||
import { wrapDocument, wrapPhoto, wrapVideo } from "./wrappers";
|
||||
import useHeavyAnimationCheck, { getHeavyAnimationPromise } from "../hooks/useHeavyAnimationCheck";
|
||||
import { isSafari } from "../helpers/userAgent";
|
||||
import { LangPackKey, i18n } from "../lib/langPack";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
|
||||
|
||||
//const testScroll = false;
|
||||
|
||||
|
@ -5,13 +5,15 @@ import appPeersManager from "../lib/appManagers/appPeersManager";
|
||||
import appPhotosManager from "../lib/appManagers/appPhotosManager";
|
||||
import appUsersManager from "../lib/appManagers/appUsersManager";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { cancelEvent, findUpAttribute, findUpClassName } from "../helpers/dom";
|
||||
import { cancelEvent } from "../helpers/dom";
|
||||
import Scrollable from "./scrollable";
|
||||
import { FocusDirection } from "../helpers/fastSmoothScroll";
|
||||
import CheckboxField from "./checkboxField";
|
||||
import appProfileManager from "../lib/appManagers/appProfileManager";
|
||||
import { safeAssign } from "../helpers/object";
|
||||
import { i18n, LangPackKey, _i18n } from "../lib/langPack";
|
||||
import findUpAttribute from "../helpers/dom/findUpAttribute";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
|
||||
type PeerType = 'contacts' | 'dialogs' | 'channelParticipants';
|
||||
|
||||
|
@ -8,7 +8,7 @@ import type { AppDocsManager } from "../../lib/appManagers/appDocsManager";
|
||||
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
||||
import type sessionStorage from '../../lib/sessionStorage';
|
||||
import type Chat from "./chat";
|
||||
import { findUpClassName, cancelEvent, findUpTag, whichChild, getElementByPoint, attachClickEvent, positionElementByIndex, reflowScrollableElement } from "../../helpers/dom";
|
||||
import { cancelEvent, whichChild, getElementByPoint, attachClickEvent, positionElementByIndex, reflowScrollableElement } from "../../helpers/dom";
|
||||
import { getObjectKeysAndSort } from "../../helpers/object";
|
||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||
import { logger } from "../../lib/logger";
|
||||
@ -49,6 +49,8 @@ import { SliceEnd } from "../../helpers/slicedArray";
|
||||
import serverTimeManager from "../../lib/mtproto/serverTimeManager";
|
||||
import PeerTitle from "../peerTitle";
|
||||
import { forEachReverse } from "../../helpers/array";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
const USE_MEDIA_TAILS = false;
|
||||
const IGNORE_ACTIONS: Message.messageService['action']['_'][] = [/* 'messageActionHistoryClear' */];
|
||||
|
@ -18,18 +18,18 @@ import type sessionStorage from '../../lib/sessionStorage';
|
||||
import EventListenerBase from "../../helpers/eventListenerBase";
|
||||
import { logger, LogLevels } from "../../lib/logger";
|
||||
import rootScope from "../../lib/rootScope";
|
||||
import appSidebarRight, { AppSidebarRight } from "../sidebarRight";
|
||||
import appSidebarRight from "../sidebarRight";
|
||||
import ChatBubbles from "./bubbles";
|
||||
import ChatContextMenu from "./contextMenu";
|
||||
import ChatInput from "./input";
|
||||
import ChatSelection from "./selection";
|
||||
import ChatTopbar from "./topbar";
|
||||
import { REPLIES_PEER_ID } from "../../lib/mtproto/mtproto_config";
|
||||
import { renderImageFromUrl } from "../misc";
|
||||
import SetTransition from "../singleTransition";
|
||||
import { fastRaf } from "../../helpers/schedulers";
|
||||
import AppPrivateSearchTab from "../sidebarRight/tabs/search";
|
||||
import type { State } from "../../lib/appManagers/appStateManager";
|
||||
import renderImageFromUrl from "../../helpers/dom/renderImageFromUrl";
|
||||
|
||||
export type ChatType = 'chat' | 'pinned' | 'replies' | 'discussion' | 'scheduled';
|
||||
|
||||
|
@ -4,7 +4,7 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
||||
import type { AppPollsManager, Poll } from "../../lib/appManagers/appPollsManager";
|
||||
import type Chat from "./chat";
|
||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||
import { attachClickEvent, cancelEvent, cancelSelection, findUpClassName, isSelectionEmpty } from "../../helpers/dom";
|
||||
import { attachClickEvent, cancelEvent, cancelSelection, isSelectionEmpty } from "../../helpers/dom";
|
||||
import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
|
||||
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../misc";
|
||||
import PopupDeleteMessages from "../popups/deleteMessages";
|
||||
@ -14,6 +14,7 @@ import { copyTextToClipboard } from "../../helpers/clipboard";
|
||||
import PopupSendNow from "../popups/sendNow";
|
||||
import { toast } from "../toast";
|
||||
import I18n, { LangPackKey } from "../../lib/langPack";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
|
||||
export default class ChatContextMenu {
|
||||
private buttons: (ButtonMenuItemOptions & {verify: () => boolean, notDirect?: () => boolean, withSelection?: true})[];
|
||||
|
@ -14,7 +14,7 @@ import apiManager from "../../lib/mtproto/mtprotoworker";
|
||||
//import Recorder from '../opus-recorder/dist/recorder.min';
|
||||
import opusDecodeController from "../../lib/opusDecodeController";
|
||||
import RichTextProcessor from "../../lib/richtextprocessor";
|
||||
import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getRichValue, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, isSendShortcutPressed } from "../../helpers/dom";
|
||||
import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, getRichValue, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, isSendShortcutPressed } from "../../helpers/dom";
|
||||
import { ButtonMenuItemOptions } from '../buttonMenu';
|
||||
import emoticonsDropdown from "../emoticonsDropdown";
|
||||
import PopupCreatePoll from "../popups/createPoll";
|
||||
@ -40,6 +40,7 @@ import appNavigationController from '../appNavigationController';
|
||||
import { isMobile } from '../../helpers/userAgent';
|
||||
import { i18n } from '../../lib/langPack';
|
||||
import { generateTail } from './bubbles';
|
||||
import findUpClassName from '../../helpers/dom/findUpClassName';
|
||||
|
||||
const RECORD_MIN_TIME = 500;
|
||||
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { AppImManager } from "../../lib/appManagers/appImManager";
|
||||
import { MarkdownType, cancelEvent, getSelectedNodes, markdownTags, findUpClassName, attachClickEvent, cancelSelection, isSelectionEmpty } from "../../helpers/dom";
|
||||
import { MarkdownType, cancelEvent, getSelectedNodes, markdownTags, attachClickEvent, isSelectionEmpty } from "../../helpers/dom";
|
||||
import RichTextProcessor from "../../lib/richtextprocessor";
|
||||
import ButtonIcon from "../buttonIcon";
|
||||
import { clamp } from "../../helpers/number";
|
||||
|
@ -1,10 +1,10 @@
|
||||
import renderImageFromUrl from "../../helpers/dom/renderImageFromUrl";
|
||||
import { limitSymbols } from "../../helpers/string";
|
||||
import appImManager, { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager";
|
||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||
import appPhotosManager from "../../lib/appManagers/appPhotosManager";
|
||||
import { RichTextProcessor } from "../../lib/richtextprocessor";
|
||||
import DivAndCaption from "../divAndCaption";
|
||||
import { renderImageFromUrl } from "../misc";
|
||||
import { wrapSticker } from "../wrappers";
|
||||
|
||||
export function wrapReplyDivAndCaption(options: {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import type ChatTopbar from "./topbar";
|
||||
import { cancelEvent, whichChild, findUpTag } from "../../helpers/dom";
|
||||
import { cancelEvent, whichChild } from "../../helpers/dom";
|
||||
import AppSearch, { SearchGroup } from "../appSearch";
|
||||
import PopupDatePicker from "../popups/datePicker";
|
||||
import { ripple } from "../ripple";
|
||||
import InputSearch from "../inputSearch";
|
||||
import type Chat from "./chat";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
export default class ChatSearch {
|
||||
private element: HTMLElement;
|
||||
|
@ -3,7 +3,7 @@ import type ChatBubbles from "./bubbles";
|
||||
import type ChatInput from "./input";
|
||||
import type Chat from "./chat";
|
||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||
import { blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getSelectedText } from "../../helpers/dom";
|
||||
import { blurActiveElement, cancelEvent, cancelSelection, getSelectedText } from "../../helpers/dom";
|
||||
import Button from "../button";
|
||||
import ButtonIcon from "../buttonIcon";
|
||||
import CheckboxField from "../checkboxField";
|
||||
@ -16,6 +16,7 @@ import PopupSendNow from "../popups/sendNow";
|
||||
import appNavigationController from "../appNavigationController";
|
||||
import { isMobileSafari } from "../../helpers/userAgent";
|
||||
import I18n, { i18n, _i18n } from "../../lib/langPack";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
|
||||
const MAX_SELECTION_LENGTH = 100;
|
||||
//const MIN_CLICK_MOVE = 32; // minimum bubble height
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { findUpClassName } from "../../helpers/dom";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
import { MyDocument } from "../../lib/appManagers/appDocsManager";
|
||||
import appImManager, { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager";
|
||||
import { CHAT_ANIMATION_GROUP } from "../../lib/appManagers/appImManager";
|
||||
import appStickersManager from "../../lib/appManagers/appStickersManager";
|
||||
import { EmoticonsDropdown } from "../emoticonsDropdown";
|
||||
import { SuperStickerRenderer } from "../emoticonsDropdown/tabs/stickers";
|
||||
|
@ -4,7 +4,7 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage
|
||||
import type { AppPeersManager } from "../../lib/appManagers/appPeersManager";
|
||||
import type { AppSidebarRight } from "../sidebarRight";
|
||||
import type Chat from "./chat";
|
||||
import { findUpClassName, cancelEvent, attachClickEvent, blurActiveElement } from "../../helpers/dom";
|
||||
import { cancelEvent, attachClickEvent, blurActiveElement } from "../../helpers/dom";
|
||||
import mediaSizes, { ScreenSize } from "../../helpers/mediaSizes";
|
||||
import { isSafari } from "../../helpers/userAgent";
|
||||
import rootScope from "../../lib/rootScope";
|
||||
@ -24,6 +24,7 @@ import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft";
|
||||
import AppPrivateSearchTab from "../sidebarRight/tabs/search";
|
||||
import PeerTitle from "../peerTitle";
|
||||
import { i18n } from "../../lib/langPack";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
|
||||
export default class ChatTopbar {
|
||||
container: HTMLDivElement;
|
||||
|
@ -1,9 +1,7 @@
|
||||
import InputField from "./inputField";
|
||||
import InputField, { InputFieldOptions } from "./inputField";
|
||||
|
||||
export default class CodeInputField extends InputField {
|
||||
constructor(options: {
|
||||
label?: string,
|
||||
name?: string,
|
||||
constructor(options: InputFieldOptions & {
|
||||
length: number,
|
||||
onFill: (code: number) => void
|
||||
}) {
|
||||
|
@ -2,11 +2,11 @@ import appDialogsManager from "../lib/appManagers/appDialogsManager";
|
||||
import appMessagesManager, {Dialog} from "../lib/appManagers/appMessagesManager";
|
||||
import appPeersManager from "../lib/appManagers/appPeersManager";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { findUpTag } from "../helpers/dom";
|
||||
import { positionMenu, openBtnMenu } from "./misc";
|
||||
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
|
||||
import PopupDeleteDialog from "./popups/deleteDialog";
|
||||
import { i18n } from "../lib/langPack";
|
||||
import findUpTag from "../helpers/dom/findUpTag";
|
||||
|
||||
export default class DialogsContextMenu {
|
||||
private element: HTMLElement;
|
||||
|
@ -2,7 +2,7 @@ import { isTouchSupported } from "../../helpers/touchSupport";
|
||||
import appChatsManager from "../../lib/appManagers/appChatsManager";
|
||||
import appImManager from "../../lib/appManagers/appImManager";
|
||||
import rootScope from "../../lib/rootScope";
|
||||
import { blurActiveElement, findUpClassName, findUpTag, whichChild } from "../../helpers/dom";
|
||||
import { blurActiveElement, whichChild } from "../../helpers/dom";
|
||||
import animationIntersector from "../animationIntersector";
|
||||
import { horizontalMenu } from "../horizontalMenu";
|
||||
import LazyLoadQueue, { LazyLoadQueueIntersector } from "../lazyLoadQueue";
|
||||
@ -16,6 +16,8 @@ import { pause } from "../../helpers/schedulers";
|
||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||
import AppGifsTab from "../sidebarRight/tabs/gifs";
|
||||
import AppStickersTab from "../sidebarRight/tabs/stickers";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
export const EMOTICONSSTICKERGROUP = 'emoticons-dropdown';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import emoticonsDropdown, { EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab } from "..";
|
||||
import { readBlobAsText } from "../../../helpers/blob";
|
||||
import renderImageFromUrl from "../../../helpers/dom/renderImageFromUrl";
|
||||
import mediaSizes from "../../../helpers/mediaSizes";
|
||||
import { MessagesAllStickers, StickerSet } from "../../../layer";
|
||||
import appDocsManager, { MyDocument } from "../../../lib/appManagers/appDocsManager";
|
||||
@ -10,7 +11,7 @@ import { RichTextProcessor } from "../../../lib/richtextprocessor";
|
||||
import rootScope from "../../../lib/rootScope";
|
||||
import animationIntersector from "../../animationIntersector";
|
||||
import LazyLoadQueue, { LazyLoadQueueRepeat } from "../../lazyLoadQueue";
|
||||
import { putPreloader, renderImageFromUrl } from "../../misc";
|
||||
import { putPreloader } from "../../misc";
|
||||
import Scrollable, { ScrollableX } from "../../scrollable";
|
||||
import StickyIntersector from "../../stickyIntersector";
|
||||
import { wrapSticker } from "../../wrappers";
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { calcImageInBox } from "../helpers/dom";
|
||||
import appDocsManager, {MyDocument} from "../lib/appManagers/appDocsManager";
|
||||
import { wrapVideo } from "./wrappers";
|
||||
import { renderImageFromUrl } from "./misc";
|
||||
import { LazyLoadQueueRepeat2 } from "./lazyLoadQueue";
|
||||
import animationIntersector from "./animationIntersector";
|
||||
import Scrollable from "./scrollable";
|
||||
import { CancellablePromise, deferredPromise } from "../helpers/cancellablePromise";
|
||||
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl";
|
||||
|
||||
const width = 400;
|
||||
const maxSingleWidth = width - 100;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { whichChild, findUpAsChild } from "../helpers/dom";
|
||||
import { whichChild } from "../helpers/dom";
|
||||
import { TransitionSlider } from "./transition";
|
||||
import { ScrollableX } from "./scrollable";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { fastRaf } from "../helpers/schedulers";
|
||||
import { FocusDirection } from "../helpers/fastSmoothScroll";
|
||||
import findUpAsChild from "../helpers/dom/findUpAsChild";
|
||||
|
||||
export function horizontalMenu(tabs: HTMLElement, content: HTMLElement, onClick?: (id: number, tabContent: HTMLDivElement) => void, onTransitionEnd?: () => void, transitionTime = 250, scrollableX?: ScrollableX) {
|
||||
const selectTab = TransitionSlider(content, tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation', transitionTime, onTransitionEnd);
|
||||
|
@ -7,54 +7,6 @@ import { isTouchSupported } from "../helpers/touchSupport";
|
||||
import { isApple, isMobileSafari } from "../helpers/userAgent";
|
||||
import appNavigationController from "./appNavigationController";
|
||||
|
||||
export const loadedURLs: {[url: string]: boolean} = {};
|
||||
const set = (elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string) => {
|
||||
if(elem instanceof HTMLImageElement || elem instanceof HTMLVideoElement) elem.src = url;
|
||||
else if(elem instanceof SVGImageElement) elem.setAttributeNS(null, 'href', url);
|
||||
else elem.style.backgroundImage = 'url(' + url + ')';
|
||||
};
|
||||
|
||||
// проблема функции в том, что она не подходит для ссылок, пригодна только для blob'ов, потому что обычным ссылкам нужен 'load' каждый раз.
|
||||
export function renderImageFromUrl(elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string, callback?: (err?: Event) => void, useCache = false): boolean {
|
||||
if(((loadedURLs[url]/* && false */) && useCache) || elem instanceof HTMLVideoElement) {
|
||||
if(elem) {
|
||||
set(elem, url);
|
||||
}
|
||||
|
||||
callback && callback();
|
||||
return true;
|
||||
} else {
|
||||
const isImage = elem instanceof HTMLImageElement;
|
||||
const loader = isImage ? elem as HTMLImageElement : new Image();
|
||||
//const loader = new Image();
|
||||
loader.src = url;
|
||||
//let perf = performance.now();
|
||||
loader.addEventListener('load', () => {
|
||||
if(!isImage && elem) {
|
||||
set(elem, url);
|
||||
}
|
||||
|
||||
loadedURLs[url] = true;
|
||||
//console.log('onload:', url, performance.now() - perf);
|
||||
if(callback) {
|
||||
// TODO: переделать прогрузки аватаров до начала анимации, иначе с этим ожиданием они неприятно появляются
|
||||
/* getHeavyAnimationPromise().then(() => {
|
||||
callback();
|
||||
}); */
|
||||
callback();
|
||||
}
|
||||
|
||||
//callback && callback();
|
||||
});
|
||||
|
||||
if(callback) {
|
||||
loader.addEventListener('error', callback);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function putPreloader(elem: Element, returnDiv = false): HTMLElement {
|
||||
const html = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="preloader-circular" viewBox="25 25 50 50">
|
||||
|
@ -1,16 +1,12 @@
|
||||
import { cancelEvent } from "../helpers/dom";
|
||||
import InputField from "./inputField";
|
||||
import InputField, { InputFieldOptions } from "./inputField";
|
||||
|
||||
export default class PasswordInputField extends InputField {
|
||||
public passwordVisible = false;
|
||||
public toggleVisible: HTMLElement;
|
||||
public onVisibilityClickAdditional: () => void;
|
||||
|
||||
constructor(options: {
|
||||
label?: string,
|
||||
name?: string,
|
||||
labelText?: string,
|
||||
} = {}) {
|
||||
constructor(options: InputFieldOptions = {}) {
|
||||
super({
|
||||
plainText: true,
|
||||
...options
|
||||
|
@ -5,13 +5,14 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM
|
||||
import serverTimeManager from "../lib/mtproto/serverTimeManager";
|
||||
import { RichTextProcessor } from "../lib/richtextprocessor";
|
||||
import rootScope from "../lib/rootScope";
|
||||
import { attachClickEvent, cancelEvent, detachClickEvent, findUpClassName, replaceContent } from "../helpers/dom";
|
||||
import { attachClickEvent, cancelEvent, detachClickEvent, replaceContent } from "../helpers/dom";
|
||||
import { ripple } from "./ripple";
|
||||
import appSidebarRight from "./sidebarRight";
|
||||
import AppPollResultsTab from "./sidebarRight/tabs/pollResults";
|
||||
import { i18n, LangPackKey } from "../lib/langPack";
|
||||
import { fastRaf } from "../helpers/schedulers";
|
||||
import SetTransition from "./singleTransition";
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
|
||||
let lineTotalLength = 0;
|
||||
const tailLength = 9;
|
||||
@ -203,7 +204,7 @@ export default class PollElement extends HTMLElement {
|
||||
|
||||
//console.log('pollElement poll:', poll, results);
|
||||
|
||||
let descKey: LangPackKey = '';
|
||||
let descKey: LangPackKey;
|
||||
if(poll.pFlags) {
|
||||
this.isPublic = !!poll.pFlags.public_voters;
|
||||
this.isQuiz = !!poll.pFlags.quiz;
|
||||
|
@ -1,15 +1,15 @@
|
||||
import type { Poll } from "../../lib/appManagers/appPollsManager";
|
||||
import type Chat from "../chat/chat";
|
||||
import PopupElement from ".";
|
||||
import { cancelEvent, findUpTag, getRichValue, isInputEmpty, whichChild } from "../../helpers/dom";
|
||||
import { cancelEvent, getRichValue, isInputEmpty, whichChild } from "../../helpers/dom";
|
||||
import CheckboxField from "../checkboxField";
|
||||
import InputField from "../inputField";
|
||||
import RadioField from "../radioField";
|
||||
import Scrollable from "../scrollable";
|
||||
import { toast } from "../toast";
|
||||
import SendContextMenu from "../chat/sendContextMenu";
|
||||
import { MessageEntity } from "../../layer";
|
||||
import I18n, { _i18n, i18n } from "../../lib/langPack";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
const MAX_LENGTH_QUESTION = 255;
|
||||
const MAX_LENGTH_OPTION = 100;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import rootScope from "../../lib/rootScope";
|
||||
import { blurActiveElement, findUpClassName } from "../../helpers/dom";
|
||||
import { blurActiveElement } from "../../helpers/dom";
|
||||
import { ripple } from "../ripple";
|
||||
import animationIntersector from "../animationIntersector";
|
||||
import appNavigationController, { NavigationItem } from "../appNavigationController";
|
||||
import { i18n, LangPackKey } from "../../lib/langPack";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
|
||||
export type PopupButton = {
|
||||
text?: string,
|
||||
@ -17,7 +18,7 @@ export type PopupButton = {
|
||||
export type PopupOptions = Partial<{
|
||||
closable: true,
|
||||
overlayClosable: true,
|
||||
withConfirm: LangPackKey,
|
||||
withConfirm: LangPackKey | true,
|
||||
body: true
|
||||
}>;
|
||||
|
||||
@ -69,7 +70,9 @@ export default class PopupElement {
|
||||
if(options.withConfirm) {
|
||||
this.btnConfirm = document.createElement('button');
|
||||
this.btnConfirm.classList.add('btn-primary', 'btn-color-primary');
|
||||
this.btnConfirm.append(i18n(options.withConfirm));
|
||||
if(options.withConfirm !== true) {
|
||||
this.btnConfirm.append(i18n(options.withConfirm));
|
||||
}
|
||||
this.header.append(this.btnConfirm);
|
||||
ripple(this.btnConfirm);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import PopupElement, { addCancelButton, PopupButton, PopupOptions } from ".";
|
||||
import { i18n, LangPackKey } from "../../lib/langPack";
|
||||
import CheckboxField, { CheckboxFieldOptions } from "../checkboxField";
|
||||
|
||||
export type PopupPeerButtonCallbackCheckboxes = {[text in LangPackKey]: boolean};
|
||||
export type PopupPeerButtonCallbackCheckboxes = Partial<{[text in LangPackKey]: boolean}>;
|
||||
export type PopupPeerButtonCallback = (checkboxes?: PopupPeerButtonCallbackCheckboxes) => void;
|
||||
|
||||
export type PopupPeerOptions = PopupOptions & Partial<{
|
||||
|
@ -13,7 +13,7 @@ export default class PopupSchedule extends PopupDatePicker {
|
||||
noButtons: true,
|
||||
noTitle: true,
|
||||
closable: true,
|
||||
withConfirm: 'Send Today',
|
||||
withConfirm: true,
|
||||
minDate: getMinDate(),
|
||||
maxDate: (() => {
|
||||
const date = new Date();
|
||||
|
@ -6,12 +6,13 @@ import { wrapSticker } from "../wrappers";
|
||||
import LazyLoadQueue from "../lazyLoadQueue";
|
||||
import { putPreloader } from "../misc";
|
||||
import animationIntersector from "../animationIntersector";
|
||||
import { findUpClassName, toggleDisability } from "../../helpers/dom";
|
||||
import { toggleDisability } from "../../helpers/dom";
|
||||
import appImManager from "../../lib/appManagers/appImManager";
|
||||
import { StickerSet } from "../../layer";
|
||||
import mediaSizes from "../../helpers/mediaSizes";
|
||||
import { i18n } from "../../lib/langPack";
|
||||
import Button from "../button";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
|
||||
const ANIMATION_GROUP = 'STICKERS-POPUP';
|
||||
|
||||
|
@ -9,7 +9,7 @@ import PeerTitle from "../peerTitle";
|
||||
|
||||
export default class PopupPinMessage {
|
||||
constructor(peerId: number, mid: number, unpin?: true, onConfirm?: () => void) {
|
||||
let title: LangPackKey, description: string, buttons: PopupButton[] = [];
|
||||
let title: LangPackKey, description: LangPackKey, buttons: PopupButton[] = [];
|
||||
|
||||
const canUnpin = appPeersManager.canPinMessage(peerId);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import findUpClassName from "../helpers/dom/findUpClassName";
|
||||
import {isTouchSupported} from "../helpers/touchSupport";
|
||||
import { findUpClassName } from "../helpers/dom";
|
||||
import rootScope from "../lib/rootScope";
|
||||
|
||||
let rippleClickId = 0;
|
||||
|
@ -5,7 +5,6 @@ import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||
import appStateManager from "../../lib/appManagers/appStateManager";
|
||||
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
||||
import rootScope from "../../lib/rootScope";
|
||||
import { attachClickEvent, findUpClassName, findUpTag } from "../../helpers/dom";
|
||||
import { SearchGroup } from "../appSearch";
|
||||
import "../avatar";
|
||||
import Scrollable, { ScrollableX } from "../scrollable";
|
||||
@ -27,6 +26,8 @@ import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
|
||||
import CheckboxField from "../checkboxField";
|
||||
import { isMobileSafari } from "../../helpers/userAgent";
|
||||
import appNavigationController from "../appNavigationController";
|
||||
import findUpClassName from "../../helpers/dom/findUpClassName";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
export const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown';
|
||||
|
||||
|
@ -26,7 +26,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
|
||||
this.setTitle('RecoveryEmailTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: '',
|
||||
caption: true,
|
||||
noDelimiter: true
|
||||
});
|
||||
|
||||
|
@ -21,7 +21,7 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
|
||||
this.setTitle('TwoStepVerificationTitle');
|
||||
|
||||
const section = new SettingSection({
|
||||
caption: ' ',
|
||||
caption: true,
|
||||
noDelimiter: true
|
||||
});
|
||||
|
||||
|
@ -5,13 +5,14 @@ import Row from "../../row";
|
||||
import { Authorization } from "../../../layer";
|
||||
import { formatDateAccordingToToday } from "../../../helpers/date";
|
||||
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
|
||||
import { attachClickEvent, findUpClassName, toggleDisability } from "../../../helpers/dom";
|
||||
import { attachClickEvent, toggleDisability } from "../../../helpers/dom";
|
||||
import ButtonMenu from "../../buttonMenu";
|
||||
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
||||
import { toast } from "../../toast";
|
||||
import AppPrivacyAndSecurityTab from "./privacyAndSecurity";
|
||||
import I18n from "../../../lib/langPack";
|
||||
import PopupPeer from "../../popups/peer";
|
||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||
|
||||
export default class AppActiveSessionsTab extends SliderSuperTab {
|
||||
public privacyTab: AppPrivacyAndSecurityTab;
|
||||
|
@ -2,8 +2,9 @@ import { generateSection } from "..";
|
||||
import { averageColor } from "../../../helpers/averageColor";
|
||||
import blur from "../../../helpers/blur";
|
||||
import { deferredPromise } from "../../../helpers/cancellablePromise";
|
||||
import { highlightningColor, rgbToHsl } from "../../../helpers/color";
|
||||
import { attachClickEvent, findUpClassName } from "../../../helpers/dom";
|
||||
import { highlightningColor } from "../../../helpers/color";
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||
import { AccountWallPapers, WallPaper } from "../../../layer";
|
||||
import appDocsManager, { MyDocument } from "../../../lib/appManagers/appDocsManager";
|
||||
import appDownloadManager from "../../../lib/appManagers/appDownloadManager";
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { SliderSuperTab } from "../../slider";
|
||||
import { SettingSection } from "..";
|
||||
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
|
||||
import { attachClickEvent, findUpTag } from "../../../helpers/dom";
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import ButtonMenu from "../../buttonMenu";
|
||||
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||
import Button from "../../button";
|
||||
import PopupPickUser from "../../popups/pickUser";
|
||||
import rootScope from "../../../lib/rootScope";
|
||||
import findUpTag from "../../../helpers/dom/findUpTag";
|
||||
|
||||
export default class AppBlockedUsersTab extends SliderSuperTab {
|
||||
public peerIds: number[];
|
||||
|
@ -167,7 +167,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
|
||||
}, {listenerSetter: this.listenerSetter});
|
||||
}
|
||||
|
||||
{
|
||||
/* {
|
||||
const section = new SettingSection({
|
||||
|
||||
});
|
||||
@ -195,7 +195,7 @@ export default class AppEditGroupTab extends SliderSuperTab {
|
||||
}
|
||||
|
||||
this.scrollable.append(section.container);
|
||||
}
|
||||
} */
|
||||
|
||||
if(appChatsManager.hasRights(this.chatId, 'delete_chat')) {
|
||||
const section = new SettingSection({});
|
||||
|
@ -5,10 +5,11 @@ import appSidebarRight from "..";
|
||||
import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
||||
import appInlineBotsManager, { AppInlineBotsManager } from "../../../lib/appManagers/appInlineBotsManager";
|
||||
import GifsMasonry from "../../gifsMasonry";
|
||||
import { findUpClassName, attachClickEvent } from "../../../helpers/dom";
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import appImManager from "../../../lib/appManagers/appImManager";
|
||||
import type { MyDocument } from "../../../lib/appManagers/appDocsManager";
|
||||
import mediaSizes from "../../../helpers/mediaSizes";
|
||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||
|
||||
const ANIMATIONGROUP = 'GIFS-SEARCH';
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { attachClickEvent, findUpTag } from "../../../helpers/dom";
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import findUpTag from "../../../helpers/dom/findUpTag";
|
||||
import ListenerSetter from "../../../helpers/listenerSetter";
|
||||
import ScrollableLoader from "../../../helpers/listLoader";
|
||||
import { ChannelParticipant, Chat, ChatBannedRights, Update } from "../../../layer";
|
||||
import appChatsManager, { ChatRights } from "../../../lib/appManagers/appChatsManager";
|
||||
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
|
||||
import appProfileManager from "../../../lib/appManagers/appProfileManager";
|
||||
import I18n, { i18n } from "../../../lib/langPack";
|
||||
import I18n, { i18n, LangPackKey } from "../../../lib/langPack";
|
||||
import rootScope from "../../../lib/rootScope";
|
||||
import CheckboxField from "../../checkboxField";
|
||||
import PopupPickUser from "../../popups/pickUser";
|
||||
@ -18,7 +19,7 @@ import AppUserPermissionsTab from "./userPermissions";
|
||||
export class ChatPermissions {
|
||||
public v: Array<{
|
||||
flags: ChatRights[],
|
||||
text: string,
|
||||
text: LangPackKey,
|
||||
checkboxField?: CheckboxField
|
||||
}>;
|
||||
private toggleWith: Partial<{[chatRight in ChatRights]: ChatRights[]}>;
|
||||
|
@ -116,7 +116,7 @@ export default class AppGroupTypeTab extends SliderSuperTabEventable {
|
||||
plainText: true,
|
||||
listenerSetter: this.listenerSetter,
|
||||
availableText: 'Link.Available',
|
||||
invalidText: 'Link is invalid',
|
||||
invalidText: 'Link.Invalid',
|
||||
takenText: 'Link.Taken',
|
||||
onChange: onChange,
|
||||
peerId: this.peerId,
|
||||
|
@ -92,9 +92,9 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
||||
|
||||
this.title.append(i18n('Telegram.PeerInfoController'));
|
||||
this.editBtn = ButtonIcon('edit');
|
||||
const moreBtn = ButtonIcon('more');
|
||||
//const moreBtn = ButtonIcon('more');
|
||||
|
||||
transitionFirstItem.append(this.title, this.editBtn, moreBtn);
|
||||
transitionFirstItem.append(this.title, this.editBtn/* , moreBtn */);
|
||||
|
||||
const transitionLastItem = document.createElement('div');
|
||||
transitionLastItem.classList.add('transition-item');
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { SliderSuperTab } from "../../slider";
|
||||
import InputSearch from "../../inputSearch";
|
||||
import LazyLoadQueue from "../../lazyLoadQueue";
|
||||
import { findUpClassName, attachClickEvent } from "../../../helpers/dom";
|
||||
import { attachClickEvent } from "../../../helpers/dom";
|
||||
import appImManager from "../../../lib/appManagers/appImManager";
|
||||
import appStickersManager from "../../../lib/appManagers/appStickersManager";
|
||||
import PopupStickers from "../../popups/stickers";
|
||||
@ -12,6 +12,7 @@ import appSidebarRight from "..";
|
||||
import { StickerSet, StickerSetCovered } from "../../../layer";
|
||||
import { forEachReverse } from "../../../helpers/array";
|
||||
import { i18n } from "../../../lib/langPack";
|
||||
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
||||
|
||||
export default class AppStickersTab extends SliderSuperTab {
|
||||
private inputSearch: InputSearch;
|
||||
|
@ -19,7 +19,6 @@ import AudioElement from './audio';
|
||||
import ReplyContainer from './chat/replyContainer';
|
||||
import { Layouter, RectPart } from './groupedLayout';
|
||||
import LazyLoadQueue from './lazyLoadQueue';
|
||||
import { renderImageFromUrl } from './misc';
|
||||
import PollElement from './poll';
|
||||
import ProgressivePreloader from './preloader';
|
||||
import './middleEllipsis';
|
||||
@ -30,6 +29,7 @@ import { SearchSuperContext } from './appSearchSuper.';
|
||||
import rootScope from '../lib/rootScope';
|
||||
import { onVideoLoad } from '../helpers/files';
|
||||
import { animateSingle } from '../helpers/animation';
|
||||
import renderImageFromUrl from '../helpers/dom/renderImageFromUrl';
|
||||
|
||||
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
|
||||
|
||||
|
@ -2,7 +2,7 @@ const App = {
|
||||
id: 1025907,
|
||||
hash: '452b0359b988148995f22ff0f4229750',
|
||||
version: '0.4.0',
|
||||
langPackVersion: '0.0.5',
|
||||
langPackVersion: '0.0.8',
|
||||
langPack: 'macos',
|
||||
langPackCode: 'en',
|
||||
domains: [] as string[],
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { renderImageFromUrl } from "../components/misc";
|
||||
import renderImageFromUrl from "./dom/renderImageFromUrl";
|
||||
|
||||
export const averageColor = (imageUrl: string): Promise<Uint8ClampedArray> => {
|
||||
const img = document.createElement('img');
|
||||
|
@ -338,56 +338,6 @@ export function generatePathData(x: number, y: number, width: number, height: nu
|
||||
|
||||
MOUNT_CLASS_TO.generatePathData = generatePathData;
|
||||
|
||||
//export function findUpClassName<T>(el: any, className: string): T;
|
||||
export function findUpClassName(el: any, className: string): HTMLElement {
|
||||
return el.closest('.' + className);
|
||||
/* if(el.classList.contains(className)) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.classList.contains(className))
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
||||
|
||||
export function findUpTag(el: any, tag: string): HTMLElement {
|
||||
return el.closest(tag);
|
||||
/* if(el.tagName === tag) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.tagName === tag)
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
||||
|
||||
export function findUpAttribute(el: any, attribute: string): HTMLElement {
|
||||
return el.closest(`[${attribute}]`);
|
||||
/* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.getAttribute(attribute) !== null)
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
||||
|
||||
export function findUpAsChild(el: any, parent: any) {
|
||||
if(el.parentElement === parent) return el;
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.parentElement === parent) {
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function whichChild(elem: Node) {
|
||||
if(!elem.parentNode) {
|
||||
return -1;
|
||||
@ -499,26 +449,6 @@ export function blurActiveElement() {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function fixSafariStickyInput(input: HTMLElement) {
|
||||
input.style.transform = 'translateY(-99999px)';
|
||||
/* input.style.position = 'fixed';
|
||||
input.style.top = '-99999px';
|
||||
input.style.left = '0'; */
|
||||
input.focus();
|
||||
|
||||
setTimeout(() => {
|
||||
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
|
||||
/* input.style.position = '';
|
||||
input.style.top = ''; */
|
||||
input.style.transform = '';
|
||||
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
|
||||
|
||||
/* setTimeout(() => {
|
||||
fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4);
|
||||
}, 50); */
|
||||
}, 0);
|
||||
}
|
||||
|
||||
export const CLICK_EVENT_NAME: 'mousedown' | 'touchend' | 'click' = (isTouchSupported ? 'mousedown' : 'click') as any;
|
||||
export type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;
|
||||
export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | MouseEvent) => void, options: AttachClickOptions = {}) => {
|
||||
|
12
src/helpers/dom/findUpAsChild.ts
Normal file
12
src/helpers/dom/findUpAsChild.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export default function findUpAsChild(el: any, parent: any) {
|
||||
if(el.parentElement === parent) return el;
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.parentElement === parent) {
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
11
src/helpers/dom/findUpAttribute.ts
Normal file
11
src/helpers/dom/findUpAttribute.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export default function findUpAttribute(el: any, attribute: string): HTMLElement {
|
||||
return el.closest(`[${attribute}]`);
|
||||
/* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.getAttribute(attribute) !== null)
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
12
src/helpers/dom/findUpClassName.ts
Normal file
12
src/helpers/dom/findUpClassName.ts
Normal file
@ -0,0 +1,12 @@
|
||||
//export function findUpClassName<T>(el: any, className: string): T;
|
||||
export default function findUpClassName(el: any, className: string): HTMLElement {
|
||||
return el.closest('.' + className);
|
||||
/* if(el.classList.contains(className)) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.classList.contains(className))
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
11
src/helpers/dom/findUpTag.ts
Normal file
11
src/helpers/dom/findUpTag.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export default function findUpTag(el: any, tag: string): HTMLElement {
|
||||
return el.closest(tag);
|
||||
/* if(el.tagName === tag) return el; // 03.02.2020
|
||||
|
||||
while(el.parentElement) {
|
||||
el = el.parentElement;
|
||||
if(el.tagName === tag)
|
||||
return el;
|
||||
}
|
||||
return null; */
|
||||
}
|
19
src/helpers/dom/fixSafariStickyInput.ts
Normal file
19
src/helpers/dom/fixSafariStickyInput.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export default function fixSafariStickyInput(input: HTMLElement) {
|
||||
input.style.transform = 'translateY(-99999px)';
|
||||
/* input.style.position = 'fixed';
|
||||
input.style.top = '-99999px';
|
||||
input.style.left = '0'; */
|
||||
input.focus();
|
||||
|
||||
setTimeout(() => {
|
||||
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
|
||||
/* input.style.position = '';
|
||||
input.style.top = ''; */
|
||||
input.style.transform = '';
|
||||
//fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4, undefined, FocusDirection.Static);
|
||||
|
||||
/* setTimeout(() => {
|
||||
fastSmoothScroll(findUpClassName(input, 'scrollable-y') || window as any, document.activeElement as HTMLElement, 'start', 4);
|
||||
}, 50); */
|
||||
}, 0);
|
||||
}
|
47
src/helpers/dom/renderImageFromUrl.ts
Normal file
47
src/helpers/dom/renderImageFromUrl.ts
Normal file
@ -0,0 +1,47 @@
|
||||
export const loadedURLs: {[url: string]: boolean} = {};
|
||||
const set = (elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string) => {
|
||||
if(elem instanceof HTMLImageElement || elem instanceof HTMLVideoElement) elem.src = url;
|
||||
else if(elem instanceof SVGImageElement) elem.setAttributeNS(null, 'href', url);
|
||||
else elem.style.backgroundImage = 'url(' + url + ')';
|
||||
};
|
||||
|
||||
// проблема функции в том, что она не подходит для ссылок, пригодна только для blob'ов, потому что обычным ссылкам нужен 'load' каждый раз.
|
||||
export default function renderImageFromUrl(elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string, callback?: (err?: Event) => void, useCache = false): boolean {
|
||||
if(((loadedURLs[url]/* && false */) && useCache) || elem instanceof HTMLVideoElement) {
|
||||
if(elem) {
|
||||
set(elem, url);
|
||||
}
|
||||
|
||||
callback && callback();
|
||||
return true;
|
||||
} else {
|
||||
const isImage = elem instanceof HTMLImageElement;
|
||||
const loader = isImage ? elem as HTMLImageElement : new Image();
|
||||
//const loader = new Image();
|
||||
loader.src = url;
|
||||
//let perf = performance.now();
|
||||
loader.addEventListener('load', () => {
|
||||
if(!isImage && elem) {
|
||||
set(elem, url);
|
||||
}
|
||||
|
||||
loadedURLs[url] = true;
|
||||
//console.log('onload:', url, performance.now() - perf);
|
||||
if(callback) {
|
||||
// TODO: переделать прогрузки аватаров до начала анимации, иначе с этим ожиданием они неприятно появляются
|
||||
/* getHeavyAnimationPromise().then(() => {
|
||||
callback();
|
||||
}); */
|
||||
callback();
|
||||
}
|
||||
|
||||
//callback && callback();
|
||||
});
|
||||
|
||||
if(callback) {
|
||||
loader.addEventListener('error', callback);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -55,24 +55,8 @@
|
||||
<div class="input-wrapper"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-password">
|
||||
<div class="container center-align">
|
||||
<div class="auth-image"></div>
|
||||
<h4 class="phone">Enter Your Password</h4>
|
||||
<p class="subtitle">Your account is protected with<br>an additional password</p>
|
||||
<div class="input-wrapper"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-signUp">
|
||||
<div class="container center-align">
|
||||
<div class="auth-image avatar-edit">
|
||||
<canvas class="avatar-edit-canvas" id="canvas-avatar"></canvas>
|
||||
<span class="tgico tgico-cameraadd"></span>
|
||||
</div>
|
||||
<h4 class="fullName">Your Name</h4>
|
||||
<p class="subtitle">Enter your name and add<br>a profile picture</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-password"></div>
|
||||
<div class="page-signUp"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -87,8 +87,8 @@ const lang = {
|
||||
"Popup.Unpin.Hide": "Hide",
|
||||
"TwoStepAuth.InvalidPassword": "Invalid password",
|
||||
"TwoStepAuth.EmailCodeChangeEmail": "Change Email",
|
||||
"PleaseWait": "Please wait...",
|
||||
"MarkupTooltip.LinkPlaceholder": "Enter URL...",
|
||||
"MediaViewer.Context.Download": "Download",
|
||||
|
||||
// * android
|
||||
"ActionCreateChannel": "Channel created",
|
||||
@ -358,7 +358,6 @@ const lang = {
|
||||
"PleaseEnterCurrentPassword": "Enter your password",
|
||||
"PleaseEnterFirstPassword": "Enter a password",
|
||||
"PleaseReEnterPassword": "Re-enter your password",
|
||||
"LoginPassword": "Password",
|
||||
"Continue": "Continue",
|
||||
"YourEmailSkip": "Skip",
|
||||
"YourEmailSkipWarning": "Warning",
|
||||
@ -391,6 +390,8 @@ const lang = {
|
||||
"Channel.UsernameAboutGroup": "People can share this link with others and find your group using Telegram search.",
|
||||
"Chat.CopySelectedText": "Copy Selected Text",
|
||||
"Chat.Confirm.Unpin": "Would you like to unpin this message?",
|
||||
"Chat.Context.Scheduled.SendNow": "Send Now",
|
||||
"Chat.Context.Scheduled.Reschedule": "Re-schedule",
|
||||
"Chat.Date.ScheduledFor": "Scheduled for %@",
|
||||
//"Chat.Date.ScheduledUntilOnline": "Scheduled until online",
|
||||
"Chat.Date.ScheduledForToday": "Scheduled for today",
|
||||
@ -483,6 +484,7 @@ const lang = {
|
||||
"Telegram.InstalledStickerPacksController": "Stickers",
|
||||
"Telegram.NotificationSettingsViewController": "Notifications",
|
||||
"Telegram.PeerInfoController": "Info",
|
||||
"Telegram.LanguageViewController": "Language",
|
||||
"Stickers.SearchAdd": "Add",
|
||||
"Stickers.SearchAdded": "Added",
|
||||
"Stickers.SuggestStickers": "Suggest Stickers by Emoji",
|
||||
@ -596,8 +598,7 @@ const lang = {
|
||||
"TwoStepAuth.RecoveryCodeInvalid": "Invalid code. Please try again.",
|
||||
"TwoStepAuth.RecoveryCodeExpired": "Code Expired",
|
||||
"TwoStepAuth.SetupHintTitle": "Password Hint",
|
||||
"TwoStepAuth.SetupHintPlaceholder": "Hint",
|
||||
"PHONE_CODE_INVALID": "Invalid code",
|
||||
"TwoStepAuth.SetupHintPlaceholder": "Hint"
|
||||
};
|
||||
|
||||
export default lang;
|
||||
|
@ -5,9 +5,22 @@ const lang = {
|
||||
"Login.PhoneLabelInvalid": "Phone Number Invalid",
|
||||
"Login.KeepSigned": "Keep me signed in",
|
||||
"Login.StartText": "Please confirm your country and\nenter your phone number.",
|
||||
"Login.Code.SentSms": "We have sent you an SMS\nwith the code.",
|
||||
"Login.Code.SentInApp": "We have sent you a message in Telegram\nwith the code.",
|
||||
"Login.Code.SentCall": "We will call you and voice\nthe code.",
|
||||
"Login.Code.SentUnknown": "Please check everything\nfor a code (type: %s)",
|
||||
"Login.Password.Title": "Enter Your Password",
|
||||
"Login.Password.Subtitle": "Your account is protected with\nan additional password",
|
||||
"Login.Register.Subtitle": "Enter your name and add\na profile picture",
|
||||
"PleaseWait": "Please wait...",
|
||||
|
||||
// * android
|
||||
|
||||
"Code": "Code",
|
||||
"LoginPassword": "Password",
|
||||
"YourName": "Your Name",
|
||||
"FirstName": "First name (required)",
|
||||
"LastName": "Last name (optional)",
|
||||
"StartMessaging": "Start Messaging",
|
||||
|
||||
// * macos
|
||||
"Login.Next": "Next",
|
||||
@ -18,6 +31,9 @@ const lang = {
|
||||
"Login.QR.Help3": "Point your phone at this screen to confirm login",
|
||||
"Login.QR.Cancel": "Log in by phone Number",
|
||||
"Login.QR.Login": "Log in by QR Code",
|
||||
"PHONE_CODE_INVALID": "Invalid code",
|
||||
"PHONE_CODE_EXPIRED": "Code expired",
|
||||
"PASSWORD_HASH_INVALID": "Incorrect password"
|
||||
};
|
||||
|
||||
export default lang;
|
||||
|
4
src/layer.d.ts
vendored
4
src/layer.d.ts
vendored
@ -6043,7 +6043,9 @@ export namespace LangPackDifference {
|
||||
lang_code: string,
|
||||
from_version: number,
|
||||
version: number,
|
||||
strings: Array<LangPackString>
|
||||
strings: Array<LangPackString>,
|
||||
local?: boolean,
|
||||
appVersion?: string
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { isSafari } from "../../helpers/userAgent";
|
||||
import { logger, LogLevels } from "../logger";
|
||||
import { RichTextProcessor } from "../richtextprocessor";
|
||||
import rootScope from "../rootScope";
|
||||
import { findUpTag, positionElementByIndex } from "../../helpers/dom";
|
||||
import { positionElementByIndex } from "../../helpers/dom";
|
||||
import appImManager from "./appImManager";
|
||||
import appMessagesManager, { Dialog } from "./appMessagesManager";
|
||||
import {MyDialogFilter as DialogFilter} from "../storages/filters";
|
||||
@ -30,6 +30,7 @@ import appNotificationsManager from "./appNotificationsManager";
|
||||
import { InputNotifyPeer } from "../../layer";
|
||||
import PeerTitle from "../../components/peerTitle";
|
||||
import { i18n } from "../langPack";
|
||||
import findUpTag from "../../helpers/dom/findUpTag";
|
||||
|
||||
type DialogDom = {
|
||||
avatarEl: AvatarElement,
|
||||
|
@ -2690,7 +2690,7 @@ export class AppMessagesManager {
|
||||
} else {
|
||||
let _ = action._;
|
||||
//let suffix = '';
|
||||
let langPackKey: LangPackKey = '';
|
||||
let langPackKey: LangPackKey;
|
||||
let args: any[];
|
||||
|
||||
const getNameDivHTML = (peerId: number, plain: boolean) => {
|
||||
@ -2789,14 +2789,14 @@ export class AppMessagesManager {
|
||||
}
|
||||
|
||||
default:
|
||||
langPackKey = langPack[_] || `[${action._}]`;
|
||||
langPackKey = (langPack[_] || `[${action._}]`) as any;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!langPackKey) {
|
||||
langPackKey = langPack[_];
|
||||
if(langPackKey === undefined) {
|
||||
langPackKey = '[' + _ + ']';
|
||||
langPackKey = '[' + _ + ']' as any;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,8 @@ import { MyDocument } from "./appDocsManager";
|
||||
import appDownloadManager from "./appDownloadManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
import blur from "../../helpers/blur";
|
||||
import { renderImageFromUrl } from "../../components/misc";
|
||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||
import renderImageFromUrl from "../../helpers/dom/renderImageFromUrl";
|
||||
|
||||
export type MyPhoto = Photo.photo;
|
||||
|
||||
|
@ -406,7 +406,7 @@ export class AppUsersManager {
|
||||
|
||||
const user = this.getUser(userId);
|
||||
if(!user) {
|
||||
key = '';
|
||||
key = '' as any;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -432,8 +432,6 @@ export class AppUsersManager {
|
||||
}
|
||||
|
||||
case 'userStatusOffline': {
|
||||
key = 'last seen ';
|
||||
|
||||
const date = user.status.was_online;
|
||||
const now = Date.now() / 1000;
|
||||
|
||||
|
@ -42,7 +42,7 @@ export const langPack: {[actionType: string]: LangPackKey} = {
|
||||
"messageActionBotAllowed": "Chat.Service.BotPermissionAllowed"
|
||||
};
|
||||
|
||||
export type LangPackKey = string | keyof typeof lang | keyof typeof langSign;
|
||||
export type LangPackKey = /* string | */keyof typeof lang | keyof typeof langSign;
|
||||
|
||||
namespace I18n {
|
||||
export const strings: Map<LangPackKey, LangPackString> = new Map();
|
||||
@ -50,10 +50,11 @@ namespace I18n {
|
||||
|
||||
let cacheLangPackPromise: Promise<LangPackDifference>;
|
||||
export let lastRequestedLangCode: string;
|
||||
export let requestedServerLanguage = false;
|
||||
export function getCacheLangPack(): Promise<LangPackDifference> {
|
||||
if(cacheLangPackPromise) return cacheLangPackPromise;
|
||||
return cacheLangPackPromise = Promise.all([
|
||||
sessionStorage.get('langPack'),
|
||||
sessionStorage.get('langPack') as Promise<LangPackDifference>,
|
||||
polyfillPromise
|
||||
]).then(([langPack]) => {
|
||||
if(!langPack/* || true */) {
|
||||
@ -91,13 +92,15 @@ namespace I18n {
|
||||
from_version: 0,
|
||||
lang_code: defaultCode,
|
||||
strings,
|
||||
version: 0
|
||||
version: 0,
|
||||
local: true
|
||||
};
|
||||
return saveLangPack(langPack);
|
||||
});
|
||||
}
|
||||
|
||||
export function loadLangPack(langCode: string) {
|
||||
requestedServerLanguage = true;
|
||||
return Promise.all([
|
||||
apiManager.invokeApiCacheable('langpack.getLangPack', {
|
||||
lang_code: langCode,
|
||||
@ -164,7 +167,6 @@ namespace I18n {
|
||||
}
|
||||
|
||||
export function saveLangPack(langPack: LangPackDifference) {
|
||||
// @ts-ignore
|
||||
langPack.appVersion = App.langPackVersion;
|
||||
|
||||
return sessionStorage.set({langPack}).then(() => {
|
||||
|
48
src/pages/loginPage.ts
Normal file
48
src/pages/loginPage.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { LangPackKey, i18n } from "../lib/langPack";
|
||||
|
||||
export default class LoginPage {
|
||||
public element: HTMLElement;
|
||||
public container: HTMLElement;
|
||||
public imageDiv: HTMLElement;
|
||||
public inputWrapper: HTMLElement;
|
||||
public title: HTMLElement;
|
||||
public subtitle: HTMLParagraphElement;
|
||||
|
||||
constructor(options: {
|
||||
className: string,
|
||||
withInputWrapper?: boolean,
|
||||
titleLangKey?: LangPackKey,
|
||||
subtitleLangKey?: LangPackKey,
|
||||
}) {
|
||||
this.element = document.body.querySelector('.' + options.className) as HTMLDivElement;
|
||||
//this.element = document.createElement('div');
|
||||
//this.element.className = 'page-' + options.className;
|
||||
|
||||
this.container = document.createElement('div');
|
||||
this.container.className = 'container center-align';
|
||||
|
||||
this.imageDiv = document.createElement('div');
|
||||
this.imageDiv.className = 'auth-image';
|
||||
|
||||
this.title = document.createElement('h4');
|
||||
if(options.titleLangKey) {
|
||||
this.title.append(i18n(options.titleLangKey));
|
||||
}
|
||||
|
||||
this.subtitle = document.createElement('p');
|
||||
this.subtitle.className = 'subtitle';
|
||||
if(options.subtitleLangKey) {
|
||||
this.subtitle.append(i18n(options.subtitleLangKey));
|
||||
}
|
||||
|
||||
this.container.append(this.imageDiv, this.title, this.subtitle);
|
||||
|
||||
if(options.withInputWrapper) {
|
||||
this.inputWrapper = document.createElement('div');
|
||||
this.inputWrapper.className = 'input-wrapper';
|
||||
this.container.append(this.inputWrapper);
|
||||
}
|
||||
|
||||
this.element.append(this.container);
|
||||
}
|
||||
}
|
@ -9,6 +9,8 @@ import pageSignIn from './pageSignIn';
|
||||
import pageSignUp from './pageSignUp';
|
||||
import TrackingMonkey from '../components/monkeys/tracking';
|
||||
import CodeInputField from '../components/codeInputField';
|
||||
import { replaceContent } from '../helpers/dom';
|
||||
import { i18n, LangPackKey } from '../lib/langPack';
|
||||
|
||||
let authCode: AuthSentCode.authSentCode = null;
|
||||
|
||||
@ -89,12 +91,12 @@ let onFirstMount = (): Promise<any> => {
|
||||
break;
|
||||
case 'PHONE_CODE_EXPIRED':
|
||||
codeInput.classList.add('error');
|
||||
codeInputField.label.innerText = 'Code expired';
|
||||
replaceContent(codeInputField.label, i18n('PHONE_CODE_EXPIRED'));
|
||||
break;
|
||||
case 'PHONE_CODE_EMPTY':
|
||||
case 'PHONE_CODE_INVALID':
|
||||
codeInput.classList.add('error');
|
||||
codeInputField.label.innerText = 'Invalid Code';
|
||||
replaceContent(codeInputField.label, i18n('PHONE_CODE_INVALID'));
|
||||
break;
|
||||
default:
|
||||
codeInputField.label.innerText = err.type;
|
||||
@ -127,21 +129,25 @@ const page = new Page('page-authCode', true, onFirstMount, (_authCode: typeof au
|
||||
}
|
||||
|
||||
headerElement.innerText = authCode.phone_number;
|
||||
let key: LangPackKey, args: any[];
|
||||
switch(authCode.type._) {
|
||||
case 'auth.sentCodeTypeSms':
|
||||
sentTypeElement.innerHTML = 'We have sent you an SMS<br>with the code.';
|
||||
key = 'Login.Code.SentSms';
|
||||
break;
|
||||
case 'auth.sentCodeTypeApp':
|
||||
sentTypeElement.innerHTML = 'We have sent you a message in Telegram<br>with the code.';
|
||||
key = 'Login.Code.SentInApp';
|
||||
break;
|
||||
case 'auth.sentCodeTypeCall':
|
||||
sentTypeElement.innerHTML = 'We will call you and voice<br>the code.';
|
||||
key = 'Login.Code.SentCall';
|
||||
break;
|
||||
default:
|
||||
sentTypeElement.innerHTML = `Please check everything<br>for a code (type: ${authCode.type._})`;
|
||||
key = 'Login.Code.SentUnknown';
|
||||
args = [authCode.type._];
|
||||
break;
|
||||
}
|
||||
|
||||
replaceContent(sentTypeElement, i18n(key, args));
|
||||
|
||||
appStateManager.pushToState('authState', {_: 'authStateAuthCode', sentCode: _authCode});
|
||||
appStateManager.saveState();
|
||||
}, () => {
|
||||
|
@ -2,6 +2,7 @@
|
||||
//import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import { blurActiveElement } from "../helpers/dom";
|
||||
import appStateManager from "../lib/appManagers/appStateManager";
|
||||
import I18n from "../lib/langPack";
|
||||
import Page from "./page";
|
||||
|
||||
let onFirstMount = () => {
|
||||
@ -14,6 +15,14 @@ let onFirstMount = () => {
|
||||
m.default.broadcast('im_mount');
|
||||
});
|
||||
|
||||
if(!I18n.requestedServerLanguage) {
|
||||
I18n.getCacheLangPack().then(langPack => {
|
||||
if(langPack.local) {
|
||||
I18n.getLangPack(langPack.lang_code);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
blurActiveElement();
|
||||
return new Promise<void>((resolve) => {
|
||||
window.requestAnimationFrame(() => {
|
||||
|
@ -8,23 +8,35 @@ import pageIm from './pageIm';
|
||||
import Button from '../components/button';
|
||||
import PasswordInputField from '../components/passwordInputField';
|
||||
import PasswordMonkey from '../components/monkeys/password';
|
||||
import { ripple } from '../components/ripple';
|
||||
import RichTextProcessor from '../lib/richtextprocessor';
|
||||
import I18n from '../lib/langPack';
|
||||
import LoginPage from './loginPage';
|
||||
import { replaceContent } from '../helpers/dom';
|
||||
|
||||
const TEST = false;
|
||||
let passwordInput: HTMLInputElement;
|
||||
|
||||
let onFirstMount = (): Promise<any> => {
|
||||
const btnNext = Button('btn-primary btn-color-primary', {text: 'NEXT'});
|
||||
const page = new LoginPage({
|
||||
className: 'page-password',
|
||||
withInputWrapper: true,
|
||||
titleLangKey: 'Login.Password.Title',
|
||||
subtitleLangKey: 'Login.Password.Subtitle'
|
||||
});
|
||||
|
||||
const btnNext = Button('btn-primary btn-color-primary');
|
||||
const btnNextI18n = new I18n.IntlElement({key: 'Login.Next'});
|
||||
|
||||
btnNext.append(btnNextI18n.element);
|
||||
|
||||
const passwordInputField = new PasswordInputField({
|
||||
label: 'Password',
|
||||
label: 'LoginPassword',
|
||||
name: 'password'
|
||||
});
|
||||
|
||||
passwordInput = passwordInputField.input as HTMLInputElement;
|
||||
|
||||
page.pageEl.querySelector('.input-wrapper').append(passwordInputField.container, btnNext);
|
||||
page.inputWrapper.append(passwordInputField.container, btnNext);
|
||||
|
||||
let getStateInterval: number;
|
||||
|
||||
@ -37,24 +49,14 @@ let onFirstMount = (): Promise<any> => {
|
||||
return !TEST && passwordManager.getState().then(_state => {
|
||||
state = _state;
|
||||
|
||||
passwordInputField.label.innerHTML = state.hint ? RichTextProcessor.wrapEmojiText(state.hint) : 'Password';
|
||||
if(state.hint) {
|
||||
replaceContent(passwordInputField.label, RichTextProcessor.wrapEmojiText(state.hint));
|
||||
} else {
|
||||
passwordInputField.setLabel();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let handleError = (err: any) => {
|
||||
btnNext.removeAttribute('disabled');
|
||||
passwordInputField.input.classList.add('error');
|
||||
|
||||
switch(err.type) {
|
||||
default:
|
||||
//btnNext.innerText = err.type;
|
||||
btnNext.innerText = 'INVALID PASSWORD';
|
||||
break;
|
||||
}
|
||||
|
||||
getState();
|
||||
};
|
||||
|
||||
let state: AccountPassword;
|
||||
|
||||
btnNext.addEventListener('click', function(this, e) {
|
||||
@ -66,8 +68,8 @@ let onFirstMount = (): Promise<any> => {
|
||||
this.setAttribute('disabled', 'true');
|
||||
let value = passwordInput.value;
|
||||
|
||||
this.textContent = 'PLEASE WAIT...';
|
||||
putPreloader(this);
|
||||
btnNextI18n.update({key: 'PleaseWait'});
|
||||
const preloader = putPreloader(this);
|
||||
|
||||
passwordManager.check(value, state).then((response) => {
|
||||
//console.log('passwordManager response:', response);
|
||||
@ -80,17 +82,30 @@ let onFirstMount = (): Promise<any> => {
|
||||
break;
|
||||
default:
|
||||
btnNext.removeAttribute('disabled');
|
||||
btnNext.innerText = response._;
|
||||
ripple(btnNext);
|
||||
btnNextI18n.update({key: response._ as any});
|
||||
preloader.remove();
|
||||
break;
|
||||
}
|
||||
}).catch(handleError);
|
||||
}).catch((err: any) => {
|
||||
btnNext.removeAttribute('disabled');
|
||||
passwordInputField.input.classList.add('error');
|
||||
|
||||
switch(err.type) {
|
||||
default:
|
||||
//btnNext.innerText = err.type;
|
||||
btnNextI18n.update({key: 'PASSWORD_HASH_INVALID'});
|
||||
break;
|
||||
}
|
||||
|
||||
preloader.remove();
|
||||
|
||||
getState();
|
||||
});
|
||||
});
|
||||
|
||||
passwordInput.addEventListener('keypress', function(this, e) {
|
||||
this.classList.remove('error');
|
||||
btnNext.innerText = 'NEXT';
|
||||
ripple(btnNext);
|
||||
btnNextI18n.update({key: 'Login.Next'});
|
||||
|
||||
if(e.key === 'Enter') {
|
||||
return btnNext.click();
|
||||
@ -99,7 +114,7 @@ let onFirstMount = (): Promise<any> => {
|
||||
|
||||
const size = mediaSizes.isMobile ? 100 : 166;
|
||||
const monkey = new PasswordMonkey(passwordInputField, size);
|
||||
page.pageEl.querySelector('.auth-image').append(monkey.container);
|
||||
page.imageDiv.append(monkey.container);
|
||||
return Promise.all([
|
||||
monkey.load(),
|
||||
getState()
|
||||
|
@ -4,7 +4,7 @@ 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, attachClickEvent, cancelEvent, replaceContent } from "../helpers/dom";
|
||||
import { attachClickEvent, cancelEvent, replaceContent } from "../helpers/dom";
|
||||
import Page from "./page";
|
||||
import pageAuthCode from "./pageAuthCode";
|
||||
import InputField from "../components/inputField";
|
||||
@ -15,9 +15,11 @@ import fastSmoothScroll from "../helpers/fastSmoothScroll";
|
||||
import { isTouchSupported } from "../helpers/touchSupport";
|
||||
import App from "../config/app";
|
||||
import Modes from "../config/modes";
|
||||
import I18n, { _i18n, i18n } from "../lib/langPack";
|
||||
import I18n, { _i18n, i18n, LangPackKey } from "../lib/langPack";
|
||||
import { LangPackString } from "../layer";
|
||||
import lottieLoader from "../lib/lottieLoader";
|
||||
import { ripple } from "../components/ripple";
|
||||
import findUpTag from "../helpers/dom/findUpTag";
|
||||
|
||||
type Country = _Country & {
|
||||
li?: HTMLLIElement[]
|
||||
@ -370,7 +372,9 @@ let onFirstMount = () => {
|
||||
|
||||
setTimeout(() => {
|
||||
btnQr.removeAttribute('disabled');
|
||||
preloaderDiv.remove();
|
||||
if(preloaderDiv) {
|
||||
preloaderDiv.remove();
|
||||
}
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
@ -442,20 +446,20 @@ let onFirstMount = () => {
|
||||
]).then(res => {
|
||||
const backup: LangPackString[] = [];
|
||||
res[0].forEach(string => {
|
||||
const backupString = I18n.strings.get(string.key);
|
||||
const backupString = I18n.strings.get(string.key as LangPackKey);
|
||||
if(!backupString) {
|
||||
return;
|
||||
}
|
||||
|
||||
backup.push(backupString);
|
||||
I18n.strings.set(string.key, string);
|
||||
I18n.strings.set(string.key as LangPackKey, string);
|
||||
});
|
||||
|
||||
const btnChangeLanguage = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.ContinueOnLanguage'});
|
||||
inputWrapper.append(btnChangeLanguage);
|
||||
|
||||
backup.forEach(string => {
|
||||
I18n.strings.set(string.key, string);
|
||||
I18n.strings.set(string.key as LangPackKey, string);
|
||||
});
|
||||
|
||||
attachClickEvent(btnChangeLanguage, (e) => {
|
||||
@ -478,6 +482,7 @@ let onFirstMount = () => {
|
||||
const page = new Page('page-sign', true, onFirstMount, () => {
|
||||
if(btnNext) {
|
||||
replaceContent(btnNext, i18n('Login.Next'));
|
||||
ripple(btnNext, undefined, undefined, true);
|
||||
btnNext.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import { bytesCmp, bytesToBase64 } from '../helpers/bytes';
|
||||
import { pause } from '../helpers/schedulers';
|
||||
import App from '../config/app';
|
||||
import Button from '../components/button';
|
||||
import { _i18n, i18n } from '../lib/langPack';
|
||||
import { _i18n, i18n, LangPackKey } from '../lib/langPack';
|
||||
|
||||
let onFirstMount = async() => {
|
||||
const pageElement = page.pageEl;
|
||||
@ -29,7 +29,7 @@ let onFirstMount = async() => {
|
||||
|
||||
const helpList = document.createElement('ol');
|
||||
helpList.classList.add('qr-description');
|
||||
['Login.QR.Help1', 'Login.QR.Help2', 'Login.QR.Help3'].forEach((key) => {
|
||||
(['Login.QR.Help1', 'Login.QR.Help2', 'Login.QR.Help3'] as LangPackKey[]).forEach((key) => {
|
||||
const li = document.createElement('li');
|
||||
li.append(i18n(key));
|
||||
helpList.append(li);
|
||||
|
@ -1,40 +1,62 @@
|
||||
import type { CancellablePromise } from '../helpers/cancellablePromise';
|
||||
import type { InputFile } from '../layer';
|
||||
import type { AuthState } from '../types';
|
||||
import Button from '../components/button';
|
||||
import InputField from '../components/inputField';
|
||||
import { putPreloader } from '../components/misc';
|
||||
import PopupAvatar from '../components/popups/avatar';
|
||||
import { replaceContent } from '../helpers/dom';
|
||||
import appStateManager from '../lib/appManagers/appStateManager';
|
||||
import I18n, { i18n } from '../lib/langPack';
|
||||
//import apiManager from '../lib/mtproto/apiManager';
|
||||
import apiManager from '../lib/mtproto/mtprotoworker';
|
||||
import RichTextProcessor from '../lib/richtextprocessor';
|
||||
import { AuthState } from '../types';
|
||||
import LoginPage from './loginPage';
|
||||
import Page from './page';
|
||||
import pageIm from './pageIm';
|
||||
|
||||
let authCode: AuthState.signUp['authCode'] = null;
|
||||
|
||||
const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(imported => {
|
||||
const pageElement = page.pageEl;
|
||||
const avatarPreview = pageElement.querySelector('#canvas-avatar') as HTMLCanvasElement;
|
||||
const page = new LoginPage({
|
||||
className: 'page-signUp',
|
||||
withInputWrapper: true,
|
||||
titleLangKey: 'YourName',
|
||||
subtitleLangKey: 'Login.Register.Subtitle'
|
||||
});
|
||||
|
||||
page.imageDiv.classList.add('avatar-edit');
|
||||
|
||||
page.title.classList.add('fullName');
|
||||
|
||||
const avatarPreview = document.createElement('canvas');
|
||||
avatarPreview.id = 'canvas-avatar';
|
||||
avatarPreview.className = 'avatar-edit-canvas';
|
||||
|
||||
const addIco = document.createElement('span');
|
||||
addIco.className = 'tgico tgico-cameraadd';
|
||||
|
||||
page.imageDiv.append(avatarPreview, addIco);
|
||||
|
||||
const appProfileManager = imported.default;
|
||||
|
||||
let uploadAvatar: () => Promise<any>;
|
||||
pageElement.querySelector('.auth-image').addEventListener('click', () => {
|
||||
let uploadAvatar: () => CancellablePromise<InputFile>;
|
||||
page.imageDiv.addEventListener('click', () => {
|
||||
new PopupAvatar().open(avatarPreview, (_uploadAvatar) => {
|
||||
uploadAvatar = _uploadAvatar;
|
||||
});
|
||||
});
|
||||
|
||||
const headerName = pageElement.getElementsByClassName('fullName')[0] as HTMLHeadingElement;
|
||||
|
||||
const handleInput = (e: Event) => {
|
||||
const name = nameInputField.value || '';
|
||||
const lastName = lastNameInputField.value || '';
|
||||
|
||||
const fullName = name || lastName
|
||||
? (name + ' ' + lastName).trim()
|
||||
: 'Your Name';
|
||||
: '';
|
||||
|
||||
if(headerName.innerHTML !== fullName) headerName.innerHTML = RichTextProcessor.wrapEmojiText(fullName);
|
||||
if(fullName) replaceContent(page.title, RichTextProcessor.wrapEmojiText(fullName));
|
||||
else replaceContent(page.title, i18n('YourName'));
|
||||
};
|
||||
|
||||
let sendAvatar = () => new Promise<void>((resolve, reject) => {
|
||||
@ -44,32 +66,28 @@ const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(i
|
||||
}
|
||||
|
||||
//console.log('invoking uploadFile...');
|
||||
uploadAvatar().then((inputFile: any) => {
|
||||
uploadAvatar().then((inputFile) => {
|
||||
//console.log('uploaded smthn', inputFile);
|
||||
|
||||
appProfileManager.uploadProfilePhoto(inputFile).then(resolve, reject);
|
||||
}, reject);
|
||||
});
|
||||
|
||||
const inputWrapper = document.createElement('div');
|
||||
inputWrapper.classList.add('input-wrapper');
|
||||
|
||||
const nameInputField = new InputField({
|
||||
label: 'Name',
|
||||
label: 'FirstName',
|
||||
maxLength: 70
|
||||
});
|
||||
|
||||
const lastNameInputField = new InputField({
|
||||
label: 'Last Name (optional)',
|
||||
label: 'LastName',
|
||||
maxLength: 64
|
||||
});
|
||||
|
||||
const btnSignUp = Button('btn-primary btn-color-primary');
|
||||
btnSignUp.append('START MESSAGING');
|
||||
const btnI18n = new I18n.IntlElement({key: 'StartMessaging'});
|
||||
btnSignUp.append(btnI18n.element);
|
||||
|
||||
inputWrapper.append(nameInputField.container, lastNameInputField.container, btnSignUp);
|
||||
|
||||
headerName.parentElement.append(inputWrapper);
|
||||
page.inputWrapper.append(nameInputField.container, lastNameInputField.container, btnSignUp);
|
||||
|
||||
nameInputField.input.addEventListener('input', handleInput);
|
||||
lastNameInputField.input.addEventListener('input', handleInput);
|
||||
@ -84,7 +102,7 @@ const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(i
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setAttribute('disabled', 'true');
|
||||
this.disabled = true;
|
||||
|
||||
const name = nameInputField.value.trim();
|
||||
const lastName = lastNameInputField.value.trim();
|
||||
@ -98,8 +116,8 @@ const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(i
|
||||
|
||||
//console.log('invoking auth.signUp with params:', params);
|
||||
|
||||
this.textContent = 'PLEASE WAIT...';
|
||||
putPreloader(this);
|
||||
btnI18n.update({key: 'PleaseWait'});
|
||||
const preloader = putPreloader(this);
|
||||
|
||||
apiManager.invokeApi('auth.signUp', params)
|
||||
.then((response) => {
|
||||
@ -115,7 +133,9 @@ const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(i
|
||||
|
||||
break;
|
||||
default:
|
||||
this.innerText = response._;
|
||||
btnI18n.update({key: response._ as any});
|
||||
this.removeAttribute('disabled');
|
||||
preloader.remove();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -123,10 +143,11 @@ const onFirstMount = () => import('../lib/appManagers/appProfileManager').then(i
|
||||
pageAuthCode(Object.assign(code, {phoneNumber})); */
|
||||
}).catch(err => {
|
||||
this.removeAttribute('disabled');
|
||||
preloader.remove();
|
||||
|
||||
switch(err.type) {
|
||||
default:
|
||||
this.innerText = err.type;
|
||||
btnI18n.update({key: err.type});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -208,4 +208,10 @@
|
||||
{"name": "users", "type": "Array<number>"}
|
||||
],
|
||||
"type": "MessageAction"
|
||||
}, {
|
||||
"predicate": "langPackDifference",
|
||||
"params": [
|
||||
{"name": "local", "type": "boolean"},
|
||||
{"name": "appVersion", "type": "string"}
|
||||
]
|
||||
}]
|
@ -102,7 +102,7 @@ $bubble-margin: .25rem;
|
||||
margin-left: -50%;
|
||||
margin-right: -50%;
|
||||
text-align: center;
|
||||
color: var(--primary-text-color);
|
||||
color: var(--primary-color);
|
||||
line-height: 2.1;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
|
Loading…
Reference in New Issue
Block a user