mirror of
https://github.com/aljazceru/hypergolic.git
synced 2025-12-17 05:24:21 +01:00
problem: not clear if contributors should vote to approve or reject a merit request
This commit is contained in:
@@ -46,12 +46,23 @@
|
||||
<Dialog.Header>
|
||||
<Dialog.Title>How much should you request?</Dialog.Title>
|
||||
<Dialog.Description
|
||||
>Use this form to calculate how many Sats you should claim. This information will be public and permanent.</Dialog.Description
|
||||
><p class="mb-2">
|
||||
A Merit Request is simply a way to inform other contributors how much you think your work
|
||||
is worth in comparison to their work.
|
||||
</p>
|
||||
<p class="mb-2">
|
||||
You should adjust your hourly rate depending on the minimum skill set required to solve
|
||||
the problem.
|
||||
</p>
|
||||
<p class="mb-2">
|
||||
Also consider what you'd need to earn in order for your work on this project to be
|
||||
sustainable.
|
||||
</p></Dialog.Description
|
||||
>
|
||||
</Dialog.Header>
|
||||
<Label for="hourly_rate">Your hourly rate in CuckLoserBucks</Label>
|
||||
<Label for="hourly_rate">Hourly rate in CuckLoserBucks</Label>
|
||||
<Input bind:value={hourly_rate} id="hourly_rate" placeholder="USD hourly rate" />
|
||||
<Label for="spent_minutes">Time spent solving this problem (minutes)</Label>
|
||||
<Label for="spent_minutes">How long you spent solving this problem (minutes)</Label>
|
||||
<Input bind:value={spent_minutes} id="spent_minutes" placeholder="minutes" />
|
||||
{#if calcSats}
|
||||
<div>Result: {calcSats.toFixed(0)} sats</div>
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label for="desc" class="text-right">Solution</Label>
|
||||
<Label for="desc" class="text-right">Solution (proof of work)</Label>
|
||||
<Textarea
|
||||
bind:value={solution}
|
||||
id="desc"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '@/components/ui/button';
|
||||
import Checkbox from '@/components/ui/checkbox/checkbox.svelte';
|
||||
import Label from '@/components/ui/label/label.svelte';
|
||||
import {
|
||||
MeritRequest,
|
||||
prepareMeritNoteEvent,
|
||||
@@ -15,6 +17,53 @@
|
||||
export let merit: MeritRequest;
|
||||
export let rocket: Rocket;
|
||||
|
||||
let checkboxes = new Map<string, boolean>();
|
||||
|
||||
let haveUnchecked = true;
|
||||
$: {
|
||||
let foundUnchecked = false;
|
||||
for (let [_, c] of checkboxes) {
|
||||
if (!c) {
|
||||
foundUnchecked = true;
|
||||
}
|
||||
}
|
||||
haveUnchecked = foundUnchecked;
|
||||
}
|
||||
|
||||
{
|
||||
checkboxes.set('I believe this problem is worth solving', false);
|
||||
checkboxes.set(
|
||||
'I believe the Problem statement is a true and accurate observation of reality',
|
||||
false
|
||||
);
|
||||
checkboxes.set("I believe the contributor's solution fully solves the stated problem", false);
|
||||
checkboxes.set(
|
||||
'I believe the Solution provided is the minimum possible answer to the described Problem, and no more complex than it needs to be',
|
||||
false
|
||||
);
|
||||
checkboxes.set(
|
||||
'I believe that the solution does NOT introduce any way to create Merits in this project other than by solving problems (proof of work)',
|
||||
false
|
||||
);
|
||||
checkboxes.set(
|
||||
'I believe that the Merit Holders are the sole beneficiary of any revenue that this solution potentially leads towards',
|
||||
false
|
||||
);
|
||||
checkboxes.set(
|
||||
"I can't see any way in which this solution could be harmful to any Nostrocket Participants, their families, community, or ecological system.",
|
||||
false
|
||||
);
|
||||
checkboxes.set(
|
||||
"I can't see any way in which this solution could be harmful to Bitcoin or Bitcoin users",
|
||||
false
|
||||
);
|
||||
checkboxes.set(
|
||||
'I believe the amount of Merits being claimed is reasonable for the work that has been done',
|
||||
false
|
||||
);
|
||||
checkboxes = checkboxes;
|
||||
}
|
||||
|
||||
function publish(ndk: NDKSvelte, direction: VoteDirection) {
|
||||
if (!ndk.signer) {
|
||||
throw new Error('no ndk signer found');
|
||||
@@ -57,28 +106,56 @@
|
||||
</script>
|
||||
|
||||
{#if $currentUser}
|
||||
<Button
|
||||
variant="default"
|
||||
class="m-2"
|
||||
on:click={() => {
|
||||
if (currentUserHasVotepower) {
|
||||
publish($ndk, 'ratify');
|
||||
} else {
|
||||
alert(`Your pubkey does not have votepower in ${rocket.Name()}`);
|
||||
}
|
||||
}}>Vote to Approve</Button
|
||||
>
|
||||
<Button
|
||||
variant="destructive"
|
||||
class="m-2"
|
||||
on:click={() => {
|
||||
if (currentUserHasVotepower) {
|
||||
publish($ndk, 'blackball');
|
||||
} else {
|
||||
alert(`Your pubkey does not have votepower in ${rocket.Name()}`);
|
||||
}
|
||||
}}>Vote to Reject</Button
|
||||
>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
{#each checkboxes as [text, bool]}
|
||||
<div class="mb-2 flex flex-nowrap text-left">
|
||||
<Checkbox
|
||||
on:click={() => {
|
||||
checkboxes.set(text, !bool), (checkboxes = checkboxes);
|
||||
}}
|
||||
id="worthsolving"
|
||||
bind:checked={bool}
|
||||
/>
|
||||
<Label
|
||||
on:mousedown={() => {
|
||||
checkboxes.set(text, !bool), (checkboxes = checkboxes);
|
||||
}}
|
||||
for={text}
|
||||
class=" ml-2 font-extralight peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
{text}
|
||||
</Label>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex">
|
||||
<Button
|
||||
variant="default"
|
||||
class="m-2"
|
||||
disabled={haveUnchecked}
|
||||
on:click={() => {
|
||||
if (currentUserHasVotepower) {
|
||||
publish($ndk, 'ratify');
|
||||
} else {
|
||||
alert(`Your pubkey does not have votepower in ${rocket.Name()}`);
|
||||
}
|
||||
}}>Vote to Approve</Button
|
||||
>
|
||||
<Button
|
||||
variant="destructive"
|
||||
class="m-2"
|
||||
disabled={!haveUnchecked}
|
||||
on:click={() => {
|
||||
if (currentUserHasVotepower) {
|
||||
publish($ndk, 'blackball');
|
||||
} else {
|
||||
alert(`Your pubkey does not have votepower in ${rocket.Name()}`);
|
||||
}
|
||||
}}>Vote to Reject</Button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<Login />
|
||||
{/if}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
import Heading from '../../../components/Heading.svelte';
|
||||
import RocketDashboard from '../../../components/RocketDashboard.svelte';
|
||||
import Rocket from '../../../route_helpers/Rocket.svelte';
|
||||
import { Circle2 } from 'svelte-loading-spinners';
|
||||
import { devmode } from '@/stores/session';
|
||||
|
||||
//flow if we only have a d-tag: fetch all 31108's with this d-tag, sort by WoT, put Nostrocket Name Service one at the top. Dedupe same rocket (same state, shadows) from multiple users, just show them all as everyone agreeing.
|
||||
//second pass: fetch ignition event for each, rebuild current state and validate all proofs, compute votepower and display only the states with > 50%.
|
||||
|
||||
@@ -15,7 +18,6 @@
|
||||
|
||||
let latestRocketEvent: Readable<ExtendedBaseType<NDKEvent> | undefined>;
|
||||
|
||||
|
||||
//if we don't have a d/p tags we just render the event provided
|
||||
//todo: to find the latest by name alone we should use a new route and redirect to this page once we've got the relevant data
|
||||
if (!dTag && !pubkey && rIgnitionOrActual.length == 64) {
|
||||
@@ -25,7 +27,6 @@
|
||||
|
||||
if (dTag && pubkey) {
|
||||
//the user wants the latest valid state of this rocket
|
||||
|
||||
}
|
||||
|
||||
//todo: check that this zap is not already included in the payment JSON for the product
|
||||
@@ -36,15 +37,51 @@
|
||||
|
||||
//todo: handle shadow events (fetch the shadowed event and render it instead)
|
||||
</script>
|
||||
|
||||
{#if dTag && pubkey}
|
||||
<Rocket bind:latestRocketEvent {dTag} {pubkey} />
|
||||
<Rocket bind:latestRocketEvent {dTag} {pubkey} />
|
||||
{/if}
|
||||
|
||||
{#if latestRocketEvent && $latestRocketEvent}
|
||||
<RocketDashboard rocket={$latestRocketEvent} />
|
||||
{:else}
|
||||
<Heading title="Fetching events for the requested rocket" />
|
||||
IGNITION: {rIgnitionOrActual} <br />
|
||||
NAME: {dTag} <br />
|
||||
PUBKEY: {pubkey} <br />
|
||||
{/if}
|
||||
<Heading title="Finding latest event for the requested rocket" />
|
||||
{#if $devmode}
|
||||
IGNITION: {rIgnitionOrActual} <br />
|
||||
NAME: {dTag} <br />
|
||||
PUBKEY: {pubkey} <br />
|
||||
{/if}
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<div class="flex flex-row">
|
||||
<div class="flex flex-col items-center justify-center gap-4 py-20">
|
||||
<Circle2 size="10" unit="px" /><Circle2 size="30" unit="px" /><Circle2
|
||||
size="60"
|
||||
unit="px"
|
||||
/><Circle2 size="90" unit="px" /><Circle2 size="120" unit="px" /><Circle2
|
||||
size="240"
|
||||
unit="px"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center gap-4 py-20">
|
||||
<Circle2 size="240" unit="px" /><Circle2 size="120" unit="px" /><Circle2
|
||||
size="90"
|
||||
unit="px"
|
||||
/><Circle2 size="60" unit="px" /><Circle2 size="30" unit="px" /><Circle2
|
||||
size="10"
|
||||
unit="px"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center gap-4 py-20">
|
||||
<Circle2 size="10" unit="px" /><Circle2 size="30" unit="px" /><Circle2
|
||||
size="60"
|
||||
unit="px"
|
||||
/><Circle2 size="90" unit="px" /><Circle2 size="120" unit="px" /><Circle2
|
||||
size="240"
|
||||
unit="px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <Circle2 size="800" unit="px" /> hodlbod's motto is "you can never have too many spinners", but I don't know about this last one, it might be too much-->
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user