mirror of
https://github.com/aljazceru/hypergolic.git
synced 2025-12-18 22:14:21 +01:00
problem: merit card doesn't look good
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
import type NDKSvelte from '@nostr-dev-kit/ndk-svelte';
|
import type NDKSvelte from '@nostr-dev-kit/ndk-svelte';
|
||||||
import { Terminal } from 'lucide-svelte';
|
import { Terminal } from 'lucide-svelte';
|
||||||
import Todo from './Todo.svelte';
|
import Todo from './Todo.svelte';
|
||||||
|
import { isValidUrl } from '@/event_helpers/rockets';
|
||||||
|
|
||||||
export let rocketEvent: NDKEvent;
|
export let rocketEvent: NDKEvent;
|
||||||
|
|
||||||
@@ -46,14 +47,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidUrl(string:string):boolean {
|
|
||||||
try {
|
|
||||||
new URL(string);
|
|
||||||
return true;
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateSolution(solution:string) {
|
function validateSolution(solution:string) {
|
||||||
if (solution.length > 0) {
|
if (solution.length > 0) {
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import * as Card from '$lib/components/ui/card/index.js';
|
|
||||||
import type { MeritRequest } from '@/event_helpers/merits';
|
|
||||||
import { ndk } from '@/ndk';
|
|
||||||
import type { NDKEvent } from '@nostr-dev-kit/ndk';
|
|
||||||
import { Avatar, Name } from '@nostr-dev-kit/ndk-svelte-components';
|
|
||||||
|
|
||||||
export let merit:MeritRequest;
|
|
||||||
export let rocket:NDKEvent;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<Card.Root class="m-2">
|
|
||||||
<Card.Header>
|
|
||||||
<Card.Title>{merit.Problem()}</Card.Title>
|
|
||||||
<Card.Description>
|
|
||||||
<div class="flex flex-nowrap">
|
|
||||||
<Avatar
|
|
||||||
ndk={$ndk}
|
|
||||||
pubkey={merit.Pubkey}
|
|
||||||
class="h-10 w-10 flex-none rounded-full object-cover"
|
|
||||||
/>
|
|
||||||
<Name
|
|
||||||
ndk={$ndk}
|
|
||||||
pubkey={merit.Pubkey}
|
|
||||||
class="hidden max-w-32 truncate p-2 md:inline-block"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Card.Description>
|
|
||||||
</Card.Header>
|
|
||||||
<Card.Content></Card.Content>
|
|
||||||
<Card.Footer class="flex justify-between">
|
|
||||||
VOTE YES VOTE NO
|
|
||||||
</Card.Footer>
|
|
||||||
</Card.Root>
|
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
import type { MeritRequest } from '@/event_helpers/merits';
|
import type { MeritRequest } from '@/event_helpers/merits';
|
||||||
import { getRocketURL } from '@/helpers';
|
import { getRocketURL } from '@/helpers';
|
||||||
import type { NDKEvent } from '@nostr-dev-kit/ndk';
|
import type { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||||
import MeritCard from './MeritCard.svelte';
|
import MeritSummaryCard from './MeritSummaryCard.svelte';
|
||||||
|
|
||||||
export let rocket: NDKEvent;
|
export let rocket: NDKEvent;
|
||||||
export let merit: MeritRequest;
|
export let merit: MeritRequest;
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
</Breadcrumb.Item>
|
</Breadcrumb.Item>
|
||||||
<Breadcrumb.Separator />
|
<Breadcrumb.Separator />
|
||||||
<Breadcrumb.Item>
|
<Breadcrumb.Item>
|
||||||
<Breadcrumb.Page>{merit.Problem()}</Breadcrumb.Page>
|
<Breadcrumb.Page>{merit.Problem().substring(0,16)}{#if merit.Problem().length > 16}...{/if}</Breadcrumb.Page>
|
||||||
</Breadcrumb.Item>
|
</Breadcrumb.Item>
|
||||||
</Breadcrumb.List>
|
</Breadcrumb.List>
|
||||||
</Breadcrumb.Root>
|
</Breadcrumb.Root>
|
||||||
@@ -33,6 +33,6 @@
|
|||||||
<main
|
<main
|
||||||
class="grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-2 lg:grid-cols-3 xl:grid-cols-3"
|
class="grid flex-1 items-start gap-4 p-4 sm:px-6 sm:py-0 md:gap-2 lg:grid-cols-3 xl:grid-cols-3"
|
||||||
>
|
>
|
||||||
<MeritCard {rocket} {merit} />
|
<MeritSummaryCard {rocket} {merit} />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
46
src/components/MeritSummaryCard.svelte
Normal file
46
src/components/MeritSummaryCard.svelte
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import * as Card from '$lib/components/ui/card/index.js';
|
||||||
|
import type { MeritRequest } from '@/event_helpers/merits';
|
||||||
|
import { ndk } from '@/ndk';
|
||||||
|
import type { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||||
|
import { Avatar, Name } from '@nostr-dev-kit/ndk-svelte-components';
|
||||||
|
import { ExternalLink } from 'lucide-svelte';
|
||||||
|
import { onDestroy } from 'svelte';
|
||||||
|
import VoteOnMeritRequest from './VoteOnMeritRequest.svelte';
|
||||||
|
|
||||||
|
export let merit: MeritRequest;
|
||||||
|
export let rocket: NDKEvent;
|
||||||
|
|
||||||
|
let votes = $ndk.storeSubscribe([merit.REQFilter(1410)], {
|
||||||
|
subId: merit.RocketTag!.split(':')[2] + '_votes'
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
votes.unsubscribe();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Card.Root class="sm:col-span-2">
|
||||||
|
<Card.Header class="pb-3">
|
||||||
|
<div class="flex flex-nowrap justify-between">
|
||||||
|
<Card.Title>Problem: {merit.Problem().substring(0, 20)}</Card.Title>{#if merit.Solution()}<a
|
||||||
|
class="text-orange-500 underline decoration-orange-500 flex flex-nowrap"
|
||||||
|
href={merit.Solution()}>View Solution <ExternalLink size={18} class="m-1"/></a
|
||||||
|
>{/if}
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-nowrap">
|
||||||
|
<Avatar
|
||||||
|
ndk={$ndk}
|
||||||
|
pubkey={merit.Pubkey}
|
||||||
|
class="h-10 w-10 flex-none rounded-full object-cover"
|
||||||
|
/>
|
||||||
|
<Name ndk={$ndk} pubkey={merit.Pubkey} class="hidden max-w-32 truncate p-2 md:inline-block" />
|
||||||
|
</div>
|
||||||
|
<Card.Description class="max-w-lg text-balance leading-relaxed">
|
||||||
|
{#if merit.Problem().length > 20}{merit.Problem()}{/if}
|
||||||
|
</Card.Description>
|
||||||
|
</Card.Header>
|
||||||
|
<Card.Footer>
|
||||||
|
<VoteOnMeritRequest {merit} {rocket} />
|
||||||
|
</Card.Footer>
|
||||||
|
</Card.Root>
|
||||||
54
src/components/VoteOnMeritRequest.svelte
Normal file
54
src/components/VoteOnMeritRequest.svelte
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { MeritRequest } from '@/event_helpers/merits';
|
||||||
|
import { currentUser } from '@/stores/session';
|
||||||
|
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||||
|
import type NDKSvelte from '@nostr-dev-kit/ndk-svelte';
|
||||||
|
import Login from './Login.svelte';
|
||||||
|
import { ndk } from '@/ndk';
|
||||||
|
|
||||||
|
export let merit: MeritRequest;
|
||||||
|
export let rocket: NDKEvent;
|
||||||
|
|
||||||
|
function publish(ndk: NDKSvelte, direction: string) {
|
||||||
|
if (!ndk.signer) {
|
||||||
|
throw new Error('no ndk signer found');
|
||||||
|
}
|
||||||
|
let e = new NDKEvent(ndk);
|
||||||
|
let author = $currentUser;
|
||||||
|
if (!author) {
|
||||||
|
throw new Error('no current user');
|
||||||
|
}
|
||||||
|
e.author = author;
|
||||||
|
e.kind = 1410;
|
||||||
|
e.created_at = Math.floor(new Date().getTime() / 1000);
|
||||||
|
e.tags.push(['a', `31108:${rocket.pubkey}:${rocket.dTag}`]);
|
||||||
|
e.tags.push(['request', merit.ID]);
|
||||||
|
e.tags.push(['e', merit.ID]);
|
||||||
|
e.tags.push(['p', merit.Pubkey]);
|
||||||
|
e.tags.push(['vote', direction]);
|
||||||
|
console.log(e.rawEvent());
|
||||||
|
e.publish().then((x) => {
|
||||||
|
console.log(x);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if $currentUser}
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
class="m-2"
|
||||||
|
on:click={() => {
|
||||||
|
publish($ndk, 'ratify');
|
||||||
|
}}>Vote to Approve</Button
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
class="m-2"
|
||||||
|
on:click={() => {
|
||||||
|
publish($ndk, 'ratify');
|
||||||
|
}}>Vote to Reject</Button
|
||||||
|
>
|
||||||
|
{:else}
|
||||||
|
<Login />
|
||||||
|
{/if}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
|
import type { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
|
||||||
import { getNumberFromTag } from './rockets';
|
import { getNumberFromTag, isValidUrl } from './rockets';
|
||||||
|
|
||||||
export class MeritRequest {
|
export class MeritRequest {
|
||||||
ID: string;
|
ID: string;
|
||||||
@@ -19,6 +19,17 @@ export class MeritRequest {
|
|||||||
}
|
}
|
||||||
return _problem;
|
return _problem;
|
||||||
}
|
}
|
||||||
|
Solution(): URL|undefined {
|
||||||
|
let _solution:URL|undefined = undefined;
|
||||||
|
for (let solution of this.Request.getMatchingTags('solution')) {
|
||||||
|
if (solution && solution.length > 2 && solution[1] == "url") {
|
||||||
|
if (isValidUrl(solution[2])) {
|
||||||
|
_solution = new URL(solution[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _solution;
|
||||||
|
}
|
||||||
IncludedInRocketState(rocket: NDKEvent): boolean {
|
IncludedInRocketState(rocket: NDKEvent): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -30,11 +41,14 @@ export class MeritRequest {
|
|||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
RocketFilter():NDKFilter {
|
REQFilter(kind?:number):NDKFilter {
|
||||||
if (!this.BasicValidation()) {
|
if (!this.BasicValidation()) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
return { '#d': [this.RocketTag?.split(":")[2]!], authors: [this.RocketTag?.split(":")[1]!], kinds: [31108 as number] }
|
if (!kind) {
|
||||||
|
kind = 31108
|
||||||
|
}
|
||||||
|
return { '#d': [this.RocketTag?.split(":")[2]!], authors: [this.RocketTag?.split(":")[1]!], kinds: [kind as number] }
|
||||||
}
|
}
|
||||||
constructor(request: NDKEvent) {
|
constructor(request: NDKEvent) {
|
||||||
this.Request = request;
|
this.Request = request;
|
||||||
|
|||||||
@@ -135,3 +135,12 @@ export function getNumberFromTag(tag:string, event?: NDKEvent): number {
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isValidUrl(string:string):boolean {
|
||||||
|
try {
|
||||||
|
new URL(string);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
//the user wants the latest valid state of this rocket
|
//the user wants the latest valid state of this rocket
|
||||||
rocketEvents = $ndk.storeSubscribe(
|
rocketEvents = $ndk.storeSubscribe(
|
||||||
[
|
[
|
||||||
meritRequest.RocketFilter()
|
meritRequest.REQFilter()
|
||||||
],
|
],
|
||||||
{ subId: meritRequest.RocketTag!.split(":")[2] }
|
{ subId: meritRequest.RocketTag!.split(":")[2] }
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user