mirror of
https://github.com/edufeed-org/polloer.git
synced 2025-12-07 15:24:31 +00:00
cleanup,
This commit is contained in:
parent
34781e8c29
commit
1878d82fad
7 changed files with 218 additions and 252 deletions
29
package-lock.json
generated
29
package-lock.json
generated
|
|
@ -774,37 +774,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@nostr-dev-kit/ndk-svelte": {
|
||||
"version": "2.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk-svelte/-/ndk-svelte-2.4.10.tgz",
|
||||
"integrity": "sha512-meBNrgcVXqM/VFPO8LykhiSncMbqvfMWqbtRF4SOsLwDMbK7IigRKtuUUJoHvalEn+3OB2TZYp/FV9EIMHQ00w==",
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk-svelte/-/ndk-svelte-2.4.11.tgz",
|
||||
"integrity": "sha512-HCHFVQJ0lJBaGmMooJzmUhpTCATMtssbZsyYDLs729xl2xO//fOOGkiV3IUePhk0nKS85TfalP0aCXouQG/XMQ==",
|
||||
"dependencies": {
|
||||
"@nostr-dev-kit/ndk": "2.14.4"
|
||||
"@nostr-dev-kit/ndk": "2.14.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@nostr-dev-kit/ndk-svelte/node_modules/@nostr-dev-kit/ndk": {
|
||||
"version": "2.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@nostr-dev-kit/ndk/-/ndk-2.14.4.tgz",
|
||||
"integrity": "sha512-mh7IoKvzDXoh6PJNyvrNVAMm6Zor1xyEKjnVfXQ11WTDXCwOA8Ksff1qxVQOn7u6ZlxlZN4wHBeUwWswuD9FSA==",
|
||||
"dependencies": {
|
||||
"@noble/curves": "^1.6.0",
|
||||
"@noble/hashes": "^1.5.0",
|
||||
"@noble/secp256k1": "^2.1.0",
|
||||
"@scure/base": "^1.1.9",
|
||||
"debug": "^4.3.6",
|
||||
"light-bolt11-decoder": "^3.2.0",
|
||||
"tseep": "^1.3.1",
|
||||
"typescript-lru-cache": "^2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"nostr-tools": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@polka/url": {
|
||||
"version": "1.0.0-next.29",
|
||||
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
|
||||
|
|
|
|||
|
|
@ -3,17 +3,14 @@
|
|||
|
||||
import { onMount } from 'svelte';
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import { ndk, ndkReady, user } from '$lib/stores';
|
||||
import { ndk } from '$lib/stores';
|
||||
import { writable } from 'svelte/store';
|
||||
import { login } from '$lib';
|
||||
import { Carta, Markdown, MarkdownEditor } from 'carta-md';
|
||||
import 'carta-md/default.css'; /* Default theme */
|
||||
import DOMPurify from 'dompurify';
|
||||
import { Confetti } from "svelte-confetti"
|
||||
|
||||
|
||||
console.log("show reactions", showReactions, event)
|
||||
import { Confetti } from 'svelte-confetti';
|
||||
|
||||
console.log('show reactions', showReactions, event);
|
||||
|
||||
// Create a new instance of Carta (you might also want to add a sanitizer if you're processing user input)
|
||||
let carta = new Carta({
|
||||
|
|
@ -21,7 +18,7 @@
|
|||
});
|
||||
let reactions = writable([]);
|
||||
let reacted = writable(window.localStorage.getItem(event.id));
|
||||
let reaction = writable({})
|
||||
let reaction = writable({});
|
||||
let clicked = writable(false);
|
||||
|
||||
async function sendReaction() {
|
||||
|
|
@ -31,28 +28,28 @@
|
|||
tags: [['e', event.id]]
|
||||
});
|
||||
await reactionEvent.publish();
|
||||
$reaction = reactionEvent;
|
||||
$reaction = reactionEvent;
|
||||
const r = await $ndk.fetchEvents({ kinds: [7], '#e': [event.id] });
|
||||
console.log('r', r);
|
||||
$reactions = Array.from(r);
|
||||
window.localStorage.setItem(event.id, 'true');
|
||||
$reacted = true;
|
||||
$clicked = true
|
||||
$reacted = 'true';
|
||||
$clicked = true;
|
||||
}
|
||||
|
||||
async function deleteVote() {
|
||||
const deletionEvent = new NDKEvent($ndk, {
|
||||
kind: 5,
|
||||
content: "User deleted vote",
|
||||
tags: [
|
||||
["e", event.id],
|
||||
["k", 7]
|
||||
]
|
||||
})
|
||||
await deletionEvent.publish()
|
||||
window.localStorage.removeItem(event.id)
|
||||
$reacted = false
|
||||
}
|
||||
async function deleteVote() {
|
||||
const deletionEvent = new NDKEvent($ndk, {
|
||||
kind: 5,
|
||||
content: 'User deleted vote',
|
||||
tags: [
|
||||
['e', event.id],
|
||||
['k', 7]
|
||||
]
|
||||
});
|
||||
await deletionEvent.publish();
|
||||
window.localStorage.removeItem(event.id);
|
||||
$reacted = 'false';
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const r = await $ndk.fetchEvents({ kinds: [7], '#e': [event.id] });
|
||||
|
|
@ -65,12 +62,12 @@
|
|||
<Markdown {carta} value={event.content} />
|
||||
{/key}
|
||||
|
||||
<div class="flex gap-2 reactions">
|
||||
<div class="reactions flex gap-2">
|
||||
{#if $reacted}
|
||||
<span>👍 {$reactions.length}</span>
|
||||
<span class="thanks">Danke für deinen Vote!</span>
|
||||
<!-- <button onclick={() => deleteVote()} class="btn">Vote zurückziehen</button> -->
|
||||
{:else if showReactions === "true"}
|
||||
<!-- <button onclick={() => deleteVote()} class="btn">Vote zurückziehen</button> -->
|
||||
{:else if showReactions === 'true'}
|
||||
<button onclick={() => sendReaction()} class="like">👍</button>
|
||||
<span>{$reactions.length}</span>
|
||||
{/if}
|
||||
|
|
@ -79,19 +76,20 @@
|
|||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.like {
|
||||
cursor: pointer;
|
||||
}
|
||||
.reactions {
|
||||
padding-top: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
.thanks {
|
||||
color: #777;
|
||||
}
|
||||
.like {
|
||||
cursor: pointer;
|
||||
}
|
||||
.reactions {
|
||||
padding-top: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
.thanks {
|
||||
color: #777;
|
||||
}
|
||||
.comment {
|
||||
border-radius: 20px;
|
||||
border-color: #ccc;
|
||||
border-radius: 20px;
|
||||
border-color: #ccc;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
import { NDKNip07Signer, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
|
||||
import { ndk as ndkStore, user as userStore } from "$lib/stores";
|
||||
import { ndk } from "$lib/stores";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
export async function login() {
|
||||
let ndk = get(ndkStore)
|
||||
let user = get(userStore)
|
||||
if (window.nostr) {
|
||||
const signer = new NDKNip07Signer();
|
||||
ndk.signer = signer;
|
||||
const signedUser = await signer.user();
|
||||
userStore.set(signedUser)
|
||||
get(ndk).signer = signer;
|
||||
signer.user();
|
||||
} else {
|
||||
console.log("no extension")
|
||||
const storedPrivateKey = window.localStorage.getItem('nostrPrivateKey');
|
||||
|
|
@ -17,24 +14,20 @@ export async function login() {
|
|||
const privateKey = JSON.parse(storedPrivateKey);
|
||||
console.log("stored private key", privateKey)
|
||||
const signer = new NDKPrivateKeySigner(privateKey);
|
||||
const signedUser = await signer.user();
|
||||
userStore.set(signedUser)
|
||||
ndk.signer = signer;
|
||||
console.log("ndk signer", ndk)
|
||||
ndkStore.set(ndk)
|
||||
ndk.update((ndk) => {
|
||||
ndk.signer = signer;
|
||||
return ndk;
|
||||
});
|
||||
// get(ndk).signer = signer;
|
||||
signer.user();
|
||||
} else {
|
||||
console.log('No private key found, generating a new one...');
|
||||
const privateKey = NDKPrivateKeySigner.generate();
|
||||
const signer = new NDKPrivateKeySigner(privateKey.privateKey);
|
||||
console.log('Generated Private Key:', privateKey);
|
||||
|
||||
const signedUser = await signer.user();
|
||||
userStore.set(signedUser)
|
||||
|
||||
signer.user();
|
||||
window.localStorage.setItem('nostrPrivateKey', JSON.stringify(privateKey.privateKey));
|
||||
ndk.signer = signer;
|
||||
console.log("ndk signer", ndk)
|
||||
ndkStore.set(ndk)
|
||||
get(ndk).signer = signer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,21 @@
|
|||
import NDKSvelte from "@nostr-dev-kit/ndk-svelte";
|
||||
import { writable, derived } from "svelte/store";
|
||||
import { NDKNip07Signer } from "@nostr-dev-kit/ndk";
|
||||
import { NDKUser } from "@nostr-dev-kit/ndk";
|
||||
|
||||
export let connected = writable(false);
|
||||
|
||||
export const ndk = writable(new NDKSvelte());
|
||||
const _ndk = new NDKSvelte({
|
||||
explicitRelayUrls: [
|
||||
'wss://relay-rpi.edufeed.org'
|
||||
],
|
||||
});
|
||||
|
||||
export const ndkReady = derived(ndk, $ndk => $ndk !== null);
|
||||
export const ndk = writable(_ndk)
|
||||
|
||||
export async function initializeNDK() {
|
||||
const signer = new NDKNip07Signer
|
||||
const ndkInstance = new NDKSvelte({
|
||||
explicitRelayUrls: [
|
||||
'wss://relay-rpi.edufeed.org'
|
||||
],
|
||||
});
|
||||
|
||||
await ndkInstance.connect();
|
||||
|
||||
// ndkInstance.signer = signer;
|
||||
ndk.set(ndkInstance);
|
||||
|
||||
return ndkInstance;
|
||||
}
|
||||
|
||||
export const user = writable(null);
|
||||
export const user = derived(ndk, $ndk => {
|
||||
console.log("updating user")
|
||||
if ($ndk.signer !== undefined) {
|
||||
return new NDKUser($ndk.signer);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,22 +1,19 @@
|
|||
<script>
|
||||
import '../app.css';
|
||||
import { onMount } from 'svelte';
|
||||
import { NDKNip07Signer } from '@nostr-dev-kit/ndk';
|
||||
import NDKSvelte from '@nostr-dev-kit/ndk-svelte/svelte5';
|
||||
import { ndk, connected, initializeNDK } from '$lib/stores';
|
||||
import { ndk, connected } from '$lib/stores';
|
||||
import { browser } from '$app/environment';
|
||||
import { login } from '$lib';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
onMount(async () => {
|
||||
const nip07signer = new NDKNip07Signer();
|
||||
if (browser) {
|
||||
try {
|
||||
await initializeNDK();
|
||||
await login()
|
||||
await $ndk.connect();
|
||||
console.log('NDK initialized successfully');
|
||||
connected.set(true);
|
||||
await login()
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize NDK:', error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,23 @@
|
|||
<script>
|
||||
import { goto } from '$app/navigation';
|
||||
import { ndk, connected, user, ndkReady } from '$lib/stores';
|
||||
import { NDKEvent, NDKNip07Signer, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk';
|
||||
import { ndk, connected, user } from '$lib/stores';
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import { writable } from 'svelte/store';
|
||||
import QRCode from 'qrcode';
|
||||
import { login } from '$lib';
|
||||
import { Carta, MarkdownEditor } from 'carta-md';
|
||||
import 'carta-md/default.css'; /* Default theme */
|
||||
import DOMPurify from 'dompurify';
|
||||
import { Confetti } from "svelte-confetti"
|
||||
import { Confetti } from 'svelte-confetti';
|
||||
|
||||
// Create a new instance of Carta (you might also want to add a sanitizer if you're processing user input)
|
||||
let carta = new Carta({
|
||||
sanitizer: DOMPurify.sanitize
|
||||
});
|
||||
let question = writable('');
|
||||
let questionId = writable(''); ;
|
||||
let questionId = writable('');
|
||||
let questionShortId = 0;
|
||||
let qrCodeUrl = writable('');
|
||||
let timer = 0;
|
||||
let votingEnabled = false;
|
||||
let sessionId = '';
|
||||
let event = writable();
|
||||
|
|
@ -27,13 +26,13 @@
|
|||
console.log('join ' + sessionId);
|
||||
const filter = {
|
||||
kinds: [1342],
|
||||
'#d': [sessionId + ''], // filter by `d` tag
|
||||
'#d': [sessionId + ''] // filter by `d` tag
|
||||
};
|
||||
console.log(filter)
|
||||
console.log(filter);
|
||||
const question = await $ndk.fetchEvent(filter);
|
||||
console.log('question', question);
|
||||
goto('/q/' + question.id);
|
||||
login()
|
||||
login();
|
||||
}
|
||||
async function postQuestion() {
|
||||
questionShortId = 10000000 + Math.floor(Math.random() * 90000000);
|
||||
|
|
@ -43,39 +42,20 @@
|
|||
tags: [['d', questionShortId + '']]
|
||||
});
|
||||
await $event.publishReplaceable();
|
||||
console.log("event id", $event.id)
|
||||
console.log('event id', $event.id);
|
||||
$questionId = `${$event.kind}:${$event.pubkey}:${$event.dTag}`;
|
||||
$qrCodeUrl = await QRCode.toDataURL(`${window.location.origin}/q/${$questionId}`, {
|
||||
width: 800,
|
||||
width: 800
|
||||
});
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
const interval = setInterval(() => {
|
||||
if (timer > 0) {
|
||||
timer--;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
votingEnabled = true;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if ($ndkReady) {
|
||||
if ($ndk.activeUser) {
|
||||
console.log('User:', $user);
|
||||
} else {
|
||||
login();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="main-layout">
|
||||
<img src="logo.png" alt="" class="logo">
|
||||
{#if !$user}
|
||||
<div class="login"><button class="btn btn-primary" onclick={() => login()}>Login</button></div>
|
||||
<img src="logo.png" alt="" class="logo" />
|
||||
{#if $ndk?.signer === undefined}
|
||||
<div class="login">
|
||||
<button class="btn btn-primary" onclick={login}>Login</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !$questionId}
|
||||
|
|
@ -84,7 +64,9 @@
|
|||
{#if $connected}
|
||||
<div class="join">
|
||||
<input type="number" class="border p-2" placeholder="12345678" bind:value={sessionId} />
|
||||
<button class="btn btn-primary rounded" onclick={() => joinSession()}> Teilnehmen </button>
|
||||
<button class="btn btn-primary rounded" onclick={() => joinSession()}>
|
||||
Teilnehmen
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -93,23 +75,36 @@
|
|||
<div class="mx-auto p-4">
|
||||
<h1 class="mb-4 text-2xl font-bold">Eine Ideensammlung starten</h1>
|
||||
{#if $connected}
|
||||
{#key $questionId}
|
||||
{#if $questionId === ''}
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<MarkdownEditor bind:value={$question} {carta} />
|
||||
<div><button class="btn btn-primary rounded mt-5" onclick={postQuestion}> Starten </button></div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="qr-share mt-4">
|
||||
<h2 class="text-xl font-bold">Diese Sammlung teilen</h2>
|
||||
<h3 class="text-center short-id">{questionShortId}</h3>
|
||||
<div class="flex justify-center"><Confetti amount="600" size="15" cone x={[-4.5, 4.5]} y={[-1.5, 1.5]} delay={[0, 1000]} /></div>
|
||||
<img src={$qrCodeUrl} alt="QR Code" class="mt-2" />
|
||||
<p class="mb-1 text-center">Diesen QR-Code oder Link teilen:</p>
|
||||
<p class="text-center mb-2 text-xl">
|
||||
<a href={`/q/${$questionId}`}>{`${window.location.origin}/q/`}<span class="font-bold">{questionShortId}</span></a>
|
||||
</p>
|
||||
<!--
|
||||
{#key $questionId}
|
||||
{#if $questionId === ''}
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<MarkdownEditor bind:value={$question} {carta} />
|
||||
<div>
|
||||
<button class="btn btn-primary mt-5 rounded" onclick={postQuestion}> Starten </button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="qr-share mt-4">
|
||||
<h2 class="text-xl font-bold">Diese Sammlung teilen</h2>
|
||||
<h3 class="short-id text-center">{questionShortId}</h3>
|
||||
<div class="flex justify-center">
|
||||
<Confetti
|
||||
amount="600"
|
||||
size="15"
|
||||
cone
|
||||
x={[-4.5, 4.5]}
|
||||
y={[-1.5, 1.5]}
|
||||
delay={[0, 1000]}
|
||||
/>
|
||||
</div>
|
||||
<img src={$qrCodeUrl} alt="QR Code" class="mt-2" />
|
||||
<p class="mb-1 text-center">Diesen QR-Code oder Link teilen:</p>
|
||||
<p class="mb-2 text-center text-xl">
|
||||
<a href={`/q/${$questionId}`}
|
||||
>{`${window.location.origin}/q/`}<span class="font-bold">{questionShortId}</span></a
|
||||
>
|
||||
</p>
|
||||
<!--
|
||||
<div class="mt-4">
|
||||
<label for="timer" class="mb-2 block">Set Timer (seconds):</label>
|
||||
<input type="number" id="timer" class="rounded border p-2" bind:value={timer} />
|
||||
|
|
@ -118,48 +113,48 @@
|
|||
</button>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if votingEnabled}
|
||||
<div class="mt-4">
|
||||
<h2 class="text-xl font-bold">Abstimmung ist jetzt aktiv!</h2>
|
||||
<p>Es können jetzt Stimmen abgegeben werden.</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
{#if votingEnabled}
|
||||
<div class="mt-4">
|
||||
<h2 class="text-xl font-bold">Abstimmung ist jetzt aktiv!</h2>
|
||||
<p>Es können jetzt Stimmen abgegeben werden.</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.carta-input) {
|
||||
height: 150px !important;
|
||||
height: 150px !important;
|
||||
}
|
||||
:global(.carta-editor) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:global(.carta-editor) {
|
||||
width: 100% !important;
|
||||
}
|
||||
input[type='number']::-webkit-inner-spin-button,
|
||||
input[type='number']::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
.short-id {
|
||||
font-size: 60px;
|
||||
font-size: 60px;
|
||||
}
|
||||
.qr-share img {
|
||||
width: 100%;
|
||||
border: 3px solid #eee;
|
||||
}
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.logo {
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.main-layout {
|
||||
margin: auto;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<script>
|
||||
import { Confetti } from 'svelte-confetti';
|
||||
import { onDestroy } from 'svelte';
|
||||
|
||||
/** @type {import('./$types').PageProps} */
|
||||
let { data } = $props();
|
||||
|
||||
import Comment from '$lib/components/Comment.svelte';
|
||||
import { ndk, ndkReady, user } from '$lib/stores';
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import { writable } from 'svelte/store';
|
||||
import { ndk, user } from '$lib/stores';
|
||||
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
|
||||
import { derived, writable } from 'svelte/store';
|
||||
import { Carta, Markdown, MarkdownEditor } from 'carta-md';
|
||||
import 'carta-md/default.css'; /* Default theme */
|
||||
import DOMPurify from 'dompurify';
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
let carta = new Carta({
|
||||
sanitizer: DOMPurify.sanitize
|
||||
});
|
||||
|
||||
function submitComment() {
|
||||
if (!$comment) {
|
||||
return;
|
||||
|
|
@ -24,61 +25,71 @@
|
|||
const commentEvent = new NDKEvent($ndk, {
|
||||
kind: 2222,
|
||||
content: $comment,
|
||||
tags: [['E', data.id]]
|
||||
tags: [['A', data.id]]
|
||||
});
|
||||
commentEvent.publish();
|
||||
comment.set('');
|
||||
setTimeout(() => submit.set(false), 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an array of objects to keep only unique objects based on their id property
|
||||
* @param {Array} array - The array of objects to filter
|
||||
* @returns {Array} - A new array containing only unique objects by id
|
||||
*/
|
||||
function getUniqueById(array) {
|
||||
// Create a Map to track unique objects by their id
|
||||
const uniqueMap = new Map();
|
||||
|
||||
// Loop through the array and add each object to the map with its id as the key
|
||||
// This automatically overrides any previous entries with the same id
|
||||
array.forEach((item) => {
|
||||
if (item && item.id !== undefined) {
|
||||
uniqueMap.set(item.id, item);
|
||||
}
|
||||
});
|
||||
|
||||
// Convert the Map values back to an array
|
||||
return Array.from(uniqueMap.values());
|
||||
}
|
||||
|
||||
let comment = writable('');
|
||||
let submit = writable(false);
|
||||
let comments = writable([]);
|
||||
let question = writable();
|
||||
const [kind, pubkey, d] = data.id.split(':');
|
||||
const showReactions = writable(false);
|
||||
const showReactions = writable('false');
|
||||
const comments = writable([]);
|
||||
|
||||
let commentStore = $ndk.storeSubscribe(
|
||||
{ kinds: [2222], '#A': [data.id] },
|
||||
{
|
||||
onEvent: (event) => {
|
||||
console.log('Event received', event);
|
||||
$comments = [event, ...$comments];
|
||||
},
|
||||
onEose: () => console.log('Subscription EOSE reached'),
|
||||
closeOnEose: false,
|
||||
autoStart: true
|
||||
}
|
||||
);
|
||||
commentStore.ref();
|
||||
|
||||
let questionStore = $ndk.storeSubscribe({ kinds: [Number(kind)], authors: [pubkey], '#d': [d] });
|
||||
questionStore.ref();
|
||||
|
||||
let question = derived(
|
||||
[questionStore],
|
||||
([$questionStore]) => {
|
||||
if ($questionStore.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$questionStore.sort((a, b) => {
|
||||
return b.created_at - a.created_at;
|
||||
});
|
||||
const reactionTag = $questionStore[0].tags.find((t) => t[0] === 'reactions');
|
||||
if (reactionTag && reactionTag[1] === 'true') {
|
||||
console.log('reactions enabled');
|
||||
$showReactions = 'true';
|
||||
}
|
||||
console.log('question', $questionStore[0]);
|
||||
return $questionStore[0];
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
onDestroy(() => {
|
||||
commentStore.unsubscribe();
|
||||
questionStore.unsubscribe();
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if ($ndkReady) {
|
||||
console.log('ndk ready');
|
||||
const sub = $ndk.subscribe({ kinds: [2222], '#E': [data.id] });
|
||||
sub.on('event', (event) => {
|
||||
console.log(event);
|
||||
const unique = getUniqueById([...$comments, event]);
|
||||
$comments = [...unique];
|
||||
console.log(`${event.content}`);
|
||||
});
|
||||
if ($ndk.signer) {
|
||||
console.log('got a signer');
|
||||
console.log('start subscription');
|
||||
commentStore.startSubscription();
|
||||
|
||||
const questionSub = $ndk.subscribe({ kinds: [Number(kind)], authors: [pubkey], '#d': [d] });
|
||||
questionSub.on('event', (event) => {
|
||||
$question = event;
|
||||
if ($question?.tags.find((t) => t[0] === 'reactions')[1] === 'true') {
|
||||
console.log('reactions enabled');
|
||||
$showReactions = 'true';
|
||||
}
|
||||
});
|
||||
questionStore.startSubscription();
|
||||
console.log('comment store', $commentStore);
|
||||
}
|
||||
console.log('user', $user);
|
||||
});
|
||||
|
||||
async function startReactions(event) {
|
||||
|
|
@ -93,35 +104,34 @@
|
|||
</script>
|
||||
|
||||
<div class="main-layout mx-auto flex w-3/4 flex-col items-center justify-center">
|
||||
{#if $question}
|
||||
{#if $question.pubkey === $user.pubkey && $showReactions === false}
|
||||
<button class="btn btn-primary mb-4" onclick={() => startReactions($question)}
|
||||
>Reaktionen/Voting aktivieren</button
|
||||
>
|
||||
{/if}
|
||||
<div class="question mb-4 w-full rounded border p-4 text-xl">
|
||||
<h2 class="text-xl font-bold">Frage / Thema:</h2>
|
||||
<Markdown {carta} value={$question.content} />
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex w-full flex-col items-center justify-center gap-2">
|
||||
<h1 class="pt-15 text-xl font-bold">Meine Idee hinzufügen</h1>
|
||||
<MarkdownEditor bind:value={$comment} {carta} />
|
||||
<button class="btn btn-primary mt-5 mb-10" onclick={() => submitComment()}>Hinzufügen</button>
|
||||
{#if $submit === true}
|
||||
<div class="flex justify-center"><Confetti amount="50"} /></div>
|
||||
{#key $question?.pubkey}
|
||||
{#if $question}
|
||||
{#if $user && $question?.pubkey === $user?.pubkey && $showReactions === "false"}
|
||||
<button class="btn btn-primary mb-4" onclick={() => startReactions($question)}
|
||||
>Reaktionen/Voting aktivieren</button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
<div class="question mb-4 w-full rounded border p-4 text-xl">
|
||||
<h2 class="text-xl font-bold">Frage / Thema:</h2>
|
||||
<Markdown {carta} value={$question.content} />
|
||||
</div>
|
||||
|
||||
<div class="mb-2 flex w-full flex-col items-center justify-center gap-2">
|
||||
<h1 class="pt-15 text-xl font-bold">Meine Idee hinzufügen</h1>
|
||||
<MarkdownEditor bind:value={$comment} {carta} />
|
||||
<button class="btn btn-primary mt-5 mb-10" onclick={() => submitComment()}
|
||||
>Hinzufügen</button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
<div class="mx-auto flex w-full flex-col items-center justify-center gap-5">
|
||||
{#key $showReactions}
|
||||
{#each $comments.sort((a, b) => b.created_at - a.created_at) as event}
|
||||
<Comment event={event} showReactions={$showReactions} />
|
||||
{/each}
|
||||
{/key}
|
||||
{#each $commentStore as event}
|
||||
<Comment {event} showReactions={$showReactions} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue