recover floating button

This commit is contained in:
KoalaSat 2022-10-31 02:23:27 +01:00
parent 0466e45da5
commit 0a77c91321
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
37 changed files with 266 additions and 275 deletions

View File

@ -4,7 +4,7 @@ module.exports = {
'eslint:recommended',
'plugin:react/recommended',
'standard-with-typescript',
'prettier'
'prettier',
],
parserOptions: {
ecmaVersion: 8,
@ -34,4 +34,4 @@ module.exports = {
version: 'detect',
},
},
};
}

View File

@ -1,5 +1,5 @@
{
"semi": true,
"semi": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,

View File

@ -4,4 +4,4 @@ module.exports = {
singleQuote: true,
trailingComma: 'all',
arrowParens: 'avoid',
};
}

View File

@ -1,4 +1,4 @@
{
"name": "Nostros",
"displayName": "Nostros"
}
}

View File

@ -1,3 +1,3 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
}

View File

@ -1,10 +1,4 @@
import {
Button,
Layout,
TopNavigation,
TopNavigationAction,
useTheme
} from '@ui-kitten/components'
import { Button, Layout, TopNavigation, TopNavigationAction, useTheme } from '@ui-kitten/components'
import React, { useContext, useEffect } from 'react'
import { StyleSheet } from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
@ -52,16 +46,16 @@ export const ConfigPage: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1
flex: 1,
},
actionContainer: {
marginTop: 30,
paddingLeft: 32,
paddingRight: 32
paddingRight: 32,
},
button: {
marginTop: 30
}
marginTop: 30,
},
})
return (

View File

@ -1,7 +1,6 @@
import { Button, Card, Input, Layout, Modal, useTheme } from '@ui-kitten/components'
import React, { useCallback, useContext, useEffect, useState } from 'react'
import { RefreshControl, ScrollView, StyleSheet } from 'react-native'
import ActionButton from 'react-native-action-button'
import { RefreshControl, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { Event, EventKind } from '../../lib/nostr/Events'
@ -10,7 +9,7 @@ import {
addContact,
getUsers,
insertUserContact,
User
User,
} from '../../Functions/DatabaseFunctions/Users'
import UserCard from '../UserCard'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
@ -48,7 +47,7 @@ export const ContactsPage: React.FC = () => {
insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''))
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta],
authors: event.tags.map((tag) => tagToUser(tag).id)
authors: event.tags.map((tag) => tagToUser(tag).id),
})
relayPool?.removeOn('event', 'contacts')
}
@ -56,7 +55,7 @@ export const ContactsPage: React.FC = () => {
if (publicKey) {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.petNames],
authors: [publicKey]
authors: [publicKey],
})
}
resolve()
@ -80,29 +79,29 @@ export const ContactsPage: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1
flex: 1,
},
actionContainer: {
marginTop: 30,
marginBottom: 30,
paddingLeft: 12,
paddingRight: 12
paddingRight: 12,
},
button: {
marginTop: 30
marginTop: 30,
},
icon: {
width: 32,
height: 32
height: 32,
},
modal: {
paddingLeft: 32,
paddingRight: 32,
width: '100%'
width: '100%',
},
backdrop: {
backgroundColor: 'rgba(0, 0, 0, 0.5)'
}
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
})
return (
@ -138,19 +137,24 @@ export const ContactsPage: React.FC = () => {
</Layout>
</Card>
</Modal>
{/* <ActionButton
buttonColor={theme['color-primary-400']}
useNativeFeedback={true}
fixNativeFeedbackRadius={true}
<TouchableOpacity
style={{
borderWidth: 1,
borderColor: 'rgba(0,0,0,0.2)',
alignItems: 'center',
justifyContent: 'center',
width: 65,
position: 'absolute',
bottom: 20,
right: 20,
height: 65,
backgroundColor: theme['color-warning-500'],
borderRadius: 100,
}}
onPress={() => setShowAddContant(true)}
>
<ActionButton.Item
buttonColor={theme['color-warning-500']}
title={t('contactsPage.add')}
onPress={() => setShowAddContant(true)}
>
<Icon name='user-plus' size={30} color={theme['text-basic-color']} solid />
</ActionButton.Item>
</ActionButton> */}
<Icon name='user-plus' size={30} color={theme['text-basic-color']} solid />
</TouchableOpacity>
</>
)
}

View File

@ -1,11 +1,9 @@
import { Card, Layout, useTheme } from '@ui-kitten/components'
import React, { useCallback, useContext, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RefreshControl, ScrollView, StyleSheet } from 'react-native'
import { RefreshControl, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
import { getNotes, Note } from '../../Functions/DatabaseFunctions/Notes'
import NoteCard from '../NoteCard'
import ActionButton from 'react-native-action-button'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { EventKind } from '../../lib/nostr/Events'
@ -21,7 +19,6 @@ export const HomePage: React.FC = () => {
const [notes, setNotes] = useState<Note[]>([])
const [totalContacts, setTotalContacts] = useState<number>(-1)
const [refreshing, setRefreshing] = useState(false)
const { t } = useTranslation('common')
const loadNotes: () => void = () => {
if (database && publicKey) {
@ -40,13 +37,13 @@ export const HomePage: React.FC = () => {
let message: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors: users.map((user) => user.id),
limit: 15
limit: 15,
}
if (notes.length !== 0) {
message = {
...message,
since: notes[0].created_at
since: notes[0].created_at,
}
}
relayPool?.subscribe('main-channel', message)
@ -99,12 +96,12 @@ export const HomePage: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1
flex: 1,
},
icon: {
width: 32,
height: 32
}
height: 32,
},
})
return (
@ -121,19 +118,24 @@ export const HomePage: React.FC = () => {
</ScrollView>
)}
</Layout>
{/* <ActionButton
buttonColor={theme['color-primary-400']}
useNativeFeedback={true}
fixNativeFeedbackRadius={true}
<TouchableOpacity
style={{
borderWidth: 1,
borderColor: 'rgba(0,0,0,0.2)',
alignItems: 'center',
justifyContent: 'center',
width: 65,
position: 'absolute',
bottom: 20,
right: 20,
height: 65,
backgroundColor: theme['color-warning-500'],
borderRadius: 100,
}}
onPress={() => goToPage(`${page}%send`)}
>
<ActionButton.Item
buttonColor={theme['color-warning-500']}
title={t('homePage.send')}
onPress={() => goToPage(`${page}%send`)}
>
<Icon name='paper-plane' size={30} color={theme['text-basic-color']} solid />
</ActionButton.Item>
</ActionButton> */}
<Icon name='paper-plane' size={30} color={theme['text-basic-color']} solid />
</TouchableOpacity>
</>
)
}

View File

@ -22,8 +22,8 @@ export const Logger: React.FC = () => {
const styles = StyleSheet.create({
input: {
marginVertical: 2,
padding: 32
}
padding: 32,
},
})
useEffect(() => {
@ -33,7 +33,7 @@ export const Logger: React.FC = () => {
initEvents()
relayPool?.subscribe('main-channel', {
kinds: [EventKind.petNames],
authors: [publicKey]
authors: [publicKey],
})
}
}, [relayPool, publicKey])
@ -87,7 +87,7 @@ export const Logger: React.FC = () => {
const authors: string[] = [publicKey, ...event.tags.map((tag) => tagToUser(tag).id)]
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta],
authors
authors,
})
}
}
@ -105,7 +105,7 @@ export const Logger: React.FC = () => {
0: t('landing.connect'),
1: t('landing.connecting'),
2: t('landing.loadingContacts'),
3: t('landing.ready')
3: t('landing.ready'),
}
return !privateKey || status !== 0 ? (

View File

@ -9,18 +9,18 @@ export const LandingPage: React.FC = () => {
tab: {
height: '100%',
alignItems: 'center',
justifyContent: 'center'
justifyContent: 'center',
},
svg: {
height: 340,
width: 340
width: 340,
},
title: {
marginTop: -40,
marginBottom: -20,
fontFamily: 'SpaceGrotesk-Bold',
fontSize: 45
}
fontSize: 45,
},
})
return (
@ -28,9 +28,7 @@ export const LandingPage: React.FC = () => {
<Layout style={styles.svg}>
<Loading />
</Layout>
<Text style={styles.title} category='h1'>
NOSTROS
</Text>
<Text style={styles.title}>NOSTROS</Text>
<Logger />
</Layout>
)

View File

@ -7,18 +7,19 @@ interface LoadingProps {
}
export const Loading: React.FC<LoadingProps> = ({ style = {} }) => {
const logo = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" viewBox="0 0 800 800"><g stroke="hsl(0, 0%, 100%)" fill="none" stroke-linecap="round" style="--darkreader-inline-stroke: #e8e6e3;" data-darkreader-inline-stroke=""><circle r="256" cx="400" cy="400" stroke-width="24" stroke-dasharray="68 51" stroke-dashoffset="25" transform="rotate(309, 400, 400)" opacity="1.00"></circle><circle r="224" cx="400" cy="400" stroke-width="23" stroke-dasharray="76 63" stroke-dashoffset="25" transform="rotate(258, 400, 400)" opacity="0.86"></circle><circle r="192" cx="400" cy="400" stroke-width="22" stroke-dasharray="63 31" stroke-dashoffset="25" transform="rotate(74, 400, 400)" opacity="0.73"></circle><circle r="160" cx="400" cy="400" stroke-width="21" stroke-dasharray="75 71" stroke-dashoffset="25" transform="rotate(62, 400, 400)" opacity="0.59"></circle><circle r="128" cx="400" cy="400" stroke-width="21" stroke-dasharray="43 37" stroke-dashoffset="25" transform="rotate(333, 400, 400)" opacity="0.46"></circle><circle r="96" cx="400" cy="400" stroke-width="20" stroke-dasharray="65 73" stroke-dashoffset="25" transform="rotate(17, 400, 400)" opacity="0.32"></circle><circle r="64" cx="400" cy="400" stroke-width="19" stroke-dasharray="33 58" stroke-dashoffset="25" transform="rotate(269, 400, 400)" opacity="0.19"></circle><circle r="32" cx="400" cy="400" stroke-width="18" stroke-dasharray="66 52" stroke-dashoffset="25" transform="rotate(281, 400, 400)" opacity="0.05"></circle></g></svg>'
const logo =
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" viewBox="0 0 800 800"><g stroke="hsl(0, 0%, 100%)" fill="none" stroke-linecap="round" style="--darkreader-inline-stroke: #e8e6e3;" data-darkreader-inline-stroke=""><circle r="256" cx="400" cy="400" stroke-width="24" stroke-dasharray="68 51" stroke-dashoffset="25" transform="rotate(309, 400, 400)" opacity="1.00"></circle><circle r="224" cx="400" cy="400" stroke-width="23" stroke-dasharray="76 63" stroke-dashoffset="25" transform="rotate(258, 400, 400)" opacity="0.86"></circle><circle r="192" cx="400" cy="400" stroke-width="22" stroke-dasharray="63 31" stroke-dashoffset="25" transform="rotate(74, 400, 400)" opacity="0.73"></circle><circle r="160" cx="400" cy="400" stroke-width="21" stroke-dasharray="75 71" stroke-dashoffset="25" transform="rotate(62, 400, 400)" opacity="0.59"></circle><circle r="128" cx="400" cy="400" stroke-width="21" stroke-dasharray="43 37" stroke-dashoffset="25" transform="rotate(333, 400, 400)" opacity="0.46"></circle><circle r="96" cx="400" cy="400" stroke-width="20" stroke-dasharray="65 73" stroke-dashoffset="25" transform="rotate(17, 400, 400)" opacity="0.32"></circle><circle r="64" cx="400" cy="400" stroke-width="19" stroke-dasharray="33 58" stroke-dashoffset="25" transform="rotate(269, 400, 400)" opacity="0.19"></circle><circle r="32" cx="400" cy="400" stroke-width="18" stroke-dasharray="66 52" stroke-dashoffset="25" transform="rotate(281, 400, 400)" opacity="0.05"></circle></g></svg>'
const spinValue = new Animated.Value(0)
Animated.timing(spinValue, {
toValue: 1,
duration: 100000,
easing: Easing.linear, // Easing is an additional import from react-native
useNativeDriver: true // To make use of native driver for performance
useNativeDriver: true, // To make use of native driver for performance
}).start()
const spin = spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '2016deg']
outputRange: ['0deg', '2016deg'],
})
return (

View File

@ -16,8 +16,8 @@ export const MainLayout: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1
}
flex: 1,
},
})
const pagination: { [pageName: string]: JSX.Element } = {
@ -27,7 +27,7 @@ export const MainLayout: React.FC = () => {
profile: <ProfilePage />,
contacts: <ContactsPage />,
note: <NotePage />,
config: <ConfigPage />
config: <ConfigPage />,
}
const breadcrump: string[] = page.split('%')

View File

@ -24,7 +24,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({ note }) => {
const { relayPool, setRelayPool, publicKey } = useContext(RelayPoolContext)
const { database, goToPage } = useContext(AppContext)
const [relayAdded, setRelayAdded] = useState<boolean>(
Object.keys(relayPool?.relays ?? {}).includes(note.content)
Object.keys(relayPool?.relays ?? {}).includes(note.content),
)
const textNote: () => JSX.Element = () => {
@ -80,7 +80,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({ note }) => {
showMessage({
message: t('alerts.relayAdded'),
description: note.content,
type: 'success'
type: 'success',
})
setRelayAdded(true)
}
@ -117,86 +117,86 @@ export const NoteCard: React.FC<NoteCardProps> = ({ note }) => {
const styles = StyleSheet.create({
layout: {
flexDirection: 'row',
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
profile: {
flex: 1,
width: 38,
alignItems: 'center',
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
content: {
flex: 4,
backgroundColor: 'transparent',
paddingLeft: 16,
paddingRight: 16
paddingRight: 16,
},
contentNoAction: {
flex: 5,
backgroundColor: 'transparent',
paddingLeft: 16,
paddingRight: 16
paddingRight: 16,
},
actions: {
flex: 1,
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
pubkey: {
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
footer: {
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
tags: {
backgroundColor: 'transparent',
marginLeft: 12
marginLeft: 12,
},
titleText: {
backgroundColor: 'transparent',
flexDirection: 'row'
flexDirection: 'row',
},
text: {
backgroundColor: 'transparent',
paddingRight: 10
}
paddingRight: 10,
},
})
const markdownStyle = {
text: {
color: theme['text-basic-color']
color: theme['text-basic-color'],
},
tr: {
borderColor: theme['border-primary-color-5']
borderColor: theme['border-primary-color-5'],
},
table: {
borderColor: theme['border-primary-color-5']
borderColor: theme['border-primary-color-5'],
},
blocklink: {
borderColor: theme['border-primary-color-5']
borderColor: theme['border-primary-color-5'],
},
hr: {
backgroundColor: theme['background-basic-color-3']
backgroundColor: theme['background-basic-color-3'],
},
blockquote: {
backgroundColor: theme['background-basic-color-3'],
borderColor: theme['border-primary-color-5'],
color: theme['text-basic-color']
color: theme['text-basic-color'],
},
code_inline: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color']
color: theme['text-basic-color'],
},
code_block: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color']
color: theme['text-basic-color'],
},
fence: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color']
}
color: theme['text-basic-color'],
},
}
return (

View File

@ -7,10 +7,8 @@ import Icon from 'react-native-vector-icons/FontAwesome5'
import NoteCard from '../NoteCard'
import { EventKind } from '../../lib/nostr/Events'
import { RelayFilters } from '../../lib/nostr/Relay'
import { RefreshControl, ScrollView, StyleSheet } from 'react-native'
import { RefreshControl, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
import Loading from '../Loading'
import ActionButton from 'react-native-action-button'
import { useTranslation } from 'react-i18next'
import { getDirectReplies, getReplyEventId } from '../../Functions/RelayFunctions/Events'
export const NotePage: React.FC = () => {
@ -20,7 +18,6 @@ export const NotePage: React.FC = () => {
const [replies, setReplies] = useState<Note[]>()
const [refreshing, setRefreshing] = useState(false)
const theme = useTheme()
const { t } = useTranslation('common')
const breadcrump = page.split('%')
const eventId = breadcrump[breadcrump.length - 1].split('#')[1]
@ -30,7 +27,7 @@ export const NotePage: React.FC = () => {
relayPool?.unsubscribeAll()
relayPool?.subscribe('main-channel', {
kinds: [EventKind.textNote],
ids: [newEventId ?? eventId]
ids: [newEventId ?? eventId],
})
}
@ -115,7 +112,7 @@ export const NotePage: React.FC = () => {
if (!replies) {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.textNote],
'#e': [eventId]
'#e': [eventId],
})
}
getNotes(database, { filters: { reply_event_id: eventId } }).then((notes) => {
@ -124,7 +121,7 @@ export const NotePage: React.FC = () => {
setReplies(rootReplies as Note[])
const message: RelayFilters = {
kinds: [EventKind.meta],
authors: [...rootReplies.map((note) => note.pubkey), event.pubkey]
authors: [...rootReplies.map((note) => note.pubkey), event.pubkey],
}
relayPool?.subscribe('main-channel', message)
} else {
@ -153,11 +150,11 @@ export const NotePage: React.FC = () => {
paddingBottom: 32,
paddingTop: 26,
paddingLeft: 26,
paddingRight: 26
paddingRight: 26,
},
loading: {
maxHeight: 160
}
maxHeight: 160,
},
})
return (
@ -179,19 +176,24 @@ export const NotePage: React.FC = () => {
<Loading style={styles.loading} />
)}
</Layout>
{/* <ActionButton
buttonColor={theme['color-primary-400']}
useNativeFeedback={true}
fixNativeFeedbackRadius={true}
<TouchableOpacity
style={{
borderWidth: 1,
borderColor: 'rgba(0,0,0,0.2)',
alignItems: 'center',
justifyContent: 'center',
width: 65,
position: 'absolute',
bottom: 10,
right: 10,
height: 65,
backgroundColor: theme['color-warning-500'],
borderRadius: 100,
}}
onPress={() => goToPage(`send#${eventId}`)}
>
<ActionButton.Item
buttonColor={theme['color-warning-500']}
title={t('notePage.reply')}
onPress={() => goToPage(`send#${eventId}`)}
>
<Icon name='reply' size={30} color={theme['text-basic-color']} solid />
</ActionButton.Item>
</ActionButton> */}
<Icon name='reply' size={30} color={theme['text-basic-color']} solid />
</TouchableOpacity>
</>
)
}

View File

@ -5,7 +5,7 @@ import {
Text,
TopNavigation,
TopNavigationAction,
useTheme
useTheme,
} from '@ui-kitten/components'
import React, { useCallback, useContext, useEffect, useState } from 'react'
import { RefreshControl, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
@ -19,13 +19,11 @@ import {
removeContact,
addContact,
User,
getUsers
getUsers,
} from '../../Functions/DatabaseFunctions/Users'
import { EventKind, Event } from '../../lib/nostr/Events'
import Relay, { RelayFilters } from '../../lib/nostr/Relay'
import Icon from 'react-native-vector-icons/FontAwesome5'
import ActionButton from 'react-native-action-button'
import { useTranslation } from 'react-i18next'
import { populatePets, tagToUser } from '../../Functions/RelayFunctions/Users'
import { getReplyEventId } from '../../Functions/RelayFunctions/Events'
import Loading from '../Loading'
@ -36,7 +34,6 @@ export const ProfilePage: React.FC = () => {
const { publicKey, lastEventId, relayPool, setLastEventId } = useContext(RelayPoolContext)
const theme = useTheme()
const [notes, setNotes] = useState<Note[]>()
const { t } = useTranslation('common')
const [user, setUser] = useState<User>()
const [contactsIds, setContactsIds] = useState<string[]>()
const [isContact, setIsContact] = useState<boolean>()
@ -152,7 +149,7 @@ export const ProfilePage: React.FC = () => {
const notesEvent: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors: [userId],
limit: 10
limit: 10,
}
if (results.length >= 10) {
@ -169,7 +166,7 @@ export const ProfilePage: React.FC = () => {
return await new Promise<void>((resolve, reject) => {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta, EventKind.petNames],
authors: [userId]
authors: [userId],
})
relayPool?.on('event', 'profile', (_relay: Relay, _subId?: string, event?: Event) => {
console.log('PROFILE EVENT =======>', event)
@ -195,19 +192,19 @@ export const ProfilePage: React.FC = () => {
const styles = StyleSheet.create({
list: {
flex: 1
flex: 1,
},
icon: {
width: 32,
height: 32
height: 32,
},
settingsIcon: {
width: 48,
height: 48
height: 48,
},
avatar: {
width: 130,
marginBottom: 16
marginBottom: 16,
},
profile: {
flex: 1,
@ -215,27 +212,27 @@ export const ProfilePage: React.FC = () => {
alignItems: 'center',
marginBottom: 2,
paddingLeft: 32,
paddingRight: 32
paddingRight: 32,
},
loading: {
maxHeight: 160
maxHeight: 160,
},
about: {
flex: 4,
maxHeight: 200
maxHeight: 200,
},
stats: {
flex: 1
flex: 1,
},
statsItem: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5
marginBottom: 5,
},
description: {
marginTop: 16,
flexDirection: 'row'
}
flexDirection: 'row',
},
})
const itemCard: (note: Note) => JSX.Element = (note) => {
@ -353,20 +350,24 @@ export const ProfilePage: React.FC = () => {
)}
</Layout>
{publicKey === userId && (
// <ActionButton
// buttonColor={theme['color-primary-400']}
// useNativeFeedback={true}
// fixNativeFeedbackRadius={true}
// >
// <ActionButton.Item
// buttonColor={theme['color-warning-500']}
// title={t('profilePage.send')}
// onPress={() => goToPage(`${page}%send`)}
// >
// <Icon name='paper-plane' size={30} color={theme['text-basic-color']} solid />
// </ActionButton.Item>
// </ActionButton>
<></>
<TouchableOpacity
style={{
borderWidth: 1,
borderColor: 'rgba(0,0,0,0.2)',
alignItems: 'center',
justifyContent: 'center',
width: 65,
position: 'absolute',
bottom: 20,
right: 20,
height: 65,
backgroundColor: theme['color-warning-500'],
borderRadius: 100,
}}
onPress={() => goToPage(`${page}%send`)}
>
<Icon name='paper-plane' size={30} color={theme['text-basic-color']} solid />
</TouchableOpacity>
)}
</>
)

View File

@ -5,7 +5,7 @@ import {
Spinner,
TopNavigation,
TopNavigationAction,
useTheme
useTheme,
} from '@ui-kitten/components'
import React, { useContext, useEffect, useState } from 'react'
import { StyleSheet } from 'react-native'
@ -41,16 +41,16 @@ export const SendPage: React.FC = () => {
const styles = StyleSheet.create({
container: {
flex: 1
flex: 1,
},
actionContainer: {
marginTop: 30,
paddingLeft: 32,
paddingRight: 32
paddingRight: 32,
},
button: {
marginTop: 30
}
marginTop: 30,
},
})
const onPressBack: () => void = () => {
@ -77,13 +77,13 @@ export const SendPage: React.FC = () => {
created_at: moment().unix(),
kind: EventKind.textNote,
pubkey: publicKey,
tags
tags,
}
relayPool?.sendEvent(event).then((sentNote) => {
if (sentNote?.id) {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.textNote],
ids: [sentNote.id]
ids: [sentNote.id],
})
setNoteId(sentNote.id)
}
@ -105,7 +105,7 @@ export const SendPage: React.FC = () => {
<Layout style={styles.container} level='2'>
<TopNavigation
alignment='center'
title={t('sendPage.title')}
title={eventId ? t('sendPage.reply') : t('sendPage.title')}
accessoryLeft={renderBackAction}
/>
<Layout style={styles.actionContainer} level='2'>

View File

@ -17,23 +17,23 @@ export const NoteCard: React.FC<NoteCardProps> = ({ user }) => {
layout: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
profile: {
flex: 1,
width: 38,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
content: {
flex: 5,
backgroundColor: 'transparent'
backgroundColor: 'transparent',
},
actions: {
flex: 1,
backgroundColor: 'transparent'
}
backgroundColor: 'transparent',
},
})
return (

View File

@ -24,7 +24,7 @@ export const initialAppContext: AppContextProps = {
goToPage: () => {},
goBack: () => {},
loadingDb: true,
database: null
database: null,
}
export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.Element => {
@ -70,7 +70,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
goToPage,
goBack,
loadingDb,
database
database,
}}
>
{children}

View File

@ -28,11 +28,11 @@ export const initialRelayPoolContext: RelayPoolContextProps = {
setPublicKey: () => {},
setPrivateKey: () => {},
setRelayPool: () => {},
setLastEventId: () => {}
setLastEventId: () => {},
}
export const RelayPoolContextProvider = ({
children
children,
}: RelayPoolContextProviderProps): JSX.Element => {
const { database, loadingDb, goToPage, page } = useContext(AppContext)
@ -51,7 +51,7 @@ export const RelayPoolContextProvider = ({
initRelayPool.add(relay.url)
})
} else {
['wss://relay.damus.io'].forEach((relayUrl) => {
;['wss://relay.damus.io'].forEach((relayUrl) => {
initRelayPool.add(relayUrl)
storeRelay({ url: relayUrl }, database)
})
@ -64,9 +64,9 @@ export const RelayPoolContextProvider = ({
showMessage({
message: relay.url,
description: event?.content ?? '',
type: 'info'
type: 'info',
})
}
},
)
initRelayPool?.on(
'event',
@ -78,7 +78,7 @@ export const RelayPoolContextProvider = ({
.then(() => setLastEventId(event.id))
.catch(() => setLastEventId(event.id))
}
}
},
)
setRelayPool(initRelayPool)
})
@ -128,7 +128,7 @@ export const RelayPoolContextProvider = ({
privateKey,
setPrivateKey,
lastEventId,
setLastEventId
setLastEventId,
}}
>
{children}

View File

@ -5,7 +5,7 @@ import { insertUserMeta } from '../Users'
export const storeEvent: (event: Event, db: SQLiteDatabase) => Promise<void> = async (
event,
db
db,
) => {
return await new Promise<void>((resolve, reject) => {
try {

View File

@ -17,7 +17,7 @@ export const createInitDatabase: (db: SQLiteDatabase) => Promise<void> = async (
reply_event_id TEXT
);
`,
db
db,
).then(() => {
simpleExecute(
`
@ -30,7 +30,7 @@ export const createInitDatabase: (db: SQLiteDatabase) => Promise<void> = async (
contact BOOLEAN DEFAULT FALSE
);
`,
db
db,
).then(() => {
simpleExecute(
`
@ -39,7 +39,7 @@ export const createInitDatabase: (db: SQLiteDatabase) => Promise<void> = async (
pet INTEGER
);
`,
db
db,
).then(() => resolve())
})
})

View File

@ -16,7 +16,7 @@ const databaseToEntity: (object: any) => Note = (object) => {
export const insertNote: (event: Event, db: SQLiteDatabase) => Promise<void> = async (
event,
db
db,
) => {
return await new Promise<void>((resolve, reject) => {
if (!verifySignature(event) || !event.id) return reject(new Error('Bad event'))
@ -44,12 +44,7 @@ export const insertNote: (event: Event, db: SQLiteDatabase) => Promise<void> = a
'${replyEventId}'
);`
db.transaction((transaction) => {
transaction.executeSql(
eventQuery,
[],
() => resolve(),
errorCallback(eventQuery, reject)
)
transaction.executeSql(eventQuery, [], () => resolve(), errorCallback(eventQuery, reject))
})
} else {
reject(new Error('Note already exists'))
@ -115,7 +110,7 @@ export const getNotes: (
const notes: Note[] = items.map((object) => databaseToEntity(object))
resolve(notes)
},
errorCallback(notesQuery, reject)
errorCallback(notesQuery, reject),
)
})
})

View File

@ -26,12 +26,7 @@ export const storeRelay: (relay: Relay, db: SQLiteDatabase) => void = async (rel
await new Promise<void>((resolve, reject) => {
db.transaction((transaction) => {
transaction.executeSql(
eventQuery,
[],
() => resolve(),
errorCallback(eventQuery, reject)
)
transaction.executeSql(eventQuery, [], () => resolve(), errorCallback(eventQuery, reject))
})
})
}
@ -40,7 +35,7 @@ export const storeRelay: (relay: Relay, db: SQLiteDatabase) => void = async (rel
export const searchRelays: (relayUrl: string, db: SQLiteDatabase) => Promise<Relay[]> = async (
relayUrl,
db
db,
) => {
const searchQuery = `
SELECT * FROM nostros_relays WHERE url = '${relayUrl}';
@ -56,7 +51,7 @@ export const searchRelays: (relayUrl: string, db: SQLiteDatabase) => Promise<Rel
const notes: Relay[] = items.map((object) => databaseToEntity(object))
resolve(notes)
},
errorCallback(searchQuery, reject)
errorCallback(searchQuery, reject),
)
})
})
@ -75,7 +70,7 @@ export const getRelays: (db: SQLiteDatabase) => Promise<Relay[]> = async (db) =>
const relays: Relay[] = items.map((object) => databaseToEntity(object))
resolve(relays)
},
errorCallback(notesQuery, reject)
errorCallback(notesQuery, reject),
)
})
})

View File

@ -19,7 +19,7 @@ const databaseToEntity: (object: object) => User = (object) => {
export const insertUserMeta: (event: Event, db: SQLiteDatabase) => Promise<void> = async (
event,
db
db,
) => {
return await new Promise<void>((resolve, reject) => {
if (!verifySignature(event)) return reject(new Error('Bad signature'))
@ -63,7 +63,7 @@ export const insertUserMeta: (event: Event, db: SQLiteDatabase) => Promise<void>
export const insertUserContact: (event: Event, db: SQLiteDatabase) => Promise<void> = async (
event,
db
db,
) => {
return await new Promise<void>((resolve, reject) => {
if (!verifySignature(event)) return reject(new Error('Bad signature'))
@ -78,7 +78,7 @@ export const insertUserContact: (event: Event, db: SQLiteDatabase) => Promise<vo
export const getUser: (pubkey: string, db: SQLiteDatabase) => Promise<User | null> = async (
pubkey,
db
db,
) => {
const userQuery = `SELECT * FROM nostros_users WHERE id = '${pubkey}';`
return await new Promise<User | null>((resolve, reject) => {
@ -95,7 +95,7 @@ export const getUser: (pubkey: string, db: SQLiteDatabase) => Promise<User | nul
resolve(null)
}
},
errorCallback(userQuery, reject)
errorCallback(userQuery, reject),
)
})
})
@ -103,7 +103,7 @@ export const getUser: (pubkey: string, db: SQLiteDatabase) => Promise<User | nul
export const removeContact: (pubkey: string, db: SQLiteDatabase) => Promise<void> = async (
pubkey,
db
db,
) => {
const userQuery = `UPDATE nostros_users SET contact = FALSE WHERE id = '${pubkey}'`
return await new Promise<void>((resolve, reject) => {
@ -115,7 +115,7 @@ export const removeContact: (pubkey: string, db: SQLiteDatabase) => Promise<void
export const addContact: (pubkey: string, db: SQLiteDatabase) => Promise<void> = async (
pubkey,
db
db,
) => {
return await new Promise<void>((resolve, reject) => {
getUser(pubkey, db).then((userDb) => {
@ -138,7 +138,7 @@ export const addContact: (pubkey: string, db: SQLiteDatabase) => Promise<void> =
export const getUsers: (
db: SQLiteDatabase,
options: { exludeIds?: string[], contacts?: boolean, includeIds?: string[] },
options: { exludeIds?: string[]; contacts?: boolean; includeIds?: string[] },
) => Promise<User[]> = async (db, { exludeIds, contacts, includeIds }) => {
let userQuery = 'SELECT * FROM nostros_users '
@ -180,7 +180,7 @@ export const getUsers: (
resolve([])
}
},
errorCallback(userQuery, reject)
errorCallback(userQuery, reject),
)
})
})

View File

@ -5,7 +5,7 @@ export const initDatabase: () => SQLiteDatabase = () => {
return SQLite.openDatabase(
{ name: 'nostros.db', location: 'default' },
() => {},
() => {}
() => {},
)
}
@ -21,7 +21,7 @@ export const getItems: (resultSet: ResultSet) => object[] = (resultSet) => {
export const simpleExecute: (query: string, db: SQLiteDatabase) => Promise<Transaction> = async (
query,
db
db,
) => {
return await db.transaction((transaction) => {
transaction.executeSql(query, [], () => {}, errorCallback(query))
@ -32,7 +32,7 @@ export const dropTables: (db: SQLiteDatabase) => Promise<Transaction> = async (d
const dropQueries = [
'DROP TABLE IF EXISTS nostros_notes;',
'DROP TABLE IF EXISTS nostros_users;',
'DROP TABLE IF EXISTS nostros_relays;'
'DROP TABLE IF EXISTS nostros_relays;',
]
return await db.transaction((transaction) => {
dropQueries.forEach((query) => {

View File

@ -20,7 +20,7 @@ export const tagToUser: (tag: string[]) => User = (tag) => {
return {
id: tag[1],
main_relay: tag[2],
name: tag[3]
name: tag[3],
}
}
@ -36,7 +36,7 @@ export const populatePets: (
created_at: moment().unix(),
kind: 3,
pubkey: publicKey,
tags: usersToTags(results)
tags: usersToTags(results),
}
relayPool?.sendEvent(event)
}
@ -54,14 +54,14 @@ export const populateProfile: (
name: result.name,
main_relay: result.main_relay,
picture: result.picture,
about: result.about
about: result.about,
}
const event: Event = {
content: JSON.stringify(profile),
created_at: moment().unix(),
kind: 0,
pubkey: publicKey,
tags: usersToTags([result])
tags: usersToTags([result]),
}
relayPool?.sendEvent(event)
}

View File

@ -36,7 +36,8 @@
"sendPage": {
"title": "Send a note",
"placeholder": "Say something to the world...",
"send": "Send"
"send": "Send",
"reply": "Send a reply"
},
"alerts": {
"relayAdded": "Relay added"

View File

@ -6,14 +6,14 @@ i18n.use(initReactI18next).init({
compatibilityJSON: 'v3',
fallbackLng: 'en',
resources: {
en
en,
},
ns: ['common'],
defaultNS: 'common',
debug: true,
interpolation: {
escapeValue: false
}
escapeValue: false,
},
})
export default i18n

View File

@ -12,9 +12,9 @@ import i18n from './i18n.config'
export const Frontend: React.FC = () => {
const mapping = {
strict: {
'text-font-family': 'OpenSans-Regular'
'text-font-family': 'OpenSans-Regular',
},
components: {}
components: {},
}
return (

View File

@ -47,7 +47,7 @@ export const verifySignature: (event: Event) => Promise<boolean> = async (event)
schnorr.verify(
Buffer.from(event.pubkey, 'hex'),
Buffer.from(event?.id, 'hex'),
Buffer.from(event?.sig, 'hex')
Buffer.from(event?.sig, 'hex'),
)
return true
} catch (_e) {
@ -58,13 +58,11 @@ export const verifySignature: (event: Event) => Promise<boolean> = async (event)
export const signEvent: (event: Event, privateKey: string) => Promise<Event> = async (
event,
privateKey
privateKey,
) => {
const hash = getEventHash(event)
const signature: string = Buffer.from(await schnorr.sign(privateKey, hash), 'hex').toString(
'hex'
)
const signature: string = Buffer.from(await schnorr.sign(privateKey, hash), 'hex').toString('hex')
event.id = hash.toString('hex')
event.sig = signature

View File

@ -21,7 +21,7 @@ export interface RelayOptions {
}
class Relay {
constructor (relayUrl: string, options: RelayOptions = { reconnect: true }) {
constructor(relayUrl: string, options: RelayOptions = { reconnect: true }) {
this.url = relayUrl
this.options = options
this.manualClose = false
@ -110,11 +110,11 @@ class Relay {
public readonly subscribe: (subId: string, filters?: RelayFilters) => void = (
subId,
filters = {}
filters = {},
) => {
const uuid = uuidv5(
`${subId}${JSON.stringify(filters)}`,
'57003344-b2cb-4b6f-a579-fae9e82c370a'
'57003344-b2cb-4b6f-a579-fae9e82c370a',
)
if (this.subscriptions[subId]?.includes(uuid)) {
console.log('Subscription already done!')

View File

@ -9,7 +9,7 @@ export interface OnFunctions {
}
class RelayPool {
constructor (relaysUrls: string[], privateKey: string, options: RelayOptions = {}) {
constructor(relaysUrls: string[], privateKey: string, options: RelayOptions = {}) {
this.relays = {}
this.privateKey = privateKey
this.options = options
@ -18,7 +18,7 @@ class RelayPool {
open: {},
event: {},
esoe: {},
notice: {}
notice: {},
}
relaysUrls.forEach((relayUrl) => {
@ -42,17 +42,17 @@ class RelayPool {
}
relay.onEvent = (eventRelay, subId, event) => {
Object.keys(this.onFunctions.event).forEach((id) =>
this.onFunctions.event[id](eventRelay, subId, event)
this.onFunctions.event[id](eventRelay, subId, event),
)
}
relay.onEsoe = (eventRelay, subId) => {
Object.keys(this.onFunctions.esoe).forEach((id) =>
this.onFunctions.esoe[id](eventRelay, subId)
this.onFunctions.esoe[id](eventRelay, subId),
)
}
relay.onNotice = (eventRelay, events) => {
Object.keys(this.onFunctions.notice).forEach((id) =>
this.onFunctions.notice[id](eventRelay, events)
this.onFunctions.notice[id](eventRelay, events),
)
}
})
@ -68,7 +68,7 @@ class RelayPool {
public removeOn: (method: 'open' | 'event' | 'esoe' | 'notice', id: string) => void = (
method,
id
id,
) => {
delete this.onFunctions[method][id]
}

View File

@ -2,8 +2,8 @@
* @format
*/
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import { AppRegistry } from 'react-native'
import App from './App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App);
AppRegistry.registerComponent(appName, () => App)

View File

@ -1,53 +1,53 @@
{
"images" : [
"images": [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
"idiom": "iphone",
"scale": "2x",
"size": "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
"idiom": "iphone",
"scale": "3x",
"size": "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
"idiom": "iphone",
"scale": "2x",
"size": "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
"idiom": "iphone",
"scale": "3x",
"size": "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
"idiom": "iphone",
"scale": "2x",
"size": "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
"idiom": "iphone",
"scale": "3x",
"size": "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
"idiom": "iphone",
"scale": "2x",
"size": "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
"idiom": "iphone",
"scale": "3x",
"size": "60x60"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
"idiom": "ios-marketing",
"scale": "1x",
"size": "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
"info": {
"author": "xcode",
"version": 1
}
}

View File

@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"info": {
"version": 1,
"author": "xcode"
}
}

View File

@ -14,4 +14,4 @@ module.exports = {
},
}),
},
};
}

View File

@ -4,4 +4,4 @@ module.exports = {
android: {},
},
assets: ['./assets/fonts/'],
};
}