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

[arcade-chat] Basic chat channels+messages flow works #28

Merged
merged 31 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
992eca5
before axe ws tests
AtlantisPleb Aug 2, 2022
61b2950
axe that for now
AtlantisPleb Aug 2, 2022
0d54440
Axe server ws
AtlantisPleb Aug 2, 2022
f374271
Add use-arcade store
AtlantisPleb Aug 2, 2022
cdc27a2
Initial subscribe
AtlantisPleb Aug 2, 2022
5478178
Fix type of useRideRequests
AtlantisPleb Aug 2, 2022
e7f8cb0
useRideRequests() working
AtlantisPleb Aug 2, 2022
bca8dd6
Try pull in UI, eh
AtlantisPleb Aug 2, 2022
2eabedf
Rename nostr-client to arcade-chat
AtlantisPleb Aug 2, 2022
eeee29a
replace microbundle w tsup
AtlantisPleb Aug 2, 2022
643860f
Button to create demo chatroom
AtlantisPleb Aug 2, 2022
a479a35
createDemoChannel good except needs random
AtlantisPleb Aug 2, 2022
0ab05ed
Creating demo channel event (not yet sending)
AtlantisPleb Aug 2, 2022
d326f3a
Fix kind
AtlantisPleb Aug 2, 2022
4a0a8e6
Storing/retrieving event 40s
AtlantisPleb Aug 2, 2022
5760360
Initial ChannelList with channel type
AtlantisPleb Aug 2, 2022
82da6b5
use NostrKind
AtlantisPleb Aug 2, 2022
96e22b9
ChannelList
AtlantisPleb Aug 2, 2022
0895fa9
Set up ChannelPreview and navto
AtlantisPleb Aug 2, 2022
445470c
Pull over tabbar and nav stuff
AtlantisPleb Aug 2, 2022
306846a
Fix UI depending on RN 0.69.1
AtlantisPleb Aug 2, 2022
9fb50be
Basic ChannelPreview/ChannelNav
AtlantisPleb Aug 2, 2022
0ab0d18
grab channel id param and axe require cycle
AtlantisPleb Aug 2, 2022
c7202ed
switch up tab icons
AtlantisPleb Aug 2, 2022
772d1d5
Initial ChannelScreen/Message placeholders
AtlantisPleb Aug 3, 2022
8a66bd5
MessageInput UI
AtlantisPleb Aug 3, 2022
b8e9f90
Navbutton back for Channel
AtlantisPleb Aug 3, 2022
18ee69d
MessageInput ready to send
AtlantisPleb Aug 3, 2022
70355a7
Send first message
AtlantisPleb Aug 3, 2022
575a72e
useChannelMessages works
AtlantisPleb Aug 3, 2022
8299908
Basic chat flow works
AtlantisPleb Aug 3, 2022
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
File renamed without changes.
23 changes: 21 additions & 2 deletions apps/nostr-client/App.tsx → apps/arcade-chat/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'text-encoding-polyfill'
import { StatusBar } from 'expo-status-bar'
import { useEffect } from 'react'
import { Button, View } from 'react-native'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { useArcadeRelay } from '@arcadecity/use-arcade'
import useCachedResources from './hooks/useCachedResources'
Expand All @@ -8,15 +11,31 @@ import Navigation from './navigation'
export const App = () => {
const isLoadingComplete = useCachedResources()
const colorScheme = useColorScheme()
useArcadeRelay()
const [state, actions] = useArcadeRelay()

useEffect(() => {
if (!state.ready) return
actions.initialSubscribe()
}, [state.ready])

if (!isLoadingComplete) {
return null
} else {
return (
<SafeAreaProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
<StatusBar style='light' />
{/* <View
style={{
position: 'absolute',
bottom: 95,
left: 0,
right: 0,
flex: 1,
justifyContent: 'center',
}}>
<Button title='CREATE DEMO CHANNEL' onPress={actions.createDemoChannel} />
</View> */}
</SafeAreaProvider>
)
}
Expand Down
7 changes: 3 additions & 4 deletions apps/nostr-client/app.json → apps/arcade-chat/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true
"supportsTablet": true,
"bundleIdentifier": "arcade.city.mobile"
},
"android": {
"adaptiveIcon": {
Expand Down
File renamed without changes.
25 changes: 25 additions & 0 deletions apps/arcade-chat/components/ChannelList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Channel, useChannelsCreated } from '@arcadecity/use-arcade'
import { FlatList, StyleSheet, Text } from 'react-native'
import { ChannelPreview } from './ChannelPreview'

export const ChannelList = () => {
const channels: Channel[] = useChannelsCreated()
return (
<FlatList
data={channels}
keyExtractor={keyExtractor}
renderItem={renderItem}
style={[styles.flatList, { backgroundColor: '#120B29' }]}
/>
)
}

const keyExtractor = (item: Channel) => item.id

const renderItem = ({ item }: { item: Channel }) => <ChannelPreview channel={item} />

const styles = StyleSheet.create({
flatList: { flex: 1 },
flatListContentContainer: { flexGrow: 1 },
statusIndicator: { left: 0, position: 'absolute', right: 0, top: 0 },
})
17 changes: 17 additions & 0 deletions apps/arcade-chat/components/ChannelPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Channel, setActiveChannelId } from '@arcadecity/use-arcade'
import { useNavigation } from '@react-navigation/native'
import { useCallback } from 'react'
import { Text, TouchableOpacity } from 'react-native'

export const ChannelPreview = ({ channel }: { channel: Channel }) => {
const navigation = useNavigation()
const navToIt = useCallback(() => {
setActiveChannelId(channel.id)
navigation.navigate('channel', { channelId: channel.id })
}, [channel.id])
return (
<TouchableOpacity key={channel.id} onPress={navToIt} activeOpacity={0.8}>
<Text style={{ color: '#EEECFB', padding: 10 }}>{channel.name}</Text>
</TouchableOpacity>
)
}
80 changes: 80 additions & 0 deletions apps/arcade-chat/components/MessageInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { color, palette } from '@arcadecity/ui'
import { Alert, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native'
import { FontAwesome } from '@expo/vector-icons'
import { useContext, useState } from 'react'
import { ArcadeContext, useActiveChannelId, UseArcadeRelayActions } from '@arcadecity/use-arcade'

export const MessageInput = () => {
const [text, setText] = useState('')
const context = useContext(ArcadeContext)
const activeChannelId = useActiveChannelId()
const actions = context.actions as UseArcadeRelayActions
const submitInput = () => {
if (text.length < 1) {
Alert.alert('Message too short', 'What is that, a message for ants?')
return
}
if (!activeChannelId) {
Alert.alert('Error getting channel ID')
return
}
actions.sendChannelMessage(activeChannelId, text)
}
return (
<View style={styles.container}>
<View style={styles.composerContainer}>
<View style={styles.inputContainer}>
<TextInput
autoCorrect={false}
multiline
onChangeText={(text: string) => setText(text)}
spellCheck={false}
style={styles.inputBox}
/>
<TouchableOpacity
activeOpacity={0.8}
onPress={submitInput}
style={styles.sendButtonContainer}>
<FontAwesome name='send' size={24} color={palette.blueBell} />
</TouchableOpacity>
</View>
</View>
</View>
)
}

const styles = StyleSheet.create({
composerContainer: {
alignItems: 'flex-end',
flexDirection: 'row',
flex: 1,
},
container: {
backgroundColor: palette.purple,
borderTopWidth: 1,
borderTopColor: palette.portGore,
padding: 10,
height: 60,
},
inputBox: {
backgroundColor: color.field,
color: color.text,
flexGrow: 1,
fontSize: 14,
height: 40,
borderRadius: 10,
includeFontPadding: false,
padding: 10,
textAlignVertical: 'center',
},
inputContainer: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
paddingLeft: 6,
paddingRight: 6,
},
sendButtonContainer: {
marginLeft: 14,
},
})
40 changes: 40 additions & 0 deletions apps/arcade-chat/components/MessageList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { color, spacing } from '@arcadecity/ui'
import { Message, useActiveChannelId, useChannelMessages } from '@arcadecity/use-arcade'
import { FlatList, StyleSheet, View } from 'react-native'
import { MessagePreview } from './message/message'

export const MessageList = () => {
const activeChannelId = useActiveChannelId()
if (!activeChannelId) return <></>
const messages: Message[] = useChannelMessages(activeChannelId)
return (
<View style={styles.container}>
<FlatList
data={messages}
keyExtractor={keyExtractor}
renderItem={renderItem}
style={[styles.flatList, { backgroundColor: '#120B29' }]}
/>
</View>
)
}

const keyExtractor = (item: Message) => item.id

const pubkey = 'd67fe59472f658c1b2dec9ffd60b86af260a2f8460b441f9a891761f87b67a5d'
const renderItem = ({ item }: { item: Message }) => (
<MessagePreview message={item} preset={pubkey === item.pubkey ? 'sent' : 'received'} />
)

const styles = StyleSheet.create({
container: {
paddingHorizontal: spacing[4],
backgroundColor: color.background,
flex: 1,
width: '100%',
},
contentContainer: {
flexGrow: 1,
},
flatList: { flex: 1 },
})
12 changes: 12 additions & 0 deletions apps/arcade-chat/components/MessagePreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Message } from '@arcadecity/use-arcade'
import { Text, TouchableOpacity } from 'react-native'

export const MessagePreview = ({ message }: { message: Message }) => {
return (
<TouchableOpacity key={message.id} activeOpacity={0.8}>
<Text style={{ color: '#EEECFB', padding: 10 }}>{message.text}</Text>
<Text style={{ color: '#EEECFB', padding: 10 }}>{message.created_at}</Text>
<Text style={{ color: '#EEECFB', padding: 10 }}>{message.pubkey}</Text>
</TouchableOpacity>
)
}
Empty file.
1 change: 1 addition & 0 deletions apps/arcade-chat/components/message/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './message'
104 changes: 104 additions & 0 deletions apps/arcade-chat/components/message/message.presets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Platform, ViewStyle, TextStyle } from 'react-native'
import { color, spacing, typography } from '@arcadecity/ui'

const STATUS_ROW = {
marginVertical: spacing[2],
marginLeft: spacing[2],
flexDirection: 'row',
}

const BASE_MESSAGE = {
container: {
flexDirection: 'row',
marginTop: 20,
} as ViewStyle,
avatarContainer: {
alignSelf: 'flex-end',
} as ViewStyle,
textBubble: {
flex: 1,
borderTopLeftRadius: 30,
borderBottomLeftRadius: 30,
borderTopRightRadius: 30,
backgroundColor: color.palette.moonRaker,
paddingHorizontal: spacing[2],
marginRight: spacing[4],
...Platform.select({
ios: {
shadowColor: color.palette.black,
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.5,
shadowRadius: 4,
},
// android: { TODO: Figure out why this causes typescript error
// elevation: 5,
// },
}),
} as ViewStyle,
textContent: {
marginHorizontal: spacing[4],
marginVertical: spacing[4],
color: color.palette.minsk,
fontFamily: typography.primary,
} as TextStyle,
date: {
...STATUS_ROW,
} as ViewStyle,
dateText: {
fontSize: 11,
color: color.palette.blueBell,
fontFamily: typography.primary,
} as TextStyle,
error: {
...STATUS_ROW,
} as ViewStyle,
errorText: {
fontSize: 12,
color: color.error,
fontFamily: typography.primary,
} as TextStyle,
errorIcon: {
marginRight: spacing[1],
alignSelf: 'center',
},
}

export const messagePresets = {
sent: BASE_MESSAGE,
received: {
...BASE_MESSAGE,
container: {
flexDirection: 'row-reverse',
marginTop: 20,
} as ViewStyle,
textBubble: {
...BASE_MESSAGE.textBubble,
marginRight: 0,
marginLeft: spacing[4],
borderBottomRightRadius: 30,
borderBottomLeftRadius: 0,
backgroundColor: color.palette.electricIndigo,
} as ViewStyle,
textContent: {
...BASE_MESSAGE.textContent,
color: color.palette.moonRaker,
} as TextStyle,
date: {
...BASE_MESSAGE.date,
justifyContent: 'flex-end',
marginRight: spacing[2],
} as ViewStyle,
error: {
...BASE_MESSAGE.error,
justifyContent: 'flex-end',
marginRight: spacing[2],
} as ViewStyle,
},
}
/**
* A list of preset names.
*/
export type MessagePresetNames = keyof typeof messagePresets
Loading