Lightbox: A number of tweaks
This commit is contained in:
parent
82f1920ce2
commit
c6278aa173
5 changed files with 85 additions and 47 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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`
|
||||||
);
|
);
|
||||||
|
|
|
@ -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!`);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue