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 "../../styles/Form.css";
import EmotePicker from "../modals/EmotePicker/EmotePicker"; import EmotePicker from "../modals/EmotePicker/EmotePicker";
import emotes from "../modals/EmotePicker/custom_emojis.json" import emotes from "../modals/EmotePicker/custom_emojis.json"
import { DEFAULT_DIFFICULTY } from "../../config";
interface FormProps { interface FormProps {
refEvent?: NostrEvent; refEvent?: NostrEvent;
@ -33,7 +34,7 @@ const NewNoteCard = ({
pubkey: "", pubkey: "",
}); });
const [difficulty, setDifficulty] = useState( const [difficulty, setDifficulty] = useState(
localStorage.getItem("difficulty") || "21" localStorage.getItem("difficulty") || DEFAULT_DIFFICULTY.toString()
); );
useEffect(() => { useEffect(() => {
@ -78,7 +79,7 @@ const NewNoteCard = ({
})); }));
}, [comment]); }, [comment]);
const { handleSubmit: originalHandleSubmit, doingWorkProp, doingWorkProgress } = useSubmitForm(unsigned, difficulty); const { handleSubmit: originalHandleSubmit, doingWorkProp, hashrate, bestPow } = useSubmitForm(unsigned, difficulty);
const handleSubmit = async (event: React.FormEvent) => { const handleSubmit = async (event: React.FormEvent) => {
await originalHandleSubmit(event); await originalHandleSubmit(event);
@ -127,13 +128,30 @@ const NewNoteCard = ({
rows={comment.split('\n').length || 1} rows={comment.split('\n').length || 1}
/> />
<div className="h-14 flex items-center justify-between"> <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"> <div className="inline-flex items-center gap-1.5 text-neutral-300">
<CpuChipIcon className="h-4 w-4" /> <CpuChipIcon className="h-4 w-4" />
</div> </div>
<p className="text-xs font-medium text-neutral-400"> <input
{difficulty} Work type="number"
</p> 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> <div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@ -148,14 +166,15 @@ const NewNoteCard = ({
</div> </div>
</div> </div>
</div> </div>
</div>
{doingWorkProp ? ( {doingWorkProp ? (
<div className="flex animate-pulse text-sm text-gray-300"> <div className="flex animate-pulse text-xs text-gray-300">
<CpuChipIcon className="h-4 w-4 ml-auto" /> <CpuChipIcon className="h-4 w-4 ml-auto" />
<span>Doing Work:</span> <span>Doing Work:</span>
{doingWorkProgress && <span>{doingWorkProgress} hashes</span>} {hashrate && <span>{hashrate > 100000 ? `${(hashrate / 1000).toFixed(0)}k` : hashrate}</span>}H/s
<span className="pl-1"> (PB:{bestPow})</span>
</div> </div>
) : null} ) : null}
</div>
<div id="postFormError" className="text-red-500" /> <div id="postFormError" className="text-red-500" />
</form> </form>
); );

View File

@ -5,6 +5,7 @@ import { useState, useEffect } from "react";
import { UnsignedEvent, Event as NostrEvent, nip19 } from "nostr-tools"; import { UnsignedEvent, Event as NostrEvent, nip19 } from "nostr-tools";
import { useSubmitForm } from "./handleSubmit"; import { useSubmitForm } from "./handleSubmit";
import "../../styles/Form.css"; import "../../styles/Form.css";
import { DEFAULT_DIFFICULTY } from "../../config";
interface FormProps { interface FormProps {
refEvent: NostrEvent; refEvent: NostrEvent;
@ -14,7 +15,7 @@ const RepostNote = ({
refEvent refEvent
}: FormProps) => { }: FormProps) => {
const [difficulty, setDifficulty] = useState( const [difficulty, setDifficulty] = useState(
localStorage.getItem("difficulty") || "21" localStorage.getItem("difficulty") || DEFAULT_DIFFICULTY.toString()
); );
const [unsigned] = useState<UnsignedEvent>({ const [unsigned] = useState<UnsignedEvent>({
kind: 6, kind: 6,
@ -42,7 +43,7 @@ const RepostNote = ({
}; };
}, []); }, []);
const { handleSubmit, doingWorkProp, doingWorkProgress } = useSubmitForm(unsigned, difficulty); const { handleSubmit, doingWorkProp, hashrate } = useSubmitForm(unsigned, difficulty);
return ( return (
<form <form
@ -75,7 +76,7 @@ const RepostNote = ({
<div className="flex animate-pulse text-sm text-gray-300"> <div className="flex animate-pulse text-sm text-gray-300">
<CpuChipIcon className="h-4 w-4 ml-auto" /> <CpuChipIcon className="h-4 w-4 ml-auto" />
<span>Doing Work:</span> <span>Doing Work:</span>
{doingWorkProgress && <span>{doingWorkProgress} hashes</span>} {hashrate && <span>{hashrate} H/s</span>}
</div> </div>
) : null} ) : null}
<div id="postFormError" className="text-red-500" /> <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 useWorkers = (numCores: number, unsigned: UnsignedEvent, difficulty: string, deps: any[]) => {
const [messageFromWorker, setMessageFromWorker] = useState(null); 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 startWork = () => {
const workers = Array(numCores).fill(null).map(() => new Worker(new URL("../../powWorker", import.meta.url))); 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) => { workers.forEach((worker, index) => {
worker.onmessage = (event) => { worker.onmessage = (event) => {
if (event.data.status === 'progress') { if (event.data.status === 'progress') {
console.log(`Worker progress: Checked ${event.data.currentNonce} nonces.`); setHashrate(Math.floor(event.data.currentNonce/((Date.now() - startTime)/1000)));
setDoingWorkProgress(event.data.currentNonce); if (event.data.bestPoW > bestPow) {
setBestPow(event.data.bestPoW)
}
} else if (event.data.found) { } else if (event.data.found) {
setMessageFromWorker(event.data.event); setMessageFromWorker(event.data.event);
// Terminate all workers once a solution is found // 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) => { 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 // Initialize the worker outside of any effects
const numCores = navigator.hardwareConcurrency || 4; 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(() => { useEffect(() => {
if (unsignedPoWEvent) { if (unsignedPoWEvent) {
@ -99,5 +104,5 @@ export const useSubmitForm = (unsigned: UnsignedEvent, difficulty: string) => {
} }
}, [messageFromWorker]); }, [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")) (event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e" || tag[0] === "a"))
) )
const sortedEvents = postEvents const sortedEvents = postEvents.sort((a, b) => b.created_at - a.created_at);
.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;
}
);
// Render the component // Render the component
return ( 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'> } { export function minePow<K extends number>(unsigned: UnsignedEvent, difficulty: number, nonceStart: number, nonceStep: number): { found: boolean, event?: Omit<Event, 'sig'> } {
let nonce = nonceStart; let nonce = nonceStart;
let bestPoW = 0;
const event = unsigned as Omit<Event, 'sig'> const event = unsigned as Omit<Event, 'sig'>
const tag = ['nonce', nonce.toString(), difficulty.toString()] 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(); tag[1] = (nonce).toString();
event.id = getEventHash(event); 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 }; return { found: true, event: event };
} }
nonce += nonceStep; nonce += nonceStep;
if (nonce % (nonceStep * 10000) === 0) { if (nonce % (nonceStep * 10000) === 0) {
ctx.postMessage({ status: 'progress', currentNonce: nonce }); ctx.postMessage({ status: 'progress', currentNonce: nonce, bestPoW});
} }
} }
return { found: false }; return { found: false };

View File

@ -1,3 +1,14 @@
textarea { textarea {
caret-color: rgb(0, 38, 255); 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 */
}