Browse Source

Improved recording overlay

master
morethanwords 3 years ago
parent
commit
1763b04162
  1. 2
      src/components/appNavigationController.ts
  2. 52
      src/components/chat/input.ts
  3. 5
      src/components/chat/selection.ts

2
src/components/appNavigationController.ts

@ -13,7 +13,7 @@ import { cancelEvent } from "../helpers/dom/cancelEvent"; @@ -13,7 +13,7 @@ import { cancelEvent } from "../helpers/dom/cancelEvent";
export type NavigationItem = {
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,
onEscape?: () => boolean,
noHistory?: boolean,

52
src/components/chat/input.ts

@ -43,7 +43,7 @@ import SendMenu from './sendContextMenu'; @@ -43,7 +43,7 @@ import SendMenu from './sendContextMenu';
import rootScope from '../../lib/rootScope';
import PopupPinMessage from '../popups/unpinMessage';
import { tsNow } from '../../helpers/date';
import appNavigationController from '../appNavigationController';
import appNavigationController, { NavigationItem } from '../appNavigationController';
import { isMobile, isMobileSafari } from '../../helpers/userAgent';
import I18n, { i18n, join, LangPackKey } from '../../lib/langPack';
import { generateTail } from './bubbles';
@ -132,6 +132,8 @@ export default class ChatInput { @@ -132,6 +132,8 @@ export default class ChatInput {
private recordTimeEl: HTMLElement;
private recordRippleEl: HTMLElement;
private recordStartTime = 0;
private recordingOverlayListener: Listener;
private recordingNavigationItem: NavigationItem;
// private scrollTop = 0;
// private scrollOffsetTop = 0;
@ -174,8 +176,6 @@ export default class ChatInput { @@ -174,8 +176,6 @@ export default class ChatInput {
private previousQuery: string;
private recordingOverlayListener: Listener;
constructor(private chat: Chat,
private appMessagesManager: AppMessagesManager,
private appMessagesIdsManager: AppMessagesIdsManager,
@ -583,6 +583,11 @@ export default class ChatInput { @@ -583,6 +583,11 @@ export default class ChatInput {
this.recordingOverlayListener = undefined;
}
if(this.recordingNavigationItem) {
appNavigationController.removeItem(this.recordingNavigationItem);
this.recordingNavigationItem = undefined;
}
if(this.recordCanceled) {
return;
}
@ -1460,26 +1465,41 @@ export default class ChatInput { @@ -1460,26 +1465,41 @@ export default class ChatInput {
this.recording = true;
this.updateSendBtn();
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) => {
if(!findUpClassName(e.target, 'chat-input') && !findUpClassName(e.target, 'popup-cancel-record')) {
cancelEvent(e);
new PopupPeer('popup-cancel-record', {
titleLangKey: 'DiscardVoiceMessageTitle',
descriptionLangKey: 'DiscardVoiceMessageDescription',
buttons: [{
langKey: 'DiscardVoiceMessageAction',
callback: () => {
simulateClickEvent(this.btnCancelRecord);
}
}, {
langKey: 'Continue',
isCancel: true
}]
}).show();
showDiscardPopup();
}
}, {capture: true, passive: false}) as any;
appNavigationController.pushItem(this.recordingNavigationItem = {
type: 'voice',
onPop: () => {
setTimeout(() => {
showDiscardPopup();
}, 0);
return false;
}
});
this.recordStartTime = Date.now();
const sourceNode: MediaStreamAudioSourceNode = this.recorder.sourceNode;

5
src/components/chat/selection.ts

@ -64,6 +64,7 @@ class AppSelection { @@ -64,6 +64,7 @@ class AppSelection {
protected getElementFromTarget: (target: HTMLElement) => HTMLElement;
protected verifyTarget: (e: MouseEvent, target: HTMLElement) => boolean;
protected verifyMouseMoveTarget: (e: MouseEvent, element: HTMLElement, selecting: boolean) => boolean;
protected verifyTouchLongPress: () => boolean;
protected targetLookupClassName: string;
protected lookupBetweenParentClassName: string;
protected lookupBetweenElementsQuery: string;
@ -75,6 +76,7 @@ class AppSelection { @@ -75,6 +76,7 @@ class AppSelection {
getElementFromTarget: AppSelection['getElementFromTarget'],
verifyTarget?: AppSelection['verifyTarget'],
verifyMouseMoveTarget?: AppSelection['verifyMouseMoveTarget'],
verifyTouchLongPress?: AppSelection['verifyTouchLongPress'],
targetLookupClassName: string,
lookupBetweenParentClassName: string,
lookupBetweenElementsQuery: string
@ -90,7 +92,7 @@ class AppSelection { @@ -90,7 +92,7 @@ class AppSelection {
});
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
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 { @@ -685,6 +687,7 @@ export default class ChatSelection extends AppSelection {
!this.selectedMids.size;
return !bad;
},
verifyTouchLongPress: () => !this.chat.input.recording,
targetLookupClassName: 'bubble',
lookupBetweenParentClassName: 'bubbles-inner',
lookupBetweenElementsQuery: '.bubble:not(.is-multiple-documents), .grouped-item'

Loading…
Cancel
Save