diff --git a/frontend/Components/MenuItems/index.tsx b/frontend/Components/MenuItems/index.tsx
index 0a5cf4b..a2f8e13 100644
--- a/frontend/Components/MenuItems/index.tsx
+++ b/frontend/Components/MenuItems/index.tsx
@@ -66,14 +66,14 @@ export const MenuItems: React.FC = () => {
{user?.name}
- {formatPubKey(nPub)}
+ {formatPubKey(user?.id ?? '')}
diff --git a/frontend/Components/NostrosAvatar/index.tsx b/frontend/Components/NostrosAvatar/index.tsx
index afe680f..5db6e5b 100644
--- a/frontend/Components/NostrosAvatar/index.tsx
+++ b/frontend/Components/NostrosAvatar/index.tsx
@@ -18,7 +18,7 @@ export const NostrosAvatar: React.FC = ({
lud06,
}) => {
const theme = useTheme()
- const displayName = name && name !== '' ? name : pubKey
+ const displayName = name && name !== '' ? name : pubKey ?? ''
const hasLud06 = lud06 && lud06 !== ''
const lud06IconSize = size / 2.85
const validImage: () => boolean = () => {
diff --git a/frontend/Components/NostrosNotification/index.tsx b/frontend/Components/NostrosNotification/index.tsx
deleted file mode 100644
index a977a33..0000000
--- a/frontend/Components/NostrosNotification/index.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react'
-import { StyleSheet } from 'react-native'
-import { Snackbar } from 'react-native-paper'
-
-interface NostrosNotificationProps {
- children: React.ReactNode
- showNotification: string | undefined
- setShowNotification: (showNotification: string | undefined) => void
-}
-
-export const NostrosNotification: React.FC = ({
- children,
- showNotification,
- setShowNotification,
-}) => {
- return (
- setShowNotification(undefined)}
- onDismiss={() => setShowNotification(undefined)}
- >
- {children}
-
- )
-}
-
-const styles = StyleSheet.create({
- snackbar: {
- margin: 16,
- bottom: 70,
- },
-})
-
-export default NostrosNotification
diff --git a/frontend/Components/ProfileCard/index.tsx b/frontend/Components/ProfileCard/index.tsx
index 2890b6c..3a98fa7 100644
--- a/frontend/Components/ProfileCard/index.tsx
+++ b/frontend/Components/ProfileCard/index.tsx
@@ -2,14 +2,13 @@ import { t } from 'i18next'
import { npubEncode } from 'nostr-tools/nip19'
import * as React from 'react'
import { Clipboard, StyleSheet, View } from 'react-native'
-import { Card, IconButton, Text } from 'react-native-paper'
+import { Card, IconButton, Snackbar, Text } from 'react-native-paper'
import { AppContext } from '../../Contexts/AppContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { UserContext } from '../../Contexts/UserContext'
import { getUser, updateUserContact, User } from '../../Functions/DatabaseFunctions/Users'
import { populatePets } from '../../Functions/RelayFunctions/Users'
import NostrosAvatar from '../NostrosAvatar'
-import NostrosNotification from '../NostrosNotification'
import LnPayment from '../LnPayment'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { navigate, push } from '../../lib/Navigation'
@@ -94,7 +93,7 @@ export const ProfileCard: React.FC = ({ userPubKey, bottomShee
- {`${user?.about?.slice(0, 75)}${
+ {`${user?.about ? user?.about?.slice(0, 75) : ''}${
user?.about && user?.about?.length > 75 ? ' ...' : ''
}`}
@@ -156,12 +155,15 @@ export const ProfileCard: React.FC = ({ userPubKey, bottomShee
{showNotification && (
- setShowNotification(undefined)}
+ onDismiss={() => setShowNotification(undefined)}
>
- {t(`profileCard.notifications.${showNotification}`)}
-
+ {t(`profileCard.notifications.${showNotification}`)}
+
)}
@@ -172,6 +174,10 @@ const styles = StyleSheet.create({
container: {
padding: 16,
},
+ snackbar: {
+ margin: 16,
+ width: '100%',
+ },
contacts: {
flexDirection: 'row',
alignItems: 'center',
diff --git a/frontend/Constants/Theme/theme-dark.json b/frontend/Constants/Theme/theme-dark.json
index 4de8300..ee31cc1 100644
--- a/frontend/Constants/Theme/theme-dark.json
+++ b/frontend/Constants/Theme/theme-dark.json
@@ -43,6 +43,5 @@
"success": "#369734",
"successContainer": "#369734",
"onSuccessContainer": "#96FA89"
-
}
}
diff --git a/frontend/Contexts/UserContext.tsx b/frontend/Contexts/UserContext.tsx
index e5f36d3..d701fc9 100644
--- a/frontend/Contexts/UserContext.tsx
+++ b/frontend/Contexts/UserContext.tsx
@@ -60,7 +60,13 @@ export const UserContextProvider = ({ children }: UserContextProviderProps): JSX
const reloadUser: () => void = () => {
if (database && publicKey) {
getUser(publicKey, database).then((result) => {
- if (result) setUser(result)
+ if (result) {
+ setUser(result)
+ } else {
+ setUser({
+ id: publicKey,
+ })
+ }
})
getContactsCount(database).then(setContantsCount)
getFollowersCount(database).then(setFollowersCount)
diff --git a/frontend/Locales/en.json b/frontend/Locales/en.json
index b488436..831e3aa 100644
--- a/frontend/Locales/en.json
+++ b/frontend/Locales/en.json
@@ -66,6 +66,11 @@
"generateInvoice": "Generate invoice",
"cancel": "Cancel"
},
+ "notificationsFeed": {
+ "emptyTitle": "You don't have notifications",
+ "emptyDescription": "Write a message to get replies and reactions.",
+ "emptyButton": "Write a message"
+ },
"profileCreatePage": {
"notifications": {
"copied": "Private key copied.\n\nSave this key on a safe place."
@@ -90,10 +95,17 @@
},
"contactsFeed": {
"notifications": {
+ "keyCopied": "Public key copied.",
"contactAdded": "Profile followed.",
"addContactError": "There was an error publishing your changes.",
"contactRemoved": "Profile unfollowed."
},
+ "emptyTitleFollowing": "You are not following no one",
+ "emptyDescriptionFollowing": "Follow other profiles to see content.",
+ "emptyButtonFollowing": "Paste public key",
+ "emptyTitleFollower": "You have no followers",
+ "emptyDescriptionFollower": "Share your public key so people can start following you.",
+ "emptyButtonFollower": "Copy public key",
"cancel": "Cancelar",
"addContact": "Añadir contacto",
"addContactDescription": "Pega la clave pública de quien desees añadir.",
@@ -108,6 +120,11 @@
"nostr": "nostr",
"nips": "NIPs"
},
+ "homeFeed": {
+ "emptyTitle": "You are not following no one",
+ "emptyDescription": "Follow other profiles to see content.",
+ "emptyButton": "Go to contacts"
+ },
"relaysPage": {
"labelAdd": "Dirección de relay",
"cancel": "Cancelar",
@@ -125,8 +142,8 @@
"nsecCopied": "Clave secreta copiada.",
"npubCopied": "Clave pública copiada.",
"profilePublished": "Perfil publicado.",
- "lud06Published": "LUD-06 publicado.",
- "nip05Published": "NIP-05 publicado.",
+ "lud06Published": "LUD-06 publicado.\n\n{{lud06}}",
+ "nip05Published": "NIP-05 publicado.\n\n{{nip05}}",
"picturePublished": "Picture publicado.",
"connectionError": "Error de conexión"
},
@@ -181,12 +198,15 @@
"copyNPub": "Copiar clave"
},
"conversationsFeed": {
- "openMessage": "Iniciar conversación",
- "openMessageLabel": "Clave pública",
- "openMessageDescription": "Pega una clave pública para iniciar una conversación.",
- "openMessageTitle": "Iniciar conversación con clave pública",
- "addPubKey": "Iniciar conversación con clave pública",
- "newMessageContact": "Iniciar conversación con contacto"
+ "openMessage": "Start conversation",
+ "openMessageLabel": "Public key",
+ "openMessageDescription": "Paste a public key to start a conversation.",
+ "openMessageTitle": "Start conversation with public key",
+ "addPubKey": "Start conversation with public key",
+ "newMessageContact": "Start conversation with contact",
+ "emptyTitle": "You don't have any message",
+ "emptyDescription": "Write direct messages to your contacts or others.",
+ "emptyButton": "Open a conversation"
}
}
}
diff --git a/frontend/Pages/ContactsFeed/index.tsx b/frontend/Pages/ContactsFeed/index.tsx
index 18d1060..cb49087 100644
--- a/frontend/Pages/ContactsFeed/index.tsx
+++ b/frontend/Pages/ContactsFeed/index.tsx
@@ -24,6 +24,7 @@ import {
AnimatedFAB,
Button,
Divider,
+ Snackbar,
Text,
TextInput,
TouchableRipple,
@@ -33,11 +34,11 @@ import { Tabs, TabScreen } from 'react-native-paper-tabs'
import NostrosAvatar from '../../Components/NostrosAvatar'
import { navigate } from '../../lib/Navigation'
import RBSheet from 'react-native-raw-bottom-sheet'
-import NostrosNotification from '../../Components/NostrosNotification'
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
export const ContactsFeed: React.FC = () => {
const { database } = useContext(AppContext)
- const { publicKey, setContantsCount, setFollowersCount } = React.useContext(UserContext)
+ const { publicKey, setContantsCount, setFollowersCount, nPub } = React.useContext(UserContext)
const { relayPool, lastEventId } = useContext(RelayPoolContext)
const theme = useTheme()
const bottomSheetAddContactRef = React.useRef(null)
@@ -192,28 +193,77 @@ export const ContactsFeed: React.FC = () => {
>
-
-
- 0 ? (
+
+
+
+
+
+ ) : (
+
+
+
+ {t('contactsFeed.emptyTitleFollowing')}
+
+
+ {t('contactsFeed.emptyDescriptionFollowing')}
+
+
-
+ )}
-
-
- 0 ? (
+
+
+
+
+
+ ) : (
+
+
+
+ {t('contactsFeed.emptyTitleFollower')}
+
+
+ {t('contactsFeed.emptyDescriptionFollower')}
+
+
-
+ )}
@@ -269,12 +319,15 @@ export const ContactsFeed: React.FC = () => {
{showNotification && (
- setShowNotification(undefined)}
+ onDismiss={() => setShowNotification(undefined)}
>
- {t(`contactsFeed.notifications.${showNotification}`)}
-
+ {t(`contactsFeed.notifications.${showNotification}`)}
+
)}
>
)
@@ -284,6 +337,10 @@ const styles = StyleSheet.create({
container: {
flex: 1,
},
+ snackbar: {
+ margin: 16,
+ marginBottom: 95,
+ },
contactRow: {
paddingLeft: 16,
paddingRight: 16,
@@ -306,6 +363,16 @@ const styles = StyleSheet.create({
right: 16,
position: 'absolute',
},
+ center: {
+ alignContent: 'center',
+ textAlign: 'center',
+ },
+ blank: {
+ justifyContent: 'space-between',
+ height: 232,
+ marginTop: 12,
+ padding: 16,
+ },
})
export default ContactsFeed
diff --git a/frontend/Pages/ConversationsFeed/index.tsx b/frontend/Pages/ConversationsFeed/index.tsx
index 0a46158..e9a6845 100644
--- a/frontend/Pages/ConversationsFeed/index.tsx
+++ b/frontend/Pages/ConversationsFeed/index.tsx
@@ -158,6 +158,7 @@ export const ConversationsFeed: React.FC = () => {
/>
),
onPress: async () => bottomSheetUserListRef.current?.open(),
+ disabled: users?.length === 0,
},
{
key: 2,
@@ -168,6 +169,7 @@ export const ConversationsFeed: React.FC = () => {
/>
),
onPress: async () => bottomSheetPubKeyRef.current?.open(),
+ disabled: false,
},
]
}, [])
@@ -199,14 +201,29 @@ export const ConversationsFeed: React.FC = () => {
)
return (
-
-
-
-
+
+ {directMessages.length > 0 ? (
+
+
+
+ ) : (
+
+
+
+ {t('conversationsFeed.emptyTitle')}
+
+
+ {t('conversationsFeed.emptyDescription')}
+
+
+
+ )}
{
title={item.title}
onPress={item.onPress}
left={item.left}
+ disabled={item.disabled}
/>
)
}}
@@ -290,6 +308,7 @@ export const ConversationsFeed: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1,
+ padding: 16,
},
contactRow: {
paddingLeft: 16,
@@ -317,6 +336,15 @@ const styles = StyleSheet.create({
right: 16,
position: 'absolute',
},
+ center: {
+ alignContent: 'center',
+ textAlign: 'center',
+ },
+ blank: {
+ justifyContent: 'space-between',
+ height: 200,
+ marginTop: 60,
+ },
})
export default ConversationsFeed
diff --git a/frontend/Pages/HomeFeed/index.tsx b/frontend/Pages/HomeFeed/index.tsx
index 04dbda0..20b2169 100644
--- a/frontend/Pages/HomeFeed/index.tsx
+++ b/frontend/Pages/HomeFeed/index.tsx
@@ -16,14 +16,20 @@ import { UserContext } from '../../Contexts/UserContext'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { EventKind } from '../../lib/nostr/Events'
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
-import { ActivityIndicator, AnimatedFAB } from 'react-native-paper'
+import { ActivityIndicator, AnimatedFAB, Button, Text } from 'react-native-paper'
import NoteCard from '../../Components/NoteCard'
import RBSheet from 'react-native-raw-bottom-sheet'
import ProfileCard from '../../Components/ProfileCard'
import { useTheme } from '@react-navigation/native'
import { navigate } from '../../lib/Navigation'
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
+import { t } from 'i18next'
-export const HomeFeed: React.FC = () => {
+interface HomeFeedProps {
+ jumpTo: (tabName: string) => void
+}
+
+export const HomeFeed: React.FC = ({ jumpTo }) => {
const theme = useTheme()
const { database } = useContext(AppContext)
const { publicKey } = useContext(UserContext)
@@ -139,8 +145,8 @@ export const HomeFeed: React.FC = () => {
}, [])
return (
- <>
- {notes && notes.length > 0 && (
+
+ {notes && notes.length > 0 ? (
{
{notes.map((note) => renderItem(note))}
{notes.length >= 10 && }
+ ) : (
+
+
+
+ {t('homeFeed.emptyTitle')}
+
+
+ {t('homeFeed.emptyDescription')}
+
+
+
)}
{
>
- >
+
)
}
@@ -184,6 +203,19 @@ const styles = StyleSheet.create({
right: 16,
position: 'absolute',
},
+ container: {
+ padding: 16,
+ flex: 1,
+ },
+ center: {
+ alignContent: 'center',
+ textAlign: 'center',
+ },
+ blank: {
+ justifyContent: 'space-between',
+ height: 200,
+ marginTop: 60,
+ },
})
export default HomeFeed
diff --git a/frontend/Pages/NotificationsFeed/index.tsx b/frontend/Pages/NotificationsFeed/index.tsx
index 2f97bf8..500add5 100644
--- a/frontend/Pages/NotificationsFeed/index.tsx
+++ b/frontend/Pages/NotificationsFeed/index.tsx
@@ -15,11 +15,15 @@ import { EventKind } from '../../lib/nostr/Events'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import { UserContext } from '../../Contexts/UserContext'
import RBSheet from 'react-native-raw-bottom-sheet'
-import { ActivityIndicator, useTheme } from 'react-native-paper'
+import { ActivityIndicator, Button, Text, useTheme } from 'react-native-paper'
import ProfileCard from '../../Components/ProfileCard'
+import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
+import { useTranslation } from 'react-i18next'
+import { navigate } from '../../lib/Navigation'
export const NotificationsFeed: React.FC = () => {
const theme = useTheme()
+ const { t } = useTranslation('common')
const { database } = useContext(AppContext)
const { publicKey } = useContext(UserContext)
const initialPageSize = 10
@@ -134,18 +138,30 @@ export const NotificationsFeed: React.FC = () => {
}, [])
return (
- <>
- {notes && notes.length > 0 && (
+
+ {notes && notes.length > 0 ? (
}
- style={styles.list}
>
{notes.map((note) => renderItem(note))}
{notes.length >= 10 && }
+ ) : (
+
+
+
+ {t('notificationsFeed.emptyTitle')}
+
+
+ {t('notificationsFeed.emptyDescription')}
+
+
+
)}
{
>
- >
+
)
}
const styles = StyleSheet.create({
- list: {
+ container: {
+ flex: 1,
padding: 16,
},
noteCard: {
marginBottom: 16,
},
+ center: {
+ alignContent: 'center',
+ textAlign: 'center',
+ },
+ blank: {
+ justifyContent: 'space-between',
+ height: 200,
+ marginTop: 60,
+ },
})
export default NotificationsFeed
diff --git a/frontend/Pages/ProfileConfigPage/index.tsx b/frontend/Pages/ProfileConfigPage/index.tsx
index 17bd116..4be4e37 100644
--- a/frontend/Pages/ProfileConfigPage/index.tsx
+++ b/frontend/Pages/ProfileConfigPage/index.tsx
@@ -15,10 +15,10 @@ import {
Text,
TouchableRipple,
TextInput,
+ Snackbar,
} from 'react-native-paper'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import RBSheet from 'react-native-raw-bottom-sheet'
-import NostrosNotification from '../../Components/NostrosNotification'
import NostrosAvatar from '../../Components/NostrosAvatar'
export const ProfileConfigPage: React.FC = () => {
@@ -478,14 +478,15 @@ export const ProfileConfigPage: React.FC = () => {
{showNotification && (
- setShowNotification(undefined)}
+ onDismiss={() => setShowNotification(undefined)}
>
- {t(`profileConfigPage.notifications.${showNotification}`)}
- {showNotification === 'nip05Published' && {nip05}}
- {showNotification === 'lud06Published' && {lnurl}}
-
+ {t(`profileConfigPage.notifications.${showNotification}`, { nip05, lnurl })}
+
)}
)
diff --git a/frontend/Pages/ProfileCreatePage/index.tsx b/frontend/Pages/ProfileCreatePage/index.tsx
index ecd3785..be092a0 100644
--- a/frontend/Pages/ProfileCreatePage/index.tsx
+++ b/frontend/Pages/ProfileCreatePage/index.tsx
@@ -65,7 +65,12 @@ export const ProfileCreatePage: React.FC = ({ navigation
{t('profileCreatePage.warningDescription')}
-
@@ -97,7 +102,7 @@ const styles = StyleSheet.create({
},
snackbar: {
margin: 16,
- width: '100%'
+ width: '100%',
},
warning: {
borderRadius: 4,
diff --git a/frontend/Pages/ProfilePage/index.tsx b/frontend/Pages/ProfilePage/index.tsx
index 1242186..0f4a39b 100644
--- a/frontend/Pages/ProfilePage/index.tsx
+++ b/frontend/Pages/ProfilePage/index.tsx
@@ -8,7 +8,14 @@ import {
StyleSheet,
View,
} from 'react-native'
-import { Surface, Text, IconButton, ActivityIndicator, useTheme } from 'react-native-paper'
+import {
+ Surface,
+ Text,
+ IconButton,
+ ActivityIndicator,
+ useTheme,
+ Snackbar,
+} from 'react-native-paper'
import NostrosAvatar from '../../Components/NostrosAvatar'
import { AppContext } from '../../Contexts/AppContext'
import { UserContext } from '../../Contexts/UserContext'
@@ -16,9 +23,8 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { getNotes, Note } from '../../Functions/DatabaseFunctions/Notes'
import { getUser, updateUserContact, User } from '../../Functions/DatabaseFunctions/Users'
import { EventKind } from '../../lib/nostr/Events'
-import { populatePets } from '../../Functions/RelayFunctions/Users'
+import { populatePets, username } from '../../Functions/RelayFunctions/Users'
import { useTranslation } from 'react-i18next'
-import NostrosNotification from '../../Components/NostrosNotification'
import { npubEncode } from 'nostr-tools/nip19'
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
import NoteCard from '../../Components/NoteCard'
@@ -86,6 +92,10 @@ export const ProfilePage: React.FC = ({ route }) => {
if (result) {
setUser(result)
setIsContact(result?.contact)
+ } else if (route.params.pubKey === publicKey) {
+ setUser({
+ id: publicKey,
+ })
}
})
}
@@ -97,12 +107,14 @@ export const ProfilePage: React.FC = ({ route }) => {
(results) => {
setNotes(results)
setRefreshing(false)
- relayPool?.subscribe('answers-profile', [
- {
- kinds: [EventKind.reaction, EventKind.textNote, EventKind.recommendServer],
- '#e': results.map((note) => note.id ?? ''),
- },
- ])
+ if (results.length > 0) {
+ relayPool?.subscribe('answers-profile', [
+ {
+ kinds: [EventKind.reaction, EventKind.textNote, EventKind.recommendServer],
+ '#e': results.map((note) => note.id ?? ''),
+ },
+ ])
+ }
},
)
}
@@ -189,7 +201,7 @@ export const ProfilePage: React.FC = ({ route }) => {
- {user?.name}
+ {user && username(user)}
{/* */}
{user?.nip05}
@@ -265,12 +277,15 @@ export const ProfilePage: React.FC = ({ route }) => {
)}
{showNotification && (
- setShowNotification(undefined)}
+ onDismiss={() => setShowNotification(undefined)}
>
- {t(`profilePage.${showNotification}`)}
-
+ {t(`profilePage.${showNotification}`)}
+
)}
{
const defaultRelayInput = React.useMemo(() => 'wss://', [])
@@ -111,12 +111,15 @@ export const RelaysPage: React.FC = () => {
extended={false}
/>
{showNotification && (
- setShowNotification(undefined)}
+ onDismiss={() => setShowNotification(undefined)}
>
{t(`relaysPage.notifications.${showNotification}`)}
-
+
)}