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