diff --git a/src/lib/stores/event_sources/kinds.ts b/src/lib/stores/event_sources/kinds.ts index c95166f..75c9e7b 100644 --- a/src/lib/stores/event_sources/kinds.ts +++ b/src/lib/stores/event_sources/kinds.ts @@ -13,7 +13,8 @@ const problemKindRecord: Record = { // 15171972: "Problem COMMIT", // 15171973: "Problem TEXT", // 31971: "Problem HEAD", - 1971: "Problem Event" + 1971: "Problem Event", + 1972: "Problem Status" }; export const problemKinds = Object.keys(problemKindRecord).map((k) => @@ -25,7 +26,8 @@ const kinds: Record = { 31108: "Rocket Metadata", 15172008: "Consensus Event", 31009: "Identity Tree Replaceable Event", - 1971: "Problem Event" + 1971: "Problem Event", + 1972: "Problem Status" // 15171971: "Problem ANCHOR", // 15171972: "Problem COMMIT", // 15171973: "Problem TEXT", @@ -51,6 +53,8 @@ export function kindToDescription(kind: number): string { return "This is a list of pubkeys to be included in an Identity Tree"; case 1971: return "This is an event that describes a Problem" + case 1972: + return "This is a problem status update event" // case 15171971: // return "This is a Problem ANCHOR event."; // case 15171972: diff --git a/src/lib/stores/nostrocket_state/master_state.ts b/src/lib/stores/nostrocket_state/master_state.ts index 69d60d9..5d63f50 100644 --- a/src/lib/stores/nostrocket_state/master_state.ts +++ b/src/lib/stores/nostrocket_state/master_state.ts @@ -107,6 +107,7 @@ function processSoftStateChangeReqeustsFromMempool(currentState: Nostrocket, eli handled.push(e); } } + case 1972: case 1971: if (HandleProblemEvent(e, currentState)) { handled.push(e) diff --git a/src/lib/stores/nostrocket_state/soft_state/simplifiedProblems.ts b/src/lib/stores/nostrocket_state/soft_state/simplifiedProblems.ts index 585fa59..d8d76e2 100644 --- a/src/lib/stores/nostrocket_state/soft_state/simplifiedProblems.ts +++ b/src/lib/stores/nostrocket_state/soft_state/simplifiedProblems.ts @@ -5,15 +5,61 @@ import { labelledTag } from "$lib/helpers/shouldBeInNDK"; export function HandleProblemEvent(ev:NDKEvent, state:Nostrocket):boolean { let success = false - if (ev.getMatchingTags("new").length > 0) { - success = handleNewProblemEvent(ev, state) - } - if (labelledTag(ev, "problem", "e")) { - success = handleProblemModification(ev, state) + switch (ev.kind) { + case 1971: + if (ev.getMatchingTags("new").length > 0) { + success = handleNewProblemEvent(ev, state) + } + if (labelledTag(ev, "problem", "e")) { + success = handleProblemModification(ev, state) + } + break; + case 1972: + let [err, s] = handleProblemStatus(ev, state) + success = s } + return success } +function handleProblemStatus(ev:NDKEvent, state:Nostrocket):[string, boolean] { + let success = false + let error = "" + if (!state.Problems) { + state.Problems = new Map(); + } + let problemID = labelledTag(ev, "problem", "e") + let statusTag = ev.getMatchingTags("status") + let newStatus = statusTag[0][1] //todo try/catch or some javascripty way to handle error + if (!statusTag) {error = "could not find a status update tag"} + if (problemID) { + let problem = state.Problems.get(problemID) + if (problem) { + if (!problem) { + error = "problem is missing" + } + if (!state.RocketMap.get(nostrocketIgnitionEvent)?.isParticipant(ev.pubkey)) { + error = "current user is not in the Identity Tree" + } + if (newStatus == "claimed" && problem?.Status != "open") { + error = "cannot claim a problem that isn't open" + } + if (newStatus == "close" && problem?.CreatedBy != ev.pubkey) { + //todo also check if maintainer + error = "you cannot close a problem unless you are the creator of it or a maintainer on its rocket" + } + if (newStatus == "patched" && (problem?.Status !== "claimed" || problem?.ClaimedBy != ev.pubkey)) { + error = "you cannot mark this problem as patched unless you are the one who claimed it" + } + if (error == "") { + problem.Status = newStatus + success = true + } + } + } + return [error, success] +} + function handleNewProblemEvent(ev:NDKEvent, state:Nostrocket):boolean { let success = false if (!state.Problems) { diff --git a/src/routes/problems/+page.svelte b/src/routes/problems/+page.svelte index 73dcdc1..01b59e1 100644 --- a/src/routes/problems/+page.svelte +++ b/src/routes/problems/+page.svelte @@ -4,7 +4,6 @@ import type { Account, Problem, ProblemStatus } from "$lib/stores/nostrocket_state/types"; import { Accordion, Column, Row, Search, Select, SelectItem, SelectItemGroup } from "carbon-components-svelte"; import { derived, writable } from "svelte/store"; - import LogNewProblemModal from "../../components/problems/LogNewProblemModal.svelte"; import ProblemComponent from "../../components/problems/ProblemComponent.svelte"; let rootNodes: Map diff --git a/src/routes/problems/[id]/+page.svelte b/src/routes/problems/[id]/+page.svelte index 3b0e461..25a147c 100644 --- a/src/routes/problems/[id]/+page.svelte +++ b/src/routes/problems/[id]/+page.svelte @@ -8,8 +8,11 @@ import type {NDKUserProfile} from "@nostr-dev-kit/ndk"; import {makeHtml} from "$lib/helpers/mundane"; import LogNewProblemModal from "../../../components/problems/LogNewProblemModal.svelte"; + import makeEvent from "$lib/helpers/eventMaker"; + import { currentUser } from "$lib/stores/hot_resources/current-user"; + import { nostrocketIgnitionEvent } from "../../../settings"; - let problem: Problem + let problem: Problem | undefined let createdBy: NDKUserProfile | undefined let claimedBy: NDKUserProfile | undefined @@ -17,7 +20,7 @@ $: { problem = $consensusTipState.Problems.get($page.params.id) - claimable = (problem.Children.size == 0 && problem.Status == "open") + claimable = (problem?.Children.size == 0 && problem.Status == "open") } @@ -38,6 +41,33 @@ })() } +function updateStatus(newStatus:string):Promise { + return new Promise((resolve, reject)=>{ + if (!problem) { + reject("problem is missing") + } + if (!$currentUser) { + reject("user not logged in") + } + if (!$consensusTipState.RocketMap.get(nostrocketIgnitionEvent)?.isParticipant($currentUser!.pubkey)) { + reject("current user is not in the Identity Tree") + } + if (newStatus == "claimed" && problem?.Status != "open") { + reject("cannot claim a problem that isn't open") + } + if (newStatus == "close" && problem?.CreatedBy != $currentUser?.pubkey) { + //todo also check if maintainer + reject("you cannot close a problem unless you are the creator of it or a maintainer on its rocket") + } + if (newStatus == "patched" && (problem?.Status !== "claimed" || problem?.ClaimedBy != $currentUser?.pubkey)) { + reject("you cannot mark this problem as patched unless you are the one who claimed it") + } + let e = makeEvent({kind:1972}) + e.tags.push(["e", problem!.UID, "problem"]) + e.tags.push(["status", newStatus]) + e.publish().then(()=>{console.log(e);resolve("published")}).catch((err)=>{reject(err)}) + }) +} @@ -122,7 +152,7 @@ - +