Lightbox: A number of tweaks

This commit is contained in:
Scott Nonnenberg 2021-09-07 09:12:26 -07:00 committed by GitHub
parent 82f1920ce2
commit c6278aa173
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 47 deletions

View file

@ -473,7 +473,7 @@ try {
); );
const link = e.target.closest('a'); const link = e.target.closest('a');
const selection = Boolean(window.getSelection().toString()); const selection = Boolean(window.getSelection().toString());
const image = e.target.closest('.module-lightbox img'); const image = e.target.closest('.Lightbox img');
if (!editable && !selection && !link && !image) { if (!editable && !selection && !link && !image) {
e.preventDefault(); e.preventDefault();
} }

View file

@ -1237,7 +1237,7 @@ export async function startApp(): Promise<void> {
return; return;
} }
const lightBox = document.querySelector('.module-lightbox'); const lightBox = document.querySelector('.Lightbox');
if (lightBox) { if (lightBox) {
return; return;
} }

View file

@ -2,7 +2,6 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import React, { import React, {
MouseEvent,
ReactNode, ReactNode,
useCallback, useCallback,
useEffect, useEffect,
@ -64,15 +63,31 @@ export function Lightbox({
const containerRef = useRef<HTMLDivElement | null>(null); const containerRef = useRef<HTMLDivElement | null>(null);
const [focusRef] = useRestoreFocus(); const [focusRef] = useRestoreFocus();
const onPrevious = useCallback(() => { const onPrevious = useCallback(
setSelectedIndex(prevSelectedIndex => Math.max(prevSelectedIndex - 1, 0)); (
}, []); event: KeyboardEvent | React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.preventDefault();
event.stopPropagation();
const onNext = useCallback(() => { setSelectedIndex(prevSelectedIndex => Math.max(prevSelectedIndex - 1, 0));
setSelectedIndex(prevSelectedIndex => },
Math.min(prevSelectedIndex + 1, media.length - 1) []
); );
}, [media]);
const onNext = useCallback(
(
event: KeyboardEvent | React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.preventDefault();
event.stopPropagation();
setSelectedIndex(prevSelectedIndex =>
Math.min(prevSelectedIndex + 1, media.length - 1)
);
},
[media]
);
const onTimeUpdate = useCallback(() => { const onTimeUpdate = useCallback(() => {
if (!videoElement) { if (!videoElement) {
@ -81,14 +96,24 @@ export function Lightbox({
setVideoTime(videoElement.currentTime); setVideoTime(videoElement.currentTime);
}, [setVideoTime, videoElement]); }, [setVideoTime, videoElement]);
const handleSave = () => { const handleSave = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.stopPropagation();
event.preventDefault();
const mediaItem = media[selectedIndex]; const mediaItem = media[selectedIndex];
const { attachment, message, index } = mediaItem; const { attachment, message, index } = mediaItem;
onSave?.({ attachment, message, index }); onSave?.({ attachment, message, index });
}; };
const handleForward = () => { const handleForward = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.preventDefault();
event.stopPropagation();
close(); close();
const mediaItem = media[selectedIndex]; const mediaItem = media[selectedIndex];
onForward?.(mediaItem.message.id); onForward?.(mediaItem.message.id);
@ -98,11 +123,7 @@ export function Lightbox({
(event: KeyboardEvent) => { (event: KeyboardEvent) => {
switch (event.key) { switch (event.key) {
case 'Escape': case 'Escape':
if (zoomed) { close();
setZoomed(false);
} else {
close();
}
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -110,31 +131,23 @@ export function Lightbox({
break; break;
case 'ArrowLeft': case 'ArrowLeft':
if (onPrevious) { onPrevious(event);
onPrevious();
event.preventDefault();
event.stopPropagation();
}
break; break;
case 'ArrowRight': case 'ArrowRight':
if (onNext) { onNext(event);
onNext();
event.preventDefault();
event.stopPropagation();
}
break; break;
default: default:
} }
}, },
[close, onNext, onPrevious, zoomed] [close, onNext, onPrevious]
); );
const stopPropagationAndClose = (event: MouseEvent<HTMLElement>) => { const onClose = (event: React.MouseEvent<HTMLElement>) => {
event.stopPropagation(); event.stopPropagation();
event.preventDefault();
close(); close();
}; };
@ -173,7 +186,7 @@ export function Lightbox({
const { attachment, contentType, loop = false, objectURL, message } = const { attachment, contentType, loop = false, objectURL, message } =
media[selectedIndex] || {}; media[selectedIndex] || {};
const isAttachmentGIF = isGIF([attachment]); const isAttachmentGIF = isGIF(attachment ? [attachment] : undefined);
useEffect(() => { useEffect(() => {
playVideo(); playVideo();
@ -211,13 +224,20 @@ export function Lightbox({
content = ( content = (
<button <button
className="Lightbox__zoom-button" className="Lightbox__zoom-button"
onClick={() => setZoomed(!zoomed)} onClick={(
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.preventDefault();
event.stopPropagation();
setZoomed(!zoomed);
}}
type="button" type="button"
> >
<img <img
alt={i18n('lightboxImageAlt')} alt={i18n('lightboxImageAlt')}
className="Lightbox__object" className="Lightbox__object"
onContextMenu={(event: MouseEvent<HTMLImageElement>) => { onContextMenu={(event: React.MouseEvent<HTMLImageElement>) => {
// These are the only image types supported by Electron's NativeImage // These are the only image types supported by Electron's NativeImage
if ( if (
event && event &&
@ -240,7 +260,7 @@ export function Lightbox({
Lightbox__unsupported: true, Lightbox__unsupported: true,
'Lightbox__unsupported--missing': true, 'Lightbox__unsupported--missing': true,
})} })}
onClick={stopPropagationAndClose} onClick={onClose}
type="button" type="button"
/> />
); );
@ -269,7 +289,7 @@ export function Lightbox({
'Lightbox__unsupported--image': isUnsupportedImageType, 'Lightbox__unsupported--image': isUnsupportedImageType,
'Lightbox__unsupported--video': isUnsupportedVideoType, 'Lightbox__unsupported--video': isUnsupportedVideoType,
})} })}
onClick={stopPropagationAndClose} onClick={onClose}
type="button" type="button"
/> />
); );
@ -280,7 +300,7 @@ export function Lightbox({
<button <button
aria-label={i18n('unsupportedAttachment')} aria-label={i18n('unsupportedAttachment')}
className="Lightbox__object Lightbox__unsupported Lightbox__unsupported--file" className="Lightbox__object Lightbox__unsupported Lightbox__unsupported--file"
onClick={stopPropagationAndClose} onClick={onClose}
type="button" type="button"
/> />
); );
@ -294,10 +314,10 @@ export function Lightbox({
? createPortal( ? createPortal(
<div <div
className="Lightbox Lightbox__container" className="Lightbox Lightbox__container"
onClick={(event: MouseEvent<HTMLDivElement>) => { onClick={(event: React.MouseEvent<HTMLDivElement>) => {
if (containerRef && event.target !== containerRef.current) { event.stopPropagation();
return; event.preventDefault();
}
close(); close();
}} }}
onKeyUp={(event: React.KeyboardEvent<HTMLDivElement>) => { onKeyUp={(event: React.KeyboardEvent<HTMLDivElement>) => {
@ -411,7 +431,14 @@ export function Lightbox({
})} })}
key={item.thumbnailObjectUrl} key={item.thumbnailObjectUrl}
type="button" type="button"
onClick={() => setSelectedIndex(index)} onClick={(
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
event.stopPropagation();
event.preventDefault();
setSelectedIndex(index);
}}
> >
{item.thumbnailObjectUrl ? ( {item.thumbnailObjectUrl ? (
<img <img

View file

@ -5836,7 +5836,7 @@ async function removeKnownStickers(
); );
const chunkSize = 50; const chunkSize = 50;
const total = getStickerCount(); const total = await getStickerCount();
console.log( console.log(
`removeKnownStickers: About to iterate through ${total} stickers` `removeKnownStickers: About to iterate through ${total} stickers`
); );

View file

@ -1357,7 +1357,7 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
if (element) { if (element) {
toast.$el.appendTo(element); toast.$el.appendTo(element);
} else { } else {
const lightboxEl = $('.module-lightbox'); const lightboxEl = $('.Lightbox');
if (lightboxEl.length > 0) { if (lightboxEl.length > 0) {
toast.$el.appendTo(lightboxEl); toast.$el.appendTo(lightboxEl);
} else { } else {
@ -2464,8 +2464,19 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
await message.retrySend(); await message.retrySend();
} }
showForwardMessageModal(messageId: string): void { async showForwardMessageModal(messageId: string): Promise<void> {
const message = window.MessageController.getById(messageId); const messageFromCache = window.MessageController.getById(messageId);
if (!messageFromCache) {
window.log.info(
'showForwardMessageModal: Fetching message from database'
);
}
const message =
messageFromCache ||
(await window.Signal.Data.getMessageById(messageId, {
Message: window.Whisper.Message,
}));
if (!message) { if (!message) {
throw new Error(`showForwardMessageModal: Message ${messageId} missing!`); throw new Error(`showForwardMessageModal: Message ${messageId} missing!`);
} }