fix: address review findings for snatch notifications (#151)
- Extract relativeTime and formatTokenAmount to helper.ts, eliminating duplicated logic between CollapseHistory and NotificationBell - Use formatUnits (via formatTokenAmount) instead of Number(BigInt)/1e18 to avoid precision loss on large token amounts - Fix allRecentSnatches emptying after mark-seen: now runs two parallel queries — one filtered by lastSeen timestamp (unseen badge count) and one unfiltered (panel history), so history is preserved after opening - Remove dead no-op watch block from useSnatchNotifications Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
60d0859eb3
commit
2fffd2a567
4 changed files with 78 additions and 92 deletions
|
|
@ -18,7 +18,7 @@
|
|||
<div class="notification-bell__event-details">
|
||||
<div class="notification-bell__event-title">Position snatched</div>
|
||||
<div class="notification-bell__event-meta">
|
||||
<span>{{ formatKrk(event.tokenAmount) }} $KRK</span>
|
||||
<span>{{ formatTokenAmount(event.tokenAmount, 18, 2) }} $KRK</span>
|
||||
<span class="notification-bell__event-time">{{ relativeTime(event.timestamp) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -35,6 +35,7 @@ import { Icon } from '@iconify/vue';
|
|||
import { useSnatchNotifications } from '@/composables/useSnatchNotifications';
|
||||
import { useWallet } from '@/composables/useWallet';
|
||||
import { DEFAULT_CHAIN_ID } from '@/config';
|
||||
import { relativeTime, formatTokenAmount } from '@/utils/helper';
|
||||
|
||||
const wallet = useWallet();
|
||||
const chainId = wallet.account.chainId ?? DEFAULT_CHAIN_ID;
|
||||
|
|
@ -43,29 +44,6 @@ const { unseenCount, allRecentSnatches, isOpen, toggle, close } = useSnatchNotif
|
|||
|
||||
const bellRef = ref<HTMLElement | null>(null);
|
||||
|
||||
function formatKrk(raw: string): string {
|
||||
try {
|
||||
const val = Number(BigInt(raw)) / 1e18;
|
||||
return val.toFixed(2);
|
||||
} catch {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
function relativeTime(ts: string): string {
|
||||
try {
|
||||
const sec = Number(ts);
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
const diff = nowSec - sec;
|
||||
if (diff < 60) return 'just now';
|
||||
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
|
||||
if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
|
||||
return `${Math.floor(diff / 86400)}d ago`;
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickOutside(event: MouseEvent) {
|
||||
if (bellRef.value && !bellRef.value.contains(event.target as Node)) {
|
||||
close();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ import type { Position } from '@/composables/usePositions';
|
|||
import FCollapse from '@/components/fcomponents/FCollapse.vue';
|
||||
import FTag from '@/components/fcomponents/FTag.vue';
|
||||
import { RouterLink } from 'vue-router';
|
||||
import { compactNumber } from '@/utils/helper';
|
||||
import { compactNumber, relativeTime, formatTokenAmount } from '@/utils/helper';
|
||||
import { calculateClosedPositionProfit } from 'kraiken-lib/position';
|
||||
import { computed } from 'vue';
|
||||
|
||||
|
|
@ -69,29 +69,12 @@ const profit = computed(() => {
|
|||
|
||||
const payoutKrk = computed(() => {
|
||||
if (!props.position.payout) return null;
|
||||
try {
|
||||
const raw = BigInt(props.position.payout);
|
||||
// payout is stored in wei (18 decimals)
|
||||
const krk = Number(raw) / 1e18;
|
||||
return krk.toFixed(4);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return formatTokenAmount(props.position.payout);
|
||||
});
|
||||
|
||||
const relativeClosedAt = computed(() => {
|
||||
if (!props.position.closedAt) return null;
|
||||
try {
|
||||
const ts = Number(props.position.closedAt);
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
const diffSec = nowSec - ts;
|
||||
if (diffSec < 60) return 'just now';
|
||||
if (diffSec < 3600) return `${Math.floor(diffSec / 60)}m ago`;
|
||||
if (diffSec < 86400) return `${Math.floor(diffSec / 3600)}h ago`;
|
||||
return `${Math.floor(diffSec / 86400)}d ago`;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return relativeTime(props.position.closedAt) || null;
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue