upd click request

This commit is contained in:
Arseniy Sitnikov 2024-12-12 18:42:33 +03:00
parent 86d3e9bbf4
commit 9e9fcc5f94
5 changed files with 101 additions and 38 deletions

BIN
frontend/src/.DS_Store vendored

Binary file not shown.

View File

@ -5,7 +5,7 @@ import { ClickerPopup } from '../ClickerPopup';
import { getGradient } from '../../../utils/getGradient';
import { useAppSelector } from '../../hooks/useAppSelector';
import { useDispatch } from 'react-redux';
import { updateEnergyRequestAsync } from '../../../store/me/actions';
import { IUserData, updateEnergyRequestAsync } from '../../../store/me/actions';
import axios from 'axios';
import { DevPopup } from '../../Elements/DevPopup';
import { saveMult } from '../../../store/mult';
@ -15,10 +15,11 @@ interface IClickerBtn {
coins: number,
setCoins(a: number): void,
energy: number,
setMult(a: number): void
setMult(a: number): void,
setEnergy(a: number): void
}
export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
export function ClickerBtn({ setCoins, energy, setMult, coins, setEnergy }: IClickerBtn) {
const urlClick = useAppSelector<string>(state => state.urlClick);
const token = useAppSelector<string>(state => state.token);
const [fill, setFill] = useState(0);
@ -29,14 +30,12 @@ export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
const [close, setClose] = useState(true);
const [gradient, setGradient] = useState(getGradient());
let styleIndex = useAppSelector<number>(state => state.styleIndex);
const [initEnergy, setEnergy] = useState(energy);
//const maxEnergy = Number(localStorage.getItem('eg'));
const [maxEnergy, setMaxEnergy] = useState(500);
const [closeError, setCloseError] = useState(true);
const [error, setError] = useState(false);
const [animClose, setAnimClose] = useState(false);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
useEffect(() => {
setFill((maxEnergy - energy) / maxEnergy * 100);
}, [energy]);
useEffect(() => {
const savedEnergy = sessionStorage.getItem('eg');
@ -44,28 +43,40 @@ export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
const encodeEnergy = atob(savedEnergy);
setMaxEnergy(Number(encodeEnergy));
}
setFill((maxEnergy - initEnergy) / maxEnergy * 100);
setFill((maxEnergy - energy) / maxEnergy * 100);
}, []);
useEffect(() => {
if (initEnergy === 0 || fill === 100) {
setCloseError(true);
}
}, [initEnergy, fill]);
useEffect(() => {
setGradient(getGradient())
}, [styleIndex]);
const btnClick = () => {
if (!(initEnergy === 0)) {
sendClick();
if (energy != 0) {
const newEnergy = energy - 1;
const newFill = (maxEnergy - newEnergy) / maxEnergy * 100;
const newCoins = coins + 1;
dispatch<any>(updateEnergyRequestAsync(newEnergy));
setCoins(newCoins);
setEnergy(newEnergy)
setFill(newFill);
if (newFill < 100) {
setSize(220);
const timer = setTimeout(() => {
setSize(240);
clearTimeout(timer);
}, 100);
} else {
setClose(false);
}
//sendClick();
} else {
setClose(false);
}
};
const sendClick = () => {
/*const sendClick = () => {
if (token && !loading) {
setLoading(true);
axios.post(`${urlClick}/api/v1/click/`,
@ -120,7 +131,7 @@ export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
console.log(err);
})
}
};
};*/
const hotCards = [
@ -144,8 +155,7 @@ export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
return (
<div className={styles.ringContainer}>
<div className={`${styles.ringBig} ${fill === 100 && styles.borderNone}`}></div>
{!loading && <div className={`${styles.ringSmall} ${fill === 100 && styles.borderNone}`} style={{ backgroundImage: `url(${img})`, backgroundSize: `${size}px` }} onClick={btnClick}></div>}
{loading && <div className={styles.loadingContainer}> <Spinner size='50px' thickness='10px' color='var(--primary)'/> </div> }
<div className={`${styles.ringSmall} ${fill === 100 && styles.borderNone}`} style={{ backgroundImage: `url(${img})`, backgroundSize: `${size}px` }} onClick={btnClick}></div>
<svg className={styles.svg} width="270" height="270" viewBox="0 0 270 270" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="135" cy="135" r="125" stroke={fill < 100 ? "url(#paint0_linear_619_10702)" : '#FF0000'} strokeWidth="20" strokeLinecap="round" style={{ strokeDasharray: `${dashArray} ${circumference}` }} />
<defs>
@ -155,9 +165,6 @@ export function ClickerBtn({ setCoins, energy, setMult, coins }: IClickerBtn) {
{!close && <ModalWindow setCloseAnimOut={setClose} removeBtn={true} setClose={setClose} modalBlock={
<ClickerPopup title='Кнопка перегрелась' cards={hotCards} setClose={setClose} isBtn={true}/>
} />}
{!closeError && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseError} modalBlock={
<DevPopup setClose={setAnimClose} title='Возникла ошибка' text='Мы пока не можем принимать клики, но скоро всё починим.'/>
} />}
</div>
);
}

View File

@ -4,8 +4,11 @@ import { formatNumber } from '../../../utils/formatNumber';
import { ETextStyles } from '../../texts';
import ReactDOM from 'react-dom';
import { useDispatch } from 'react-redux';
import { updatePointsRequestAsync } from '../../../store/me/actions';
import { meRequest, meRequestError, updateEnergyRequestAsync, updatePointsRequestAsync } from '../../../store/me/actions';
import { checkIOS } from '../../../utils/checkMobile';
import axios from 'axios';
import { useAppSelector } from '../../hooks/useAppSelector';
import { saveMult } from '../../../store/mult';
interface IPointsZoom {
points: number,
@ -13,27 +16,64 @@ interface IPointsZoom {
className ?: string,
closePointsAnim: boolean,
setClosePointsAnim(a: boolean): void,
setCoins(a:number):void
setCoins(a:number):void,
setCloseError(a: boolean): void,
setEnergy(a: number): void,
setMult(a: number): void,
}
export function PointsZoom({ points, setClose, setCoins, className, closePointsAnim, setClosePointsAnim }: IPointsZoom) {
export function PointsZoom({ points, setMult, setClose, setCoins, className, closePointsAnim, setClosePointsAnim, setCloseError, setEnergy }: IPointsZoom) {
const [open, setOpen] = useState(true);
const node = document.querySelector('#modal_root');
const urlClick = useAppSelector<string>(state => state.urlClick);
const token = useAppSelector<string>(state => state.token);
const [sizeHand, setSizeHand] = useState(30);
const energy = Number(useAppSelector<string | undefined>(state=>state.me.data.energy));
if (!node) return null;
const dispatch = useDispatch();
const sendClicks = () => {
const initPoints = points;
dispatch(meRequest());
axios.post(`${urlClick}/api/v1/batch-click/`,
{
count: initPoints
},
{
headers: {
"Authorization": `TelegramToken ${token}`
}
}
).then(resp => {
const data = resp.data;
const click = Number(data.click.value);
const encodeMult = btoa(click.toString());
sessionStorage.setItem('mt', encodeMult);
setMult(Number(click.toFixed(2)));
const energy = Number(data.energy);
dispatch<any>(saveMult(Number(click.toFixed(2))));
dispatch<any>(updateEnergyRequestAsync(energy));
dispatch<any>(updatePointsRequestAsync());
}).catch(err => {
console.log(err);
setCloseError(false);
const returnEnergy = energy + initPoints;
setEnergy(returnEnergy);
dispatch<any>(updateEnergyRequestAsync(returnEnergy));
dispatch(meRequestError(String(err)));
})
};
useEffect(() => {
const timer = setInterval(() => {
setOpen(false);
clearInterval(timer);
}, 400);
console.log(checkIOS())
}, []);
useEffect(() => {
if (closePointsAnim) {
dispatch<any>(updatePointsRequestAsync());
sendClicks();
const timer = setTimeout(() => {
setClosePointsAnim(false);
setClose(true);
@ -43,12 +83,21 @@ export function PointsZoom({ points, setClose, setCoins, className, closePointsA
}
}, [closePointsAnim]);
useEffect(() => {
setSizeHand(25);
const timer = setTimeout(() => {
setSizeHand(30);
}, 100);
return () => clearTimeout(timer);
}, [points]);
return (
<div className={`${styles.container} ${className} ${open ? styles.animBack : ''} ${closePointsAnim ? styles.animBackClose : ''}`}>
{ReactDOM.createPortal((
<div className={`${styles.innerContainer} ${open ? styles.animBlock : ''} ${closePointsAnim ? styles.animBlockClose : ''} ${checkIOS() && styles.ios}`}>
<div className={styles.icon} style={{ backgroundImage: `url('assets/btnIcon.png')` }}></div>
<p className={styles.point} style={ETextStyles.InSb18100}>{`+${formatNumber(Number(points.toFixed(2)))}`}</p>
<div className={styles.icon} style={{ backgroundImage: `url('assets/point.png')`, width: `${sizeHand}px`, height: `${sizeHand}px` }}></div>
<p className={styles.point} style={ETextStyles.InSb18100}>{`${formatNumber(Number(points.toFixed(2)))}`}</p>
</div>
), node)}
</div>

View File

@ -15,6 +15,7 @@
left: 10px;
z-index: 50;
width: calc(100% - 20px);
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
@ -29,8 +30,6 @@
}
.icon {
width: 40px;
height: 40px;
background-position: center;
background-size: contain;
background-repeat: no-repeat;

View File

@ -9,6 +9,8 @@ import { StyleElements } from '../../Clicker/StyleElements';
import { PointsZoom } from '../../Clicker/PointsZoom';
import { useWindowSize } from 'usehooks-ts';
import { useAppSelector } from '../../hooks/useAppSelector';
import { ModalWindow } from '../../ModalWindow';
import { DevPopup } from '../../Elements/DevPopup';
interface IClickerPageInterface {
name: string,
@ -25,6 +27,9 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
const [closePointsAnim, setClosePointsAnim] = useState(false);
const { width, height } = useWindowSize();
const savedMult = useAppSelector<number>(state => state.mult);
const [closeError, setCloseError] = useState(true);
const [animClose, setAnimClose] = useState(false);
const [initEnergy, setInitEnergy] = useState(energy);
useEffect(() => {
setMult(savedMult);
@ -49,18 +54,21 @@ export function ClickerPage({ name, points, img, energy }: IClickerPageInterface
return (
<div className={styles.container}>
<div className={styles.records}>
{!closePoints && <PointsZoom setCoins={setCoins} points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
{!closePoints && <PointsZoom setMult={setMult} setEnergy={setInitEnergy} setCloseError={setCloseError} setCoins={setCoins} points={coins} setClosePointsAnim={setClosePointsAnim} setClose={setClosePoints} className={styles.pointsAnim} closePointsAnim={closePointsAnim}/>}
<Profile name={name} className={styles.profile} img={img}/>
<h1 style={ETextStyles.RwSb24100} className={styles.title}>Мои рекорды</h1>
<SectionsBlock mult={mult}/>
</div>
<div className={styles.clicker} style={{height: `${height > 670 && 'calc(100vh - 355px)'}`}}>
<ClickerBtn coins={coins} setCoins={setCoins} energy={energy} setMult={setMult}/>
<ClickerBtn setEnergy={setInitEnergy} coins={coins} setCoins={setCoins} energy={initEnergy} setMult={setMult}/>
</div>
<ClickerFooter />
{styleIndex != 0 && <div>
<StyleElements styleIndex={styleIndex}/>
</div>}
{!closeError && <ModalWindow removeBtn={true} setCloseAnimOut={setAnimClose} closeAnimOut={animClose} setClose={setCloseError} modalBlock={
<DevPopup setClose={setAnimClose} title='Возникла ошибка' text='Мы пока не можем принимать клики, но скоро всё починим.' />
} />}
</div>
);
}