Commit Graph

111 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé 8d11b3024e [iOS] Add initial CallKit support
This commit adds initial support for CallKit on supported platforms: iOS >= 10.

Since the call flow in Jitsi Meet is basically making outgoing calls, only
outgoing call support is currently handled via CallKit.

Features:
 - "Green bar" when in a call.
 - Native CallKit view when tapping on the call label on the lock screen.
 - Support for audio muting from the native CallKit view.
 - Support for recent calls (audio-only calls logged as Audio calls, others show
   as Video calls).
 - Call display name is room name.
 - Graceful downgrade on systems without CallKit support.

Limitations:
 - Native CallKit view cannot be shown for audio-only calls (this is a CallKit
   limitaion).
 - The video button in the CallKit view will start a new video call to the same
   room, and terminate the previous one.
 - No support for call hold.
2017-09-28 16:36:39 -05:00
Lyubo Marinov 2e2129fa44 Import PropTypes from prop-types
Prepare for React 16.
2017-09-27 16:24:53 -05:00
Saúl Ibarra Corretgé 35da39becf [RN] NetworkActivityIndicator
The basic indicator is extracted into a LoadingIndicator component,
which then NetworkActivityIndicator displays (or not) based on network
activity.
2017-09-20 15:59:56 -05:00
Lyubo Marinov 241dc3b147 [RN] Support XMPP authentication 2017-09-19 23:04:45 -05:00
paweldomas 141acea194 [RN] Support XMPP authentication 2017-09-19 14:38:45 -05:00
Lyubo Marinov fce0e4c22c [RN] Report loadConfigError with locationURL to the SDK consumers 2017-09-06 20:34:46 -05:00
Saúl Ibarra Corretgé 284e4e543e [RN] Detect errors when loading the configuration
The error is stored in the redux store in base/config so other components can
consult it. It is also broadcasted as a new event in the external API for the
SDK.
2017-09-06 16:31:14 -05:00
Lyubo Marinov 86e4876df2 Coding style 2017-09-05 15:56:59 -05:00
Saúl Ibarra Corretgé 034518a6a0 [RN] Cache configurations in localStorage
This only helps iff there is a short transient network error which prevents the
configuration from being loaded. In such case, use the cached version in
localStorage, which may not match the shard, but it's (probably!) better than
nothing.

In case there is no Internet connectivity, an error will be produced as soon as
the XMPP connection is attempted anyway.
2017-09-05 14:58:26 -05:00
Saúl Ibarra Corretgé 18d1572dab [RN] Load config.js only when the room is known
This patch loads the config later than we used to, that is, only once we
know the room the user is about to join.

Due to architectural limitations in lib-jitsi-meet, it needs to be
initialized with a configuration in order to properly function. This is
unfortunate because we need to create a video track in the welcome page,
but don't know the room (hence no config) yet. In order to circumvent
this problem an empty configuration is used, which is later swapped with
the appropriate one, once loaded.

Some interesting side-effects of this change are a perceived speed
increase when the app starts or a conference is hangup. They are both
due to the fact that no config needs to be fetched from a remote server
in those cases.
2017-09-02 13:26:07 -05:00
Lyubo Marinov 45a1ae26ca [RN] Prepare to display BlankPage more
For example, while config.js and other files are being loaded before the
navigation to Conference is feasible.
2017-09-02 13:26:06 -05:00
Lyubo Marinov 6545a7a1bb Remove duplication 2017-09-01 23:55:25 -05:00
Lyubo Marinov ec9c05e401 [RN] Load config.js with ?room=
In order to load the configuration from the shard that will actually
host the conference, it's imperative that we add the room= query
parameter:

https://meet.jit.si/config.js?room=example

This implies a departure from our current model, where the config is
discarded if the domain for the next conference is different, but kept
otherwise.
2017-09-01 23:55:25 -05:00
Дамян Минков 6682543691 Moves analytics loading to react. (#1945)
* feat(analytics): move to React

The analytics handlers have been moved to JitsiMeetGlobalNS, so now they are
stored in `window.JitsiMeetJS.app.analyticsHandlers`.

The analytics handlers are re-downloaded and re-initialized on every
lib-jitsi-meet initialization, which happens every time the config is changed
(moving between deployments in the mobile app).

* Adds legacy support for old analytics location.
2017-09-01 14:14:03 -05:00
Lyubo Marinov 8436f23e05 Comments 2017-08-31 19:31:46 -05:00
Saúl Ibarra Corretgé 328da08b3a [RN] Remove obsolete comment
We have already made the implicit decision not to pursue what the
comment describes. If we ever revisit it, it probably won't be handled
where the comment is anyway.
2017-08-31 11:50:18 -05:00
Lyubo Marinov 7f8e8177d0 [RN] Refactor "Keep track of ongoing network requests" and "Show a progress indicator in the BlankPage"
I'm not saying that the two commits in question were wrong or worse than
what I'm offering. Anyway, I think what I'm offering brings:

* Compliance with expectations i.e. the middleware doesn't compute the
next state from the current state, the reducer does;

* Clarity and/or simplicity i.e. there's no global variable (reqIndex),
there's no need for the term "index" (a.k.a "reqIndex") in the redux
store.

* By renaming net-interceptor to network-activity feels like it's
preparing the feature to implement a NetworkActivityIndicator React
Component which will take on more of the knowledge about the specifics
of what is the network activity redux state exactly, is it maintained by
interception or some other mechanism, and abstracts it in the feature
itself allowing outsiders to merely render a React Component.
2017-08-29 18:54:04 -05:00
Saúl Ibarra Corretgé d669a6c73c [RN] Keep track of ongoing network requests
Works only for XHR requests, which is the only network request mobile performs
(WebRTC traffic aside). The fetch API is implemented on top of XHR, so that's
covered too.

Requests are kept in the redux store until they complete, at which point they
are removed.
2017-08-29 18:54:04 -05:00
Lyubo Marinov 0b8c12de0e Simplify route navigation
I see it as the first step in simplifying the route navigate of the
JavaScript app by removing BlankWelcomePage from _getRouteToRender. From
a faraway point of view, the app is at the route at which it is not in a
conference. Historically, the route was known as the Welcome page. But
mobile complicated the route by saying that actually it may not want to
see the room name input and join button.

Additionally, I renamed BlankWelcomePage to BlankPage because I don't
think of it as a WelcomePage alternative but rather as a more generic
BlankPage which may be utilized elsewhere in the future.

I plan for the next steps to:
* Merge Entryway, _interceptComponent, and _getRouteToRender in one
React Component rendered by AbstractApp so that the whole logic is in
one file;
* Get rid of RouteRegistry and routes.
2017-08-22 16:38:14 -05:00
Saúl Ibarra Corretgé 26f0f7f89c [RN] Alert the user when they need to manually grant a permission 2017-08-22 07:28:19 -05:00
Saúl Ibarra Corretgé 9bca0e3b3d [RN] Create tracks right when they are required
When do we need tracks?

- Welcome page (only the video track)
- Conference (depends if starting with audio / video muted is requested)

When do we need to destroy the tracks?

- When we are not in a conference and there is no welcome page

In order to accommodate all the above use cases, a new component is introduced:
BlankWelcomePage. Its purpose is to take the place of the welcome page when it
is disabled. When this component is mounted local tracks are destroyed.

Analogously, a video track is created when the (real) welcome page is created,
and all the desired tracks are created then the Conference component is created.
What are desired tracks? These are the tracks we'd like to use for the
conference that is about to happen. By default both audio and video are desired.
It's possible, however, the user requested to start the call with no
video/audio, in which case it's muted in base/media and a track is not created.

The first time the app starts (with the welcome page) it will request permission
for video only, since there is no need for audio in the welcome page. Later,
when a conference is joined permission for audio will be requested when an audio
track is to be created. The audio track is not destroyed when the conference
ends. Yours truly thinks this is not needed since it's a stopped track which is
not using system resources.
2017-08-22 07:28:19 -05:00
Saúl Ibarra Corretgé c42f1704ff [RN] Rename createInitialLocalTracks to createLocalTracks
The name better suits its purpose, since it can be called at any time.
2017-08-21 08:15:55 -05:00
Lyubo Marinov c0de88ba8c [RN] Remove unnecessary import 2017-08-18 14:45:00 -05:00
Lyubo Marinov 6003b560ae [RN] Fix opening the same URL multiple times
Deep/universal linking now utilizes loadURL (when possible). But loadURL
is imperative in the native source code while its JavaScript counterpart
i.e. React App Component prop url is declarative. So there's the
following bug: open a URL, leave the conference (by tapping the hangup
button, for example), and then opening the same URL actually leaves you
on the Welcome page (if enabled; otherwise, a black screen).

The implementation has a flow though: opening the same URL twice in a
row without an intervening leave will leave the first opening and join
the new opening. Which can be improved by not leaving and joining if the
conference is joined, joining, an not leaving. But that can be done
separately as an improvement independent of the current implementation
details.
2017-08-15 17:32:37 -05:00
Lyubo Marinov 571958cf26 Start the switch to prop-types
As https://facebook.github.io/react/docs/typechecking-with-proptypes.html
says, React.PropTypes have moved into the npm package prop-types since
React v15.5. I've already failed to update certain devDependencies
because they mandate the use of prop-types so I'd rather we (gradually
at least) move to prop-types rather than face a lot of work later on.
2017-08-15 17:32:37 -05:00
Saúl Ibarra Corretgé 122ebe48c7 [RN] Cache avatars and provide a default in case load fails
Avatars are cached to the filesystem and loaded from there when requested again.
The cache is cleaned after a conference ends and on application startup
(defensive move).

In addition, implement a fully local avatar system, which is used as a fallback
when loading a remote avatar fails. It can also be forced using a prop.

The fully local avatars use a user icon as a mask and apply a background color
qhich is picked by hashing the URI passed to the avatar. If no URI is passed a
random color is chosen.

A grace period of 1 second is also implemented so a default local avatar will be
rendered if an Avatar component is mounted but has no URI. If a URI is specified
later on, it will be loaded and displayed. In case loading the remote avatar
fails, the locally generated one will be used.
2017-08-03 13:45:41 -05:00
Lyubo Marinov caea02a322 [RN] Mitigate 'Not joining a new URL while in a conference' 2017-08-01 06:31:03 -05:00
Lyubo Marinov e542af28a2 [RN] Converge with Web's ExternalAPI a bit
Web's ExternalAPI accepts an object with properties as one of its
constructor arguments and from which it generated a URL. Mobile's
JitsiMeetView.loadURLObject is supposed to accept pretty much the same
object.
2017-07-27 16:48:38 -05:00
Lyubo Marinov 3546cf4915 Fixes jsdocs, formatting 2017-07-26 15:54:57 -05:00
Lyubo Marinov a2c2d3bee1 [RN] Alternative to JitsiMeetView.loadURL w/o URL
Introduces loadURLObject in JitsiMeetView on Android and iOS which
accepts a Bundle and NSDictionary, respectively, similar in structure to
the JS object accepted by the constructor of Web's ExternalAPI. At this
time, only the property url of the bundle/dictionary is supported.
However, it allows the public API of loadURLObject to be consumed. The
property url will be made optional in the future and other properties
will be supported from which a URL will be constructed.
2017-07-26 15:53:35 -05:00
Lyubo Marinov 96e0c56bde [RN] Don't override config values 2017-07-21 17:40:09 -05:00
Saúl Ibarra Corretgé 1d90826098 [RN] Use a more resilient way for testing if we are on React Native
navigator.product is read-only, so we don't run into the risk of it being
changed.
2017-07-19 16:40:06 -05:00
Lyubo Marinov d87b8823e9 [RN] Don't open the camera on startup when there is no welcome page 2017-07-18 23:42:08 -05:00
Saúl Ibarra Corretgé 8225600b61 [RN] Don't open the camera on startup when there is no welcome page
The end goal of this patch was to avoid opening the camera when there is no
welcome page.

In order to achieve this, the logic for creating the local tracks was
refactored:

Before this patch local tracks were created when lib-jitsi-meet was initialized,
and destroyed when it was deinitialized. As a side note, this meant that when a
conference in a non-default domain was joined, local tracks were destroyed and
recreated in quick succession.

Now, local trans are created and destroyed based on what the next route will be,
and this happens when the target room has been decided. This allows us to create
local tracks the moment we need to render any route, and destroy them when there
is no route to be rendered. As an interesting byproduct, this refactor also
avoids the destruction + recreation of local tracks when a conference in a
non-default domain was left.
2017-07-18 20:42:20 -05:00
Lyubo Marinov 7dbba59dee [RN] Disconnect/hangup before joining a new URL 2017-07-06 15:00:29 -05:00
Lyubo Marinov 61fd4e4ce4 [RN] Fix passing url prop to Root and App components 2017-07-06 14:59:57 -05:00
Lyubo Marinov 9bd6bbfd95 Fix jsdocs. Simplify the source code 2017-07-06 14:59:57 -05:00
Saúl Ibarra Corretgé cc9249ba1a [RN] Fix passing url prop to Root and App components
React (pun intended) to prop changes, that is, load the new specified URL.

In addition, fix a hidden bug in loading the initial URL from the linking
module: we prefer a prop to the URL the app was launched with, in case somehow
both are specified. We (the Jitsi Meet app) are not going to run into this
corner case, but let's be defensive just in case.
2017-07-06 14:59:57 -05:00
Lyubo Marinov 25ec8ac6a7 Prepare for eslint 4 2017-06-14 22:17:35 -05:00
Lyubo Marinov 5f64ccb97d [RN] Naming 2017-06-09 14:51:31 -05:00
Saúl Ibarra Corretgé 4687c1f465 [RN] Add ability to skip the welcome page
Also expose this in the native SDKs.
2017-06-09 14:10:10 -05:00
Saúl Ibarra Corretgé 79d51bc379 feat(App): remove obsolete config prop
It's obsolete now, since config is handled in Redux. Also add a "defaultUrl"
prop so emdedding applications can select what the default base URL is.
2017-06-09 14:10:10 -05:00
Saúl Ibarra Corretgé a075f24000 [RN] Add conference events to native SDKs
The current implementation doesn't use the API and Transport modules. This is
due to the fact that they are too tied to APP at the moment, which is web only.

Once API is refactored and moved into the Redux store this will be adjusted,
though it's unlikely that the lowest level React Native module (ExternalAPI)
changes drastically.

This commit also introduces a stopgap limitation of only allowing a single
instance for JitsiMeetView objects on both Android and iOS. React Native doesn't
really play well with having multiple instances of the same modules on the same
bridge, since they behave a bit like singletons. Even if we were to use multiple
bridges, some features depend on system-level global state, such as the
AVAudioSession mode or Android's immersive mode. Further attempts will be made
at lifting this limitation in the future, though.
2017-06-09 00:03:23 -05:00
Lyubo Marinov a4a13bed84 Invite URL w/o (hash & query/search) params 2017-06-01 21:04:31 -05:00
Lyubo Marinov 4dc658c270 Fix 'Missing JSDoc comment  require-jsdoc' 2017-06-01 21:01:50 -05:00
Lyubo Marinov 320e67baa1 Fix the initialization of the (external) API
The counterpart of the external API in the Jitsi Meet Web app uses the
search URL param jwt to heuristically detect that the Web app is very
likely embedded (as an iframe) and, consequently, needs to forcefully
enable itself. It was looking at whether there was a JSON Web Token
(JWT) but that logic got broken when the JWT support was rewritten
because the check started happening before the search URL param jwt was
parsed.
2017-05-30 09:38:18 -05:00
Saúl Ibarra Corretgé 5304660e14 [RN] Polyfill Symbol 2017-05-26 16:37:22 -05:00
Lyubo Marinov 2f3706bd37 [RN] Simplify
There were getDomain, setDomain, SET_DOMAIN, setRoomURL, SET_ROOM_URL
which together were repeating one and the same information and in the
case of the 'room URL' abstraction was not 100% accurate because it
would exist even when there was no room. Replace them all with a
'location URL' abstraction which exists with or without a room.

Then the 'room URL' abstraction was not used in (mobile) feature
share-room. Use the 'location URL' there now.

Finally, removes source code duplication in supporting the Web
application context root.
2017-05-09 16:31:21 -05:00
Lyubo Marinov e6f6884c36 [RN] Support JSON Web Token (JWT)
Make 'Add jwt module to react' work on mobile.
2017-05-09 00:21:14 -05:00
Ilya Daynatovich ab5c2e9ded Add jwt module to react 2017-05-09 00:21:14 -05:00