fix performance from useCoins

This commit is contained in:
dohsimpson
2025-01-08 18:39:36 -05:00
parent 25798e3e8e
commit 8bbd684873
4 changed files with 101 additions and 69 deletions

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## Version 0.1.16
### Fixed
- fix performance
## Version 0.1.15 ## Version 0.1.15
### Fixed ### Fixed

View File

@@ -1,73 +1,24 @@
import { useAtom } from 'jotai' 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 { addCoins, removeCoins } from '@/app/actions/data'
import { toast } from '@/hooks/use-toast' import { toast } from '@/hooks/use-toast'
import { getTodayInTimezone, isSameDate, t2d } from '@/lib/utils'
export function useCoins() { export function useCoins() {
const [coins, setCoins] = useAtom(coinsAtom) const [coins, setCoins] = useAtom(coinsAtom)
const [settings] = useAtom(settingsAtom) const [settings] = useAtom(settingsAtom)
const [coinsEarnedToday] = useAtom(coinsEarnedTodayAtom)
const getTotalEarned = () => { const [totalEarned] = useAtom(totalEarnedAtom)
return coins.transactions const [totalSpent] = useAtom(totalSpentAtom)
.filter(t => { const [coinsSpentToday] = useAtom(coinsSpentTodayAtom)
if (t.type === 'HABIT_COMPLETION' && t.relatedItemId) { const [transactionsToday] = useAtom(transactionsTodayAtom)
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 add = async (amount: number, description: string) => { const add = async (amount: number, description: string) => {
if (isNaN(amount) || amount <= 0) { if (isNaN(amount) || amount <= 0) {
@@ -105,10 +56,10 @@ export function useCoins() {
remove, remove,
balance: coins.balance, balance: coins.balance,
transactions: coins.transactions, transactions: coins.transactions,
coinsEarnedToday: getCoinsEarnedToday(), coinsEarnedToday,
totalEarned: getTotalEarned(), totalEarned,
totalSpent: getTotalSpent(), totalSpent,
coinsSpentToday: getCoinsSpentToday(), coinsSpentToday,
transactionsToday: getTransactionsToday() transactionsToday
} }
} }

View File

@@ -5,8 +5,83 @@ import {
getDefaultCoinsData, getDefaultCoinsData,
getDefaultWishlistData getDefaultWishlistData
} from "./types"; } from "./types";
import { getTodayInTimezone, isSameDate, t2d } from "@/lib/utils";
export const settingsAtom = atom(getDefaultSettings()); export const settingsAtom = atom(getDefaultSettings());
export const habitsAtom = atom(getDefaultHabitsData()); export const habitsAtom = atom(getDefaultHabitsData());
export const coinsAtom = atom(getDefaultCoinsData()); export const coinsAtom = atom(getDefaultCoinsData());
export const wishlistAtom = atom(getDefaultWishlistData()); 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;
});

View File

@@ -1,6 +1,6 @@
{ {
"name": "habittrove", "name": "habittrove",
"version": "0.1.15", "version": "0.1.16",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev --turbopack",