Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

130 lines
4.0 KiB
TypeScript
Raw Normal View History

2025-09-16 11:52:19 +01:00
import React, { useMemo, useState, useEffect } from "react";
2025-09-12 16:27:45 +01:00
import { Stack, Text, Box, ActionIcon, Group, Center } from "@mantine/core";
import { useTranslation } from "react-i18next";
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
import RotateRightIcon from "@mui/icons-material/RotateRight";
import { RotateParametersHook } from "../../../hooks/tools/rotate/useRotateParameters";
import { useSelectedFiles } from "../../../contexts/file/fileHooks";
import { useThumbnailGeneration } from "../../../hooks/useThumbnailGeneration";
import DocumentThumbnail from "../../shared/filePreview/DocumentThumbnail";
interface RotateSettingsProps {
parameters: RotateParametersHook;
disabled?: boolean;
}
const RotateSettings = ({ parameters, disabled = false }: RotateSettingsProps) => {
const { t } = useTranslation();
const { selectedFiles } = useSelectedFiles();
const { getThumbnailFromCache, requestThumbnail } = useThumbnailGeneration();
// Get the first selected file for preview
const selectedFile = useMemo(() => {
return selectedFiles.length > 0 ? selectedFiles[0] : null;
}, [selectedFiles]);
// Get thumbnail for the selected file
2025-09-16 11:52:19 +01:00
const [thumbnail, setThumbnail] = useState<string | null>(null);
useEffect(() => {
if (!selectedFile) {
setThumbnail(null);
return;
}
2025-09-12 16:27:45 +01:00
const pageId = `${selectedFile.fileId}-1`;
2025-09-16 11:52:19 +01:00
2025-09-12 16:27:45 +01:00
// Try to get cached thumbnail first
const cached = getThumbnailFromCache(pageId);
2025-09-16 11:52:19 +01:00
if (cached) {
setThumbnail(cached);
return;
}
2025-09-12 16:27:45 +01:00
// Request thumbnail if not cached
2025-09-16 11:52:19 +01:00
requestThumbnail(pageId, selectedFile, 1).then((result) => {
setThumbnail(result);
}).catch(() => {
setThumbnail(null);
2025-09-12 16:27:45 +01:00
});
}, [selectedFile, getThumbnailFromCache, requestThumbnail]);
// Calculate current angle display
const currentAngle = parameters.parameters.angle;
return (
<Stack gap="md">
{/* Thumbnail Preview Section */}
<Stack gap="xs">
<Text size="sm" fw={500}>
{t("rotate.preview.title", "Rotation Preview")}
</Text>
<Center>
<Box
style={{
width: '200px',
height: '280px',
border: '2px dashed var(--mantine-color-gray-4)',
borderRadius: '8px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'var(--mantine-color-gray-0)',
overflow: 'hidden'
}}
>
<Box
style={{
width: '100%',
height: '100%',
transform: `rotate(${currentAngle}deg)`,
transition: 'transform 0.3s ease-in-out',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<DocumentThumbnail
file={selectedFile}
thumbnail={thumbnail}
style={{
maxWidth: '180px',
maxHeight: '260px'
}}
/>
</Box>
</Box>
</Center>
</Stack>
{/* Rotation Controls */}
<Group justify="center" gap="lg">
<ActionIcon
size="xl"
variant="outline"
onClick={parameters.rotateAnticlockwise}
disabled={disabled}
aria-label={t("rotate.rotateLeft", "Rotate Anticlockwise")}
title={t("rotate.rotateLeft", "Rotate Anticlockwise")}
>
<RotateLeftIcon style={{ fontSize: '1.5rem' }} />
</ActionIcon>
<ActionIcon
size="xl"
variant="outline"
onClick={parameters.rotateClockwise}
disabled={disabled}
aria-label={t("rotate.rotateRight", "Rotate Clockwise")}
title={t("rotate.rotateRight", "Rotate Clockwise")}
>
<RotateRightIcon style={{ fontSize: '1.5rem' }} />
</ActionIcon>
</Group>
</Stack>
);
};
export default RotateSettings;