222
This commit is contained in:
parent
669cd43978
commit
0c875ccbaf
@ -1,9 +1,12 @@
|
||||
import { MOUNT_CLASS_TO } from "../config/debug";
|
||||
import { isSafari } from "../helpers/userAgent";
|
||||
import { isSafari, isAppleMobile } from "../helpers/userAgent";
|
||||
import { cancelEvent } from "../helpers/dom";
|
||||
|
||||
export type NavigationItem = {
|
||||
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' | 'esg',
|
||||
onPop: (canAnimate: boolean) => boolean | void
|
||||
onPop: (canAnimate: boolean) => boolean | void,
|
||||
onEscape?: () => boolean,
|
||||
noHistory?: boolean,
|
||||
};
|
||||
|
||||
export class AppNavigationController {
|
||||
@ -26,7 +29,7 @@ export class AppNavigationController {
|
||||
return;
|
||||
}
|
||||
|
||||
const good = item.onPop(isSafari ? false : undefined);
|
||||
const good = item.onPop(isSafari && isAppleMobile ? false : undefined);
|
||||
console.log('[NC]: popstate, navigation:', item, this.navigations);
|
||||
if(good === false) {
|
||||
this.pushItem(item);
|
||||
@ -35,6 +38,15 @@ export class AppNavigationController {
|
||||
//this.pushState(); // * prevent adding forward arrow
|
||||
});
|
||||
|
||||
window.addEventListener('keydown', (e) => {
|
||||
const item = this.navigations[this.navigations.length - 1];
|
||||
if(!item) return;
|
||||
if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {
|
||||
cancelEvent(e);
|
||||
this.back();
|
||||
}
|
||||
}, {capture: true});
|
||||
|
||||
this.pushState(); // * push init state
|
||||
}
|
||||
|
||||
@ -45,7 +57,10 @@ export class AppNavigationController {
|
||||
public pushItem(item: NavigationItem) {
|
||||
this.navigations.push(item);
|
||||
console.log('[NC]: pushstate', item, this.navigations);
|
||||
this.pushState();
|
||||
|
||||
if(!item.noHistory) {
|
||||
this.pushState();
|
||||
}
|
||||
}
|
||||
|
||||
private pushState() {
|
||||
@ -55,6 +70,10 @@ export class AppNavigationController {
|
||||
public replaceState() {
|
||||
history.replaceState(this.id, '');
|
||||
}
|
||||
|
||||
public removeItem(item: NavigationItem) {
|
||||
this.navigations.findAndSplice(i => i === item);
|
||||
}
|
||||
}
|
||||
|
||||
const appNavigationController = new AppNavigationController();
|
||||
|
@ -1654,7 +1654,8 @@ export default class ChatBubbles {
|
||||
public setBubblePosition(bubble: HTMLElement, message: any, reverse: boolean) {
|
||||
const dateMessage = this.getDateContainerByMessage(message, reverse);
|
||||
if(this.chat.type === 'scheduled' || this.chat.type === 'pinned') {
|
||||
let children = Array.from(dateMessage.container.children).slice(2) as HTMLElement[];
|
||||
const offset = this.stickyIntersector ? 2 : 1;
|
||||
let children = Array.from(dateMessage.container.children).slice(offset) as HTMLElement[];
|
||||
let i = 0, foundMidOnSameTimestamp = 0;
|
||||
for(; i < children.length; ++i) {
|
||||
const t = children[i];
|
||||
@ -1671,7 +1672,7 @@ export default class ChatBubbles {
|
||||
}
|
||||
|
||||
// * 1 for date, 1 for date sentinel
|
||||
let index = this.stickyIntersector ? 2 + i : 1 + i;
|
||||
let index = offset + i;
|
||||
/* if(bubble.parentElement) { // * if already mounted
|
||||
const currentIndex = whichChild(bubble);
|
||||
if(index > currentIndex) {
|
||||
|
@ -556,7 +556,7 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
public saveDraft() {
|
||||
if(!this.chat.peerId || this.editMsgId) return;
|
||||
if(!this.chat.peerId || this.editMsgId || this.chat.type === 'scheduled') return;
|
||||
|
||||
const entities: MessageEntity[] = [];
|
||||
const str = getRichValue(this.messageInputField.input, entities);
|
||||
@ -604,7 +604,7 @@ export default class ChatInput {
|
||||
}
|
||||
|
||||
public setDraft(draft?: MyDraftMessage, fromUpdate = true) {
|
||||
if(!isInputEmpty(this.messageInput)) return false;
|
||||
if(!isInputEmpty(this.messageInput) || this.chat.type === 'scheduled') return false;
|
||||
|
||||
if(!draft) {
|
||||
draft = this.appDraftsManager.getDraft(this.chat.peerId, this.chat.threadId);
|
||||
|
@ -141,7 +141,7 @@ export default class PopupDatePicker extends PopupElement {
|
||||
this.onPick(this.selectedDate.getTime() / 1000 | 0);
|
||||
}
|
||||
|
||||
this.destroy();
|
||||
this.hide();
|
||||
}, {once: true});
|
||||
|
||||
this.body.append(this.timeDiv);
|
||||
|
@ -2,6 +2,8 @@ import rootScope from "../../lib/rootScope";
|
||||
import { blurActiveElement, cancelEvent, findUpClassName } from "../../helpers/dom";
|
||||
import { ripple } from "../ripple";
|
||||
import animationIntersector from "../animationIntersector";
|
||||
import appNavigationController, { NavigationItem } from "../appNavigationController";
|
||||
import { isMobileSafari, isSafari } from "../../helpers/userAgent";
|
||||
|
||||
export type PopupOptions = Partial<{closable: true, overlayClosable: true, withConfirm: string, body: true}>;
|
||||
export default class PopupElement {
|
||||
@ -17,6 +19,8 @@ export default class PopupElement {
|
||||
protected onCloseAfterTimeout: () => void;
|
||||
protected onEscape: () => boolean = () => true;
|
||||
|
||||
protected navigationItem: NavigationItem;
|
||||
|
||||
constructor(className: string, buttons?: Array<PopupButton>, options: PopupOptions = {}) {
|
||||
this.element.classList.add('popup');
|
||||
this.element.className = 'popup' + (className ? ' ' + className : '');
|
||||
@ -33,7 +37,7 @@ export default class PopupElement {
|
||||
//ripple(this.closeBtn);
|
||||
this.header.prepend(this.btnClose);
|
||||
|
||||
this.btnClose.addEventListener('click', this.destroy, {once: true});
|
||||
this.btnClose.addEventListener('click', this.hide, {once: true});
|
||||
|
||||
if(options.overlayClosable) {
|
||||
const onOverlayClick = (e: MouseEvent) => {
|
||||
@ -46,8 +50,6 @@ export default class PopupElement {
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', this._onKeyDown, {capture: true});
|
||||
|
||||
if(options.withConfirm) {
|
||||
this.btnConfirm = document.createElement('button');
|
||||
this.btnConfirm.classList.add('btn-primary');
|
||||
@ -98,14 +100,15 @@ export default class PopupElement {
|
||||
this.element.append(this.container);
|
||||
}
|
||||
|
||||
private _onKeyDown = (e: KeyboardEvent) => {
|
||||
if(e.key === 'Escape' && this.onEscape()) {
|
||||
cancelEvent(e);
|
||||
this.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
public show() {
|
||||
this.navigationItem = {
|
||||
type: 'popup',
|
||||
onPop: this.destroy,
|
||||
onEscape: this.onEscape
|
||||
};
|
||||
|
||||
appNavigationController.pushItem(this.navigationItem);
|
||||
|
||||
blurActiveElement(); // * hide mobile keyboard
|
||||
document.body.append(this.element);
|
||||
void this.element.offsetWidth; // reflow
|
||||
@ -114,15 +117,21 @@ export default class PopupElement {
|
||||
animationIntersector.checkAnimations(true);
|
||||
}
|
||||
|
||||
public destroy = () => {
|
||||
public hide = () => {
|
||||
appNavigationController.back();
|
||||
};
|
||||
|
||||
private destroy = () => {
|
||||
this.onClose && this.onClose();
|
||||
this.element.classList.add('hiding');
|
||||
this.element.classList.remove('active');
|
||||
|
||||
window.removeEventListener('keydown', this._onKeyDown, {capture: true});
|
||||
if(this.btnClose) this.btnClose.removeEventListener('click', this.destroy);
|
||||
if(this.btnClose) this.btnClose.removeEventListener('click', this.hide);
|
||||
rootScope.overlayIsActive = false;
|
||||
|
||||
appNavigationController.removeItem(this.navigationItem);
|
||||
this.navigationItem = undefined;
|
||||
|
||||
setTimeout(() => {
|
||||
this.element.remove();
|
||||
this.onCloseAfterTimeout && this.onCloseAfterTimeout();
|
||||
|
@ -142,7 +142,7 @@ export default class PopupNewMedia extends PopupElement {
|
||||
return;
|
||||
}
|
||||
|
||||
this.destroy();
|
||||
this.hide();
|
||||
const willAttach = this.willAttach;
|
||||
willAttach.isMedia = willAttach.type === 'media' ? true : undefined;
|
||||
|
||||
|
@ -18,4 +18,6 @@ export const isAppleMobile = (/iPad|iPhone|iPod/.test(navigator.platform) ||
|
||||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
|
||||
!ctx.MSStream;
|
||||
|
||||
export const isSafari = !!('safari' in ctx) || !!(userAgent && (/\b(iPad|iPhone|iPod)\b/.test(userAgent) || (!!userAgent.match('Safari') && !userAgent.match('Chrome'))))/* || true */;
|
||||
export const isSafari = !!('safari' in ctx) || !!(userAgent && (/\b(iPad|iPhone|iPod)\b/.test(userAgent) || (!!userAgent.match('Safari') && !userAgent.match('Chrome'))))/* || true */;
|
||||
|
||||
export const isMobileSafari = isSafari && isAppleMobile;
|
||||
|
Loading…
Reference in New Issue
Block a user