refactor: include relays in kind3
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Kieran 2024-01-30 22:38:23 +00:00
parent ad8d0af976
commit 07510d92ca
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
6 changed files with 63 additions and 42 deletions

View File

@ -2,7 +2,7 @@ import { HexKey } from "@snort/system";
import { FormattedMessage } from "react-intl";
import AsyncButton from "@/Components/Button/AsyncButton";
import useEventPublisher from "@/Hooks/useEventPublisher";
import useFollowsControls from "@/Hooks/useFollowControls";
import useLogin from "@/Hooks/useLogin";
import { parseId } from "@/Utils";
@ -14,32 +14,18 @@ export interface FollowButtonProps {
}
export default function FollowButton(props: FollowButtonProps) {
const pubkey = parseId(props.pubkey);
const { publisher, system } = useEventPublisher();
const { follows, readonly } = useLogin(s => ({ follows: s.follows, readonly: s.readonly }));
const isFollowing = follows.item.includes(pubkey);
const readonly = useLogin(s => s.readonly);
const control = useFollowsControls();
const isFollowing = control.isFollowing(pubkey);
const baseClassname = props.className ? `${props.className} ` : "";
async function follow(pubkey: HexKey) {
if (publisher) {
const ev = await publisher.contactList([pubkey, ...follows.item].map(a => ["p", a]));
system.BroadcastEvent(ev);
}
}
async function unfollow(pubkey: HexKey) {
if (publisher) {
const ev = await publisher.contactList(follows.item.filter(a => a !== pubkey).map(a => ["p", a]));
system.BroadcastEvent(ev);
}
}
return (
<AsyncButton
className={isFollowing ? `${baseClassname} secondary` : `${baseClassname} primary`}
disabled={readonly}
onClick={async e => {
e.stopPropagation();
await (isFollowing ? unfollow(pubkey) : follow(pubkey));
await (isFollowing ? control.removeFollow([pubkey]) : control.addFollow([pubkey]));
}}>
{isFollowing ? <FormattedMessage {...messages.Unfollow} /> : <FormattedMessage {...messages.Follow} />}
</AsyncButton>

View File

@ -1,12 +1,10 @@
import { dedupe } from "@snort/shared";
import { HexKey } from "@snort/system";
import { ReactNode, useMemo } from "react";
import { FormattedMessage } from "react-intl";
import ProfilePreview from "@/Components/User/ProfilePreview";
import useEventPublisher from "@/Hooks/useEventPublisher";
import useFollowsControls from "@/Hooks/useFollowControls";
import useLogin from "@/Hooks/useLogin";
import { setFollows } from "@/Utils/Login";
import AsyncButton from "../Button/AsyncButton";
import messages from "../messages";
@ -30,19 +28,13 @@ export default function FollowListBase({
actions,
profileActions,
}: FollowListBaseProps) {
const { publisher, system } = useEventPublisher();
const { id, follows } = useLogin(s => ({ id: s.id, follows: s.follows }));
const control = useFollowsControls();
const login = useLogin();
const profilePreviewOptions = useMemo(() => ({ about: showAbout, profileCards: true }), [showAbout]);
async function followAll() {
if (publisher) {
const newFollows = dedupe([...pubkeys, ...follows.item]);
const ev = await publisher.contactList(newFollows.map(a => ["p", a]));
setFollows(id, newFollows, ev.created_at);
await system.BroadcastEvent(ev);
}
await control.addFollow(pubkeys);
}
return (

View File

@ -0,0 +1,42 @@
import { dedupe } from "@snort/shared";
import { useMemo } from "react";
import useEventPublisher from "./useEventPublisher";
import useLogin from "./useLogin";
/**
* Simple hook for adding / removing follows
*/
export default function useFollowsControls() {
const { publisher, system } = useEventPublisher();
const { follows, relays } = useLogin(s => ({ follows: s.follows.item, readonly: s.readonly, relays: s.relays.item }));
return useMemo(() => {
const publishList = async (newList: Array<string>) => {
if (publisher) {
const ev = await publisher.contactList(
newList.map(a => ["p", a]),
relays,
);
system.BroadcastEvent(ev);
}
};
return {
isFollowing: (pk: string) => {
return follows.includes(pk);
},
addFollow: async (pk: Array<string>) => {
const newList = dedupe([...follows, ...pk]);
await publishList(newList);
},
removeFollow: async (pk: Array<string>) => {
const newList = follows.filter(a => !pk.includes(a));
await publishList(newList);
},
setFollows: async (pk: Array<string>) => {
await publishList(dedupe(pk));
},
};
}, [follows, relays, publisher, system]);
}

View File

@ -6,9 +6,9 @@ import { FormattedMessage, FormattedNumber } from "react-intl";
import AsyncButton from "@/Components/Button/AsyncButton";
import ProfileImage from "@/Components/User/ProfileImage";
import useEventPublisher from "@/Hooks/useEventPublisher";
import useFollowsControls from "@/Hooks/useFollowControls";
import useLogin from "@/Hooks/useLogin";
import { Day } from "@/Utils/Const";
import { setFollows } from "@/Utils/Login";
import { FollowsRelayHealth } from "./follows-relay-health";
@ -18,13 +18,14 @@ const enum PruneStage {
}
export function PruneFollowList() {
const { id, follows } = useLogin(s => ({ id: s.id, follows: s.follows }));
const { publisher, system } = useEventPublisher();
const { follows } = useLogin(s => ({ id: s.id, follows: s.follows }));
const { system } = useEventPublisher();
const uniqueFollows = dedupe(follows.item);
const [status, setStatus] = useState<PruneStage>();
const [progress, setProgress] = useState(0);
const [lastPost, setLastPosts] = useState<Record<string, number>>();
const [unfollow, setUnfollow] = useState<Array<string>>([]);
const followControls = useFollowsControls();
async function fetchLastPosts() {
setStatus(PruneStage.FetchLastPostTimestamp);
@ -74,12 +75,7 @@ export function PruneFollowList() {
}, [uniqueFollows, unfollow]);
async function publishFollowList() {
const newFollows = newFollowList.map(a => ["p", a]) as Array<[string, string]>;
if (publisher) {
const ev = await publisher.contactList(newFollows);
await system.BroadcastEvent(ev);
setFollows(id, newFollowList, ev.created_at * 1000);
}
await followControls.setFollows(newFollowList);
}
function getStatus() {

View File

@ -122,8 +122,10 @@ export async function generateNewLogin(
const publisher = EventPublisher.privateKey(privateKey);
// Create new contact list following self and site account
const contactList = [publicKey, ...CONFIG.signUp.defaultFollows.map(a => bech32ToHex(a))].map(a => ["p", a]);
const ev = await publisher.contactList(contactList);
const contactList = [publicKey, ...CONFIG.signUp.defaultFollows.map(a => bech32ToHex(a))].map(a => ["p", a]) as Array<
[string, string]
>;
const ev = await publisher.contactList(contactList, newRelays);
system.BroadcastEvent(ev);
// Create relay metadata event

View File

@ -257,9 +257,12 @@ export class EventPublisher {
return await this.#sign(eb);
}
async contactList(tags: Array<[string, string]>) {
async contactList(tags: Array<[string, string]>, relays?: Record<string, RelaySettings>) {
const eb = this.#eb(EventKind.ContactList);
tags.forEach(a => eb.tag(a));
if (relays) {
eb.content(JSON.stringify(relays));
}
return await this.#sign(eb);
}