add websocket to table of watchlist

This commit is contained in:
MuslemRahimi 2024-11-25 22:20:24 +01:00
parent 175330e86e
commit cf38fd48ed
3 changed files with 157 additions and 5 deletions

View File

@ -213,7 +213,6 @@
}
if ($isOpen) {
//&& currentDateTime > startTime && currentDateTime < endTime
await websocketRealtimeData();
}
});

View File

@ -0,0 +1,54 @@
import {
isOpen,
isAfterMarketClose,
isBeforeMarketOpen,
isWeekend,
} from "$lib/store";
const checkMarketHour = async () => {
const holidays = [
"2024-01-01",
"2024-01-15",
"2024-02-19",
"2024-03-29",
"2024-05-27",
"2024-06-19",
"2024-07-04",
"2024-09-02",
"2024-11-28",
"2024-12-25",
];
const currentDate = new Date().toISOString().split("T")[0];
// Get the current time in the ET time zone
const etTimeZone = "America/New_York";
const currentTime = new Date().toLocaleString("en-US", {
timeZone: etTimeZone,
});
// Determine if the NYSE is currently open or closed
const currentHour = new Date(currentTime).getHours();
const isWeekendValue =
new Date(currentTime).getDay() === 6 ||
new Date(currentTime).getDay() === 0;
const isBeforeMarketOpenValue =
currentHour < 9 ||
(currentHour === 9 && new Date(currentTime).getMinutes() < 30);
const isAfterMarketCloseValue = currentHour >= 16;
isOpen.set(
!(
isWeekendValue ||
isBeforeMarketOpenValue ||
isAfterMarketCloseValue ||
holidays?.includes(currentDate)
),
);
isWeekend.set(isWeekendValue);
isBeforeMarketOpen.set(isBeforeMarketOpenValue);
isAfterMarketClose.set(isAfterMarketCloseValue);
};
export const load = async ({ params, data }) => {
await checkMarketHour();
};

View File

@ -1,9 +1,8 @@
<script lang="ts">
import { screenWidth, numberOfUnreadNotification } from "$lib/store";
import { screenWidth, numberOfUnreadNotification, isOpen } from "$lib/store";
import { formatDate, abbreviateNumber } from "$lib/utils";
import toast from "svelte-french-toast";
import { onMount } from "svelte";
import { onMount, onDestroy, afterUpdate } from "svelte";
import Input from "$lib/components/Input.svelte";
import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js";
import { Button } from "$lib/components/shadcn/button/index.js";
@ -20,8 +19,10 @@
let deleteTickerList = [];
let watchList: any[] = [];
let news = [];
let checkedItems;
let socket;
let allRows = [
{ name: "Volume", rule: "volume", type: "int" },
@ -131,11 +132,34 @@
);
let isLoaded = false;
let searchDataLoaded = false; // Flag to track data loading
let downloadWorker: Worker | undefined;
let displayWatchList;
let allList = data?.getAllWatchlist;
function calculateChange(oldList, newList) {
// Create a map for faster lookups
const newListMap = new Map(newList.map((item) => [item.symbol, item]));
// Use for loop instead of forEach for better performance
for (let i = 0; i < oldList.length; i++) {
const item = oldList[i];
const newItem = newListMap.get(item?.symbol);
if (newItem) {
// Calculate the new changePercentage
const baseLine = item?.price / (1 + item?.changesPercentage / 100);
const newPrice = newItem?.ap;
const newChangePercentage = (newPrice / baseLine - 1) * 100;
// Update the item directly in the oldList
item.price = newPrice;
item.changesPercentage = newChangePercentage;
}
}
return [...oldList];
}
const handleDownloadMessage = (event) => {
isLoaded = false;
watchList = event?.data?.watchlistData ?? [];
@ -149,6 +173,47 @@
});
};
function sendMessage(message) {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON?.stringify(message));
} else {
console.error("WebSocket is not open. Unable to send message.");
}
}
async function websocketRealtimeData() {
try {
socket = new WebSocket(data?.wsURL + "/multiple-realtime-data");
socket.addEventListener("open", () => {
console.log("WebSocket connection opened");
// Initial connection send
const tickerList = watchList?.map((item) => item?.symbol) || [];
sendMessage(tickerList);
});
socket.addEventListener("message", (event) => {
const data = event.data;
try {
const newList = JSON?.parse(data);
if (newList?.length > 0) {
console.log("Received message:", newList);
watchList = calculateChange(watchList, newList);
}
} catch (e) {
console.error("Error parsing WebSocket message:", e);
}
});
socket.addEventListener("close", (event) => {
console.log("WebSocket connection closed:", event.reason);
});
} catch (error) {
console.error("WebSocket connection error:", error);
}
}
async function getWatchlistData() {
const postData = {
watchListId: displayWatchList?.id,
@ -499,6 +564,39 @@
} catch (e) {
console.log(e);
}
if (!$isOpen) {
await websocketRealtimeData();
}
});
let previousList = [];
afterUpdate(async () => {
if (
JSON?.stringify(previousList) !== JSON?.stringify(watchList) &&
typeof socket !== "undefined"
) {
previousList = watchList;
socket?.close();
await new Promise((resolve, reject) => {
socket?.addEventListener("close", resolve);
});
if (socket?.readyState === WebSocket?.CLOSED) {
await websocketRealtimeData();
console.log("connecting again");
}
}
});
onDestroy(() => {
try {
//socket?.send('close')
socket?.close();
} catch (e) {
console.log(e);
}
});
function handleWatchlistModal() {
@ -1136,6 +1234,7 @@
{#each ruleOfList as row}
{#if isChecked(row?.name)}
<td
id={item?.symbol}
class="whitespace-nowrap text-sm sm:text-[1rem] text-end text-white border-b-[#09090B]"
>
{#if item?.[row?.rule] !== undefined && item?.[row?.rule] !== null}