rm boards

This commit is contained in:
smolgrrr 2024-04-19 19:27:30 +10:00
parent eef394a388
commit 91311e6346
7 changed files with 2 additions and 330 deletions

View File

@ -6,8 +6,6 @@ import Thread from "./components/Thread";
import Header from "./components/Header/Header";
import AddToHomeScreenPrompt from "./components/Modals/CheckMobile/CheckMobile";
import Notifications from "./components/Notifications";
import Board from "./components/Board";
import Boards from "./components/Boards";
function App() {
return (
@ -18,8 +16,6 @@ function App() {
<Route path="/" element={<Home />} />
<Route path="/thread/:id" element={<Thread />} />
<Route path="/notifications" element={<Notifications />} />
<Route path="/board/:id" element={<Board />} />
<Route path="/boards" element={<Boards />} />
</Routes>
<AddToHomeScreenPrompt/>
</Router>

View File

@ -1,130 +0,0 @@
import { useEffect, useState, useCallback } from "react";
import PostCard from "./Modals/NoteCard";
import { uniqBy } from "../utils/otherUtils"; // Assume getPow is a correct import now
import { subBoardFeed, subProfile} from "../utils/subscriptions";
import { verifyPow } from "../utils/mine";
import { Event, nip19 } from "nostr-tools";
import NewNoteCard from "./Forms/PostFormCard";
import RepostCard from "./Modals/RepostCard";
import OptionsBar from "./Modals/OptionsBar";
import { useParams } from "react-router-dom";
const DEFAULT_DIFFICULTY = 20;
const useUniqEvents = (pubkey: string) => {
const [events, setEvents] = useState<Event[]>([]);
const age = Number(localStorage.getItem("age")) || 24;
useEffect(() => {
const onEvent = (event: Event) => setEvents((prevEvents) => [...prevEvents, event]);
console.log(events)
const unsubscribe = subBoardFeed(pubkey, onEvent, age);
return unsubscribe;
}, [pubkey]);
const uniqEvents = uniqBy(events, "id");
const noteEvents = uniqEvents.filter(event => event.kind === 1 || event.kind === 6);
const metadataEvents = uniqEvents.filter(event => event.kind === 0);
const pinnedEvents = uniqEvents.filter(event => event.pubkey === pubkey && !event.tags.some((tag) => tag[0] === "e"));
return { pinnedEvents, noteEvents, metadataEvents };
};
const Board = () => {
const { id } = useParams();
const filterDifficulty = localStorage.getItem("filterDifficulty") || DEFAULT_DIFFICULTY;
const [sortByTime, setSortByTime] = useState<boolean>(localStorage.getItem('sortBy') !== 'false');
const [setAnon, setSetAnon] = useState<boolean>(localStorage.getItem('anonMode') !== 'false');
let decodeResult = nip19.decode(id as string);
let pubkey = decodeResult.data as string;
const {pinnedEvents, noteEvents, metadataEvents } = useUniqEvents(pubkey);
const [delayedSort, setDelayedSort] = useState(false)
const postEvents: Event[] = noteEvents
.filter((event) =>
verifyPow(event) >= Number(filterDifficulty) &&
event.kind !== 0 &&
(event.kind !== 1 || !event.tags.some((tag) => tag[0] === "e"))
)
// Delayed filtering
useEffect(() => {
const timer = setTimeout(() => {
setDelayedSort(true);
}, 3000);
return () => clearTimeout(timer);
}, []);
let sortedEvents = [...postEvents]
.sort((a, b) =>
sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a)
)
if (delayedSort) {
sortedEvents = sortedEvents.filter(
!setAnon ? (e) => !metadataEvents.some((metadataEvent) => metadataEvent.pubkey === e.pubkey) : () => true
);
} else {
sortedEvents = sortedEvents.filter((e) => setAnon || e.tags.some((tag) => tag[0] === "client" && tag[1] === 'getwired.app'));
}
const toggleSort = useCallback(() => {
setSortByTime(prev => {
const newValue = !prev;
localStorage.setItem('sortBy', String(newValue));
return newValue;
});
}, []);
const toggleAnon = useCallback(() => {
setSetAnon(prev => {
const newValue = !prev;
localStorage.setItem('anonMode', String(newValue));
return newValue;
});
}, []);
const countReplies = (event: Event) => {
return noteEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length;
};
// Render the component
return (
<main className="text-white mb-20">
<div className="w-full px-4 sm:px-0 sm:max-w-xl mx-auto my-2">
<NewNoteCard board={id}/>
</div>
<OptionsBar sortByTime={sortByTime} setAnon={setAnon} toggleSort={toggleSort} toggleAnon={toggleAnon} />
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4">
{pinnedEvents.map((event) => (
<div className="rounded-lg border border-red-900">
<PostCard
event={event}
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null}
replyCount={countReplies(event)}
/>
</div>
))}
{sortedEvents.map((event) => (
event.kind === 1 ?
<PostCard
event={event}
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null}
replyCount={countReplies(event)}
/>
:
<RepostCard
event={event}
/>
))}
</div>
</main>
);
};
export default Board;

View File

@ -1,85 +0,0 @@
import React, { useState } from 'react';
export const DefaultBoards = [
['Bitcoin', 'npub19nrn4l0s39kpwww7pgk9jddj8lzekqxmtrll8r2a57chtq3zx6sq00vetn', 'btc'],
['Technology', 'npub1mltf3r3tskdxfjlq6ltt2n73xs29wcza3sjfw75ggxz3p8fpcg4qe44h9v', 'g'],
['Television & Film', 'npub1cpeuaea3cymx42fmmx2ur82t5qnckqv85qy5q2nhzhxwzael5v4sksfe29', 'tv'],
['Vidya', 'npub19t2dt6deqaleq59fdaq576tnqdzwkyzwptxfa2tck0v66w29xagqe7yqll', 'v'],
['Politically Incorrect', 'npub19znf32s8s7qpkpfrck0suyym3m3wtrwpnldj76u0qwjtms3dcftsqs6r87', 'pol']
];
const Boards = () => {
const [addedBoards, setAddedBoards] = useState<string[][]>(JSON.parse(localStorage.getItem('addedBoards') as string) || []);
const [boardName, setBoardName] = useState('');
const [boardPubkey, setboardPubkey] = useState('')
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const newBoards = [...addedBoards, [boardName, boardPubkey]];
setAddedBoards(newBoards);
localStorage.setItem('addedBoards', JSON.stringify(newBoards));
};
const clearBoards = () => {
localStorage.setItem('addedBoards', JSON.stringify([]));
setAddedBoards([]);
};
return (
<div className="settings-page bg-black text-white p-8 flex flex-col h-full">
<h1 className="text-lg font-semibold mb-4">Boards</h1>
<div className="">
{/* Map over DefaultBoards and addedBoards and display them */}
<ul className='py-4'>
{DefaultBoards.map((board, index) => (
<li key={index}><a href={`/board/${board[1]}`} className='hover:underline'>/{board[0]}/</a></li>
))}
{addedBoards.map((board: string[], index: number) => (
<li key={index}><a href={`/board/${board[1]}`} className='hover:underline'>/{board[0]}/</a></li>
))}
</ul>
<form onSubmit={handleSubmit}>
<div className="flex flex-wrap -mx-2 my-4">
<div className="w-full md:w-1/3 px-2 mb-4 md:mb-0">
<label className="block text-xs mb-2" htmlFor="difficulty">
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
Add Board
</span>
</label>
<div className="flex">
<input
id="BoardName"
type="string"
placeholder={'Board Name'}
onChange={e => setBoardName(e.target.value)}
className="w-full px-3 py-2 border rounded-md bg-black"
/>
<input
id="BoardPubkey"
type="string"
placeholder={'Board Pubkey'}
onChange={e => setboardPubkey(e.target.value)}
className="w-full px-3 py-2 border rounded-md bg-black"
/>
</div>
</div>
</div>
<button
type="submit"
className="bg-black border text-white font-bold py-2 px-4 rounded">
Add Board
</button>
<button
type="button"
onClick={clearBoards}
className="bg-black border text-white font-bold py-2 px-4 rounded mx-4">
Clear
</button>
</form>
</div>
</div>
);
};
export default Boards;

View File

@ -16,13 +16,11 @@ import "./Form.css";
interface FormProps {
refEvent?: NostrEvent;
tagType?: 'Reply' | 'Quote' | '';
board?: string;
}
const NewNoteCard = ({
refEvent,
tagType,
board
tagType
}: FormProps) => {
const ref = useRef<HTMLDivElement | null>(null);
const [comment, setComment] = useState("");
@ -62,10 +60,6 @@ const NewNoteCard = ({
}
}
if (board) {
unsigned.tags.push(['d', nip19.decode(board).data as string]);
}
const handleDifficultyChange = (event: Event) => {
const customEvent = event as CustomEvent;
const { difficulty } = customEvent.detail;

View File

@ -3,7 +3,6 @@ import {
BellIcon,
ArchiveBoxIcon
} from "@heroicons/react/24/outline";
import { DefaultBoards } from "../Boards";
export default function Header() {
return (
@ -17,11 +16,6 @@ export default function Header() {
</span>
</div>
</a>
<div className="hidden md:block">
{DefaultBoards.map((board) => (
<a href={`/board/${board[1]}`} className='hover:underline text-neutral-600 text-xs pr-4'>/{board[2]}/</a>
))}
</div>
<div>
<a
href="/boards"
@ -49,11 +43,6 @@ export default function Header() {
</a>
</div>
</div>
<div className="block md:hidden flex justify-center ">
{DefaultBoards.map((board) => (
<a href={`/board/${board[1]}`} className='hover:underline text-neutral-600 text-xs pr-4'>/{board[2]}/</a>
))}
</div>
</header>
);
}

View File

@ -8,7 +8,7 @@ type TestResponse = {
};
const Settings = () => {
const [filterDifficulty, setFilterDifficulty] = useState(localStorage.getItem('filterDifficulty') || 20);
const [filterDifficulty, setFilterDifficulty] = useState(localStorage.getItem('filterDifficulty') || 21);
const [difficulty, setDifficulty] = useState(localStorage.getItem('difficulty') || 21);
const [age, setAge] = useState(localStorage.getItem('age') || 24);
const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);

View File

@ -262,98 +262,6 @@ export const subNotifications = (
});
};
/** subscribe to global feed */
export const subBoardFeed = (
board: string,
onEvent: SubCallback,
age: number
) => {
console.info('subscribe to board feed');
unsubAll();
const now = Math.floor(Date.now() * 0.001);
const pubkeys = new Set<string>();
const notes = new Set<string>();
const prefix = Math.floor(16 / 4); // 4 bits in each '0' character
sub({ // get past events
cb: (evt, relay) => {
pubkeys.add(evt.pubkey);
notes.add(evt.id);
onEvent(evt, relay);
},
filter: {
...(prefix && { ids: ['0'.repeat(prefix)] }),
"#d": [board],
kinds: [1, 6],
since: Math.floor((Date.now() * 0.001) - (age * 60 * 60)),
limit: 500,
},
unsub: true
});
sub({
cb: (evt, relay) => {
onEvent(evt, relay);
},
filter: {
authors: [board],
kinds: [1, 7],
limit: 25,
},
unsub: true,
});
setTimeout(() => {
// get profile info
sub({
cb: onEvent,
filter: {
authors: Array.from(pubkeys),
kinds: [0],
limit: pubkeys.size,
},
unsub: true,
});
pubkeys.clear();
sub({
cb: onEvent,
filter: {
'#e': Array.from(notes),
kinds: [1],
},
unsub: true,
});
notes.clear();
}, 2000);
// subscribe to future notes, reactions and profile updates
sub({
cb: (evt, relay) => {
onEvent(evt, relay);
if (
evt.kind !== 1
|| pubkeys.has(evt.pubkey)
) {
return;
}
subOnce({ // get profile data
relay,
cb: onEvent,
filter: {
authors: [evt.pubkey],
kinds: [0],
limit: 1,
}
});
},
filter: {
...(prefix && { ids: ['0'.repeat(prefix)] }),
kinds: [1],
since: now,
},
});
};
export const subProfile = (
pubkey: string,
onEvent: SubCallback,