Skip to content

Commit

Permalink
fix performance from useCoins
Browse files Browse the repository at this point in the history
  • Loading branch information
dohsimpson committed Jan 8, 2025
1 parent 25798e3 commit 8bbd684
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 69 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Version 0.1.16

### Fixed

- fix performance

## Version 0.1.15

### Fixed
Expand Down
87 changes: 19 additions & 68 deletions hooks/useCoins.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,24 @@
import { useAtom } from 'jotai'
import { coinsAtom, settingsAtom } from '@/lib/atoms'
import {
coinsAtom,
settingsAtom,
coinsEarnedTodayAtom,
totalEarnedAtom,
totalSpentAtom,
coinsSpentTodayAtom,
transactionsTodayAtom
} from '@/lib/atoms'
import { addCoins, removeCoins } from '@/app/actions/data'
import { toast } from '@/hooks/use-toast'
import { getTodayInTimezone, isSameDate, t2d } from '@/lib/utils'

export function useCoins() {
const [coins, setCoins] = useAtom(coinsAtom)
const [settings] = useAtom(settingsAtom)

const getTotalEarned = () => {
return coins.transactions
.filter(t => {
if (t.type === 'HABIT_COMPLETION' && t.relatedItemId) {
return !coins.transactions.some(undoT =>
undoT.type === 'HABIT_UNDO' &&
undoT.relatedItemId === t.relatedItemId
)
}
return t.amount > 0 && t.type !== 'HABIT_UNDO'
})
.reduce((sum, t) => sum + t.amount, 0)
}

const getTotalSpent = () => {
return Math.abs(
coins.transactions
.filter(t => t.type === 'WISH_REDEMPTION' || t.type === 'MANUAL_ADJUSTMENT')
.reduce((sum, t) => sum + (t.amount < 0 ? t.amount : 0), 0)
)
}

const getCoinsEarnedToday = () => {
const today = getTodayInTimezone(settings.system.timezone)
return coins.transactions
.filter(transaction =>
isSameDate(t2d({ timestamp: transaction.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone }))
)
.reduce((sum, transaction) => {
if (transaction.type !== 'HABIT_UNDO' && transaction.amount > 0) {
return sum + transaction.amount
}
if (transaction.type === 'HABIT_UNDO') {
return sum - Math.abs(transaction.amount)
}
return sum
}, 0)
}

const getCoinsSpentToday = () => {
const today = getTodayInTimezone(settings.system.timezone)
return Math.abs(
coins.transactions
.filter(t =>
isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone })) &&
t.amount < 0
)
.reduce((sum, t) => sum + t.amount, 0)
)
}

const getTransactionsToday = () => {
const today = getTodayInTimezone(settings.system.timezone)
return coins.transactions.filter(t =>
isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone }))
).length
}
const [coinsEarnedToday] = useAtom(coinsEarnedTodayAtom)
const [totalEarned] = useAtom(totalEarnedAtom)
const [totalSpent] = useAtom(totalSpentAtom)
const [coinsSpentToday] = useAtom(coinsSpentTodayAtom)
const [transactionsToday] = useAtom(transactionsTodayAtom)

const add = async (amount: number, description: string) => {
if (isNaN(amount) || amount <= 0) {
Expand Down Expand Up @@ -105,10 +56,10 @@ export function useCoins() {
remove,
balance: coins.balance,
transactions: coins.transactions,
coinsEarnedToday: getCoinsEarnedToday(),
totalEarned: getTotalEarned(),
totalSpent: getTotalSpent(),
coinsSpentToday: getCoinsSpentToday(),
transactionsToday: getTransactionsToday()
coinsEarnedToday,
totalEarned,
totalSpent,
coinsSpentToday,
transactionsToday
}
}
75 changes: 75 additions & 0 deletions lib/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,83 @@ import {
getDefaultCoinsData,
getDefaultWishlistData
} from "./types";
import { getTodayInTimezone, isSameDate, t2d } from "@/lib/utils";

export const settingsAtom = atom(getDefaultSettings());
export const habitsAtom = atom(getDefaultHabitsData());
export const coinsAtom = atom(getDefaultCoinsData());
export const wishlistAtom = atom(getDefaultWishlistData());

// Derived atom for coins earned today
export const coinsEarnedTodayAtom = atom((get) => {
const coins = get(coinsAtom);
const settings = get(settingsAtom);
const today = getTodayInTimezone(settings.system.timezone);
return coins.transactions
.filter(transaction =>
isSameDate(t2d({ timestamp: transaction.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone }))
)
.reduce((sum, transaction) => {
if (transaction.type !== 'HABIT_UNDO' && transaction.amount > 0) {
return sum + transaction.amount;
}
if (transaction.type === 'HABIT_UNDO') {
return sum - Math.abs(transaction.amount);
}
return sum;
}, 0);
});

// Derived atom for total earned
export const totalEarnedAtom = atom((get) => {
const coins = get(coinsAtom);
return coins.transactions
.filter(t => {
if (t.type === 'HABIT_COMPLETION' && t.relatedItemId) {
return !coins.transactions.some(undoT =>
undoT.type === 'HABIT_UNDO' &&
undoT.relatedItemId === t.relatedItemId
);
}
return t.amount > 0 && t.type !== 'HABIT_UNDO';
})
.reduce((sum, t) => sum + t.amount, 0);
});

// Derived atom for total spent
export const totalSpentAtom = atom((get) => {
const coins = get(coinsAtom);
return Math.abs(
coins.transactions
.filter(t => t.type === 'WISH_REDEMPTION' || t.type === 'MANUAL_ADJUSTMENT')
.reduce((sum, t) => sum + (t.amount < 0 ? t.amount : 0), 0)
);
});

// Derived atom for coins spent today
export const coinsSpentTodayAtom = atom((get) => {
const coins = get(coinsAtom);
const settings = get(settingsAtom);
const today = getTodayInTimezone(settings.system.timezone);
return Math.abs(
coins.transactions
.filter(t =>
isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone })) &&
t.amount < 0
)
.reduce((sum, t) => sum + t.amount, 0)
);
});

// Derived atom for transactions today
export const transactionsTodayAtom = atom((get) => {
const coins = get(coinsAtom);
const settings = get(settingsAtom);
const today = getTodayInTimezone(settings.system.timezone);
return coins.transactions.filter(t =>
isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }),
t2d({ timestamp: today, timezone: settings.system.timezone }))
).length;
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "habittrove",
"version": "0.1.15",
"version": "0.1.16",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
Expand Down

0 comments on commit 8bbd684

Please sign in to comment.