From 30a32ca94f0122f56d12a5a8625b2cd8e1ba370b Mon Sep 17 00:00:00 2001 From: codytseng Date: Wed, 4 Jun 2025 09:17:00 +0800 Subject: [PATCH] feat: followed by --- src/components/NoteList/index.tsx | 2 +- src/i18n/locales/ar.ts | 3 +- src/i18n/locales/de.ts | 3 +- src/i18n/locales/en.ts | 3 +- src/i18n/locales/es.ts | 3 +- src/i18n/locales/fr.ts | 3 +- src/i18n/locales/it.ts | 3 +- src/i18n/locales/ja.ts | 3 +- src/i18n/locales/pl.ts | 3 +- src/i18n/locales/pt-BR.ts | 3 +- src/i18n/locales/pt-PT.ts | 3 +- src/i18n/locales/ru.ts | 3 +- src/i18n/locales/zh.ts | 3 +- .../secondary/ProfilePage/FollowedBy.tsx | 50 +++++++++++++++++++ src/pages/secondary/ProfilePage/index.tsx | 22 ++++---- 15 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 src/pages/secondary/ProfilePage/FollowedBy.tsx diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index e139e54..a258daf 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -229,7 +229,7 @@ export default function NoteList({ return () => { promise.then((closer) => closer()) } - }, [JSON.stringify(relayUrls), filterType, refreshCount]) + }, [JSON.stringify(relayUrls), filterType, refreshCount, JSON.stringify(filter)]) useEffect(() => { const options = { diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts index 52080a4..c124397 100644 --- a/src/i18n/locales/ar.ts +++ b/src/i18n/locales/ar.ts @@ -236,6 +236,7 @@ export default { 'View on njump.me': 'عرض على njump.me', 'Hide content from untrusted users': 'إخفاء المحتوى من المستخدمين غير الموثوقين', 'Only show content from your followed users and the users they follow': - 'فقط عرض المحتوى من المستخدمين الذين تتابعهم والمستخدمين الذين يتابعونهم' + 'فقط عرض المحتوى من المستخدمين الذين تتابعهم والمستخدمين الذين يتابعونهم', + 'Followed by': 'متابع من قبل' } } diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 9b1551b..c547d33 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -243,6 +243,7 @@ export default { 'Hide content from untrusted users': 'Inhalte von nicht vertrauenswürdigen Benutzern ausblenden', 'Only show content from your followed users and the users they follow': - 'Nur Inhalte von Benutzern anzeigen, denen du folgst und die sie folgen' + 'Nur Inhalte von Benutzern anzeigen, denen du folgst und die sie folgen', + 'Followed by': 'Gefolgt von' } } diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 7a64af2..499a8dc 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -236,6 +236,7 @@ export default { 'View on njump.me': 'View on njump.me', 'Hide content from untrusted users': 'Hide content from untrusted users', 'Only show content from your followed users and the users they follow': - 'Only show content from your followed users and the users they follow' + 'Only show content from your followed users and the users they follow', + 'Followed by': 'Followed by' } } diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index 83ed1db..429b5f4 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -241,6 +241,7 @@ export default { 'View on njump.me': 'Ver en njump.me', 'Hide content from untrusted users': 'Ocultar contenido de usuarios no confiables', 'Only show content from your followed users and the users they follow': - 'Solo mostrar contenido de tus usuarios seguidos y los usuarios que ellos siguen' + 'Solo mostrar contenido de tus usuarios seguidos y los usuarios que ellos siguen', + 'Followed by': 'Seguidos por' } } diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts index fd00374..7bdc715 100644 --- a/src/i18n/locales/fr.ts +++ b/src/i18n/locales/fr.ts @@ -241,6 +241,7 @@ export default { 'View on njump.me': 'Voir sur njump.me', 'Hide content from untrusted users': 'Hider le contenu des utilisateurs non fiables', 'Only show content from your followed users and the users they follow': - 'Afficher uniquement le contenu de vos utilisateurs suivis et des utilisateurs qu’ils suivent' + 'Afficher uniquement le contenu de vos utilisateurs suivis et des utilisateurs qu’ils suivent', + 'Followed by': 'Suivi par' } } diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts index 7a8c8be..642cbd4 100644 --- a/src/i18n/locales/it.ts +++ b/src/i18n/locales/it.ts @@ -240,6 +240,7 @@ export default { 'View on njump.me': 'Visualizza su njump.me', 'Hide content from untrusted users': 'Nascondi contenuti da utenti non fidati', 'Only show content from your followed users and the users they follow': - 'Mostra solo contenuti dai tuoi utenti seguiti e dagli utenti che seguono' + 'Mostra solo contenuti dai tuoi utenti seguiti e dagli utenti che seguono', + 'Followed by': 'Seguito da' } } diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts index 3f550e8..0e5a0cd 100644 --- a/src/i18n/locales/ja.ts +++ b/src/i18n/locales/ja.ts @@ -237,6 +237,7 @@ export default { 'View on njump.me': 'njump.meで表示', 'Hide content from untrusted users': '信頼できないユーザーのコンテンツを非表示', 'Only show content from your followed users and the users they follow': - 'フォローしているユーザーとそのユーザーがフォローしているユーザーのコンテンツのみを表示' + 'フォローしているユーザーとそのユーザーがフォローしているユーザーのコンテンツのみを表示', + 'Followed by': 'フォロワー' } } diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts index 016c583..088a0a3 100644 --- a/src/i18n/locales/pl.ts +++ b/src/i18n/locales/pl.ts @@ -239,6 +239,7 @@ export default { 'View on njump.me': 'Zobacz na njump.me', 'Hide content from untrusted users': 'Ukryj treści od nieznanych użytkowników', 'Only show content from your followed users and the users they follow': - 'Pokaż tylko treści od użytkowników, których obserwujesz i ich obserwowanych' + 'Pokaż tylko treści od użytkowników, których obserwujesz i ich obserwowanych', + 'Followed by': 'Obserwowany przez' } } diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts index b7a0164..df6481c 100644 --- a/src/i18n/locales/pt-BR.ts +++ b/src/i18n/locales/pt-BR.ts @@ -239,6 +239,7 @@ export default { 'View on njump.me': 'Ver em njump.me', 'Hide content from untrusted users': 'Ocultar conteúdo de usuários não confiáveis', 'Only show content from your followed users and the users they follow': - 'Mostrar apenas conteúdo dos usuários que você segue e dos usuários que eles seguem' + 'Mostrar apenas conteúdo dos usuários que você segue e dos usuários que eles seguem', + 'Followed by': 'Seguido por' } } diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts index 1ae93e9..50f7c1f 100644 --- a/src/i18n/locales/pt-PT.ts +++ b/src/i18n/locales/pt-PT.ts @@ -240,6 +240,7 @@ export default { 'View on njump.me': 'Ver em njump.me', 'Hide content from untrusted users': 'Esconder conteúdo de usuários não confiáveis', 'Only show content from your followed users and the users they follow': - 'Mostrar apenas conteúdo dos usuários que você segue e dos usuários que eles seguem' + 'Mostrar apenas conteúdo dos usuários que você segue e dos usuários que eles seguem', + 'Followed by': 'Seguido por' } } diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts index 370c111..3f46342 100644 --- a/src/i18n/locales/ru.ts +++ b/src/i18n/locales/ru.ts @@ -240,6 +240,7 @@ export default { 'View on njump.me': 'Посмотреть на njump.me', 'Hide content from untrusted users': 'Скрыть контент от недоверенных пользователей', 'Only show content from your followed users and the users they follow': - 'Показывать только контент от пользователей, на которых вы подписаны, и от пользователей, на которых они подписаны' + 'Показывать только контент от пользователей, на которых вы подписаны, и от пользователей, на которых они подписаны', + 'Followed by': 'Подписан на' } } diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts index 3cd2f7d..5e755a9 100644 --- a/src/i18n/locales/zh.ts +++ b/src/i18n/locales/zh.ts @@ -237,6 +237,7 @@ export default { 'View on njump.me': '在 njump.me 上查看', 'Hide content from untrusted users': '隐藏不受信任用户的内容', 'Only show content from your followed users and the users they follow': - '仅显示您关注的用户及其关注的用户的内容' + '仅显示您关注的用户及其关注的用户的内容', + 'Followed by': '关注者' } } diff --git a/src/pages/secondary/ProfilePage/FollowedBy.tsx b/src/pages/secondary/ProfilePage/FollowedBy.tsx new file mode 100644 index 0000000..4e1994d --- /dev/null +++ b/src/pages/secondary/ProfilePage/FollowedBy.tsx @@ -0,0 +1,50 @@ +import UserAvatar from '@/components/UserAvatar' +import { useNostr } from '@/providers/NostrProvider' +import { useScreenSize } from '@/providers/ScreenSizeProvider' +import client from '@/services/client.service' +import { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' + +export default function FollowedBy({ pubkey }: { pubkey: string }) { + const { t } = useTranslation() + const { isSmallScreen } = useScreenSize() + const [followedBy, setFollowedBy] = useState([]) + const { pubkey: accountPubkey } = useNostr() + + useEffect(() => { + if (!pubkey || !accountPubkey) return + + const init = async () => { + const followings = (await client.fetchFollowings(accountPubkey)).reverse() + const followingsOfFollowings = await Promise.all( + followings.map(async (following) => { + return client.fetchFollowings(following) + }) + ) + const _followedBy: string[] = [] + const limit = isSmallScreen ? 3 : 5 + for (const [index, following] of followings.entries()) { + if (following === pubkey) continue + if (followingsOfFollowings[index].includes(pubkey)) { + _followedBy.push(following) + } + if (_followedBy.length >= limit) { + break + } + } + setFollowedBy(_followedBy) + } + init() + }, [pubkey, accountPubkey]) + + if (followedBy.length === 0) return null + + return ( +
+
{t('Followed by')}
+ {followedBy.map((p) => ( + + ))} +
+ ) +} diff --git a/src/pages/secondary/ProfilePage/index.tsx b/src/pages/secondary/ProfilePage/index.tsx index 18079bd..a670d27 100644 --- a/src/pages/secondary/ProfilePage/index.tsx +++ b/src/pages/secondary/ProfilePage/index.tsx @@ -23,6 +23,7 @@ import { Link, Zap } from 'lucide-react' import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import NotFoundPage from '../NotFoundPage' +import FollowedBy from './FollowedBy' import Followings from './Followings' import Relays from './Relays' @@ -176,15 +177,18 @@ const ProfilePage = forwardRef(({ id, index }: { id?: string; index?: number }, )} -
- - - {isSelf && ( - - {mutePubkeys.length} -
{t('Muted')}
-
- )} +
+
+ + + {isSelf && ( + + {mutePubkeys.length} +
{t('Muted')}
+
+ )} +
+ {!isSelf && }