websocket logic is changed
This commit is contained in:
parent
378183bfb8
commit
d908b2987c
|
|
@ -6,11 +6,18 @@ interface CountdownProps {
|
|||
startsAt: string;
|
||||
endsAt: string;
|
||||
setVoteStatus: Dispatch<SetStateAction<string | undefined>>;
|
||||
setEventStatus: Dispatch<SetStateAction<string>>;
|
||||
eventStatus: string;
|
||||
}
|
||||
|
||||
const Countdown: React.FC<CountdownProps> = ({ startsAt, endsAt, setVoteStatus }) => {
|
||||
const Countdown: React.FC<CountdownProps> = ({
|
||||
startsAt,
|
||||
endsAt,
|
||||
setVoteStatus,
|
||||
setEventStatus,
|
||||
eventStatus,
|
||||
}) => {
|
||||
const [timeLeft, setTimeLeft] = useState<string>('');
|
||||
const [eventStatus, setEventStatus] = useState<string>('Finished');
|
||||
|
||||
useEffect(() => {
|
||||
// Parsing the start and end times to Date objects in the correct format
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
"use client";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import GradientTitle from "./GradientTitle";
|
||||
import ParticipantCard from "./ParticipantCard";
|
||||
import { v4 } from "uuid";
|
||||
import { IAllVotes, VotingItem } from "@/models/allVotes.model";
|
||||
import { Queries } from "@/api/queries";
|
||||
import Loader from "../Loader";
|
||||
import VoteContext from "@/context/VoteContext";
|
||||
import PageBage from "./PageBage";
|
||||
import Image from "next/image";
|
||||
import { useMediaQuery } from "usehooks-ts";
|
||||
import Countdown from "./Countdown";
|
||||
import Link from "next/link";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
'use client';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import GradientTitle from './GradientTitle';
|
||||
import ParticipantCard from './ParticipantCard';
|
||||
import { v4 } from 'uuid';
|
||||
import { IAllVotes, VotingItem } from '@/models/allVotes.model';
|
||||
import { Queries } from '@/api/queries';
|
||||
import Loader from '../Loader';
|
||||
import VoteContext from '@/context/VoteContext';
|
||||
import PageBage from './PageBage';
|
||||
import Image from 'next/image';
|
||||
import { useMediaQuery } from 'usehooks-ts';
|
||||
import Countdown from './Countdown';
|
||||
import Link from 'next/link';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
|
||||
interface IParams {
|
||||
vote_id?: string;
|
||||
|
|
@ -30,6 +30,9 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
const [data, setData] = useState<IAllVotes>();
|
||||
const [participantsData, setParticipantsData] = useState<VotingItem[]>([]);
|
||||
const [voteStatus, setVoteStatus] = useState<string>();
|
||||
const [eventStatus, setEventStatus] = useState<string>('Finished');
|
||||
const [manualClose, setManualClose] = useState(false); // Track manual closure
|
||||
|
||||
const [winnersCount, setWinnersCount] = useState<number>(0);
|
||||
|
||||
// States realted to web socket
|
||||
|
|
@ -37,7 +40,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
const [socket, setSocket] = useState<WebSocket | null>(null);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
|
||||
const mobile = useMediaQuery("(max-width: 768px)");
|
||||
const mobile = useMediaQuery('(max-width: 768px)');
|
||||
|
||||
const { setVoteDescription } = useContext(VoteContext).voteDescriptionContext;
|
||||
|
||||
|
|
@ -72,68 +75,73 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
|
||||
const connectWebSocket = () => {
|
||||
try {
|
||||
socket = new WebSocket(
|
||||
`wss://sms.turkmentv.gov.tm/ws/voting?dst=${smsNumber}`
|
||||
);
|
||||
setSocket(socket);
|
||||
// Only connect if manualClose is false
|
||||
if (!manualClose) {
|
||||
socket = new WebSocket(`wss://sms.turkmentv.gov.tm/ws/voting?dst=${smsNumber}`);
|
||||
setSocket(socket);
|
||||
|
||||
socket.onopen = () => {
|
||||
console.log("WebSocket is connected");
|
||||
setIsConnected(true);
|
||||
// addVotes();
|
||||
socket.onopen = () => {
|
||||
console.log('WebSocket is connected');
|
||||
setIsConnected(true);
|
||||
|
||||
pingInterval = setInterval(() => {
|
||||
if (socket?.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
socket.send(JSON.stringify({ type: "ping" }));
|
||||
// addVotes();
|
||||
} catch (error) {
|
||||
console.error("Error sending ping:", error);
|
||||
pingInterval = setInterval(() => {
|
||||
if (socket?.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
socket.send(JSON.stringify({ type: 'ping' }));
|
||||
} catch (error) {
|
||||
console.error('Error sending ping:', error);
|
||||
}
|
||||
}
|
||||
}, 25000); // Ping every 25 seconds
|
||||
};
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
handleWebSocketMessage(message);
|
||||
} catch (error) {
|
||||
console.error('Error processing message:', error);
|
||||
}
|
||||
}, 25000); // Ping every 25 seconds
|
||||
};
|
||||
};
|
||||
|
||||
socket.onmessage = (event) => {
|
||||
try {
|
||||
console.log("Message received from WebSocket:", event.data);
|
||||
const message = JSON.parse(event.data);
|
||||
handleWebSocketMessage(message);
|
||||
} catch (error) {
|
||||
console.error("Error processing message:", error);
|
||||
}
|
||||
};
|
||||
socket.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
|
||||
socket.onerror = (error) => {
|
||||
console.error("WebSocket error:", error);
|
||||
};
|
||||
if (!manualClose && !reconnectTimeout) {
|
||||
reconnectTimeout = setTimeout(() => {
|
||||
console.log('Attempting to reconnect WebSocket after error...');
|
||||
connectWebSocket();
|
||||
}, 5000); // Reconnect after 5 seconds
|
||||
}
|
||||
};
|
||||
|
||||
socket.onclose = () => {
|
||||
console.log("WebSocket is closed");
|
||||
setIsConnected(false);
|
||||
socket.onclose = () => {
|
||||
console.log('WebSocket is closed');
|
||||
setIsConnected(false);
|
||||
|
||||
if (pingInterval) {
|
||||
clearInterval(pingInterval);
|
||||
}
|
||||
if (pingInterval) {
|
||||
clearInterval(pingInterval);
|
||||
}
|
||||
|
||||
if (!reconnectTimeout) {
|
||||
reconnectTimeout = setTimeout(() => {
|
||||
console.log("Attempting to reconnect WebSocket...");
|
||||
connectWebSocket();
|
||||
}, 5000); // Reconnect after 5 seconds
|
||||
}
|
||||
};
|
||||
// Clean up resources on close
|
||||
if (reconnectTimeout) {
|
||||
clearTimeout(reconnectTimeout);
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("WebSocket connection error:", error);
|
||||
console.error('WebSocket connection error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
if (smsNumber) {
|
||||
// WebSocket connection only if eventStatus is 'Started'
|
||||
if (smsNumber && eventStatus === 'Started' && !manualClose) {
|
||||
connectWebSocket();
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (socket) {
|
||||
setManualClose(true); // Mark it as a manual close
|
||||
socket.close();
|
||||
}
|
||||
if (reconnectTimeout) {
|
||||
|
|
@ -143,7 +151,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
clearInterval(pingInterval);
|
||||
}
|
||||
};
|
||||
}, [smsNumber]);
|
||||
}, [smsNumber, eventStatus, manualClose]); // Add manualClose to dependencies
|
||||
|
||||
const handleWebSocketMessage = (message: ISocketMessage) => {
|
||||
setParticipantsData((prevVotingItems) => {
|
||||
|
|
@ -151,9 +159,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
|
||||
// Update the corresponding voting item
|
||||
const updatedItems = prevVotingItems.map((item, index) =>
|
||||
item.id === message.voting_item_id
|
||||
? { ...item, votes_count: item.votes_count + 1 }
|
||||
: item
|
||||
item.id === message.voting_item_id ? { ...item, votes_count: item.votes_count + 1 } : item,
|
||||
);
|
||||
|
||||
// Sort the updated items array by votes_count in descending order
|
||||
|
|
@ -167,10 +173,10 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
|
||||
// Update the corresponding voting item
|
||||
const updatedItems = prevVotingItems.map((item, index) =>
|
||||
index === 1 ? { ...item, votes_count: item.votes_count + 1 } : item
|
||||
index === 1 ? { ...item, votes_count: item.votes_count + 1 } : item,
|
||||
);
|
||||
|
||||
console.log("votes updated");
|
||||
console.log('votes updated');
|
||||
console.log(updatedItems.sort((a, b) => b.votes_count - a.votes_count));
|
||||
// Sort the updated items array by votes_count in descending order
|
||||
return updatedItems.sort((a, b) => b.votes_count - a.votes_count);
|
||||
|
|
@ -180,10 +186,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
const winnersCountHandle = (winners: VotingItem[]) => {
|
||||
let count = 0;
|
||||
winners.map((winner) => {
|
||||
if (
|
||||
winner.votes_percents === 100 &&
|
||||
winner.votes_count === winners[0].votes_count
|
||||
) {
|
||||
if (winner.votes_percents === 100 && winner.votes_count === winners[0].votes_count) {
|
||||
count++;
|
||||
setWinnersCount(count);
|
||||
}
|
||||
|
|
@ -197,27 +200,21 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
if (!data?.data) {
|
||||
return (
|
||||
<div className="py-12">
|
||||
<GradientTitle title={"No voting to show on the site"} size="big" />
|
||||
<GradientTitle title={'No voting to show on the site'} size="big" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-[20px] sm:gap-[40px] w-full items-center">
|
||||
{data.data.description ? (
|
||||
<PageBage title={data.data.description} />
|
||||
) : null}
|
||||
{data.data.description ? <PageBage title={data.data.description} /> : null}
|
||||
|
||||
{data.data.banner ? (
|
||||
<div className="relative w-full md:min-h-[150px] md:h-auto h-[100px] ">
|
||||
{mobile ? (
|
||||
<Image
|
||||
fill
|
||||
src={
|
||||
data.data.banner_mobile !== null
|
||||
? data.data.banner_mobile
|
||||
: data.data.banner
|
||||
}
|
||||
src={data.data.banner_mobile !== null ? data.data.banner_mobile : data.data.banner}
|
||||
alt={data.data.title}
|
||||
unselectable="off"
|
||||
unoptimized
|
||||
|
|
@ -244,30 +241,28 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
endsAt={data.data.ends_at}
|
||||
startsAt={data.data.starts_at}
|
||||
setVoteStatus={setVoteStatus}
|
||||
setEventStatus={setEventStatus}
|
||||
eventStatus={eventStatus}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<div className="flex w-full flex-col items-center gap-[10px] sm:gap-[20px]">
|
||||
{winnersCount > 1 ? (
|
||||
<GradientTitle title="победители" size="small" />
|
||||
) : null}
|
||||
{winnersCount > 1 ? <GradientTitle title="победители" size="small" /> : null}
|
||||
|
||||
{participantsData && participantsData[0].votes_count > 0 ? (
|
||||
<div className="flex flex-col items-center overflow-hidden bg-fillNavyBlue rounded-[10px] sm:rounded-[30px] max-w-[940px] w-full px-[5px] py-[20px] sm:p-[20px] sm:gap-[20px] gap-[10px]">
|
||||
{participantsData.map((participant, index) =>
|
||||
participant.votes_count ===
|
||||
participantsData[0].votes_count ? (
|
||||
participant.votes_count === participantsData[0].votes_count ? (
|
||||
participant.url ? (
|
||||
<Link
|
||||
href={participant.url ? participant.url : ""}
|
||||
href={participant.url ? participant.url : ''}
|
||||
target="_blank"
|
||||
className="w-full"
|
||||
key={v4()}
|
||||
>
|
||||
key={v4()}>
|
||||
<ParticipantCard
|
||||
index={index}
|
||||
hasUrl={true}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -284,7 +279,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
key={v4()}
|
||||
index={index}
|
||||
hasUrl={false}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -296,14 +291,12 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
winner={true}
|
||||
/>
|
||||
)
|
||||
) : null
|
||||
) : null,
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{winnersCount > 1 ? (
|
||||
<div className="w-full h-[1px] bg-[#3636A3]"></div>
|
||||
) : null}
|
||||
{winnersCount > 1 ? <div className="w-full h-[1px] bg-[#3636A3]"></div> : null}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col items-center max-w-[940px] w-full gap-5 justify-center mx-auto">
|
||||
|
|
@ -312,15 +305,14 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
!hasVotes ? (
|
||||
participant.url ? (
|
||||
<Link
|
||||
href={participant.url ? participant.url : ""}
|
||||
href={participant.url ? participant.url : ''}
|
||||
target="_blank"
|
||||
className="w-full mx-auto"
|
||||
key={v4()}
|
||||
>
|
||||
key={v4()}>
|
||||
<ParticipantCard
|
||||
index={index}
|
||||
hasUrl={true}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -337,7 +329,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
hasUrl={false}
|
||||
key={v4()}
|
||||
index={index}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -350,19 +342,17 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
/>
|
||||
)
|
||||
) : (
|
||||
participant.votes_count !==
|
||||
participantsData[0].votes_count &&
|
||||
participant.votes_count !== participantsData[0].votes_count &&
|
||||
(participant.url ? (
|
||||
<Link
|
||||
href={participant.url ? participant.url : ""}
|
||||
href={participant.url ? participant.url : ''}
|
||||
target="_blank"
|
||||
className="w-full mx-auto"
|
||||
key={v4()}
|
||||
>
|
||||
key={v4()}>
|
||||
<ParticipantCard
|
||||
index={index}
|
||||
hasUrl={true}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -379,7 +369,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
hasUrl={false}
|
||||
key={v4()}
|
||||
index={index}
|
||||
voteStatus={voteStatus ? voteStatus : ""}
|
||||
voteStatus={voteStatus ? voteStatus : ''}
|
||||
isFirst={index === 0 ? true : false}
|
||||
name={participant.title}
|
||||
progress={participant.votes_percents}
|
||||
|
|
@ -391,7 +381,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
|||
winner={false}
|
||||
/>
|
||||
))
|
||||
)
|
||||
),
|
||||
)
|
||||
: null}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue