Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some bugs #154

Merged
merged 7 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import * as storage from "./utils/storage"
import { customFontsToLoad } from "./theme"
import { setupReactotron } from "./services/reactotron"
import Config from "./config"
import RelayProvider from "./components/RelayProvider"
import { RelayProvider } from "./components/RelayProvider"

// Set up Reactotron, which is a free desktop app for inspecting and debugging
// React Native apps. Learn more here: https://github.com/infinitered/reactotron
Expand Down
2 changes: 2 additions & 0 deletions app/components/ChannelItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export function ChannelItem({ id }: { id: string }) {
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setMetadata(content)
} else {
console.log("channel metadata not found", id)
}
}

Expand Down
42 changes: 28 additions & 14 deletions app/components/RelayProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
import React, { createContext, useEffect, useMemo } from "react"
import { useStores } from "app/models"
import { nip19 } from "nostr-tools"
import { connectDb, ArcadeIdentity, NostrPool } from "arclib/src"
import { observer } from "mobx-react-lite"

export const DEFAULT_RELAYS = [
"wss://relay.arcade.city",
"wss://arc1.arcadelabs.co",
"wss://welcome.nostr.wine",
"wss://relay.nostr.band/all",
"wss://nostr.mutinywallet.com",
"wss://relay.damus.io",
]

export const RelayContext = createContext({})

export default function RelayProvider({ children }: { children: React.ReactNode }) {
const db: any = connectDb()

export const RelayProvider = observer(function RelayProvider({
children,
}: {
children: React.ReactNode
}) {
if (!db) throw new Error("cannot initialized db")

const {
userStore: { privkey },
userStore: { privkey, metadata, isNewUser, clearNewUser },
} = useStores()

const db: any = useMemo(() => connectDb(), [])
const nsec = useMemo(() => (privkey ? nip19.nsecEncode(privkey) : null), [privkey])
const ident = useMemo(() => (nsec ? new ArcadeIdentity(nsec, "", "") : null), [nsec])
const pool = useMemo(() => (ident ? new NostrPool(ident, db) : null), [ident])
const ident = useMemo(() => (privkey ? new ArcadeIdentity(privkey, "", "") : null), [privkey])
const pool = useMemo(() => (ident ? new NostrPool(ident, db) : null), [privkey])

useEffect(() => {
if (!pool) return

async function initRelays() {
await pool.setRelays(DEFAULT_RELAYS)
if (isNewUser) {
console.log("creating user...")
pool.send({
content: metadata,
tags: [],
kind: 0,
})
clearNewUser()
}
}

if (nsec) {
initRelays().catch(console.error)
}
}, [pool, nsec])
initRelays().catch(console.error)
}, [pool])

return <RelayContext.Provider value={pool}>{children}</RelayContext.Provider>
}
})
2 changes: 2 additions & 0 deletions app/components/User.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export function User({ pubkey }: { pubkey: string }) {
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setProfile(content)
} else {
console.log("user profile not found", pubkey)
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/components/UserFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export function UserFeed({ pubkey }: { pubkey: string }) {
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setProfile(content)
} else {
console.log("user profile not found", pubkey)
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/components/UserOffer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export function UserOffer({ pubkey }: { pubkey: string }) {
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setProfile(content)
} else {
console.log("user profile not found", pubkey)
}
}

Expand Down
19 changes: 7 additions & 12 deletions app/models/UserStore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Instance, SnapshotIn, SnapshotOut, types } from "mobx-state-tree"
import { withSetPropAction } from "./helpers/withSetPropAction"
import { generatePrivateKey, getPublicKey, nip19 } from "nostr-tools"
import { ArcadeIdentity, NostrPool } from "arclib/src"

/**
* Model description here for TypeScript hints.
Expand All @@ -11,7 +10,9 @@ export const UserStoreModel = types
.props({
pubkey: "",
privkey: "",
metadata: "",
isLoggedIn: false,
isNewUser: false,
channels: types.optional(types.array(types.string), [
"1abf8948d2fd05dd1836b33b324dca65138b2e80c77b27eeeed4323246efba4d", // Arcade Open R&D
"d4de13fde818830703539f80ae31ce3419f8f18d39c3043013bee224be341c3b", // Arcade Exchange Test
Expand All @@ -32,21 +33,12 @@ export const UserStoreModel = types
async signup(username: string, displayName: string, about: string) {
const privkey = generatePrivateKey()
const pubkey = getPublicKey(privkey)
const nsec = nip19.nsecEncode(privkey)

self.setProp("pubkey", pubkey)
self.setProp("privkey", privkey)
self.setProp("isLoggedIn", true)

// publish
const ident = new ArcadeIdentity(nsec, "", "")
const pool = new NostrPool(ident)
await pool.setRelays(["wss://relay.damus.io"])
await pool.send({
content: JSON.stringify({ display_name: displayName, name: username, about }),
tags: [],
kind: 0,
})
self.setProp("isNewUser", true)
self.setProp("metadata", JSON.stringify({display_name: displayName, username, about}))
},
async loginWithNsec(nsec: string) {
if (!nsec.startsWith("nsec1") || nsec.length < 60) {
Expand Down Expand Up @@ -74,6 +66,9 @@ export const UserStoreModel = types

console.log("Removed keys from storage.")
},
clearNewUser() {
self.setProp("isNewUser", false)
}
})) // eslint-disable-line @typescript-eslint/no-unused-vars

export interface UserStore extends Instance<typeof UserStoreModel> {}
Expand Down
25 changes: 17 additions & 8 deletions app/screens/ChatScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { FC, useContext, useEffect, useLayoutEffect, useMemo } from "react"
import React, { FC, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react"
import { observer } from "mobx-react-lite"
import { Pressable, TextStyle, View, ViewStyle, Alert } from "react-native"
import { Pressable, TextStyle, View, ViewStyle, Alert, ActivityIndicator } from "react-native"
import { NativeStackScreenProps } from "@react-navigation/native-stack"
import { AppStackScreenProps } from "app/navigators"
import {
Expand Down Expand Up @@ -41,6 +41,8 @@ export const ChatScreen: FC<ChatScreenProps> = observer(function ChatScreen({
// Pull in navigation via hook
const navigation = useNavigation<any>()

const [loading, setLoading] = useState(true)

const leaveJoinedChannel = () => {
Alert.alert("Confirm leave channel", "Are you sure?", [
{
Expand Down Expand Up @@ -87,16 +89,17 @@ export const ChatScreen: FC<ChatScreenProps> = observer(function ChatScreen({
}

async function subscribe() {
// stop loading
setLoading(false)
console.log("subscribing...")
return await channel.sub(id, handleNewMessage, {
since: Math.floor(Date.now() / 1000),
})
}

// fetch all channel messages
channelStore.fetchMessages(channel, id)

// subscribe for new messages
console.log("subscribing...")
subscribe().catch(console.error)

return () => {
Expand All @@ -105,7 +108,7 @@ export const ChatScreen: FC<ChatScreenProps> = observer(function ChatScreen({
// clear channel store
channelStore.reset()
}
}, [route, channel])
}, [route, userStore, channel])

return (
<BottomSheetModalProvider>
Expand Down Expand Up @@ -138,9 +141,15 @@ export const ChatScreen: FC<ChatScreenProps> = observer(function ChatScreen({
</View>
)}
ListEmptyComponent={
<View style={$emptyState}>
<Text text="Loading..." />
</View>
loading ? (
<View style={$emptyState}>
<ActivityIndicator color={colors.palette.cyan500} animating={loading} />
</View>
) : (
<View style={$emptyState}>
<Text text="No message..." />
</View>
)
}
estimatedItemSize={100}
inverted={true}
Expand Down
23 changes: 16 additions & 7 deletions app/screens/DirectMessageScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { FC, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react"
import { observer } from "mobx-react-lite"
import { TextStyle, View, ViewStyle } from "react-native"
import { ActivityIndicator, TextStyle, View, ViewStyle } from "react-native"
import { NativeStackScreenProps } from "@react-navigation/native-stack"
import { AppStackScreenProps } from "app/navigators"
import { DirectMessageForm, Header, RelayContext, Screen, Text, User } from "app/components"
import { useNavigation } from "@react-navigation/native"
import { colors, spacing } from "app/theme"
import { FlashList } from "@shopify/flash-list"
import TextWithImage from "app/components/TextWithImage"
import Nip04Manager from "arclib/src/private"
import PrivateMessageManager from "arclib/src/private"

interface DirectMessageScreenProps
extends NativeStackScreenProps<AppStackScreenProps<"DirectMessage">> {}
Expand All @@ -19,8 +19,9 @@ export const DirectMessageScreen: FC<DirectMessageScreenProps> = observer(
const navigation = useNavigation<any>()
const pool: any = useContext(RelayContext)

const dms = useMemo(() => new Nip04Manager(pool), [pool])
const dms = useMemo(() => new PrivateMessageManager(pool), [pool])
const [data, setData] = useState([])
const [loading, setLoading] = useState(true)

useLayoutEffect(() => {
navigation.setOptions({
Expand Down Expand Up @@ -51,6 +52,8 @@ export const DirectMessageScreen: FC<DirectMessageScreenProps> = observer(
const list = await dms.list({}, true, id)
// update state
setData(list.reverse())
// stop loading
setLoading(false)
}

// fetch direct messages
Expand All @@ -64,7 +67,7 @@ export const DirectMessageScreen: FC<DirectMessageScreenProps> = observer(
console.log("unsubscribing...")
pool.unsub(handleNewMessage)
}
}, [dms])
}, [id, dms])

return (
<Screen style={$root} preset="fixed" safeAreaEdges={["bottom"]} keyboardOffset={120}>
Expand All @@ -85,9 +88,15 @@ export const DirectMessageScreen: FC<DirectMessageScreenProps> = observer(
</View>
)}
ListEmptyComponent={
<View style={$emptyState}>
<Text text="Loading..." />
</View>
loading ? (
<View style={$emptyState}>
<ActivityIndicator color={colors.palette.cyan500} animating={loading} />
</View>
) : (
<View style={$emptyState}>
<Text text="No message..." />
</View>
)
}
estimatedItemSize={100}
inverted={true}
Expand Down
12 changes: 11 additions & 1 deletion app/screens/HomeMessagesScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { observer } from "mobx-react-lite"
import { View, ViewStyle } from "react-native"
import { NativeStackScreenProps } from "@react-navigation/native-stack"
import { AppStackScreenProps } from "app/navigators"
import { ScreenWithSidebar, ChannelItem } from "app/components"
import { ScreenWithSidebar, ChannelItem, Text } from "app/components"
import { spacing } from "app/theme"
import { FlashList } from "@shopify/flash-list"
import { useStores } from "app/models"
Expand All @@ -24,6 +24,11 @@ export const HomeMessagesScreen: FC<HomeMessagesScreenProps> = observer(
data={userStore.channels.slice()}
keyExtractor={(item) => item}
renderItem={({ item }) => <ChannelItem id={item} />}
ListEmptyComponent={
<View style={$emptyState}>
<Text text="No channel..." />
</View>
}
estimatedItemSize={50}
/>
</View>
Expand Down Expand Up @@ -58,3 +63,8 @@ const $messsages: ViewStyle = {
paddingVertical: spacing.extraSmall,
// paddingHorizontal: spacing.small,
}

const $emptyState: ViewStyle = {
alignSelf: "center",
paddingVertical: spacing.medium,
}
2 changes: 1 addition & 1 deletion app/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { observer } from "mobx-react-lite"
import { TextStyle, View, ViewStyle } from "react-native"
import { NativeStackScreenProps } from "@react-navigation/native-stack"
import { AppStackScreenProps } from "app/navigators"
import { Button, CityBackground, Screen, Spotlight, Text } from "app/components"
import { Button, CityBackground, Screen, Text } from "app/components"
import { useNavigation } from "@react-navigation/native"
import { colors, spacing } from "app/theme"

Expand Down
13 changes: 11 additions & 2 deletions app/screens/ProfileScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ export const ProfileScreen: FC<ProfileScreenProps> = observer(function ProfileSc
const [profile, setProfile] = useState(null)

// Pull in one of our MST stores
const { userStore } = useStores()
const { userStore, channelStore } = useStores()

// Pull in navigation via hook
const navigation = useNavigation<any>()

const logout = () => {
// clear user store
userStore.logout()
// clear channel store
channelStore.reset()
}

useLayoutEffect(() => {
navigation.setOptions({
headerShown: true,
Expand All @@ -36,7 +43,7 @@ export const ProfileScreen: FC<ProfileScreenProps> = observer(function ProfileSc
<Pressable onPress={() => navigation.navigate("EditProfile")}>
<EditIcon size={20} color={colors.palette.cyan400} />
</Pressable>
<Pressable onPress={() => userStore.logout()}>
<Pressable onPress={() => logout()}>
<LogOutIcon size={20} color={colors.palette.cyan400} />
</Pressable>
</View>
Expand All @@ -52,6 +59,8 @@ export const ProfileScreen: FC<ProfileScreenProps> = observer(function ProfileSc
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setProfile(content)
} else {
alert("relay return nothing")
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/screens/UserScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export const UserScreen: FC<UserScreenProps> = observer(function UserScreen({
if (list.length > 0) {
const content = JSON.parse(list[0].content)
setProfile(content)
} else {
alert("relay return nothing")
}
}

Expand Down
6 changes: 6 additions & 0 deletions bin/postInstall
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
* have to remember these extra steps.
*/

// init submodule
run("git submodule update --init")

// update submodule
run("git submodule update --remote --merge")

// Patch any packages that need patching
run("npx patch-package")

Expand Down
2 changes: 1 addition & 1 deletion packages/arclib
Loading