Fix context menu again
Multiselect fixes for desktop & mobile Safari Fix multiselect album on mobiles
This commit is contained in:
parent
50915cf493
commit
984b04ab40
@ -1173,7 +1173,7 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
|||||||
this.openMedia(appMessagesManager.getMessage(target.mid), target.element);
|
this.openMedia(appMessagesManager.getMessage(target.mid), target.element);
|
||||||
};
|
};
|
||||||
|
|
||||||
onForwardClick = (e: MouseEvent) => {
|
onForwardClick = () => {
|
||||||
if(this.currentMessageID) {
|
if(this.currentMessageID) {
|
||||||
//appSidebarRight.forwardTab.open([this.currentMessageID]);
|
//appSidebarRight.forwardTab.open([this.currentMessageID]);
|
||||||
new PopupForward([this.currentMessageID], () => {
|
new PopupForward([this.currentMessageID], () => {
|
||||||
@ -1198,7 +1198,7 @@ export default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delet
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onDownloadClick = (e: MouseEvent) => {
|
onDownloadClick = () => {
|
||||||
const message = appMessagesManager.getMessage(this.currentMessageID);
|
const message = appMessagesManager.getMessage(this.currentMessageID);
|
||||||
if(message.media.photo) {
|
if(message.media.photo) {
|
||||||
appPhotosManager.savePhotoFile(message.media.photo);
|
appPhotosManager.savePhotoFile(message.media.photo);
|
||||||
@ -1370,7 +1370,7 @@ export class AppMediaViewerAvatar extends AppMediaViewerBase<'', 'delete', AppMe
|
|||||||
this.openMedia(target.photoID, target.element, 1);
|
this.openMedia(target.photoID, target.element, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
onDownloadClick = (e: MouseEvent) => {
|
onDownloadClick = () => {
|
||||||
appPhotosManager.savePhotoFile(appPhotosManager.getPhoto(this.currentPhotoID));
|
appPhotosManager.savePhotoFile(appPhotosManager.getPhoto(this.currentPhotoID));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import { isSafari } from "../helpers/userAgent";
|
|||||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||||
import rootScope from "../lib/rootScope";
|
import rootScope from "../lib/rootScope";
|
||||||
import './middleEllipsis';
|
import './middleEllipsis';
|
||||||
|
import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
|
||||||
|
|
||||||
rootScope.on('messages_media_read', e => {
|
rootScope.on('messages_media_read', e => {
|
||||||
const mids = e.detail;
|
const mids = e.detail;
|
||||||
@ -213,12 +214,14 @@ function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement, mid: number) {
|
|||||||
mousedown = false;
|
mousedown = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
progress.addEventListener('click', (e) => {
|
progress.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
if(!audio.paused) scrub(e);
|
if(!audio.paused) scrub(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
function scrub(e: MouseEvent) {
|
function scrub(e: MouseEvent | TouchEvent) {
|
||||||
const scrubTime = e.offsetX / availW /* width */ * audio.duration;
|
const offsetX = e instanceof MouseEvent ? e.offsetX : e.changedTouches[0].clientX;
|
||||||
|
const scrubTime = offsetX / availW /* width */ * audio.duration;
|
||||||
lastIndex = Math.round(scrubTime / audio.duration * barCount);
|
lastIndex = Math.round(scrubTime / audio.duration * barCount);
|
||||||
|
|
||||||
rects.slice(0, lastIndex + 1).forEach(node => node.classList.add('active'));
|
rects.slice(0, lastIndex + 1).forEach(node => node.classList.add('active'));
|
||||||
@ -366,7 +369,8 @@ export default class AudioElement extends HTMLElement {
|
|||||||
audioTimeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true) + ' / ' + durationStr;
|
audioTimeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true) + ' / ' + durationStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle.addEventListener('click', () => {
|
toggle.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
if(audio.paused) audio.play().catch(() => {});
|
if(audio.paused) audio.play().catch(() => {});
|
||||||
else audio.pause();
|
else audio.pause();
|
||||||
});
|
});
|
||||||
@ -395,7 +399,8 @@ export default class AudioElement extends HTMLElement {
|
|||||||
if(doc.type == 'voice') {
|
if(doc.type == 'voice') {
|
||||||
let download: Download;
|
let download: Download;
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = (e: Event) => {
|
||||||
|
cancelEvent(e);
|
||||||
if(!download) {
|
if(!download) {
|
||||||
if(!preloader) {
|
if(!preloader) {
|
||||||
preloader = new ProgressivePreloader(null, true);
|
preloader = new ProgressivePreloader(null, true);
|
||||||
@ -406,7 +411,7 @@ export default class AudioElement extends HTMLElement {
|
|||||||
|
|
||||||
download.then(() => {
|
download.then(() => {
|
||||||
downloadDiv.remove();
|
downloadDiv.remove();
|
||||||
this.removeEventListener('click', onClick);
|
this.removeEventListener(CLICK_EVENT_NAME, onClick);
|
||||||
onLoad();
|
onLoad();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
if(err.name === 'AbortError') {
|
if(err.name === 'AbortError') {
|
||||||
@ -422,7 +427,7 @@ export default class AudioElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addEventListener('click', onClick);
|
this.addEventListener(CLICK_EVENT_NAME, onClick);
|
||||||
this.click();
|
this.click();
|
||||||
} else {
|
} else {
|
||||||
onLoad(false);
|
onLoad(false);
|
||||||
@ -430,8 +435,9 @@ export default class AudioElement extends HTMLElement {
|
|||||||
//if(appMediaPlaybackController.mediaExists(mid)) { // чтобы показать прогресс, если аудио уже было скачано
|
//if(appMediaPlaybackController.mediaExists(mid)) { // чтобы показать прогресс, если аудио уже было скачано
|
||||||
//onLoad();
|
//onLoad();
|
||||||
//} else {
|
//} else {
|
||||||
const r = () => {
|
const r = (e: Event) => {
|
||||||
//onLoad();
|
//onLoad();
|
||||||
|
cancelEvent(e);
|
||||||
appMediaPlaybackController.resolveWaitingForLoadMedia(mid);
|
appMediaPlaybackController.resolveWaitingForLoadMedia(mid);
|
||||||
|
|
||||||
appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio
|
appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio
|
||||||
@ -464,7 +470,7 @@ export default class AudioElement extends HTMLElement {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addEventListener('click', r, {once: true});
|
this.addEventListener(CLICK_EVENT_NAME, r, {once: true});
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { CLICK_EVENT_NAME } from "../helpers/dom";
|
||||||
import { ripple } from "./ripple";
|
import { ripple } from "./ripple";
|
||||||
|
|
||||||
export type ButtonMenuItemOptions = {icon: string, text: string, onClick: (e: MouseEvent) => void, element?: HTMLElement};
|
export type ButtonMenuItemOptions = {icon: string, text: string, onClick: (e: MouseEvent | TouchEvent) => void, element?: HTMLElement};
|
||||||
|
|
||||||
const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
|
const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
|
||||||
if(options.element) return options.element;
|
if(options.element) return options.element;
|
||||||
@ -11,7 +12,7 @@ const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
|
|||||||
el.innerText = text;
|
el.innerText = text;
|
||||||
|
|
||||||
ripple(el);
|
ripple(el);
|
||||||
el.addEventListener('click', onClick);
|
el.addEventListener(CLICK_EVENT_NAME, onClick);
|
||||||
|
|
||||||
return options.element = el;
|
return options.element = el;
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
|
||||||
import ButtonIcon from "./buttonIcon";
|
import ButtonIcon from "./buttonIcon";
|
||||||
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
|
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
|
||||||
import { closeBtnMenu, openBtnMenu } from "./misc";
|
import { closeBtnMenu, openBtnMenu } from "./misc";
|
||||||
@ -12,14 +13,13 @@ const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true}> =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ButtonMenuToggleHandler = (el: HTMLElement) => {
|
const ButtonMenuToggleHandler = (el: HTMLElement) => {
|
||||||
(el as HTMLElement).addEventListener('click', (e) => {
|
(el as HTMLElement).addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
//console.log('click pageIm');
|
//console.log('click pageIm');
|
||||||
if(!el.classList.contains('btn-menu-toggle')) return false;
|
if(!el.classList.contains('btn-menu-toggle')) return false;
|
||||||
|
|
||||||
//window.removeEventListener('mousemove', onMouseMove);
|
//window.removeEventListener('mousemove', onMouseMove);
|
||||||
const openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
|
const openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;
|
||||||
e.cancelBubble = true;
|
cancelEvent(e);
|
||||||
//cancelEvent(e);
|
|
||||||
|
|
||||||
if(el.classList.contains('menu-open')) {
|
if(el.classList.contains('menu-open')) {
|
||||||
closeBtnMenu();
|
closeBtnMenu();
|
||||||
|
@ -87,33 +87,60 @@ export default class ChatContextMenu {
|
|||||||
|
|
||||||
const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
|
const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
|
||||||
//bubble.parentElement.append(this.element);
|
//bubble.parentElement.append(this.element);
|
||||||
|
//appImManager.log('contextmenu', e, bubble, side);
|
||||||
positionMenu(e, this.element, side);
|
positionMenu(e, this.element, side);
|
||||||
openBtnMenu(this.element, () => {
|
openBtnMenu(this.element, () => {
|
||||||
this.peerID = this.msgID = 0;
|
this.peerID = this.msgID = 0;
|
||||||
this.target = null;
|
this.target = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
/////this.log('contextmenu', e, bubble, msgID, side);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(isTouchSupported) {
|
if(isTouchSupported) {
|
||||||
attachTo.addEventListener('click', (e) => {
|
const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent) => void) => {
|
||||||
//const good = !!findUpClassName(e.target, 'message') || !!findUpClassName(e.target, 'bubble__container');
|
elem.addEventListener('touchstart', (e) => {
|
||||||
|
const onTouchMove = (e: TouchEvent) => {
|
||||||
|
elem.removeEventListener('touchend', onTouchEnd);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onTouchEnd = (e: TouchEvent) => {
|
||||||
|
elem.removeEventListener('touchmove', onTouchMove);
|
||||||
|
callback(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
elem.addEventListener('touchend', onTouchEnd, {once: true});
|
||||||
|
elem.addEventListener('touchmove', onTouchMove, {once: true});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
attachClickEvent(attachTo, (e) => {
|
||||||
|
if(appImManager.chatSelection.isSelecting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const className = (e.target as HTMLElement).className;
|
const className = (e.target as HTMLElement).className;
|
||||||
if(!className || !className.includes) return;
|
if(!className || !className.includes) return;
|
||||||
|
|
||||||
|
appImManager.log('touchend', e);
|
||||||
|
|
||||||
const good = ['bubble', 'bubble__container', 'message', 'time', 'inner'].find(c => className.match(new RegExp(c + '($|\\s)')));
|
const good = ['bubble', 'bubble__container', 'message', 'time', 'inner'].find(c => className.match(new RegExp(c + '($|\\s)')));
|
||||||
if(good) {
|
if(good) {
|
||||||
onContextMenu(e);
|
cancelEvent(e);
|
||||||
|
onContextMenu(e.changedTouches[0]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
attachContextMenuListener(attachTo, (e) => {
|
attachContextMenuListener(attachTo, (e) => {
|
||||||
if(appImManager.chatSelection.isSelecting) return;
|
if(appImManager.chatSelection.isSelecting) return;
|
||||||
|
|
||||||
|
// * these two lines will fix instant text selection on iOS Safari
|
||||||
|
attachTo.classList.add('no-select');
|
||||||
|
attachTo.addEventListener('touchend', () => {
|
||||||
|
attachTo.classList.remove('no-select');
|
||||||
|
}, {once: true});
|
||||||
|
|
||||||
cancelSelection();
|
cancelSelection();
|
||||||
cancelEvent(e as any);
|
//cancelEvent(e as any);
|
||||||
let bubble = findUpClassName(e.target, 'bubble');
|
const bubble = findUpClassName(e.target, 'album-item') || findUpClassName(e.target, 'bubble');
|
||||||
if(bubble) {
|
if(bubble) {
|
||||||
appImManager.chatSelection.toggleByBubble(bubble);
|
appImManager.chatSelection.toggleByBubble(bubble);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { isTouchSupported } from "../../helpers/touchSupport";
|
import { isTouchSupported } from "../../helpers/touchSupport";
|
||||||
import type { AppImManager } from "../../lib/appManagers/appImManager";
|
import type { AppImManager } from "../../lib/appManagers/appImManager";
|
||||||
import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManager";
|
import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManager";
|
||||||
import { cancelEvent, cancelSelection, findUpClassName, getSelectedText } from "../../helpers/dom";
|
import { blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getSelectedText } from "../../helpers/dom";
|
||||||
import Button from "../button";
|
import Button from "../button";
|
||||||
import ButtonIcon from "../buttonIcon";
|
import ButtonIcon from "../buttonIcon";
|
||||||
import CheckboxField from "../checkbox";
|
import CheckboxField from "../checkbox";
|
||||||
@ -225,6 +225,8 @@ export default class ChatSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blurActiveElement(); // * for mobile keyboards
|
||||||
|
|
||||||
SetTransition(bubblesContainer, 'is-selecting', !!this.selectedMids.size, 200, () => {
|
SetTransition(bubblesContainer, 'is-selecting', !!this.selectedMids.size, 200, () => {
|
||||||
if(!this.isSelecting) {
|
if(!this.isSelecting) {
|
||||||
this.selectionContainer.remove();
|
this.selectionContainer.remove();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Countries, { Country, PhoneCodesMain } from "../countries";
|
import Countries, { Country, PhoneCodesMain } from "../countries";
|
||||||
import { cancelEvent } from "../helpers/dom";
|
import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom";
|
||||||
import mediaSizes from "../helpers/mediaSizes";
|
import mediaSizes from "../helpers/mediaSizes";
|
||||||
import { clamp } from "../helpers/number";
|
import { clamp } from "../helpers/number";
|
||||||
import { isTouchSupported } from "../helpers/touchSupport";
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
@ -148,7 +148,7 @@ export const closeBtnMenu = () => {
|
|||||||
window.removeEventListener('contextmenu', onClick);
|
window.removeEventListener('contextmenu', onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.removeEventListener('click', onClick);
|
document.removeEventListener(CLICK_EVENT_NAME, onClick);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
@ -186,18 +186,21 @@ export function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ! safari iOS doesn't handle window click event on overlay, idk why
|
// ! safari iOS doesn't handle window click event on overlay, idk why
|
||||||
document.addEventListener('click', onClick);
|
document.addEventListener(CLICK_EVENT_NAME, onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PADDING_TOP = 8;
|
const PADDING_TOP = 8;
|
||||||
const PADDING_LEFT = 8;
|
const PADDING_LEFT = 8;
|
||||||
export function positionMenu({clientX, clientY}: {clientX: number, clientY: number}/* e: MouseEvent */, elem: HTMLElement, side?: 'left' | 'right' | 'center') {
|
export function positionMenu({pageX, pageY}: MouseEvent | Touch, elem: HTMLElement, side?: 'left' | 'right' | 'center') {
|
||||||
//let {clientX, clientY} = e;
|
//let {clientX, clientY} = e;
|
||||||
|
|
||||||
// * side mean the OPEN side
|
// * side mean the OPEN side
|
||||||
|
|
||||||
let {scrollWidth: menuWidth, scrollHeight: menuHeight} = elem;
|
let {scrollWidth: menuWidth, scrollHeight: menuHeight} = elem;
|
||||||
let {innerWidth: windowWidth, innerHeight: windowHeight} = window;
|
//let {innerWidth: windowWidth, innerHeight: windowHeight} = window;
|
||||||
|
const rect = document.body.getBoundingClientRect();
|
||||||
|
const windowWidth = rect.width;
|
||||||
|
const windowHeight = rect.height;
|
||||||
|
|
||||||
side = mediaSizes.isMobile ? 'right' : 'left';
|
side = mediaSizes.isMobile ? 'right' : 'left';
|
||||||
let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';
|
let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';
|
||||||
@ -205,17 +208,17 @@ export function positionMenu({clientX, clientY}: {clientX: number, clientY: numb
|
|||||||
const getSides = () => {
|
const getSides = () => {
|
||||||
return {
|
return {
|
||||||
x: {
|
x: {
|
||||||
left: clientX,
|
left: pageX,
|
||||||
right: clientX - menuWidth
|
right: pageX - menuWidth
|
||||||
},
|
},
|
||||||
intermediateX: side == 'right' ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,
|
intermediateX: side == 'right' ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,
|
||||||
//intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,
|
//intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,
|
||||||
y: {
|
y: {
|
||||||
top: clientY,
|
top: pageY,
|
||||||
bottom: clientY - menuHeight
|
bottom: pageY - menuHeight
|
||||||
},
|
},
|
||||||
//intermediateY: verticalSide == 'top' ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,
|
//intermediateY: verticalSide == 'top' ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,
|
||||||
intermediateY: clientY < windowHeight / 2 ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,
|
intermediateY: pageY < windowHeight / 2 ? PADDING_TOP : windowHeight - menuHeight - PADDING_TOP,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,11 +293,13 @@ export function attachContextMenuListener(element: HTMLElement, callback: (e: To
|
|||||||
if(isApple && isTouchSupported) {
|
if(isApple && isTouchSupported) {
|
||||||
let timeout: number;
|
let timeout: number;
|
||||||
|
|
||||||
|
const options: any = /* null */{capture: true};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
element.removeEventListener('touchmove', onCancel);
|
element.removeEventListener('touchmove', onCancel, options);
|
||||||
element.removeEventListener('touchend', onCancel);
|
element.removeEventListener('touchend', onCancel, options);
|
||||||
element.removeEventListener('touchcancel', onCancel);
|
element.removeEventListener('touchcancel', onCancel, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
element.addEventListener('touchstart', (e) => {
|
element.addEventListener('touchstart', (e) => {
|
||||||
@ -303,11 +308,12 @@ export function attachContextMenuListener(element: HTMLElement, callback: (e: To
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
element.addEventListener('touchmove', onCancel);
|
element.addEventListener('touchmove', onCancel, options);
|
||||||
element.addEventListener('touchend', onCancel);
|
element.addEventListener('touchend', onCancel, options);
|
||||||
element.addEventListener('touchcancel', onCancel);
|
element.addEventListener('touchcancel', onCancel, options);
|
||||||
|
|
||||||
timeout = window.setTimeout(() => {
|
timeout = window.setTimeout(() => {
|
||||||
|
element.addEventListener('touchend', cancelEvent, {once: true}); // * fix instant closing
|
||||||
callback(e.touches[0]);
|
callback(e.touches[0]);
|
||||||
onCancel();
|
onCancel();
|
||||||
}, .4e3);
|
}, .4e3);
|
||||||
|
@ -5,7 +5,7 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM
|
|||||||
import serverTimeManager from "../lib/mtproto/serverTimeManager";
|
import serverTimeManager from "../lib/mtproto/serverTimeManager";
|
||||||
import { RichTextProcessor } from "../lib/richtextprocessor";
|
import { RichTextProcessor } from "../lib/richtextprocessor";
|
||||||
import rootScope from "../lib/rootScope";
|
import rootScope from "../lib/rootScope";
|
||||||
import { cancelEvent, findUpClassName } from "../helpers/dom";
|
import { cancelEvent, CLICK_EVENT_NAME, findUpClassName } from "../helpers/dom";
|
||||||
import { ripple } from "./ripple";
|
import { ripple } from "./ripple";
|
||||||
import appSidebarRight from "./sidebarRight";
|
import appSidebarRight from "./sidebarRight";
|
||||||
|
|
||||||
@ -338,7 +338,8 @@ export default class PollElement extends HTMLElement {
|
|||||||
this.votersCountDiv.classList.add('hide');
|
this.votersCountDiv.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendVoteBtn.addEventListener('click', () => {
|
this.sendVoteBtn.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
/* const indexes = this.answerDivs.filter(el => el.classList.contains('is-chosing')).map(el => +el.dataset.index);
|
/* const indexes = this.answerDivs.filter(el => el.classList.contains('is-chosing')).map(el => +el.dataset.index);
|
||||||
if(indexes.length) {
|
if(indexes.length) {
|
||||||
|
|
||||||
@ -363,7 +364,7 @@ export default class PollElement extends HTMLElement {
|
|||||||
this.performResults(results, poll.chosenIndexes);
|
this.performResults(results, poll.chosenIndexes);
|
||||||
} else if(!this.isClosed) {
|
} else if(!this.isClosed) {
|
||||||
this.setVotersCount(results);
|
this.setVotersCount(results);
|
||||||
this.addEventListener('click', this.clickHandler);
|
this.addEventListener(CLICK_EVENT_NAME, this.clickHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +406,7 @@ export default class PollElement extends HTMLElement {
|
|||||||
this.descDiv.append(toggleHint);
|
this.descDiv.append(toggleHint);
|
||||||
|
|
||||||
//let active = false;
|
//let active = false;
|
||||||
toggleHint.addEventListener('click', (e) => {
|
toggleHint.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
|
|
||||||
//active = true;
|
//active = true;
|
||||||
@ -425,12 +426,13 @@ export default class PollElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clickHandler(e: MouseEvent) {
|
clickHandler(e: Event) {
|
||||||
const target = findUpClassName(e.target, 'poll-answer') as HTMLElement;
|
const target = findUpClassName(e.target, 'poll-answer') as HTMLElement;
|
||||||
if(!target) {
|
if(!target) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelEvent(e);
|
||||||
const answerIndex = +target.dataset.index;
|
const answerIndex = +target.dataset.index;
|
||||||
if(this.isMultiple) {
|
if(this.isMultiple) {
|
||||||
target.classList.toggle('is-chosing');
|
target.classList.toggle('is-chosing');
|
||||||
@ -512,9 +514,9 @@ export default class PollElement extends HTMLElement {
|
|||||||
this.chosenIndexes = chosenIndexes.slice();
|
this.chosenIndexes = chosenIndexes.slice();
|
||||||
|
|
||||||
if(this.isRetracted) {
|
if(this.isRetracted) {
|
||||||
this.addEventListener('click', this.clickHandler);
|
this.addEventListener(CLICK_EVENT_NAME, this.clickHandler);
|
||||||
} else {
|
} else {
|
||||||
this.removeEventListener('click', this.clickHandler);
|
this.removeEventListener(CLICK_EVENT_NAME, this.clickHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import rootScope from "../lib/rootScope";
|
import rootScope from "../lib/rootScope";
|
||||||
import { cancelEvent, findUpClassName } from "../helpers/dom";
|
import { blurActiveElement, cancelEvent, findUpClassName } from "../helpers/dom";
|
||||||
import { ripple } from "./ripple";
|
import { ripple } from "./ripple";
|
||||||
|
|
||||||
export class PopupElement {
|
export class PopupElement {
|
||||||
@ -100,6 +100,7 @@ export class PopupElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public show() {
|
public show() {
|
||||||
|
blurActiveElement(); // * hide mobile keyboard
|
||||||
document.body.append(this.element);
|
document.body.append(this.element);
|
||||||
void this.element.offsetWidth; // reflow
|
void this.element.offsetWidth; // reflow
|
||||||
this.element.classList.add('active');
|
this.element.classList.add('active');
|
||||||
|
@ -8,7 +8,7 @@ import appStateManager from "../../lib/appManagers/appStateManager";
|
|||||||
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
import appUsersManager from "../../lib/appManagers/appUsersManager";
|
||||||
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
|
import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config";
|
||||||
import rootScope from "../../lib/rootScope";
|
import rootScope from "../../lib/rootScope";
|
||||||
import { findUpClassName, findUpTag } from "../../helpers/dom";
|
import { CLICK_EVENT_NAME, findUpClassName, findUpTag } from "../../helpers/dom";
|
||||||
import AppSearch, { SearchGroup } from "../appSearch";
|
import AppSearch, { SearchGroup } from "../appSearch";
|
||||||
import "../avatar";
|
import "../avatar";
|
||||||
import { parseMenuButtonsTo, putPreloader } from "../misc";
|
import { parseMenuButtonsTo, putPreloader } from "../misc";
|
||||||
@ -292,32 +292,32 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
|
|
||||||
this.archivedCount = this.buttons.archived.querySelector('.archived-count') as HTMLSpanElement;
|
this.archivedCount = this.buttons.archived.querySelector('.archived-count') as HTMLSpanElement;
|
||||||
|
|
||||||
this.buttons.saved.addEventListener('click', (e) => {
|
this.buttons.saved.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
///////this.log('savedbtn click');
|
///////this.log('savedbtn click');
|
||||||
setTimeout(() => { // menu doesn't close if no timeout (lol)
|
setTimeout(() => { // menu doesn't close if no timeout (lol)
|
||||||
appImManager.setPeer(appImManager.myID);
|
appImManager.setPeer(appImManager.myID);
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.buttons.archived.addEventListener('click', (e) => {
|
this.buttons.archived.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.archived);
|
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.archived);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.buttons.contacts.addEventListener('click', (e) => {
|
this.buttons.contacts.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.contactsTab.openContacts();
|
this.contactsTab.openContacts();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.buttons.settings.addEventListener('click', (e) => {
|
this.buttons.settings.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.settingsTab.fillElements();
|
this.settingsTab.fillElements();
|
||||||
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.settings);
|
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.newButtons.channel.addEventListener('click', (e) => {
|
this.newButtons.channel.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.newChannel);
|
this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.newChannel);
|
||||||
});
|
});
|
||||||
|
|
||||||
[this.newButtons.group, this.buttons.newGroup].forEach(btn => {
|
[this.newButtons.group, this.buttons.newGroup].forEach(btn => {
|
||||||
btn.addEventListener('click', (e) => {
|
btn.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.addMembersTab.init(0, 'chat', false, (peerIDs) => {
|
this.addMembersTab.init(0, 'chat', false, (peerIDs) => {
|
||||||
this.newGroupTab.init(peerIDs);
|
this.newGroupTab.init(peerIDs);
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,7 @@ import appMessagesManager from '../lib/appManagers/appMessagesManager';
|
|||||||
import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager';
|
import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager';
|
||||||
import LottieLoader from '../lib/lottieLoader';
|
import LottieLoader from '../lib/lottieLoader';
|
||||||
import VideoPlayer from '../lib/mediaPlayer';
|
import VideoPlayer from '../lib/mediaPlayer';
|
||||||
import { isInDOM } from "../helpers/dom";
|
import { cancelEvent, CLICK_EVENT_NAME, isInDOM } from "../helpers/dom";
|
||||||
import webpWorkerController from '../lib/webp/webpWorkerController';
|
import webpWorkerController from '../lib/webp/webpWorkerController';
|
||||||
import animationIntersector from './animationIntersector';
|
import animationIntersector from './animationIntersector';
|
||||||
import appMediaPlaybackController from './appMediaPlaybackController';
|
import appMediaPlaybackController from './appMediaPlaybackController';
|
||||||
@ -373,7 +373,8 @@ export function wrapDocument(doc: MyDocument, withTime = false, uploading = fals
|
|||||||
let preloader: ProgressivePreloader;
|
let preloader: ProgressivePreloader;
|
||||||
let download: DownloadBlob;
|
let download: DownloadBlob;
|
||||||
|
|
||||||
docDiv.addEventListener('click', (e) => {
|
docDiv.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
if(!download) {
|
if(!download) {
|
||||||
if(downloadDiv.classList.contains('downloading')) {
|
if(downloadDiv.classList.contains('downloading')) {
|
||||||
return; // means not ready yet
|
return; // means not ready yet
|
||||||
@ -670,7 +671,8 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
if(emoji) {
|
if(emoji) {
|
||||||
div.addEventListener('click', () => {
|
div.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
let animation = LottieLoader.getAnimation(div);
|
let animation = LottieLoader.getAnimation(div);
|
||||||
|
|
||||||
if(animation.paused) {
|
if(animation.paused) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { MOUNT_CLASS_TO } from "../lib/mtproto/mtproto_config";
|
import { MOUNT_CLASS_TO } from "../lib/mtproto/mtproto_config";
|
||||||
|
import { isTouchSupported } from "./touchSupport";
|
||||||
|
|
||||||
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {
|
||||||
if(!element) {
|
if(!element) {
|
||||||
@ -66,6 +67,38 @@ export function placeCaretAtEnd(el: HTMLElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* export function getFieldSelection(field: any) {
|
||||||
|
if(field.selectionStart) {
|
||||||
|
return field.selectionStart;
|
||||||
|
// @ts-ignore
|
||||||
|
} else if(!document.selection) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const c = '\x01';
|
||||||
|
// @ts-ignore
|
||||||
|
const sel = document.selection.createRange();
|
||||||
|
const txt = sel.text;
|
||||||
|
const dup = sel.duplicate();
|
||||||
|
let len = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
dup.moveToElementText(field);
|
||||||
|
} catch(e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sel.text = txt + c;
|
||||||
|
len = dup.text.indexOf(c);
|
||||||
|
sel.moveStart('character', -1);
|
||||||
|
sel.text = '';
|
||||||
|
|
||||||
|
// if (browser.msie && len == -1) {
|
||||||
|
// return field.value.length
|
||||||
|
// }
|
||||||
|
return len;
|
||||||
|
} */
|
||||||
|
|
||||||
export function getRichValue(field: HTMLElement) {
|
export function getRichValue(field: HTMLElement) {
|
||||||
if(!field) {
|
if(!field) {
|
||||||
return '';
|
return '';
|
||||||
@ -90,6 +123,15 @@ MOUNT_CLASS_TO && (MOUNT_CLASS_TO.getRichValue = getRichValue);
|
|||||||
const markdownTags = [{
|
const markdownTags = [{
|
||||||
tagName: 'STRONG',
|
tagName: 'STRONG',
|
||||||
markdown: '**'
|
markdown: '**'
|
||||||
|
}, {
|
||||||
|
tagName: 'B', // * legacy (Ctrl+B)
|
||||||
|
markdown: '**'
|
||||||
|
}, {
|
||||||
|
tagName: 'U', // * legacy (Ctrl+I)
|
||||||
|
markdown: '_-_'
|
||||||
|
}, {
|
||||||
|
tagName: 'I', // * legacy (Ctrl+I)
|
||||||
|
markdown: '__'
|
||||||
}, {
|
}, {
|
||||||
tagName: 'EM',
|
tagName: 'EM',
|
||||||
markdown: '__'
|
markdown: '__'
|
||||||
@ -126,7 +168,7 @@ export function getRichElementValue(node: HTMLElement, lines: string[], line: st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
line.push(markdown && node.nodeValue.trim() ? markdown + node.nodeValue + markdown : node.nodeValue);
|
line.push(markdown && node.nodeValue.trim() ? '\x01' + markdown + node.nodeValue + markdown + '\x01' : node.nodeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -392,3 +434,11 @@ export function getSelectedText(): string {
|
|||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function blurActiveElement() {
|
||||||
|
if(document.activeElement && (document.activeElement as HTMLInputElement).blur) {
|
||||||
|
(document.activeElement as HTMLInputElement).blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CLICK_EVENT_NAME = isTouchSupported ? 'touchend' : 'click';
|
||||||
|
@ -569,7 +569,7 @@ export class ApiUpdatesManager {
|
|||||||
} else {
|
} else {
|
||||||
// ! for testing
|
// ! for testing
|
||||||
/* state.seq = 1;
|
/* state.seq = 1;
|
||||||
state.pts = state.pts - 100;
|
state.pts = state.pts - 1000;
|
||||||
state.date = 1; */
|
state.date = 1; */
|
||||||
|
|
||||||
Object.assign(this.updatesState, state);
|
Object.assign(this.updatesState, state);
|
||||||
|
@ -202,6 +202,7 @@ export class AppDialogsManager {
|
|||||||
//private topOffsetIndex = 0;
|
//private topOffsetIndex = 0;
|
||||||
|
|
||||||
private sliceTimeout: number;
|
private sliceTimeout: number;
|
||||||
|
private reorderDialogsTimeout: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.chatsPreloader = putPreloader(null, true);
|
this.chatsPreloader = putPreloader(null, true);
|
||||||
@ -891,37 +892,40 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
private reorderDialogs() {
|
private reorderDialogs() {
|
||||||
//const perf = performance.now();
|
//const perf = performance.now();
|
||||||
|
if(this.reorderDialogsTimeout) return;
|
||||||
let offset = 0;
|
this.reorderDialogsTimeout = window.requestAnimationFrame(() => {
|
||||||
if(this.topOffsetIndex) {
|
this.reorderDialogsTimeout = 0;
|
||||||
const element = this.chatList.firstElementChild;
|
let offset = 0;
|
||||||
if(element) {
|
if(this.topOffsetIndex) {
|
||||||
const peerID = +element.getAttribute('data-peerID');
|
const element = this.chatList.firstElementChild;
|
||||||
const firstDialog = appMessagesManager.getDialogByPeerID(peerID);
|
if(element) {
|
||||||
offset = firstDialog[1];
|
const peerID = +element.getAttribute('data-peerID');
|
||||||
}
|
const firstDialog = appMessagesManager.getDialogByPeerID(peerID);
|
||||||
}
|
offset = firstDialog[1];
|
||||||
|
|
||||||
const dialogs = appMessagesManager.dialogsStorage.getFolder(this.filterID);
|
|
||||||
const currentOrder = (Array.from(this.chatList.children) as HTMLElement[]).map(el => +el.getAttribute('data-peerID'));
|
|
||||||
|
|
||||||
dialogs.forEach((dialog, index) => {
|
|
||||||
const dom = this.getDialogDom(dialog.peerID);
|
|
||||||
if(!dom) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentIndex = currentOrder[dialog.peerID];
|
|
||||||
const needIndex = index - offset;
|
|
||||||
|
|
||||||
if(currentIndex != needIndex) {
|
|
||||||
if(positionElementByIndex(dom.listEl, this.chatList, needIndex)) {
|
|
||||||
this.log.debug('setDialogPosition:', dialog, dom, needIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dialogs = appMessagesManager.dialogsStorage.getFolder(this.filterID);
|
||||||
|
const currentOrder = (Array.from(this.chatList.children) as HTMLElement[]).map(el => +el.getAttribute('data-peerID'));
|
||||||
|
|
||||||
|
dialogs.forEach((dialog, index) => {
|
||||||
|
const dom = this.getDialogDom(dialog.peerID);
|
||||||
|
if(!dom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const needIndex = index - offset;
|
||||||
|
const peerIDByIndex = currentOrder[needIndex];
|
||||||
|
|
||||||
|
if(peerIDByIndex != dialog.peerID) {
|
||||||
|
if(positionElementByIndex(dom.listEl, this.chatList, needIndex)) {
|
||||||
|
this.log.debug('setDialogPosition:', dialog, dom, peerIDByIndex, needIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//this.log('Reorder time:', performance.now() - perf);
|
||||||
});
|
});
|
||||||
|
|
||||||
//this.log('Reorder time:', performance.now() - perf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLastMessage(dialog: any, lastMessage?: any, dom?: DialogDom, highlightWord?: string) {
|
public setLastMessage(dialog: any, lastMessage?: any, dom?: DialogDom, highlightWord?: string) {
|
||||||
|
@ -40,7 +40,7 @@ import apiManager from '../mtproto/mtprotoworker';
|
|||||||
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from '../rootScope';
|
import rootScope from '../rootScope';
|
||||||
import { cancelEvent, findUpClassName, findUpTag, placeCaretAtEnd, whichChild } from "../../helpers/dom";
|
import { cancelEvent, CLICK_EVENT_NAME, findUpClassName, findUpTag, placeCaretAtEnd, whichChild } from "../../helpers/dom";
|
||||||
import apiUpdatesManager from './apiUpdatesManager';
|
import apiUpdatesManager from './apiUpdatesManager';
|
||||||
import appChatsManager, { Channel, Chat } from "./appChatsManager";
|
import appChatsManager, { Channel, Chat } from "./appChatsManager";
|
||||||
import appDialogsManager from "./appDialogsManager";
|
import appDialogsManager from "./appDialogsManager";
|
||||||
@ -708,7 +708,7 @@ export class AppImManager {
|
|||||||
this.mutePeer(this.peerID);
|
this.mutePeer(this.peerID);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.btnJoin.addEventListener('click', (e) => {
|
this.btnJoin.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
|
|
||||||
this.btnJoin.setAttribute('disabled', 'true');
|
this.btnJoin.setAttribute('disabled', 'true');
|
||||||
@ -717,11 +717,11 @@ export class AppImManager {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.menuButtons.mute.addEventListener('click', (e) => {
|
this.menuButtons.mute.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
this.mutePeer(this.peerID);
|
this.mutePeer(this.peerID);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.menuButtons.search.addEventListener('click', (e) => {
|
this.menuButtons.search.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
new ChatSearch();
|
new ChatSearch();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -745,6 +745,12 @@ export class AppImManager {
|
|||||||
this.chatInputC.replyElements.cancelBtn.click();
|
this.chatInputC.replyElements.cancelBtn.click();
|
||||||
} else if(this.peerID != 0) { // hide current dialog
|
} else if(this.peerID != 0) { // hide current dialog
|
||||||
this.setPeer(0);
|
this.setPeer(0);
|
||||||
|
cancelEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * cancel event for safari, because if application is in fullscreen, browser will try to exit fullscreen
|
||||||
|
if(this.peerID) {
|
||||||
|
cancelEvent(e);
|
||||||
}
|
}
|
||||||
} else if(e.key == 'Meta' || e.key == 'Control') {
|
} else if(e.key == 'Meta' || e.key == 'Control') {
|
||||||
return;
|
return;
|
||||||
@ -785,7 +791,8 @@ export class AppImManager {
|
|||||||
|
|
||||||
document.body.addEventListener('keydown', onKeyDown);
|
document.body.addEventListener('keydown', onKeyDown);
|
||||||
|
|
||||||
this.goDownBtn.addEventListener('click', () => {
|
this.goDownBtn.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
const dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
|
const dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0];
|
||||||
|
|
||||||
if(dialog) {
|
if(dialog) {
|
||||||
@ -1898,7 +1905,8 @@ export class AppImManager {
|
|||||||
containerDiv.append(rowDiv);
|
containerDiv.append(rowDiv);
|
||||||
});
|
});
|
||||||
|
|
||||||
containerDiv.addEventListener('click', (e) => {
|
containerDiv.addEventListener(CLICK_EVENT_NAME, (e) => {
|
||||||
|
cancelEvent(e);
|
||||||
let target = e.target as HTMLElement;
|
let target = e.target as HTMLElement;
|
||||||
|
|
||||||
if(!target.classList.contains('reply-markup-button')) target = findUpClassName(target, 'reply-markup-button');
|
if(!target.classList.contains('reply-markup-button')) target = findUpClassName(target, 'reply-markup-button');
|
||||||
@ -2790,8 +2798,13 @@ export class AppImManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setMutedState(muted = false) {
|
public setMutedState(muted = false) {
|
||||||
appSidebarRight.sharedMediaTab.profileElements.notificationsCheckbox.checked = !muted;
|
if(!this.peerID) return;
|
||||||
appSidebarRight.sharedMediaTab.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
|
||||||
|
const profileElements = appSidebarRight.sharedMediaTab.profileElements;
|
||||||
|
if(profileElements) {
|
||||||
|
appSidebarRight.sharedMediaTab.profileElements.notificationsCheckbox.checked = !muted;
|
||||||
|
appSidebarRight.sharedMediaTab.profileElements.notificationsStatus.innerText = muted ? 'Disabled' : 'Enabled';
|
||||||
|
}
|
||||||
|
|
||||||
if(appPeersManager.isBroadcast(this.peerID)) { // not human
|
if(appPeersManager.isBroadcast(this.peerID)) { // not human
|
||||||
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
|
this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');
|
||||||
|
@ -87,7 +87,7 @@ Utility Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No Text Select
|
// No Text Select
|
||||||
.no-select {
|
.no-select/* , .no-select * */ {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ avatar-element {
|
|||||||
/* overflow: hidden; */
|
/* overflow: hidden; */
|
||||||
position: relative;
|
position: relative;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -106,6 +106,10 @@
|
|||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.bottom-center {
|
||||||
|
transform-origin: top center;
|
||||||
|
}
|
||||||
|
|
||||||
&.top-left {
|
&.top-left {
|
||||||
top: initial;
|
top: initial;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -120,6 +124,14 @@
|
|||||||
transform-origin: bottom left;
|
transform-origin: bottom left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.center-left {
|
||||||
|
transform-origin: center right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center-right {
|
||||||
|
transform-origin: center left;
|
||||||
|
}
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -170,6 +182,7 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
user-select: none;
|
||||||
//background-color: rgba(0, 0, 0, .2);
|
//background-color: rgba(0, 0, 0, .2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +229,12 @@ $bubble-margin: .25rem;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#bubbles.is-selecting & {
|
||||||
|
.audio, .document, .attachment, poll-element {
|
||||||
|
pointer-events: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
//min-width: 60px;
|
//min-width: 60px;
|
||||||
@ -244,7 +250,12 @@ $bubble-margin: .25rem;
|
|||||||
height: fit-content;
|
height: fit-content;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
transition: .2s transform;
|
transition: .2s transform;
|
||||||
user-select: text;
|
user-select: none;
|
||||||
|
|
||||||
|
html.no-touch #bubbles:not(.is-selecting) &,
|
||||||
|
html.is-touch #bubbles.is-selecting:not(.no-select) & {
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
max-width: 85%;
|
max-width: 85%;
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
height: 50px;
|
min-height: 50px;
|
||||||
}
|
}
|
||||||
/* font-weight: 500; */
|
/* font-weight: 500; */
|
||||||
|
|
||||||
|
@ -214,12 +214,9 @@
|
|||||||
max-width: 78px;
|
max-width: 78px;
|
||||||
width: 78px;
|
width: 78px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
cursor: pointer;
|
|
||||||
padding: 12px 0 0 !important;
|
padding: 12px 0 0 !important;
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
@ -233,6 +230,10 @@
|
|||||||
height: 54px;
|
height: 54px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-title-details {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.user-caption {
|
.user-caption {
|
||||||
max-width: 65px;
|
max-width: 65px;
|
||||||
padding: 2px 0px 9px;
|
padding: 2px 0px 9px;
|
||||||
@ -243,10 +244,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-title {
|
|
||||||
max-width: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-group-scrollable {
|
.search-group-scrollable {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -595,10 +592,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-field input {
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-left-h2 {
|
.sidebar-left-h2 {
|
||||||
|
@ -198,6 +198,38 @@ $messages-container-width: 728px;
|
|||||||
unicode-range:U + 0000-00FF, U + 0131, U + 0152-0153, U + 02BB-02BC, U + 02C6, U + 02DA, U + 02DC, U + 2000-206F, U + 2074, U + 20AC, U + 2122, U + 2191, U + 2193, U + 2212, U + 2215, U + FEFF, U + FFFD
|
unicode-range:U + 0000-00FF, U + 0131, U + 0152-0153, U + 02BB-02BC, U + 02C6, U + 02DA, U + 02DC, U + 2000-206F, U + 2074, U + 20AC, U + 2122, U + 2191, U + 2193, U + 2212, U + 2215, U + FEFF, U + FFFD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!! FIX FOR [contenteditable] Ctrl+B, due to font-weight: 500;
|
||||||
|
|
||||||
|
/* cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: local('Roboto Medium'), local('Roboto-Medium'), url(assets/fonts/KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP.woff2) format('woff2');
|
||||||
|
unicode-range:U + 0400-045F, U + 0490-0491, U + 04B0-04B1, U + 2116
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin-ext */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: local('Roboto Medium'), local('Roboto-Medium'), url(assets/fonts/KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP.woff2) format('woff2');
|
||||||
|
unicode-range:U + 0100-024F, U + 0259, U + 1E00-1EFF, U + 2020, U + 20A0-20AB, U + 20AD-20CF, U + 2113, U + 2C60-2C7F, U + A720-A7FF
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: local('Roboto Medium'), local('Roboto-Medium'), url(assets/fonts/KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2) format('woff2');
|
||||||
|
unicode-range:U + 0000-00FF, U + 0131, U + 0152-0153, U + 02BB-02BC, U + 02C6, U + 02DA, U + 02DC, U + 2000-206F, U + 2074, U + 20AC, U + 2122, U + 2191, U + 2193, U + 2212, U + 2215, U + FEFF, U + FFFD
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -404,7 +436,8 @@ hr {
|
|||||||
|
|
||||||
.user-title, b/* , .user-last-message b */ {
|
.user-title, b/* , .user-last-message b */ {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-weight: 500;
|
font-weight: bolder;
|
||||||
|
//font-weight: 500;
|
||||||
//font-weight: normal;
|
//font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user