Improved recording overlay
This commit is contained in:
parent
a3d4776373
commit
1763b04162
src/components
@ -13,7 +13,7 @@ import { cancelEvent } from "../helpers/dom/cancelEvent";
|
|||||||
|
|
||||||
export type NavigationItem = {
|
export type NavigationItem = {
|
||||||
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' |
|
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' |
|
||||||
'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | 'global-search',
|
'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | 'global-search' | 'voice',
|
||||||
onPop: (canAnimate: boolean) => boolean | void,
|
onPop: (canAnimate: boolean) => boolean | void,
|
||||||
onEscape?: () => boolean,
|
onEscape?: () => boolean,
|
||||||
noHistory?: boolean,
|
noHistory?: boolean,
|
||||||
|
@ -43,7 +43,7 @@ import SendMenu from './sendContextMenu';
|
|||||||
import rootScope from '../../lib/rootScope';
|
import rootScope from '../../lib/rootScope';
|
||||||
import PopupPinMessage from '../popups/unpinMessage';
|
import PopupPinMessage from '../popups/unpinMessage';
|
||||||
import { tsNow } from '../../helpers/date';
|
import { tsNow } from '../../helpers/date';
|
||||||
import appNavigationController from '../appNavigationController';
|
import appNavigationController, { NavigationItem } from '../appNavigationController';
|
||||||
import { isMobile, isMobileSafari } from '../../helpers/userAgent';
|
import { isMobile, isMobileSafari } from '../../helpers/userAgent';
|
||||||
import I18n, { i18n, join, LangPackKey } from '../../lib/langPack';
|
import I18n, { i18n, join, LangPackKey } from '../../lib/langPack';
|
||||||
import { generateTail } from './bubbles';
|
import { generateTail } from './bubbles';
|
||||||
@ -132,6 +132,8 @@ export default class ChatInput {
|
|||||||
private recordTimeEl: HTMLElement;
|
private recordTimeEl: HTMLElement;
|
||||||
private recordRippleEl: HTMLElement;
|
private recordRippleEl: HTMLElement;
|
||||||
private recordStartTime = 0;
|
private recordStartTime = 0;
|
||||||
|
private recordingOverlayListener: Listener;
|
||||||
|
private recordingNavigationItem: NavigationItem;
|
||||||
|
|
||||||
// private scrollTop = 0;
|
// private scrollTop = 0;
|
||||||
// private scrollOffsetTop = 0;
|
// private scrollOffsetTop = 0;
|
||||||
@ -174,8 +176,6 @@ export default class ChatInput {
|
|||||||
|
|
||||||
private previousQuery: string;
|
private previousQuery: string;
|
||||||
|
|
||||||
private recordingOverlayListener: Listener;
|
|
||||||
|
|
||||||
constructor(private chat: Chat,
|
constructor(private chat: Chat,
|
||||||
private appMessagesManager: AppMessagesManager,
|
private appMessagesManager: AppMessagesManager,
|
||||||
private appMessagesIdsManager: AppMessagesIdsManager,
|
private appMessagesIdsManager: AppMessagesIdsManager,
|
||||||
@ -583,6 +583,11 @@ export default class ChatInput {
|
|||||||
this.recordingOverlayListener = undefined;
|
this.recordingOverlayListener = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.recordingNavigationItem) {
|
||||||
|
appNavigationController.removeItem(this.recordingNavigationItem);
|
||||||
|
this.recordingNavigationItem = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if(this.recordCanceled) {
|
if(this.recordCanceled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1460,26 +1465,41 @@ export default class ChatInput {
|
|||||||
this.recording = true;
|
this.recording = true;
|
||||||
this.updateSendBtn();
|
this.updateSendBtn();
|
||||||
opusDecodeController.setKeepAlive(true);
|
opusDecodeController.setKeepAlive(true);
|
||||||
|
|
||||||
|
const showDiscardPopup = () => {
|
||||||
|
new PopupPeer('popup-cancel-record', {
|
||||||
|
titleLangKey: 'DiscardVoiceMessageTitle',
|
||||||
|
descriptionLangKey: 'DiscardVoiceMessageDescription',
|
||||||
|
buttons: [{
|
||||||
|
langKey: 'DiscardVoiceMessageAction',
|
||||||
|
callback: () => {
|
||||||
|
simulateClickEvent(this.btnCancelRecord);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
langKey: 'Continue',
|
||||||
|
isCancel: true
|
||||||
|
}]
|
||||||
|
}).show();
|
||||||
|
};
|
||||||
|
|
||||||
this.recordingOverlayListener = this.listenerSetter.add(document.body)('mousedown', (e) => {
|
this.recordingOverlayListener = this.listenerSetter.add(document.body)('mousedown', (e) => {
|
||||||
if(!findUpClassName(e.target, 'chat-input') && !findUpClassName(e.target, 'popup-cancel-record')) {
|
if(!findUpClassName(e.target, 'chat-input') && !findUpClassName(e.target, 'popup-cancel-record')) {
|
||||||
cancelEvent(e);
|
cancelEvent(e);
|
||||||
new PopupPeer('popup-cancel-record', {
|
showDiscardPopup();
|
||||||
titleLangKey: 'DiscardVoiceMessageTitle',
|
|
||||||
descriptionLangKey: 'DiscardVoiceMessageDescription',
|
|
||||||
buttons: [{
|
|
||||||
langKey: 'DiscardVoiceMessageAction',
|
|
||||||
callback: () => {
|
|
||||||
simulateClickEvent(this.btnCancelRecord);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
langKey: 'Continue',
|
|
||||||
isCancel: true
|
|
||||||
}]
|
|
||||||
}).show();
|
|
||||||
}
|
}
|
||||||
}, {capture: true, passive: false}) as any;
|
}, {capture: true, passive: false}) as any;
|
||||||
|
|
||||||
|
appNavigationController.pushItem(this.recordingNavigationItem = {
|
||||||
|
type: 'voice',
|
||||||
|
onPop: () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
showDiscardPopup();
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.recordStartTime = Date.now();
|
this.recordStartTime = Date.now();
|
||||||
|
|
||||||
const sourceNode: MediaStreamAudioSourceNode = this.recorder.sourceNode;
|
const sourceNode: MediaStreamAudioSourceNode = this.recorder.sourceNode;
|
||||||
|
@ -64,6 +64,7 @@ class AppSelection {
|
|||||||
protected getElementFromTarget: (target: HTMLElement) => HTMLElement;
|
protected getElementFromTarget: (target: HTMLElement) => HTMLElement;
|
||||||
protected verifyTarget: (e: MouseEvent, target: HTMLElement) => boolean;
|
protected verifyTarget: (e: MouseEvent, target: HTMLElement) => boolean;
|
||||||
protected verifyMouseMoveTarget: (e: MouseEvent, element: HTMLElement, selecting: boolean) => boolean;
|
protected verifyMouseMoveTarget: (e: MouseEvent, element: HTMLElement, selecting: boolean) => boolean;
|
||||||
|
protected verifyTouchLongPress: () => boolean;
|
||||||
protected targetLookupClassName: string;
|
protected targetLookupClassName: string;
|
||||||
protected lookupBetweenParentClassName: string;
|
protected lookupBetweenParentClassName: string;
|
||||||
protected lookupBetweenElementsQuery: string;
|
protected lookupBetweenElementsQuery: string;
|
||||||
@ -75,6 +76,7 @@ class AppSelection {
|
|||||||
getElementFromTarget: AppSelection['getElementFromTarget'],
|
getElementFromTarget: AppSelection['getElementFromTarget'],
|
||||||
verifyTarget?: AppSelection['verifyTarget'],
|
verifyTarget?: AppSelection['verifyTarget'],
|
||||||
verifyMouseMoveTarget?: AppSelection['verifyMouseMoveTarget'],
|
verifyMouseMoveTarget?: AppSelection['verifyMouseMoveTarget'],
|
||||||
|
verifyTouchLongPress?: AppSelection['verifyTouchLongPress'],
|
||||||
targetLookupClassName: string,
|
targetLookupClassName: string,
|
||||||
lookupBetweenParentClassName: string,
|
lookupBetweenParentClassName: string,
|
||||||
lookupBetweenElementsQuery: string
|
lookupBetweenElementsQuery: string
|
||||||
@ -90,7 +92,7 @@ class AppSelection {
|
|||||||
});
|
});
|
||||||
|
|
||||||
attachContextMenuListener(this.listenElement, (e) => {
|
attachContextMenuListener(this.listenElement, (e) => {
|
||||||
if(this.isSelecting) return;
|
if(this.isSelecting || (this.verifyTouchLongPress && !this.verifyTouchLongPress())) return;
|
||||||
|
|
||||||
// * these two lines will fix instant text selection on iOS Safari
|
// * these two lines will fix instant text selection on iOS Safari
|
||||||
document.body.classList.add('no-select'); // * need no-select on body because chat-input transforms in channels
|
document.body.classList.add('no-select'); // * need no-select on body because chat-input transforms in channels
|
||||||
@ -685,6 +687,7 @@ export default class ChatSelection extends AppSelection {
|
|||||||
!this.selectedMids.size;
|
!this.selectedMids.size;
|
||||||
return !bad;
|
return !bad;
|
||||||
},
|
},
|
||||||
|
verifyTouchLongPress: () => !this.chat.input.recording,
|
||||||
targetLookupClassName: 'bubble',
|
targetLookupClassName: 'bubble',
|
||||||
lookupBetweenParentClassName: 'bubbles-inner',
|
lookupBetweenParentClassName: 'bubbles-inner',
|
||||||
lookupBetweenElementsQuery: '.bubble:not(.is-multiple-documents), .grouped-item'
|
lookupBetweenElementsQuery: '.bubble:not(.is-multiple-documents), .grouped-item'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user