From ed504b0590d57e870a78a7014bea47b6e80a0466 Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 23 Jul 2024 16:26:32 +0800 Subject: [PATCH] problem: can't see if merit request is approved/rejected/pending --- src/components/MeritRequests.svelte | 38 ++++++++++++++++++++++-- src/lib/event_helpers/merits.ts | 46 ++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/components/MeritRequests.svelte b/src/components/MeritRequests.svelte index 9c0e128..e3c3ee0 100644 --- a/src/components/MeritRequests.svelte +++ b/src/components/MeritRequests.svelte @@ -3,7 +3,8 @@ import { base } from '$app/paths'; import * as Card from '@/components/ui/card'; import * as Table from '@/components/ui/table'; - import { MeritRequest } from '@/event_helpers/merits'; + import { MapOfMeritResult, MeritRequest } from '@/event_helpers/merits'; + import { Rocket, RocketATagFilter } from '@/event_helpers/rockets'; import { unixToRelativeTime } from '@/helpers'; import { ndk } from '@/ndk'; import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk'; @@ -12,6 +13,7 @@ import { derived } from 'svelte/store'; export let rocket: NDKEvent; + let parsedRocket = new Rocket(rocket); let _merits = $ndk.storeSubscribe( [{ '#a': [`31108:${rocket.author.pubkey}:${rocket.dTag}`], kinds: [1409 as NDKKind] }], @@ -20,14 +22,19 @@ } ); + let _votes = $ndk.storeSubscribe({ '#a': [RocketATagFilter(rocket)], kinds: [1410 as NDKKind] }); + onDestroy(() => { _merits?.unsubscribe(); + _votes?.unsubscribe(); }); let merits = derived(_merits, ($merits) => { let map = new Map(); for (let z of $merits) { + console.log('z', z); let meritRequest = new MeritRequest(z); + console.log('meritRequest', meritRequest); if (meritRequest.BasicValidation()) { if (meritRequest.Event.sig) { //broadcast the events to our relays @@ -40,6 +47,32 @@ return map; }); + let votes = derived(_votes, ($_votes) => { + return new MapOfMeritResult($_votes, parsedRocket).meritResult; + }); + + type MeritUIStatus = 'approved' | 'rejected' | 'pending'; + + const status = (merit: MeritRequest): MeritUIStatus => { + if (merit.IncludedInRocketState(parsedRocket)) { + return 'approved'; + } + if ($votes.get(merit.ID) === 'blackball') { + return 'rejected'; + } + return 'pending'; + }; + + const background = (merit: MeritRequest) => { + if (status(merit) === 'approved') { + return 'bg-lime-600'; + } else if (status(merit) === 'rejected') { + return 'bg-red-600'; + } else { + return 'bg-accent'; + } + }; + //todo: update rocket event with confirmed zaps if we have votepower @@ -65,7 +98,7 @@ on:click={() => { goto(`${base}/rockets/merits/${merit.ID}`); }} - class="cursor-pointer bg-accent" + class={`cursor-pointer ${background(merit)}`} >
@@ -87,6 +120,7 @@ + {status(merit).toUpperCase()} {/each} diff --git a/src/lib/event_helpers/merits.ts b/src/lib/event_helpers/merits.ts index 2b443b4..379386d 100644 --- a/src/lib/event_helpers/merits.ts +++ b/src/lib/event_helpers/merits.ts @@ -33,8 +33,8 @@ export class MeritRequest { return _solution; } IncludedInRocketState(rocket: Rocket): boolean { - let included = rocket.ApprovedMeritRequests() - return Boolean(included.get(this.ID)) + let included = rocket.ApprovedMeritRequests(); + return Boolean(included.get(this.ID)); } BasicValidation(): boolean { //todo: make a ValidateAgainstRocket and check that pubkey is in WoT @@ -67,9 +67,9 @@ export class MeritRequest { } constructor(request: NDKEvent | string) { if (typeof request == 'string') { - console.log(69) + console.log(69); } else { - console.log(71) + console.log(71); this.LeadTime = 0; this.LastLTUpdate = 0; this.Event = request; @@ -301,3 +301,41 @@ export class MapOfVotes { } } } + +export class MapOfMeritResult { + meritResult: Map; + constructor(votes: NDKEvent[], rocket: Rocket) { + const meritVotes = new Map(); + for (let v of votes) { + let vote = new Vote(v); + if (vote.BasicValidation() && vote.ValidateAgainstRocket(rocket)) { + const mVotes = meritVotes.get(vote.Request); + if (mVotes) { + meritVotes.set(vote.Request, pubkeyLatestVote(new Votes([...mVotes.Votes, vote]))); + } else { + meritVotes.set(vote.Request, new Votes([vote])); + } + } + } + this.meritResult = new Map(); + for (let [merit, votes] of meritVotes) { + const result = votes.Results().Result(rocket); + this.meritResult.set(merit, result); + } + } +} + +/** + * only show the latest vote from each pubkey + */ +function pubkeyLatestVote(votes: Votes) { + let pMap = new Map(); + for (let v of votes.Votes) { + let existing = pMap.get(v.Pubkey); + if (!existing || (existing && existing.TimeStamp < v.TimeStamp)) { + //todo: check if this merit request has already been included in the rocket. If not, and if we have enough votes to approve it, update the rocket. + pMap.set(v.Pubkey, v); + } + } + return new Votes([...pMap.values()]); +}