mirror of
https://github.com/aljazceru/hypergolic.git
synced 2025-12-18 22:14:21 +01:00
problem: not clear when someone makes a purchase
resolve https://github.com/nostrocket/hypergolic/issues/94
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { ndk } from '@/ndk.js';
|
||||
import { Chart } from 'flowbite-svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import { Toaster } from '$lib/components/ui/sonner';
|
||||
export let data: { pubkey: string; merits: number; sats: number }[];
|
||||
|
||||
let pubkeys = Array.from(data, (x) => x.pubkey);
|
||||
@@ -130,4 +131,9 @@
|
||||
// </Card>
|
||||
</script>
|
||||
|
||||
<Chart options={$o} class="py-6" />
|
||||
<div class="relative h-full w-full">
|
||||
<Chart options={$o} class="py-6" />
|
||||
<div class="absolute left-1/2 top-0 z-20 w-[356px] -translate-x-1/2 transform">
|
||||
<Toaster position="top-center" id="purchase" duration={10000} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
48
src/components/PruchaseToast.svelte
Normal file
48
src/components/PruchaseToast.svelte
Normal file
@@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
import { Avatar, Name } from '@nostr-dev-kit/ndk-svelte-components';
|
||||
import { ndk } from '@/ndk';
|
||||
import { unixToRelativeTime } from '@/helpers';
|
||||
import { fetchEvent } from '@/event_helpers/products';
|
||||
import { Product, Rocket, type ZapPurchase } from '@/event_helpers/rockets';
|
||||
|
||||
export let zapPurchase: ZapPurchase;
|
||||
export let rocket: Rocket;
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
{#if zapPurchase.ZapReceipt.content}
|
||||
<div>{zapPurchase.ZapReceipt.content}</div>
|
||||
{:else}
|
||||
<!-- Sometimes ZapReceipt.content is empty -->
|
||||
{#await fetchEvent(zapPurchase.ProductID, $ndk)}
|
||||
<div>New purchase</div>
|
||||
{:then product}
|
||||
<div>{`Purchase of ${new Product(product).Name()} from ${rocket.Name()}.`}</div>
|
||||
{/await}
|
||||
{/if}
|
||||
{#if zapPurchase.BuyerPubkey}
|
||||
<div class="flex flex-nowrap gap-1">
|
||||
<Avatar
|
||||
ndk={$ndk}
|
||||
pubkey={zapPurchase.BuyerPubkey}
|
||||
class="h-10 w-10 flex-none rounded-full object-cover"
|
||||
/>
|
||||
<Name
|
||||
ndk={$ndk}
|
||||
pubkey={zapPurchase.BuyerPubkey}
|
||||
class="hidden max-w-32 truncate p-2 md:inline-block"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if zapPurchase.Amount}
|
||||
<div>
|
||||
Amount: {(zapPurchase.Amount / 1000).toFixed(0)}
|
||||
{(zapPurchase.Amount / 1000).toFixed(0) === '1' ? 'sat' : 'sats'}
|
||||
</div>
|
||||
{/if}
|
||||
{#if zapPurchase.ZapReceipt.created_at}
|
||||
<div>
|
||||
{unixToRelativeTime(zapPurchase.ZapReceipt.created_at * 1000)}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -2,8 +2,10 @@
|
||||
import * as Breadcrumb from '$lib/components/ui/breadcrumb/index.js';
|
||||
import Button from '@/components/ui/button/button.svelte';
|
||||
import * as Card from '@/components/ui/card';
|
||||
import PurchaseToast from './PruchaseToast.svelte';
|
||||
import { Rocket, ZapPurchase } from '@/event_helpers/rockets';
|
||||
import { devmode } from '@/stores/session';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import type { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import BitcoinAssociations from './AssociatedBitcoinAddresses.svelte';
|
||||
import MeritRequests from './MeritRequests.svelte';
|
||||
@@ -11,10 +13,47 @@
|
||||
import ProductFomo from './ProductFomo.svelte';
|
||||
import ProposedProducts from './ProposedProducts.svelte';
|
||||
import UpdateMission from './UpdateMission.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let rocket: NDKEvent;
|
||||
|
||||
$: unratifiedZaps = new Map<string, ZapPurchase>();
|
||||
let lastCheckTime = Date.now() / 1000; // Current time in seconds
|
||||
|
||||
function checkNewZaps() {
|
||||
const currentTime = Date.now() / 1000;
|
||||
const recentZaps = Array.from(unratifiedZaps.values()).filter(
|
||||
(zap) =>
|
||||
zap.ZapReceipt.created_at &&
|
||||
zap.ZapReceipt.created_at > lastCheckTime &&
|
||||
zap.ZapReceipt.created_at <= currentTime
|
||||
);
|
||||
|
||||
recentZaps.forEach((zapPurchase) => {
|
||||
toast(PurchaseToast, {
|
||||
componentProps: {
|
||||
zapPurchase,
|
||||
rocket: new Rocket(rocket)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
lastCheckTime = currentTime;
|
||||
}
|
||||
$: {
|
||||
if (unratifiedZaps.size > 0) {
|
||||
checkNewZaps();
|
||||
}
|
||||
}
|
||||
onMount(() => {
|
||||
lastCheckTime = Date.now() / 1000 - 30; // 30 seconds ago
|
||||
});
|
||||
|
||||
$: lasted = Array.from(unratifiedZaps.values()).sort((a, b) => {
|
||||
if (a.ZapReceipt.created_at && b.ZapReceipt.created_at) {
|
||||
return b.ZapReceipt.created_at - a.ZapReceipt.created_at;
|
||||
} else return 0;
|
||||
})[0];
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -32,6 +71,27 @@
|
||||
</Breadcrumb.Root>
|
||||
</header>
|
||||
<main class="grid w-full flex-1 grid-cols-1 items-start gap-4 sm:grid-cols-3 md:gap-2">
|
||||
{#if $devmode}
|
||||
<Button
|
||||
on:click={() => {
|
||||
if (!lasted) {
|
||||
toast('unratifiedZaps is null');
|
||||
} else {
|
||||
console.log(lasted);
|
||||
toast(PurchaseToast, {
|
||||
componentProps: {
|
||||
zapPurchase: lasted,
|
||||
rocket: new Rocket(rocket)
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
variant="outline">Popup Last Purchase Notification</Button
|
||||
>
|
||||
<Button variant="outline" on:click={() => console.log(Array.from(unratifiedZaps.values()))}
|
||||
>print unratifiedZaps</Button
|
||||
>
|
||||
{/if}
|
||||
<MeritsAndSatflow {unratifiedZaps} rocket={new Rocket(rocket)} />
|
||||
|
||||
<ProductFomo bind:unratifiedZaps rocket={new Rocket(rocket)} />
|
||||
|
||||
@@ -27,16 +27,19 @@
|
||||
sessionStarted = true;
|
||||
}
|
||||
|
||||
onMount(()=>{getBitcoinTip();})
|
||||
|
||||
setInterval(function () {
|
||||
onMount(() => {
|
||||
getBitcoinTip();
|
||||
}, 2* 60 * 1000);
|
||||
});
|
||||
|
||||
setInterval(
|
||||
function () {
|
||||
getBitcoinTip();
|
||||
},
|
||||
2 * 60 * 1000
|
||||
);
|
||||
</script>
|
||||
|
||||
<ModeWatcher defaultMode="dark" />
|
||||
<SidePanelLayout>
|
||||
<div slot="content"><slot></slot></div>
|
||||
</SidePanelLayout>
|
||||
|
||||
<style></style>
|
||||
|
||||
Reference in New Issue
Block a user