diff --git a/src/components/appMediaPlaybackController.ts b/src/components/appMediaPlaybackController.ts index 56b4a644..4ad5f297 100644 --- a/src/components/appMediaPlaybackController.ts +++ b/src/components/appMediaPlaybackController.ts @@ -470,7 +470,7 @@ class AppMediaPlaybackController { navigator.mediaSession.metadata = metadata; } - private getMessageByMedia(media: HTMLMediaElement) { + private getMessageByMedia(media: HTMLMediaElement): Message.message { const details = this.mediaDetails.get(media); const {peerId, mid} = details; const message = details.isScheduled ? appMessagesManager.getScheduledMessageByPeer(peerId, mid) : appMessagesManager.getMessageByPeer(peerId, mid); @@ -517,10 +517,28 @@ class AppMediaPlaybackController { // audio_pause не успеет сработать без таймаута setTimeout(() => { - rootScope.dispatchEvent('media_play', {doc: appMessagesManager.getMediaFromMessage(message), message, media}); + if(this.playingMedia !== media) { + return; + } + + rootScope.dispatchEvent('media_play', this.getPlayingDetails()); }, 0); }; + public getPlayingDetails() { + const {playingMedia} = this; + if(!playingMedia) { + return; + } + + const message = this.getMessageByMedia(playingMedia); + return { + doc: appMessagesManager.getMediaFromMessage(message), + message, + media: playingMedia + }; + } + private onPause = (e?: Event) => { /* const target = e.target as HTMLMediaElement; if(!isInDOM(target)) { diff --git a/src/components/chat/audio.ts b/src/components/chat/audio.ts index b071da2b..f22419f2 100644 --- a/src/components/chat/audio.ts +++ b/src/components/chat/audio.ts @@ -19,11 +19,14 @@ import { i18n } from "../../lib/langPack"; import { formatFullSentTime } from "../../helpers/date"; import { MediaProgressLine, VolumeSelector } from "../../lib/mediaPlayer"; import ButtonIcon from "../buttonIcon"; +import { MyDocument } from "../../lib/appManagers/appDocsManager"; +import { Message } from "../../layer"; export default class ChatAudio extends PinnedContainer { private toggleEl: HTMLElement; private progressLine: MediaProgressLine; private volumeSelector: VolumeSelector; + private fasterEl: HTMLElement; constructor(protected topbar: ChatTopbar, protected chat: Chat, protected appMessagesManager: AppMessagesManager) { super({ @@ -81,7 +84,7 @@ export default class ChatAudio extends PinnedContainer { this.volumeSelector.btn.prepend(tunnel); this.volumeSelector.btn.append(volumeProgressLineContainer); - const fasterEl = ButtonIcon('playback_2x', {noRipple: true}); + const fasterEl = this.fasterEl = ButtonIcon('playback_2x', {noRipple: true}); attachClick(fasterEl, () => { appMediaPlaybackController.playbackRate = fasterEl.classList.contains('active') ? 1 : 1.75; }); @@ -96,37 +99,61 @@ export default class ChatAudio extends PinnedContainer { progressWrapper.append(this.progressLine.container); this.wrapper.insertBefore(progressWrapper, this.wrapperUtils); + this.topbar.listenerSetter.add(rootScope)('media_play', this.onMediaPlay); + this.topbar.listenerSetter.add(rootScope)('media_pause', this.onPause); + this.topbar.listenerSetter.add(rootScope)('media_stop', this.onStop); this.topbar.listenerSetter.add(rootScope)('media_playback_params', ({playbackRate}) => { - fasterEl.classList.toggle('active', playbackRate > 1); + this.onPlaybackRateChange(playbackRate); }); - this.topbar.listenerSetter.add(rootScope)('media_play', ({doc, message, media}) => { - let title: string | HTMLElement, subtitle: string | HTMLElement | DocumentFragment; - if(doc.type === 'voice' || doc.type === 'round') { - title = new PeerTitle({peerId: message.fromId}).element; - - //subtitle = 'Voice message'; - subtitle = formatFullSentTime(message.date); - fasterEl.classList.remove('hide'); - } else { - title = doc.audioTitle || doc.fileName; - subtitle = doc.audioPerformer || i18n('AudioUnknownArtist'); - fasterEl.classList.add('hide'); - } - - this.progressLine.setMedia(media); - - this.fill(title, subtitle, message); - this.toggleEl.classList.add('flip-icon'); - this.toggle(false); - }); - - this.topbar.listenerSetter.add(rootScope)('media_pause', () => { - this.toggleEl.classList.remove('flip-icon'); - }); + const playingDetails = appMediaPlaybackController.getPlayingDetails(); + if(playingDetails) { + this.onMediaPlay(playingDetails); + this.onPlaybackRateChange(appMediaPlaybackController.playbackRate); + } + } - this.topbar.listenerSetter.add(rootScope)('media_stop', () => { - this.toggle(true); - }); + public destroy() { + if(this.progressLine) { + this.progressLine.removeListeners(); + } } + + private onPlaybackRateChange = (playbackRate: number) => { + this.fasterEl.classList.toggle('active', playbackRate > 1); + }; + + private onPause = () => { + this.toggleEl.classList.remove('flip-icon'); + }; + + private onStop = () => { + this.toggle(true); + }; + + private onMediaPlay = ({doc, message, media}: { + doc: MyDocument, + message: Message.message, + media: HTMLMediaElement + }) => { + let title: string | HTMLElement, subtitle: string | HTMLElement | DocumentFragment; + if(doc.type === 'voice' || doc.type === 'round') { + title = new PeerTitle({peerId: message.fromId}).element; + + //subtitle = 'Voice message'; + subtitle = formatFullSentTime(message.date); + this.fasterEl.classList.remove('hide'); + } else { + title = doc.audioTitle || doc.fileName; + subtitle = doc.audioPerformer || i18n('AudioUnknownArtist'); + this.fasterEl.classList.add('hide'); + } + + this.progressLine.setMedia(media); + + this.fill(title, subtitle, message); + // this.toggleEl.classList.add('flip-icon'); + this.toggleEl.classList.toggle('flip-icon', !media.paused); + this.toggle(false); + }; } diff --git a/src/components/chat/topbar.ts b/src/components/chat/topbar.ts index ba371294..2ddd781a 100644 --- a/src/components/chat/topbar.ts +++ b/src/components/chat/topbar.ts @@ -664,7 +664,6 @@ export default class ChatTopbar { public destroy() { //this.chat.log.error('Topbar destroying'); - this.listenerSetter.removeAll(); window.clearInterval(this.setPeerStatusInterval); @@ -672,6 +671,10 @@ export default class ChatTopbar { this.pinnedMessage.destroy(); // * возможно это можно не делать } + if(this.chatAudio) { + this.chatAudio.destroy(); + } + delete this.chatAudio; delete this.pinnedMessage; }