[GSOC] React Native SDK

Hi @saghul @Calinteodor (tmoldovan8x8 doesn’t seem to have an account under this name in this forum) and anyone else interested with the topic. I’m opening this forum to discuss ideas and questions to come up with a good GSOC proposal.

So first to make sure if I understand the general idea correctly: Jitsi provides an SDK for native ios and android right now. The goal is to develop a React Native SDK as it would be convenient for many developers and also the Jitsi Apps are written in React Native.

My first question is if there is any history with this project. Which problems do you see with it? I’m very new to Open Source, but I assume there is reasons why there is little cooperation between this project and Jitsi. Other than that, what is your opinion on building the RN SDK as a RN wrapper for the Native SDK?

To get started I downloaded the SDK Samples and played around with the API a bit to understand the structure and general idea of the SDK.
Would be great if you could answer these questions and perhaps give me a hint or two whether there already are older discussions and challenges for this problem
Filip

Correct. Both our apps and native SDKs are really written in RN, the project is about making that consumable as a RN package / library.

Excellent question. I cannot comment on the cooperation since they never reached out to us :person_shrugging: That said, I consider the approach that project took (wrapping our SDKs in RN) the wrong approach.

Our SDKs are already using RN, so there is no good reason to “wrap the wrapper”. What you get by doing that is tons of incompatibilities. In iOS for example you’ll get 2 instances of RN running at the same time, and depending on the libraries the other app is using you may run into issues when doing dybnamic lookups in the ObjC runtime. On Android it’s actually worse because then the app is “forced” to use the same RN version.

Going forward we should have a podscpec file for iOS and a build.gradle file for android which act like a regular RN package.

I was thinking that maybe one way to go would be to have a react-native-package/ directory where we have the scaffold, and then at package time we copy the files over from the main project, to the right locations.

okay, so basically the SDKs are extending the original ReactRootView for the JitsiMeetView, making it a React Component that is not consumable in React right? Didn’t even know that was possible😁

So overall a good approach to this could be to build it somewhat as a RN View extension and do pretty much the same for all other SDK components. What are your thoughts on this?

Ok so I have been thinking about this a bit more and a couple more questions came up.
1.) I am having kinda a hard time what ExternalAPIModule.java is doing, could you give a quick summary?
2.) I realised that what I wrote above is veeery oversimplified. So let me go through the example SDK for android to try to understand what is happening right now: If I decide to launch a conference “org.jitsi.meet.CONFERENCE” is being passed as in an intent. Is that conference.js?
3.) I am not sure if I understand how the JitsiMeetView exactly works. It extends the BaseReactView which looks like it’s backed by the React Native View, but only the part that is on the native side of the RN bridge. But why do we need a View at all when the layouts are defined in different places in native android and ios development. To me in the example sdk


it looks like the JitsiMeetActivity is only used as a API called by a e.g. onButtonClick function, I think it would help a lot if I understood that. Perhaps you could also explain why the native SDKs have been written in that way? (So being backed by the native part of RN components)
I think all of this would help to tackle this feature so very glad about every explanation.

Yep.

Not really. We already have a root component, we “just” need to make that importable. The biggest challenge I think is the native modules which are part of the app / SDK, that will need to be linked to the consuper apps.

That is a module that acts as a communication channel between the native view and the JS code.

No. When the main intent is launched the pp is opened you end up in App.native.js.

That’s correct. Our view has a single subview, thew RN root view.

Because the SDK is for native apps, and native apps need to have a view of some kind to put in their layout.

Excellent question.

In that example, you are going to have 1 Activity in the beginning, let’s say it’s MainActivity. That is 100% native code. When you press a button we’d like to join a meeting.Joining a meeting is implemented with our SDK, so we want to launch a screen with the meeting in it. Generally speaking, in Android, this is another activity, because it’s an action that takes over.

So we launch a second Activity, JitsiMeetActivity, which is also native code, so now the unsuspecting Android developer is using our SDK to implement the meetings functionality, but under the hood, there is JS code and RN! Let’s look at the layers.

JitsiMeetActivity has a simple layout with a single Fragment: JitsiMeetFragment. We made it this way in case someone wants to integrate the Fragment in an activity that had other content too. Then the fragment has a single view: JitsiMeetView. This is where “the magic” happens. JitsiMeetView is a native view with a single subview: the React Native Root View.

We built it this way because our main consumers are native apps, not RN apps.

On iOS there is less integration because typically SDKs don’t offer a ViewController as an API, but a UIView (for example the Google Maps SDK). So there the app needs to implement its own controller, but the concept is the same, there is a JitsiMeetView with a single subview which is the React Native Root View.

Hope that helps!

Shifting the discussion here, as asked.

I think I did not explain my approach that well before. Allow me to reiterate from our perspective.(My earlier post was from the perspective of the user who will be using a RN SDK)

What I meant was the JS code for the RN SDK will be written before hand this way->
with

  1. In the RN SDK - all the functions necessary for calling the external API (including the iFrame API will all be initialized by us beforehand) written in another directory separate from the components which we will be using.
  2. Make another file to handle the user defined options for the externalAPI /IFrameApi as props passed to ( 1.) (default server : ‘https://meet.jit.si’)
  3. We will fetch API with the above mentioned specifications. the IFrame API will also be called to initialize it with userdefiend element (the element/window where the SDK user wants to integrate jitsi meet ) in the user app, …which will be a container for jitsi-meet .
  4. Then we will make a View component which will will accept some props and pass it to ( 2.)
    This is the View component which will then be set as the window for the above fetched API to the above-mentioned element in (3.).
  5. What the user will be consuming ->is the last View component mentioned in (4.) and then using this view component on the javascript side of the RN bridge.
  6. The native side of the bridge will get only the View component mentioned in (4) from the JS side of the user’s RN application , all the other functions were called by the SDK beforehand.

Would this be the correct implementation of the APIs ?

The iframe API is for web integrations, is has no place in the RN SDK.

We kind of already have that. This would be the main component of our SDK: jitsi-meet/App.native.js at 7e5ffdb3906d80bdbf2976d5f85d3e79f7e6455a · jitsi/jitsi-meet · GitHub we’d need a thin wrapper component around it, I reckon.

Not really. The RN SDK should me closer to our React SDK: React SDK | Jitsi Meet so we’d expose a component which RN apps can mount wherever they want.

The current App component is that View we need.

Yes I was going to mention that … plus the web and native components for the current SDK are handled in different ways too perhaps because of iFrame Api difference ?

The current App.native.js is pretty much what I was saying. Like you mentioned, we should probably wrap it.

Yes, what I was saying was something like this. .Where the props are passed to the exported single component which are then used for the external Api References maybe?

Helps a lot! Thank you! Lots to think about

So basically the wrapper could mean extending App.native.js and adding all props necessary to have a similar option set to the native sdk right?

What do you mean by using for the external API References? From my understanding App.native.js is already a RN Component so there’s no need to call APIs from a RN SDK

Sure What I meant was having a middleware like this That will be utilised by the main View Component in this case App.native.js by passing the values as props to that middleware

Something similar to the external API would be needed yes, for example to call some onReadyToClose prop that the user passed to our JitsiMeeting component.

2 Likes

First, are there any tests for the existing SDKs? I can’t seem to find them.

Help me understand this one please:
If JM Activity receives a READY_TO_CLOSE Broadcast message which in the end just calls View.leave() which resets the props the ReactRootView and reloads it. Do you see any obstacles in handling this with state changes? Because I am not aware of broadcast functionality in react native and I don’t really understand how something similar to the external API would look in that context. Could you elaborate a bit?

About that I got one more question: We got the JitsiMeetView with the React Root View. If someone let’s say joins a meeting, the props are updated and either the ReactRootView is updated or created if not existing. However I can’t really find the link to App.native.js. In which part of the code is this being launched/utilized? I would think that the ReactRootView is set to display App.native.js but I don’t understand how that is happening.

Cheers!

Not at this time. We are starting an effort to add them with Detox, it’s still early stages.

Instead of sending a broadcast message it would call a prop on the componet, say onReadyToClose.

It happens here: jitsi-meet/JitsiMeetView.m at 856ef757d47092f421a7630c0e8e05ca1282f390 · jitsi/jitsi-meet · GitHub that “App” module name refers to this one: jitsi-meet/index.native.js at 856ef757d47092f421a7630c0e8e05ca1282f390 · jitsi/jitsi-meet · GitHub which as you can see will render the Root component which renders the App component.

1 Like

Gotcha thanks, gonna send my proposal sometime in the evening today

1 Like

Submitted my proposal! Would be very thankful if you could feedback it so I can improve it before the final deadline

Hello @saghul ,
It’s been my pleasure to reach you out here on this community page.

My approach is a little bit different . It’s been always fascinating to solve this kind of problem .
Kindly review my proposal on mail from priyanshvatsal@gmail.com .

Let me know if you like my proposal and we can continue & achieve the goal in best way possible

I don’t know if the submitted doc is in a good form for reviewing so here’s the google doc.
Of course I am thankful for feedback by anyone who is interested in this project - Just request access :slight_smile: