Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
4.8 KiB
180 lines
4.8 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import { GrabEvent } from "../helpers/dom/attachGrabListeners"; |
|
import appMediaPlaybackController from "./appMediaPlaybackController"; |
|
import RangeSelector from "./rangeSelector"; |
|
|
|
export default class MediaProgressLine extends RangeSelector { |
|
protected filledLoad: HTMLDivElement; |
|
|
|
protected progressRAF = 0; |
|
|
|
protected media: HTMLMediaElement; |
|
protected streamable: boolean; |
|
|
|
constructor(media?: HTMLAudioElement | HTMLVideoElement, streamable?: boolean, withTransition?: boolean, useTransform?: boolean) { |
|
super({ |
|
step: 1000 / 60 / 1000, |
|
min: 0, |
|
max: 1, |
|
withTransition, |
|
useTransform |
|
}, 0); |
|
|
|
if(media) { |
|
this.setMedia(media, streamable); |
|
} |
|
} |
|
|
|
public setMedia(media: HTMLMediaElement, streamable = false) { |
|
if(this.media) { |
|
this.removeListeners(); |
|
} |
|
|
|
if(streamable && !this.filledLoad) { |
|
this.filledLoad = document.createElement('div'); |
|
this.filledLoad.classList.add('progress-line__filled', 'progress-line__loaded'); |
|
this.container.prepend(this.filledLoad); |
|
//this.setLoadProgress(); |
|
} else if(this.filledLoad) { |
|
this.filledLoad.classList.toggle('hide', !streamable); |
|
} |
|
|
|
this.media = media; |
|
this.streamable = streamable; |
|
if(!media.paused || media.currentTime > 0) { |
|
this.onPlay(); |
|
} |
|
|
|
let wasPlaying = false; |
|
this.setSeekMax(); |
|
this.setListeners(); |
|
this.setHandlers({ |
|
onMouseDown: () => { |
|
wasPlaying = !this.media.paused; |
|
wasPlaying && this.media.pause(); |
|
}, |
|
|
|
onMouseUp: (e) => { |
|
// cancelEvent(e.event); |
|
wasPlaying && this.media.play(); |
|
} |
|
}); |
|
} |
|
|
|
protected onLoadedData = () => { |
|
this.max = this.media.duration; |
|
this.seek.setAttribute('max', '' + this.max); |
|
}; |
|
|
|
protected onEnded = () => { |
|
this.setProgress(); |
|
}; |
|
|
|
protected onPlay = () => { |
|
let r = () => { |
|
this.setProgress(); |
|
|
|
this.progressRAF = this.media.paused ? 0 : window.requestAnimationFrame(r); |
|
}; |
|
|
|
if(this.progressRAF) { |
|
window.cancelAnimationFrame(this.progressRAF); |
|
} |
|
|
|
if(this.streamable) { |
|
this.setLoadProgress(); |
|
} |
|
|
|
this.progressRAF = window.requestAnimationFrame(r); |
|
}; |
|
|
|
protected onTimeUpdate = () => { |
|
if(this.media.paused) { |
|
this.setProgress(); |
|
|
|
if(this.streamable) { |
|
this.setLoadProgress(); |
|
} |
|
} |
|
}; |
|
|
|
protected onProgress = (e: Event) => { |
|
this.setLoadProgress(); |
|
}; |
|
|
|
protected scrub(e: GrabEvent) { |
|
const scrubTime = super.scrub(e); |
|
this.media.currentTime = scrubTime; |
|
return scrubTime; |
|
} |
|
|
|
protected setLoadProgress() { |
|
if(appMediaPlaybackController.isSafariBuffering(this.media)) return; |
|
const buf = this.media.buffered; |
|
const numRanges = buf.length; |
|
|
|
const currentTime = this.media.currentTime; |
|
let nearestStart = 0, end = 0; |
|
for(let i = 0; i < numRanges; ++i) { |
|
const start = buf.start(i); |
|
if(currentTime >= start && start >= nearestStart) { |
|
nearestStart = start; |
|
end = buf.end(i); |
|
} |
|
|
|
//console.log('onProgress range:', i, buf.start(i), buf.end(i), this.media); |
|
} |
|
|
|
//console.log('onProgress correct range:', nearestStart, end, this.media); |
|
|
|
const percents = this.media.duration ? end / this.media.duration : 0; |
|
this.filledLoad.style.width = (percents * 100) + '%'; |
|
//this.filledLoad.style.transform = 'scaleX(' + percents + ')'; |
|
} |
|
|
|
protected setSeekMax() { |
|
this.max = this.media.duration || 0; |
|
if(this.max > 0) { |
|
this.onLoadedData(); |
|
} else { |
|
this.media.addEventListener('loadeddata', this.onLoadedData); |
|
} |
|
} |
|
|
|
public setProgress() { |
|
if(appMediaPlaybackController.isSafariBuffering(this.media)) return; |
|
const currentTime = this.media.currentTime; |
|
|
|
super.setProgress(currentTime); |
|
} |
|
|
|
public setListeners() { |
|
super.setListeners(); |
|
this.media.addEventListener('ended', this.onEnded); |
|
this.media.addEventListener('play', this.onPlay); |
|
this.media.addEventListener('timeupdate', this.onTimeUpdate); |
|
this.streamable && this.media.addEventListener('progress', this.onProgress); |
|
} |
|
|
|
public removeListeners() { |
|
super.removeListeners(); |
|
|
|
if(this.media) { |
|
this.media.removeEventListener('loadeddata', this.onLoadedData); |
|
this.media.removeEventListener('ended', this.onEnded); |
|
this.media.removeEventListener('play', this.onPlay); |
|
this.media.removeEventListener('timeupdate', this.onTimeUpdate); |
|
this.streamable && this.media.removeEventListener('progress', this.onProgress); |
|
} |
|
|
|
if(this.progressRAF) { |
|
window.cancelAnimationFrame(this.progressRAF); |
|
this.progressRAF = 0; |
|
} |
|
} |
|
}
|
|
|