fix: исправлено контекстное меню на Android и улучшена работа с изображениями

This commit is contained in:
kazachilo 2025-03-26 10:15:16 +03:00
parent 61a8740d37
commit 047665c07a
4 changed files with 22 additions and 3 deletions

View File

@ -7,6 +7,10 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
} }
.image { .image {
@ -14,6 +18,8 @@
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
pointer-events: none;
touch-action: none;
} }
.hidden { .hidden {

View File

@ -8,6 +8,7 @@ interface ImageWithFallbackProps {
onClick?: () => void; onClick?: () => void;
onContextMenu?: (e: React.MouseEvent<HTMLDivElement>) => void; onContextMenu?: (e: React.MouseEvent<HTMLDivElement>) => void;
maxRetries?: number; maxRetries?: number;
isDeleteMode?: boolean;
} }
const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({ const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
@ -16,7 +17,8 @@ const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
className = '', className = '',
onClick, onClick,
onContextMenu, onContextMenu,
maxRetries = 2 // По умолчанию 2 попытки автоматической перезагрузки maxRetries = 2, // По умолчанию 2 попытки автоматической перезагрузки
isDeleteMode = false
}) => { }) => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(false); const [error, setError] = useState(false);
@ -112,6 +114,12 @@ const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
className={`${styles.container} ${className}`} className={`${styles.container} ${className}`}
onClick={handleClick} onClick={handleClick}
onContextMenu={onContextMenu} onContextMenu={onContextMenu}
onTouchStart={(e) => {
// Предотвращаем стандартное поведение только если не в режиме удаления
if (!isDeleteMode && onContextMenu) {
e.preventDefault();
}
}}
> >
{/* Показываем индикатор загрузки, если изображение загружается */} {/* Показываем индикатор загрузки, если изображение загружается */}
{loading && ( {loading && (
@ -125,6 +133,7 @@ const ImageWithFallback: React.FC<ImageWithFallbackProps> = ({
ref={imgRef} ref={imgRef}
src={imageSrc} src={imageSrc}
alt={alt} alt={alt}
draggable="false"
className={`${styles.image} ${error ? styles.hidden : ''}`} className={`${styles.image} ${error ? styles.hidden : ''}`}
onLoad={handleLoad} onLoad={handleLoad}
onError={handleError} onError={handleError}

View File

@ -12,6 +12,7 @@ interface NotificationModalProps {
showGalleryButton?: boolean; // Параметр для управления видимостью кнопки "В галерею" showGalleryButton?: boolean; // Параметр для управления видимостью кнопки "В галерею"
showButtons?: boolean; // Новый параметр для управления видимостью всех кнопок showButtons?: boolean; // Новый параметр для управления видимостью всех кнопок
continueButtonText?: string; // Новый параметр для изменения текста кнопки "Продолжить" continueButtonText?: string; // Новый параметр для изменения текста кнопки "Продолжить"
galleryButtonText?: string; // Новый параметр для изменения текста кнопки "В галерею"
} }
const NotificationModal: React.FC<NotificationModalProps> = ({ const NotificationModal: React.FC<NotificationModalProps> = ({
@ -24,7 +25,8 @@ const NotificationModal: React.FC<NotificationModalProps> = ({
onContinueClick, onContinueClick,
showGalleryButton = true, // По умолчанию кнопка "В галерею" видима showGalleryButton = true, // По умолчанию кнопка "В галерею" видима
showButtons = true, // По умолчанию все кнопки видимы showButtons = true, // По умолчанию все кнопки видимы
continueButtonText = 'Продолжить' // По умолчанию текст кнопки "Продолжить" continueButtonText = 'Продолжить', // По умолчанию текст кнопки "Продолжить"
galleryButtonText = 'В галерею' // По умолчанию текст кнопки "В галерею"
}) => { }) => {
if (!isVisible) return null; if (!isVisible) return null;
@ -53,7 +55,7 @@ const NotificationModal: React.FC<NotificationModalProps> = ({
className={`${styles.button} ${styles.secondaryButton}`} className={`${styles.button} ${styles.secondaryButton}`}
onClick={onGalleryClick} onClick={onGalleryClick}
> >
Отмена {galleryButtonText}
</button> </button>
)} )}
<button <button

View File

@ -312,6 +312,7 @@ const GalleryScreen: React.FC = () => {
onClick={() => !isDeleteMode && image.url && setSelectedImage(image.url)} onClick={() => !isDeleteMode && image.url && setSelectedImage(image.url)}
onContextMenu={(e: React.MouseEvent<HTMLDivElement>) => e.preventDefault()} onContextMenu={(e: React.MouseEvent<HTMLDivElement>) => e.preventDefault()}
maxRetries={3} maxRetries={3}
isDeleteMode={isDeleteMode}
/> />
{isDeleteMode && ( {isDeleteMode && (
<div <div
@ -343,6 +344,7 @@ const GalleryScreen: React.FC = () => {
message="Вы уверены, что хотите удалить этот стикер?" message="Вы уверены, что хотите удалить этот стикер?"
isLoading={isDeleting} isLoading={isDeleting}
showGalleryButton={true} showGalleryButton={true}
galleryButtonText="Отмена"
continueButtonText="Удалить" continueButtonText="Удалить"
onContinueClick={handleConfirmDelete} onContinueClick={handleConfirmDelete}
onGalleryClick={() => setSelectedForDelete(null)} onGalleryClick={() => setSelectedForDelete(null)}