Fix audio player content overflow with sidebar
Always display .gif as video Restrict jumping from webpage media to regular Fix displaying round video in webpage
This commit is contained in:
parent
d7d4f67b0f
commit
1a39932068
@ -360,7 +360,7 @@ class AppMediaPlaybackController {
|
||||
private async setNewMediadata(message: Message.message, playingMedia = this.playingMedia) {
|
||||
await onMediaLoad(playingMedia, undefined, false); // have to wait for load, otherwise on macOS won't set
|
||||
|
||||
const doc = (message.media as MessageMedia.messageMediaDocument).document as MyDocument;
|
||||
const doc = appMessagesManager.getMediaFromMessage(message) as MyDocument;
|
||||
|
||||
const artwork: MediaImage[] = [];
|
||||
|
||||
@ -624,7 +624,7 @@ class AppMediaPlaybackController {
|
||||
|
||||
public previous = () => {
|
||||
const media = this.playingMedia;
|
||||
if(media && media.currentTime > 5) {
|
||||
if(media && (media.currentTime > 5 || !this.listLoader.previous.length)) {
|
||||
media.currentTime = 0;
|
||||
this.toggle(true);
|
||||
return;
|
||||
|
@ -28,6 +28,7 @@ import htmlToSpan from "../helpers/dom/htmlToSpan";
|
||||
import { formatFullSentTime } from "../helpers/date";
|
||||
import { clamp, formatBytes } from "../helpers/number";
|
||||
import throttleWithRaf from "../helpers/schedulers/throttleWithRaf";
|
||||
import { NULL_PEER_ID } from "../lib/mtproto/mtproto_config";
|
||||
|
||||
rootScope.addEventListener('messages_media_read', ({mids, peerId}) => {
|
||||
mids.forEach(mid => {
|
||||
@ -340,20 +341,28 @@ function constructDownloadPreloader(tryAgainOnFail = true) {
|
||||
return preloader;
|
||||
}
|
||||
|
||||
export const findAudioTargets = (anchor: HTMLElement, useSearch: boolean) => {
|
||||
export const findMediaTargets = (anchor: HTMLElement/* , useSearch: boolean */) => {
|
||||
let prev: MediaItem[], next: MediaItem[];
|
||||
// if(anchor.classList.contains('search-super-item') || !useSearch) {
|
||||
const container = findUpClassName(anchor, anchor.classList.contains('search-super-item') ? 'tabs-tab' : 'bubbles-inner');
|
||||
const isBubbles = !anchor.classList.contains('search-super-item');
|
||||
const container = findUpClassName(anchor, !isBubbles ? 'tabs-tab' : 'bubbles-inner');
|
||||
if(container) {
|
||||
const attr = `:not([data-is-outgoing="1"])`;
|
||||
const justAudioSelector = `.audio:not(.is-voice)${attr}`;
|
||||
let selector: string;
|
||||
let selectors: string[];
|
||||
if(!anchor.matches(justAudioSelector)) {
|
||||
selector = `.audio.is-voice${attr}, .media-round${attr}`;
|
||||
selectors = [`.audio.is-voice${attr}`, `.media-round${attr}`];
|
||||
} else {
|
||||
selector = justAudioSelector;
|
||||
selectors = [justAudioSelector];
|
||||
}
|
||||
|
||||
if(isBubbles) {
|
||||
const prefix = '.bubble:not(.webpage) ';
|
||||
selectors = selectors.map(s => prefix + s);
|
||||
}
|
||||
|
||||
const selector = selectors.join(', ');
|
||||
|
||||
const elements = Array.from(container.querySelectorAll(selector)) as HTMLElement[];
|
||||
const idx = elements.indexOf(anchor);
|
||||
|
||||
@ -454,8 +463,13 @@ export default class AudioElement extends HTMLElement {
|
||||
e && cancelEvent(e);
|
||||
|
||||
if(paused) {
|
||||
if(appMediaPlaybackController.setSearchContext(this.searchContext)) {
|
||||
const [prev, next] = findAudioTargets(this, this.searchContext.useSearch);
|
||||
const hadSearchContext = !!this.searchContext;
|
||||
if(appMediaPlaybackController.setSearchContext(this.searchContext || {
|
||||
peerId: NULL_PEER_ID,
|
||||
inputFilter: {_: 'inputMessagesFilterEmpty'},
|
||||
useSearch: false
|
||||
})) {
|
||||
const [prev, next] = !hadSearchContext ? [] : findMediaTargets(this/* , this.searchContext.useSearch */);
|
||||
appMediaPlaybackController.setTargets({peerId: this.message.peerId, mid: this.message.mid}, prev, next);
|
||||
}
|
||||
|
||||
|
@ -1042,6 +1042,9 @@ export default class ChatBubbles {
|
||||
return;
|
||||
}
|
||||
|
||||
const SINGLE_MEDIA_CLASSNAME = 'webpage';
|
||||
const isSingleMedia = bubble.classList.contains(SINGLE_MEDIA_CLASSNAME);
|
||||
|
||||
const f = documentDiv ? (media: any) => {
|
||||
return AppMediaViewer.isMediaCompatibleForDocumentViewer(media);
|
||||
} : (media: any) => {
|
||||
@ -1049,7 +1052,10 @@ export default class ChatBubbles {
|
||||
};
|
||||
|
||||
const targets: {element: HTMLElement, mid: number, peerId: PeerId}[] = [];
|
||||
const ids = Object.keys(this.bubbles).map(k => +k).filter(id => {
|
||||
const ids = isSingleMedia ? [messageId] : Object.keys(this.bubbles).map(k => +k).filter(id => {
|
||||
/* if(isSingleMedia && !this.bubbles[id].classList.contains(SINGLE_MEDIA_CLASSNAME)) {
|
||||
return false;
|
||||
} */
|
||||
//if(!this.scrollable.visibleElements.find(e => e.element === this.bubbles[id])) return false;
|
||||
|
||||
const message = this.chat.getMessage(id);
|
||||
@ -1117,7 +1123,7 @@ export default class ChatBubbles {
|
||||
threadId: this.chat.threadId,
|
||||
peerId: this.peerId,
|
||||
inputFilter: {_: documentDiv ? 'inputMessagesFilterDocument' : 'inputMessagesFilterPhotoVideo'},
|
||||
useSearch: this.chat.type !== 'scheduled',
|
||||
useSearch: this.chat.type !== 'scheduled' && !isSingleMedia,
|
||||
isScheduled: this.chat.type === 'scheduled'
|
||||
})
|
||||
.openMedia(message, targets[idx].element, 0, true, targets.slice(0, idx), targets.slice(idx + 1));
|
||||
@ -2707,15 +2713,21 @@ export default class ChatBubbles {
|
||||
|
||||
const doc = webpage.document as MyDocument;
|
||||
if(doc) {
|
||||
if(doc.type === 'gif' || doc.type === 'video') {
|
||||
if(doc.type === 'gif' || doc.type === 'video' || doc.type === 'round') {
|
||||
//if(doc.size <= 20e6) {
|
||||
bubble.classList.add('video');
|
||||
const mediaSize = doc.type === 'round' ? mediaSizes.active.round : mediaSizes.active.webpage;
|
||||
if(doc.type === 'round') {
|
||||
bubble.classList.add('round');
|
||||
preview.classList.add('is-round');
|
||||
} else {
|
||||
bubble.classList.add('video');
|
||||
}
|
||||
wrapVideo({
|
||||
doc,
|
||||
container: preview,
|
||||
message,
|
||||
boxWidth: mediaSizes.active.webpage.width,
|
||||
boxHeight: mediaSizes.active.webpage.height,
|
||||
boxWidth: mediaSize.width,
|
||||
boxHeight: mediaSize.height,
|
||||
lazyLoadQueue: this.lazyLoadQueue,
|
||||
middleware: this.getMiddleware(),
|
||||
isOut,
|
||||
|
@ -89,10 +89,10 @@ export default class PinnedContainer {
|
||||
return;
|
||||
}
|
||||
|
||||
const scrollable = this.chat.bubbles.scrollable;
|
||||
// const scrollable = this.chat.bubbles.scrollable;
|
||||
|
||||
const isFloating = (this.floating || mediaSizes.isMobile) && !hide;
|
||||
const scrollTop = isFloating || this.divAndCaption.container.classList.contains('is-floating') ? scrollable.scrollTop : undefined;
|
||||
// const scrollTop = isFloating || this.divAndCaption.container.classList.contains('is-floating') ? scrollable.scrollTop : undefined;
|
||||
|
||||
this.divAndCaption.container.classList.toggle('is-floating', isFloating);
|
||||
this.divAndCaption.container.classList.toggle('hide', hide);
|
||||
@ -100,12 +100,13 @@ export default class PinnedContainer {
|
||||
this.topbar.container.classList.toggle('is-pinned-floating', isFloating);
|
||||
this.topbar.container.classList.toggle(`is-pinned-${this.className}-shown`, !hide);
|
||||
|
||||
const active = classNames.filter(className => this.topbar.container.classList.contains(className));
|
||||
const maxActive = hide ? 0 : 1;
|
||||
// const active = classNames.filter(className => this.topbar.container.classList.contains(className));
|
||||
// const maxActive = hide ? 0 : 1;
|
||||
|
||||
if(scrollTop !== undefined && active.length <= maxActive/* && !scrollable.isScrolledDown */) {
|
||||
scrollable.scrollTop = scrollTop + ((hide ? -1 : 1) * HEIGHT);
|
||||
}
|
||||
// * not sure when it became unneeded
|
||||
// if(scrollTop !== undefined && active.length <= maxActive/* && !scrollable.isScrolledDown */) {
|
||||
// scrollable.scrollTop = scrollTop + ((hide ? -1 : 1) * HEIGHT);
|
||||
// }
|
||||
|
||||
this.topbar.setFloating();
|
||||
this.topbar.setUtilsWidth();
|
||||
|
@ -728,7 +728,7 @@ export default class ChatTopbar {
|
||||
void this.chatInfo.offsetLeft; // reflow */
|
||||
const width = /* chatUtils.scrollWidth */this.chatUtils.getBoundingClientRect().width;
|
||||
this.chat.log('utils width:', width);
|
||||
this.chatInfo.style.setProperty('--utils-width', width + 'px');
|
||||
this.container.style.setProperty('--utils-width', width + 'px');
|
||||
//this.chatInfo.classList.toggle('have-utils-width', !!width);
|
||||
//}, 0);
|
||||
|
||||
|
@ -20,7 +20,7 @@ import LottieLoader from '../lib/lottieLoader';
|
||||
import webpWorkerController from '../lib/webp/webpWorkerController';
|
||||
import animationIntersector from './animationIntersector';
|
||||
import appMediaPlaybackController, { MediaSearchContext } from './appMediaPlaybackController';
|
||||
import AudioElement, { findAudioTargets as findMediaTargets } from './audio';
|
||||
import AudioElement, { findMediaTargets } from './audio';
|
||||
import ReplyContainer from './chat/replyContainer';
|
||||
import { Layouter, RectPart } from './groupedLayout';
|
||||
import LazyLoadQueue from './lazyLoadQueue';
|
||||
@ -29,7 +29,6 @@ import ProgressivePreloader from './preloader';
|
||||
import './middleEllipsis';
|
||||
import RichTextProcessor from '../lib/richtextprocessor';
|
||||
import appImManager from '../lib/appManagers/appImManager';
|
||||
import { SearchSuperContext } from './appSearchSuper.';
|
||||
import rootScope from '../lib/rootScope';
|
||||
import { onMediaLoad } from '../helpers/files';
|
||||
import { animateSingle } from '../helpers/animation';
|
||||
@ -49,6 +48,7 @@ import MEDIA_MIME_TYPES_SUPPORTED from '../environment/mediaMimeTypesSupport';
|
||||
import { MiddleEllipsisElement } from './middleEllipsis';
|
||||
import { joinElementsWith } from '../lib/langPack';
|
||||
import throttleWithRaf from '../helpers/schedulers/throttleWithRaf';
|
||||
import { NULL_PEER_ID } from '../lib/mtproto/mtproto_config';
|
||||
|
||||
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
|
||||
|
||||
@ -305,8 +305,13 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai
|
||||
} */
|
||||
|
||||
if(globalVideo.paused) {
|
||||
if(appMediaPlaybackController.setSearchContext(searchContext)) {
|
||||
const [prev, next] = findMediaTargets(divRound, searchContext.useSearch);
|
||||
const hadSearchContext = !!searchContext;
|
||||
if(appMediaPlaybackController.setSearchContext(searchContext || {
|
||||
peerId: NULL_PEER_ID,
|
||||
inputFilter: {_: 'inputMessagesFilterEmpty'},
|
||||
useSearch: false
|
||||
})) {
|
||||
const [prev, next] = !hadSearchContext ? [] : findMediaTargets(divRound/* , searchContext.useSearch */);
|
||||
appMediaPlaybackController.setTargets({peerId: message.peerId, mid: message.mid}, prev, next);
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,10 @@ export type MyDocument = Document.document;
|
||||
|
||||
// TODO: если залить картинку файлом, а потом перезайти в диалог - превьюшка заново скачается
|
||||
|
||||
const EXTENSION_MIME_TYPE_MAP: {[key: string]: string} = {
|
||||
mov: 'video/quicktime'
|
||||
const EXTENSION_MIME_TYPE_MAP = {
|
||||
mov: 'video/quicktime',
|
||||
gif: 'image/gif',
|
||||
pdf: 'application/pdf',
|
||||
};
|
||||
|
||||
export class AppDocsManager {
|
||||
@ -163,6 +165,7 @@ export class AppDocsManager {
|
||||
|
||||
if(!doc.mime_type) {
|
||||
const ext = (doc.file_name || '').split('.').pop();
|
||||
// @ts-ignore
|
||||
const mappedMimeType = ext && EXTENSION_MIME_TYPE_MAP[ext.toLowerCase()];
|
||||
if(mappedMimeType) {
|
||||
doc.mime_type = mappedMimeType;
|
||||
@ -187,8 +190,10 @@ export class AppDocsManager {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(doc.mime_type === 'application/pdf') {
|
||||
} else if(doc.mime_type === EXTENSION_MIME_TYPE_MAP.pdf) {
|
||||
doc.type = 'pdf';
|
||||
} else if(doc.mime_type === EXTENSION_MIME_TYPE_MAP.gif) {
|
||||
doc.type = 'gif';
|
||||
}
|
||||
|
||||
if(doc.type === 'voice' || doc.type === 'round') {
|
||||
|
@ -3696,7 +3696,7 @@ export class AppMessagesManager {
|
||||
|
||||
const foundCount: number = searchResult.count || (foundMsgs.length + searchResult.messages.length);
|
||||
|
||||
searchResult.messages.forEach((message: any) => {
|
||||
searchResult.messages.forEach((message: MyMessage) => {
|
||||
const peerId = this.getMessagePeer(message);
|
||||
if(peerId.isAnyChat()) {
|
||||
const chat: Chat.chat = appChatsManager.getChat(peerId.toChatId());
|
||||
|
@ -597,12 +597,12 @@ $bubble-beside-button-width: 38px;
|
||||
max-height: var(--round-video-size) !important;
|
||||
width: var(--round-video-size) !important;
|
||||
height: var(--round-video-size) !important;
|
||||
}
|
||||
|
||||
.media-photo,
|
||||
.media-video {
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.media-photo,
|
||||
.media-video {
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@ -922,6 +922,13 @@ $bubble-beside-button-width: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-round {
|
||||
.media-photo,
|
||||
.media-video {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-text {
|
||||
|
@ -285,6 +285,12 @@
|
||||
|
||||
.pinned-container-content {
|
||||
margin-right: .5rem;
|
||||
|
||||
@include respond-to(medium-screens) {
|
||||
body.is-right-column-shown & {
|
||||
padding-right: var(--right-column-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* &:before {
|
||||
|
Loading…
x
Reference in New Issue
Block a user