Skip to content

Commit

Permalink
fix: use callback on react app init
Browse files Browse the repository at this point in the history
  • Loading branch information
siepra committed Apr 23, 2024
1 parent 8f759e0 commit 12b24d4
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import androidx.core.app.NotificationCompat
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.quietmobile.BuildConfig
import com.quietmobile.Communication.CommunicationModule
import com.quietmobile.MainApplication
import com.quietmobile.Notification.NotificationHandler
import com.quietmobile.R
import com.quietmobile.Scheme.WebsocketConnectionPayload
import com.quietmobile.Utils.Const
import com.quietmobile.Utils.Const.WEBSOCKET_CONNECTION_DELAY
import com.quietmobile.Utils.Utils
import com.quietmobile.Utils.isAppOnForeground
import io.socket.client.IO
Expand Down Expand Up @@ -98,35 +96,20 @@ class BackendWorker(private val context: Context, workerParams: WorkerParameters
withContext(Dispatchers.IO) {

// Get and store data port for usage in methods across the app
val dataPort = Utils.getOpenPort(11000)
val socketPort = Utils.getOpenPort(11000)
val socketIOSecret = Utils.generateRandomString(20)

(applicationContext as MainApplication).setSocketPort(socketPort)
(applicationContext as MainApplication).setSocketIOSecret(socketIOSecret)

// Init nodejs project
launch {
nodeProject.init()
}

launch {
notificationHandler = NotificationHandler(context)
subscribePushNotifications(dataPort, socketIOSecret)
}

launch {
/*
* Wait for CommunicationModule to be initialized with reactContext
* (there's no callback we can use for that purpose).
*
* Code featured below suspends nothing but the websocket connection
* and it doesn't affect anything besides that.
*
* In any case, websocket won't connect until data server starts listening
*/
val intervals: Array<Long> = arrayOf(30000)

for (interval in intervals) {
delay(interval)
startWebsocketConnection(dataPort, socketIOSecret)
}
subscribePushNotifications(socketPort, socketIOSecret)
}

val dataPath = Utils.createDirectory(context)
Expand All @@ -143,7 +126,7 @@ class BackendWorker(private val context: Context, workerParams: WorkerParameters
* https://github.com/TryQuiet/quiet/issues/2214
*/
delay(500)
startNodeProjectWithArguments("bundle.cjs --torBinary $torBinary --dataPath $dataPath --dataPort $dataPort --platform $platform --socketIOSecret $socketIOSecret")
startNodeProjectWithArguments("bundle.cjs --torBinary $torBinary --dataPath $dataPath --dataPort $socketPort --platform $platform --socketIOSecret $socketIOSecret")
}
}

Expand All @@ -159,8 +142,6 @@ class BackendWorker(private val context: Context, workerParams: WorkerParameters
return Result.success()
}

private external fun sendMessageToNodeChannel(channelName: String, message: String): Void

private external fun startNodeWithArguments(
arguments: Array<String?>?,
modulesPath: String?
Expand Down Expand Up @@ -218,17 +199,6 @@ class BackendWorker(private val context: Context, workerParams: WorkerParameters
notificationHandler.notify(message, username)
}

private fun startWebsocketConnection(port: Int, socketIOSecret: String) {
Log.d("WEBSOCKET CONNECTION", "Starting on $port")
// Proceed only if data port is defined
val websocketConnectionPayload = WebsocketConnectionPayload(port, socketIOSecret)
CommunicationModule.handleIncomingEvents(
CommunicationModule.WEBSOCKET_CONNECTION_CHANNEL,
Gson().toJson(websocketConnectionPayload),
"" // Empty extras
)
}

fun handleNodeMessages(channelName: String, msg: String?) {
print("handle node message - channel name $channelName")
print("handle node message - msg $msg")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import com.google.gson.Gson;
import com.quietmobile.MainApplication;
import com.quietmobile.Notification.NotificationHandler;
import com.quietmobile.Scheme.WebsocketConnectionPayload;

import androidx.annotation.NonNull;

Expand All @@ -24,6 +27,8 @@

public class CommunicationModule extends ReactContextBaseJavaModule {

public static final String APP_READY_CHANNEL = "_APP_READY_";

public static final String PUSH_NOTIFICATION_CHANNEL = "_PUSH_NOTIFICATION_";
public static final String WEBSOCKET_CONNECTION_CHANNEL = "_WEBSOCKET_CONNECTION_";
public static final String INIT_CHECK_CHANNEL = "_INIT_CHECK_";
Expand All @@ -48,14 +53,16 @@ public CommunicationModule(ReactApplicationContext reactContext) {
}

@ReactMethod
public static void handleIncomingEvents(String event, String payload, String extra) {
public static void handleIncomingEvents(String event, @Nullable String payload, @Nullable String extra) {
switch (event) {
case APP_READY_CHANNEL:
startWebsocketConnection();
break;
case PUSH_NOTIFICATION_CHANNEL:
String message = payload;
String username = extra;
notificationHandler.notify(message, username);
break;
case WEBSOCKET_CONNECTION_CHANNEL:
case INIT_CHECK_CHANNEL:
case BACKEND_CLOSED_CHANNEL:
passDataToReact(event, payload);
Expand Down Expand Up @@ -88,6 +95,15 @@ private static void sendEvent(@Nullable WritableMap params) {
}
}

private static void startWebsocketConnection() {
Context context = reactContext.getApplicationContext();
int port = ((MainApplication) context).getSocketPort();
String socketIOSecret = ((MainApplication) context).getSocketIOSecret();

WebsocketConnectionPayload websocketConnectionPayload = new WebsocketConnectionPayload(port, socketIOSecret);
passDataToReact(WEBSOCKET_CONNECTION_CHANNEL, new Gson().toJson(websocketConnectionPayload));
}

@ReactMethod
private static void deleteBackendData() {
Context context = reactContext.getApplicationContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ class MainApplication : Application(), ReactApplication {
createNotificationChannel()
}

private var socketPort: Int = 0
private var socketIOSecret: String = ""

fun getSocketPort(): Int {
return socketPort
}

fun setSocketPort(value: Int) {
this.socketPort = value
}

fun getSocketIOSecret(): String {
return socketIOSecret
}

fun setSocketIOSecret(value: String) {
this.socketIOSecret = value
}

private fun createForegroundServiceNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,4 @@ object Const {
const val NODEJS_PROJECT_DIR = "nodejs-project"
const val NODEJS_BUILTIN_NATIVE_ASSETS_PREFIX = "nodejs-native-assets-"
const val NODEJS_TRASH_DIR = "nodejs-project-trash"

// Websocket
const val WEBSOCKET_CONNECTION_DELAY: Long = 5000
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ object Utils {
return dataDirectory.absolutePath
}

@JvmStatic
fun generateRandomString(length: Int): String {
val CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
val secureRandom = SecureRandom()
Expand All @@ -43,6 +44,7 @@ object Utils {
return randomString.toString()
}

@JvmStatic
suspend fun getOpenPort(starting: Int) = suspendCoroutine<Int> { continuation ->
val port = checkPort(starting)
continuation.resume(port)
Expand Down
6 changes: 4 additions & 2 deletions packages/mobile/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useEffect } from 'react'
import { useDispatch } from 'react-redux'

import { LogBox, StatusBar } from 'react-native'
import { LogBox, NativeModules, StatusBar } from 'react-native'

import { APP_READY_CHANNEL } from '@quiet/state-manager'

import WebviewCrypto from 'react-native-webview-crypto'

Expand All @@ -28,7 +30,6 @@ import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'

import { navigationRef } from './RootNavigation'
import { initActions } from './store/init/init.slice'
import { navigationActions } from './store/navigation/navigation.slice'

import { rootSaga } from './store/root.saga'
Expand Down Expand Up @@ -76,6 +77,7 @@ function App(): JSX.Element {

useEffect(() => {
console.log('LAUNCHED APPLICATION: ', (Math.random() + 1).toString(36).substring(7))
NativeModules.CommunicationModule.handleIncomingEvents(APP_READY_CHANNEL, null, null)
}, [])

return (
Expand Down
1 change: 1 addition & 0 deletions packages/state-manager/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const AUTODOWNLOAD_SIZE_LIMIT = 20971520 // 20 MB

export const APP_READY_CHANNEL = '_APP_READY_'
export const PUSH_NOTIFICATION_CHANNEL = '_PUSH_NOTIFICATION_'
export const WEBSOCKET_CONNECTION_CHANNEL = '_WEBSOCKET_CONNECTION_'
export const INIT_CHECK_CHANNEL = '_INIT_CHECK_'
Expand Down

0 comments on commit 12b24d4

Please sign in to comment.