Browse Source

Media viewer refactor

Open avatar with media viewer
master
morethanwords 4 years ago
parent
commit
cab8bc52cb
  1. 1327
      src/components/appMediaViewer.ts
  2. 21
      src/components/avatar.ts
  3. 11
      src/components/buttonIcon.ts
  4. 2
      src/components/buttonMenu.ts
  5. 34
      src/components/buttonMenuToggle.ts
  6. 12
      src/components/sidebarRight/tabs/sharedMedia.ts
  7. 53
      src/components/swipeHandler.ts
  8. 42
      src/index.hbs
  9. 3
      src/layer.d.ts
  10. 21
      src/lib/appManagers/appChatsManager.ts
  11. 12
      src/lib/appManagers/appImManager.ts
  12. 54
      src/lib/appManagers/appMediaViewer_old.ts
  13. 8
      src/lib/appManagers/appPhotosManager.ts
  14. 20
      src/lib/services.ts
  15. 21
      src/pages/pageIm.ts
  16. 5
      src/scripts/in/schema_additional_params.json
  17. 4
      src/scss/partials/_avatar.scss
  18. 2
      src/scss/partials/_mediaViewer.scss

1327
src/components/appMediaViewer.ts

File diff suppressed because it is too large Load Diff

21
src/components/avatar.ts

@ -1,5 +1,7 @@
import appProfileManager from "../lib/appManagers/appProfileManager"; import appProfileManager from "../lib/appManagers/appProfileManager";
import $rootScope from "../lib/rootScope"; import $rootScope from "../lib/rootScope";
import { cancelEvent } from "../lib/utils";
import { AppMediaViewerAvatar } from "./appMediaViewer";
$rootScope.$on('avatar_update', (e) => { $rootScope.$on('avatar_update', (e) => {
let peerID = e.detail; let peerID = e.detail;
@ -26,12 +28,27 @@ export default class AvatarElement extends HTMLElement {
// (может вызываться много раз, если элемент многократно добавляется/удаляется) // (может вызываться много раз, если элемент многократно добавляется/удаляется)
this.isDialog = !!this.getAttribute('dialog'); this.isDialog = !!this.getAttribute('dialog');
if(this.getAttribute('clickable') === '') {
this.setAttribute('clickable', 'set');
this.addEventListener('click', (e) => {
cancelEvent(e);
//console.log('avatar clicked');
const peerID = this.peerID;
appProfileManager.getFullPhoto(this.peerID).then(photo => {
if(this.peerID != peerID) return;
if(photo) {
const good = Array.from(this.querySelectorAll('img')).find(img => !img.classList.contains('emoji'));
new AppMediaViewerAvatar().openMedia(peerID, good ? this : null);
}
});
});
}
} }
disconnectedCallback() { //disconnectedCallback() {
// браузер вызывает этот метод при удалении элемента из документа // браузер вызывает этот метод при удалении элемента из документа
// (может вызываться много раз, если элемент многократно добавляется/удаляется) // (может вызываться много раз, если элемент многократно добавляется/удаляется)
} //}
static get observedAttributes(): string[] { static get observedAttributes(): string[] {
return ['peer', 'dialog', 'peer-title'/* массив имён атрибутов для отслеживания их изменений */]; return ['peer', 'dialog', 'peer-title'/* массив имён атрибутов для отслеживания их изменений */];

11
src/components/buttonIcon.ts

@ -0,0 +1,11 @@
import { ripple } from "./ripple";
const ButtonIcon = (className: string, options: Partial<{noRipple: true, onlyMobile: true}> = {}) => {
const button = document.createElement('button');
button.className = `btn-icon tgico-${className}`;
if(!options.noRipple) ripple(button);
if(options.onlyMobile) button.classList.add('only-handhelds');
return button;
};
export default ButtonIcon;

2
src/components/buttonMenu.ts

@ -1,6 +1,6 @@
import { ripple } from "./ripple"; import { ripple } from "./ripple";
export type ButtonMenuItemOptions = {icon: string, text: string, onClick: () => void, element?: HTMLElement}; export type ButtonMenuItemOptions = {icon: string, text: string, onClick: (e: MouseEvent) => void, element?: HTMLElement};
const ButtonMenuItem = (options: ButtonMenuItemOptions) => { const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
if(options.element) return options.element; if(options.element) return options.element;

34
src/components/buttonMenuToggle.ts

@ -0,0 +1,34 @@
import ButtonIcon from "./buttonIcon";
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
import { openBtnMenu } from "./misc";
const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true}> = {}, direction: 'bottom-left', buttons: ButtonMenuItemOptions[]) => {
const button = ButtonIcon('more', options);
const btnMenu = ButtonMenu(buttons);
btnMenu.classList.add(direction);
ButtonMenuToggleHandler(button);
button.append(btnMenu);
return button;
};
const ButtonMenuToggleHandler = (el: HTMLElement) => {
(el as HTMLElement).addEventListener('click', (e) => {
//console.log('click pageIm');
if(!el.classList.contains('btn-menu-toggle')) return false;
//window.removeEventListener('mousemove', onMouseMove);
let openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
e.cancelBubble = true;
//cancelEvent(e);
if(el.classList.contains('menu-open')) {
el.classList.remove('menu-open');
openedMenu.classList.remove('active');
} else {
openBtnMenu(openedMenu);
}
});
};
export { ButtonMenuToggleHandler };
export default ButtonMenuToggle;

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

@ -1,21 +1,21 @@
import appImManager from "../../../lib/appManagers/appImManager"; import appImManager from "../../../lib/appManagers/appImManager";
import appMediaViewer from "../../../lib/appManagers/appMediaViewer";
import appMessagesManager from "../../../lib/appManagers/appMessagesManager"; import appMessagesManager from "../../../lib/appManagers/appMessagesManager";
import appPeersManager from "../../../lib/appManagers/appPeersManager"; import appPeersManager from "../../../lib/appManagers/appPeersManager";
import appPhotosManager from "../../../lib/appManagers/appPhotosManager"; import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
import appProfileManager from "../../../lib/appManagers/appProfileManager"; import appProfileManager from "../../../lib/appManagers/appProfileManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager"; import appUsersManager from "../../../lib/appManagers/appUsersManager";
import { logger, LogLevels } from "../../../lib/logger"; import { logger } from "../../../lib/logger";
import { RichTextProcessor } from "../../../lib/richtextprocessor"; import { RichTextProcessor } from "../../../lib/richtextprocessor";
import $rootScope from "../../../lib/rootScope"; import $rootScope from "../../../lib/rootScope";
import { getAbbreviation, limitSymbols } from "../../../lib/utils"; import { getAbbreviation, limitSymbols } from "../../../lib/utils";
import AppMediaViewer from "../../appMediaViewer";
import AvatarElement from "../../avatar"; import AvatarElement from "../../avatar";
import { horizontalMenu } from "../../horizontalMenu"; import { horizontalMenu } from "../../horizontalMenu";
import LazyLoadQueue from "../../lazyLoadQueue"; import LazyLoadQueue from "../../lazyLoadQueue";
import { renderImageFromUrl, putPreloader } from "../../misc"; import { putPreloader, renderImageFromUrl } from "../../misc";
import Scrollable from "../../scrollable"; import Scrollable from "../../scrollable";
import { SliderTab } from "../../slider"; import { SliderTab } from "../../slider";
import { wrapDocument, wrapAudio } from "../../wrappers"; import { wrapAudio, wrapDocument } from "../../wrappers";
const testScroll = false; const testScroll = false;
@ -197,7 +197,7 @@ export default class AppSharedMediaTab implements SliderTab {
return {element, mid: id}; return {element, mid: id};
}); });
appMediaViewer.openMedia(message, target, false, this.container, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), true); new AppMediaViewer().openMedia(message, target, false, targets.slice(idx + 1).reverse(), targets.slice(0, idx).reverse(), true);
}); });
this.profileElements.notificationsCheckbox.addEventListener('change', () => { this.profileElements.notificationsCheckbox.addEventListener('change', () => {
@ -819,7 +819,7 @@ export default class AppSharedMediaTab implements SliderTab {
//membersLi.style.display = appPeersManager.isBroadcast(peerID) ? 'none' : ''; //membersLi.style.display = appPeersManager.isBroadcast(peerID) ? 'none' : '';
let chat = appPeersManager.getPeer(peerID); let chat = appPeersManager.getPeer(peerID);
appProfileManager.getChatFull(chat.id).then((chatFull: any) => { appProfileManager.getChatFull(chat.id).then((chatFull) => {
if(this.peerID != peerID) { if(this.peerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;

53
src/components/swipeHandler.ts

@ -0,0 +1,53 @@
export default class SwipeHandler {
private xDown: number;
private yDown: number;
constructor(element: HTMLElement, private onSwipe: (xDiff: number, yDiff: number) => boolean) {
element.addEventListener('touchstart', this.handleTouchStart, false);
element.addEventListener('touchmove', this.handleTouchMove, false);
}
handleTouchStart = (evt: TouchEvent) => {
// * Fix for seek input
if((evt.target as HTMLElement).tagName == 'INPUT') {
this.xDown = this.yDown = null;
return;
}
const firstTouch = evt.touches[0];
this.xDown = firstTouch.clientX;
this.yDown = firstTouch.clientY;
};
handleTouchMove = (evt: TouchEvent) => {
if(this.xDown == null || this.yDown == null) {
return;
}
const xUp = evt.touches[0].clientX;
const yUp = evt.touches[0].clientY;
const xDiff = this.xDown - xUp;
const yDiff = this.yDown - yUp;
// if(Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
// if(xDiff > 0) { /* left swipe */
// } else { /* right swipe */
// }
// } else {
// if(yDiff > 0) { /* up swipe */
// } else { /* down swipe */
// }
// }
/* reset values */
if(this.onSwipe(xDiff, yDiff)) {
this.xDown = null;
this.yDown = null;
}
};
}

42
src/index.hbs

@ -139,42 +139,6 @@
<path id="poll-line" d="M4.47,5.33v13.6c0,4.97,4.03,9,9,9h458.16"/> <path id="poll-line" d="M4.47,5.33v13.6c0,4.97,4.03,9,9,9h458.16"/>
</defs> </defs>
</svg> </svg>
<div class="media-viewer-whole">
<div class="overlays">
<div class="media-viewer">
<div class="media-viewer-author">
<avatar-element class="media-viewer-userpic"></avatar-element>
<div class="media-viewer-name"></div>
<div class="media-viewer-date"></div>
</div>
<div class="media-viewer-buttons">
<div class="btn-icon tgico-delete menu-delete rp"></div>
<div class="btn-icon tgico-forward menu-forward rp"></div>
<div class="btn-icon tgico-download menu-download rp"></div>
<div class="btn-icon tgico-close menu-close rp"></div>
</div>
<div class="media-viewer-content">
<div class="media-viewer-stub"></div>
<div class="media-viewer-container">
<div class="media-viewer-media"></div>
</div>
<div class="media-viewer-caption"></div>
</div>
</div>
</div>
<div class="btn-icon tgico-close only-handhelds menu-mobile-close rp"></div>
<div class="btn-icon tgico-more rp btn-menu-toggle only-handhelds">
<div class="btn-menu bottom-left">
<div class="btn-menu-item menu-menu-forward tgico-forward rp">Forward</div>
<div class="btn-menu-item menu-menu-download tgico-download rp">Download</div>
<div class="btn-menu-item menu-menu-delete danger tgico-delete rp btn-disabled">Delete</div>
</div>
</div>
{{!-- <div class="media-viewer-switchers"> --}}
<div class="media-viewer-switcher media-viewer-switcher-left menu-prev"><span class="tgico-down media-viewer-prev-button"></span></div>
<div class="media-viewer-switcher media-viewer-switcher-right menu-next"><span class="tgico-down media-viewer-next-button"></span></div>
{{!-- </div> --}}
</div>
<div id="main-columns" class="tabs-container"> <div id="main-columns" class="tabs-container">
<div class="chats-container sidebar sidebar-left main-column" id="column-left"> <div class="chats-container sidebar sidebar-left main-column" id="column-left">
<div class="sidebar-slider tabs-container"> <div class="sidebar-slider tabs-container">
@ -305,7 +269,7 @@
</div> </div>
<div class="sidebar-content"> <div class="sidebar-content">
<div class="profile-content-wrapper scrollable scrollable-y"> <div class="profile-content-wrapper scrollable scrollable-y">
<avatar-element class="profile-avatar"></avatar-element> <avatar-element class="profile-avatar" clickable></avatar-element>
<div class="profile-name"></div> <div class="profile-name"></div>
<div class="profile-subtitle"></div> <div class="profile-subtitle"></div>
<div class="profile-buttons"> <div class="profile-buttons">
@ -451,7 +415,7 @@
<button class="btn-icon tgico-back sidebar-close-button"></button> <button class="btn-icon tgico-back sidebar-close-button"></button>
<div class="chat-info"> <div class="chat-info">
<div class="person"> <div class="person">
<avatar-element id="im-avatar" dialog="1"></avatar-element> <avatar-element id="im-avatar" dialog="1" clickable></avatar-element>
<div class="content"> <div class="content">
<div class="top"> <div class="top">
<div class="user-title" id="im-title"></div> <div class="user-title" id="im-title"></div>
@ -573,7 +537,7 @@
</div> </div>
<div class="profile-content"> <div class="profile-content">
<div class="profile-content-wrapper"> <div class="profile-content-wrapper">
<avatar-element class="profile-avatar" dialog="1"></avatar-element> <avatar-element class="profile-avatar" dialog="1" clickable></avatar-element>
<div class="profile-name"></div> <div class="profile-name"></div>
<div class="profile-subtitle"></div> <div class="profile-subtitle"></div>

3
src/layer.d.ts vendored

@ -1441,7 +1441,8 @@ export namespace UserFull {
bot_info?: BotInfo, bot_info?: BotInfo,
pinned_msg_id?: number, pinned_msg_id?: number,
common_chats_count: number, common_chats_count: number,
folder_id?: number folder_id?: number,
rAbout?: string
}; };
} }

21
src/lib/appManagers/appChatsManager.ts

@ -1,4 +1,4 @@
import { ChatAdminRights, ChatBannedRights, InputChannel, InputChatPhoto, InputPeer, Updates } from "../../layer"; import { ChatAdminRights, ChatBannedRights, ChatFull, ChatParticipants, InputChannel, InputChatPhoto, InputPeer, Updates } from "../../layer";
import apiManager from '../mtproto/mtprotoworker'; import apiManager from '../mtproto/mtprotoworker';
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import $rootScope from "../rootScope"; import $rootScope from "../rootScope";
@ -442,17 +442,17 @@ export class AppChatsManager {
public async getOnlines(id: number): Promise<number> { public async getOnlines(id: number): Promise<number> {
if(this.isMegagroup(id)) { if(this.isMegagroup(id)) {
let timestamp = Date.now() / 1000 | 0; const timestamp = Date.now() / 1000 | 0;
let cached = this.megagroupOnlines[id] ?? (this.megagroupOnlines[id] = {timestamp: 0, onlines: 1}); const cached = this.megagroupOnlines[id] ?? (this.megagroupOnlines[id] = {timestamp: 0, onlines: 1});
if((timestamp - cached.timestamp) < 60) { if((timestamp - cached.timestamp) < 60) {
return cached.onlines; return cached.onlines;
} }
let res = await apiManager.invokeApi('messages.getOnlines', { const res = await apiManager.invokeApi('messages.getOnlines', {
peer: this.getChannelInputPeer(id) peer: this.getChannelInputPeer(id)
}); });
let onlines = res.onlines ?? 1; const onlines = res.onlines ?? 1;
cached.timestamp = timestamp; cached.timestamp = timestamp;
cached.onlines = onlines; cached.onlines = onlines;
@ -461,12 +461,13 @@ export class AppChatsManager {
return 1; return 1;
} }
let chatInfo = appProfileManager.getChatFull(id); const chatInfo = await appProfileManager.getChatFull(id);
if(chatInfo._ == 'chatFull' && chatInfo.participants && chatInfo.participants.participants) { const _participants = (chatInfo as ChatFull.chatFull).participants as ChatParticipants.chatParticipants;
let participants = chatInfo.participants.participants; if(_participants && _participants.participants) {
const participants = _participants.participants;
return participants.reduce((acc: number, participant: any) => { return participants.reduce((acc: number, participant) => {
let user = appUsersManager.getUser(participant.user_id); const user = appUsersManager.getUser(participant.user_id);
if(user && user.status && user.status._ == 'userStatusOnline') { if(user && user.status && user.status._ == 'userStatusOnline') {
return acc + 1; return acc + 1;
} }

12
src/lib/appManagers/appImManager.ts

@ -1,5 +1,6 @@
//import apiManager from '../mtproto/apiManager'; //import apiManager from '../mtproto/apiManager';
import animationIntersector from '../../components/animationIntersector'; import animationIntersector from '../../components/animationIntersector';
import AppMediaViewer from "../../components/appMediaViewer";
import AudioElement from '../../components/audio'; import AudioElement from '../../components/audio';
import AvatarElement from '../../components/avatar'; import AvatarElement from '../../components/avatar';
import BubbleGroups from '../../components/bubbleGroups'; import BubbleGroups from '../../components/bubbleGroups';
@ -38,7 +39,6 @@ import appChatsManager, { Channel, Chat } from "./appChatsManager";
import appDialogsManager from "./appDialogsManager"; import appDialogsManager from "./appDialogsManager";
import appDocsManager from './appDocsManager'; import appDocsManager from './appDocsManager';
import appInlineBotsManager from './AppInlineBotsManager'; import appInlineBotsManager from './AppInlineBotsManager';
import appMediaViewer from "./appMediaViewer";
import appMessagesManager, { Dialog } from "./appMessagesManager"; import appMessagesManager, { Dialog } from "./appMessagesManager";
import appPeersManager from "./appPeersManager"; import appPeersManager from "./appPeersManager";
import appPhotosManager from "./appPhotosManager"; import appPhotosManager from "./appPhotosManager";
@ -502,8 +502,8 @@ export class AppImManager {
return; return;
} }
appMediaViewer.openMedia(message, targets[idx].element, true, new AppMediaViewer().openMedia(message, targets[idx].element, true,
this.scroll.parentElement, targets.slice(0, idx), targets.slice(idx + 1)/* , !message.grouped_id */); targets.slice(0, idx), targets.slice(idx + 1)/* , !message.grouped_id */);
//appMediaViewer.openMedia(message, target as HTMLImageElement); //appMediaViewer.openMedia(message, target as HTMLImageElement);
return; return;
@ -620,9 +620,9 @@ export class AppImManager {
//this.log('onkeydown', e); //this.log('onkeydown', e);
if(e.key == 'Escape') { if(e.key == 'Escape') {
if(appMediaViewer.wholeDiv.classList.contains('active')) { /* if(AppMediaViewer.wholeDiv.classList.contains('active')) {
appMediaViewer.buttons.close.click(); AppMediaViewer.buttons.close.click();
} else if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) { } else */ if(appSidebarRight.historyTabIDs.slice(-1)[0] == AppSidebarRight.SLIDERITEMSIDS.forward) {
appSidebarRight.forwardTab.closeBtn.click(); appSidebarRight.forwardTab.closeBtn.click();
} else if(this.chatInputC.replyElements.container.classList.contains('active')) { } else if(this.chatInputC.replyElements.container.classList.contains('active')) {
this.chatInputC.replyElements.cancelBtn.click(); this.chatInputC.replyElements.cancelBtn.click();

54
src/lib/appManagers/appMediaViewer.ts → src/lib/appManagers/appMediaViewer_old.ts

@ -95,6 +95,7 @@ export class AppMediaViewer {
}; };
public currentMessageID = 0; public currentMessageID = 0;
private tempID = 0;
private preloader: ProgressivePreloader = null; private preloader: ProgressivePreloader = null;
private preloaderStreamable: ProgressivePreloader = null; private preloaderStreamable: ProgressivePreloader = null;
@ -172,7 +173,9 @@ export class AppMediaViewer {
}); });
const forward = (e: MouseEvent) => { const forward = (e: MouseEvent) => {
appSidebarRight.forwardTab.open([this.currentMessageID]); if(this.currentMessageID) {
appSidebarRight.forwardTab.open([this.currentMessageID]);
}
}; };
[this.buttons.forward, this.buttons["menu-forward"]].forEach(el => { [this.buttons.forward, this.buttons["menu-forward"]].forEach(el => {
@ -254,11 +257,13 @@ export class AppMediaViewer {
}; };
onAuthorClick = (e: MouseEvent) => { onAuthorClick = (e: MouseEvent) => {
const mid = this.currentMessageID; if(this.currentMessageID) {
this.close(e).then(() => { const mid = this.currentMessageID;
const message = appMessagesManager.getMessage(mid); this.close(e).then(() => {
appImManager.setPeer(message.peerID, mid); const message = appMessagesManager.getMessage(mid);
}); appImManager.setPeer(message.peerID, mid);
});
}
}; };
onClickDownload = (e: MouseEvent) => { onClickDownload = (e: MouseEvent) => {
@ -861,11 +866,27 @@ export class AppMediaViewer {
} */ } */
} }
public async openMedia(message: any, target?: HTMLElement, reverse = false, targetContainer?: HTMLElement, public async openMedia(messageOrPeerID: any, target?: HTMLElement, reverse = false,
prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], needLoadMore = true) { prevTargets: AppMediaViewer['prevTargets'] = [], nextTargets: AppMediaViewer['prevTargets'] = [], needLoadMore = true) {
if(this.setMoverPromise) return this.setMoverPromise; if(this.setMoverPromise) return this.setMoverPromise;
this.log('openMedia doc:', message);
const media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo; this.log('openMedia:', messageOrPeerID);
let media: any;
let fromID: number;
let caption: string, totalEntities: any[];
let message: any;
const isAvatar = typeof(messageOrPeerID) === 'number';
if(isAvatar) {
media = appPeersManager.getPeerPhoto(messageOrPeerID);
fromID = messageOrPeerID;
} else {
message = messageOrPeerID;
media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
fromID = message.fromID;
caption = message.message;
totalEntities = message.totalEntities;
}
const isVideo = (media as MyDocument).type == 'video' || (media as MyDocument).type == 'gif'; const isVideo = (media as MyDocument).type == 'video' || (media as MyDocument).type == 'gif';
const isFirstOpen = !this.peerID; const isFirstOpen = !this.peerID;
@ -908,6 +929,7 @@ export class AppMediaViewer {
this.currentMessageID = message.mid; this.currentMessageID = message.mid;
this.lastTarget = target; this.lastTarget = target;
const tempID = ++this.tempID;
if(this.needLoadMore) { if(this.needLoadMore) {
if(this.nextTargets.length < 20) { if(this.nextTargets.length < 20) {
@ -929,12 +951,12 @@ export class AppMediaViewer {
const dateStr = months[date.getMonth()] + ' ' + date.getDate() + ' at '+ date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2); const dateStr = months[date.getMonth()] + ' ' + date.getDate() + ' at '+ date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
this.author.date.innerText = dateStr; this.author.date.innerText = dateStr;
const name = appPeersManager.getPeerTitle(message.fromID); const name = appPeersManager.getPeerTitle(fromID);
this.author.nameEl.innerHTML = name; this.author.nameEl.innerHTML = name;
if(message.message) { if(caption) {
this.content.caption.innerHTML = RichTextProcessor.wrapRichText(message.message, { this.content.caption.innerHTML = RichTextProcessor.wrapRichText(caption, {
entities: message.totalEntities entities: totalEntities
}); });
} else { } else {
this.content.caption.innerHTML = ''; this.content.caption.innerHTML = '';
@ -942,7 +964,7 @@ export class AppMediaViewer {
let oldAvatar = this.author.avatarEl; let oldAvatar = this.author.avatarEl;
this.author.avatarEl = (this.author.avatarEl.cloneNode() as AvatarElement); this.author.avatarEl = (this.author.avatarEl.cloneNode() as AvatarElement);
this.author.avatarEl.setAttribute('peer', '' + message.fromID); this.author.avatarEl.setAttribute('peer', '' + fromID);
oldAvatar.parentElement.replaceChild(this.author.avatarEl, oldAvatar); oldAvatar.parentElement.replaceChild(this.author.avatarEl, oldAvatar);
// ok set // ok set
@ -1079,7 +1101,7 @@ export class AppMediaViewer {
} }
(promise as Promise<any>).then(async() => { (promise as Promise<any>).then(async() => {
if(this.currentMessageID != message.mid) { if(this.tempID != tempID) {
this.log.warn('media viewer changed video'); this.log.warn('media viewer changed video');
return; return;
} }
@ -1116,7 +1138,7 @@ export class AppMediaViewer {
this.preloader.attach(mover, true, cancellablePromise); this.preloader.attach(mover, true, cancellablePromise);
}); });
cancellablePromise.then(() => { cancellablePromise.then(() => {
if(this.currentMessageID != message.mid) { if(this.tempID != tempID) {
this.log.warn('media viewer changed photo'); this.log.warn('media viewer changed photo');
return; return;
} }

8
src/lib/appManagers/appPhotosManager.ts

@ -2,6 +2,7 @@ import { CancellablePromise } from "../../helpers/cancellablePromise";
import { isSafari } from "../../helpers/userAgent"; import { isSafari } from "../../helpers/userAgent";
import { FileLocation, InputFileLocation, Photo, PhotoSize } from "../../layer"; import { FileLocation, InputFileLocation, Photo, PhotoSize } from "../../layer";
import { bytesFromHex, getFileNameByLocation } from "../bin_utils"; import { bytesFromHex, getFileNameByLocation } from "../bin_utils";
import { DownloadOptions } from "../mtproto/apiFileManager";
import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase"; import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase";
import { calcImageInBox, isObject, safeReplaceArrayInObject } from "../utils"; import { calcImageInBox, isObject, safeReplaceArrayInObject } from "../utils";
import { MyDocument } from "./appDocsManager"; import { MyDocument } from "./appDocsManager";
@ -245,7 +246,7 @@ export class AppPhotosManager {
return {url: getFileURL('photo', downloadOptions), location: downloadOptions.location}; return {url: getFileURL('photo', downloadOptions), location: downloadOptions.location};
} */ } */
public preloadPhoto(photoID: any, photoSize?: PhotoSize): CancellablePromise<Blob> { public preloadPhoto(photoID: any, photoSize?: PhotoSize, downloadOptions?: DownloadOptions): CancellablePromise<Blob> {
const photo = this.getPhoto(photoID); const photo = this.getPhoto(photoID);
// @ts-ignore // @ts-ignore
@ -265,7 +266,10 @@ export class AppPhotosManager {
return Promise.resolve() as any; return Promise.resolve() as any;
} }
const downloadOptions = this.getPhotoDownloadOptions(photo, photoSize); if(!downloadOptions) {
downloadOptions = this.getPhotoDownloadOptions(photo, photoSize);
}
const fileName = getFileNameByLocation(downloadOptions.location); const fileName = getFileNameByLocation(downloadOptions.location);
let download = appDownloadManager.getDownload(fileName); let download = appDownloadManager.getDownload(fileName);

20
src/lib/services.ts

@ -1,20 +1,20 @@
console.log('Services included!'); console.log('Services included!');
import AppUsersManager from './appManagers/appUsersManager'; import AppMediaViewer from '../components/appMediaViewer';
import AppChatsManager from './appManagers/appChatsManager'; import AppSidebarLeft from '../components/sidebarLeft';
import AppMessagesIDsManager from './appManagers/appMessagesIDsManager'; import AppSidebarRight from '../components/sidebarRight';
import ApiUpdatesManager from './appManagers/apiUpdatesManager'; import ApiUpdatesManager from './appManagers/apiUpdatesManager';
import AppPhotosManager from './appManagers/appPhotosManager'; import AppChatsManager from './appManagers/appChatsManager';
import AppDialogsManager from './appManagers/appDialogsManager'; import AppDialogsManager from './appManagers/appDialogsManager';
import AppMessagesManager from './appManagers/appMessagesManager'; import AppDocsManager from './appManagers/appDocsManager';
import AppProfileManager from './appManagers/appProfileManager';
import AppImManager from './appManagers/appImManager'; import AppImManager from './appManagers/appImManager';
import AppMessagesIDsManager from './appManagers/appMessagesIDsManager';
import AppMessagesManager from './appManagers/appMessagesManager';
import AppPeersManager from './appManagers/appPeersManager'; import AppPeersManager from './appManagers/appPeersManager';
import AppPhotosManager from './appManagers/appPhotosManager';
import AppProfileManager from './appManagers/appProfileManager';
import AppStickersManager from './appManagers/appStickersManager'; import AppStickersManager from './appManagers/appStickersManager';
import AppDocsManager from './appManagers/appDocsManager'; import AppUsersManager from './appManagers/appUsersManager';
import AppSidebarRight from '../components/sidebarRight';
import AppSidebarLeft from '../components/sidebarLeft';
import AppMediaViewer from './appManagers/appMediaViewer';
//import AppSharedMediaManager from './appManagers/appSharedMediaManager'; //import AppSharedMediaManager from './appManagers/appSharedMediaManager';
const appUsersManager = AppUsersManager; const appUsersManager = AppUsersManager;

21
src/pages/pageIm.ts

@ -1,6 +1,6 @@
//import {stackBlurImage} from '../lib/StackBlur'; //import {stackBlurImage} from '../lib/StackBlur';
import Page from "./page";
import { DEBUG } from "../lib/mtproto/mtproto_config"; import { DEBUG } from "../lib/mtproto/mtproto_config";
import Page from "./page";
let onFirstMount = () => { let onFirstMount = () => {
//return; //return;
@ -26,24 +26,9 @@ let onFirstMount = () => {
//(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el)); //(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el));
const misc = await import("../components/misc"); const misc = await import("../components/buttonMenuToggle");
Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => { Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => {
(el as HTMLElement).addEventListener('click', (e) => { misc.ButtonMenuToggleHandler(el as HTMLElement);
//console.log('click pageIm');
if(!el.classList.contains('btn-menu-toggle')) return false;
//window.removeEventListener('mousemove', onMouseMove);
let openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
e.cancelBubble = true;
//cancelEvent(e);
if(el.classList.contains('menu-open')) {
el.classList.remove('menu-open');
openedMenu.classList.remove('active');
} else {
misc.openBtnMenu(openedMenu);
}
});
}); });
}) })

5
src/scripts/in/schema_additional_params.json

@ -86,4 +86,9 @@
"params": [ "params": [
{"name": "deleted", "type": "boolean"} {"name": "deleted", "type": "boolean"}
] ]
}, {
"predicate": "userFull",
"params": [
{"name": "rAbout", "type": "string"}
]
}] }]

4
src/scss/partials/_avatar.scss

@ -56,4 +56,8 @@ avatar-element {
&.tgico-avatar_deletedaccount { &.tgico-avatar_deletedaccount {
font-size: 3rem; font-size: 3rem;
} }
&[clickable] {
cursor: pointer;
}
} }

2
src/scss/partials/_mediaViewer.scss

@ -247,7 +247,7 @@ $move-duration: .35s;
} }
&.active { &.active {
transition: $open-duration transform; transition: $open-duration transform, $open-duration border-radius;
} }
&.moving { &.moving {

Loading…
Cancel
Save