improve follow/unfollow, support petname

This commit is contained in:
reya 2023-10-26 13:29:13 +07:00
parent 37ed0f4892
commit 6fac37a0ca
5 changed files with 137 additions and 70 deletions

View File

@ -1,14 +1,16 @@
import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import * as Dialog from '@radix-ui/react-dialog';
import { memo, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { toast } from 'sonner';
import { useNDK } from '@libs/ndk/provider';
import { useStorage } from '@libs/storage/provider';
import { NIP05 } from '@shared/nip05';
import { TextNote } from '@shared/notes';
import { User } from '@shared/user';
import { useNostr } from '@utils/hooks/useNostr';
import { useProfile } from '@utils/hooks/useProfile';
import { displayNpub } from '@utils/shortenKey';
@ -19,27 +21,48 @@ export const UserWithDrawer = memo(function UserWithDrawer({
}: {
pubkey: string;
}) {
const { addContact, removeContact } = useNostr();
const { db } = useStorage();
const { ndk } = useNDK();
const { status, user } = useProfile(pubkey);
const [followed, setFollowed] = useState(false);
const followUser = (pubkey: string) => {
const follow = async (pubkey: string) => {
try {
addContact(pubkey);
// update state
setFollowed(true);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
} else {
toast('You already follow this user');
}
} catch (error) {
console.log(error);
}
};
const unfollowUser = (pubkey: string) => {
const unfollow = async (pubkey: string) => {
try {
removeContact(pubkey);
// update state
setFollowed(false);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
contacts.delete(new NDKUser({ hexpubkey: pubkey }));
let list: string[][];
contacts.forEach((el) =>
list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
);
const event = new NDKEvent(ndk);
event.content = '';
event.kind = NDKKind.Contacts;
event.tags = list;
const publishedRelays = await event.publish();
if (publishedRelays) {
setFollowed(false);
}
} catch (error) {
console.log(error);
}
@ -100,7 +123,7 @@ export const UserWithDrawer = memo(function UserWithDrawer({
{followed ? (
<button
type="button"
onClick={() => unfollowUser(pubkey)}
onClick={() => unfollow(pubkey)}
className="inline-flex h-9 w-36 items-center justify-center rounded-lg bg-neutral-300 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-700"
>
Unfollow
@ -108,7 +131,7 @@ export const UserWithDrawer = memo(function UserWithDrawer({
) : (
<button
type="button"
onClick={() => followUser(pubkey)}
onClick={() => follow(pubkey)}
className="inline-flex h-9 w-36 items-center justify-center rounded-lg bg-neutral-300 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-700"
>
Follow

View File

@ -1,40 +1,63 @@
import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { toast } from 'sonner';
import { EditProfileModal } from '@app/users/components/modal';
import { UserStats } from '@app/users/components/stats';
import { useNDK } from '@libs/ndk/provider';
import { useStorage } from '@libs/storage/provider';
import { Image } from '@shared/image';
import { NIP05 } from '@shared/nip05';
import { useNostr } from '@utils/hooks/useNostr';
import { useProfile } from '@utils/hooks/useProfile';
import { displayNpub } from '@utils/shortenKey';
export function UserProfile({ pubkey }: { pubkey: string }) {
const { db } = useStorage();
const { ndk } = useNDK();
const { user } = useProfile(pubkey);
const { addContact, removeContact } = useNostr();
const [followed, setFollowed] = useState(false);
const followUser = (pubkey: string) => {
const follow = async (pubkey: string) => {
try {
addContact(pubkey);
// update state
setFollowed(true);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
} else {
toast('You already follow this user');
}
} catch (error) {
console.log(error);
}
};
const unfollowUser = (pubkey: string) => {
const unfollow = async (pubkey: string) => {
try {
removeContact(pubkey);
// update state
setFollowed(false);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
contacts.delete(new NDKUser({ hexpubkey: pubkey }));
let list: string[][];
contacts.forEach((el) =>
list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
);
const event = new NDKEvent(ndk);
event.content = '';
event.kind = NDKKind.Contacts;
event.tags = list;
const publishedRelays = await event.publish();
if (publishedRelays) {
setFollowed(false);
}
} catch (error) {
console.log(error);
}
@ -100,7 +123,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
{followed ? (
<button
type="button"
onClick={() => unfollowUser(pubkey)}
onClick={() => unfollow(pubkey)}
className="inline-flex h-10 w-36 items-center justify-center rounded-md bg-neutral-200 text-sm font-medium text-neutral-900 backdrop-blur-xl hover:bg-blue-600 hover:text-neutral-100 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-blue-600 dark:hover:text-neutral-100"
>
Unfollow
@ -108,7 +131,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
) : (
<button
type="button"
onClick={() => followUser(pubkey)}
onClick={() => follow(pubkey)}
className="inline-flex h-10 w-36 items-center justify-center rounded-md bg-neutral-200 text-sm font-medium text-neutral-900 backdrop-blur-xl hover:bg-blue-600 hover:text-neutral-100 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-blue-600 dark:hover:text-neutral-100"
>
Follow

View File

@ -1,40 +1,61 @@
import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { toast } from 'sonner';
import { UserStats } from '@app/users/components/stats';
import { useNDK } from '@libs/ndk/provider';
import { useStorage } from '@libs/storage/provider';
import { NIP05 } from '@shared/nip05';
import { useNostr } from '@utils/hooks/useNostr';
import { useProfile } from '@utils/hooks/useProfile';
import { displayNpub } from '@utils/shortenKey';
export function UserProfile({ pubkey }: { pubkey: string }) {
const { db } = useStorage();
const { ndk } = useNDK();
const { user } = useProfile(pubkey);
const { addContact, removeContact } = useNostr();
const [followed, setFollowed] = useState(false);
const followUser = (pubkey: string) => {
const follow = async (pubkey: string) => {
try {
addContact(pubkey);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
// update state
setFollowed(true);
if (add) {
setFollowed(true);
} else {
toast('You already follow this user');
}
} catch (error) {
console.log(error);
}
};
const unfollowUser = (pubkey: string) => {
const unfollow = async (pubkey: string) => {
try {
removeContact(pubkey);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
contacts.delete(new NDKUser({ hexpubkey: pubkey }));
// update state
setFollowed(false);
let list: string[][];
contacts.forEach((el) =>
list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
);
const event = new NDKEvent(ndk);
event.content = '';
event.kind = NDKKind.Contacts;
event.tags = list;
const publishedRelays = await event.publish();
if (publishedRelays) {
setFollowed(false);
}
} catch (error) {
console.log(error);
}
@ -61,7 +82,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
{followed ? (
<button
type="button"
onClick={() => unfollowUser(pubkey)}
onClick={() => unfollow(pubkey)}
className="inline-flex h-9 w-28 items-center justify-center rounded-lg bg-neutral-200 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-800"
>
Unfollow
@ -69,7 +90,7 @@ export function UserProfile({ pubkey }: { pubkey: string }) {
) : (
<button
type="button"
onClick={() => followUser(pubkey)}
onClick={() => follow(pubkey)}
className="inline-flex h-9 w-28 items-center justify-center rounded-lg bg-neutral-200 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-800"
>
Follow

View File

@ -1,12 +1,13 @@
import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import { useStorage } from '@libs/storage/provider';
import { FollowIcon, UnfollowIcon } from '@shared/icons';
import { Image } from '@shared/image';
import { useNostr } from '@utils/hooks/useNostr';
import { compactNumber } from '@utils/number';
import { shortenKey } from '@utils/shortenKey';
@ -17,7 +18,7 @@ export interface Profile {
export function NostrBandUserProfile({ data }: { data: Profile }) {
const { db } = useStorage();
const { addContact, removeContact } = useNostr();
const { ndk } = useStorage();
const { status, data: userStats } = useQuery(
['user-stats', data.pubkey],
async () => {
@ -37,21 +38,42 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
const [followed, setFollowed] = useState(false);
const followUser = (pubkey: string) => {
const follow = async (pubkey: string) => {
try {
addContact(pubkey);
// update state
setFollowed(true);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
const add = await user.follow(new NDKUser({ hexpubkey: pubkey }), contacts);
if (add) {
setFollowed(true);
} else {
toast('You already follow this user');
}
} catch (error) {
console.log(error);
}
};
const unfollowUser = (pubkey: string) => {
const unfollow = async (pubkey: string) => {
try {
removeContact(pubkey);
// update state
setFollowed(false);
const user = ndk.getUser({ hexpubkey: db.account.pubkey });
const contacts = await user.follows();
contacts.delete(new NDKUser({ hexpubkey: pubkey }));
let list: string[][];
contacts.forEach((el) =>
list.push(['p', el.pubkey, el.relayUrls?.[0] || '', el.profile?.name || ''])
);
const event = new NDKEvent(ndk);
event.content = '';
event.kind = NDKKind.Contacts;
event.tags = list;
const publishedRelays = await event.publish();
if (publishedRelays) {
setFollowed(false);
}
} catch (error) {
console.log(error);
}
@ -93,7 +115,7 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
{followed ? (
<button
type="button"
onClick={() => unfollowUser(data.pubkey)}
onClick={() => unfollow(data.pubkey)}
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-neutral-200 text-neutral-900 backdrop-blur-xl hover:bg-blue-600 hover:text-white dark:bg-neutral-800 dark:text-neutral-100 dark:hover:text-white"
>
<UnfollowIcon className="h-4 w-4" />
@ -101,7 +123,7 @@ export function NostrBandUserProfile({ data }: { data: Profile }) {
) : (
<button
type="button"
onClick={() => followUser(data.pubkey)}
onClick={() => follow(data.pubkey)}
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-neutral-200 text-neutral-900 backdrop-blur-xl hover:bg-blue-600 hover:text-white dark:bg-neutral-800 dark:text-neutral-100 dark:hover:text-white"
>
<FollowIcon className="h-4 w-4" />

View File

@ -46,26 +46,6 @@ export function useNostr() {
}
};
const addContact = async (pubkey: string) => {
const list = new Set(db.account.follows);
list.add(pubkey);
const tags = [];
list.forEach((item) => {
tags.push(['p', item]);
});
};
const removeContact = async (pubkey: string) => {
const list = new Set(db.account.follows);
list.delete(pubkey);
const tags = [];
list.forEach((item) => {
tags.push(['p', item]);
});
};
const getAllActivities = async (limit?: number) => {
try {
const events = await ndk.fetchEvents({
@ -261,8 +241,6 @@ export function useNostr() {
return {
sub,
addContact,
removeContact,
getAllNIP04Chats,
getAllEventsSinceLastLogin,
getContactsByPubkey,