Skip to content

Commit

Permalink
Simplify walletSlice for activities
Browse files Browse the repository at this point in the history
The previous solution was hard to understand what's the difference between transactions and activities. Instead of using the term transaction, we will keep all activities and use selectors to check which ones are completed. While `latestActivities` will be used to display notifications to the user.
  • Loading branch information
kkosiorowska committed May 27, 2024
1 parent acd81b7 commit 6f45140
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 46 deletions.
12 changes: 6 additions & 6 deletions dapp/src/components/shared/ActivitiesList/ActivitiesList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react"
import { List, ListItem, ListProps } from "@chakra-ui/react"
import { AnimatePresence, Variants, motion } from "framer-motion"
import { useActivitiesNEW as useActivities, useAppDispatch } from "#/hooks"
import { deleteActivity } from "#/store/wallet"
import { useAppDispatch, useLatestActivities } from "#/hooks"
import { deleteLatestActivity } from "#/store/wallet"
import ActivitiesListItem from "./ActivitiesListItem"

const MotionList = motion(List)
Expand All @@ -15,18 +15,18 @@ const listItemVariants: Variants = {

function ActivitiesList(props: ListProps) {
const dispatch = useAppDispatch()
const activities = useActivities()
const latestActivities = useLatestActivities()

const handleItemDismiss = (activityId: string) => {
dispatch(deleteActivity(activityId))
dispatch(deleteLatestActivity(activityId))
}

if (activities.length === 0) return null
if (latestActivities.length === 0) return null

return (
<MotionList pos="relative" {...props}>
<AnimatePresence mode="popLayout">
{activities.map((item) => (
{latestActivities.map((item) => (
<MotionListItem
key={item.id}
layout="position"
Expand Down
5 changes: 2 additions & 3 deletions dapp/src/hooks/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ export * from "./useActionFlowType"
export * from "./useActionFlowStatus"
export * from "./useActionFlowActiveStep"
export * from "./useActionFlowTokenAmount"
// TODO: Rename when the old hook is deleted.
export { useActivities as useActivitiesNEW } from "./useActivities"
export * from "./useTransactions"
export * from "./useCompletedActivities"
export * from "./useLatestActivities"
6 changes: 0 additions & 6 deletions dapp/src/hooks/store/useActivities.ts

This file was deleted.

6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useCompletedActivities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectCompletedActivities } from "#/store/wallet"
import { useAppSelector } from "./useAppSelector"

export function useCompletedActivities() {
return useAppSelector(selectCompletedActivities)
}
6 changes: 6 additions & 0 deletions dapp/src/hooks/store/useLatestActivities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { selectLatestActivities } from "#/store/wallet"
import { useAppSelector } from "./useAppSelector"

export function useLatestActivities() {
return useAppSelector(selectLatestActivities)
}
6 changes: 0 additions & 6 deletions dapp/src/hooks/store/useTransactions.ts

This file was deleted.

15 changes: 9 additions & 6 deletions dapp/src/store/wallet/walletSelector.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Activity } from "#/types"
import { createSelector } from "@reduxjs/toolkit"
import { isActivityCompleted } from "#/utils"
import { RootState } from ".."

export const selectActivities = createSelector(
(state: RootState) => state.wallet.activities,
(activities) => Object.values(activities),
export const selectLatestActivities = createSelector(
(state: RootState) => state.wallet.latestActivities,
(latestActivities) => Object.values(latestActivities),
)

export const selectTransactions = (state: RootState): Activity[] =>
state.wallet.transactions
export const selectCompletedActivities = createSelector(
(state: RootState) => state.wallet.activities,
(activities) =>
activities.filter((activity) => isActivityCompleted(activity)),
)
45 changes: 26 additions & 19 deletions dapp/src/store/wallet/walletSlice.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,56 @@
import { ActivitiesByIds, Activity } from "#/types"
import { isActivityCompleted } from "#/utils"
import { PayloadAction, createSlice } from "@reduxjs/toolkit"

type WalletState = {
activities: ActivitiesByIds
transactions: Activity[]
latestActivities: ActivitiesByIds
activities: Activity[]
}

const initialState: WalletState = {
activities: {},
transactions: [],
latestActivities: {},
activities: [],
}

export const walletSlice = createSlice({
name: "wallet",
initialState,
reducers: {
setTransactions(state, action: PayloadAction<Activity[]>) {
state.transactions = action.payload
},
setActivities(state, action: PayloadAction<Activity[]>) {
const newActivitiesByIds = Object.fromEntries(
action.payload.map((activity) => [activity.id, activity]),
const allActivities = action.payload

const pendingActivities = allActivities.reduce<[string, Activity][]>(
(acc, activity) => {
if (!isActivityCompleted(activity)) acc.push([activity.id, activity])

return acc
},
[],
)
const newActivitiesIds = new Set(Object.keys(newActivitiesByIds))
const pendingActivitiesByIds = Object.fromEntries(pendingActivities)
const pendingActivitiesIds = Object.keys(pendingActivities)

const { latestActivities } = state
const updatedActivitiesByIds = Object.values(
state.activities,
latestActivities,
).reduce<ActivitiesByIds>((acc, activity) => {
if (!newActivitiesIds.has(activity.id)) {
if (!pendingActivitiesIds.includes(activity.id))
acc[activity.id] = { ...activity, status: "completed" }
}

return acc
}, {})

state.activities = Object.assign(
state.activities = allActivities
state.latestActivities = Object.assign(
updatedActivitiesByIds,
newActivitiesByIds,
pendingActivitiesByIds,
)
},
deleteActivity(state, action: PayloadAction<string>) {
deleteLatestActivity(state, action: PayloadAction<string>) {
const activityId = action.payload
delete state.activities[activityId]
delete state.latestActivities[activityId]
},
},
})

export const { setTransactions, setActivities, deleteActivity } =
walletSlice.actions
export const { setActivities, deleteLatestActivity } = walletSlice.actions
4 changes: 4 additions & 0 deletions dapp/src/utils/activities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Activity } from "#/types"

export const isActivityCompleted = (activity: Activity): boolean =>
activity.status === "completed"
1 change: 1 addition & 0 deletions dapp/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from "./exchangeApi"
export * from "./verifyDepositAddress"
export * from "./json"
export * from "./subgraphAPI"
export * from "./activities"

0 comments on commit 6f45140

Please sign in to comment.