mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-29 22:50:43 +00:00
Offline mode
This commit is contained in:
parent
bada78bf9d
commit
368c48510e
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@ -30,7 +30,6 @@ jobs:
|
||||
|
||||
https://github.com/KoalaSat/nostros/releases/${{ github.ref_name }}
|
||||
|
||||
**What's Changed**
|
||||
# Upload APK artifact asset
|
||||
- name: 'Download universal APK Artifact'
|
||||
uses: actions/download-artifact@v3
|
||||
|
@ -116,6 +116,15 @@ public class RelayPoolModule extends ReactContextBaseJavaModule {
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void disconnect(Callback callback) {
|
||||
relays = database.getRelays(context, createdEvents);
|
||||
for (Relay relay : relays) {
|
||||
relay.disconnect();
|
||||
}
|
||||
callback.invoke();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendAll(String message, boolean isGlobalFeed) throws IOException {
|
||||
for (Relay relay : relays) {
|
||||
|
@ -35,7 +35,7 @@ interface GroupHeaderIconProps {
|
||||
|
||||
export const GroupHeaderIcon: React.FC<GroupHeaderIconProps> = ({ groupId }) => {
|
||||
const { t } = useTranslation('common')
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { sendEvent, lastEventId } = useContext(RelayPoolContext)
|
||||
const theme = useTheme()
|
||||
@ -62,7 +62,7 @@ export const GroupHeaderIcon: React.FC<GroupHeaderIconProps> = ({ groupId }) =>
|
||||
setNewGroupPicture(result.picture)
|
||||
})
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
const pastePicture: () => void = () => {
|
||||
Clipboard.getString().then((value) => {
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
TouchableRipple,
|
||||
useTheme,
|
||||
} from 'react-native-paper'
|
||||
import SInfo from 'react-native-sensitive-info'
|
||||
import Logo from '../Logo'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||
@ -19,11 +20,11 @@ import { navigate } from '../../lib/Navigation'
|
||||
import { usernamePubKey } from '../../Functions/RelayFunctions/Users'
|
||||
import ProfileData from '../ProfileData'
|
||||
import { WalletContext } from '../../Contexts/WalletContext'
|
||||
import { AppContext } from '../../Contexts/AppContext'
|
||||
import { AppContext, type Config } from '../../Contexts/AppContext'
|
||||
|
||||
export const MenuItems: React.FC = () => {
|
||||
const [drawerItemIndex, setDrawerItemIndex] = React.useState<number>(-1)
|
||||
const { getSatoshiSymbol } = React.useContext(AppContext)
|
||||
const { getSatoshiSymbol, online } = React.useContext(AppContext)
|
||||
const { relays } = React.useContext(RelayPoolContext)
|
||||
const { balance, type } = React.useContext(WalletContext)
|
||||
const {
|
||||
@ -40,13 +41,19 @@ export const MenuItems: React.FC = () => {
|
||||
} = React.useContext(UserContext)
|
||||
const { t } = useTranslation('common')
|
||||
const theme = useTheme()
|
||||
const { switchLine } = React.useContext(RelayPoolContext)
|
||||
|
||||
const [activerelays, setActiveRelays] = React.useState<number>(0)
|
||||
const [loadingConnection, setLoadingConnection] = React.useState<boolean>(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
setActiveRelays(relays.filter((relay) => relay.active).length)
|
||||
}, [relays, balance])
|
||||
|
||||
React.useEffect(() => {
|
||||
setLoadingConnection(false)
|
||||
}, [online])
|
||||
|
||||
const onPressLogout: () => void = () => {
|
||||
logout()
|
||||
}
|
||||
@ -72,6 +79,10 @@ export const MenuItems: React.FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
setLoadingConnection(false)
|
||||
}, [online])
|
||||
|
||||
return (
|
||||
<>
|
||||
<DrawerContentScrollView
|
||||
@ -136,7 +147,7 @@ export const MenuItems: React.FC = () => {
|
||||
onPress={() => onPressItem('relays', 0)}
|
||||
onTouchEnd={() => setDrawerItemIndex(-1)}
|
||||
right={() =>
|
||||
activerelays < 1 ? (
|
||||
activerelays < 1 || !online ? (
|
||||
<Text style={{ color: theme.colors.error }}>{t('menuItems.notConnected')}</Text>
|
||||
) : (
|
||||
<Text style={{ color: '#7ADC70' }}>
|
||||
@ -220,9 +231,38 @@ export const MenuItems: React.FC = () => {
|
||||
/>
|
||||
</Drawer.Section>
|
||||
</DrawerContentScrollView>
|
||||
<Drawer.Section
|
||||
style={[
|
||||
styles.section,
|
||||
{
|
||||
backgroundColor: theme.colors.background,
|
||||
},
|
||||
]}
|
||||
showDivider={false}
|
||||
>
|
||||
<Button
|
||||
mode='outlined'
|
||||
onPress={() => {
|
||||
setLoadingConnection(true)
|
||||
switchLine()
|
||||
}}
|
||||
loading={loadingConnection}
|
||||
textColor={theme.colors.onSurface}
|
||||
icon={() => (
|
||||
<MaterialCommunityIcons
|
||||
name={online ? 'web' : 'web-off'}
|
||||
size={20}
|
||||
style={online ? { color: '#7ADC70' } : { color: theme.colors.error }}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{t(online ? 'menuItems.online' : 'menuItems.offline')}
|
||||
</Button>
|
||||
</Drawer.Section>
|
||||
{publicKey && (
|
||||
<Drawer.Section
|
||||
style={[
|
||||
styles.section,
|
||||
styles.bottomSection,
|
||||
{
|
||||
backgroundColor: theme.colors.background,
|
||||
@ -281,10 +321,14 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'flex-end',
|
||||
flex: 1,
|
||||
},
|
||||
bottomSection: {
|
||||
section: {
|
||||
marginBottom: 0,
|
||||
paddingBottom: 24,
|
||||
paddingLeft: 24,
|
||||
paddingRight: 24
|
||||
},
|
||||
bottomSection: {
|
||||
borderBottomRightRadius: 28,
|
||||
padding: 24,
|
||||
},
|
||||
username: {
|
||||
flexDirection: 'row',
|
||||
|
@ -79,6 +79,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
showSensitive,
|
||||
relayColouring,
|
||||
longPressZap,
|
||||
online
|
||||
} = useContext(AppContext)
|
||||
const [relayAdded, setRelayAdded] = useState<boolean>(false)
|
||||
const [positiveReactions, setPositiveReactions] = useState<number>(0)
|
||||
@ -127,7 +128,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
const bTags = getBitcoinTag(note)
|
||||
setBitcoinTag(bTags[bTags.length - 1] ?? undefined)
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (database && note) {
|
||||
|
@ -20,6 +20,7 @@ export interface Config {
|
||||
relay_coloruring: boolean
|
||||
long_press_zap: number | undefined
|
||||
sign_height: boolean
|
||||
online: boolean
|
||||
}
|
||||
|
||||
export interface AppContextProps {
|
||||
@ -58,6 +59,8 @@ export interface AppContextProps {
|
||||
setQrReader: (qrReader: string | undefined) => void
|
||||
signHeight: boolean
|
||||
setSignWithHeight: (signHeight: boolean) => void
|
||||
online: boolean
|
||||
setOnline: (online: boolean) => void
|
||||
}
|
||||
|
||||
export interface AppContextProviderProps {
|
||||
@ -99,7 +102,9 @@ export const initialAppContext: AppContextProps = {
|
||||
longPressZap: undefined,
|
||||
setLongPressZap: () => {},
|
||||
signHeight: false,
|
||||
setSignWithHeight: () => {}
|
||||
setSignWithHeight: () => {},
|
||||
online: true,
|
||||
setOnline: () => {}
|
||||
}
|
||||
|
||||
export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.Element => {
|
||||
@ -128,6 +133,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
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)
|
||||
|
||||
useEffect(() => {
|
||||
if (pushedTab) setPushedTab(undefined)
|
||||
@ -176,6 +182,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
setLongPressZap(config.long_press_zap ?? initialAppContext.longPressZap)
|
||||
setRelayColouring(config.relay_coloruring ?? initialAppContext.relayColouring)
|
||||
setSignWithHeight(config.sign_height ?? initialAppContext.signHeight)
|
||||
setOnline(config.online ?? initialAppContext.online)
|
||||
} else {
|
||||
const config: Config = {
|
||||
show_public_images: initialAppContext.showPublicImages,
|
||||
@ -188,6 +195,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
relay_coloruring: initialAppContext.relayColouring,
|
||||
long_press_zap: initialAppContext.longPressZap,
|
||||
sign_height: initialAppContext.signHeight,
|
||||
online: initialAppContext.online,
|
||||
}
|
||||
SInfo.setItem('config', JSON.stringify(config), {})
|
||||
}
|
||||
@ -226,6 +234,14 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
SInfo.getItem('config', {}).then((result) => {
|
||||
const config: Config = JSON.parse(result)
|
||||
config.online = online
|
||||
SInfo.setItem('config', JSON.stringify(config), {})
|
||||
})
|
||||
}, [online])
|
||||
|
||||
useEffect(init, [])
|
||||
|
||||
return (
|
||||
@ -264,7 +280,9 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
||||
qrReader,
|
||||
setQrReader,
|
||||
signHeight,
|
||||
setSignWithHeight
|
||||
setSignWithHeight,
|
||||
online,
|
||||
setOnline
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -34,6 +34,7 @@ export interface RelayPoolContextProps {
|
||||
setNewGroupMessages: (newGroupMessages: number) => void
|
||||
relayPay: PayEvent[]
|
||||
setRelayPay: (invoices: PayEvent[]) => void
|
||||
switchLine: () => void
|
||||
}
|
||||
|
||||
export interface WebsocketEvent {
|
||||
@ -73,14 +74,15 @@ export const initialRelayPoolContext: RelayPoolContextProps = {
|
||||
newGroupMessages: 0,
|
||||
setNewGroupMessages: () => {},
|
||||
relayPay: [],
|
||||
setRelayPay: () => {}
|
||||
setRelayPay: () => {},
|
||||
switchLine: () => {}
|
||||
}
|
||||
|
||||
export const RelayPoolContextProvider = ({
|
||||
children,
|
||||
images,
|
||||
}: RelayPoolContextProviderProps): JSX.Element => {
|
||||
const { database, signHeight } = useContext(AppContext)
|
||||
const { database, signHeight, online, setOnline } = useContext(AppContext)
|
||||
const { publicKey, privateKey } = React.useContext(UserContext)
|
||||
const [relayPool, setRelayPool] = useState<RelayPool>()
|
||||
const [relayPoolReady, setRelayPoolReady] = useState<boolean>(false)
|
||||
@ -209,8 +211,8 @@ export const RelayPoolContextProvider = ({
|
||||
|
||||
const loadRelayPool: () => void = async () => {
|
||||
if (database && publicKey) {
|
||||
const initRelayPool = new RelayPool(privateKey)
|
||||
initRelayPool.connect(publicKey, () => {
|
||||
const initRelayPool = new RelayPool(online, privateKey)
|
||||
initRelayPool.switchLine(online, publicKey, () => {
|
||||
setRelayPool(initRelayPool)
|
||||
})
|
||||
}
|
||||
@ -292,6 +294,12 @@ export const RelayPoolContextProvider = ({
|
||||
randomrelays.forEach(async (url) => await addRelayItem({ url }))
|
||||
}
|
||||
|
||||
const switchLine: () => void = () => {
|
||||
if (relayPool && publicKey) {
|
||||
relayPool.switchLine(!online, publicKey, () => setOnline(!online))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (publicKey && publicKey !== '') {
|
||||
DeviceEventEmitter.addListener('WebsocketEvent', debouncedEventIdHandler)
|
||||
@ -346,7 +354,8 @@ export const RelayPoolContextProvider = ({
|
||||
newGroupMessages,
|
||||
setNewGroupMessages,
|
||||
relayPay,
|
||||
setRelayPay
|
||||
setRelayPay,
|
||||
switchLine
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -157,7 +157,9 @@
|
||||
"faq": "FAQ",
|
||||
"reportBug": "Bug melden",
|
||||
"logout": "Abmelden",
|
||||
"exports": "Export"
|
||||
"exports": "Export",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"configPage": {
|
||||
"signHeight": "Sign events with latest Bitcoin block",
|
||||
|
@ -152,7 +152,9 @@
|
||||
"contacts": "Contacts",
|
||||
"reportBug": "Report a bug",
|
||||
"logout": "Logout",
|
||||
"exports": "Export"
|
||||
"exports": "Export",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"configPage": {
|
||||
"showPublicImages": "Show images on public feed",
|
||||
|
@ -178,7 +178,9 @@
|
||||
"faq": "Preguntas frecuentes",
|
||||
"reportBug": "Reportar un bug",
|
||||
"logout": "Salir",
|
||||
"exports": "Exportar/Importar"
|
||||
"exports": "Exportar/Importar",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"configPage": {
|
||||
"signHeight": "Firmar con el último bloque bitcoin",
|
||||
|
@ -178,7 +178,9 @@
|
||||
"faq": "FAQ",
|
||||
"reportBug": "Report a bug",
|
||||
"logout": "Sortir",
|
||||
"exports": "Export"
|
||||
"exports": "Export",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"language": {
|
||||
"en": "English",
|
||||
|
@ -179,7 +179,9 @@
|
||||
"logout": "Выйти",
|
||||
"reportBug": "Report a bug",
|
||||
"imageHostingService": "Хостинг изображений",
|
||||
"exports": "Export"
|
||||
"exports": "Export",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"configPage": {
|
||||
"signHeight": "Sign events with latest Bitcoin block",
|
||||
|
@ -177,7 +177,9 @@
|
||||
"faq": "常见问题",
|
||||
"reportBug": "反馈问题",
|
||||
"logout": "退出",
|
||||
"exports": "Export"
|
||||
"exports": "Export",
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"configPage": {
|
||||
"signHeight": "用最新的比特币区块签署事件",
|
||||
|
@ -37,7 +37,7 @@ export const ContactsPage: React.FC = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const theme = useTheme()
|
||||
const initialPageSize = 20
|
||||
const { database, setDisplayUserDrawer, qrReader, setQrReader } = useContext(AppContext)
|
||||
const { database, setDisplayUserDrawer, 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)
|
||||
@ -73,7 +73,7 @@ export const ContactsPage: React.FC = () => {
|
||||
reloadLists()
|
||||
loadUsers()
|
||||
subscribeContacts()
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
loadUsers()
|
||||
|
@ -51,7 +51,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
const theme = useTheme()
|
||||
const scrollViewRef = useRef<ScrollView>()
|
||||
const { database, setRefreshBottomBarAt, setDisplayUserDrawer } = useContext(AppContext)
|
||||
const { relayPool, lastEventId, sendEvent } = useContext(RelayPoolContext)
|
||||
const { relayPool, lastEventId, sendEvent, online } = useContext(RelayPoolContext)
|
||||
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
|
||||
const otherPubKey = useMemo(() => route.params.pubKey, [])
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
@ -83,7 +83,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
|
||||
useEffect(() => {
|
||||
loadDirectMessages(false)
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
const loadDirectMessages: (subscribe: boolean) => void = (subscribe) => {
|
||||
if (database && publicKey && privateKey) {
|
||||
|
@ -15,7 +15,7 @@ export const ExternalIdentitiesPage: React.FC = () => {
|
||||
const theme = useTheme()
|
||||
const { database } = React.useContext(AppContext)
|
||||
const { publicKey } = React.useContext(UserContext)
|
||||
const { lastEventId, sendEvent } = React.useContext(RelayPoolContext)
|
||||
const { lastEventId, sendEvent, online } = React.useContext(RelayPoolContext)
|
||||
|
||||
const [user, setUser] = React.useState<User>()
|
||||
const [showNotification, setShowNotification] = React.useState<string>()
|
||||
@ -49,7 +49,7 @@ export const ExternalIdentitiesPage: React.FC = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [user, lastEventId])
|
||||
}, [user, lastEventId, online])
|
||||
|
||||
const services: Record<
|
||||
string,
|
||||
|
@ -46,7 +46,7 @@ interface GroupPageProps {
|
||||
export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
const initialPageSize = 20
|
||||
const theme = useTheme()
|
||||
const { database, setDisplayUserDrawer } = useContext(AppContext)
|
||||
const { database, setDisplayUserDrawer, online } = useContext(AppContext)
|
||||
const { relayPool, lastEventId, sendEvent } = useContext(RelayPoolContext)
|
||||
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
@ -75,7 +75,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
|
||||
useEffect(() => {
|
||||
loadGroupMessages(false)
|
||||
}, [lastEventId, pageSize])
|
||||
}, [lastEventId, pageSize, online])
|
||||
|
||||
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
|
||||
if (database && publicKey && route.params.groupId) {
|
||||
|
@ -44,7 +44,7 @@ export const ConversationsFeed: React.FC = () => {
|
||||
const initialPageSize = 14
|
||||
const theme = useTheme()
|
||||
const { t } = useTranslation('common')
|
||||
const { database, refreshBottomBarAt, qrReader, setQrReader } = useContext(AppContext)
|
||||
const { database, refreshBottomBarAt, qrReader, setQrReader, online } = useContext(AppContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const { publicKey, privateKey } = useContext(UserContext)
|
||||
const { relayPool, lastEventId, setNewDirectMessages, newDirectMessages } = useContext(RelayPoolContext)
|
||||
@ -71,7 +71,7 @@ export const ConversationsFeed: React.FC = () => {
|
||||
useEffect(() => {
|
||||
setNewDirectMessages(0)
|
||||
loadDirectMessages(false)
|
||||
}, [lastEventId, refreshBottomBarAt, newDirectMessages])
|
||||
}, [lastEventId, refreshBottomBarAt, newDirectMessages, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (qrReader) {
|
||||
|
@ -41,7 +41,7 @@ import DatabaseModule from '../../../lib/Native/DatabaseModule'
|
||||
export const GroupsFeed: React.FC = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const theme = useTheme()
|
||||
const { database, qrReader, setQrReader, refreshBottomBarAt } = useContext(AppContext)
|
||||
const { database, qrReader, setQrReader, refreshBottomBarAt, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { relayPool, lastEventId, lastConfirmationtId, sendEvent, setNewGroupMessages, newGroupMessages } = useContext(RelayPoolContext)
|
||||
const bottomSheetSearchRef = React.useRef<RBSheet>(null)
|
||||
@ -72,7 +72,7 @@ export const GroupsFeed: React.FC = () => {
|
||||
useEffect(() => {
|
||||
setNewGroupMessages(0)
|
||||
loadGroups()
|
||||
}, [lastEventId, lastConfirmationtId, refreshBottomBarAt])
|
||||
}, [lastEventId, lastConfirmationtId, refreshBottomBarAt, online])
|
||||
|
||||
useEffect(() => {
|
||||
setNewGroupMessages(0)
|
||||
|
@ -15,43 +15,34 @@ import { Kind } from 'nostr-tools'
|
||||
import { type RelayFilters } from '../../../../lib/nostr/RelayPool/intex'
|
||||
import { ActivityIndicator, Button, Text } from 'react-native-paper'
|
||||
import NoteCard from '../../../../Components/NoteCard'
|
||||
import { useTheme } from '@react-navigation/native'
|
||||
import { useFocusEffect, useTheme } from '@react-navigation/native'
|
||||
import { FlashList, type ListRenderItem } from '@shopify/flash-list'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { getContactsCount } from '../../../../Functions/DatabaseFunctions/Users'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
|
||||
interface BookmarksFeedProps {
|
||||
navigation: any
|
||||
updateLastLoad: () => void
|
||||
pageSize: number
|
||||
setPageSize: (pageSize: number) => void
|
||||
activeTab: string
|
||||
}
|
||||
|
||||
export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
navigation,
|
||||
updateLastLoad,
|
||||
pageSize,
|
||||
setPageSize,
|
||||
activeTab,
|
||||
}) => {
|
||||
export const BookmarksFeed: React.FC = () => {
|
||||
const initialPageSize = 10
|
||||
const theme = useTheme()
|
||||
const { t } = useTranslation('common')
|
||||
const { database, pushedTab } = useContext(AppContext)
|
||||
const { database, pushedTab, online } = useContext(AppContext)
|
||||
const { publicKey, publicBookmarks, privateBookmarks, reloadBookmarks } = useContext(UserContext)
|
||||
const { lastEventId, relayPool, lastConfirmationtId } = useContext(RelayPoolContext)
|
||||
const initialPageSize = 10
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||
const [contactsCount, setContactsCount] = useState<number>()
|
||||
const [filter, setFilter] = useState<'private' | 'public'>('private')
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const flashListRef = React.useRef<FlashList<Note>>(null)
|
||||
|
||||
useEffect(() => {
|
||||
reloadBookmarks()
|
||||
}, [])
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setPageSize(initialPageSize)
|
||||
|
||||
return () => {}
|
||||
}, []),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (pushedTab) {
|
||||
@ -60,7 +51,7 @@ export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
}, [pushedTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (relayPool && publicKey && database && activeTab === 'bookmarks') {
|
||||
if (relayPool && publicKey && database) {
|
||||
if (!contactsCount) getContactsCount(database).then(setContactsCount)
|
||||
loadNotes()
|
||||
}
|
||||
@ -71,9 +62,9 @@ export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
relayPool,
|
||||
publicKey,
|
||||
database,
|
||||
activeTab,
|
||||
publicBookmarks,
|
||||
privateBookmarks,
|
||||
online
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
@ -85,7 +76,8 @@ export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
|
||||
const onRefresh = useCallback(() => {
|
||||
setRefreshing(true)
|
||||
updateLastLoad()
|
||||
loadNotes()
|
||||
reloadBookmarks()
|
||||
}, [])
|
||||
|
||||
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
|
||||
|
@ -20,37 +20,45 @@ import { Kind } from 'nostr-tools'
|
||||
import { type RelayFilters } from '../../../../lib/nostr/RelayPool/intex'
|
||||
import { Chip, Button, Text } from 'react-native-paper'
|
||||
import NoteCard from '../../../../Components/NoteCard'
|
||||
import { useTheme } from '@react-navigation/native'
|
||||
import { useFocusEffect, useTheme } from '@react-navigation/native'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { t } from 'i18next'
|
||||
import { FlashList, type ListRenderItem } from '@shopify/flash-list'
|
||||
import { getUnixTime } from 'date-fns'
|
||||
|
||||
interface GlobalFeedProps {
|
||||
navigation: any
|
||||
updateLastLoad: () => void
|
||||
lastLoadAt: number
|
||||
pageSize: number
|
||||
setPageSize: (pageSize: number) => void
|
||||
activeTab: string
|
||||
}
|
||||
|
||||
export const GlobalFeed: React.FC<GlobalFeedProps> = ({
|
||||
navigation,
|
||||
updateLastLoad,
|
||||
lastLoadAt,
|
||||
pageSize,
|
||||
setPageSize,
|
||||
activeTab,
|
||||
navigation
|
||||
}) => {
|
||||
const initialPageSize = 10
|
||||
const theme = useTheme()
|
||||
const { database, showPublicImages, pushedTab } = useContext(AppContext)
|
||||
const { database, showPublicImages, pushedTab, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { lastEventId, relayPool, lastConfirmationtId } = useContext(RelayPoolContext)
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
const [newNotesCount, setNewNotesCount] = useState<number>(0)
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
const flashListRef = React.useRef<FlashList<Note>>(null)
|
||||
const [lastLoadAt, setLastLoadAt] = useState<number>(0)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setPageSize(initialPageSize)
|
||||
|
||||
return () => {}
|
||||
}, []),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (pageSize > initialPageSize) {
|
||||
updateLastLoad()
|
||||
loadNotes(true)
|
||||
}
|
||||
}, [pageSize, lastLoadAt])
|
||||
|
||||
useEffect(() => {
|
||||
if (pushedTab) {
|
||||
@ -59,19 +67,18 @@ export const GlobalFeed: React.FC<GlobalFeedProps> = ({
|
||||
}, [pushedTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (relayPool && publicKey && activeTab === 'globalFeed') {
|
||||
if (relayPool && publicKey) {
|
||||
loadNotes()
|
||||
}
|
||||
}, [lastEventId, lastConfirmationtId, lastLoadAt, relayPool, publicKey, activeTab])
|
||||
}, [lastEventId, lastConfirmationtId, relayPool, publicKey, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (pageSize > initialPageSize) {
|
||||
loadNotes(true)
|
||||
}
|
||||
}, [pageSize])
|
||||
const updateLastLoad: () => void = () => {
|
||||
setLastLoadAt(getUnixTime(new Date()) - 5)
|
||||
}
|
||||
|
||||
const onRefresh = useCallback(() => {
|
||||
setRefreshing(true)
|
||||
loadNotes()
|
||||
setNewNotesCount(0)
|
||||
updateLastLoad()
|
||||
flashListRef.current?.scrollToIndex({ animated: true, index: 0 })
|
||||
|
@ -15,7 +15,7 @@ import { Kind } from 'nostr-tools'
|
||||
import { type RelayFilters } from '../../../../lib/nostr/RelayPool/intex'
|
||||
import { ActivityIndicator, Button, Text } from 'react-native-paper'
|
||||
import NoteCard from '../../../../Components/NoteCard'
|
||||
import { useTheme } from '@react-navigation/native'
|
||||
import { useFocusEffect, useTheme } from '@react-navigation/native'
|
||||
import { FlashList, type ListRenderItem } from '@shopify/flash-list'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -27,29 +27,29 @@ import {
|
||||
|
||||
interface MyFeedProps {
|
||||
navigation: any
|
||||
updateLastLoad: () => void
|
||||
pageSize: number
|
||||
setPageSize: (pageSize: number) => void
|
||||
activeTab: string
|
||||
}
|
||||
|
||||
export const MyFeed: React.FC<MyFeedProps> = ({
|
||||
navigation,
|
||||
updateLastLoad,
|
||||
pageSize,
|
||||
setPageSize,
|
||||
activeTab,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const initialPageSize = 10
|
||||
const { t } = useTranslation('common')
|
||||
const { database, pushedTab } = useContext(AppContext)
|
||||
const { database, pushedTab, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { lastEventId, relayPool, lastConfirmationtId } = useContext(RelayPoolContext)
|
||||
const initialPageSize = 10
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||
const [contactsCount, setContactsCount] = useState<number>()
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const flashListRef = React.useRef<FlashList<Note>>(null)
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setPageSize(initialPageSize)
|
||||
return () => {}
|
||||
}, []),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (pushedTab) {
|
||||
@ -58,11 +58,11 @@ export const MyFeed: React.FC<MyFeedProps> = ({
|
||||
}, [pushedTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (relayPool && publicKey && database && activeTab === 'myFeed') {
|
||||
if (relayPool && publicKey && database) {
|
||||
if (!contactsCount) getContactsCount(database).then(setContactsCount)
|
||||
loadNotes()
|
||||
}
|
||||
}, [lastEventId, lastConfirmationtId, relayPool, publicKey, database, activeTab])
|
||||
}, [lastEventId, lastConfirmationtId, relayPool, publicKey, database, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (pageSize > initialPageSize) {
|
||||
@ -72,7 +72,7 @@ export const MyFeed: React.FC<MyFeedProps> = ({
|
||||
|
||||
const onRefresh = useCallback(() => {
|
||||
setRefreshing(true)
|
||||
updateLastLoad()
|
||||
loadNotes()
|
||||
}, [])
|
||||
|
||||
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
|
||||
|
@ -15,7 +15,7 @@ import { Kind } from 'nostr-tools'
|
||||
import { type RelayFilters } from '../../../../lib/nostr/RelayPool/intex'
|
||||
import { ActivityIndicator, Button, Text } from 'react-native-paper'
|
||||
import NoteCard from '../../../../Components/NoteCard'
|
||||
import { useTheme } from '@react-navigation/native'
|
||||
import { useFocusEffect, useTheme } from '@react-navigation/native'
|
||||
import { FlashList, type ListRenderItem } from '@shopify/flash-list'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -25,28 +25,29 @@ import { getUsers, type User } from '../../../../Functions/DatabaseFunctions/Use
|
||||
|
||||
interface ZapsFeedProps {
|
||||
navigation: any
|
||||
updateLastLoad: () => void
|
||||
pageSize: number
|
||||
setPageSize: (pageSize: number) => void
|
||||
activeTab: string
|
||||
}
|
||||
|
||||
export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
navigation,
|
||||
updateLastLoad,
|
||||
pageSize,
|
||||
setPageSize,
|
||||
activeTab,
|
||||
navigation
|
||||
}) => {
|
||||
const initialPageSize = 10
|
||||
const theme = useTheme()
|
||||
const { t } = useTranslation('common')
|
||||
const { database, pushedTab } = useContext(AppContext)
|
||||
const { database, pushedTab, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { lastEventId, relayPool, lastConfirmationtId } = useContext(RelayPoolContext)
|
||||
const initialPageSize = 10
|
||||
const [notes, setNotes] = useState<Note[]>()
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
const flashListRef = React.useRef<FlashList<Note>>(null)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
setPageSize(initialPageSize)
|
||||
|
||||
return () => {}
|
||||
}, []),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (pushedTab) {
|
||||
@ -55,10 +56,10 @@ export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
}, [pushedTab])
|
||||
|
||||
useEffect(() => {
|
||||
if (relayPool && publicKey && activeTab === 'zaps') {
|
||||
if (relayPool && publicKey) {
|
||||
loadNotes()
|
||||
}
|
||||
}, [lastEventId, lastConfirmationtId, relayPool, publicKey, activeTab])
|
||||
}, [lastEventId, lastConfirmationtId, relayPool, publicKey, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (pageSize > initialPageSize) {
|
||||
@ -68,7 +69,7 @@ export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
|
||||
const onRefresh = useCallback(() => {
|
||||
setRefreshing(true)
|
||||
updateLastLoad()
|
||||
loadNotes()
|
||||
}, [])
|
||||
|
||||
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
|
||||
@ -85,6 +86,7 @@ export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
{
|
||||
kinds: [9735],
|
||||
'#p': contacts,
|
||||
since: getUnixTime(new Date()) - 86400
|
||||
},
|
||||
])
|
||||
|
||||
|
@ -1,34 +1,47 @@
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import React, { useContext, useEffect } from 'react'
|
||||
import { Dimensions, StyleSheet, View } from 'react-native'
|
||||
import { UserContext } from '../../../Contexts/UserContext'
|
||||
import { RelayPoolContext } from '../../../Contexts/RelayPoolContext'
|
||||
import { AnimatedFAB } from 'react-native-paper'
|
||||
import { useFocusEffect } from '@react-navigation/native'
|
||||
import { navigate } from '../../../lib/Navigation'
|
||||
import GlobalFeed from './GlobalFeed'
|
||||
import MyFeed from './MyFeed'
|
||||
import { getUnixTime } from 'date-fns'
|
||||
import { AppContext } from '../../../Contexts/AppContext'
|
||||
import Tabs from '../../../Components/Tabs'
|
||||
import ZapsFeed from './ZapsFeed'
|
||||
import BookmarksFeed from './BookmarksFeed'
|
||||
import { RelayPoolContext } from '../../../Contexts/RelayPoolContext'
|
||||
|
||||
interface HomeFeedProps {
|
||||
navigation: any
|
||||
}
|
||||
|
||||
export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
|
||||
const initialPageSize = 10
|
||||
const { database } = useContext(AppContext)
|
||||
const { privateKey, publicKey } = useContext(UserContext)
|
||||
const { relayPool } = useContext(RelayPoolContext)
|
||||
const [activeTab, setActiveTab] = React.useState('myFeed')
|
||||
const [prevTab, setPrevTab] = React.useState('')
|
||||
const [lastLoadAt, setLastLoadAt] = useState<number>(0)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
|
||||
const unsubscribe: () => void = () => {
|
||||
if (prevTab === 'zaps') {
|
||||
useEffect(() => {
|
||||
if (activeTab !== 'myFeed') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-myfeed-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-myfeed-reposts${publicKey?.substring(0, 8)}`,
|
||||
`homepage-myfeed-reaction${publicKey?.substring(0, 8)}`
|
||||
])
|
||||
}
|
||||
if (activeTab !== 'bookmarks') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-bookmarks-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-bookmarks-reactions${publicKey?.substring(0, 8)}`,
|
||||
`homepage-bookmarks-reposts${publicKey?.substring(0, 8)}`,
|
||||
])
|
||||
}
|
||||
if (activeTab !== 'globalFeed') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-global-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-global-reposts${publicKey?.substring(0, 8)}`,
|
||||
`homepage-global-reactions${publicKey?.substring(0, 8)}`
|
||||
])
|
||||
}
|
||||
if (activeTab !== 'zaps') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-zaps-notes${publicKey?.substring(0, 8)}`,
|
||||
`homepage-zaps-reactions${publicKey?.substring(0, 8)}`,
|
||||
@ -36,91 +49,26 @@ export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
|
||||
`homepage-zaps-main${publicKey?.substring(0, 8)}`,
|
||||
])
|
||||
}
|
||||
if (prevTab === 'myFeed') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-myfeed-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-myfeed-reposts${publicKey?.substring(0, 8)}`,
|
||||
`homepage-myfeed-reaction${publicKey?.substring(0, 8)}`
|
||||
])
|
||||
}
|
||||
if (prevTab === 'globalFeed') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-global-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-global-reposts${publicKey?.substring(0, 8)}`,
|
||||
`homepage-global-reactions${publicKey?.substring(0, 8)}`
|
||||
])
|
||||
}
|
||||
if (prevTab === 'bookmarks') {
|
||||
relayPool?.unsubscribe([
|
||||
`homepage-bookmarks-main${publicKey?.substring(0, 8)}`,
|
||||
`homepage-bookmarks-reactions${publicKey?.substring(0, 8)}`,
|
||||
`homepage-bookmarks-reposts${publicKey?.substring(0, 8)}`,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
useFocusEffect(
|
||||
React.useCallback(() => {
|
||||
updateLastLoad()
|
||||
|
||||
return unsubscribe
|
||||
}, []),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (database && relayPool) {
|
||||
if (prevTab !== '') unsubscribe()
|
||||
setPrevTab(activeTab)
|
||||
}
|
||||
}, [activeTab, database, relayPool])
|
||||
|
||||
useEffect(() => {
|
||||
if (pageSize > initialPageSize) {
|
||||
updateLastLoad()
|
||||
}
|
||||
}, [pageSize, lastLoadAt])
|
||||
|
||||
const updateLastLoad: () => void = () => {
|
||||
setLastLoadAt(getUnixTime(new Date()) - 5)
|
||||
}
|
||||
}, [activeTab])
|
||||
|
||||
const renderScene: Record<string, JSX.Element> = {
|
||||
globalFeed: (
|
||||
<GlobalFeed
|
||||
navigation={navigation}
|
||||
updateLastLoad={updateLastLoad}
|
||||
lastLoadAt={lastLoadAt}
|
||||
pageSize={pageSize}
|
||||
setPageSize={setPageSize}
|
||||
activeTab={activeTab}
|
||||
/>
|
||||
),
|
||||
myFeed: (
|
||||
<MyFeed
|
||||
navigation={navigation}
|
||||
updateLastLoad={updateLastLoad}
|
||||
pageSize={pageSize}
|
||||
setPageSize={setPageSize}
|
||||
activeTab={activeTab}
|
||||
/>
|
||||
),
|
||||
zaps: (
|
||||
<ZapsFeed
|
||||
navigation={navigation}
|
||||
updateLastLoad={updateLastLoad}
|
||||
pageSize={pageSize}
|
||||
setPageSize={setPageSize}
|
||||
activeTab={activeTab}
|
||||
/>
|
||||
),
|
||||
bookmarks: (
|
||||
<BookmarksFeed
|
||||
navigation={navigation}
|
||||
updateLastLoad={updateLastLoad}
|
||||
pageSize={pageSize}
|
||||
setPageSize={setPageSize}
|
||||
activeTab={activeTab}
|
||||
/>
|
||||
<BookmarksFeed />
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,13 @@ import { getTaggedEventIds } from '../../../Functions/RelayFunctions/Events'
|
||||
import ParsedText from 'react-native-parsed-text'
|
||||
import { getUser } from '../../../Functions/DatabaseFunctions/Users'
|
||||
import { getNpub } from '../../../lib/nostr/Nip19'
|
||||
import { RelayFilters } from '../../../lib/nostr/RelayPool/intex'
|
||||
import { type RelayFilters } from '../../../lib/nostr/RelayPool/intex'
|
||||
|
||||
export const NotificationsFeed: React.FC = () => {
|
||||
const initialLimitPage = React.useMemo(() => 20, [])
|
||||
const theme = useTheme()
|
||||
const { t } = useTranslation('common')
|
||||
const { database, setNotificationSeenAt, pushedTab, getSatoshiSymbol } = useContext(AppContext)
|
||||
const { database, setNotificationSeenAt, pushedTab, getSatoshiSymbol, online } = useContext(AppContext)
|
||||
const { publicKey, reloadLists, mutedEvents, mutedUsers } = useContext(UserContext)
|
||||
const { lastEventId, relayPool, setNewNotifications, newNotifications } = useContext(RelayPoolContext)
|
||||
const [notifications, setNotifications] = useState<Notification[]>([])
|
||||
@ -52,10 +52,7 @@ export const NotificationsFeed: React.FC = () => {
|
||||
loadNotes()
|
||||
updateLastSeen()
|
||||
return () => {
|
||||
relayPool?.unsubscribe([
|
||||
`notification-feed${publicKey?.substring(0, 8)}`,
|
||||
`notification-users${publicKey?.substring(0, 8)}`,
|
||||
])
|
||||
unsubscribe()
|
||||
updateLastSeen()
|
||||
}
|
||||
}, []),
|
||||
@ -66,7 +63,7 @@ export const NotificationsFeed: React.FC = () => {
|
||||
reloadLists()
|
||||
setRefreshing(false)
|
||||
setNewNotifications(0)
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
setNewNotifications(0)
|
||||
@ -82,6 +79,13 @@ export const NotificationsFeed: React.FC = () => {
|
||||
}
|
||||
}, [pushedTab])
|
||||
|
||||
const unsubscribe: () => void = () => {
|
||||
relayPool?.unsubscribe([
|
||||
`notification-feed${publicKey?.substring(0, 8)}`,
|
||||
`notification-users${publicKey?.substring(0, 8)}`,
|
||||
])
|
||||
}
|
||||
|
||||
const updateLastSeen: () => void = () => {
|
||||
const unixtime = getUnixTime(new Date())
|
||||
setNotificationSeenAt(unixtime)
|
||||
@ -154,6 +158,7 @@ export const NotificationsFeed: React.FC = () => {
|
||||
const onRefresh = useCallback(() => {
|
||||
setRefreshing(true)
|
||||
if (relayPool && publicKey) {
|
||||
unsubscribe()
|
||||
subscribeNotes()
|
||||
}
|
||||
}, [])
|
||||
|
@ -27,7 +27,7 @@ export const NoteActionsPage: React.FC<NoteActionsPageProps> = ({ route: { param
|
||||
privateBookmarks,
|
||||
mutedEvents,
|
||||
} = React.useContext(UserContext)
|
||||
const { database, displayNoteDrawer, relayColouring } = React.useContext(AppContext)
|
||||
const { database, displayNoteDrawer, relayColouring, online } = React.useContext(AppContext)
|
||||
const { relayPool, setDisplayrelayDrawer, lastEventId, sendEvent } =
|
||||
React.useContext(RelayPoolContext)
|
||||
const [relays, setRelays] = React.useState<NoteRelay[]>([])
|
||||
@ -39,7 +39,7 @@ export const NoteActionsPage: React.FC<NoteActionsPageProps> = ({ route: { param
|
||||
|
||||
React.useEffect(() => {
|
||||
loadNoteRelays()
|
||||
}, [displayNoteDrawer, lastEventId, bookmarked, isMuted])
|
||||
}, [displayNoteDrawer, lastEventId, bookmarked, isMuted, online])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (note) {
|
||||
|
@ -22,7 +22,7 @@ interface NotePageProps {
|
||||
}
|
||||
|
||||
export const NotePage: React.FC<NotePageProps> = ({ route }) => {
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { publicKey, privateKey } = useContext(UserContext)
|
||||
const { relayPool, lastEventId } = useContext(RelayPoolContext)
|
||||
const [note, setNote] = useState<Note>()
|
||||
@ -46,7 +46,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
|
||||
useEffect(() => {
|
||||
loadNote()
|
||||
loadGroup()
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
const loadGroup: () => void = async () => {
|
||||
if (database) {
|
||||
|
@ -27,7 +27,7 @@ interface ProfileActionsProps {
|
||||
|
||||
export const ProfileActionsPage: React.FC<ProfileActionsProps> = ({ route: { params: { userId } } }) => {
|
||||
const theme = useTheme()
|
||||
const { database, longPressZap } = React.useContext(AppContext)
|
||||
const { database, longPressZap, online } = React.useContext(AppContext)
|
||||
const { publicKey, privateKey, mutedUsers } = React.useContext(UserContext)
|
||||
const { relayPool, addRelayItem, lastEventId, sendEvent, relays } =
|
||||
React.useContext(RelayPoolContext)
|
||||
@ -60,7 +60,7 @@ export const ProfileActionsPage: React.FC<ProfileActionsProps> = ({ route: { par
|
||||
React.useEffect(() => {
|
||||
loadUser()
|
||||
loadRelays()
|
||||
}, [lastEventId, isMuted])
|
||||
}, [lastEventId, isMuted, online])
|
||||
|
||||
const hideGroupsUser: () => void = () => {
|
||||
if (publicKey && relayPool && database && userId) {
|
||||
|
@ -32,7 +32,7 @@ export const ProfileConfigPage: React.FC = () => {
|
||||
const bottomSheetDirectoryRef = React.useRef<RBSheet>(null)
|
||||
const bottomSheetNip05Ref = React.useRef<RBSheet>(null)
|
||||
const bottomSheetLud06Ref = React.useRef<RBSheet>(null)
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { relayPool, lastEventId, lastConfirmationtId, sendEvent } = useContext(RelayPoolContext)
|
||||
const {
|
||||
publicKey,
|
||||
@ -83,7 +83,7 @@ export const ProfileConfigPage: React.FC = () => {
|
||||
bottomSheetNip05Ref.current?.close()
|
||||
bottomSheetLud06Ref.current?.close()
|
||||
}
|
||||
}, [lastEventId, lastConfirmationtId])
|
||||
}, [lastEventId, lastConfirmationtId, online])
|
||||
|
||||
const publishUser: () => Promise<void> = async () => {
|
||||
return await new Promise<void>((resolve) => {
|
||||
|
@ -30,7 +30,7 @@ export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
const initialPageSize = 10
|
||||
const theme = useTheme()
|
||||
const { t } = useTranslation('common')
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
@ -47,7 +47,7 @@ export const BookmarksFeed: React.FC<BookmarksFeedProps> = ({
|
||||
subscribe()
|
||||
loadNotes()
|
||||
}
|
||||
}, [pageSize, lastEventId, activeTab])
|
||||
}, [pageSize, lastEventId, activeTab, online])
|
||||
|
||||
const subscribe: () => Promise<void> = async () => {
|
||||
if (database) {
|
||||
|
@ -24,7 +24,7 @@ export const NotesFeed: React.FC<NotesFeedProps> = ({
|
||||
activeTab,
|
||||
}) => {
|
||||
const initialPageSize = 10
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
@ -41,7 +41,7 @@ export const NotesFeed: React.FC<NotesFeedProps> = ({
|
||||
subscribe()
|
||||
loadNotes()
|
||||
}
|
||||
}, [pageSize, lastEventId, activeTab])
|
||||
}, [pageSize, lastEventId, activeTab, online])
|
||||
|
||||
const subscribe: () => Promise<void> = async () => {
|
||||
relayPool?.subscribe(`profile-user${publicKey.substring(0, 8)}`, [
|
||||
|
@ -24,7 +24,7 @@ export const RepliesFeed: React.FC<RepliesFeedProps> = ({
|
||||
activeTab,
|
||||
}) => {
|
||||
const initialPageSize = 10
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
@ -39,7 +39,7 @@ export const RepliesFeed: React.FC<RepliesFeedProps> = ({
|
||||
if (activeTab === 'replies') {
|
||||
loadNotes()
|
||||
}
|
||||
}, [pageSize, lastEventId, activeTab])
|
||||
}, [pageSize, lastEventId, activeTab, online])
|
||||
|
||||
const loadNotes: (main?: boolean) => void = () => {
|
||||
if (database) {
|
||||
|
@ -25,7 +25,7 @@ export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
activeTab,
|
||||
}) => {
|
||||
const initialPageSize = 10
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||
const [notes, setNotes] = useState<Note[]>([])
|
||||
@ -42,7 +42,7 @@ export const ZapsFeed: React.FC<ZapsFeedProps> = ({
|
||||
subscribe()
|
||||
loadNotes()
|
||||
}
|
||||
}, [pageSize, lastEventId, activeTab])
|
||||
}, [pageSize, lastEventId, activeTab, online])
|
||||
|
||||
const subscribe: () => Promise<void> = async () => {
|
||||
relayPool?.subscribe(`profile-zaps${publicKey}`, [
|
||||
|
@ -21,7 +21,7 @@ interface ProfilePageProps {
|
||||
}
|
||||
|
||||
export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext)
|
||||
const { t } = useTranslation('common')
|
||||
@ -73,7 +73,7 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
|
||||
if (!firstLoad && !user?.name) {
|
||||
loadUser()
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
if (refreshing) {
|
||||
|
@ -50,7 +50,7 @@ export const RelaysPage: React.FC = () => {
|
||||
removeRelayItem,
|
||||
} = useContext(RelayPoolContext)
|
||||
const { publicKey } = useContext(UserContext)
|
||||
const { database } = useContext(AppContext)
|
||||
const { database, online } = useContext(AppContext)
|
||||
const { t } = useTranslation('common')
|
||||
const theme = useTheme()
|
||||
const bottomSheetAddRef = React.useRef<RBSheet>(null)
|
||||
@ -88,7 +88,7 @@ export const RelaysPage: React.FC = () => {
|
||||
|
||||
React.useEffect(() => {
|
||||
loadRelays()
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
const addRelay: (url: string) => void = (url) => {
|
||||
if (!relayList.find((relay) => relay.url === url)) {
|
||||
|
@ -31,7 +31,7 @@ interface SearchPageProps {
|
||||
export const SearchPage: React.FC<SearchPageProps> = ({ route }) => {
|
||||
const pageSize = 30
|
||||
const theme = useTheme()
|
||||
const { database } = React.useContext(AppContext)
|
||||
const { database, online } = React.useContext(AppContext)
|
||||
const { relayPool, lastEventId } = React.useContext(RelayPoolContext)
|
||||
const [users, setUsers] = React.useState<User[]>([])
|
||||
const [resultsUsers, setResultsUsers] = React.useState<User[]>([])
|
||||
@ -76,7 +76,7 @@ export const SearchPage: React.FC<SearchPageProps> = ({ route }) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
const subscribeHandler = React.useMemo(
|
||||
() =>
|
||||
|
@ -28,7 +28,7 @@ import { navigate } from '../../lib/Navigation'
|
||||
|
||||
export const WalletPage: React.FC = () => {
|
||||
const theme = useTheme()
|
||||
const { getSatoshiSymbol, database, setDisplayUserDrawer } = React.useContext(AppContext)
|
||||
const { getSatoshiSymbol, database, setDisplayUserDrawer, online } = React.useContext(AppContext)
|
||||
const { publicKey } = React.useContext(UserContext)
|
||||
const { relayPool, lastEventId } = React.useContext(RelayPoolContext)
|
||||
const { refreshWallet, updateWallet, type, balance, transactions, invoices, updatedAt } =
|
||||
@ -73,7 +73,7 @@ export const WalletPage: React.FC = () => {
|
||||
},
|
||||
])
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
const array = [...transactions, ...invoices]
|
||||
|
@ -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 } = React.useContext(AppContext)
|
||||
const { getSatoshiSymbol, database, setDisplayUserDrawer, online } = React.useContext(AppContext)
|
||||
const { relayPool, lastEventId } = React.useContext(RelayPoolContext)
|
||||
const { publicKey, privateKey } = React.useContext(UserContext)
|
||||
const bottomSheetLnPaymentRef = React.useRef<RBSheet>(null)
|
||||
@ -85,7 +85,7 @@ export const ZapPage: React.FC<ZapPageProps> = ({ route: { params: { note, user
|
||||
setZapsUpdated(getUnixTime(new Date()))
|
||||
})
|
||||
}
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, online])
|
||||
|
||||
useEffect(() => {
|
||||
bottomSheetLnPaymentRef.current?.forceUpdate()
|
||||
|
@ -5,6 +5,7 @@ interface RelayPoolInterface {
|
||||
sendAll: (message: string, globalFeed: boolean) => void
|
||||
sendRelay: (message: string, relayUrl: string) => void
|
||||
connect: (pubKey: string, callback: (eventId: string) => void) => void
|
||||
disconnect: (callback: () => void) => void
|
||||
add: (url: string, resilient: number, globalFeed: number, callback: () => void) => void
|
||||
remove: (url: string, callback: () => void) => void
|
||||
removeAll: (callback?: () => void) => void
|
||||
|
@ -66,18 +66,22 @@ export const fallbackRelays = [
|
||||
]
|
||||
|
||||
class RelayPool {
|
||||
constructor(privateKey?: string) {
|
||||
constructor(online: boolean, privateKey?: string) {
|
||||
this.privateKey = privateKey
|
||||
this.subscriptions = {}
|
||||
this.online = online
|
||||
}
|
||||
|
||||
private readonly privateKey?: string
|
||||
private subscriptions: Record<string, string[]>
|
||||
|
||||
public online: boolean
|
||||
|
||||
private readonly sendAll: (message: object, globalFeed?: boolean) => void = async (
|
||||
message,
|
||||
globalFeed,
|
||||
) => {
|
||||
if (!this.online) return
|
||||
const tosend = JSON.stringify(message)
|
||||
RelayPoolModule.sendAll(tosend, globalFeed ?? false)
|
||||
}
|
||||
@ -86,15 +90,11 @@ class RelayPool {
|
||||
message,
|
||||
relayUrl,
|
||||
) => {
|
||||
if (!this.online) return
|
||||
const tosend = JSON.stringify(message)
|
||||
RelayPoolModule.sendRelay(tosend, relayUrl)
|
||||
}
|
||||
|
||||
public readonly connect: (publicKey: string, onEventId: (eventId: string) => void) => void =
|
||||
async (publicKey, onEventId) => {
|
||||
RelayPoolModule.connect(publicKey, onEventId)
|
||||
}
|
||||
|
||||
public readonly add: (
|
||||
relayUrl: string,
|
||||
resilient: number,
|
||||
@ -125,10 +125,29 @@ class RelayPool {
|
||||
RelayPoolModule.update(relayUrl, active, globalfeed, paid, callback)
|
||||
}
|
||||
|
||||
public readonly switchLine: (online: boolean, publicKey: string, callback?: () => void) => void = async (
|
||||
online,
|
||||
publicKey,
|
||||
callback = () => {}
|
||||
) => {
|
||||
if (online) {
|
||||
RelayPoolModule.connect(publicKey, () => {
|
||||
this.online = true
|
||||
callback()
|
||||
})
|
||||
} else {
|
||||
RelayPoolModule.disconnect(() => {
|
||||
this.online = false
|
||||
callback()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public readonly sendEvent: (event: Event, relayUrl?: string) => Promise<Event | null> = async (
|
||||
event,
|
||||
relayUrl,
|
||||
) => {
|
||||
if (!this.online) return null
|
||||
if (validateEvent(event)) {
|
||||
if (relayUrl) {
|
||||
this.sendRelay(['EVENT', event], relayUrl)
|
||||
@ -146,6 +165,7 @@ class RelayPool {
|
||||
event,
|
||||
relayUrl,
|
||||
) => {
|
||||
if (!this.online) return null
|
||||
if (validateEvent(event)) {
|
||||
this.sendRelay(['AUTH', event], relayUrl)
|
||||
return event
|
||||
@ -159,6 +179,7 @@ class RelayPool {
|
||||
subId,
|
||||
filters,
|
||||
) => {
|
||||
if (!this.online) return
|
||||
const id = `${subId}${JSON.stringify(filters)}`
|
||||
if (this.subscriptions[subId]?.includes(id)) {
|
||||
console.log('Subscription already done!', subId)
|
||||
@ -170,6 +191,7 @@ class RelayPool {
|
||||
}
|
||||
|
||||
public readonly unsubscribe: (subIds: string[]) => void = async (subIds) => {
|
||||
if (!this.online) return
|
||||
subIds.forEach((subId: string) => {
|
||||
this.sendAll(['CLOSE', subId])
|
||||
delete this.subscriptions[subId]
|
||||
@ -177,6 +199,7 @@ class RelayPool {
|
||||
}
|
||||
|
||||
public readonly unsubscribeAll: () => void = async () => {
|
||||
if (!this.online) return
|
||||
this.unsubscribe(Object.keys(this.subscriptions))
|
||||
this.subscriptions = {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user