Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit

Permalink
refactor: websocket logic in spotlights
Browse files Browse the repository at this point in the history
  • Loading branch information
ruilopesm committed Feb 6, 2024
1 parent 150026e commit eae5a1b
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 165 deletions.
56 changes: 28 additions & 28 deletions components/Layout/components/Banner.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ISpotlight, useNotify } from "@context/Notification";
import { displayRemainingTime } from "@lib/time";
import { compareDates, displayRemainingTime } from "@lib/time";
import { motion as Motion } from "framer-motion";
import Link from "next/link";
import { useEffect, useState } from "react";

function PlainBanner({ spotlight }: { spotlight: ISpotlight }) {
const [remaining, setRemaining] = useState("");
const [remaining, setRemaining] = useState(
displayRemainingTime(spotlight.end)
);

useEffect(() => {
const timerID = setInterval(() => {
Expand Down Expand Up @@ -74,33 +76,31 @@ function PlainBanner({ spotlight }: { spotlight: ISpotlight }) {

export default function Banner() {
const { spotlight } = useNotify();
const [lastSpotlight, setLastSpotlight] = useState(null);

useEffect(() => {
if (spotlight) {
setLastSpotlight(spotlight);
}
}, [spotlight]);
if (spotlight) {
const dateDifferenceinMs: number =
new Date(spotlight.end).getTime() - new Date().getTime();

if (!lastSpotlight) {
return null;
} else if (spotlight) {
return (
<Motion.div
initial={{ y: -100, height: 0 }}
animate={{ y: 0, height: "auto" }}
>
<PlainBanner spotlight={spotlight} />
</Motion.div>
);
} else {
return (
<Motion.div
initial={{ y: 0, height: "auto" }}
animate={{ y: -100, height: 0 }}
>
<PlainBanner spotlight={lastSpotlight} />
</Motion.div>
);
if (dateDifferenceinMs > 0) {
return (
<Motion.div
initial={{ y: -100, height: 0 }}
animate={{ y: 0, height: "auto" }}
>
<PlainBanner spotlight={spotlight} />
</Motion.div>
);
} else if (dateDifferenceinMs >= -1000) {
return (
<Motion.div
initial={{ y: 0, height: "auto" }}
animate={{ y: -100, height: 0 }}
>
<PlainBanner spotlight={spotlight} />
</Motion.div>
);
}
}

return null;
}
47 changes: 29 additions & 18 deletions context/Notification/NotifyContext.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
import { NotificationData, fetchers } from "./fetchers";
import { useContext, createContext, useState, useEffect } from "react";
import { Socket, io } from "socket.io-client";
import { Socket } from "phoenix";

export interface ISpotlight {
id: number;
name: string;
badge_id: number;
end: string;
}

type NotificationData = {
spotlight: ISpotlight;
};

const NotifyContext = createContext({} as NotificationData);

export const useNotify = () => useContext<NotificationData>(NotifyContext);

export function NotifyProvider({ children }) {
const initialValue = Object.fromEntries(
Object.entries(fetchers).map(([k, v]) => [k, v.initialValue])
);
const getPushUrl = () => {
return process.env.NEXT_PUBLIC_WS_URL;
};

const [socket, setSocket] = useState<Socket>(null);
const [value, setValue] = useState(initialValue as NotificationData);
export function NotifyProvider({ children }) {
const [value, setValue] = useState({ spotlight: null } as NotificationData);

useEffect(() => {
fetch("/api/notifications").finally(() => {
const s = io();
const socket = new Socket(getPushUrl(), {
reconnectAfterMs: () => 10000,
rejoinAfterMs: () => 10000,
heartbeatIntervalMs: 30000,
});

socket.connect();
const channel = socket.channel("spotlight");

Object.keys(fetchers).forEach((key) => {
s.on(key, (data) => {
setValue({ ...value, [key]: data });
});
});
channel.join();

setSocket(s);
channel.on("spotlight", (data: ISpotlight) => {
setValue({ ...value, spotlight: data });
});

return () => {
socket?.disconnect();
setSocket(null);
socket.disconnect();
};
}, []);

Expand Down
54 changes: 54 additions & 0 deletions context/Notification/WebSocket.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useState, useEffect } from "react";
import { Socket } from "phoenix";

const getPushUrl = () => {
return `ws://${process.env.NEXT_PUBLIC_API_URL}/socket`;
};

function useWebSocket({ room, onNewMessage }) {
const [channel, setChannel] = useState();
const [connected, setConnected] = useState(false);

useEffect(() => {
if (room) {
const socket = new Socket(getPushUrl(), {
reconnectAfterMs: () => 10000,
rejoinAfterMs: () => 10000,
heartbeatIntervalMs: 30000,
});

socket.connect();
const channel = socket.channel(room);

setChannel(channel);
channel
.join()
.receive("ok", () => {
setConnected(true);
})
.receive("error", () => {
setConnected(false);
});

if (onNewMessage) {
channel.on("spotlight", onNewMessage);
}

return () => {
setConnected(false);
socket.disconnect();
};
}

return () => {};
}, []);

useEffect(() => {
channel?.off("spotlight");
channel?.on("spotlight", onNewMessage);
}, [onNewMessage]);

return { connected, channel };
}

export default useWebSocket;
53 changes: 0 additions & 53 deletions context/Notification/fetchers.ts

This file was deleted.

2 changes: 1 addition & 1 deletion context/Notification/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export type { ISpotlight } from "./fetchers";
export type { ISpotlight } from "./NotifyContext";
export { NotifyProvider, useNotify } from "./NotifyContext";
8 changes: 7 additions & 1 deletion lib/time.js → lib/time.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function displayRemainingTime(end) {
export function displayRemainingTime(end: string) {
const now = new Date();
const endTime = new Date(end);
const timeDifference = endTime.getTime() - now.getTime();
Expand All @@ -15,3 +15,9 @@ export function displayRemainingTime(end) {

return `${formattedMinutes}:${formattedSeconds}`;
}

export function compareDates(a: Date, b: Date) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"jsqr": "^1.4.0",
"lottie-web": "^5.8.1",
"next": "^13.4.19",
"phoenix": "^1.7.7",
"qrcode": "^1.5.1",
"react": "^18.2.0",
"react-cool-inview": "^2.0.8",
Expand Down
64 changes: 0 additions & 64 deletions pages/api/notifications.ts

This file was deleted.

0 comments on commit eae5a1b

Please sign in to comment.