Media viewer refactor
Open avatar with media viewer
This commit is contained in:
parent
632e7eacf6
commit
cab8bc52cb
1327
src/components/appMediaViewer.ts
Normal file
1327
src/components/appMediaViewer.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
Normal file
11
src/components/buttonIcon.ts
Normal file
@ -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;
|
@ -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
Normal file
34
src/components/buttonMenuToggle.ts
Normal file
@ -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;
|
@ -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
Normal file
53
src/components/swipeHandler.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -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
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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) => {
|
||||||
|
if(this.currentMessageID) {
|
||||||
appSidebarRight.forwardTab.open([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) => {
|
||||||
|
if(this.currentMessageID) {
|
||||||
const mid = this.currentMessageID;
|
const mid = this.currentMessageID;
|
||||||
this.close(e).then(() => {
|
this.close(e).then(() => {
|
||||||
const message = appMessagesManager.getMessage(mid);
|
const message = appMessagesManager.getMessage(mid);
|
||||||
appImManager.setPeer(message.peerID, 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;
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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 AppMessagesIDsManager from './appManagers/appMessagesIDsManager';
|
|
||||||
import ApiUpdatesManager from './appManagers/apiUpdatesManager';
|
|
||||||
import AppPhotosManager from './appManagers/appPhotosManager';
|
|
||||||
import AppDialogsManager from './appManagers/appDialogsManager';
|
|
||||||
import AppMessagesManager from './appManagers/appMessagesManager';
|
|
||||||
import AppProfileManager from './appManagers/appProfileManager';
|
|
||||||
import AppImManager from './appManagers/appImManager';
|
|
||||||
import AppPeersManager from './appManagers/appPeersManager';
|
|
||||||
import AppStickersManager from './appManagers/appStickersManager';
|
|
||||||
import AppDocsManager from './appManagers/appDocsManager';
|
|
||||||
import AppSidebarRight from '../components/sidebarRight';
|
|
||||||
import AppSidebarLeft from '../components/sidebarLeft';
|
import AppSidebarLeft from '../components/sidebarLeft';
|
||||||
import AppMediaViewer from './appManagers/appMediaViewer';
|
import AppSidebarRight from '../components/sidebarRight';
|
||||||
|
import ApiUpdatesManager from './appManagers/apiUpdatesManager';
|
||||||
|
import AppChatsManager from './appManagers/appChatsManager';
|
||||||
|
import AppDialogsManager from './appManagers/appDialogsManager';
|
||||||
|
import AppDocsManager from './appManagers/appDocsManager';
|
||||||
|
import AppImManager from './appManagers/appImManager';
|
||||||
|
import AppMessagesIDsManager from './appManagers/appMessagesIDsManager';
|
||||||
|
import AppMessagesManager from './appManagers/appMessagesManager';
|
||||||
|
import AppPeersManager from './appManagers/appPeersManager';
|
||||||
|
import AppPhotosManager from './appManagers/appPhotosManager';
|
||||||
|
import AppProfileManager from './appManagers/appProfileManager';
|
||||||
|
import AppStickersManager from './appManagers/appStickersManager';
|
||||||
|
import AppUsersManager from './appManagers/appUsersManager';
|
||||||
//import AppSharedMediaManager from './appManagers/appSharedMediaManager';
|
//import AppSharedMediaManager from './appManagers/appSharedMediaManager';
|
||||||
|
|
||||||
const appUsersManager = AppUsersManager;
|
const appUsersManager = AppUsersManager;
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -86,4 +86,9 @@
|
|||||||
"params": [
|
"params": [
|
||||||
{"name": "deleted", "type": "boolean"}
|
{"name": "deleted", "type": "boolean"}
|
||||||
]
|
]
|
||||||
|
}, {
|
||||||
|
"predicate": "userFull",
|
||||||
|
"params": [
|
||||||
|
{"name": "rAbout", "type": "string"}
|
||||||
|
]
|
||||||
}]
|
}]
|
@ -56,4 +56,8 @@ avatar-element {
|
|||||||
&.tgico-avatar_deletedaccount {
|
&.tgico-avatar_deletedaccount {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[clickable] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
@ -247,7 +247,7 @@ $move-duration: .35s;
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
transition: $open-duration transform;
|
transition: $open-duration transform, $open-duration border-radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.moving {
|
&.moving {
|
||||||
|
Loading…
Reference in New Issue
Block a user