mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-28 22:30:41 +00:00
Smooth event navigation and profile load
This commit is contained in:
parent
02a9150423
commit
76f1295a23
@ -25,6 +25,7 @@ export const ConfigPage: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
const onPressBack: () => void = () => {
|
||||
relayPool?.unsubscribeAll();
|
||||
goBack();
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,7 @@ export const ContactsPage: React.FC = () => {
|
||||
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
||||
if (database && event?.id && event.kind === EventKind.petNames) {
|
||||
insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''));
|
||||
relayPool?.removeOn('event', 'contacts');
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
@ -56,7 +56,7 @@ export const Logger: React.FC = () => {
|
||||
|
||||
const initEvents: () => void = () => {
|
||||
relayPool?.on('event', 'landing', (_relay: Relay, _subId?: string, event?: Event) => {
|
||||
console.log('LandingPage EVENT =======>', event);
|
||||
console.log('LANDING EVENT =======>', event);
|
||||
if (event && database) {
|
||||
if (event.kind === EventKind.petNames) {
|
||||
loadPets(event);
|
||||
|
@ -24,23 +24,23 @@ export const NotePage: React.FC = () => {
|
||||
const { page, goBack, goToPage, database } = useContext(AppContext);
|
||||
const { lastEventId, relayPool } = useContext(RelayPoolContext);
|
||||
const [note, setNote] = useState<Note>();
|
||||
const [replies, setReplies] = useState<Note[]>([]);
|
||||
const [replies, setReplies] = useState<Note[]>();
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation('common');
|
||||
const breadcrump = page.split('%');
|
||||
const eventId = breadcrump[breadcrump.length - 1].split('#')[1];
|
||||
|
||||
useEffect(() => {
|
||||
const reload: () => void = () => {
|
||||
setNote(undefined);
|
||||
setReplies(undefined);
|
||||
relayPool?.unsubscribeAll();
|
||||
relayPool?.subscribe('main-channel', {
|
||||
kinds: [EventKind.textNote, EventKind.recommendServer],
|
||||
kinds: [EventKind.textNote],
|
||||
ids: [eventId],
|
||||
});
|
||||
relayPool?.subscribe('main-channel', {
|
||||
kinds: [EventKind.textNote, EventKind.recommendServer],
|
||||
'#e': [eventId],
|
||||
});
|
||||
}, []);
|
||||
};
|
||||
|
||||
useEffect(reload, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (database) {
|
||||
@ -48,13 +48,19 @@ export const NotePage: React.FC = () => {
|
||||
if (events.length > 0) {
|
||||
const event = events[0];
|
||||
setNote(event);
|
||||
if (!replies) {
|
||||
relayPool?.subscribe('main-channel', {
|
||||
kinds: [EventKind.textNote],
|
||||
'#e': [eventId],
|
||||
});
|
||||
}
|
||||
getNotes(database, { filters: { reply_event_id: eventId } }).then((notes) => {
|
||||
const rootReplies = getDirectReplies(notes, event);
|
||||
const rootReplies = getDirectReplies(event, notes);
|
||||
if (rootReplies.length > 0) {
|
||||
setReplies(rootReplies as Note[]);
|
||||
const message: RelayFilters = {
|
||||
kinds: [EventKind.meta],
|
||||
authors: rootReplies.map((note) => note.pubkey),
|
||||
authors: [...rootReplies.map((note) => note.pubkey), event.pubkey],
|
||||
};
|
||||
relayPool?.subscribe('main-channel', message);
|
||||
} else {
|
||||
@ -67,9 +73,20 @@ export const NotePage: React.FC = () => {
|
||||
}, [lastEventId, page]);
|
||||
|
||||
const onPressBack: () => void = () => {
|
||||
relayPool?.unsubscribeAll();
|
||||
goBack();
|
||||
};
|
||||
|
||||
const onPressGoParent: () => void = () => {
|
||||
if (note) {
|
||||
const replyId = getReplyEventId(note);
|
||||
if (replyId) {
|
||||
goToPage(`note#${replyId}`);
|
||||
reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const renderBackAction = (): JSX.Element => {
|
||||
return (
|
||||
<TopNavigationAction
|
||||
@ -79,6 +96,17 @@ export const NotePage: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const renderNoteActions = (): JSX.Element => {
|
||||
return note && getReplyEventId(note) ? (
|
||||
<TopNavigationAction
|
||||
icon={<Icon name='arrow-up' size={16} color={theme['text-basic-color']} />}
|
||||
onPress={onPressGoParent}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
};
|
||||
|
||||
const onPressNote: (note: Note) => void = (note) => {
|
||||
if (note.kind !== EventKind.recommendServer) {
|
||||
const replyEventId = getReplyEventId(note);
|
||||
@ -87,7 +115,7 @@ export const NotePage: React.FC = () => {
|
||||
} else if (note.id) {
|
||||
goToPage(`note#${note.id}`);
|
||||
}
|
||||
setReplies([]);
|
||||
reload();
|
||||
}
|
||||
};
|
||||
|
||||
@ -127,10 +155,11 @@ export const NotePage: React.FC = () => {
|
||||
alignment='center'
|
||||
title={`${eventId.slice(0, 12)}...${eventId.slice(-12)}`}
|
||||
accessoryLeft={renderBackAction}
|
||||
accessoryRight={renderNoteActions}
|
||||
/>
|
||||
<Layout level='4'>
|
||||
{note ? (
|
||||
<List data={[note, ...replies]} renderItem={(item) => ItemCard(item?.item)} />
|
||||
<List data={[note, ...(replies ?? [])]} renderItem={(item) => ItemCard(item?.item)} />
|
||||
) : (
|
||||
<Loading style={styles.loading} />
|
||||
)}
|
||||
|
@ -48,7 +48,6 @@ export const ProfilePage: React.FC = () => {
|
||||
useEffect(() => {
|
||||
setNotes(undefined);
|
||||
setUser(undefined);
|
||||
relayPool?.unsubscribeAll();
|
||||
relayPool?.subscribe('main-channel', {
|
||||
kinds: [EventKind.meta, EventKind.petNames],
|
||||
authors: [userId],
|
||||
@ -121,7 +120,7 @@ export const ProfilePage: React.FC = () => {
|
||||
if (publicKey === userId) {
|
||||
return (
|
||||
<TopNavigationAction
|
||||
icon={<Icon name='dna' size={16} color={theme['text-basic-color']} solid />}
|
||||
icon={<Icon name='cog' size={16} color={theme['text-basic-color']} solid />}
|
||||
onPress={() => goToPage('config')}
|
||||
/>
|
||||
);
|
||||
@ -149,6 +148,8 @@ export const ProfilePage: React.FC = () => {
|
||||
};
|
||||
|
||||
const onPressBack: () => void = () => {
|
||||
relayPool?.removeOn('event', 'profile');
|
||||
relayPool?.unsubscribeAll();
|
||||
goBack();
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ import React, { useContext, useEffect, useState } from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { AppContext } from '../../Contexts/AppContext';
|
||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||
import { Event } from '../../lib/nostr/Events';
|
||||
import { Event, EventKind } from '../../lib/nostr/Events';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
||||
import moment from 'moment';
|
||||
@ -75,12 +75,19 @@ export const SendPage: React.FC = () => {
|
||||
const event: Event = {
|
||||
content,
|
||||
created_at: moment().unix(),
|
||||
kind: 1,
|
||||
kind: EventKind.textNote,
|
||||
pubkey: publicKey,
|
||||
tags,
|
||||
};
|
||||
relayPool?.sendEvent(event);
|
||||
setNoteId(note.id);
|
||||
relayPool?.sendEvent(event).then((sentNote) => {
|
||||
if (sentNote?.id) {
|
||||
relayPool?.subscribe('main-channel', {
|
||||
kinds: [EventKind.textNote],
|
||||
ids: [sentNote.id],
|
||||
});
|
||||
setNoteId(sentNote.id);
|
||||
}
|
||||
});
|
||||
setSending(true);
|
||||
});
|
||||
}
|
||||
|
@ -74,7 +74,9 @@ export const RelayPoolContextProvider = ({
|
||||
(relay: Relay, _subId?: string, event?: Event) => {
|
||||
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
||||
if (database && event?.id && event.kind !== EventKind.petNames) {
|
||||
storeEvent(event, database).finally(() => setLastEventId(event.id));
|
||||
storeEvent(event, database)
|
||||
.then(() => setLastEventId(event.id))
|
||||
.catch(() => setLastEventId(event.id));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -26,14 +26,21 @@ export const getReplyEventId: (event: Event) => string | null = (event) => {
|
||||
return mainTag ? mainTag[1] : null;
|
||||
};
|
||||
|
||||
export const getDirectReplies: (replies: Event[], event: Event) => Event[] = (replies, event) => {
|
||||
const expectedTags: number = getETags(event).length + 1;
|
||||
const filter = replies.filter((event) => {
|
||||
const eventETags = getETags(event);
|
||||
return eventETags.length === expectedTags;
|
||||
});
|
||||
export const getDirectReplies: (event: Event, replies: Event[]) => Event[] = (event, replies) => {
|
||||
return replies.filter((item) => isDirectReply(event, item));
|
||||
};
|
||||
|
||||
return filter;
|
||||
export const isDirectReply: (mainEvent: Event, reply: Event) => boolean = (mainEvent, reply) => {
|
||||
const taggedMainEventsIds: string[] = getTaggedEventIds(mainEvent);
|
||||
const taggedReplyEventsIds: string[] = getTaggedEventIds(reply);
|
||||
const difference = taggedReplyEventsIds.filter((item) => !taggedMainEventsIds.includes(item));
|
||||
|
||||
return difference.length === 1 && difference[0] === mainEvent.id;
|
||||
};
|
||||
|
||||
export const getTaggedEventIds: (event: Event) => string[] = (event) => {
|
||||
const mainEventETags: string[][] = getETags(event);
|
||||
return mainEventETags.map((item) => item[1] ?? '');
|
||||
};
|
||||
|
||||
export const getETags: (event: Event) => string[][] = (event) => {
|
||||
|
Loading…
Reference in New Issue
Block a user