mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-29 22:50:43 +00:00
Fix groups
This commit is contained in:
parent
b541827bc4
commit
7658a1d7a4
@ -209,27 +209,6 @@ public class Event {
|
||||
database.replace("nostros_notes", null, values);
|
||||
}
|
||||
|
||||
protected void updateGroup(SQLiteDatabase database) throws JSONException {
|
||||
JSONObject groupContent = new JSONObject(content);
|
||||
JSONArray eTags = filterTags("e");
|
||||
String groupId = eTags.getJSONArray(0).getString(1);
|
||||
String query = "SELECT created_at, pubkey FROM nostros_groups WHERE id = ?";
|
||||
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {groupId});
|
||||
|
||||
if (cursor.moveToFirst() && created_at > cursor.getInt(0) && pubkey.equals(cursor.getString(1))) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("name", groupContent.optString("name"));
|
||||
values.put("about", groupContent.optString("about"));
|
||||
values.put("picture", groupContent.optString("picture"));
|
||||
|
||||
String whereClause = "id = ?";
|
||||
String[] whereArgs = new String[] {
|
||||
groupId
|
||||
};
|
||||
database.update("nostros_groups", values, whereClause, whereArgs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void blockUser(SQLiteDatabase database) throws JSONException {
|
||||
JSONArray pTags = filterTags("p");
|
||||
String groupId = pTags.getJSONArray(0).getString(1);
|
||||
@ -266,19 +245,60 @@ public class Event {
|
||||
|
||||
protected void saveGroup(SQLiteDatabase database) throws JSONException {
|
||||
JSONObject groupContent = new JSONObject(content);
|
||||
String query = "SELECT created_at, pubkey FROM nostros_groups WHERE id = ?";
|
||||
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {id});
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("id", id);
|
||||
values.put("content", content);
|
||||
values.put("created_at", created_at);
|
||||
values.put("kind", kind);
|
||||
values.put("pubkey", pubkey);
|
||||
values.put("sig", sig);
|
||||
values.put("tags", tags.toString());
|
||||
|
||||
if (cursor.getCount() == 0) {
|
||||
values.put("id", id);
|
||||
values.put("name", groupContent.optString("name"));
|
||||
values.put("about", groupContent.optString("about"));
|
||||
values.put("picture", groupContent.optString("picture"));
|
||||
database.insert("nostros_groups", null, values);
|
||||
} else if (cursor.moveToFirst() && cursor.getString(0).isEmpty()) {
|
||||
String whereClause = "id = ?";
|
||||
String[] whereArgs = new String[] {
|
||||
id
|
||||
};
|
||||
database.update("nostros_groups", values, whereClause, whereArgs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateGroup(SQLiteDatabase database) throws JSONException {
|
||||
JSONObject groupContent = new JSONObject(content);
|
||||
JSONArray eTags = filterTags("e");
|
||||
String groupId = eTags.getJSONArray(0).getString(1);
|
||||
String query = "SELECT created_at, pubkey FROM nostros_groups WHERE id = ?";
|
||||
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {groupId});
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("name", groupContent.optString("name"));
|
||||
values.put("about", groupContent.optString("about"));
|
||||
values.put("picture", groupContent.optString("picture"));
|
||||
database.insert("nostros_groups", null, values);
|
||||
|
||||
if (cursor.getCount() == 0) {
|
||||
values.put("id", groupId);
|
||||
values.put("content", content);
|
||||
values.put("created_at", created_at);
|
||||
values.put("kind", kind);
|
||||
values.put("pubkey", pubkey);
|
||||
values.put("sig", sig);
|
||||
values.put("tags", tags.toString());
|
||||
database.insert("nostros_groups", null, values);
|
||||
} else if (cursor.moveToFirst() && created_at > cursor.getInt(0) && pubkey.equals(cursor.getString(1))) {
|
||||
String whereClause = "id = ?";
|
||||
String[] whereArgs = new String[] {
|
||||
groupId
|
||||
};
|
||||
database.update("nostros_groups", values, whereClause, whereArgs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveGroupMessage(SQLiteDatabase database) throws JSONException {
|
||||
|
@ -27,14 +27,13 @@ import {
|
||||
Text,
|
||||
useTheme,
|
||||
Avatar,
|
||||
IconButton,
|
||||
TouchableRipple,
|
||||
Chip,
|
||||
Surface,
|
||||
} from 'react-native-paper'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { REGEX_SOCKET_LINK } from '../../Constants/Relay'
|
||||
import { push } from '../../lib/Navigation'
|
||||
import { navigate, push } from '../../lib/Navigation'
|
||||
import { Kind } from 'nostr-tools'
|
||||
import ProfileData from '../ProfileData'
|
||||
import { relayToColor } from '../../Functions/NativeFunctions'
|
||||
@ -141,7 +140,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
const textNote: () => JSX.Element = () => {
|
||||
return (
|
||||
<>
|
||||
{note?.reply_event_id && showAnswerData && (
|
||||
{note?.reply_event_id && !note.repost_id && showAnswerData && (
|
||||
<TouchableRipple
|
||||
onPress={() =>
|
||||
note.kind !== Kind.RecommendRelay && push('Note', { noteId: note.reply_event_id })
|
||||
@ -150,15 +149,11 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
<Card.Content style={[styles.answerContent, { borderColor: theme.colors.onSecondary }]}>
|
||||
<View style={styles.answerData}>
|
||||
<MaterialCommunityIcons
|
||||
name={note.repost_id ? 'cached' : 'arrow-left-top'}
|
||||
name='arrow-left-top'
|
||||
size={16}
|
||||
color={theme.colors.onPrimaryContainer}
|
||||
/>
|
||||
<Text>
|
||||
{note.repost_id
|
||||
? t('noteCard.reposting', { pubkey: formatPubKey(note.pubkey) })
|
||||
: t('noteCard.answering', { pubkey: formatPubKey(note.pubkey) })}
|
||||
</Text>
|
||||
<Text>{t('noteCard.answering', { pubkey: formatPubKey(note.pubkey) })}</Text>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={styles.link}>{t('noteCard.seeParent')}</Text>
|
||||
@ -179,13 +174,42 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
numberOfLines={numberOfLines}
|
||||
/>
|
||||
)}
|
||||
{showRepostPreview && repost && (
|
||||
<NoteCard
|
||||
note={repost}
|
||||
showAction={false}
|
||||
showPreview={showPreview}
|
||||
showRepostPreview={false}
|
||||
/>
|
||||
{note?.repost_id && (
|
||||
<>
|
||||
{repost && showRepostPreview ? (
|
||||
<NoteCard
|
||||
note={repost}
|
||||
showActionCount={false}
|
||||
showPreview={showPreview}
|
||||
showRepostPreview={false}
|
||||
/>
|
||||
) : (
|
||||
<TouchableRipple
|
||||
style={{
|
||||
marginTop: note.content.length > 5 ? 16 : -16,
|
||||
}}
|
||||
onPress={() => navigate('Note', { noteId: note.repost_id })}
|
||||
>
|
||||
<Chip
|
||||
icon={() => (
|
||||
<MaterialCommunityIcons
|
||||
name='cached'
|
||||
size={16}
|
||||
color={theme.colors.onTertiaryContainer}
|
||||
/>
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: theme.colors.secondaryContainer,
|
||||
color: theme.colors.onTertiaryContainer,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.colors.onTertiaryContainer }}>
|
||||
{t('noteCard.reposted')}
|
||||
</Text>
|
||||
</Chip>
|
||||
</TouchableRipple>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Card.Content>
|
||||
</>
|
||||
@ -351,18 +375,9 @@ export const NoteCard: React.FC<NoteCardProps> = ({
|
||||
lud06={note?.lnurl}
|
||||
picture={showAvatarImage ? note?.picture : undefined}
|
||||
timestamp={note?.created_at}
|
||||
avatarSize={56}
|
||||
avatarSize={40}
|
||||
/>
|
||||
</TouchableRipple>
|
||||
{showAction && (
|
||||
<View style={styles.topAction}>
|
||||
<IconButton
|
||||
icon='dots-vertical'
|
||||
size={24}
|
||||
onPress={() => setDisplayUserDrawer(note.pubkey)}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</Card.Content>
|
||||
{getNoteContent()}
|
||||
{showAction && (
|
||||
@ -471,9 +486,8 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
title: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignContent: 'center',
|
||||
paddingBottom: 16,
|
||||
flex: 1,
|
||||
},
|
||||
userBlockedWrapper: {
|
||||
flexDirection: 'row',
|
||||
|
@ -38,39 +38,61 @@ export const ProfileData: React.FC<ProfileCardProps> = ({
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<NostrosAvatar name={username} pubKey={nPub} src={picture} lud06={lud06} size={avatarSize} />
|
||||
<View style={[styles.contactData, { height: avatarSize }]}>
|
||||
<View style={styles.contactName}>
|
||||
<Text variant='titleSmall' numberOfLines={1}>
|
||||
{usernamePubKey(username, nPub)}
|
||||
</Text>
|
||||
{validNip05 ? (
|
||||
<MaterialCommunityIcons
|
||||
name='check-decagram-outline'
|
||||
color={theme.colors.onPrimaryContainer}
|
||||
style={styles.verifyIcon}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<View style={styles.left}>
|
||||
<NostrosAvatar
|
||||
name={username}
|
||||
pubKey={nPub}
|
||||
src={picture}
|
||||
lud06={lud06}
|
||||
size={avatarSize}
|
||||
/>
|
||||
<View style={[styles.contactData, { height: avatarSize }]}>
|
||||
<View style={styles.contactName}>
|
||||
<Text variant='titleSmall' numberOfLines={1}>
|
||||
{usernamePubKey(username, nPub)}
|
||||
</Text>
|
||||
{validNip05 ? (
|
||||
<MaterialCommunityIcons
|
||||
name='check-decagram-outline'
|
||||
color={theme.colors.onPrimaryContainer}
|
||||
style={styles.verifyIcon}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</View>
|
||||
<Text numberOfLines={1}>{validNip05 ? getNip05Domain(nip05) : ''}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.right}>
|
||||
<View style={styles.contactData}>
|
||||
<Text numberOfLines={1}>{date ?? ''}</Text>
|
||||
</View>
|
||||
<Text numberOfLines={1}>{validNip05 ? getNip05Domain(nip05) : ''}</Text>
|
||||
<Text numberOfLines={1}>{date ?? ''}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
right: {
|
||||
flexDirection: 'row',
|
||||
width: '50%',
|
||||
justifyContent: 'flex-end'
|
||||
},
|
||||
left: {
|
||||
flexDirection: 'row',
|
||||
width: '50%'
|
||||
},
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
flex: 1
|
||||
},
|
||||
contactName: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
contactData: {
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
marginLeft: 12,
|
||||
},
|
||||
verifyIcon: {
|
||||
|
@ -152,7 +152,40 @@ export const TextContent: React.FC<TextContentProps> = ({
|
||||
return matchingString
|
||||
}
|
||||
|
||||
const generatePreview: () => JSX.Element = () => {
|
||||
const parsedText = React.useMemo(() => (
|
||||
<ParsedText
|
||||
style={[styles.text, { color: theme.colors.onSurfaceVariant }]}
|
||||
parse={[
|
||||
{ type: 'url', style: styles.url, onPress: handleUrlPress, renderText: renderUrlText },
|
||||
{ type: 'email', style: styles.email, onPress: handleUrlPress },
|
||||
event
|
||||
? {
|
||||
pattern: /#\[(\d+)\]/,
|
||||
style: styles.mention,
|
||||
onPress: handleMentionPress,
|
||||
renderText: renderMentionText,
|
||||
}
|
||||
: {
|
||||
pattern: /#\[(\d+)\]/,
|
||||
},
|
||||
{ pattern: /#(\w+)/, style: styles.hashTag },
|
||||
{ pattern: /(lnbc)\S*/, style: styles.nip19, renderText: renderLnurl },
|
||||
{ pattern: /(nevent1)\S*/, style: styles.nip19, onPress: handleNip05NotePress },
|
||||
{
|
||||
pattern: /(npub1|nprofile1)\S*/,
|
||||
style: styles.nip19,
|
||||
onPress: handleNip05ProfilePress,
|
||||
},
|
||||
]}
|
||||
childrenProps={{ allowFontScaling: false }}
|
||||
onLongPress={() => Clipboard.setString(text)}
|
||||
numberOfLines={numberOfLines}
|
||||
>
|
||||
{text}
|
||||
</ParsedText>
|
||||
), [loadedUsers])
|
||||
|
||||
const preview = React.useMemo(() => {
|
||||
if (!showPreview) return <></>
|
||||
|
||||
const getRequireCover: () => string | undefined = () => {
|
||||
@ -233,41 +266,12 @@ export const TextContent: React.FC<TextContentProps> = ({
|
||||
{invoice && <LnPreview invoice={invoice} setInvoice={setInvoice} />}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}, [invoice, url, linkType])
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ParsedText
|
||||
style={[styles.text, { color: theme.colors.onSurfaceVariant }]}
|
||||
parse={[
|
||||
{ type: 'url', style: styles.url, onPress: handleUrlPress, renderText: renderUrlText },
|
||||
{ type: 'email', style: styles.email, onPress: handleUrlPress },
|
||||
event
|
||||
? {
|
||||
pattern: /#\[(\d+)\]/,
|
||||
style: styles.mention,
|
||||
onPress: handleMentionPress,
|
||||
renderText: renderMentionText,
|
||||
}
|
||||
: {
|
||||
pattern: /#\[(\d+)\]/,
|
||||
},
|
||||
{ pattern: /#(\w+)/, style: styles.hashTag },
|
||||
{ pattern: /(lnbc)\S*/, style: styles.nip19, renderText: renderLnurl },
|
||||
{ pattern: /(nevent1)\S*/, style: styles.nip19, onPress: handleNip05NotePress },
|
||||
{
|
||||
pattern: /(npub1|nprofile1)\S*/,
|
||||
style: styles.nip19,
|
||||
onPress: handleNip05ProfilePress,
|
||||
},
|
||||
]}
|
||||
childrenProps={{ allowFontScaling: false }}
|
||||
onLongPress={() => Clipboard.setString(text)}
|
||||
numberOfLines={numberOfLines}
|
||||
>
|
||||
{text}
|
||||
</ParsedText>
|
||||
{generatePreview()}
|
||||
{parsedText}
|
||||
{preview}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
|
||||
import { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
|
||||
import { AppContext } from '../../Contexts/AppContext'
|
||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||
import { Event } from '../../lib/nostr/Events'
|
||||
@ -21,7 +21,6 @@ import { useFocusEffect } from '@react-navigation/native'
|
||||
import { Kind } from 'nostr-tools'
|
||||
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
|
||||
import NostrosAvatar from '../../Components/NostrosAvatar'
|
||||
import { FlashList, ListRenderItem } from '@shopify/flash-list'
|
||||
import UploadImage from '../../Components/UploadImage'
|
||||
|
||||
interface ConversationPageProps {
|
||||
@ -102,7 +101,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
|
||||
const subscribeDirectMessages: (lastCreateAt?: number) => void = async (lastCreateAt) => {
|
||||
if (publicKey && otherPubKey) {
|
||||
relayPool?.subscribe(`conversation${route.params.pubKey}`, [
|
||||
relayPool?.subscribe(`conversation${route.params.pubKey.substring(0,8)}`, [
|
||||
{
|
||||
kinds: [Kind.EncryptedDirectMessage],
|
||||
authors: [publicKey],
|
||||
@ -145,7 +144,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
|
||||
const directMessage = event as DirectMessage
|
||||
directMessage.pending = true
|
||||
directMessage.valid_nip05 = validNip05
|
||||
directMessage.valid_nip05 = validNip05 ?? false
|
||||
setSendingMessages((prev) => [...prev, directMessage])
|
||||
setInput('')
|
||||
}
|
||||
@ -238,8 +237,8 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlashList
|
||||
inverted
|
||||
<FlatList
|
||||
style={styles.list}
|
||||
data={[...sendingMessages, ...directMessages]}
|
||||
renderItem={renderDirectMessageItem}
|
||||
horizontal={false}
|
||||
@ -313,12 +312,16 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
list: {
|
||||
scaleY: -1
|
||||
},
|
||||
scrollView: {
|
||||
paddingBottom: 16,
|
||||
},
|
||||
messageRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
scaleY: -1
|
||||
},
|
||||
cardContentDate: {
|
||||
flexDirection: 'row',
|
||||
|
@ -111,20 +111,16 @@ export const GlobalFeed: React.FC<GlobalFeedProps> = ({ navigation }) => {
|
||||
setRefreshing(false)
|
||||
if (results.length > 0) {
|
||||
setNotes(results)
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '')
|
||||
const message: RelayFilters[] = [
|
||||
{
|
||||
kinds: [Kind.Metadata],
|
||||
authors: results.map((note) => note.pubkey ?? ''),
|
||||
},
|
||||
]
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.repost_id ?? '')
|
||||
if (repostIds.length > 0) {
|
||||
message.push({
|
||||
kinds: [Kind.Text],
|
||||
'#e': repostIds,
|
||||
})
|
||||
const message: RelayFilters[] = [
|
||||
{
|
||||
kinds: [Kind.Text],
|
||||
ids: repostIds,
|
||||
},
|
||||
]
|
||||
relayPool?.subscribe('homepage-global-meta-repost', message)
|
||||
}
|
||||
relayPool?.subscribe('homepage-global-meta-repost', message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { NativeScrollEvent, NativeSyntheticEvent, ScrollView, StyleSheet, View } from 'react-native'
|
||||
import React, { useContext, useEffect, useMemo, useState } from 'react'
|
||||
import {
|
||||
FlatList,
|
||||
ListRenderItem,
|
||||
NativeScrollEvent,
|
||||
NativeSyntheticEvent,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import { AppContext } from '../../Contexts/AppContext'
|
||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||
import { Event } from '../../lib/nostr/Events'
|
||||
@ -7,14 +14,20 @@ import { useTranslation } from 'react-i18next'
|
||||
import { username, usernamePubKey } from '../../Functions/RelayFunctions/Users'
|
||||
import { getUnixTime, formatDistance, fromUnixTime } from 'date-fns'
|
||||
import TextContent from '../../Components/TextContent'
|
||||
import { Card, useTheme, TextInput, TouchableRipple, Text } from 'react-native-paper'
|
||||
import {
|
||||
Card,
|
||||
useTheme,
|
||||
TextInput,
|
||||
TouchableRipple,
|
||||
Text,
|
||||
ActivityIndicator,
|
||||
} from 'react-native-paper'
|
||||
import { UserContext } from '../../Contexts/UserContext'
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||
import { useFocusEffect } from '@react-navigation/native'
|
||||
import { Kind } from 'nostr-tools'
|
||||
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
|
||||
import NostrosAvatar from '../../Components/NostrosAvatar'
|
||||
import { FlashList, ListRenderItem } from '@shopify/flash-list'
|
||||
import UploadImage from '../../Components/UploadImage'
|
||||
import { getGroupMessages, GroupMessage } from '../../Functions/DatabaseFunctions/Groups'
|
||||
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
|
||||
@ -26,7 +39,6 @@ interface GroupPageProps {
|
||||
export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
const initialPageSize = 10
|
||||
const theme = useTheme()
|
||||
const scrollViewRef = useRef<ScrollView>()
|
||||
const { database, setDisplayUserDrawer } = useContext(AppContext)
|
||||
const { relayPool, lastEventId } = useContext(RelayPoolContext)
|
||||
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
|
||||
@ -50,7 +62,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
|
||||
useEffect(() => {
|
||||
loadGroupMessages(false)
|
||||
}, [lastEventId])
|
||||
}, [lastEventId, pageSize])
|
||||
|
||||
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
|
||||
if (database && publicKey && privateKey && route.params.groupId) {
|
||||
@ -64,9 +76,9 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
const pubKeys = results
|
||||
.map((message) => message.pubkey)
|
||||
.filter((key, index, array) => array.indexOf(key) === index)
|
||||
const lastCreateAt = pageSize <= results.length ? results[0].created_at : 0
|
||||
if (subscribe) subscribeGroupMessages(lastCreateAt, pubKeys)
|
||||
} else if (subscribe) {
|
||||
const lastCreateAt = results.length < pageSize ? 0 : results[0].created_at
|
||||
subscribeGroupMessages(lastCreateAt, pubKeys)
|
||||
} else {
|
||||
subscribeGroupMessages()
|
||||
}
|
||||
})
|
||||
@ -102,7 +114,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
})
|
||||
}
|
||||
|
||||
relayPool?.subscribe(`group${route.params.groupId}`, filters)
|
||||
relayPool?.subscribe(`group${route.params.groupId.substring(0, 8)}`, filters)
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,10 +143,10 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
item.pubkey === publicKey
|
||||
? usernamePubKey(name, publicKey)
|
||||
: username({ name: item.name, id: item.pubkey })
|
||||
const showAvatar = groupMessages[index - 1]?.pubkey !== item.pubkey
|
||||
const showAvatar = [...groupMessages, ...sendingMessages][index - 1]?.pubkey !== item.pubkey
|
||||
|
||||
return (
|
||||
<View style={styles.messageRow}>
|
||||
<View style={styles.messageRow} key={index}>
|
||||
{publicKey !== item.pubkey && (
|
||||
<View style={styles.pictureSpaceLeft}>
|
||||
{showAvatar && (
|
||||
@ -212,14 +224,20 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlashList
|
||||
inverted
|
||||
<FlatList
|
||||
style={styles.list}
|
||||
data={[...sendingMessages, ...groupMessages]}
|
||||
renderItem={renderGroupMessageItem}
|
||||
horizontal={false}
|
||||
ref={scrollViewRef}
|
||||
estimatedItemSize={100}
|
||||
onScroll={onScroll}
|
||||
showsVerticalScrollIndicator={false}
|
||||
ListFooterComponent={
|
||||
groupMessages.length > 0 ? (
|
||||
<ActivityIndicator style={styles.loading} animating={true} />
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
@ -235,7 +253,6 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
label={t('groupPage.typeMessage') ?? ''}
|
||||
value={input}
|
||||
onChangeText={setInput}
|
||||
onFocus={() => scrollViewRef.current?.scrollToEnd({ animated: true })}
|
||||
left={
|
||||
<TextInput.Icon
|
||||
icon={() => (
|
||||
@ -276,12 +293,16 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
list: {
|
||||
scaleY: -1
|
||||
},
|
||||
scrollView: {
|
||||
paddingBottom: 16,
|
||||
},
|
||||
messageRow: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
scaleY: -1
|
||||
},
|
||||
cardContentDate: {
|
||||
flexDirection: 'row',
|
||||
@ -291,7 +312,7 @@ const styles = StyleSheet.create({
|
||||
paddingBottom: 16,
|
||||
paddingRight: 16,
|
||||
justifyContent: 'space-between',
|
||||
flex: 1,
|
||||
flex: 1
|
||||
},
|
||||
card: {
|
||||
marginTop: 16,
|
||||
@ -324,6 +345,9 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'column-reverse',
|
||||
marginTop: 16,
|
||||
},
|
||||
loading: {
|
||||
paddingTop: 16,
|
||||
},
|
||||
snackbar: {
|
||||
margin: 16,
|
||||
bottom: 70,
|
||||
|
@ -73,25 +73,19 @@ export const GroupsFeed: React.FC = () => {
|
||||
const filters: RelayFilters[] = [
|
||||
{
|
||||
kinds: [Kind.ChannelCreation],
|
||||
authors: [publicKey],
|
||||
authors: [publicKey, newGroupId ?? ''],
|
||||
},
|
||||
]
|
||||
if (results && results.length > 0) {
|
||||
filters.push({
|
||||
kinds: [Kind.ChannelMetadata],
|
||||
ids: [...results.map((group) => group.id ?? ''), publicKey, newGroupId ?? ''],
|
||||
})
|
||||
if (results.length > 0) {
|
||||
setGroups(results)
|
||||
filters.push({
|
||||
kinds: [Kind.Metadata],
|
||||
ids: [...results.map((group) => group.pubkey)],
|
||||
})
|
||||
filters.push({
|
||||
kinds: [Kind.ChannelMetadata],
|
||||
ids: [...results.map((group) => group.id ?? ''), publicKey, newGroupId ?? ''],
|
||||
})
|
||||
if (newGroupId) {
|
||||
filters.push({
|
||||
kinds: [Kind.ChannelCreation],
|
||||
ids: [newGroupId],
|
||||
})
|
||||
}
|
||||
}
|
||||
relayPool?.subscribe('groups-create', filters)
|
||||
})
|
||||
@ -157,13 +151,13 @@ export const GroupsFeed: React.FC = () => {
|
||||
<View>
|
||||
<View style={styles.username}>
|
||||
<Text>{username({ name: item.user_name, id: item.pubkey })}</Text>
|
||||
{item.valid_nip05 && (
|
||||
{item.valid_nip05 ? (
|
||||
<MaterialCommunityIcons
|
||||
name='check-decagram-outline'
|
||||
color={theme.colors.onPrimaryContainer}
|
||||
style={styles.verifyIcon}
|
||||
/>
|
||||
)}
|
||||
) : <></>}
|
||||
</View>
|
||||
<Text style={{ color: theme.colors.onSurfaceVariant }}>{formatId(item.id)}</Text>
|
||||
</View>
|
||||
@ -246,7 +240,6 @@ export const GroupsFeed: React.FC = () => {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlashList
|
||||
estimatedItemSize={71}
|
||||
showsVerticalScrollIndicator={false}
|
||||
data={groups}
|
||||
renderItem={renderGroupItem}
|
||||
|
@ -132,13 +132,12 @@ export const MyFeed: React.FC<MyFeedProps> = ({ navigation }) => {
|
||||
since: lastReply?.created_at ?? 0,
|
||||
},
|
||||
])
|
||||
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '')
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.repost_id ?? '')
|
||||
if (repostIds.length > 0) {
|
||||
relayPool?.subscribe('homepage-contacts-repost', [
|
||||
{
|
||||
kinds: [Kind.Text],
|
||||
'#e': repostIds,
|
||||
ids: repostIds,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import { navigate } from '../../lib/Navigation'
|
||||
import { useFocusEffect } from '@react-navigation/native'
|
||||
import { SkeletonNote } from '../../Components/SkeletonNote/SkeletonNote'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
|
||||
|
||||
interface NotePageProps {
|
||||
route: { params: { noteId: string } }
|
||||
@ -54,12 +55,19 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
|
||||
|
||||
const notes = await getNotes(database, { filters: { reply_event_id: route.params.noteId } })
|
||||
const rootReplies = getDirectReplies(event, notes)
|
||||
relayPool?.subscribe(`meta-notepage${route.params.noteId}`, [
|
||||
const filters: RelayFilters[] = [
|
||||
{
|
||||
kinds: [Kind.Metadata],
|
||||
authors: [...rootReplies.map((note) => note.pubkey), event.pubkey],
|
||||
},
|
||||
])
|
||||
]
|
||||
if (event.repost_id) {
|
||||
filters.push({
|
||||
kinds: [Kind.Text],
|
||||
ids: [event.repost_id],
|
||||
})
|
||||
}
|
||||
relayPool?.subscribe(`meta-notepage${route.params.noteId.substring(0,8)}`, filters)
|
||||
setReplies(rootReplies as Note[])
|
||||
}
|
||||
setRefreshing(false)
|
||||
@ -74,13 +82,13 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
|
||||
|
||||
const subscribeNotes: (past?: boolean) => Promise<void> = async (past) => {
|
||||
if (database && route.params.noteId) {
|
||||
relayPool?.subscribe(`notepage${route.params.noteId}`, [
|
||||
relayPool?.subscribe(`notepage${route.params.noteId.substring(0,8)}`, [
|
||||
{
|
||||
kinds: [Kind.Text],
|
||||
ids: [route.params.noteId],
|
||||
},
|
||||
])
|
||||
relayPool?.subscribe(`notepage-replies-${route.params.noteId}`, [
|
||||
relayPool?.subscribe(`notepage-replies-${route.params.noteId.substring(0,8)}`, [
|
||||
{
|
||||
kinds: [Kind.Reaction, Kind.Text, Kind.RecommendRelay],
|
||||
'#e': [route.params.noteId],
|
||||
|
@ -96,7 +96,7 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
|
||||
setNotes(results)
|
||||
setRefreshing(false)
|
||||
if (results.length > 0) {
|
||||
relayPool?.subscribe(`profile-answers${route.params.pubKey}`, [
|
||||
relayPool?.subscribe(`profile-answers${route.params.pubKey.substring(0,8)}`, [
|
||||
{
|
||||
kinds: [Kind.Reaction, Kind.Text, Kind.RecommendRelay],
|
||||
'#e': results.map((note) => note.id ?? ''),
|
||||
@ -109,7 +109,7 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
|
||||
}
|
||||
|
||||
const subscribeProfile: () => Promise<void> = async () => {
|
||||
relayPool?.subscribe(`profile-user${route.params.pubKey}`, [
|
||||
relayPool?.subscribe(`profile-user${route.params.pubKey.substring(0,8)}`, [
|
||||
{
|
||||
kinds: [Kind.Metadata, Kind.Contacts],
|
||||
authors: [route.params.pubKey],
|
||||
@ -125,7 +125,7 @@ export const ProfilePage: React.FC<ProfilePageProps> = ({ route }) => {
|
||||
authors: [route.params.pubKey],
|
||||
limit: pageSize,
|
||||
}
|
||||
relayPool?.subscribe(`profile${route.params.pubKey}`, [message])
|
||||
relayPool?.subscribe(`profile${route.params.pubKey.substring(0,8)}`, [message])
|
||||
}
|
||||
|
||||
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
|
||||
|
@ -129,12 +129,12 @@ export const ReactionsFeed: React.FC<ReactionsFeedProps> = ({ navigation }) => {
|
||||
},
|
||||
])
|
||||
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '')
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.repost_id ?? '')
|
||||
if (repostIds.length > 0) {
|
||||
relayPool?.subscribe('homepage-contacts-repost', [
|
||||
{
|
||||
kinds: [Kind.Text],
|
||||
'#e': repostIds,
|
||||
ids: repostIds,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
@ -106,7 +106,6 @@ export const RepostsFeed: React.FC<RepostsFeedProps> = ({ navigation }) => {
|
||||
authors: notes.map((note) => note.pubkey ?? ''),
|
||||
},
|
||||
])
|
||||
|
||||
const lastReaction = await getLastReaction(database, {
|
||||
eventIds: notes.map((note) => note.id ?? ''),
|
||||
})
|
||||
@ -128,13 +127,12 @@ export const RepostsFeed: React.FC<RepostsFeedProps> = ({ navigation }) => {
|
||||
since: lastReply?.created_at ?? 0,
|
||||
},
|
||||
])
|
||||
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.id ?? '')
|
||||
const repostIds = notes.filter((note) => note.repost_id).map((note) => note.repost_id ?? '')
|
||||
if (repostIds.length > 0) {
|
||||
relayPool?.subscribe('homepage-contacts-repost', [
|
||||
{
|
||||
kinds: [Kind.Text],
|
||||
'#e': repostIds,
|
||||
ids: repostIds,
|
||||
},
|
||||
])
|
||||
}
|
||||
|
4
index.js
4
index.js
@ -6,4 +6,8 @@ import { AppRegistry } from 'react-native'
|
||||
import App from './App'
|
||||
import { name as appName } from './app.json'
|
||||
|
||||
// FIXME: https://github.com/facebook/react-native/issues/30034#issuecomment-1277360480
|
||||
import ViewReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes'
|
||||
ViewReactNativeStyleAttributes.scaleY = true
|
||||
|
||||
AppRegistry.registerComponent(appName, () => App)
|
||||
|
Loading…
Reference in New Issue
Block a user