- Added support for sending OTP messages using Kavenegar's VerifyLookup method, ensuring compliance with specified token formatting and template usage. - Updated OtpService to handle new template parameters and fallback mechanisms. - Introduced ImageCropModal component for cropping images with a user-friendly interface. - Created utility function for cropping images and generating downloadable files.
50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
import type { Area } from 'react-easy-crop';
|
|
|
|
function createImage(url: string): Promise<HTMLImageElement> {
|
|
return new Promise((resolve, reject) => {
|
|
const image = new Image();
|
|
image.addEventListener('load', () => resolve(image));
|
|
image.addEventListener('error', (err) => reject(err));
|
|
image.setAttribute('crossOrigin', 'anonymous');
|
|
image.src = url;
|
|
});
|
|
}
|
|
|
|
export async function getCroppedImage(
|
|
src: string,
|
|
area: Area,
|
|
fileName: string,
|
|
outputSize = 512,
|
|
): Promise<File> {
|
|
const image = await createImage(src);
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) throw new Error('عدم دسترسی به canvas');
|
|
|
|
canvas.width = outputSize;
|
|
canvas.height = outputSize;
|
|
|
|
ctx.drawImage(
|
|
image,
|
|
area.x,
|
|
area.y,
|
|
area.width,
|
|
area.height,
|
|
0,
|
|
0,
|
|
outputSize,
|
|
outputSize,
|
|
);
|
|
|
|
const blob: Blob = await new Promise((resolve, reject) => {
|
|
canvas.toBlob(
|
|
(b) => (b ? resolve(b) : reject(new Error('خطا در برش تصویر'))),
|
|
'image/jpeg',
|
|
0.92,
|
|
);
|
|
});
|
|
|
|
const baseName = fileName.replace(/\.[^./\\]+$/, '') || 'avatar';
|
|
return new File([blob], `${baseName}.jpg`, { type: 'image/jpeg' });
|
|
}
|