diff --git a/src/model/quizSettings.ts b/src/model/quizSettings.ts index 8cd58b35..5c8b9aca 100644 --- a/src/model/quizSettings.ts +++ b/src/model/quizSettings.ts @@ -39,6 +39,8 @@ export interface QuizConfig { description: string; button: string; position: QuizStartpageAlignType; + favIcon: string | null; + originalFavIcon: string | null; background: { type: null | "image" | "video"; desktop: string | null; @@ -71,6 +73,8 @@ export const defaultQuizConfig: QuizConfig = { description: "", button: "", position: "left", + favIcon: null, + originalFavIcon: null, background: { type: null, desktop: null, diff --git a/src/pages/startPage/StartPageSettings.tsx b/src/pages/startPage/StartPageSettings.tsx index 144d8b8c..c1665b5d 100755 --- a/src/pages/startPage/StartPageSettings.tsx +++ b/src/pages/startPage/StartPageSettings.tsx @@ -35,8 +35,8 @@ import UploadIcon from "../../assets/icons/UploadIcon"; import ModalSizeImage from "./ModalSizeImage"; import SelectableIconButton from "./SelectableIconButton"; import { DropZone } from "./dropZone"; -import DropFav from "./dropfavicon"; import Extra from "./extra"; +import { resizeFavIcon } from "@ui_kit/reactImageFileResizer"; const designTypes = [ @@ -85,6 +85,33 @@ export default function StartPageSettings() { if (!quiz) return null; // TODO throw and catch with error boundary + const favIconDropZoneElement = ( + { + const resizedImage = await resizeFavIcon(file); + uploadQuizImage(quiz.id, resizedImage, (quiz, url) => { + quiz.config.startpage.favIcon = url; + quiz.config.startpage.originalFavIcon = url; + }); + }} + onImageSaveClick={async file => { + const resizedImage = await resizeFavIcon(file); + uploadQuizImage(quiz.id, resizedImage, (quiz, url) => { + quiz.config.startpage.favIcon = url; + }); + }} + onDeleteClick={() => { + updateQuiz(quiz.id, quiz => { + quiz.config.startpage.favIcon = null; + }); + }} + /> + ); + return ( <> { @@ -476,7 +501,6 @@ export default function StartPageSettings() { { @@ -557,7 +581,6 @@ export default function StartPageSettings() { - - + {favIconDropZoneElement} - - + {favIconDropZoneElement} ; - heightImg: string; - widthImg?: string; + deleteIconSx?: SxProps; imageUrl: string | null; originalImageUrl: string | null; onImageUploadClick: (image: Blob) => void; @@ -32,7 +31,7 @@ interface Props { } //Научи функцию принимать данные для валидации -export const DropZone = ({ text, sx, heightImg, widthImg, imageUrl, originalImageUrl, onImageUploadClick, onImageSaveClick, onDeleteClick }: Props) => { +export const DropZone = ({ text, sx, deleteIconSx, imageUrl, originalImageUrl, onImageUploadClick, onImageSaveClick, onDeleteClick }: Props) => { const theme = useTheme(); const quiz = useCurrentQuiz(); const [isDropReady, setIsDropReady] = useState(false); @@ -103,14 +102,15 @@ export const DropZone = ({ text, sx, heightImg, widthImg, imageUrl, originalImag justifyContent: "center", alignItems: "center", borderRadius: "8px", + overflow: "hidden", }} > {imageUrl ? @@ -144,6 +144,7 @@ export const DropZone = ({ text, sx, heightImg, widthImg, imageUrl, originalImag borderRadius: "8px", borderBottomRightRadius: 0, borderTopLeftRadius: 0, + ...deleteIconSx, }} > diff --git a/src/pages/startPage/dropfavicon.tsx b/src/pages/startPage/dropfavicon.tsx deleted file mode 100644 index 032f44f8..00000000 --- a/src/pages/startPage/dropfavicon.tsx +++ /dev/null @@ -1,274 +0,0 @@ -import { Box, ButtonBase, SxProps, Theme, Typography, useTheme } from "@mui/material"; -import Resizer from "@ui_kit/reactImageFileResizer"; -import saveAs from "file-saver"; -import JSZip from "jszip"; -import { enqueueSnackbar } from "notistack"; -import { useEffect, useState } from "react"; -import UploadIcon from "../../assets/icons/UploadIcon"; - -interface Props { - text?: string; - sx?: SxProps; - heightImg: string; - widthImg?: string; -} - -const imageFavicon = [ - { - maxWidth: 16, - maxHeight: 16, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 32, - maxHeight: 32, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 48, - maxHeight: 48, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 76, - maxHeight: 76, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 96, - maxHeight: 96, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 120, - maxHeight: 120, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 128, - maxHeight: 128, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 144, - maxHeight: 144, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 152, - maxHeight: 152, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 167, - maxHeight: 167, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 180, - maxHeight: 180, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 192, - maxHeight: 192, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 196, - maxHeight: 196, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 228, - maxHeight: 288, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 256, - maxHeight: 256, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 300, - maxHeight: 300, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 384, - maxHeight: 384, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, - { - maxWidth: 512, - maxHeight: 512, - compressFormat: "PNG", - quality: 100, - rotation: 0, - }, -]; -export default ({ text, sx, heightImg, widthImg }: Props) => { - const theme = useTheme(); - const [favList, setFavList] = useState([]); - - useEffect(() => { - if (favList.length === 18) { - - const zip = new JSZip(); //создание зип архива - - favList.forEach((uri, i) => { - const idx = uri.indexOf("base64,") + "base64,".length; //обработка строки картинки - const content = uri.substring(idx); //обработка строки картинки - zip.file(`fav${i}.jpg`, content, { base64: true }); //сохранение картинки в архив с именем "fav.jpg" - }); - - zip.generateAsync({ type: "blob" }).then(function (content) { - // скачивание архива - saveAs(content, "fav.zip"); // скачивание архива - }); // скачивание архива - } - }, [favList]); - - const callback = (uri: string) => { - setFavList((old) => [...old, uri]); - }; - - const imgHC = (imgInp: HTMLInputElement) => { - const file = imgInp.files?.[0]; - if (file) { - setFavList([]); - if (file.size < 5242880) { - setData(URL.createObjectURL(file)); - imageFavicon.forEach((obj) => { - try { - Resizer.imageFileResizer( - file, - obj.maxWidth, - obj.compressFormat, - obj.quality, - obj.rotation, - callback, - "string" - ); - } catch (err) { - console.log(err); - } - }); - } else { - enqueueSnackbar("Размер картинки слишком велик"); - } - } - }; - - const [data, setData] = useState(""); - const [ready, setReady] = useState(false); - - const dragenterHC = () => { - setReady(true); - }; - - const dragexitHC = () => { - setReady(false); - }; - - const dropHC = (event: React.DragEvent) => { - event.preventDefault(); - setReady(false); - const file = event.dataTransfer.files[0]; - if (file.size < 5242880) { - setData(URL.createObjectURL(file)); - } else { - enqueueSnackbar("Размер картинки слишком велик"); - } - }; - - const dragOverHC = (event: React.DragEvent) => { - event.preventDefault(); - }; - - return ( - - imgHC(event.target)} hidden accept="image/*" multiple type="file" /> - - - - {text} - - {data ? ( - - ) : null} - - - ); -}; diff --git a/src/ui_kit/reactImageFileResizer.ts b/src/ui_kit/reactImageFileResizer.ts index 7b4b8498..aa477036 100644 --- a/src/ui_kit/reactImageFileResizer.ts +++ b/src/ui_kit/reactImageFileResizer.ts @@ -174,4 +174,20 @@ class Resizer { outputType, ); }, - }; \ No newline at end of file + }; + +export function resizeFavIcon(blob: Blob) { + return new Promise(resolve => { + Resizer.createResizedImage( + new File([blob], "image"), + 48, + "PNG", + 100, + 0, + async (file: Blob) => { + resolve(file); + }, + "blob" + ); + }); +}