feat: import twitter follows

This commit is contained in:
Kieran 2023-01-23 10:32:43 +00:00
parent 7835ad8562
commit c3853066be
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
4 changed files with 68 additions and 7 deletions

View File

@ -20,7 +20,7 @@ export default function AsyncButton(props: any) {
}
return (
<div {...props} className={`btn ${props.className}${loading ? "disabled" : ""}`} onClick={(e) => handle(e)}>
<div {...props} className={`btn ${props.className}${loading ? " disabled" : ""}`} onClick={(e) => handle(e)}>
{props.children}
</div>
)

View File

@ -16,7 +16,7 @@ export default function FollowListBase({ pubkeys, title }: FollowListBaseProps)
return (
<>
<div className="flex">
<div className="flex mt10">
<div className="f-grow">{title}</div>
<div className="btn" onClick={() => followAll()}>Follow All</div>
</div>

View File

@ -1,18 +1,75 @@
import { RecommendedFollows } from "Const";
import AsyncButton from "Element/AsyncButton";
import FollowListBase from "Element/FollowListBase";
import ProfilePreview from "Element/ProfilePreview";
import { HexKey } from "Nostr";
import { useMemo, useState } from "react";
import { useSelector } from "react-redux";
import { RootState } from "State/Store";
import { bech32ToHex } from "Util";
const TwitterFollowsApi = "https://api.snort.social/api/v1/twitter/follows-for-nostr";
export default function NewUserPage() {
const [twitterUsername, setTwitterUsername] = useState<string>("");
const [follows, setFollows] = useState<string[]>([]);
const currentFollows = useSelector<RootState, HexKey[]>(s => s.login.follows);
const [error, setError] = useState<string>("");
const sortedReccomends = useMemo(() => {
return RecommendedFollows
.sort(a => Math.random() >= 0.5 ? -1 : 1);
}, []);
const sortedTwitterFollows = useMemo(() => {
return follows.map(a => bech32ToHex(a))
.sort((a, b) => currentFollows.includes(a) ? 1 : -1);
}, [follows]);
async function loadFollows() {
setFollows([]);
setError("");
try {
let rsp = await fetch(`${TwitterFollowsApi}?username=${twitterUsername}`);
if (rsp.ok) {
setFollows(await rsp.json());
} else {
setError("Failed to load follows, is your profile public?");
}
} catch (e) {
console.warn(e);
setError("Failed to load follows, is your profile public?");
}
}
function followSomebody() {
return (
<>
<h2>Follow some popular accounts</h2>
<h4>Here are some suggestions:</h4>
{RecommendedFollows
.sort(a => Math.random() >= 0.5 ? -1 : 1)
.map(a => <ProfilePreview key={a} pubkey={a.toLowerCase()} />)}
{sortedReccomends.map(a => <ProfilePreview key={a} pubkey={a.toLowerCase()} />)}
</>
)
}
return followSomebody()
function importTwitterFollows() {
return (
<>
<h2>Import twitter follows</h2>
<p>Find your twitter follows on nostr (Data provided by <a href="https://nostr.directory" target="_blank" rel="noreferrer">nostr.directory</a>)</p>
<div className="flex">
<input type="text" placeholder="Twitter username.." className="f-grow mr10" value={twitterUsername} onChange={e => setTwitterUsername(e.target.value)} />
<AsyncButton onClick={loadFollows}>Check</AsyncButton>
</div>
{error.length > 0 && <b className="error">{error}</b>}
{sortedTwitterFollows.length > 0 && (<FollowListBase pubkeys={sortedTwitterFollows} />)}
</>
)
}
return (
<>
{importTwitterFollows()}
{followSomebody()}
</>
);
}

View File

@ -312,6 +312,10 @@ body.scroll-lock {
margin-right: 5px;
}
.mt10 {
margin-top: 10px;
}
.ml5 {
margin-left: 5px;
}