diff --git a/src/components/Menu.svelte b/src/components/Menu.svelte index d1535a9..26f535f 100644 --- a/src/components/Menu.svelte +++ b/src/components/Menu.svelte @@ -3,8 +3,17 @@ import { page } from '$app/stores'; import { Badge } from '@/components/ui/badge'; import Separator from '@/components/ui/separator/separator.svelte'; - import { currentUser } from '@/stores/session'; - import { GitBranch, HelpCircle, Mail, Package, Pyramid, Rocket, Users } from 'lucide-svelte'; + import { currentUser, devmode } from '@/stores/session'; + import { + Code, + GitBranch, + HelpCircle, + Mail, + Package, + Pyramid, + Rocket, + Users + } from 'lucide-svelte'; import { GitAltBrand, TelegramBrand } from 'svelte-awesome-icons'; let iconClass = 'h-5 w-5 md:h-4 md:w-4'; @@ -57,4 +66,16 @@ Help - + + { + devmode.update((dm) => { + return !dm; + }); + }} +> + + Toggle Dev Mode + diff --git a/src/components/MeritsAndSatflow.svelte b/src/components/MeritsAndSatflow.svelte index 8ec17e2..b9aa6d3 100644 --- a/src/components/MeritsAndSatflow.svelte +++ b/src/components/MeritsAndSatflow.svelte @@ -1,7 +1,7 @@ {#if product.Validate()} @@ -34,18 +66,30 @@ cover {/if} - - {#if !rocket.Products().get(product.ID())} + + {#if !rocket.Products().get(product.ID()) && !productFromRocket} - {:else} - + {:else if productFromRocket} + {#if productFromRocket.MaxPurchases() && unratifiedZaps} +
+ {remainingProducts(productFromRocket, unratifiedZaps)} available +
+ {/if} + 0 && + remainingProducts(productFromRocket, unratifiedZaps) == 0} + {product} + rocketProduct={rocket.Products().get(product.ID())} + {rocket} + /> {/if} - { - console.log(product); - }}>print to console + {#if $devmode} + { + console.log(product); + }}>print to console{/if}
{/if} diff --git a/src/components/ProductCardFromID.svelte b/src/components/ProductCardFromID.svelte index 220ea71..1eb9bac 100644 --- a/src/components/ProductCardFromID.svelte +++ b/src/components/ProductCardFromID.svelte @@ -3,10 +3,11 @@ import { ndk } from '@/ndk'; import ProductCard from './ProductCard.svelte'; import { fetchEvent } from '@/event_helpers/products'; - import { Product, type Rocket } from '@/event_helpers/rockets'; + import { Product, ZapPurchase, type Rocket } from '@/event_helpers/rockets'; export let productID: string | undefined = undefined; export let rocket: Rocket; export let product: Product | undefined = undefined; + export let unratifiedZaps: Map | undefined = undefined; onMount(() => { if (!product && productID) { @@ -16,7 +17,7 @@ {#if product} - + {/if} diff --git a/src/components/ProductFomo.svelte b/src/components/ProductFomo.svelte index 5e4818d..735737d 100644 --- a/src/components/ProductFomo.svelte +++ b/src/components/ProductFomo.svelte @@ -1,6 +1,6 @@ {#if currentPage} - + {#if unratifiedZaps} {/if} diff --git a/src/components/ProductPurchases.svelte b/src/components/ProductPurchases.svelte index b4ee3f0..810d4b7 100644 --- a/src/components/ProductPurchases.svelte +++ b/src/components/ProductPurchases.svelte @@ -11,7 +11,7 @@ //export let products: Product[]; export let rocket: Rocket; - export let unratifiedZaps: Map; + export let unratifiedZaps: Map; let zaps = $ndk.storeSubscribe( [{ '#a': [`31108:${rocket.Event.author.pubkey}:${rocket.Event.dTag}`], kinds: [9735] }], @@ -85,7 +85,7 @@ validatedZapsNotInRocket.subscribe((zaps) => { for (let [_, z] of zaps) { - unratifiedZaps.set(z.ZapReceipt.id, z.Amount); + unratifiedZaps.set(z.ZapReceipt.id, z); } unratifiedZaps = unratifiedZaps; }); diff --git a/src/components/RocketDashboard.svelte b/src/components/RocketDashboard.svelte index 08b897d..1b9940b 100644 --- a/src/components/RocketDashboard.svelte +++ b/src/components/RocketDashboard.svelte @@ -2,7 +2,7 @@ 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 { Rocket } from '@/event_helpers/rockets'; + import { Rocket, ZapPurchase } from '@/event_helpers/rockets'; import type { NDKEvent } from '@nostr-dev-kit/ndk'; import BitcoinAssociations from './AssociatedBitcoinAddresses.svelte'; import MeritRequests from './MeritRequests.svelte'; @@ -14,7 +14,7 @@ export let rocket: NDKEvent; - $: unratifiedZaps = new Map(); + $: unratifiedZaps = new Map();
diff --git a/src/lib/event_helpers/rockets.ts b/src/lib/event_helpers/rockets.ts index 03a83b2..04f4530 100644 --- a/src/lib/event_helpers/rockets.ts +++ b/src/lib/event_helpers/rockets.ts @@ -175,7 +175,7 @@ export class Rocket { let _products = new Map(); for (let p of this.Event.getMatchingTags('product')) { let rp = new RocketProduct(p); - _products.set(rp.ID, rp); + _products.set(rp.ID(), rp); } return _products; } @@ -551,28 +551,52 @@ export class RocketAMR { } export class RocketProduct { - ID: string; - Price: number; - ValidAfter: number; //unix time - MaxPurchases: number; - Purchases: Map; + tag: NDKTag; + ID(): string { + return this.tag[1].split(':')[0]; + } + Price(): number { + return parseInt(this.tag[1].split(':')[1], 10); + } + ValidAfter(): number { + return parseInt(this.tag[1].split(':')[2], 10); + } + MaxPurchases(): number { + return parseInt(this.tag[1].split(':')[3], 10); + } + Purchases(): Map { + let result: Map = new Map(); + let purchases = JSON.parse(this.tag[3]); + for (let p of purchases) { + let payment = new ProductPayment(p); + result.set(payment.ZapID, payment); + } + return result; + } PurchasesJSON(): string { let purchases = []; - for (let [_, p] of this.Purchases) { + for (let [_, p] of this.Purchases()) { purchases.push(`${p.ZapID}:${p.BuyerPubkey}:${p.WitnessedAt}`); } return JSON.stringify(purchases); } + Validate(): boolean { + try { + this.ID(); + this.Price(); + this.ValidAfter(); + this.MaxPurchases(); + this.Purchases(); + this.PurchasesJSON(); + return true; + } catch { + return false; + } + } constructor(tag: NDKTag) { - this.Purchases = new Map(); - this.ID = tag[1].split(':')[0]; - this.Price = parseInt(tag[1].split(':')[1], 10); - this.ValidAfter = parseInt(tag[1].split(':')[2], 10); - this.MaxPurchases = parseInt(tag[1].split(':')[3], 10); - let purchases = JSON.parse(tag[3]); - for (let p of purchases) { - let payment = new ProductPayment(p); - this.Purchases.set(payment.ZapID, payment); + this.tag = tag; + if (!this.Validate()) { + throw new Error('bug!'); } } } @@ -610,7 +634,7 @@ export class ZapPurchase { IncludedInRocketState(rocket: NDKEvent): boolean { let thisProduct = this.ProductFromRocket(rocket); if (thisProduct) { - return thisProduct.Purchases.get(this.ZapReceipt.id) ? true : false; + return thisProduct.Purchases().get(this.ZapReceipt.id) ? true : false; } else { return false; } @@ -627,7 +651,7 @@ export class ZapPurchase { return true; } let product = this.ProductFromRocket(rocket); - if (product && this.Amount / 1000 >= product.Price) { + if (product && this.Amount / 1000 >= product.Price()) { return true; } return false; diff --git a/src/lib/stores/session.ts b/src/lib/stores/session.ts index ecc80b3..e27e7e5 100644 --- a/src/lib/stores/session.ts +++ b/src/lib/stores/session.ts @@ -9,3 +9,5 @@ export async function prepareUserSession(ndk: NDKSvelte, user: NDKUser): Promise //implement any session set up stuff here }); } + +export const devmode = writable(false);