Browse Source

Language improvements

master
Eduard Kuzmenko 3 years ago
parent
commit
fc8861027b
  1. 9
      src/components/appMediaViewer.ts
  2. 9
      src/components/appMediaViewerNew.ts
  3. 6
      src/components/appSearchSuper..ts
  4. 4
      src/components/appSelectPeers.ts
  5. 4
      src/components/chat/bubbles.ts
  6. 4
      src/components/chat/chat.ts
  7. 3
      src/components/chat/contextMenu.ts
  8. 3
      src/components/chat/input.ts
  9. 2
      src/components/chat/markupTooltip.ts
  10. 2
      src/components/chat/replyContainer.ts
  11. 3
      src/components/chat/search.ts
  12. 3
      src/components/chat/selection.ts
  13. 4
      src/components/chat/stickersHelper.ts
  14. 3
      src/components/chat/topbar.ts
  15. 6
      src/components/codeInputField.ts
  16. 2
      src/components/dialogsContextMenu.ts
  17. 4
      src/components/emoticonsDropdown/index.ts
  18. 3
      src/components/emoticonsDropdown/tabs/stickers.ts
  19. 4
      src/components/gifsMasonry.ts
  20. 3
      src/components/horizontalMenu.ts
  21. 48
      src/components/misc.ts
  22. 8
      src/components/passwordInputField.ts
  23. 5
      src/components/poll.ts
  24. 4
      src/components/popups/createPoll.ts
  25. 9
      src/components/popups/index.ts
  26. 2
      src/components/popups/peer.ts
  27. 4
      src/components/popups/schedule.ts
  28. 3
      src/components/popups/stickers.ts
  29. 2
      src/components/popups/unpinMessage.ts
  30. 2
      src/components/ripple.ts
  31. 3
      src/components/sidebarLeft/index.ts
  32. 2
      src/components/sidebarLeft/tabs/2fa/email.ts
  33. 2
      src/components/sidebarLeft/tabs/2fa/index.ts
  34. 3
      src/components/sidebarLeft/tabs/activeSessions.ts
  35. 5
      src/components/sidebarLeft/tabs/background.ts
  36. 3
      src/components/sidebarLeft/tabs/blockedUsers.ts
  37. 4
      src/components/sidebarRight/tabs/editGroup.ts
  38. 3
      src/components/sidebarRight/tabs/gifs.ts
  39. 7
      src/components/sidebarRight/tabs/groupPermissions.ts
  40. 2
      src/components/sidebarRight/tabs/groupType.ts
  41. 4
      src/components/sidebarRight/tabs/sharedMedia.ts
  42. 3
      src/components/sidebarRight/tabs/stickers.ts
  43. 2
      src/components/wrappers.ts
  44. 2
      src/config/app.ts
  45. 2
      src/helpers/averageColor.ts
  46. 70
      src/helpers/dom.ts
  47. 12
      src/helpers/dom/findUpAsChild.ts
  48. 11
      src/helpers/dom/findUpAttribute.ts
  49. 12
      src/helpers/dom/findUpClassName.ts
  50. 11
      src/helpers/dom/findUpTag.ts
  51. 19
      src/helpers/dom/fixSafariStickyInput.ts
  52. 47
      src/helpers/dom/renderImageFromUrl.ts
  53. 20
      src/index.hbs
  54. 9
      src/lang.ts
  55. 18
      src/langSign.ts
  56. 4
      src/layer.d.ts
  57. 3
      src/lib/appManagers/appDialogsManager.ts
  58. 6
      src/lib/appManagers/appMessagesManager.ts
  59. 2
      src/lib/appManagers/appPhotosManager.ts
  60. 4
      src/lib/appManagers/appUsersManager.ts
  61. 10
      src/lib/langPack.ts
  62. 48
      src/pages/loginPage.ts
  63. 2
      src/pages/page.ts
  64. 18
      src/pages/pageAuthCode.ts
  65. 9
      src/pages/pageIm.ts
  66. 69
      src/pages/pagePassword.ts
  67. 17
      src/pages/pageSignIn.ts
  68. 4
      src/pages/pageSignQR.ts
  69. 69
      src/pages/pageSignUp.ts
  70. 6
      src/scripts/in/schema_additional_params.json
  71. 2
      src/scss/partials/_chatBubble.scss

9
src/components/appMediaViewer.ts

@ -11,7 +11,7 @@ import { logger } from "../lib/logger"; @@ -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"; @@ -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"; @@ -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 @@ -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 @@ -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',

9
src/components/appMediaViewerNew.ts

@ -11,7 +11,7 @@ import { logger } from "../lib/logger"; @@ -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"; @@ -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."; @@ -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 @@ -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 @@ -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',

6
src/components/appSearchSuper..ts

@ -1,5 +1,5 @@ @@ -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"; @@ -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;

4
src/components/appSelectPeers.ts

@ -5,13 +5,15 @@ import appPeersManager from "../lib/appManagers/appPeersManager"; @@ -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';

4
src/components/chat/bubbles.ts

@ -8,7 +8,7 @@ import type { AppDocsManager } from "../../lib/appManagers/appDocsManager"; @@ -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"; @@ -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' */];

4
src/components/chat/chat.ts

@ -18,18 +18,18 @@ import type sessionStorage from '../../lib/sessionStorage'; @@ -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';

3
src/components/chat/contextMenu.ts

@ -4,7 +4,7 @@ import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; @@ -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"; @@ -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})[];

3
src/components/chat/input.ts

@ -14,7 +14,7 @@ import apiManager from "../../lib/mtproto/mtprotoworker"; @@ -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'; @@ -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.';

2
src/components/chat/markupTooltip.ts

@ -1,5 +1,5 @@ @@ -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";

2
src/components/chat/replyContainer.ts

@ -1,10 +1,10 @@ @@ -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: {

3
src/components/chat/search.ts

@ -1,10 +1,11 @@ @@ -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
src/components/chat/selection.ts

@ -3,7 +3,7 @@ import type ChatBubbles from "./bubbles"; @@ -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"; @@ -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

4
src/components/chat/stickersHelper.ts

@ -1,6 +1,6 @@ @@ -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";

3
src/components/chat/topbar.ts

@ -4,7 +4,7 @@ import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManage @@ -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"; @@ -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;

6
src/components/codeInputField.ts

@ -1,9 +1,7 @@ @@ -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
src/components/dialogsContextMenu.ts

@ -2,11 +2,11 @@ import appDialogsManager from "../lib/appManagers/appDialogsManager"; @@ -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;

4
src/components/emoticonsDropdown/index.ts

@ -2,7 +2,7 @@ import { isTouchSupported } from "../../helpers/touchSupport"; @@ -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"; @@ -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';

3
src/components/emoticonsDropdown/tabs/stickers.ts

@ -1,5 +1,6 @@ @@ -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"; @@ -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";

4
src/components/gifsMasonry.ts

@ -1,11 +1,11 @@ @@ -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;
@ -209,4 +209,4 @@ export default class GifsMasonry { @@ -209,4 +209,4 @@ export default class GifsMasonry {
(gotThumb?.thumb?.url ? renderImageFromUrl(img, gotThumb.thumb.url, afterRender) : afterRender());
}
}
}

3
src/components/horizontalMenu.ts

@ -1,9 +1,10 @@ @@ -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);

48
src/components/misc.ts

@ -7,54 +7,6 @@ import { isTouchSupported } from "../helpers/touchSupport"; @@ -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">

8
src/components/passwordInputField.ts

@ -1,16 +1,12 @@ @@ -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
src/components/poll.ts

@ -5,13 +5,14 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM @@ -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 { @@ -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;

4
src/components/popups/createPoll.ts

@ -1,15 +1,15 @@ @@ -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;

9
src/components/popups/index.ts

@ -1,9 +1,10 @@ @@ -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 = { @@ -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 { @@ -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);
}

2
src/components/popups/peer.ts

@ -3,7 +3,7 @@ import PopupElement, { addCancelButton, PopupButton, PopupOptions } from "."; @@ -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<{

4
src/components/popups/schedule.ts

@ -13,7 +13,7 @@ export default class PopupSchedule extends PopupDatePicker { @@ -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();
@ -30,4 +30,4 @@ export default class PopupSchedule extends PopupDatePicker { @@ -30,4 +30,4 @@ export default class PopupSchedule extends PopupDatePicker {
this.title.replaceWith(this.monthTitle);
this.body.append(this.btnConfirm);
}
}
}

3
src/components/popups/stickers.ts

@ -6,12 +6,13 @@ import { wrapSticker } from "../wrappers"; @@ -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';

2
src/components/popups/unpinMessage.ts

@ -9,7 +9,7 @@ import PeerTitle from "../peerTitle"; @@ -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);

2
src/components/ripple.ts

@ -1,5 +1,5 @@ @@ -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;

3
src/components/sidebarLeft/index.ts

@ -5,7 +5,6 @@ import appPeersManager from "../../lib/appManagers/appPeersManager"; @@ -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"; @@ -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';

2
src/components/sidebarLeft/tabs/2fa/email.ts

@ -26,7 +26,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab { @@ -26,7 +26,7 @@ export default class AppTwoStepVerificationEmailTab extends SliderSuperTab {
this.setTitle('RecoveryEmailTitle');
const section = new SettingSection({
caption: '',
caption: true,
noDelimiter: true
});

2
src/components/sidebarLeft/tabs/2fa/index.ts

@ -21,7 +21,7 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab { @@ -21,7 +21,7 @@ export default class AppTwoStepVerificationTab extends SliderSuperTab {
this.setTitle('TwoStepVerificationTitle');
const section = new SettingSection({
caption: ' ',
caption: true,
noDelimiter: true
});

3
src/components/sidebarLeft/tabs/activeSessions.ts

@ -5,13 +5,14 @@ import Row from "../../row"; @@ -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;

5
src/components/sidebarLeft/tabs/background.ts

@ -2,8 +2,9 @@ import { generateSection } from ".."; @@ -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";

3
src/components/sidebarLeft/tabs/blockedUsers.ts

@ -1,13 +1,14 @@ @@ -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[];

4
src/components/sidebarRight/tabs/editGroup.ts

@ -167,7 +167,7 @@ export default class AppEditGroupTab extends SliderSuperTab { @@ -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 { @@ -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({});

3
src/components/sidebarRight/tabs/gifs.ts

@ -5,10 +5,11 @@ import appSidebarRight from ".."; @@ -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';

7
src/components/sidebarRight/tabs/groupPermissions.ts

@ -1,11 +1,12 @@ @@ -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"; @@ -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[]}>;

2
src/components/sidebarRight/tabs/groupType.ts

@ -116,7 +116,7 @@ export default class AppGroupTypeTab extends SliderSuperTabEventable { @@ -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,

4
src/components/sidebarRight/tabs/sharedMedia.ts

@ -92,9 +92,9 @@ export default class AppSharedMediaTab extends SliderSuperTab { @@ -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');

3
src/components/sidebarRight/tabs/stickers.ts

@ -1,7 +1,7 @@ @@ -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 ".."; @@ -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;

2
src/components/wrappers.ts

@ -19,7 +19,6 @@ import AudioElement from './audio'; @@ -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.'; @@ -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
src/config/app.ts

@ -2,7 +2,7 @@ const App = { @@ -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[],

2
src/helpers/averageColor.ts

@ -1,4 +1,4 @@ @@ -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');

70
src/helpers/dom.ts

@ -338,56 +338,6 @@ export function generatePathData(x: number, y: number, width: number, height: nu @@ -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() { @@ -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

@ -0,0 +1,12 @@ @@ -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

@ -0,0 +1,11 @@ @@ -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

@ -0,0 +1,12 @@ @@ -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

@ -0,0 +1,11 @@ @@ -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

@ -0,0 +1,19 @@ @@ -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

@ -0,0 +1,47 @@ @@ -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;
}
}

20
src/index.hbs

@ -55,24 +55,8 @@ @@ -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>

9
src/lang.ts

@ -87,8 +87,8 @@ const lang = { @@ -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 = { @@ -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 = { @@ -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 = { @@ -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 = { @@ -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;

18
src/langSign.ts

@ -5,9 +5,22 @@ const 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 = { @@ -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

@ -6043,7 +6043,9 @@ export namespace LangPackDifference { @@ -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
};
}

3
src/lib/appManagers/appDialogsManager.ts

@ -11,7 +11,7 @@ import { isSafari } from "../../helpers/userAgent"; @@ -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"; @@ -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,

6
src/lib/appManagers/appMessagesManager.ts

@ -2690,7 +2690,7 @@ export class AppMessagesManager { @@ -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 { @@ -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;
}
}

2
src/lib/appManagers/appPhotosManager.ts

@ -11,8 +11,8 @@ import { MyDocument } from "./appDocsManager"; @@ -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;

4
src/lib/appManagers/appUsersManager.ts

@ -406,7 +406,7 @@ export class AppUsersManager { @@ -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 { @@ -432,8 +432,6 @@ export class AppUsersManager {
}
case 'userStatusOffline': {
key = 'last seen ';
const date = user.status.was_online;
const now = Date.now() / 1000;

10
src/lib/langPack.ts

@ -42,7 +42,7 @@ export const langPack: {[actionType: string]: LangPackKey} = { @@ -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 { @@ -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 { @@ -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 { @@ -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

@ -0,0 +1,48 @@ @@ -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);
}
}

2
src/pages/page.ts

@ -32,4 +32,4 @@ export default class Page { @@ -32,4 +32,4 @@ export default class Page {
pagesManager.setPage(this);
}
}
}

18
src/pages/pageAuthCode.ts

@ -9,6 +9,8 @@ import pageSignIn from './pageSignIn'; @@ -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> => { @@ -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 @@ -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();
}, () => {

9
src/pages/pageIm.ts

@ -2,6 +2,7 @@ @@ -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 = () => { @@ -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(() => {

69
src/pages/pagePassword.ts

@ -8,23 +8,35 @@ import pageIm from './pageIm'; @@ -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> => { @@ -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> => { @@ -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> => { @@ -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((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;
}
}).catch(handleError);
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> => { @@ -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()

17
src/pages/pageSignIn.ts

@ -4,7 +4,7 @@ import Countries, { Country as _Country } from "../countries"; @@ -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"; @@ -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 = () => { @@ -370,7 +372,9 @@ let onFirstMount = () => {
setTimeout(() => {
btnQr.removeAttribute('disabled');
preloaderDiv.remove();
if(preloaderDiv) {
preloaderDiv.remove();
}
}, 200);
});
});
@ -442,20 +446,20 @@ let onFirstMount = () => { @@ -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 = () => { @@ -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');
}

4
src/pages/pageSignQR.ts

@ -10,7 +10,7 @@ import { bytesCmp, bytesToBase64 } from '../helpers/bytes'; @@ -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() => { @@ -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);

69
src/pages/pageSignUp.ts

@ -1,40 +1,62 @@ @@ -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 @@ -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');
inputWrapper.append(nameInputField.container, lastNameInputField.container, btnSignUp);
const btnI18n = new I18n.IntlElement({key: 'StartMessaging'});
btnSignUp.append(btnI18n.element);
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 @@ -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 @@ -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 @@ -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 @@ -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;
}
});

6
src/scripts/in/schema_additional_params.json

@ -208,4 +208,10 @@ @@ -208,4 +208,10 @@
{"name": "users", "type": "Array<number>"}
],
"type": "MessageAction"
}, {
"predicate": "langPackDifference",
"params": [
{"name": "local", "type": "boolean"},
{"name": "appVersion", "type": "string"}
]
}]

2
src/scss/partials/_chatBubble.scss

@ -102,7 +102,7 @@ $bubble-margin: .25rem; @@ -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…
Cancel
Save