Post form changes and sort timeline by age again

This commit is contained in:
smolgrrr 2024-08-23 12:46:57 +10:00
parent dd06723203
commit 8231f7bf93
6 changed files with 70 additions and 37 deletions

View File

@ -7,6 +7,7 @@ import { useSubmitForm } from "./handleSubmit";
import "../../styles/Form.css";
import EmotePicker from "../modals/EmotePicker/EmotePicker";
import emotes from "../modals/EmotePicker/custom_emojis.json"
import { DEFAULT_DIFFICULTY } from "../../config";
interface FormProps {
refEvent?: NostrEvent;
@ -33,7 +34,7 @@ const NewNoteCard = ({
pubkey: "",
});
const [difficulty, setDifficulty] = useState(
localStorage.getItem("difficulty") || "21"
localStorage.getItem("difficulty") || DEFAULT_DIFFICULTY.toString()
);
useEffect(() => {
@ -78,7 +79,7 @@ const NewNoteCard = ({
}));
}, [comment]);
const { handleSubmit: originalHandleSubmit, doingWorkProp, doingWorkProgress } = useSubmitForm(unsigned, difficulty);
const { handleSubmit: originalHandleSubmit, doingWorkProp, hashrate, bestPow } = useSubmitForm(unsigned, difficulty);
const handleSubmit = async (event: React.FormEvent) => {
await originalHandleSubmit(event);
@ -127,13 +128,30 @@ const NewNoteCard = ({
rows={comment.split('\n').length || 1}
/>
<div className="h-14 flex items-center justify-between">
<div className="inline-flex items-center gap-2 bg-neutral-800 px-1.5 py-1 rounded-lg">
<div className="inline-flex items-center bg-neutral-800 px-1 py-0.5 rounded-lg">
<div className="inline-flex items-center gap-1.5 text-neutral-300">
<CpuChipIcon className="h-4 w-4" />
</div>
<p className="text-xs font-medium text-neutral-400">
{difficulty} Work
</p>
<input
type="number"
className="bg-neutral-800 text-white text-xs font-medium border-none rounded-lg w-10"
value={difficulty}
onChange={(e) => setDifficulty(e.target.value)}
min="10" // Assuming a minimum difficulty value of 1
/>
<button
type="button"
onClick={() => setDifficulty(String(Math.max(10, parseInt(difficulty) - 1)))} // Decrement, ensuring not below min
>
-
</button>
<button
type="button"
className="pl-0.5"
onClick={() => setDifficulty(String(parseInt(difficulty) + 1))} // Increment
>
+
</button>
</div>
<div>
<div className="flex items-center gap-4">
@ -148,14 +166,15 @@ const NewNoteCard = ({
</div>
</div>
</div>
{doingWorkProp ? (
<div className="flex animate-pulse text-xs text-gray-300">
<CpuChipIcon className="h-4 w-4 ml-auto" />
<span>Doing Work:</span>
{hashrate && <span>{hashrate > 100000 ? `${(hashrate / 1000).toFixed(0)}k` : hashrate}</span>}H/s
<span className="pl-1"> (PB:{bestPow})</span>
</div>
) : null}
</div>
{doingWorkProp ? (
<div className="flex animate-pulse text-sm text-gray-300">
<CpuChipIcon className="h-4 w-4 ml-auto" />
<span>Doing Work:</span>
{doingWorkProgress && <span>{doingWorkProgress} hashes</span>}
</div>
) : null}
<div id="postFormError" className="text-red-500" />
</form>
);

View File

@ -5,6 +5,7 @@ import { useState, useEffect } from "react";
import { UnsignedEvent, Event as NostrEvent, nip19 } from "nostr-tools";
import { useSubmitForm } from "./handleSubmit";
import "../../styles/Form.css";
import { DEFAULT_DIFFICULTY } from "../../config";
interface FormProps {
refEvent: NostrEvent;
@ -14,7 +15,7 @@ const RepostNote = ({
refEvent
}: FormProps) => {
const [difficulty, setDifficulty] = useState(
localStorage.getItem("difficulty") || "21"
localStorage.getItem("difficulty") || DEFAULT_DIFFICULTY.toString()
);
const [unsigned] = useState<UnsignedEvent>({
kind: 6,
@ -42,7 +43,7 @@ const RepostNote = ({
};
}, []);
const { handleSubmit, doingWorkProp, doingWorkProgress } = useSubmitForm(unsigned, difficulty);
const { handleSubmit, doingWorkProp, hashrate } = useSubmitForm(unsigned, difficulty);
return (
<form
@ -75,7 +76,7 @@ const RepostNote = ({
<div className="flex animate-pulse text-sm text-gray-300">
<CpuChipIcon className="h-4 w-4 ml-auto" />
<span>Doing Work:</span>
{doingWorkProgress && <span>{doingWorkProgress} hashes</span>}
{hashrate && <span>{hashrate} H/s</span>}
</div>
) : null}
<div id="postFormError" className="text-red-500" />

View File

@ -4,7 +4,10 @@ import { publish } from "../../utils/relays";
const useWorkers = (numCores: number, unsigned: UnsignedEvent, difficulty: string, deps: any[]) => {
const [messageFromWorker, setMessageFromWorker] = useState(null);
const [doingWorkProgress, setDoingWorkProgress] = useState(0);
const [hashrate, setHashrate] = useState(0);
const [bestPow, setBestPow] = useState(0);
const startTime = Date.now();
const startWork = () => {
const workers = Array(numCores).fill(null).map(() => new Worker(new URL("../../powWorker", import.meta.url)));
@ -12,8 +15,10 @@ const useWorkers = (numCores: number, unsigned: UnsignedEvent, difficulty: strin
workers.forEach((worker, index) => {
worker.onmessage = (event) => {
if (event.data.status === 'progress') {
console.log(`Worker progress: Checked ${event.data.currentNonce} nonces.`);
setDoingWorkProgress(event.data.currentNonce);
setHashrate(Math.floor(event.data.currentNonce/((Date.now() - startTime)/1000)));
if (event.data.bestPoW > bestPow) {
setBestPow(event.data.bestPoW)
}
} else if (event.data.found) {
setMessageFromWorker(event.data.event);
// Terminate all workers once a solution is found
@ -30,7 +35,7 @@ const useWorkers = (numCores: number, unsigned: UnsignedEvent, difficulty: strin
});
};
return { startWork, messageFromWorker, doingWorkProgress };
return { startWork, messageFromWorker, hashrate, bestPow };
};
export const useSubmitForm = (unsigned: UnsignedEvent, difficulty: string) => {
@ -44,7 +49,7 @@ export const useSubmitForm = (unsigned: UnsignedEvent, difficulty: string) => {
// Initialize the worker outside of any effects
const numCores = navigator.hardwareConcurrency || 4;
const { startWork, messageFromWorker, doingWorkProgress } = useWorkers(numCores, unsignedWithPubkey, difficulty, [unsignedWithPubkey]);
const { startWork, messageFromWorker, hashrate, bestPow } = useWorkers(numCores, unsignedWithPubkey, difficulty, [unsignedWithPubkey]);
useEffect(() => {
if (unsignedPoWEvent) {
@ -99,5 +104,5 @@ export const useSubmitForm = (unsigned: UnsignedEvent, difficulty: string) => {
}
}, [messageFromWorker]);
return { handleSubmit, doingWorkProp, doingWorkProgress };
return { handleSubmit, doingWorkProp, hashrate, bestPow };
};

View File

@ -17,16 +17,7 @@ const Home = () => {
(event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e" || tag[0] === "a"))
)
const sortedEvents = postEvents
.sort((a, b) => {
// Sort by PoW in descending order
const powDiff = verifyPow(b) - verifyPow(a);
if (powDiff !== 0) return powDiff;
// If PoW is the same, sort by created_at in descending order
return b.created_at - a.created_at;
}
);
const sortedEvents = postEvents.sort((a, b) => b.created_at - a.created_at);
// Render the component
return (

View File

@ -45,6 +45,7 @@ export function getPow(hex: string): number {
*/
export function minePow<K extends number>(unsigned: UnsignedEvent, difficulty: number, nonceStart: number, nonceStep: number): { found: boolean, event?: Omit<Event, 'sig'> } {
let nonce = nonceStart;
let bestPoW = 0;
const event = unsigned as Omit<Event, 'sig'>
const tag = ['nonce', nonce.toString(), difficulty.toString()]
@ -57,15 +58,20 @@ export function minePow<K extends number>(unsigned: UnsignedEvent, difficulty: n
tag[1] = (nonce).toString();
event.id = getEventHash(event);
let leadingZeroes = getPow(event.id);
if (getPow(event.id) >= difficulty) {
if (leadingZeroes > bestPoW) {
bestPoW = leadingZeroes;
}
if (leadingZeroes >= difficulty) {
return { found: true, event: event };
}
nonce += nonceStep;
if (nonce % (nonceStep * 10000) === 0) {
ctx.postMessage({ status: 'progress', currentNonce: nonce });
ctx.postMessage({ status: 'progress', currentNonce: nonce, bestPoW});
}
}
return { found: false };

View File

@ -1,3 +1,14 @@
textarea {
caret-color: rgb(0, 38, 255);
}
/* Hide the increment and decrement buttons on number inputs */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield; /* Firefox */
}