mirror of
https://github.com/aljazceru/hypergolic.git
synced 2025-12-19 06:24:20 +01:00
problem: can't see how many products ar remaining
This commit is contained in:
@@ -3,8 +3,17 @@
|
|||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import Separator from '@/components/ui/separator/separator.svelte';
|
import Separator from '@/components/ui/separator/separator.svelte';
|
||||||
import { currentUser } from '@/stores/session';
|
import { currentUser, devmode } from '@/stores/session';
|
||||||
import { GitBranch, HelpCircle, Mail, Package, Pyramid, Rocket, Users } from 'lucide-svelte';
|
import {
|
||||||
|
Code,
|
||||||
|
GitBranch,
|
||||||
|
HelpCircle,
|
||||||
|
Mail,
|
||||||
|
Package,
|
||||||
|
Pyramid,
|
||||||
|
Rocket,
|
||||||
|
Users
|
||||||
|
} from 'lucide-svelte';
|
||||||
import { GitAltBrand, TelegramBrand } from 'svelte-awesome-icons';
|
import { GitAltBrand, TelegramBrand } from 'svelte-awesome-icons';
|
||||||
|
|
||||||
let iconClass = 'h-5 w-5 md:h-4 md:w-4';
|
let iconClass = 'h-5 w-5 md:h-4 md:w-4';
|
||||||
@@ -57,4 +66,16 @@
|
|||||||
<HelpCircle class={iconClass} />
|
<HelpCircle class={iconClass} />
|
||||||
Help
|
Help
|
||||||
</a>
|
</a>
|
||||||
<Separator class="my-2" />
|
<Separator class="dark:bg-slate-700" />
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class={getClass('dev')}
|
||||||
|
on:click={() => {
|
||||||
|
devmode.update((dm) => {
|
||||||
|
return !dm;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Code class={iconClass} />
|
||||||
|
Toggle Dev Mode
|
||||||
|
</a>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '@/components/ui/card';
|
import * as Card from '@/components/ui/card';
|
||||||
import * as Table from '@/components/ui/table';
|
import * as Table from '@/components/ui/table';
|
||||||
import { Rocket } from '@/event_helpers/rockets';
|
import { Rocket, ZapPurchase } from '@/event_helpers/rockets';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import Pie from './Pie.svelte';
|
import Pie from './Pie.svelte';
|
||||||
import { Avatar, Name } from '@nostr-dev-kit/ndk-svelte-components';
|
import { Avatar, Name } from '@nostr-dev-kit/ndk-svelte-components';
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
import NumberIncrement from '@components/ui/number-increment';
|
import NumberIncrement from '@components/ui/number-increment';
|
||||||
|
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
export let unratifiedZaps: Map<string, number>;
|
export let unratifiedZaps: Map<string, ZapPurchase>;
|
||||||
|
|
||||||
let unratifiedZapsAmount = 0;
|
let unratifiedZapsAmount = 0;
|
||||||
let dataLoaded = false;
|
let dataLoaded = false;
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
$: {
|
$: {
|
||||||
unratifiedZapsAmount = 0;
|
unratifiedZapsAmount = 0;
|
||||||
for (let [_, a] of unratifiedZaps) {
|
for (let [_, a] of unratifiedZaps) {
|
||||||
unratifiedZapsAmount += a / 1000;
|
unratifiedZapsAmount += a.Amount / 1000;
|
||||||
}
|
}
|
||||||
unratifiedZapsAmount = unratifiedZapsAmount;
|
unratifiedZapsAmount = unratifiedZapsAmount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
import { Button, buttonVariants } from '$lib/components/ui/button/index.js';
|
||||||
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||||
import * as Alert from '@/components/ui/alert';
|
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
import * as Alert from '@/components/ui/alert';
|
||||||
|
import type { Product, Rocket, RocketProduct } from '@/event_helpers/rockets';
|
||||||
|
import { formatSats } from '@/helpers';
|
||||||
import { ndk } from '@/ndk';
|
import { ndk } from '@/ndk';
|
||||||
import { currentUser } from '@/stores/session';
|
import { currentUser } from '@/stores/session';
|
||||||
import { NDKZap } from '@nostr-dev-kit/ndk';
|
import { NDKZap } from '@nostr-dev-kit/ndk';
|
||||||
import { Terminal } from 'lucide-svelte';
|
|
||||||
import { requestProvider } from 'webln';
|
|
||||||
import QrCodeSvg from './QrCodeSvg.svelte';
|
|
||||||
import CopyButton from './CopyButton.svelte';
|
|
||||||
import type { Product, Rocket, RocketProduct } from '@/event_helpers/rockets';
|
|
||||||
import { formatSats } from '@/helpers';
|
|
||||||
import { Spinner } from 'flowbite-svelte';
|
import { Spinner } from 'flowbite-svelte';
|
||||||
import { CheckCircleOutline } from 'flowbite-svelte-icons';
|
import { CheckCircleOutline } from 'flowbite-svelte-icons';
|
||||||
import { tweened, type Tweened } from 'svelte/motion';
|
import { Terminal } from 'lucide-svelte';
|
||||||
import { cubicOut } from 'svelte/easing';
|
import { cubicOut } from 'svelte/easing';
|
||||||
import { fade, fly } from 'svelte/transition';
|
import { tweened } from 'svelte/motion';
|
||||||
|
import { requestProvider } from 'webln';
|
||||||
|
import CopyButton from './CopyButton.svelte';
|
||||||
|
import QrCodeSvg from './QrCodeSvg.svelte';
|
||||||
|
|
||||||
export let product: Product;
|
export let product: Product;
|
||||||
export let rocketProduct: RocketProduct | undefined;
|
export let rocketProduct: RocketProduct | undefined;
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
|
export let disabled = false;
|
||||||
|
|
||||||
let invoice: string | null;
|
let invoice: string | null;
|
||||||
let paymentInitiated: boolean;
|
let paymentInitiated: boolean;
|
||||||
@@ -37,7 +36,7 @@
|
|||||||
zappedUser: rocket.Event.author
|
zappedUser: rocket.Event.author
|
||||||
});
|
});
|
||||||
invoice = await z.createZapRequest(
|
invoice = await z.createZapRequest(
|
||||||
rocketProduct.Price * 1000,
|
rocketProduct.Price() * 1000,
|
||||||
`Purchase of ${product.Name()} from ${rocket.Event.dTag}`,
|
`Purchase of ${product.Name()} from ${rocket.Event.dTag}`,
|
||||||
[['product', product.ID()]]
|
[['product', product.ID()]]
|
||||||
);
|
);
|
||||||
@@ -83,12 +82,16 @@
|
|||||||
|
|
||||||
{#if rocketProduct}
|
{#if rocketProduct}
|
||||||
<Dialog.Root bind:open>
|
<Dialog.Root bind:open>
|
||||||
<Dialog.Trigger class={buttonVariants({ variant: 'default' })}>
|
<Dialog.Trigger>
|
||||||
|
<Button {disabled}>
|
||||||
{#if open}
|
{#if open}
|
||||||
<Spinner class="me-2" color="white" size={4} /> Confirming...
|
<Spinner class="me-2" color="white" size={4} /> Confirming...
|
||||||
{:else}
|
{:else if !disabled}
|
||||||
Buy Now for {formatSats(rocketProduct.Price)}
|
Buy Now for {formatSats(rocketProduct.Price())}
|
||||||
|
{:else if disabled}
|
||||||
|
Out of Stock!
|
||||||
{/if}
|
{/if}
|
||||||
|
</Button>
|
||||||
</Dialog.Trigger>
|
</Dialog.Trigger>
|
||||||
|
|
||||||
<Dialog.Content class="sm:max-w-[425px]">
|
<Dialog.Content class="sm:max-w-[425px]">
|
||||||
@@ -104,9 +107,9 @@
|
|||||||
</Alert.Root>
|
</Alert.Root>
|
||||||
{/if}
|
{/if}
|
||||||
<Dialog.Description
|
<Dialog.Description
|
||||||
>Pay {rocketProduct.Price === 1
|
>Pay {rocketProduct.Price() === 1
|
||||||
? `${rocketProduct.Price} sat`
|
? `${rocketProduct.Price()} sat`
|
||||||
: `${rocketProduct.Price} sats`} now with Lightning</Dialog.Description
|
: `${rocketProduct.Price()} sats`} now with Lightning</Dialog.Description
|
||||||
>
|
>
|
||||||
</Dialog.Header>
|
</Dialog.Header>
|
||||||
{#if invoice}
|
{#if invoice}
|
||||||
|
|||||||
@@ -1,11 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '$lib/components/ui/card/index.js';
|
import * as Card from '$lib/components/ui/card/index.js';
|
||||||
import { Product, Rocket } from '@/event_helpers/rockets';
|
import {
|
||||||
|
Product as ProductEvent,
|
||||||
|
Rocket,
|
||||||
|
RocketProduct,
|
||||||
|
ZapPurchase
|
||||||
|
} from '@/event_helpers/rockets';
|
||||||
import AddProductToRocket from './AddProductToRocket.svelte';
|
import AddProductToRocket from './AddProductToRocket.svelte';
|
||||||
import PayNow from './PayNow.svelte';
|
import PayNow from './PayNow.svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { devmode } from '@/stores/session';
|
||||||
|
|
||||||
export let product: Product;
|
export let product: ProductEvent;
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
|
export let unratifiedZaps: Map<string, ZapPurchase> | undefined = undefined;
|
||||||
|
|
||||||
|
let productFromRocket = rocket.Products().get(product.ID());
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (!product.Validate()) {
|
||||||
|
throw new Error('this should not happen');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function remainingProducts(product: RocketProduct, zaps?: Map<string, ZapPurchase>): number {
|
||||||
|
let numberOfPurchases = 0;
|
||||||
|
if (zaps) {
|
||||||
|
for (let [_, zap] of zaps) {
|
||||||
|
if (zap.ProductID == product.ID()) {
|
||||||
|
numberOfPurchases++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let remaining = product.MaxPurchases() - numberOfPurchases;
|
||||||
|
if (remaining < 0) {
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if product.Validate()}
|
{#if product.Validate()}
|
||||||
@@ -34,18 +66,30 @@
|
|||||||
<img src={product.CoverImage()} alt="cover" class="aspect-square object-cover" />
|
<img src={product.CoverImage()} alt="cover" class="aspect-square object-cover" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Card.Footer class="flex items-center justify-center pt-2">
|
<Card.Footer class="flex flex-col items-center justify-center pt-2">
|
||||||
{#if !rocket.Products().get(product.ID())}
|
{#if !rocket.Products().get(product.ID()) && !productFromRocket}
|
||||||
<AddProductToRocket {product} {rocket} />
|
<AddProductToRocket {product} {rocket} />
|
||||||
{:else}
|
{:else if productFromRocket}
|
||||||
<PayNow {product} rocketProduct={rocket.Products().get(product.ID())} {rocket} />
|
{#if productFromRocket.MaxPurchases() && unratifiedZaps}
|
||||||
|
<div class="flex flex-nowrap">
|
||||||
|
{remainingProducts(productFromRocket, unratifiedZaps)} available
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<PayNow
|
||||||
|
disabled={productFromRocket.MaxPurchases() > 0 &&
|
||||||
|
remainingProducts(productFromRocket, unratifiedZaps) == 0}
|
||||||
|
{product}
|
||||||
|
rocketProduct={rocket.Products().get(product.ID())}
|
||||||
|
{rocket}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{#if $devmode}
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
console.log(product);
|
console.log(product);
|
||||||
}}>print to console</a
|
}}>print to console</a
|
||||||
>
|
>{/if}
|
||||||
</Card.Footer>
|
</Card.Footer>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
import { ndk } from '@/ndk';
|
import { ndk } from '@/ndk';
|
||||||
import ProductCard from './ProductCard.svelte';
|
import ProductCard from './ProductCard.svelte';
|
||||||
import { fetchEvent } from '@/event_helpers/products';
|
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 productID: string | undefined = undefined;
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
export let product: Product | undefined = undefined;
|
export let product: Product | undefined = undefined;
|
||||||
|
export let unratifiedZaps: Map<string, ZapPurchase> | undefined = undefined;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (!product && productID) {
|
if (!product && productID) {
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if product}
|
{#if product}
|
||||||
<ProductCard {rocket} {product}>
|
<ProductCard {unratifiedZaps} {rocket} {product}>
|
||||||
<slot />
|
<slot />
|
||||||
</ProductCard>
|
</ProductCard>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Card from '$lib/components/ui/card/index.js';
|
import * as Card from '$lib/components/ui/card/index.js';
|
||||||
import { Product, Rocket } from '@/event_helpers/rockets';
|
import { Product, Rocket, ZapPurchase } from '@/event_helpers/rockets';
|
||||||
import { fetchEvent } from '@/event_helpers/products';
|
import { fetchEvent } from '@/event_helpers/products';
|
||||||
import { ndk } from '@/ndk';
|
import { ndk } from '@/ndk';
|
||||||
import { derived, writable } from 'svelte/store';
|
import { derived, writable } from 'svelte/store';
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
import CreateMeritRequest from './CreateMeritRequest.svelte';
|
import CreateMeritRequest from './CreateMeritRequest.svelte';
|
||||||
|
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
export let unratifiedZaps: Map<string, number>;
|
export let unratifiedZaps: Map<string, ZapPurchase>;
|
||||||
|
|
||||||
let products = writable(new Map<string, Product>());
|
let products = writable(new Map<string, Product>());
|
||||||
|
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
let groups = derived(products, ($products) => {
|
let groups = derived(products, ($products) => {
|
||||||
let productGroups = new Map<string, Map<string, Product>>();
|
let productGroups = new Map<string, Map<string, Product>>();
|
||||||
for (let [id, p] of $products) {
|
for (let [id, p] of $products) {
|
||||||
console.log(p.Group());
|
|
||||||
if (!productGroups.get(p.Group())) {
|
if (!productGroups.get(p.Group())) {
|
||||||
productGroups.set(p.Group(), new Map());
|
productGroups.set(p.Group(), new Map());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
import ProductPurchases from './ProductPurchases.svelte';
|
import ProductPurchases from './ProductPurchases.svelte';
|
||||||
import * as Pagination from '@/components/ui/pagination';
|
import * as Pagination from '@/components/ui/pagination';
|
||||||
import { ChevronLeft, ChevronRight } from 'lucide-svelte';
|
import { ChevronLeft, ChevronRight } from 'lucide-svelte';
|
||||||
import { Product, Rocket } from '@/event_helpers/rockets';
|
import { Product, Rocket, ZapPurchase } from '@/event_helpers/rockets';
|
||||||
|
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
export let products: Product[];
|
export let products: Product[];
|
||||||
export let unratifiedZaps: Map<string, number> | undefined = undefined;
|
export let unratifiedZaps: Map<string, ZapPurchase> | undefined = undefined;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Pagination.Root count={products.length} perPage={1} siblingCount={1} let:pages let:currentPage>
|
<Pagination.Root count={products.length} perPage={1} siblingCount={1} let:pages let:currentPage>
|
||||||
{#if currentPage}
|
{#if currentPage}
|
||||||
<ProductCardFromId {rocket} product={products[currentPage - 1]}>
|
<ProductCardFromId {unratifiedZaps} {rocket} product={products[currentPage - 1]}>
|
||||||
{#if unratifiedZaps}
|
{#if unratifiedZaps}
|
||||||
<ProductPurchases bind:unratifiedZaps {rocket} {products} />
|
<ProductPurchases bind:unratifiedZaps {rocket} {products} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
//export let products: Product[];
|
//export let products: Product[];
|
||||||
export let rocket: Rocket;
|
export let rocket: Rocket;
|
||||||
|
|
||||||
export let unratifiedZaps: Map<string, number>;
|
export let unratifiedZaps: Map<string, ZapPurchase>;
|
||||||
|
|
||||||
let zaps = $ndk.storeSubscribe(
|
let zaps = $ndk.storeSubscribe(
|
||||||
[{ '#a': [`31108:${rocket.Event.author.pubkey}:${rocket.Event.dTag}`], kinds: [9735] }],
|
[{ '#a': [`31108:${rocket.Event.author.pubkey}:${rocket.Event.dTag}`], kinds: [9735] }],
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
validatedZapsNotInRocket.subscribe((zaps) => {
|
validatedZapsNotInRocket.subscribe((zaps) => {
|
||||||
for (let [_, z] of zaps) {
|
for (let [_, z] of zaps) {
|
||||||
unratifiedZaps.set(z.ZapReceipt.id, z.Amount);
|
unratifiedZaps.set(z.ZapReceipt.id, z);
|
||||||
}
|
}
|
||||||
unratifiedZaps = unratifiedZaps;
|
unratifiedZaps = unratifiedZaps;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import * as Breadcrumb from '$lib/components/ui/breadcrumb/index.js';
|
import * as Breadcrumb from '$lib/components/ui/breadcrumb/index.js';
|
||||||
import Button from '@/components/ui/button/button.svelte';
|
import Button from '@/components/ui/button/button.svelte';
|
||||||
import * as Card from '@/components/ui/card';
|
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 type { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||||
import BitcoinAssociations from './AssociatedBitcoinAddresses.svelte';
|
import BitcoinAssociations from './AssociatedBitcoinAddresses.svelte';
|
||||||
import MeritRequests from './MeritRequests.svelte';
|
import MeritRequests from './MeritRequests.svelte';
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
export let rocket: NDKEvent;
|
export let rocket: NDKEvent;
|
||||||
|
|
||||||
$: unratifiedZaps = new Map<string, number>();
|
$: unratifiedZaps = new Map<string, ZapPurchase>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ export class Rocket {
|
|||||||
let _products = new Map<string, RocketProduct>();
|
let _products = new Map<string, RocketProduct>();
|
||||||
for (let p of this.Event.getMatchingTags('product')) {
|
for (let p of this.Event.getMatchingTags('product')) {
|
||||||
let rp = new RocketProduct(p);
|
let rp = new RocketProduct(p);
|
||||||
_products.set(rp.ID, rp);
|
_products.set(rp.ID(), rp);
|
||||||
}
|
}
|
||||||
return _products;
|
return _products;
|
||||||
}
|
}
|
||||||
@@ -551,28 +551,52 @@ export class RocketAMR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RocketProduct {
|
export class RocketProduct {
|
||||||
ID: string;
|
tag: NDKTag;
|
||||||
Price: number;
|
ID(): string {
|
||||||
ValidAfter: number; //unix time
|
return this.tag[1].split(':')[0];
|
||||||
MaxPurchases: number;
|
}
|
||||||
Purchases: Map<string, ProductPayment>;
|
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<string, ProductPayment> {
|
||||||
|
let result: Map<string, ProductPayment> = 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 {
|
PurchasesJSON(): string {
|
||||||
let purchases = [];
|
let purchases = [];
|
||||||
for (let [_, p] of this.Purchases) {
|
for (let [_, p] of this.Purchases()) {
|
||||||
purchases.push(`${p.ZapID}:${p.BuyerPubkey}:${p.WitnessedAt}`);
|
purchases.push(`${p.ZapID}:${p.BuyerPubkey}:${p.WitnessedAt}`);
|
||||||
}
|
}
|
||||||
return JSON.stringify(purchases);
|
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) {
|
constructor(tag: NDKTag) {
|
||||||
this.Purchases = new Map();
|
this.tag = tag;
|
||||||
this.ID = tag[1].split(':')[0];
|
if (!this.Validate()) {
|
||||||
this.Price = parseInt(tag[1].split(':')[1], 10);
|
throw new Error('bug!');
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -610,7 +634,7 @@ export class ZapPurchase {
|
|||||||
IncludedInRocketState(rocket: NDKEvent): boolean {
|
IncludedInRocketState(rocket: NDKEvent): boolean {
|
||||||
let thisProduct = this.ProductFromRocket(rocket);
|
let thisProduct = this.ProductFromRocket(rocket);
|
||||||
if (thisProduct) {
|
if (thisProduct) {
|
||||||
return thisProduct.Purchases.get(this.ZapReceipt.id) ? true : false;
|
return thisProduct.Purchases().get(this.ZapReceipt.id) ? true : false;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -627,7 +651,7 @@ export class ZapPurchase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let product = this.ProductFromRocket(rocket);
|
let product = this.ProductFromRocket(rocket);
|
||||||
if (product && this.Amount / 1000 >= product.Price) {
|
if (product && this.Amount / 1000 >= product.Price()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,3 +9,5 @@ export async function prepareUserSession(ndk: NDKSvelte, user: NDKUser): Promise
|
|||||||
//implement any session set up stuff here
|
//implement any session set up stuff here
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const devmode = writable(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user