Single playback controller for audio & round video
This commit is contained in:
parent
994bbccde9
commit
fb1ebeb9a1
|
@ -1,149 +0,0 @@
|
|||
import { MTDocument } from "../types";
|
||||
import { $rootScope } from "../lib/utils";
|
||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||
import appDocsManager from "../lib/appManagers/appDocsManager";
|
||||
import opusDecodeController from "../lib/opusDecodeController";
|
||||
|
||||
// TODO: если удалить сообщение, и при этом аудио будет играть - оно не остановится, и можно будет по нему перейти вникуда
|
||||
|
||||
class AppAudio {
|
||||
private container: HTMLElement;
|
||||
private audios: {[mid: string]: HTMLAudioElement} = {};
|
||||
private playingAudio: HTMLAudioElement;
|
||||
|
||||
public willBePlayedAudio: HTMLAudioElement;
|
||||
|
||||
private prevMid: number;
|
||||
private nextMid: number;
|
||||
|
||||
constructor() {
|
||||
this.container = document.createElement('div');
|
||||
//this.container.style.cssText = 'position: absolute; top: -10000px; left: -10000px;';
|
||||
this.container.style.cssText = 'display: none;';
|
||||
document.body.append(this.container);
|
||||
}
|
||||
|
||||
public addAudio(doc: MTDocument, mid: number) {
|
||||
if(this.audios[mid]) return this.audios[mid];
|
||||
|
||||
const audio = document.createElement('audio');
|
||||
const source = document.createElement('source');
|
||||
source.type = doc.type == 'voice' && !opusDecodeController.isPlaySupported() ? 'audio/wav' : doc.mime_type;
|
||||
|
||||
audio.autoplay = false;
|
||||
audio.volume = 1;
|
||||
audio.append(source);
|
||||
|
||||
audio.addEventListener('playing', (e) => {
|
||||
if(this.playingAudio != audio) {
|
||||
if(this.playingAudio && !this.playingAudio.paused) {
|
||||
this.playingAudio.pause();
|
||||
}
|
||||
|
||||
this.playingAudio = audio;
|
||||
this.loadSiblingsAudio(doc.type as 'voice' | 'audio', mid);
|
||||
}
|
||||
|
||||
// audio_pause не успеет сработать без таймаута
|
||||
setTimeout(() => {
|
||||
$rootScope.$broadcast('audio_play', {doc, mid});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
audio.addEventListener('pause', this.onPause);
|
||||
audio.addEventListener('ended', this.onEnded);
|
||||
|
||||
const onError = (e: Event) => {
|
||||
if(this.nextMid == mid) {
|
||||
this.loadSiblingsAudio(doc.type as 'voice' | 'audio', mid).then(() => {
|
||||
if(this.nextMid && this.audios[this.nextMid]) {
|
||||
this.audios[this.nextMid].play();
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
audio.addEventListener('error', onError);
|
||||
|
||||
const downloadPromise: Promise<any> = !doc.supportsStreaming ? appDocsManager.downloadDocNew(doc.id) : Promise.resolve();
|
||||
|
||||
downloadPromise.then(() => {
|
||||
this.container.append(audio);
|
||||
source.src = doc.url;
|
||||
}, onError);
|
||||
|
||||
return this.audios[mid] = audio;
|
||||
}
|
||||
|
||||
onPause = (e: Event) => {
|
||||
$rootScope.$broadcast('audio_pause');
|
||||
};
|
||||
|
||||
onEnded = (e: Event) => {
|
||||
this.onPause(e);
|
||||
|
||||
if(this.nextMid) {
|
||||
this.audios[this.nextMid].play();
|
||||
}
|
||||
};
|
||||
|
||||
private loadSiblingsAudio(type: 'voice' | 'audio', mid: number) {
|
||||
const audio = this.playingAudio;
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.prevMid = this.nextMid = 0;
|
||||
|
||||
return appMessagesManager.getSearch(message.peerID, '', {
|
||||
_: type == 'audio' ? 'inputMessagesFilterMusic' : 'inputMessagesFilterVoice'
|
||||
}, mid, 3, 0, 2).then(value => {
|
||||
if(this.playingAudio != audio) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(let m of value.history) {
|
||||
if(m > mid) {
|
||||
this.nextMid = m;
|
||||
} else if(m < mid) {
|
||||
this.prevMid = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[this.prevMid, this.nextMid].filter(Boolean).forEach(mid => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.addAudio(message.media.document, mid);
|
||||
});
|
||||
|
||||
//console.log('loadSiblingsAudio', audio, type, mid, value, this.prevMid, this.nextMid);
|
||||
});
|
||||
}
|
||||
|
||||
public toggle() {
|
||||
if(!this.playingAudio) return;
|
||||
|
||||
if(this.playingAudio.paused) {
|
||||
this.playingAudio.play();
|
||||
} else {
|
||||
this.playingAudio.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public pause() {
|
||||
if(!this.playingAudio || this.playingAudio.paused) return;
|
||||
this.playingAudio.pause();
|
||||
}
|
||||
|
||||
public willBePlayed(audio: HTMLAudioElement) {
|
||||
this.willBePlayedAudio = audio;
|
||||
}
|
||||
|
||||
public audioExists(mid: number) {
|
||||
return !!this.audios[mid];
|
||||
}
|
||||
}
|
||||
|
||||
const appAudio = new AppAudio();
|
||||
// @ts-ignore
|
||||
if(process.env.NODE_ENV != 'production') {
|
||||
(window as any).appAudio = appAudio;
|
||||
}
|
||||
export default appAudio;
|
157
src/components/appMediaPlaybackController.ts
Normal file
157
src/components/appMediaPlaybackController.ts
Normal file
|
@ -0,0 +1,157 @@
|
|||
import { MTDocument } from "../types";
|
||||
import { $rootScope } from "../lib/utils";
|
||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||
import appDocsManager from "../lib/appManagers/appDocsManager";
|
||||
|
||||
// TODO: если удалить сообщение, и при этом аудио будет играть - оно не остановится, и можно будет по нему перейти вникуда
|
||||
|
||||
type HTMLMediaElement = HTMLAudioElement | HTMLVideoElement;
|
||||
|
||||
type MediaType = 'voice' | 'audio' | 'round';
|
||||
|
||||
class AppMediaPlaybackController {
|
||||
private container: HTMLElement;
|
||||
private media: {[mid: string]: HTMLMediaElement} = {};
|
||||
private playingMedia: HTMLMediaElement;
|
||||
|
||||
public willBePlayedMedia: HTMLMediaElement;
|
||||
|
||||
private prevMid: number;
|
||||
private nextMid: number;
|
||||
|
||||
constructor() {
|
||||
this.container = document.createElement('div');
|
||||
//this.container.style.cssText = 'position: absolute; top: -10000px; left: -10000px;';
|
||||
this.container.style.cssText = 'display: none;';
|
||||
document.body.append(this.container);
|
||||
}
|
||||
|
||||
public addMedia(doc: MTDocument, mid: number): HTMLMediaElement {
|
||||
if(this.media[mid]) return this.media[mid];
|
||||
|
||||
const media = document.createElement(doc.type == 'round' ? 'video' : 'audio');
|
||||
//const source = document.createElement('source');
|
||||
//source.type = doc.type == 'voice' && !opusDecodeController.isPlaySupported() ? 'audio/wav' : doc.mime_type;
|
||||
|
||||
media.autoplay = false;
|
||||
media.volume = 1;
|
||||
//media.append(source);
|
||||
|
||||
media.addEventListener('playing', () => {
|
||||
if(this.playingMedia != media) {
|
||||
if(this.playingMedia && !this.playingMedia.paused) {
|
||||
this.playingMedia.pause();
|
||||
}
|
||||
|
||||
this.playingMedia = media;
|
||||
this.loadSiblingsMedia(doc.type as MediaType, mid);
|
||||
}
|
||||
|
||||
// audio_pause не успеет сработать без таймаута
|
||||
setTimeout(() => {
|
||||
$rootScope.$broadcast('audio_play', {doc, mid});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
media.addEventListener('pause', this.onPause);
|
||||
media.addEventListener('ended', this.onEnded);
|
||||
|
||||
const onError = (e: Event) => {
|
||||
if(this.nextMid == mid) {
|
||||
this.loadSiblingsMedia(doc.type as MediaType, mid).then(() => {
|
||||
if(this.nextMid && this.media[this.nextMid]) {
|
||||
this.media[this.nextMid].play();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
media.addEventListener('error', onError);
|
||||
|
||||
const downloadPromise: Promise<any> = !doc.supportsStreaming ? appDocsManager.downloadDocNew(doc.id) : Promise.resolve();
|
||||
|
||||
downloadPromise.then(() => {
|
||||
//if(doc.type != 'round') {
|
||||
this.container.append(media);
|
||||
//}
|
||||
|
||||
//source.src = doc.url;
|
||||
media.src = doc.url;
|
||||
}, onError);
|
||||
|
||||
return this.media[mid] = media;
|
||||
}
|
||||
|
||||
onPause = (e: Event) => {
|
||||
$rootScope.$broadcast('audio_pause');
|
||||
};
|
||||
|
||||
onEnded = (e: Event) => {
|
||||
this.onPause(e);
|
||||
|
||||
if(this.nextMid) {
|
||||
this.media[this.nextMid].play();
|
||||
}
|
||||
};
|
||||
|
||||
private loadSiblingsMedia(type: MediaType, mid: number) {
|
||||
const media = this.playingMedia;
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.prevMid = this.nextMid = 0;
|
||||
|
||||
return appMessagesManager.getSearch(message.peerID, '', {
|
||||
//_: type == 'audio' ? 'inputMessagesFilterMusic' : (type == 'round' ? 'inputMessagesFilterRoundVideo' : 'inputMessagesFilterVoice')
|
||||
_: type == 'audio' ? 'inputMessagesFilterMusic' : 'inputMessagesFilterRoundVoice'
|
||||
}, mid, 3, 0, 2).then(value => {
|
||||
if(this.playingMedia != media) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(let m of value.history) {
|
||||
if(m > mid) {
|
||||
this.nextMid = m;
|
||||
} else if(m < mid) {
|
||||
this.prevMid = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[this.prevMid, this.nextMid].filter(Boolean).forEach(mid => {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
this.addMedia(message.media.document, mid);
|
||||
});
|
||||
|
||||
//console.log('loadSiblingsAudio', audio, type, mid, value, this.prevMid, this.nextMid);
|
||||
});
|
||||
}
|
||||
|
||||
public toggle() {
|
||||
if(!this.playingMedia) return;
|
||||
|
||||
if(this.playingMedia.paused) {
|
||||
this.playingMedia.play();
|
||||
} else {
|
||||
this.playingMedia.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public pause() {
|
||||
if(!this.playingMedia || this.playingMedia.paused) return;
|
||||
this.playingMedia.pause();
|
||||
}
|
||||
|
||||
public willBePlayed(media: HTMLMediaElement) {
|
||||
this.willBePlayedMedia = media;
|
||||
}
|
||||
|
||||
public mediaExists(mid: number) {
|
||||
return !!this.media[mid];
|
||||
}
|
||||
}
|
||||
|
||||
const appMediaPlaybackController = new AppMediaPlaybackController();
|
||||
// @ts-ignore
|
||||
if(process.env.NODE_ENV != 'production') {
|
||||
(window as any).appMediaPlaybackController = appMediaPlaybackController;
|
||||
}
|
||||
export default appMediaPlaybackController;
|
|
@ -3,7 +3,7 @@ import { RichTextProcessor } from "../lib/richtextprocessor";
|
|||
import { formatDate } from "./wrappers";
|
||||
import ProgressivePreloader from "./preloader";
|
||||
import { MediaProgressLine } from "../lib/mediaPlayer";
|
||||
import appAudio from "./appAudio";
|
||||
import appMediaPlaybackController from "./appMediaPlaybackController";
|
||||
import { MTDocument } from "../types";
|
||||
import { mediaSizes } from "../lib/config";
|
||||
import { Download } from "../lib/appManagers/appDownloadManager";
|
||||
|
@ -313,7 +313,7 @@ export default class AudioElement extends HTMLElement {
|
|||
audioTimeDiv.innerHTML = durationStr;
|
||||
|
||||
const onLoad = () => {
|
||||
const audio = this.audio = appAudio.addAudio(doc, mid);
|
||||
const audio = this.audio = appMediaPlaybackController.addMedia(doc, mid);
|
||||
|
||||
this.onTypeDisconnect = onTypeLoad();
|
||||
|
||||
|
@ -390,13 +390,13 @@ export default class AudioElement extends HTMLElement {
|
|||
this.addEventListener('click', onClick);
|
||||
this.click();
|
||||
} else {
|
||||
if(appAudio.audioExists(mid)) { // чтобы показать прогресс, если аудио уже было скачано
|
||||
if(appMediaPlaybackController.mediaExists(mid)) { // чтобы показать прогресс, если аудио уже было скачано
|
||||
onLoad();
|
||||
} else {
|
||||
const r = () => {
|
||||
onLoad();
|
||||
|
||||
appAudio.willBePlayed(this.audio); // prepare for loading audio
|
||||
appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio
|
||||
|
||||
if(!preloader) {
|
||||
preloader = new ProgressivePreloader(null, false);
|
||||
|
@ -413,9 +413,9 @@ export default class AudioElement extends HTMLElement {
|
|||
|
||||
//setTimeout(() => {
|
||||
// release loaded audio
|
||||
if(appAudio.willBePlayedAudio == this.audio) {
|
||||
if(appMediaPlaybackController.willBePlayedMedia == this.audio) {
|
||||
this.audio.play();
|
||||
appAudio.willBePlayedAudio = null;
|
||||
appMediaPlaybackController.willBePlayedMedia = null;
|
||||
}
|
||||
//}, 10e3);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import appPhotosManager, { MTPhoto } from '../lib/appManagers/appPhotosManager';
|
||||
import LottieLoader from '../lib/lottieLoader';
|
||||
import appDocsManager from "../lib/appManagers/appDocsManager";
|
||||
import { formatBytes, getEmojiToneIndex } from "../lib/utils";
|
||||
import { formatBytes, getEmojiToneIndex, isInDOM } from "../lib/utils";
|
||||
import ProgressivePreloader from './preloader';
|
||||
import LazyLoadQueue from './lazyLoadQueue';
|
||||
import VideoPlayer from '../lib/mediaPlayer';
|
||||
|
@ -17,6 +17,7 @@ import AudioElement from './audio';
|
|||
import { DownloadBlob } from '../lib/appManagers/appDownloadManager';
|
||||
import webpWorkerController from '../lib/webp/webpWorkerController';
|
||||
import { readBlobAsText } from '../helpers/blob';
|
||||
import appMediaPlaybackController from './appMediaPlaybackController';
|
||||
|
||||
export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group}: {
|
||||
doc: MTDocument,
|
||||
|
@ -55,7 +56,72 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||
return wrapPhoto(doc, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware);
|
||||
}
|
||||
|
||||
/* const video = doc.type == 'round' ? appMediaPlaybackController.addMedia(doc, message.mid) as HTMLVideoElement : document.createElement('video');
|
||||
if(video.parentElement) {
|
||||
video.remove();
|
||||
} */
|
||||
|
||||
const video = document.createElement('video');
|
||||
if(doc.type == 'round') {
|
||||
video.muted = true;
|
||||
const globalVideo = appMediaPlaybackController.addMedia(doc, message.mid);
|
||||
|
||||
video.addEventListener('canplay', () => {
|
||||
if(globalVideo.currentTime > 0) {
|
||||
video.currentTime = globalVideo.currentTime;
|
||||
}
|
||||
|
||||
if(!globalVideo.paused) {
|
||||
// с закоментированными настройками - хром выключал видео при скролле, для этого нужно было включить видео - выйти из диалога, зайти заново и проскроллить вверх
|
||||
/* video.autoplay = true;
|
||||
video.loop = false; */
|
||||
video.play();
|
||||
}
|
||||
}, {once: true});
|
||||
|
||||
const clear = () => {
|
||||
//console.log('clearing video');
|
||||
|
||||
globalVideo.removeEventListener('timeupdate', onTimeUpdate);
|
||||
globalVideo.removeEventListener('play', onGlobalPlay);
|
||||
globalVideo.removeEventListener('pause', onGlobalPause);
|
||||
video.removeEventListener('play', onVideoPlay);
|
||||
video.removeEventListener('pause', onVideoPause);
|
||||
};
|
||||
|
||||
const onTimeUpdate = () => {
|
||||
if(!isInDOM(video)) {
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
const onGlobalPlay = () => {
|
||||
video.play();
|
||||
};
|
||||
|
||||
const onGlobalPause = () => {
|
||||
video.pause();
|
||||
};
|
||||
|
||||
const onVideoPlay = () => {
|
||||
globalVideo.play();
|
||||
};
|
||||
|
||||
const onVideoPause = () => {
|
||||
//console.log('video pause event');
|
||||
if(isInDOM(video)) {
|
||||
globalVideo.pause();
|
||||
} else {
|
||||
clear();
|
||||
}
|
||||
};
|
||||
|
||||
globalVideo.addEventListener('timeupdate', onTimeUpdate);
|
||||
globalVideo.addEventListener('play', onGlobalPlay);
|
||||
globalVideo.addEventListener('pause', onGlobalPause);
|
||||
video.addEventListener('play', onVideoPlay);
|
||||
video.addEventListener('pause', onVideoPause);
|
||||
}
|
||||
|
||||
let img: HTMLImageElement;
|
||||
if(message) {
|
||||
|
@ -154,7 +220,10 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
|||
}, {once: true});
|
||||
//}
|
||||
|
||||
renderImageFromUrl(video, doc.url);
|
||||
//if(doc.type != 'round') {
|
||||
renderImageFromUrl(video, doc.url);
|
||||
//}
|
||||
|
||||
video.setAttribute('playsinline', '');
|
||||
|
||||
/* if(!container.parentElement) {
|
||||
|
|
|
@ -35,7 +35,7 @@ import PopupStickers from '../../components/popupStickers';
|
|||
import SearchInput from '../../components/searchInput';
|
||||
import AppSearch, { SearchGroup } from '../../components/appSearch';
|
||||
import PopupDatePicker from '../../components/popupDatepicker';
|
||||
import appAudio from '../../components/appAudio';
|
||||
import appMediaPlaybackController from '../../components/appMediaPlaybackController';
|
||||
import appPollsManager from './appPollsManager';
|
||||
import { ripple } from '../../components/ripple';
|
||||
import { horizontalMenu } from '../../components/horizontalMenu';
|
||||
|
@ -420,20 +420,20 @@ class ChatAudio {
|
|||
this.container.style.display = 'none';
|
||||
this.container.parentElement.classList.remove('is-audio-shown');
|
||||
if(this.toggle.classList.contains('flip-icon')) {
|
||||
appAudio.toggle();
|
||||
appMediaPlaybackController.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
this.toggle.addEventListener('click', (e) => {
|
||||
cancelEvent(e);
|
||||
appAudio.toggle();
|
||||
appMediaPlaybackController.toggle();
|
||||
});
|
||||
|
||||
$rootScope.$on('audio_play', (e: CustomEvent) => {
|
||||
const {doc, mid} = e.detail;
|
||||
|
||||
let title: string, subtitle: string;
|
||||
if(doc.type == 'voice') {
|
||||
if(doc.type == 'voice' || doc.type == 'round') {
|
||||
const message = appMessagesManager.getMessage(mid);
|
||||
title = appPeersManager.getPeerTitle(message.fromID, false, true);
|
||||
//subtitle = 'Voice message';
|
||||
|
|
|
@ -12,10 +12,9 @@ import AvatarElement from "../../components/avatar";
|
|||
import LazyLoadQueue from "../../components/lazyLoadQueue";
|
||||
import appForward from "../../components/appForward";
|
||||
import { isSafari, mediaSizes, touchSupport } from "../config";
|
||||
import appAudio from "../../components/appAudio";
|
||||
import { deferredPromise } from "../polyfill";
|
||||
import { MTDocument } from "../../types";
|
||||
import idbFileStorage from "../idb";
|
||||
import appMediaPlaybackController from "../../components/appMediaPlaybackController";
|
||||
|
||||
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
|
||||
// TODO: картинки "обрезаются" если возвращаются или появляются с места, где есть их перекрытие (топбар, поле ввода)
|
||||
|
@ -954,8 +953,8 @@ export class AppMediaViewer {
|
|||
video.dataset.overlay = '1';
|
||||
|
||||
// fix for simultaneous play
|
||||
appAudio.pause();
|
||||
appAudio.willBePlayedAudio = null;
|
||||
appMediaPlaybackController.pause();
|
||||
appMediaPlaybackController.willBePlayedMedia = null;
|
||||
|
||||
Promise.all([canPlayThrough, onAnimationEnd]).then(() => {
|
||||
const player = new VideoPlayer(video, true, media.supportsStreaming);
|
||||
|
|
|
@ -2896,7 +2896,7 @@ export class AppMessagesManager {
|
|||
var neededContents: {
|
||||
[type: string]: boolean
|
||||
} = {},
|
||||
neededDocType: string | boolean;
|
||||
neededDocTypes: string[] = [];
|
||||
var neededLimit = limit || 20;
|
||||
var message;
|
||||
|
||||
|
@ -2908,32 +2908,36 @@ export class AppMessagesManager {
|
|||
case 'inputMessagesFilterPhotoVideo':
|
||||
neededContents['messageMediaPhoto'] = true;
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = 'video';
|
||||
neededDocTypes.push('video');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterVideo':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = 'video';
|
||||
neededDocTypes.push('video');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterDocument':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = false;
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterVoice':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = 'voice';
|
||||
neededDocTypes.push('voice');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterRoundVoice':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocTypes.push('round', 'voice');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterRoundVideo':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = 'round';
|
||||
neededDocTypes.push('round');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterMusic':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
neededDocType = 'audio';
|
||||
neededDocTypes.push('audio');
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterUrl':
|
||||
|
@ -2955,9 +2959,9 @@ export class AppMessagesManager {
|
|||
for(let i = 0; i < historyStorage.history.length; i++) {
|
||||
message = this.messagesStorage[historyStorage.history[i]];
|
||||
if(message.media && neededContents[message.media._]) {
|
||||
if(neededDocType !== undefined &&
|
||||
if(neededDocTypes.length &&
|
||||
message.media._ == 'messageMediaDocument' &&
|
||||
message.media.document.type != neededDocType) {
|
||||
!neededDocTypes.includes(message.media.document.type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { cancelEvent, whichChild } from "./utils";
|
||||
import { cancelEvent } from "./utils";
|
||||
import { touchSupport } from "./config";
|
||||
|
||||
export class ProgressLine {
|
||||
|
@ -7,7 +7,7 @@ export class ProgressLine {
|
|||
protected seek: HTMLInputElement;
|
||||
|
||||
protected duration = 1;
|
||||
protected mousedown = false;
|
||||
public mousedown = false;
|
||||
|
||||
private events: Partial<{
|
||||
//onMouseMove: ProgressLine['onMouseMove'],
|
||||
|
@ -343,7 +343,9 @@ export default class VideoPlayer {
|
|||
volumeSvg.innerHTML = `<path d="${d}"></path>`;
|
||||
} catch(err) {}
|
||||
|
||||
volumeProgress.setProgress(video.muted ? 0 : volume);
|
||||
if(!volumeProgress.mousedown) {
|
||||
volumeProgress.setProgress(video.muted ? 0 : volume);
|
||||
}
|
||||
};
|
||||
|
||||
// не вызовется повторно если на 1 установить 1
|
||||
|
@ -439,6 +441,14 @@ export default class VideoPlayer {
|
|||
iconVolume.style.display = '';
|
||||
});
|
||||
}
|
||||
|
||||
video.addEventListener('play', () => {
|
||||
this.wrapper.classList.add('is-playing');
|
||||
});
|
||||
|
||||
video.addEventListener('pause', () => {
|
||||
this.wrapper.classList.remove('is-playing');
|
||||
});
|
||||
|
||||
if(video.duration > 0) {
|
||||
timeDuration.innerHTML = String(Math.round(video.duration)).toHHMMSS();
|
||||
|
@ -469,7 +479,7 @@ export default class VideoPlayer {
|
|||
}
|
||||
|
||||
this.video[this.video.paused ? 'play' : 'pause']();
|
||||
this.video.paused ? this.wrapper.classList.remove('is-playing') : this.wrapper.classList.add('is-playing');
|
||||
//this.wrapper.classList.toggle('is-playing', !this.video.paused);
|
||||
}
|
||||
|
||||
private handleProgress(timeDuration: HTMLElement, circumference: number, circle: SVGCircleElement, updateInterval: number) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user