From 887bbbe65fec9fd6b08086ebd80eba8543729dcb Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Mon, 6 Mar 2023 18:56:03 +0400 Subject: [PATCH] fixes --- src/components/appMediaPlaybackController.ts | 1 + src/components/appMediaViewerBase.ts | 11 ++---- src/components/audio.ts | 38 +++++++++++-------- src/components/chat/audio.ts | 7 ++-- src/components/chat/bubbles.ts | 7 +++- src/components/mediaProgressLine.ts | 34 +++++++++-------- .../sidebarLeft/tabs/dataAndStorage.ts | 29 +++++++------- src/lib/files/cacheStorage.ts | 6 +-- src/lib/mediaPlayer.ts | 17 +++++++-- 9 files changed, 84 insertions(+), 66 deletions(-) diff --git a/src/components/appMediaPlaybackController.ts b/src/components/appMediaPlaybackController.ts index 5c85cae2..918cbab8 100644 --- a/src/components/appMediaPlaybackController.ts +++ b/src/components/appMediaPlaybackController.ts @@ -707,6 +707,7 @@ export class AppMediaPlaybackController extends EventListenerBase<{ } media.currentTime = 0; + simulateEvent(media, 'ended'); // ! important, will be used to hide controls for audio element if(media === this.playingMedia) { const details = this.mediaDetails.get(media); diff --git a/src/components/appMediaViewerBase.ts b/src/components/appMediaViewerBase.ts index de47b0b9..cfe66dc5 100644 --- a/src/components/appMediaViewerBase.ts +++ b/src/components/appMediaViewerBase.ts @@ -237,13 +237,10 @@ export default class AppMediaViewerBase< this.clampZoomDebounced?.clearTimeout(); }, onMouseDown: () => { - this.moversContainer.classList.add('no-transition'); - this.zoomElements.rangeSelector.container.classList.remove('with-transition'); + this.onSwipeFirst(); }, onMouseUp: () => { - this.moversContainer.classList.remove('no-transition'); - this.zoomElements.rangeSelector.container.classList.add('with-transition'); - this.setZoomValue(); + this.onSwipeReset(); } }); @@ -429,10 +426,10 @@ export default class AppMediaViewerBase< }); } - protected onSwipeFirst = (e: MouseEvent | TouchEvent | WheelEvent) => { + protected onSwipeFirst = (e?: MouseEvent | TouchEvent | WheelEvent) => { this.lastDragOffset = this.lastDragDelta = {x: 0, y: 0}; this.lastTransform = {...this.transform}; - if(e.type !== 'wheel' || !this.ctrlKeyDown) { // keep transition for real mouse wheel + if(e?.type !== 'wheel' || !this.ctrlKeyDown) { // keep transition for real mouse wheel this.moversContainer.classList.add('no-transition'); this.zoomElements.rangeSelector.container.classList.remove('with-transition'); } diff --git a/src/components/audio.ts b/src/components/audio.ts index b54d4cc3..8b7edc80 100644 --- a/src/components/audio.ts +++ b/src/components/audio.ts @@ -225,9 +225,7 @@ async function wrapVoiceMessage(audioEl: AudioElement) { let progress = svg as any as HTMLElement, progressLine: MediaProgressLine; if(!progress) { - progressLine = new MediaProgressLine({ - streamable: doc.supportsStreaming - }); + progressLine = new MediaProgressLine(); waveformContainer.append(progressLine.container); } @@ -306,7 +304,11 @@ async function wrapVoiceMessage(audioEl: AudioElement) { } }, noop); - !progress && progressLine.setMedia(audio); + !progress && progressLine.setMedia({ + media: audio, + streamable: doc.supportsStreaming, + duration: doc.duration + }); return () => { progress?.remove(); @@ -381,9 +383,11 @@ async function wrapAudio(audioEl: AudioElement) { const onLoad = () => { let launched = false; - let progressLine = new MediaProgressLine({ + let progressLine = new MediaProgressLine(); + progressLine.setMedia({ media: audioEl.audio, - streamable: doc.supportsStreaming + streamable: doc.supportsStreaming, + duration: doc.duration }); audioEl.addAudioListener('ended', () => { @@ -760,18 +764,20 @@ export default class AudioElement extends HTMLElement { } public playWithTimestamp(timestamp: number) { - this.load?.(true, true); - appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio - this.readyPromise.then(() => { - if(appMediaPlaybackController.willBePlayedMedia !== this.audio && this.audio.paused) { - return; - } + this.load?.(true); + this.audio.currentTime = timestamp; + this.togglePlay(undefined, true); + // appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio + // this.readyPromise.then(() => { + // if(appMediaPlaybackController.willBePlayedMedia !== this.audio && this.audio.paused) { + // return; + // } - appMediaPlaybackController.willBePlayed(undefined); + // appMediaPlaybackController.willBePlayed(undefined); - this.audio.currentTime = timestamp; - this.togglePlay(undefined, true); - }); + // this.audio.currentTime = timestamp; + // this.togglePlay(undefined, true); + // }); } get addAudioListener() { diff --git a/src/components/chat/audio.ts b/src/components/chat/audio.ts index eb39990e..eec3a796 100644 --- a/src/components/chat/audio.ts +++ b/src/components/chat/audio.ts @@ -111,8 +111,6 @@ export default class ChatAudio extends PinnedContainer { progressWrapper.classList.add('pinned-audio-progress-wrapper'); this.progressLine = new MediaProgressLine({ - media: undefined, - streamable: undefined, withTransition: true, useTransform: true }); @@ -174,7 +172,10 @@ export default class ChatAudio extends PinnedContainer { this.onPlaybackParams(playbackParams); this.volumeSelector.setVolume(); - this.progressLine.setMedia(media); + this.progressLine.setMedia({ + media, + duration: doc.duration + }); this.fill(title, subtitle, message); // this.toggleEl.classList.add('flip-icon'); diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 99c7d284..798a2ec1 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -3370,9 +3370,12 @@ export default class ChatBubbles { savedPosition: ChatSavedPosition, samePeer: boolean }) { - const middleware = this.getMiddleware(); const peerId = this.peerId; + if(peerId.isUser()) { + return; + } + const middleware = this.getMiddleware(); const needFetchInterval = await this.managers.appMessagesManager.isFetchIntervalNeeded(peerId); const needFetchNew = savedPosition || needFetchInterval; if(!needFetchNew) { @@ -3934,7 +3937,7 @@ export default class ChatBubbles { customEmojiSize ??= this.chat.appImManager.customEmojiSize; - const maxMediaTimestamp = needToSetHTML && getMediaDurationFromMessage(albumTextMessage || message as Message.message); + const maxMediaTimestamp = getMediaDurationFromMessage(albumTextMessage || message as Message.message); if(albumTextMessage && needToSetHTML) { bubble.dataset.textMid = '' + albumTextMessage.mid; } diff --git a/src/components/mediaProgressLine.ts b/src/components/mediaProgressLine.ts index 973a679b..4b9f26cf 100644 --- a/src/components/mediaProgressLine.ts +++ b/src/components/mediaProgressLine.ts @@ -20,13 +20,11 @@ export default class MediaProgressLine extends RangeSelector { // protected lastOnPlayCurrentTime: number; constructor(protected options: { - media?: HTMLAudioElement | HTMLVideoElement, - streamable?: boolean, withTransition?: boolean, useTransform?: boolean, onSeekStart?: () => void, onSeekEnd?: () => void - }) { + } = {}) { super({ step: 1000 / 60 / 1000, min: 0, @@ -34,13 +32,17 @@ export default class MediaProgressLine extends RangeSelector { withTransition: options.withTransition, useTransform: options.useTransform }, 0); - - if(options.media) { - this.setMedia(options.media, options.streamable); - } } - public setMedia(media: HTMLMediaElement, streamable = false) { + public setMedia({ + media, + streamable, + duration + }: { + media: HTMLMediaElement, + streamable?: boolean, + duration?: number + }) { if(this.media) { this.removeListeners(); } @@ -61,7 +63,7 @@ export default class MediaProgressLine extends RangeSelector { } let wasPlaying = false; - this.setSeekMax(); + this.setSeekMax(duration); this.setListeners(); this.setHandlers({ onMouseDown: () => { @@ -79,8 +81,7 @@ export default class MediaProgressLine extends RangeSelector { } protected onLoadedData = () => { - this.max = this.media.duration; - this.seek.setAttribute('max', '' + this.max); + this.setSeekMax(); }; protected onEnded = () => { @@ -148,15 +149,16 @@ export default class MediaProgressLine extends RangeSelector { // console.log('onProgress correct range:', nearestStart, end, this.media); - const percents = this.media.duration ? end / this.media.duration : 0; + const percents = this.max ? end / this.max : 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(); + protected setSeekMax(duration?: number) { + const realDuration = this.media.duration || 0; + if(duration === undefined || realDuration) duration = realDuration; + if(this.max = duration) { + this.seek.setAttribute('max', '' + this.max); } else { this.media.addEventListener('loadeddata', this.onLoadedData); } diff --git a/src/components/sidebarLeft/tabs/dataAndStorage.ts b/src/components/sidebarLeft/tabs/dataAndStorage.ts index 1c5817a3..30176344 100644 --- a/src/components/sidebarLeft/tabs/dataAndStorage.ts +++ b/src/components/sidebarLeft/tabs/dataAndStorage.ts @@ -21,7 +21,6 @@ import {SliderSuperTabEventable, SliderSuperTabEventableConstructable} from '../ import AppAutoDownloadFileTab from './autoDownload/file'; import AppAutoDownloadPhotoTab from './autoDownload/photo'; import AppAutoDownloadVideoTab from './autoDownload/video'; -import apiManagerProxy from '../../../lib/mtproto/mtprotoworker'; import SettingSection from '../../settingSection'; const AUTO_DOWNLOAD_FOR_KEYS: {[k in keyof AutoDownloadPeerTypeSettings]: LangPackKey} = { @@ -32,18 +31,16 @@ const AUTO_DOWNLOAD_FOR_KEYS: {[k in keyof AutoDownloadPeerTypeSettings]: LangPa }; export default class AppDataAndStorageTab extends SliderSuperTabEventable { - public async init() { + public init() { this.setTitle('DataSettings'); { const section = new SettingSection({name: 'AutomaticMediaDownload', caption: 'AutoDownloadAudioInfo'}); - const state = await apiManagerProxy.getState(); - const autoCheckboxField = new CheckboxField({ text: 'AutoDownloadMedia', name: 'auto', - checked: !state.settings.autoDownloadNew.pFlags.disabled, + checked: !rootScope.settings.autoDownloadNew.pFlags.disabled, listenerSetter: this.listenerSetter }); @@ -54,14 +51,14 @@ export default class AppDataAndStorageTab extends SliderSuperTabEventable { const onChange = () => { toggleDisability([resetButton], - deepEqual(state.settings.autoDownload, STATE_INIT.settings.autoDownload) && - deepEqual(state.settings.autoDownloadNew, STATE_INIT.settings.autoDownloadNew)); + deepEqual(rootScope.settings.autoDownload, STATE_INIT.settings.autoDownload) && + deepEqual(rootScope.settings.autoDownloadNew, STATE_INIT.settings.autoDownloadNew)); }; const setSubtitles = () => { - this.setAutoDownloadSubtitle(photoRow, state.settings.autoDownload.photo /* state.settings.autoDownloadNew.photo_size_max */); - this.setAutoDownloadSubtitle(videoRow, state.settings.autoDownload.video/* , state.settings.autoDownloadNew.video_size_max */); - this.setAutoDownloadSubtitle(fileRow, state.settings.autoDownload.file, state.settings.autoDownloadNew.file_size_max); + this.setAutoDownloadSubtitle(photoRow, rootScope.settings.autoDownload.photo /* state.settings.autoDownloadNew.photo_size_max */); + this.setAutoDownloadSubtitle(videoRow, rootScope.settings.autoDownload.video/* , state.settings.autoDownloadNew.video_size_max */); + this.setAutoDownloadSubtitle(fileRow, rootScope.settings.autoDownload.file, rootScope.settings.autoDownloadNew.file_size_max); }; const openTab = (tabConstructor: SliderSuperTabEventableConstructable) => { @@ -113,29 +110,29 @@ export default class AppDataAndStorageTab extends SliderSuperTabEventable { const settings = rootScope.settings; settings.autoDownloadNew = copy(STATE_INIT.settings.autoDownloadNew); settings.autoDownload = copy(STATE_INIT.settings.autoDownload); - state.settings = settings; + rootScope.settings = settings; this.managers.appStateManager.setByKey('settings', settings); setSubtitles(); - autoCheckboxField.checked = !state.settings.autoDownloadNew.pFlags.disabled; + autoCheckboxField.checked = !rootScope.settings.autoDownloadNew.pFlags.disabled; }); }); const onDisabledChange = () => { const disabled = !autoCheckboxField.checked; - const settings = rootScope.settings; + const autoDownloadNew = rootScope.settings.autoDownloadNew; if(disabled) { - settings.autoDownloadNew.pFlags.disabled = true; + autoDownloadNew.pFlags.disabled = true; } else { - delete settings.autoDownloadNew.pFlags.disabled; + delete autoDownloadNew.pFlags.disabled; } [photoRow, videoRow, fileRow].forEach((row) => { row.container.classList.toggle('is-disabled', disabled); }); - this.managers.appStateManager.setByKey('settings', settings); + this.managers.appStateManager.setByKey('settings.autoDownloadNew', autoDownloadNew); onChange(); }; diff --git a/src/lib/files/cacheStorage.ts b/src/lib/files/cacheStorage.ts index 22c686ea..90eba674 100644 --- a/src/lib/files/cacheStorage.ts +++ b/src/lib/files/cacheStorage.ts @@ -57,9 +57,9 @@ export default class CacheStorageController implements FileStorage { } public getFile(fileName: string, method: 'blob' | 'json' | 'text' = 'blob'): Promise { - /* if(method === 'blob') { - return Promise.reject(); - } */ + // if(method === 'blob') { + // return Promise.reject(makeError('NO_ENTRY_FOUND')); + // } // const str = `get fileName: ${fileName}`; // console.time(str); diff --git a/src/lib/mediaPlayer.ts b/src/lib/mediaPlayer.ts index 2548f6e5..4e8e69c4 100644 --- a/src/lib/mediaPlayer.ts +++ b/src/lib/mediaPlayer.ts @@ -41,7 +41,15 @@ export default class VideoPlayer extends ControlsHover { protected onPip?: (pip: boolean) => void; protected onPipClose?: () => void; - constructor({video, play = false, streamable = false, duration, onPlaybackRackMenuToggle, onPip, onPipClose}: { + constructor({ + video, + play = false, + streamable = false, + duration, + onPlaybackRackMenuToggle, + onPip, + onPipClose + }: { video: HTMLVideoElement, play?: boolean, streamable?: boolean, @@ -83,8 +91,6 @@ export default class VideoPlayer extends ControlsHover { if(this.skin === 'default') { const controls = this.wrapper.querySelector('.default__controls.ckin__controls') as HTMLDivElement; this.progress = new MediaProgressLine({ - media: video, - streamable, onSeekStart: () => { this.wrapper.classList.add('is-seeking'); }, @@ -92,6 +98,11 @@ export default class VideoPlayer extends ControlsHover { this.wrapper.classList.remove('is-seeking'); } }); + this.progress.setMedia({ + media: video, + streamable, + duration + }); controls.prepend(this.progress.container); }