Offline and Contacts fixes

This commit is contained in:
KoalaSat 2023-12-12 00:26:27 +01:00
parent b04544cfd9
commit c2fcbfeca8
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
17 changed files with 102 additions and 86 deletions

View File

@ -26,6 +26,10 @@ jobs:
https://github.com/KoalaSat/nostros/releases/download/${{ github.ref_name }}/nostros-${{ github.ref_name }}-universal.apk
**Torrent**
https://github.com/KoalaSat/nostros/releases/download/${{ github.ref_name }}/nostros-${{ github.ref_name }}-universal.torrent
**Changelog**
https://github.com/KoalaSat/nostros/releases/${{ github.ref_name }}
@ -75,4 +79,13 @@ jobs:
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: app-armeabi-v7a-release.apk
asset_name: nostros-${{ github.ref_name }}-armeabi-v7a.apk
asset_content_type: application/apk
asset_content_type: application/apk
- name: Install torf-cli
run: sudo pip3 install torf-cli
- name: Create torrent using torf-cli
run: torf "nostros-${{ github.ref_name }}-universal.apk" -o "nostros-${{ github.ref_name }}-universal.torrent" -w "https://github.com/KoalaSat/nostros/releases/download/${{ github.ref_name }}/nostros-${{ github.ref_name }}-universal.apk" -s "torrent-webseed-creator"
- name: Upload torrent file
uses: actions/upload-artifact@v3
with:
name: Torrent
path: nostros-${{ github.ref_name }}-universal.torrent

View File

@ -132,7 +132,7 @@ export const MenuItems: React.FC = () => {
/>
</TouchableRipple>
<View style={styles.cardEdit}>
{privateKey && (
{privateKey && online && (
<IconButton
icon='pencil-outline'
size={20}

View File

@ -306,7 +306,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
<View style={styles.reactionsPopupContent}>
<Button
onPress={() => {
if (!userDownvoted && privateKey) {
if (!userDownvoted && privateKey && online) {
setUserDownvoted(true)
setNegativeReactions((prev) => prev + 1)
publishReaction(false)
@ -325,7 +325,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
</Button>
<Button
onPress={() => {
if (!userUpvoted && privateKey) {
if (!userUpvoted && privateKey && online) {
setUserUpvoted(true)
setPositiveReactions((prev) => prev + 1)
publishReaction(true)

View File

@ -47,7 +47,6 @@ export interface AppContextProps {
setClipboardNip21: (clipboardNip21: string | undefined) => void
checkClipboard: () => void
displayUserDrawer?: string
setDisplayUserDrawer: (displayUserDrawer: string | undefined) => void
displayNoteDrawer?: string
refreshBottomBarAt?: number
setRefreshBottomBarAt: (refreshBottomBarAt: number) => void
@ -98,7 +97,6 @@ export const initialAppContext: AppContextProps = {
getImageHostingService: () => '',
getSatoshiSymbol: () => <></>,
setClipboardNip21: () => {},
setDisplayUserDrawer: () => {},
longPressZap: undefined,
setLongPressZap: () => {},
signHeight: false,
@ -130,7 +128,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb)
const [clipboardLoads, setClipboardLoads] = React.useState<string[]>([])
const [clipboardNip21, setClipboardNip21] = React.useState<string>()
const [displayUserDrawer, setDisplayUserDrawer] = React.useState<string>()
const [pushedTab, setPushedTab] = useState<string>()
const [signHeight, setSignWithHeight] = useState<boolean>(initialAppContext.signHeight)
const [online, setOnline] = React.useState<boolean>(initialAppContext.online)
@ -249,8 +246,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
value={{
relayColouring,
setRelayColouring,
displayUserDrawer,
setDisplayUserDrawer,
language,
setLanguage,
checkClipboard,

View File

@ -35,6 +35,7 @@ export const dropTables: (db: QuickSQLiteConnection) => Promise<BatchQueryResult
['DELETE FROM nostros_reactions;', [[]]],
['DELETE FROM nostros_relays;', [[]]],
['DELETE FROM nostros_notes_relays;', [[]]],
['DELETE FROM nostros_relay_metadata;', [[]]],
['DELETE FROM nostros_direct_messages;', [[]]],
['DELETE FROM nostros_group_meta;', [[]]],
['DELETE FROM nostros_group_messages;', [[]]],

View File

@ -32,17 +32,17 @@ import ProfileData from '../../Components/ProfileData'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import DatabaseModule from '../../lib/Native/DatabaseModule'
import { removeMutedUsersList } from '../../Functions/RelayFunctions/Lists'
import { push } from '../../lib/Navigation'
export const ContactsPage: React.FC = () => {
const { t } = useTranslation('common')
const theme = useTheme()
const initialPageSize = 20
const { database, setDisplayUserDrawer, qrReader, setQrReader, online } = useContext(AppContext)
const { database, qrReader, setQrReader, online } = useContext(AppContext)
const { privateKey, publicKey, nPub, mutedUsers, reloadLists } = React.useContext(UserContext)
const { relayPool, lastEventId, sendEvent } = useContext(RelayPoolContext)
const [pageSize, setPageSize] = useState<number>(initialPageSize)
const bottomSheetAddContactRef = React.useRef<RBSheet>(null)
const bottomSheetProfileRef = React.useRef<RBSheet>(null)
// State
const [followers, setFollowers] = useState<User[]>([])
const [following, setFollowing] = useState<User[]>([])
@ -208,10 +208,7 @@ export const ContactsPage: React.FC = () => {
const renderContactItem: ListRenderItem<User> = ({ index, item }) => {
return (
<TouchableRipple
onPress={() => {
setDisplayUserDrawer(item.id)
bottomSheetProfileRef.current?.open()
}}
onPress={() => push('ProfileActions', { userId: item.id, title: item?.name })}
>
<View key={item.id} style={styles.contactRow}>
<View style={styles.profileData}>
@ -238,10 +235,7 @@ export const ContactsPage: React.FC = () => {
const renderMutedItem: ListRenderItem<User> = ({ index, item }) => {
return (
<TouchableRipple
onPress={() => {
setDisplayUserDrawer(item.id)
bottomSheetProfileRef.current?.open()
}}
onPress={() => push('ProfileActions', { userId: item.id, title: item?.name })}
>
<View key={item.id} style={styles.contactRow}>
<View style={styles.profileData}>

View File

@ -41,6 +41,7 @@ import UploadImage from '../../Components/UploadImage'
import { Swipeable } from 'react-native-gesture-handler'
import { getETags } from '../../Functions/RelayFunctions/Events'
import DatabaseModule from '../../lib/Native/DatabaseModule'
import { push } from '../../lib/Navigation'
interface ConversationPageProps {
route: { params: { pubKey: string; conversationId: string } }
@ -50,8 +51,8 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
const initialPageSize = 10
const theme = useTheme()
const scrollViewRef = useRef<ScrollView>()
const { database, setRefreshBottomBarAt, setDisplayUserDrawer } = useContext(AppContext)
const { relayPool, lastEventId, sendEvent, online } = useContext(RelayPoolContext)
const { database, setRefreshBottomBarAt, online } = useContext(AppContext)
const { relayPool, lastEventId, sendEvent } = useContext(RelayPoolContext)
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
const otherPubKey = useMemo(() => route.params.pubKey, [])
const [pageSize, setPageSize] = useState<number>(initialPageSize)
@ -254,7 +255,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
<TextContent
content={message?.content}
event={message}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
onPressUser={(user) => push('ProfileActions', { userId: user.id, title: user?.name })}
copyText
/>
) : (
@ -292,7 +293,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
{publicKey !== item.pubkey && (
<View style={styles.pictureSpaceLeft}>
{showAvatar && (
<TouchableRipple onPress={() => setDisplayUserDrawer(otherPubKey)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: otherUser.id, title: otherUser.name })}>
<NostrosAvatar
name={otherUser.name}
pubKey={otherPubKey}
@ -334,7 +335,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
{publicKey === item.pubkey && (
<View style={styles.pictureSpaceRight}>
{showAvatar && (
<TouchableRipple onPress={() => setDisplayUserDrawer(publicKey)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: publicKey, title: name })}>
<NostrosAvatar name={name} pubKey={publicKey} src={picture} size={40} />
</TouchableRipple>
)}
@ -400,7 +401,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
<TextContent
content={reply.content}
event={reply}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
onPressUser={(user) => push('ProfileActions', { userId: user.id, title: user?.name })}
showPreview={false}
numberOfLines={3}
/>

View File

@ -38,6 +38,7 @@ import ProfileData from '../../Components/ProfileData'
import { ScrollView, Swipeable } from 'react-native-gesture-handler'
import { getETags } from '../../Functions/RelayFunctions/Events'
import DatabaseModule from '../../lib/Native/DatabaseModule'
import { push } from '../../lib/Navigation'
interface GroupPageProps {
route: { params: { groupId: string } }
@ -46,7 +47,7 @@ interface GroupPageProps {
export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
const initialPageSize = 20
const theme = useTheme()
const { database, setDisplayUserDrawer, online } = useContext(AppContext)
const { database, online } = useContext(AppContext)
const { relayPool, lastEventId, sendEvent } = useContext(RelayPoolContext)
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
const [pageSize, setPageSize] = useState<number>(initialPageSize)
@ -308,7 +309,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
<TextContent
content={message?.content}
event={message}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
onPressUser={(user) => push('ProfileActions', { userId: user.id, title: user?.name })}
copyText
/>
) : (
@ -335,7 +336,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
{publicKey !== item.pubkey && (
<View style={styles.pictureSpaceLeft}>
{showAvatar && (
<TouchableRipple onPress={() => setDisplayUserDrawer(item.pubkey)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: item.id, title: item?.name })}>
<NostrosAvatar
name={displayName(item)}
pubKey={item.pubkey}
@ -379,7 +380,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
{publicKey === item.pubkey && (
<View style={styles.pictureSpaceRight}>
{showAvatar && (
<TouchableRipple onPress={() => setDisplayUserDrawer(publicKey)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: publicKey, title: name })}>
<NostrosAvatar name={name} pubKey={publicKey} src={picture} size={40} />
</TouchableRipple>
)}
@ -435,7 +436,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
<TextContent
content={reply.content}
event={reply}
onPressUser={(user) => setDisplayUserDrawer(user.id)}
onPressUser={(user) => push('ProfileActions', { userId: user.id, title: user?.name })}
showPreview={false}
numberOfLines={3}
/>

View File

@ -282,15 +282,17 @@ export const ConversationsFeed: React.FC = () => {
</Button>
</View>
)}
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='pencil-outline'
label='Label'
onPress={() => bottomSheetCreateRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
{privateKey && online && (
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='pencil-outline'
label='Label'
onPress={() => bottomSheetCreateRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
)}
<RBSheet ref={bottomSheetCreateRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<FlatList
data={createOptions}

View File

@ -42,7 +42,7 @@ export const GroupsFeed: React.FC = () => {
const { t } = useTranslation('common')
const theme = useTheme()
const { database, qrReader, setQrReader, refreshBottomBarAt, online } = useContext(AppContext)
const { publicKey } = useContext(UserContext)
const { publicKey, privateKey } = useContext(UserContext)
const { relayPool, lastEventId, lastConfirmationtId, sendEvent, setNewGroupMessages, newGroupMessages } = useContext(RelayPoolContext)
const bottomSheetSearchRef = React.useRef<RBSheet>(null)
const bottomSheetCreateRef = React.useRef<RBSheet>(null)
@ -297,15 +297,17 @@ export const GroupsFeed: React.FC = () => {
horizontal={false}
estimatedItemSize={76}
/>
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='plus'
label='Label'
onPress={() => bottomSheetFabActionRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
{privateKey && online && (
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='plus'
label='Label'
onPress={() => bottomSheetFabActionRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
)}
<RBSheet ref={bottomSheetCreateRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<View>
<Text style={styles.input} variant='titleLarge'>

View File

@ -9,12 +9,14 @@ import Tabs from '../../../Components/Tabs'
import ZapsFeed from './ZapsFeed'
import BookmarksFeed from './BookmarksFeed'
import { RelayPoolContext } from '../../../Contexts/RelayPoolContext'
import { AppContext } from '../../../Contexts/AppContext'
interface HomeFeedProps {
navigation: any
}
export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
const { online } = useContext(AppContext)
const { privateKey, publicKey } = useContext(UserContext)
const { relayPool } = useContext(RelayPoolContext)
const [activeTab, setActiveTab] = React.useState('myFeed')
@ -80,7 +82,7 @@ export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
defaultTab='myFeed'
/>
<View style={styles.feed}>{renderScene[activeTab]}</View>
{privateKey && (
{privateKey && online && (
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='pencil-outline'

View File

@ -143,7 +143,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
/>
</View>
</ScrollView>
{privateKey && (
{privateKey && online && (
<AnimatedFAB
style={[styles.fabSend, { top: Dimensions.get('window').height - 136 }]}
icon='message-plus-outline'

View File

@ -18,8 +18,7 @@ interface ProfileCreatePageProps {
export const ProfileCreatePage: React.FC<ProfileCreatePageProps> = ({ navigation }) => {
const { t } = useTranslation('common')
const { setPrivateKey, setUserState, publicKey } = useContext(UserContext)
const { createRandomRelays, sendEvent, relays } = useContext(RelayPoolContext)
const [key, setKey] = useState<string>()
const { createRandomRelays, sendEvent, relays, relayPoolReady } = useContext(RelayPoolContext)
const [inputValue, setInputValue] = useState<string>()
const [keyboardShow, setKeyboardShow] = useState<boolean>(false)
const [step, setStep] = useState<number>(0)
@ -35,13 +34,16 @@ export const ProfileCreatePage: React.FC<ProfileCreatePageProps> = ({ navigation
generateRandomMnemonic().then((words) => {
setMnemonicWords(words)
const privateKey = nip06.privateKeyFromSeedWords(Object.values(words).join(' '))
setKey(privateKey)
setPrivateKey(privateKey)
const nsec = nip19.nsecEncode(privateKey)
setInputValue(nsec)
})
createRandomRelays()
}, [])
React.useEffect(() => {
if (relayPoolReady) createRandomRelays()
}, [relayPoolReady])
useEffect(() => {
if (inputValue) setLoading(false)
}, [inputValue])
@ -92,7 +94,6 @@ export const ProfileCreatePage: React.FC<ProfileCreatePageProps> = ({ navigation
sendEvent(event)
}
if (validConfirmation()) {
setPrivateKey(key)
publishRelays()
setUserState('ready')
} else {
@ -104,7 +105,6 @@ export const ProfileCreatePage: React.FC<ProfileCreatePageProps> = ({ navigation
}
const onPressSkip: () => void = () => {
setPrivateKey(key)
publishRelays()
setUserState('ready')
}

View File

@ -1,7 +1,7 @@
import React, { useContext, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { type ListRenderItem, StyleSheet, View, FlatList } from 'react-native'
import { Button, Card, Divider, List, Text, useTheme } from 'react-native-paper'
import { ActivityIndicator, Button, Card, Divider, List, Text, useTheme } from 'react-native-paper'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { AppContext } from '../../../Contexts/AppContext'
import { RelayPoolContext } from '../../../Contexts/RelayPoolContext'
@ -121,6 +121,7 @@ export const ThirdStep: React.FC<ThirdStepProps> = ({ nextStep, skip }) => {
<Card.Content>
<View style={styles.loadingProfile}>
<Text>{t('profileLoadPage.contatcsRelays')}</Text>
<ActivityIndicator animating={true} size={20} />
<Text style={{ color: '#7ADC70' }}>
{t('profileLoadPage.contatcsRelaysCount', { activeRelays: contactsRelays.length })}
</Text>

View File

@ -350,27 +350,31 @@ export const RelaysPage: React.FC = () => {
ItemSeparatorComponent={Divider}
/>
</ScrollView>
<AnimatedFAB
style={styles.fabContacts}
icon='cached'
label='push'
onPress={() => {
calculateContactsRelays()
bottomSheetContactsRef.current?.open()
}}
animateFrom='right'
iconMode='static'
extended={false}
/>
<AnimatedFAB
style={styles.fabPush}
icon='upload-multiple'
label='push'
onPress={() => bottomSheetPushRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
{online && (
<>
<AnimatedFAB
style={styles.fabContacts}
icon='cached'
label='push'
onPress={() => {
calculateContactsRelays()
bottomSheetContactsRef.current?.open()
}}
animateFrom='right'
iconMode='static'
extended={false}
/>
<AnimatedFAB
style={styles.fabPush}
icon='upload-multiple'
label='push'
onPress={() => bottomSheetPushRef.current?.open()}
animateFrom='right'
iconMode='static'
extended={false}
/>
</>
)}
<AnimatedFAB
style={styles.fabAdd}
icon='plus'

View File

@ -24,11 +24,11 @@ import { UserContext } from '../../Contexts/UserContext'
import { WalletContext } from '../../Contexts/WalletContext'
import { getZaps, type Zap } from '../../Functions/DatabaseFunctions/Zaps'
import type WalletAction from '../../lib/Lightning'
import { navigate } from '../../lib/Navigation'
import { navigate, push } from '../../lib/Navigation'
export const WalletPage: React.FC = () => {
const theme = useTheme()
const { getSatoshiSymbol, database, setDisplayUserDrawer, online } = React.useContext(AppContext)
const { getSatoshiSymbol, database, online } = React.useContext(AppContext)
const { publicKey } = React.useContext(UserContext)
const { relayPool, lastEventId } = React.useContext(RelayPoolContext)
const { refreshWallet, updateWallet, type, balance, transactions, invoices, updatedAt } =
@ -171,7 +171,7 @@ export const WalletPage: React.FC = () => {
if (zap.zapped_event_id) {
navigate('Note', { noteId: zap.zapped_event_id })
} else if (zap.zapper_user_id) {
setDisplayUserDrawer(zap.zapper_user_id)
push('ProfileActions', { userId: zap.zapper_user_id, title: zap.name })
}
}
}}

View File

@ -18,7 +18,7 @@ import { Kind } from 'nostr-tools'
import { getUsers, type User } from '../../Functions/DatabaseFunctions/Users'
import LnPreview from '../../Components/LnPreview'
import { FlatList, type ListRenderItem, ScrollView, StyleSheet, View, Dimensions } from 'react-native'
import { goBack } from '../../lib/Navigation'
import { goBack, push } from '../../lib/Navigation'
import { getZapTag } from '../../Functions/RelayFunctions/Events'
interface ZapPageProps {
@ -33,7 +33,7 @@ export const ZapPage: React.FC<ZapPageProps> = ({ route: { params: { note, user
const userId = user?.id ?? note?.pubkey
const zapPubkey = user?.zap_pubkey ?? note?.zap_pubkey
const zapSplitTags = getZapTag(note)
const { getSatoshiSymbol, database, setDisplayUserDrawer, online } = React.useContext(AppContext)
const { getSatoshiSymbol, database, online } = React.useContext(AppContext)
const { relayPool, lastEventId } = React.useContext(RelayPoolContext)
const { publicKey, privateKey } = React.useContext(UserContext)
const bottomSheetLnPaymentRef = React.useRef<RBSheet>(null)
@ -135,7 +135,7 @@ export const ZapPage: React.FC<ZapPageProps> = ({ route: { params: { note, user
const zapDescription = item.tags?.find((tag) => tag[0] === 'description')
const content = zapDescription ? JSON.parse(zapDescription[1])?.content : undefined
return (
<TouchableRipple onPress={() => setDisplayUserDrawer(item.user_id)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: item?.user_id, title: item?.name })}>
<View key={item.id} style={styles.zapperRow}>
<View style={styles.zapperData}>
<ProfileData
@ -171,7 +171,7 @@ export const ZapPage: React.FC<ZapPageProps> = ({ route: { params: { note, user
const totalWeight = zapSplitTags.reduce((acc, tag) => acc + parseInt(tag[3] ?? '0', 10), 0)
const weightedAllocation = allocationTag ? (parseInt(allocationTag[3] ?? '0', 10) * 100) / totalWeight : 0
return (
<TouchableRipple onPress={() => setDisplayUserDrawer(item)}>
<TouchableRipple onPress={() => push('ProfileActions', { userId: user?.id, title: user?.name })}>
<View key={item} style={styles.zapperRow}>
<View style={styles.zapperData}>
<ProfileData