@@ -16,10 +16,14 @@ import {
1616 enderChatPrefix ,
1717 sendMessageError
1818} from './packetHandler'
19+ import { createConnection } from './sessionBuilder'
1920import globalStyle from '../../globalStyle'
2021import useDarkMode from '../../context/useDarkMode'
22+ import AccountsContext from '../../context/accountsContext'
23+ import ServersContext from '../../context/serversContext'
24+ import useSessionStore from '../../context/sessionStore'
2125import SettingsContext from '../../context/settingsContext'
22- import ConnectionContext from '../../context/connectionContext'
26+ import ConnectionContext , { Connection } from '../../context/connectionContext'
2327import {
2428 ChatToJsx ,
2529 mojangColorMap ,
@@ -41,6 +45,8 @@ interface RootStackParamList {
4145}
4246type Props = NativeStackScreenProps < RootStackParamList , 'Chat' >
4347
48+ export type Status = 'OPENING' | 'CONNECTING' | 'CONNECTED' | 'CLOSED'
49+
4450interface Message {
4551 key : number
4652 text : MinecraftChat
@@ -84,17 +90,26 @@ const handleError =
8490 addMessage ( enderChatPrefix + translated )
8591 }
8692
93+ const isConnection = ( connection : any ) : connection is Connection =>
94+ ! ! ( connection as Connection ) . connection
95+
8796// TODO: Ability to copy text.
8897const ChatScreen = ( { navigation, route } : Props ) => {
8998 const darkMode = useDarkMode ( )
9099 const { settings } = useContext ( SettingsContext )
91- const { connection, setConnection } = useContext ( ConnectionContext )
100+ const { servers } = useContext ( ServersContext )
101+ const { accounts, setAccounts } = useContext ( AccountsContext )
102+ const { connection, setConnection, setDisconnectReason } =
103+ useContext ( ConnectionContext )
104+ const { sessions, setSession } = useSessionStore ( )
92105 // TODO: Show command history.
93106 const [ , setCommandHistory ] = useState < string [ ] > ( [ ] )
94107 const [ settingsOpen , setSettingsOpen ] = useState ( false )
95108 const [ messages , setMessages ] = useState < Message [ ] > ( [ ] )
96109 const [ loggedIn , setLoggedIn ] = useState ( false )
97110 const [ message , setMessage ] = useState ( '' )
111+ const healthRef = useRef < number | null > ( null )
112+ const statusRef = useRef < Status > ( connection ? 'CONNECTING' : 'OPENING' )
98113 const idRef = useRef ( 0 )
99114
100115 const charLimit =
@@ -106,17 +121,67 @@ const ChatScreen = ({ navigation, route }: Props) => {
106121 const trunc = m . length > 500 ? m . slice ( 0 , 499 ) : m
107122 return [ { key : idRef . current ++ , text } ] . concat ( trunc )
108123 } )
124+ const closeChatScreen = ( ) => {
125+ if ( navigation . canGoBack ( ) && statusRef . current !== 'CLOSED' ) {
126+ navigation . goBack ( )
127+ }
128+ }
129+
130+ // Screen cleanup function.
131+ useEffect ( ( ) =>
132+ navigation . addListener ( 'beforeRemove' , ( ) => {
133+ statusRef . current = 'CLOSED'
134+ // Gracefully disconnect on unmount, destroy will be called in 20s automatically if needed.
135+ if ( connection ) {
136+ connection . connection . close ( )
137+ setConnection ( undefined )
138+ }
139+ } )
140+ )
141+
142+ // Create connection useEffect.
143+ useEffect ( ( ) => {
144+ if ( statusRef . current === 'OPENING' ) {
145+ statusRef . current = 'CONNECTING'
146+ createConnection (
147+ route . params . serverName ,
148+ route . params . version ,
149+ servers ,
150+ settings ,
151+ accounts ,
152+ sessions ,
153+ setSession ,
154+ setAccounts ,
155+ setConnection ,
156+ setDisconnectReason ,
157+ closeChatScreen
158+ )
159+ . then ( conn => {
160+ console . log ( statusRef . current )
161+ console . log ( isConnection ( conn ) )
162+ if ( statusRef . current !== 'CLOSED' ) {
163+ if ( isConnection ( conn ) ) setConnection ( conn )
164+ else setDisconnectReason ( conn )
165+ } else if ( isConnection ( conn ) ) conn . connection . close ( ) // No memory leaky
166+ } )
167+ . catch ( ( ) => {
168+ closeChatScreen ( )
169+ setDisconnectReason ( {
170+ server : route . params . serverName ,
171+ reason : 'An error occurred resolving the server hostname!'
172+ } )
173+ } )
174+ }
175+ } )
109176
110177 // Packet handler useEffect.
111- const loggedInRef = useRef ( false )
112- const healthRef = useRef < number | null > ( null )
113178 useEffect ( ( ) => {
114179 if ( ! connection ) return
115180 connection . connection . on (
116181 'packet' ,
117182 packetHandler (
118183 healthRef ,
119- loggedInRef ,
184+ statusRef ,
120185 setLoggedIn ,
121186 connection . connection ,
122187 addMessage ,
@@ -138,19 +203,6 @@ const ChatScreen = ({ navigation, route }: Props) => {
138203 settings . sendSpawnCommand
139204 ] )
140205
141- // Cleanup useEffect on unload.
142- useEffect ( ( ) => {
143- if ( ! connection ) {
144- navigation . goBack ( ) // Safety net.
145- return
146- }
147- return ( ) => {
148- // Gracefully disconnect, destroy will be called in 20s automatically if needed.
149- connection . connection . close ( )
150- setConnection ( undefined )
151- }
152- } , [ connection , setConnection , navigation ] )
153-
154206 const sendMessage = ( msg : string , saveHistory : boolean ) => {
155207 if ( ! connection || ! msg ) return
156208 setMessage ( '' )
@@ -191,7 +243,6 @@ const ChatScreen = ({ navigation, route }: Props) => {
191243 }
192244 }
193245
194- if ( ! connection ) return < > </ > // This should never be hit hopefully.
195246 const title =
196247 route . params . serverName . length > 12
197248 ? route . params . serverName . substring ( 0 , 9 ) + '...'
@@ -203,7 +254,7 @@ const ChatScreen = ({ navigation, route }: Props) => {
203254 iconStyle = { styles . backButtonIcon }
204255 backgroundColor = '#363636'
205256 onPress = { ( ) => {
206- settingsOpen ? setSettingsOpen ( false ) : navigation . goBack ( )
257+ settingsOpen ? setSettingsOpen ( false ) : closeChatScreen ( )
207258 } }
208259 />
209260 </ View >
@@ -223,7 +274,7 @@ const ChatScreen = ({ navigation, route }: Props) => {
223274 onPress = { ( ) => setSettingsOpen ( true ) }
224275 />
225276 </ View >
226- { ! loggedIn && (
277+ { ( ! loggedIn || ! connection ) && (
227278 < View style = { styles . loadingScreen } >
228279 < ActivityIndicator
229280 color = '#00aaff'
@@ -235,7 +286,7 @@ const ChatScreen = ({ navigation, route }: Props) => {
235286 < Text style = { styles . loadingScreenText } > Connecting...</ Text >
236287 </ View >
237288 ) }
238- { loggedIn && (
289+ { loggedIn && connection && (
239290 < >
240291 < ChatMessageListMemo
241292 messages = { messages }
0 commit comments