Skip to content

Commit

Permalink
Update mentions and reposts (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
KoalaSat authored Nov 19, 2023
2 parents 25548bf + d72b731 commit f839a96
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 71 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/notify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@ jobs:
~/go/bin/noscl relay add "wss://nostr-1.afarazit.eu"
~/go/bin/noscl relay add "wss://lbrygen.xyz"
~/go/bin/noscl relay add "wss://soloco.nl"
~/go/bin/noscl relay add "wss://relayable.org"
~/go/bin/noscl relay add "wss://relay.damus.io"
~/go/bin/noscl relay add "wss://relay.snort.social"
~/go/bin/noscl relay add "wss://pyramid.fiatjaf.com"
~/go/bin/noscl publish "${{ github.event.release.body }}"
71 changes: 56 additions & 15 deletions frontend/Components/TextContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getUser, type User } from '../../Functions/DatabaseFunctions/Users'
import { formatPubKey } from '../../Functions/RelayFunctions/Users'
import getUnixTime from 'date-fns/getUnixTime'
import { useTheme } from 'react-native-paper'
import { nip19 } from 'nostr-tools'
import { getNip19Key, getNpub } from '../../lib/nostr/Nip19'
import { navigate } from '../../lib/Navigation'
import {
Expand Down Expand Up @@ -38,7 +39,7 @@ export const TextContent: React.FC<TextContentProps> = ({
}) => {
const theme = useTheme()
const { database } = useContext(AppContext)
const [userNames, setUserNames] = useState<Record<number, string>>({})
const [userNames, setUserNames] = useState<Record<string, string>>({})
const [loadedUsers, setLoadedUsers] = useState<number>(0)
const [urls, setUrls] = useState<Record<string, string>>({})
const [lnUrl, setLnUrl] = useState<string>()
Expand All @@ -53,7 +54,7 @@ export const TextContent: React.FC<TextContentProps> = ({
Linking.openURL(url)
}

const handleNip05NotePress: (nip19: string) => void = (nip19) => {
const handleNotePress: (nip19: string) => void = (nip19) => {
const noteId = getNip19Key(nip19)

if (noteId) {
Expand All @@ -67,12 +68,17 @@ export const TextContent: React.FC<TextContentProps> = ({
}
}

const handleNip05ProfilePress: (nip19: string) => void = (nip19) => {
const pubKey = getNip19Key(nip19)
const handleProfilePress: (matchingString: string) => void = (matchingString) => {
const npub = matchingString.replace('nostr:', '')
const decoded = nip19.decode(npub)

if (pubKey) {
navigate('Profile', { pubKey })
let pubKey = decoded.data as string

if (decoded.type === 'nprofile') {
pubKey = (decoded.data as nip19.ProfilePointer).pubkey
}

onPressUser({ id: pubKey, name: userNames[matchingString] ?? formatPubKey(npub) })
}

const handleMentionPress: (text: string) => void = (text) => {
Expand Down Expand Up @@ -102,26 +108,26 @@ export const TextContent: React.FC<TextContentProps> = ({
const mentionIndex: number = parseInt(matches[1])

if (userNames[mentionIndex]) {
return userNames[mentionIndex]
return `@${userNames[matchingString]}`
} else if (event) {
const tag = event.tags[mentionIndex]

if (tag) {
const kind = tag[0]
const pudKey = tag[1]
const pubKey = tag[1]

if (kind === 'e') return ''

if (database) {
getUser(pudKey, database).then((user) => {
getUser(pubKey, database).then((user) => {
setLoadedUsers(getUnixTime(new Date()))
setUserNames((prev) => {
if (user?.name) prev[mentionIndex] = `@${user.name}`
if (user?.name) prev[mentionIndex] = user.name
return prev
})
})
}
return `@${formatPubKey(getNpub(pudKey))}`
return `@${formatPubKey(getNpub(pubKey))}`
} else {
return matchingString
}
Expand All @@ -130,6 +136,33 @@ export const TextContent: React.FC<TextContentProps> = ({
}
}

const renderProfile: (matchingString: string, matches: string[]) => string = (
matchingString,
) => {
const decoded = nip19.decode(matchingString.replace('nostr:', ''))

let pubKey = decoded.data as string

if (decoded.type === 'nprofile') {
pubKey = (decoded.data as nip19.ProfilePointer).pubkey
}

if (userNames[matchingString]) {
return `@${userNames[matchingString]}`
} else {
if (database) {
getUser(pubKey, database).then((user) => {
setLoadedUsers(getUnixTime(new Date()))
setUserNames((prev) => {
if (user?.name) prev[matchingString] = user.name
return prev
})
})
}
return `@${formatPubKey(pubKey)}`
}
}

const linkPreview: (url: string) => string = (url) => {
if (validMediaUrl(url)) {
return 'video'
Expand Down Expand Up @@ -157,6 +190,13 @@ export const TextContent: React.FC<TextContentProps> = ({
return matchingString
}

const renderNote: (matchingString: string, matches: string[]) => string = (
_matchingString,
_matches,
) => {
return ''
}

const onLongPress: () => void = () => {
if (copyText) Clipboard.setString(text)
}
Expand Down Expand Up @@ -188,12 +228,13 @@ export const TextContent: React.FC<TextContentProps> = ({
style: styles.mention,
},
{ pattern: /#(\w+)/, style: styles.hashTag, onPress: handleHashtagPress },
{ pattern: /(lnbc)\S+/, style: styles.nip19, renderText: renderLnurl },
{ pattern: /(nevent1)\S+/, style: styles.nip19, onPress: handleNip05NotePress },
{ pattern: /\b(lnbc)\S+\b/, style: styles.nip19, renderText: renderLnurl },
{ pattern: /\b(nostr:)?(nevent1|note1)\S+\b/, style: styles.nip19, onPress: handleNotePress, renderText: renderNote },
{
pattern: /(npub1|nprofile1)\S+/,
pattern: /\b(nostr:)?(npub1|nprofile1)\S+\b/,
style: styles.nip19,
onPress: handleNip05ProfilePress,
renderText: renderProfile,
onPress: handleProfilePress,
},
{
pattern: getHightlightText(),
Expand Down
30 changes: 15 additions & 15 deletions frontend/Contexts/RelayPoolContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export interface RelayPoolContextProps {
loadRelays: () => Promise<Relay[]>
createRandomRelays: () => Promise<void>
sendEvent: (event: Event, relayUrl?: string) => Promise<Event | null | undefined>
newNotifications: boolean
setNewNotifications: (newNotifications: boolean) => void
newDirectMessages: boolean
setNewDirectMessages: (newDirectMessages: boolean) => void
newGroupMessages: boolean
setNewGroupMessages: (newGroupMessages: boolean) => void
newNotifications: number
setNewNotifications: (newNotifications: number) => void
newDirectMessages: number
setNewDirectMessages: (newDirectMessages: number) => void
newGroupMessages: number
setNewGroupMessages: (newGroupMessages: number) => void
}

export interface WebsocketEvent {
Expand All @@ -56,11 +56,11 @@ export const initialRelayPoolContext: RelayPoolContextProps = {
loadRelays: async () => [],
createRandomRelays: async () => {},
sendEvent: async () => null,
newNotifications: false,
newNotifications: 0,
setNewNotifications: () => {},
newDirectMessages: false,
newDirectMessages: 0,
setNewDirectMessages: () => {},
newGroupMessages: false,
newGroupMessages: 0,
setNewGroupMessages: () => {},
}

Expand All @@ -76,9 +76,9 @@ export const RelayPoolContextProvider = ({
const [lastConfirmationtId, setLastConfirmationId] = useState<string>('')
const [relays, setRelays] = React.useState<Relay[]>([])
const [displayRelayDrawer, setDisplayrelayDrawer] = React.useState<string>()
const [newNotifications, setNewNotifications] = useState<boolean>(false)
const [newDirectMessages, setNewDirectMessages] = useState<boolean>(false)
const [newGroupMessages, setNewGroupMessages] = useState<boolean>(false)
const [newNotifications, setNewNotifications] = useState<number>(0)
const [newDirectMessages, setNewDirectMessages] = useState<number>(0)
const [newGroupMessages, setNewGroupMessages] = useState<number>(0)

const sendEvent: (event: Event, relayUrl?: string) => Promise<Event | null | undefined> = async (
event,
Expand Down Expand Up @@ -132,11 +132,11 @@ export const RelayPoolContextProvider = ({
}
const changeNotificationHandler: (event: WebsocketEvent) => void = (event) => {
if (event.kind === '4') {
setNewDirectMessages(true)
setNewDirectMessages((prev) => prev + 1)
} else if (event.kind === '42') {
setNewGroupMessages(true)
setNewGroupMessages((prev) => prev + 1)
} else {
setNewNotifications(true)
setNewNotifications((prev) => prev + 1)
}
}

Expand Down
8 changes: 6 additions & 2 deletions frontend/Functions/DatabaseFunctions/Notifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export interface Notification {
event_id?: string
tags: string[][]
name: string
zapper_user_id: string
zapper_name: string
}
const databaseToEntity: (object: any) => Notification = (object) => {
object.tags = object.tags ? JSON.parse(object.tags) : []
Expand All @@ -27,11 +29,13 @@ export const getNotifications: (
) => Promise<Notification[]> = async (db, { limit, since }) => {
let notificationsQuery = `
SELECT
nostros_notifications.*, nostros_users.name
nostros_notifications.*, users1.name, users2.name as zapper_name
FROM
nostros_notifications
LEFT JOIN
nostros_users ON nostros_users.id = nostros_notifications.pubkey
nostros_users users1 ON users1.id = nostros_notifications.pubkey
LEFT JOIN
nostros_users users2 ON users2.id = nostros_notifications.zapper_user_id
`
if (since) {
notificationsQuery += `WHERE nostros_notifications.created_at > ${since} `
Expand Down
11 changes: 0 additions & 11 deletions frontend/Functions/DatabaseFunctions/Relays/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { type QuickSQLiteConnection } from 'react-native-quick-sqlite'
import { getItems } from '..'
import { median } from '../../NativeFunctions'
import { getNoteRelaysUsage } from '../NotesRelays'

export interface Relay {
url: string
Expand Down Expand Up @@ -66,12 +64,3 @@ export const getRelay: (db: QuickSQLiteConnection, url: string) => Promise<Relay
const relays: Relay[] = items.map((object) => databaseToEntity(object))
return relays[0]
}

export const getResilientRelays: (db: QuickSQLiteConnection) => Promise<string[]> = async (db) => {
const relayUsage = await getNoteRelaysUsage(db)
const medianUsage = median(Object.values(relayUsage))
const resilientRelays = Object.keys(relayUsage).sort((n1: string, n2: string) => {
return Math.abs(relayUsage[n1] - medianUsage) - Math.abs(relayUsage[n2] - medianUsage)
})
return resilientRelays
}
2 changes: 1 addition & 1 deletion frontend/Functions/NativeFunctions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export const validTubeUrl: (url: string | undefined) => boolean = (url) => {

export const validBlueBirdUrl: (url: string | undefined) => boolean = (url) => {
if (url) {
const serviceRegexp = /^(https?:\/\/.*\.?(twitter.com|t.co){1}.*)$/
const serviceRegexp = /^(https?:\/\/.*\.?(twitter.com|t.co|x.com){1}.*)$/
return serviceRegexp.test(url)
} else {
return false
Expand Down
1 change: 0 additions & 1 deletion frontend/Pages/FeedNavigator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export const HomeNavigator: React.FC = () => {
const {
displayUserDrawer,
displayNoteDrawer,
setDisplayUserDrawer,
setRefreshBottomBarAt,
database,
} = React.useContext(AppContext)
Expand Down
2 changes: 1 addition & 1 deletion frontend/Pages/HomePage/ConversationsFeed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const ConversationsFeed: React.FC = () => {
)

useEffect(() => {
setNewDirectMessages(false)
setNewDirectMessages(0)
loadDirectMessages(false)
}, [lastEventId, refreshBottomBarAt])

Expand Down
2 changes: 1 addition & 1 deletion frontend/Pages/HomePage/GroupsFeed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const GroupsFeed: React.FC = () => {
)

useEffect(() => {
setNewGroupMessages(false)
setNewGroupMessages(0)
loadGroups()
}, [lastEventId, lastConfirmationtId, refreshBottomBarAt])

Expand Down
Loading

0 comments on commit f839a96

Please sign in to comment.