Media spoilers in shared media
This commit is contained in:
parent
e207ea088f
commit
5d7dbbab77
|
@ -74,6 +74,7 @@ import wrapDocument from './wrappers/document';
|
|||
import wrapPhoto from './wrappers/photo';
|
||||
import wrapVideo from './wrappers/video';
|
||||
import noop from '../helpers/noop';
|
||||
import wrapMediaSpoiler, {onMediaSpoilerClick} from './wrappers/mediaSpoiler';
|
||||
|
||||
// const testScroll = false;
|
||||
|
||||
|
@ -549,6 +550,15 @@ export default class AppSearchSuper {
|
|||
return;
|
||||
}
|
||||
|
||||
const mediaSpoiler: HTMLElement = target.querySelector('.media-spoiler-container');
|
||||
if(mediaSpoiler) {
|
||||
onMediaSpoilerClick({
|
||||
event: e,
|
||||
mediaSpoiler
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
const peerId = target.dataset.peerId.toPeerId();
|
||||
|
||||
const targets = (Array.from(this.tabs[inputFilter].querySelectorAll('.' + targetClassName)) as HTMLElement[]).map((el) => {
|
||||
|
@ -666,7 +676,23 @@ export default class AppSearchSuper {
|
|||
});
|
||||
}
|
||||
|
||||
[wrapped.images.thumb, wrapped.images.full].filter(Boolean).forEach((image) => {
|
||||
if((message.media as MessageMedia.messageMediaPhoto).pFlags.spoiler) {
|
||||
const mediaSpoiler = await wrapMediaSpoiler({
|
||||
animationGroup: 'chat',
|
||||
media,
|
||||
middleware,
|
||||
width: 140,
|
||||
height: 140,
|
||||
multiply: 0.3
|
||||
});
|
||||
|
||||
div.append(mediaSpoiler);
|
||||
}
|
||||
|
||||
[
|
||||
wrapped.images.thumb,
|
||||
wrapped.images.full
|
||||
].filter(Boolean).forEach((image) => {
|
||||
image.classList.add('grid-item-media');
|
||||
});
|
||||
|
||||
|
@ -1645,6 +1671,7 @@ export default class AppSearchSuper {
|
|||
}
|
||||
|
||||
public destroy() {
|
||||
this.cleanup();
|
||||
this.listenerSetter.removeAll();
|
||||
this.scrollable.destroy();
|
||||
this.swipeHandler?.removeListeners();
|
||||
|
|
|
@ -127,7 +127,7 @@ import {BatchProcessor} from '../../helpers/sortedList';
|
|||
import wrapUrl from '../../lib/richTextProcessor/wrapUrl';
|
||||
import getMessageThreadId from '../../lib/appManagers/utils/messages/getMessageThreadId';
|
||||
import wrapTopicNameButton from '../wrappers/topicNameButton';
|
||||
import wrapMediaSpoiler, {toggleMediaSpoiler} from '../wrappers/mediaSpoiler';
|
||||
import wrapMediaSpoiler, {onMediaSpoilerClick, toggleMediaSpoiler} from '../wrappers/mediaSpoiler';
|
||||
import confirmationPopup from '../confirmationPopup';
|
||||
import wrapPeerTitle from '../wrappers/peerTitle';
|
||||
import {PopupPeerCheckboxOptions} from '../popups/peer';
|
||||
|
@ -1642,24 +1642,10 @@ export default class ChatBubbles {
|
|||
|
||||
const mediaSpoiler: HTMLElement = findUpClassName(target, 'media-spoiler-container');
|
||||
if(mediaSpoiler) {
|
||||
cancelEvent(e);
|
||||
|
||||
if(mediaSpoiler.classList.contains('is-revealing')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const video = mediaSpoiler.parentElement.querySelector('video');
|
||||
if(video && !mediaSpoiler.parentElement.querySelector('.video-play')) {
|
||||
video.autoplay = true;
|
||||
video.play().catch(noop);
|
||||
}
|
||||
|
||||
toggleMediaSpoiler({
|
||||
mediaSpoiler,
|
||||
reveal: true,
|
||||
destroyAfter: true
|
||||
onMediaSpoilerClick({
|
||||
event: e,
|
||||
mediaSpoiler
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import {IS_MOBILE} from '../environment/userAgent';
|
||||
import {animate} from '../helpers/animation';
|
||||
import drawCircle, {drawCircleFromStart} from '../helpers/canvas/drawCircle';
|
||||
import {Middleware} from '../helpers/middleware';
|
||||
import clamp from '../helpers/number/clamp';
|
||||
import animationIntersector, {AnimationItemGroup, AnimationItemWrapper} from './animationIntersector';
|
||||
|
@ -32,7 +31,11 @@ export default class DotRenderer implements AnimationItemWrapper {
|
|||
|
||||
private dpr: number;
|
||||
|
||||
constructor(private width: number, private height: number) {
|
||||
constructor(
|
||||
private width: number,
|
||||
private height: number,
|
||||
private multiply?: number
|
||||
) {
|
||||
const canvas = this.canvas = document.createElement('canvas');
|
||||
const dpr = this.dpr = window.devicePixelRatio;
|
||||
canvas.width = width * dpr;
|
||||
|
@ -47,7 +50,9 @@ export default class DotRenderer implements AnimationItemWrapper {
|
|||
|
||||
private prepare() {
|
||||
let count = Math.round(this.width * this.height / (35 * (IS_MOBILE ? 2 : 1)));
|
||||
count *= this.multiply || 1;
|
||||
count = Math.min(IS_MOBILE ? 1000 : 2200, count);
|
||||
count = Math.round(count);
|
||||
const dots: DotRendererDot[] = this.dots = new Array(count);
|
||||
|
||||
for(let i = 0; i < count; ++i) {
|
||||
|
@ -151,18 +156,20 @@ export default class DotRenderer implements AnimationItemWrapper {
|
|||
width,
|
||||
height,
|
||||
middleware,
|
||||
animationGroup
|
||||
animationGroup,
|
||||
multiply
|
||||
}: {
|
||||
width: number,
|
||||
height: number,
|
||||
middleware: Middleware,
|
||||
animationGroup: AnimationItemGroup
|
||||
animationGroup: AnimationItemGroup,
|
||||
multiply?: number
|
||||
}) {
|
||||
middleware.onClean(() => {
|
||||
animationIntersector.removeAnimationByPlayer(dotRenderer);
|
||||
});
|
||||
|
||||
const dotRenderer = new DotRenderer(width, height);
|
||||
const dotRenderer = new DotRenderer(width, height, multiply);
|
||||
dotRenderer.renderFirstFrame();
|
||||
|
||||
animationIntersector.addAnimation(dotRenderer, animationGroup, dotRenderer.canvas, true);
|
||||
|
|
|
@ -16,6 +16,7 @@ export const RIGHT_COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown';
|
|||
export class AppSidebarRight extends SidebarSlider {
|
||||
private isColumnProportionSet = false;
|
||||
private sharedMediaTab: AppSharedMediaTab;
|
||||
// public rect: DOMRect;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -91,6 +92,7 @@ export class AppSidebarRight extends SidebarSlider {
|
|||
private setColumnProportion() {
|
||||
const proportion = this.sidebarEl.scrollWidth / this.sidebarEl.previousElementSibling.scrollWidth;
|
||||
document.documentElement.style.setProperty('--right-column-proportion', '' + proportion);
|
||||
// this.rect = this.sidebarEl.getBoundingClientRect();
|
||||
}
|
||||
|
||||
public toggleSidebar(enable?: boolean, animate?: boolean) {
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
import cancelEvent from '../../helpers/dom/cancelEvent';
|
||||
import getImageFromStrippedThumb from '../../helpers/getImageFromStrippedThumb';
|
||||
import {Middleware} from '../../helpers/middleware';
|
||||
import noop from '../../helpers/noop';
|
||||
import {Document, Photo, PhotoSize} from '../../layer';
|
||||
import {AnimationItemGroup} from '../animationIntersector';
|
||||
import DotRenderer from '../dotRenderer';
|
||||
import SetTransition from '../singleTransition';
|
||||
|
||||
|
@ -31,19 +31,34 @@ export function toggleMediaSpoiler(options: {
|
|||
});
|
||||
}
|
||||
|
||||
export function wrapMediaSpoilerWithImage({
|
||||
middleware,
|
||||
width,
|
||||
height,
|
||||
animationGroup,
|
||||
image
|
||||
}: {
|
||||
middleware: Middleware,
|
||||
width: number,
|
||||
height: number,
|
||||
animationGroup: AnimationItemGroup,
|
||||
image: Awaited<ReturnType<typeof getImageFromStrippedThumb>>['image']
|
||||
export function onMediaSpoilerClick(options: {
|
||||
mediaSpoiler: HTMLElement,
|
||||
event: Event
|
||||
}) {
|
||||
const {mediaSpoiler, event} = options;
|
||||
cancelEvent(event);
|
||||
|
||||
if(mediaSpoiler.classList.contains('is-revealing')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const video = mediaSpoiler.parentElement.querySelector('video');
|
||||
if(video && !mediaSpoiler.parentElement.querySelector('.video-play')) {
|
||||
video.autoplay = true;
|
||||
video.play().catch(noop);
|
||||
}
|
||||
|
||||
toggleMediaSpoiler({
|
||||
mediaSpoiler,
|
||||
reveal: true,
|
||||
destroyAfter: true
|
||||
});
|
||||
}
|
||||
|
||||
export function wrapMediaSpoilerWithImage(options: {
|
||||
image: Awaited<ReturnType<typeof getImageFromStrippedThumb>>['image']
|
||||
} & Parameters<typeof DotRenderer['create']>[0]) {
|
||||
const {middleware, image} = options;
|
||||
if(!middleware()) {
|
||||
return;
|
||||
}
|
||||
|
@ -55,10 +70,8 @@ export function wrapMediaSpoilerWithImage({
|
|||
container.middlewareHelper = middleware.create();
|
||||
|
||||
const dotRenderer = DotRenderer.create({
|
||||
width,
|
||||
height,
|
||||
middleware: container.middlewareHelper.get(),
|
||||
animationGroup
|
||||
...options,
|
||||
middleware: container.middlewareHelper.get()
|
||||
});
|
||||
|
||||
container.append(image, dotRenderer.canvas);
|
||||
|
|
|
@ -364,7 +364,7 @@
|
|||
border-radius: 4px;
|
||||
background-color: var(--message-time-background);
|
||||
padding: 0px 6px 0px 5px;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
line-height: 18px;
|
||||
|
|
Loading…
Reference in New Issue