Skip to content

Commit

Permalink
feat: add dynamic component for events
Browse files Browse the repository at this point in the history
  • Loading branch information
pociej committed Jun 2, 2024
1 parent a579acc commit 6e4c7f2
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 75 deletions.
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"dayjs": "^1.11.10",
"debug": "^4.3.4",
"ethereumjs-util": "^7.1.5",
"framer-motion": "^11.0.23",
"framer-motion": "^11.0.24",
"install": "^0.13.0",
"js-big-decimal": "^2.0.7",
"notistack": "^3.0.1",
"ramda": "^0.29.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/home.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Layout } from "./layout/layout";
import { TopBar } from "./homePage/topBar";
import { Events } from "./homePage/events";
import { Events } from "./homePage/events/events";
import { Status } from "./homePage/status";
import { Action } from "./homePage/action";
import { LayoutProvider } from "./providers/layoutProvider";
Expand Down
22 changes: 0 additions & 22 deletions frontend/src/components/homePage/events.tsx

This file was deleted.

58 changes: 58 additions & 0 deletions frontend/src/components/homePage/events/event.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Event, EventType, Payload } from "types/events";

import { Card } from "react-daisyui";

import { motion } from "framer-motion";
const variants = {
visible: { opacity: 1, transition: { duration: 1 } },
hidden: { opacity: 0, transition: { duration: 1 } },
};

const AllocationCreatedEvent = (event: {
kind: Event.ALLOCATION_CREATED;
payload: Payload[Event.ALLOCATION_CREATED];
}) => {
return (
<Card bordered={true}>
<Card.Body>
<Card.Title>Allocation Created</Card.Title>
<div>
<div>Allocation ID: {event.payload.allocationId}</div>
<div>Amount: {event.payload.amount}</div>
<div>Recipient: {event.payload.validityTimestamp}</div>
</div>
</Card.Body>
</Card>
);
};

const AllocationReleasedEvent = (event: {
kind: Event.ALLOCATION_RELEASED;
payload: Payload[Event.ALLOCATION_RELEASED];
}) => {
return (
<Card bordered={true}>
<Card.Body>
<Card.Title>Allocation Released</Card.Title>
<div>
<div>Allocation ID: {event.payload.allocationId}</div>
</div>
</Card.Body>
</Card>
);
};

export const EventCard = (event: EventType) => {
return (
<motion.div variants={variants} initial="hidden" animate="visible">
{(() => {
switch (event.kind) {
case Event.ALLOCATION_CREATED:
return <AllocationCreatedEvent {...event} />;
case Event.ALLOCATION_RELEASED:
return <AllocationReleasedEvent {...event} />;
}
})()}
</motion.div>
);
};
40 changes: 35 additions & 5 deletions frontend/src/components/homePage/events/events.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import { EventType } from "types/events";
import { useAllocationEvents } from "hooks/events/useAllocationEvents";
import { EventCard } from "./event";
import { uniqBy } from "ramda";
import { use } from "i18next";

export const Events = () => {
const [events, setEvents] = useState<EventType[]>([]);
const [events, setEvents] = useState<
(EventType & {
id: number;
timestamp: number;
})[]
>([]);
const { events$: allocationEvents$ } = useAllocationEvents();

allocationEvents$.subscribe((event) => {
setEvents((prevEvents) => [...prevEvents, event]);
});
useEffect(() => {
console.log("subscribing");
const sub = allocationEvents$.subscribe((event) => {
console.log("new event", event);
setEvents((prevEvents) => {
return uniqBy(
(e) => {
return `${e.kind}-${e.id}`;
},
[...prevEvents, event]
);
});
});
return () => {
console.log("unsubscribing");
};
}, [allocationEvents$]);

return (
<>
{events.map((event, index) => {
return <EventCard key={index} {...event} />;
})}
</>
);
};
30 changes: 19 additions & 11 deletions frontend/src/components/homePage/statusSections/allocation.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { AllocationLink } from "components/alloctionLink";
import { useCreateAllocationEvents } from "hooks/events/useCreateAllocationEvents";
import { useReleaseAllocationEvents } from "hooks/events/useReleaseAllocationEvents";
import { useCreateAllocation } from "hooks/useCreateAllocation";
import { useCurrentAllocation } from "hooks/useCurrentAllocation";
import { useReleaseAllocation } from "hooks/useReleaseAllocation";
import { useUser } from "hooks/useUser";
import { Loading } from "react-daisyui";
import { Event } from "types/events";
import { formatBalance } from "utils/formatBalance";

Expand All @@ -14,8 +14,8 @@ export const Allocation = () => {
const { currentAllocation } = useCurrentAllocation();
const { releaseAllocation } = useReleaseAllocation();
const { user } = useUser();
const { events$, emit } = useCreateAllocationEvents();

const { emit: emitCreateAllocation } = useCreateAllocationEvents();
const { emit: emitReleaseAllocation } = useReleaseAllocationEvents();
return (
<div className="stats shadow mt-2 ">
<div
Expand Down Expand Up @@ -76,18 +76,26 @@ export const Allocation = () => {
<button
className="btn"
onClick={() => {
emit({
kind: Event.ALLOCATION_CREATED,
payload: {
amount: 100,
allocationId: "123",
validityTimestamp: Date.now() + 1000 * 60 * 60 * 24 * 30,
},
emitReleaseAllocation({
allocationId: "123",
});
}}
>
{" "}
Create{" "}
</button>
<button
className="btn"
onClick={() => {
emitCreateAllocation({
amount: 100,
allocationId: "123",
validityTimestamp: Date.now() + 1000 * 60 * 60 * 24 * 30,
});
}}
>
{" "}
Dupa{" "}
Create{" "}
</button>
{/* {isCreatingAllocation ? (
<Loading variant="infinity" />
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/hooks/events/useAllocationEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { useCreateAllocationEvents } from "./useCreateAllocationEvents";
import { useReleaseAllocationEvents } from "./useReleaseAllocationEvents";

export const useAllocationEvents = () => {
console.log("useAllocationEvents");
const { events$: createAllocationEvents$ } = useCreateAllocationEvents();
const { events$: releaseAllocationEvents$ } = useReleaseAllocationEvents();

return {
events$: merge([createAllocationEvents$, releaseAllocationEvents$]),
events$: merge(releaseAllocationEvents$, createAllocationEvents$),
};
};
82 changes: 49 additions & 33 deletions frontend/src/hooks/events/useSyncExternalEvent.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
import { useCallback, useMemo, useSyncExternalStore } from "react";
import {
useCallback,
useEffect,
useMemo,
useRef,
useSyncExternalStore,
} from "react";
import { Subject } from "rxjs";
import { Payload, Event } from "types/events";
import { useCall } from "wagmi";
import { Payload, Event, ExtractPayload } from "types/events";

const getId = (e: any) => e.id;
export const useSyncExternalEvents = ({

export const useSyncExternalEvents = <K extends Event>({
key,
eventKind,
}: {
key: string;
eventKind: Event;
eventKind: K;
}) => {
const events$ = useMemo(() => {
console.log("werwe");
return new Subject<{
kind: typeof eventKind;
kind: K;
payload: Payload[typeof eventKind];
id: number;
timestamp: number;
}>();
}, []);

const store = useMemo(() => {
return {
getSnapshot: () => {
return localStorage.getItem(key);
},
subscribe: () => {
const callback = (event: StorageEvent) => {
const lastEvent = JSON.parse(event.newValue || "[]").find(
(e: any) =>
!JSON.parse(event.oldValue || "[]")
.map(getId)
.includes(e.id)
) as { kind: typeof eventKind; payload: Payload[typeof eventKind] };
if (lastEvent) {
events$.next(lastEvent);
}
};
window.addEventListener("storage", callback);
return () => {
window.removeEventListener("storage", callback);
};
},
};
}, []);
const previousEvents = useRef<any[]>([]);

const store = useRef({
getSnapshot: () => {
const events = localStorage.getItem(key);
return events;
},
subscribe: (listener: () => void) => {
window.addEventListener("storage", listener);
return () => {
window.removeEventListener("storage", listener);
};
},
});

const emit = useCallback((payload: Payload[typeof eventKind]) => {
const emit = useCallback((payload: ExtractPayload<K>) => {
const currentEvents = JSON.parse(localStorage.getItem(key) || "[]");
const newEvents = [
...currentEvents,
Expand All @@ -57,7 +56,6 @@ export const useSyncExternalEvents = ({
},
];
localStorage.setItem(key, JSON.stringify(newEvents));
console.log("emitting", newEvents);
window.dispatchEvent(
new StorageEvent("storage", {
key,
Expand All @@ -67,9 +65,27 @@ export const useSyncExternalEvents = ({
);
}, []);

const currentEvents = useSyncExternalStore(
store.current.subscribe,
store.current.getSnapshot
);

useEffect(() => {
console.log("allo");
if (currentEvents) {
console.log("currentEvents", currentEvents);
const events = JSON.parse(currentEvents);
events.forEach((e: any) => {
if (e.kind === eventKind) {
console.log("proper kins");
console.log("calling next");
events$.next(e);
}
});
}
}, [currentEvents]);
return {
events$,
emit,
currentEvents: useSyncExternalStore(store.subscribe, store.getSnapshot),
};
};
6 changes: 5 additions & 1 deletion frontend/src/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type Payload = {
agreementId: string;
};
[Event.ALLOCATION_RELEASED]: {
agreementId: string;
allocationId: string;
};
[Event.PAYMENT_FOR_GAS]: {
agreementId: string;
Expand All @@ -59,3 +59,7 @@ export type Payload = {
};

export type EventType = EventWithPayload<Payload>;

export type ExtractPayload<K extends Event> = K extends keyof Payload
? Payload[K]
: never;

0 comments on commit 6e4c7f2

Please sign in to comment.