Commit Graph

459 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé 9bfe54475b android: read Dropbox API from main package resources
This makes Dropbox work on apps using the SDK without needing to build it
themselves.
2019-01-29 15:39:20 +01:00
Saúl Ibarra Corretgé d5a43426ed android: don't read Dropbox key from iOS files 2019-01-29 15:39:20 +01:00
Saúl Ibarra Corretgé 15c8f2b125 android: remove unused import 2019-01-25 11:06:35 +01:00
Saúl Ibarra Corretgé 349b1ff70e android: fix warning 2019-01-25 11:06:35 +01:00
Guus der Kinderen 4b99caa1a9 Android SDK build instructions: add 'clean'
I'm ashamed to admit that I spent several _days_ chasing a bug that was already fixed. :( This obvious instruction would have been a time-saver.
2019-01-23 16:46:51 +01:00
Saúl Ibarra Corretgé 7c69308270 android: remove unused ProGuard rules file 2019-01-16 14:55:58 -06:00
Saúl Ibarra Corretgé 50b4212463 android: add missing ProGuard rules 2019-01-16 14:55:58 -06:00
Saúl Ibarra Corretgé bb8fc8770a android: fix packager in debug mode in API 28
These values must match these ones in React Native:
5939d078a0/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoHelpers.java (L20-L22)
2019-01-16 14:55:12 -06:00
Bettenbuk Zoltan 8a241ba2b7 [RN] Add chat functionality
Co-authored-by: DimaG <dgeorgiev06@gmail.com>
2019-01-15 11:33:12 +01:00
Saúl Ibarra Corretgé 634f304815 android: simplify handling of the back button
Provide a default and builtin default implementation which finishes the
Activity, same as before.

What this PR removes is the ability to provide a custom default handler because
applications can already take this decision when calling `onBackPressed`. In
addition, make `onBackPressed` return `void` because it's virtually impossible
for it to return `false` (that would mean that there is no
`ReactInstanceManager`, which means there is no app to begin with).

In addition, remove the use of `BackAndroid` since `BackHandler` contains an iOS
shim now.
2019-01-08 17:43:36 +01:00
Saúl Ibarra Corretgé 148d4ebb90 rn: add Firebase integration
This is done at the app level, not the SDK.

Currently 2 Firebase services are used:

  - Crashlytics
  - Dynamic Links

They are enabled in tandem, if the appropriate Google services file
(GoogleService-Info.plist on iOS or google-services.json on Android) is found.

Each service needs to be individually enabled in the Firebase console.
2019-01-08 17:42:59 +01:00
Saúl Ibarra Corretgé a1ebba0ef7 android: fix compilation warning
The annotation processor is required for our Glide module to be included.
2019-01-08 17:42:59 +01:00
Sebastian Safari ce01b31514 doc: add notes to enable 32bit only mode 2019-01-03 13:43:11 +01:00
Saúl Ibarra Corretgé 0469e5af5e deps: update react-native-calendar-events 2018-12-20 13:52:14 +01:00
Saúl Ibarra Corretgé 1e83891a70 deps: update react-native-immersive 2018-12-19 17:44:29 +01:00
Saúl Ibarra Corretgé f97869ffde deps: update react-native-keep-awake 2018-12-19 15:20:10 +01:00
Saúl Ibarra Corretgé 0fc69416d4 android: update build and target SDK versions
Note that Android 9 Pie (API 28) disallows HTTP requests by default, so an
exception was needed in the app in order for the Metro bundler to work in debug
mode.
2018-12-19 15:18:10 +01:00
Saúl Ibarra Corretgé f8f544c615 android: remove unneeded gradle task 2018-12-19 15:18:10 +01:00
Saúl Ibarra Corretgé ac624b104f android: remove duplicated Maven repo
The Google repository is already added with google().
2018-12-19 15:18:10 +01:00
Saúl Ibarra Corretgé d18f582922 android: fix warning 2018-12-19 15:18:10 +01:00
Saúl Ibarra Corretgé 85b141db89 android: update proguard rules 2018-12-19 15:18:10 +01:00
Saúl Ibarra Corretgé e4b1e40cc6 deps: update react-native-google-signin 2018-12-19 15:15:21 +01:00
Saúl Ibarra Corretgé 342718f673 rn: drop support for no longer supported deployments 2018-12-18 16:18:08 +01:00
Saúl Ibarra Corretgé 545ad0e1a6 android: update documentation 2018-12-18 09:05:50 +01:00
Saúl Ibarra Corretgé 053437c86e android: circumvent trouble with apps using Glide
Glide (which is used by react-native-fast-image) can cause trouble if the host
app (the one using the SDK) is using Glide already.

To avoid this, don't use the builtin AppGlideModule (as the docs recommend) and
let apps define it.
2018-12-18 09:05:50 +01:00
Saúl Ibarra Corretgé 0031fd2678 android, ios: update react-native-fast-image dependency 2018-12-18 09:05:50 +01:00
Saúl Ibarra Corretgé 22199cb57a android: update documentation to match the new SDK API 2018-12-06 15:29:59 +01:00
Saúl Ibarra Corretgé 0c3d037cb5 android: throw if Activity doesn't implement the required interface 2018-12-04 20:09:54 +01:00
damencho 34f2ff9b85 Update comments. 2018-12-03 16:46:59 +01:00
damencho 21b0ed691b Auto accept android license on build machines.
Every time the android version that is used changes we need to update the license hash.
2018-12-03 16:46:59 +01:00
Saúl Ibarra Corretgé 8b359f48db android: remove no longer needed code
The dependency was dropped, so it's no longer needed.
2018-12-03 16:41:12 +01:00
Saúl Ibarra Corretgé ee8d2df355 android: update build instructions 2018-12-03 11:49:03 +01:00
Saúl Ibarra Corretgé bc77a62626 android: fix maven repo relative location
Assume it's at the same level as the Jitsi Meet repo, by default.
2018-12-03 11:49:03 +01:00
Saúl Ibarra Corretgé b15533d75f android: update app / sdk version
Set them to the next release versions. In additon, the buildNumber variable will
be used to match the requirements of versionCode:
https://developer.android.com/studio/publish/versioning

that is, a monotonically increasing number, independent of the app / sdk
version.
2018-12-03 11:49:03 +01:00
Saúl Ibarra Corretgé cf9a65f475 android: update dependencies for publishing 2018-12-03 11:49:03 +01:00
Saúl Ibarra Corretgé d7ba4a8a2a android: add helper scripts to publish RN and JSC to Maven 2018-12-03 11:49:03 +01:00
Saúl Ibarra Corretgé 26ba974757 [RN] Drop react-native-locale-detector dependency
The upstream package has been unmaintained for 2 years now, and making the litle
changes needed as React Native needs them is getting old. The actual
funcionality is a couple of one-liners plus tons of boliterplate, which gets
reduced by quite a bit if we just embed it. So here it goes.
2018-12-03 11:48:44 +01:00
Guus der Kinderen fb6949f7ba [Android] Add jsc-android to SDK project / improve build docs
Due to a switch to a newer version of JSCore, the jsc-android dependency is now used by the
SDK. As this dependency is not (yet) available in the Jitsi Maven repository, an error like
this is reported when an application is ran that uses the SDK:

    com.facebook.react.common.JavascriptException: Can't find variable: Symbol

This commit primarily improves the instructions on how to create a local Maven repository
that contains all required dependencies, including the JSCore dependency that was missing.

This intends to address the issue described in https://github.com/jitsi/jitsi-meet/issues/3399
2018-11-29 22:21:27 +00:00
Leonard Kim d5fb2c2717 ref(sdk): update comments to exclude mention of componentWillReceiveProps 2018-11-21 08:08:45 -08:00
Saúl Ibarra Corretgé 011a46ce2d [RN] Don't bundle fonts we don't use 2018-10-16 14:33:48 +02:00
Saúl Ibarra Corretgé b71adbdf70 deps: update React Native to version 0.57 2018-10-10 18:07:36 +02:00
hristoterezov 39a22effb1 fix(build.gradle): Move dropboxAppKey definition to defaultConfig 2018-09-27 01:42:59 -05:00
hristoterezov ca600928f5 feat(build.gradle): Use the Dropbox app key specified in Info.plist. 2018-09-27 01:42:59 -05:00
hristoterezov 60decf7692 ref(dropbox): Consistency for the naming around the app key. 2018-09-27 01:42:59 -05:00
hristoterezov 38517127c3 feat(dropbox): Implement react-native module. 2018-09-27 01:42:59 -05:00
hristoterezov 717fade79c ref(proguard): Create common proguard config. 2018-09-18 14:37:05 -05:00
hristoterezov 959e687ed4 feat(proguard): Add crashlytics rules 2018-09-18 14:37:05 -05:00
hristoterezov 5f5adc3fa8 feat(proguard): enable 2018-09-18 14:37:05 -05:00
Bettenbuk Zoltan d10d61fb7a [RN] Add Google Sign In to live streaming 2018-09-05 23:09:56 +02:00
Bettenbuk Zoltan 9fe2b834eb [Android] Implement Activity.onActivityResult 2018-09-05 23:09:56 +02:00
Saúl Ibarra Corretgé f3d623e0ca android: move calendar permission handling to the SDK
Since this is a feature implemented in the SDK, it makes sense that all the
plumbing required to make it work it's in the SDK itself.
2018-09-05 14:56:00 -05:00
Saúl Ibarra Corretgé 388c906312 android: implement the PermissionAwareActivity interface
This makes the PermissionsAndroid builtin module work.

Introduce the JitsiMeetActivityInterface, which defines the interface that
activities using JitsiMeetView directly must implement in order to ensure full
functionality.
2018-09-05 14:56:00 -05:00
Saúl Ibarra Corretgé 4fd8172126 [Android] Add LeakCanary
LeakCanary is a memory leak detection library which will run only in Debug mode.
2018-08-31 16:27:51 -05:00
Saúl Ibarra Corretgé 8d3cecad86 [Android] Update JSC version
The JSC version used by React Native is about 3 years old, and doesn't implement
things like Symbol or Typed Arrays, which require polyfills. These polyfills are
sometimes a los less performant, as is the case for Typed Arrays.

Bumping an updated JSC version makes both platforms consistent when it comes to
the JavaScript platform.
2018-08-05 17:04:16 -05:00
Saúl Ibarra Corretgé 27021ea271 [RN] Replace cached image implementation
Use react-native-fastimage, which uses 2 full-native image impleentations using
well known and mature (native) libraries.

This gets us rid of 2 libraries which were observerd as a source of bugs and
created trouble with dependencies: react-native-fetch-blob and
react-native-img-cache. They are also no longer well maintained.
2018-07-31 14:07:17 -05:00
Saúl Ibarra Corretgé 243dd16285 android: run all audio and bluetooth operation on a dedicated thread 2018-07-27 15:39:39 -05:00
Saúl Ibarra Corretgé 92001f4d37 android: run WiFi stats operations on a dedicated thread 2018-07-27 15:39:39 -05:00
Lyubo Marinov 8ff3ae0ab2 [Android] Introduce IncomingCallView (continued) 2018-07-18 22:47:18 -05:00
Saúl Ibarra Corretgé ea22d12581 [Android] Introduce IncomingCallView
It's a separate view (on the native side) and app (on the JavaScript side) so
applications can use it independently.

Co-authored-by: Shuai Li <sli@atlassian.com>
Co-authored-by: Pawel Domas <pawel.domas@jitsi.org>
2018-07-18 22:47:18 -05:00
Saúl Ibarra Corretgé 9972e88b67 [Android] Split base functionality out of JitsiMeetView
As the need for adding more views connected with our React code arises, having
everything in JitsiMeetView is not going to scale.

In order to pave the way for multiple apps / views feeding off the React side,
the following changes have been made:

- All base functionality related to creating a ReactRootView and layout are now
  in BaseReactView
- All Activity lifecycle methods that need to be called by any activity holding
  a BaseReactView are now conveniently placed in ReactActivityLifecycleAdapter
- ExternalAPIModule has been refactored to cater for multiple views: events are
  delivered to views, and its their resposibility to deal with them
- Following on the previous point, ListenerUtils is a utility class for helping
  with the translation from events into listener methods
2018-07-18 22:47:18 -05:00
Saúl Ibarra Corretgé c3f602b7b6 Revert "fix(android): do not require java 8 target"
This reverts commit 9e0fee6c7d.

WebRTC requires Java 8, and Java 7 is now considered unsupported:
https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/discuss-webrtc/V1h2uQMDCkA/RA-uzncVAAAJ
2018-06-25 22:58:26 -05:00
virtuacoplenny 3e79926ad4 feat(recording): add sounds for when recording starts and stops (#3078)
* feat(recording): add sounds for when recording starts and stops

* squash: use constants, play sounds for file only

* squash: rename recordingStopped.mp3 -> recordingOff.mp3

* squash: flip var declaration for alpha order
2018-06-05 20:20:43 +02:00
Guus der Kinderen f604b1c82d doc: elaborate in Jitsi Meet SDK for Android readme 2018-05-30 16:51:18 +02:00
Saúl Ibarra Corretgé ab83a97fd5 [Android] Handle audio focus changes while in a conference 2018-05-25 15:33:36 +02:00
Saúl Ibarra Corretgé c8c198b0b1 [Android] Add support for USB headset detection
The API to gather these was introduced in API level 26.
2018-05-24 16:40:11 +02:00
hristoterezov d4d2c25499 [RN] Add rejected ringtone sound assets to build 2018-05-23 15:22:01 -05:00
Lyubo Marinov 75c7cfd9e1 Coding style: comments, formatting, sorting order 2018-05-20 19:01:59 -05:00
Saúl Ibarra Corretgé ef7fb1a7b0 [RN] Make all delegate / listener methods run in the main / UI thread 2018-05-20 16:46:44 -05:00
Saúl Ibarra Corretgé 284d09eae7 [RN] Add ringtone sound assets to build 2018-05-17 08:31:46 -05:00
Saúl Ibarra Corretgé 52da5010cc [Android] Make sure we use the react-native version in node_modules
Releases are also published to jcenter, and due to how the dependency is
declared, we are picking the latest release from there, which is arguably not
what we want.
2018-05-15 13:48:34 -05:00
Lyubo Marinov 6a0de0ddde Coding style: consistency, formatting, naming 2018-05-07 10:05:37 -05:00
Lyubo Marinov 7ffdaf59c7 [RN] Add an example how to consume the public SDK invite API 2018-05-07 00:38:49 -05:00
Lyubo Marinov 5e79bbecef Codying style: naming, formatting, comments 2018-05-03 18:04:59 -05:00
paweldomas 565fd37f28 fix(Android|PiP): do not invoke 'enterPictureInPicture' in PAUSED state
Activity.enterPictureInPictureMode method must be invoked synchronously
on userLeaveHint callback in order to be sure that the current Activity
is still visible (does not transit to PAUSED state). Previously if the
asynchronous processing would be delayed enough for the Activity to go
into the PAUSED state it will be too late to go into the PiP mode.
2018-05-02 17:06:24 +02:00
Lyubo Marinov effd3728b6 [RN] add support for inviting participants during a call on mobile (2) 2018-05-02 12:54:02 +02:00
Ryan Peck f64c13d4b7 [RN] add support for inviting participants during a call on mobile
* Button conditionally shown based on if the feature is enabled and available
* Hooks for launching the invite UI (delegates to the native layer)
* Hooks for using the search and dial out checks from the native layer (calls back into JS)
* Hooks for handling sending invites and passing any failures back to the native layer
* Android and iOS handling for those hooks

Author: Ryan Peck <rpeck@atlassian.com>
Author: Eric Brynsvold <ebrynsvold@atlassian.com>
2018-04-25 18:58:06 +02:00
paweldomas 9cbcbf6e26 fix(PictureInPictureModule): catch the RuntimeException
Activity.enterPictureInPictureMode can fail for a couple of reasons
mentioned in the JSDoc:

"The system may disallow entering picture-in-picture in various cases,
including when the activity is not visible, if the screen is locked or
if the user has an activity pinned."

It seems to be safe to assume that those cases will be caught by
a RuntimeException handler (only RuntimeExceptions can be left without
explicit catch block).

Anyway the root cause for problems is the fact that the current process
for going to the picture in picture mode is not synchronised with
Activity's lifecycle. On Activity's "userLeaveHint" callback we dispatch
async task to the JS code which only then after dispatching some more
stuff eventually call native method that enter PiP. In case we spend too
much time on the JS side and the Activity goes to PAUSED state the call
will fail with IllegalStatException: "activity is not visible",
"activity is paused" etc. This means with this fix the app will not
crash, but we'll see it sometimes not go to the PiP mode as expected.
2018-04-22 00:41:18 -05:00
paweldomas 8b2ce21e1a fix(RN): bundle sound files in release build
On Android the files will be copied to the assets/sounds directory of
the SDK bundle on build time. To play the "asset:/" prefix has to be
used to locate the files correctly.

On iOS each sound file must be added to the SDK's Xcode project in order
to be bundled correctly. To playback we need to know the path of the SDK
bundle which is now exposed by the AppInfo iOS module.
2018-04-10 10:59:52 +02:00
paweldomas 968b279b37 feat(android): support NAT64
Adds Nat64InfoModule which resolves IPv6 addresses for IPv4 addresses
in IPv6 only network where jitsi-meet deployment does not provide any
IPv6 addresses as ICE candidates.
2018-04-05 10:21:59 -05:00
zbettenbuk bba480f329 Add calendar-sync feature 2018-03-13 18:04:14 -05:00
paweldomas 60e03e3dec feat: add join/leave sounds on mobile
Adds base/sounds feature which allows other features to register a sound
source under specified id. A new SoundsCollection component will then
render corresponding HTMLAudioElement for each such sound. Once "setRef"
callback is called by the HTMLAudioElement, this element will be added
to the Redux store. When that happens sound can be played through the
new 'playSound' action which will call play() method on the stored
HTMLAudioElement instance.
2018-03-13 16:57:28 -05:00
Shuai Li 5cde674eff
fix(android): webrtc progurd rule
The new libwebrtc.jar contains an extra unused class file, when proguard is enabled result in the following warning:

org.chromium.build.BuildHooksAndroidImpl: can't find superclass or interface org.chromium.build.BuildHooksAndroid
2018-03-09 12:29:49 -08:00
Lyubo Marinov c018252eee [Android] Fix RuntimeException in RNImmersiveModule
java.lang.RuntimeException: Tried to access a JS module before the React instance was fully set up. Calls to ReactContext#getJSModule should only happen once initialize() has been called on your native module.
	at com.facebook.react.bridge.ReactContext.getJSModule(ReactContext.java:102)
	at com.rnimmersive.RNImmersiveModule.emitImmersiveStateChangeEvent(RNImmersiveModule.java:74)
	at org.jitsi.meet.sdk.JitsiMeetView.onWindowFocusChanged(JitsiMeetView.java:504)
	at android.view.View.dispatchWindowFocusChanged(View.java:10257)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1193)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3602)
	at android.os.Handler.dispatchMessage(Handler.java:102)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6119)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
2018-03-09 13:50:07 -06:00
paweldomas 9e0fee6c7d fix(android): do not require java 8 target
Updates react-native-webrtc to get rid of Java 8 requirement for
the Android app.
2018-03-08 15:47:05 -06:00
Lyubo Marinov 9f69c4d730 Grow features/settings from features/app-settings and features/settings-menu 2018-02-26 19:19:01 -06:00
zbettenbuk 9a9890f86c Introduce SafeArea for Settings and Header 2018-02-26 18:35:13 -06:00
Lyubo Marinov b8de5bbfc3 [RN] Add Picture-in-Picture support (Coding style: naming, consistency) 2018-02-23 11:21:26 -06:00
Saúl Ibarra Corretgé b3683068d4 [RN] Add Picture-in-Picture support
This only works automatically on Android >= 8. On other platforms / versions, it
relies on the SDK user on implementing a "reduced UI" mode and reacting to the
"request PIP" delegate method.
2018-02-23 11:21:25 -06:00
Lyubo Marinov 94473e5660 [Android] Allow accessing react-native's in-app developer menu (in the emulator) 2018-02-23 11:21:25 -06:00
Lyubo Marinov e2cf7a788d [RN] Make full-screen more resilient on Android (Coding style: consistency) 2018-02-14 12:28:22 -06:00
Saúl Ibarra Corretgé 4757c1ebca [RN] Make full-screen more resilient on Android
On Android we go into "immersive mode" when in a conference, this is our way of
being full-creen. There are occasions, however, in which Android takes us out of
immerfive mode without us (the application / SDK) knowing: when a child activity
is started, a modal window shown, etc.

In order to be resilient to any possible change in the immersive mode, register
a listener which will be called when Android changes it, so we can re-eavluate
if we need it and thus re-enable it.
2018-02-13 15:00:36 -06:00
Saúl Ibarra Corretgé 9c2849a663 [Android] Enable Java 1.8 compatibility support
It was recently introduced in WebRTC, so we we need to enable it project wide.
As for what features are supportd, see:
https://developer.android.com/studio/write/java8-support.html
2018-01-19 14:05:25 -06:00
Saúl Ibarra Corretgé 292f3ab1bd [Android] Fix crash if settings activity cannot be opened
The documentation states this is possible, so make sure we handle such errors.

Ref:
https://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DETAILS_SETTINGS
2018-01-09 13:12:53 -06:00
damencho 2f3ea1b458 [Android] Add module that provides getWiFiStats 2017-12-19 11:07:11 +01:00
Saúl Ibarra Corretgé b920140488 android: update Gradle plugin version for AS 3.0.1 2017-12-14 15:20:05 -06:00
Saúl Ibarra Corretgé 49acd6bf6a android: simplify using the Google Maven repo reference
Also remove mavenLocal since we don't need it.
2017-12-14 15:20:05 -06:00
Saúl Ibarra Corretgé e9c91d194c android: update appcompat version 2017-12-13 09:35:34 -06:00
Saúl Ibarra Corretgé 3460fe03e5 android: update target SDK version
Android Oreo (API level 26) is supported since React Native 50.
2017-12-13 09:35:34 -06:00
Saúl Ibarra Corretgé 57206cc36a [RN] Build react-native-locale-detector
Upstream lacked a CocoaPods podspec file, PR:
https://github.com/DylanVann/react-native-locale-detector/pull/3
2017-12-13 10:17:05 +01:00
Saúl Ibarra Corretgé f6ace61674 doc: document required proguard rules 2017-12-12 10:48:51 -06:00
Lyubo Marinov 569b3547c8 Upgrade NPM dependencies/packages: react-native 0.50 2017-12-04 00:45:18 -06:00
Lyubo Marinov 81094ba7fd [Android] Fix NullPointerException in AudioModeModule 2017-11-19 21:58:24 -06:00
Lyubo Marinov 3acf0c7f64 [Android] Fix UnsupportedOperationException in AudioModeModule 2017-11-19 21:58:24 -06:00
Saúl Ibarra Corretgé f973a695d8 [RN] Add audio route picker
Due to the difference in nature, the iOS and Android implementations are
completely different:

iOS: MPVolumeView is used, which allows us to place a button which will launch a
native route picker provided by iOS itself. This view is different depending on
the iOS version, with the iOS 11 version being more complete.

Android: A completely custom component is used, which displays a bottom sheet
with the device categories, not devices individually. This is akin to the sheet
in the builtin dialer.
2017-11-15 09:31:40 -06:00
paweldomas 3f6f5e7eb9 fix(JitsiMeetView): use setAppProperties 2017-11-02 14:32:35 +01:00
paweldomas b74bede0e7 feat(web/RN): update React to v16 and React Native to 0.49 2017-11-02 14:32:35 +01:00
Lyubo Marinov 0550858653 [Android] Maven artifact publishing documentation 2017-10-30 16:04:37 -05:00
Saúl Ibarra Corretgé 5308f78c9a [Android] Fix Android Studio 3.0 (final) 2017-10-26 10:04:52 +02:00
Saúl Ibarra Corretgé a14cc60e30 [Android] Specify build tools version
Android Studio won't build the app otherwise. Since the gradle plugin 3.0 beta7,
the minimum supported build tools version is 26.0.2, so set it to that. Also
bump compileSdkVersion to 26 since they need to match (in the major number, that
is).

The target API is still 25. Android Oreo (26) brought some changes in overlay
permissions which I haven't figured out yet.
2017-10-25 15:16:09 -05:00
Saúl Ibarra Corretgé ae0e37be34 [Android] Fix Android Studio 3.0 RC2 2017-10-25 16:17:23 +02:00
Lyubo Marinov e0b73fdd1c [Android] Fix Android Studio 3.0 Beta 7 2017-10-03 20:45:43 -05:00
Lyubo Marinov 4bf19d73fd [RN] Fix documentation comments
* Javadoc introduced @code as a replacement of <code> and <tt> which is
  better aligned with other javadoc tags such as @link. Use it in the
  Java source code. If we switch to Kotlin, then we'll definitely use
  Markdown.

* There are more uses of @code in the JavaScript source code than <tt>
  so use @code for the sake of consistency. Eventually, I'd rather we
  switch to Markdown because it's easier on my eyes.

* Xcode is plain confused by @code and @link. The Internet says that
  Xcode supports the backquote character to denote the beginning and end
  of a string of characters which should be formatted for display as
  code but it doesn't work for me. <tt> is not rendered at all. So use
  the backquote which is rendered itself. Hopefully, if we switch to
  Markdown, then it'll be common between JavaScript and Objective-C
  source code.
2017-10-01 01:35:19 -05:00
Lyubo Marinov b3cef401f2 [Android] Fix Android Studio 3.0 Beta 6 2017-10-01 00:18:25 -05:00
Lyubo Marinov 3b5ee2d4c6 [iOS] Add initial CallKit support 2017-09-29 12:00:13 -05:00
Lyubo Marinov e1222e947b [RN] Documentation, comments 2017-09-27 13:08:37 -05:00
Saúl Ibarra Corretgé 341e7e01aa [RN] Add the ability to set the default URL in the SDK 2017-09-27 11:59:00 -05:00
Lyubo Marinov b55faab33e Coding style 2017-09-27 11:01:27 -05:00
Saúl Ibarra Corretgé 3fdffa7497 [RN] Add AppInfo module
It provides access to the app's display name and version.
2017-09-27 10:32:07 -05:00
Lyubo Marinov ec58aa9959 [Android] Implement DefaultHardwareBackBtnHandler
* Regardless of whether the SDK client/consumer employs
  JitsiMeetActivity or JitsiMeetView, default to finishing the
  associated Activity upon invoking the back button (which is what
  Activity#onBackPressed() is documented to do).

* Do not break the public API of JitsiMeetView and, thus, Jitsi Meet SDK
  for Android.
2017-09-21 23:57:16 -05:00
paweldomas 35dab19b30 [Android] Implement DefaultHardwareBackBtnHandler
If the JS side chooses to not handle the back button press call
'super.onBackPressed()' to close the app.
2017-09-21 23:56:43 -05:00
Lyubo Marinov 2496b3ec02 [Android] Don't require camera, autofocus
Don't require autofocus because that prevents the app from appearing in
Google Play Store for some devices.

Don't require camera for the same reason but also because camera/video
is not a mandatory feature of the app, it's merely likely very
desirable.
2017-09-14 12:16:46 -05:00
Lyubo Marinov bf915fe886 Coding style, formatting 2017-09-14 12:14:54 -05:00
Lyubo Marinov f86f21beb2 [Android] Fix VerifyError on Android 4
The class ReflectiveOperationException used in ExternalAPIModule was
introduced in API level 19.
2017-09-13 14:32:32 -05:00
Saúl Ibarra Corretgé fe8f383a41 [Android] Update gradle plugin version for Android Studio 3 beta 5 2017-09-13 14:35:21 +02:00
Lyubo Marinov 72c9933e73 [RN] SDK building, installing, and publishing
Based on work authored by Shuai Li <sli@atlassian.com>, Daniel Ornelas
<dornelas@atlassian.com>, and Lyubo Marinov <lmarinov@atlassian.com>.
2017-09-11 20:12:56 -05:00
Saúl Ibarra Corretgé ba49c7955a [Android] Fix gradle and plugin versions with Android Studio 3.0 Beta 4 2017-09-08 10:47:08 +02:00
Lyubo Marinov fce0e4c22c [RN] Report loadConfigError with locationURL to the SDK consumers 2017-09-06 20:34:46 -05:00
Lyubo Marinov 4dc78ce458 [RN] Increase the coverage of JitsiMeetViewListener
JitsiMeetViewListener is an integral part of the public API of Jitsi
Meet SDK for Android. Utilize it in the Debug configuration of the Jitsi
Meet app for Android in order to increase (1) awareness of API breakages
and (2) API coverage.

The same goes for JitsiMeetViewDelegate in Jitsi Meet SDK and app for
iOS.
2017-09-06 16:31:15 -05:00
Lyubo Marinov e830b80b6b [RN] Fix documentation 2017-09-06 16:31:15 -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 1d8ee9d32f [RN] Reduce maintenance
JitsiMeetViewListener currently has methods of one and the same pattern
so adding new methods i.e. events i.e. redux action types is a question
of repetition in the Java source code. Speed up the support of new
events by trying to deal with them in a generic way.

The same goes for JitsiMeetViewDelegate.
2017-09-06 15:57:00 -05:00
Lyubo Marinov 6982506acc [RN] Remove duplication 2017-09-06 14:48:53 -05:00
Saúl Ibarra Corretgé 5f55b3198c [Android] Update gradle plugin version for Android Studio 3 beta 2 2017-08-24 15:04:31 +02: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
Lyubo Marinov 2356238887 [Android] Reduce boilerplate/duplication 2017-08-21 13:58:13 -05:00
Saúl Ibarra Corretgé ca80839094 [Android] Fix gradle and plugin versions with Android Studio 3.0 Canary 9 2017-08-08 14:48:43 -05:00
Saúl Ibarra Corretgé 1c1604bee7 [Android] Don't mute the microphone under any circumstance
It's a global action, and if we do that other applications won't be able to use
it. I experienced this with the system camera. We do, however, make sure to
enable it when we need to.

Note that enabling it doesn't mean we are *using* it. It just means we *can*,
and that we will get actual audio when we do.
2017-08-03 13:45:41 -05:00
Saúl Ibarra Corretgé 99fd325a51 [Android] Fix gradle warning
This setting is no longer used.
2017-08-03 13:45:41 -05:00
Saúl Ibarra Corretgé 4f6ec920cd [Android] Set targetApiVersion to 25
We keep being compatible with versions all the way down to 16 for now, but this
will disable internal compatibility shims when running on 25.
2017-08-03 13:45:41 -05:00
Saúl Ibarra Corretgé 0d33844d51 [Android] Use an appropriate Android support library version
It must match the compileSdkVersion major number.
2017-08-03 13:45:41 -05:00
Lyubo Marinov 504646fff0 Coding style 2017-08-03 13:45:41 -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 1ad8436cb5 [Android] Use loadURL in the app 2017-08-01 12:07:22 -05:00
Saúl Ibarra Corretgé bfa5f4c953 [Android] Fix resource leak when JitsiMeetView is destroyed
In iOS this is automagically done in the view destructor, bunt we don't have
that luxury in Java we have to do it manually.

The new disponse() method MUST be called when the Activity holding the view is
going to be destroyed, typically in the onDestroy() handler.
2017-07-28 10:50:12 -05:00
Saúl Ibarra Corretgé d00ee3d7b6 [Android] Add an example for loadURLObject 2017-07-28 09:19:07 -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
Saúl Ibarra Corretgé 51934dac1b [Android] Fix gradle version with Android Studio 3.0 Canary 8 2017-07-26 17:30:45 +02:00
Lyubo Marinov f0ab835b46 [RN] Add loadURLString to JitsiMeetView
Initializing a new URL/NSURL instance is a chore especially when one
takes into account that the JavaScript side (1) is loading the URL
asynchronously and (2) is capable of parsing strings that may or may not
be represented as URL/NSURL.

The Android method loadURLString(String) may have been called
loadURL(String) to overload loadURL(URL) but I didn't want to do that
because:

1. It would not be compatible with existing source code such as
loadURL(null) which would have become ambiguous.

2. I wanted to achieve better convergence with the iOS API.
2017-07-25 19:07:01 -05:00
Saúl Ibarra Corretgé 4efbbe14b1 [Android] Require OpenGL ES 2.0
This was already an implicit requirement, as it's the only version implemented
in libwebrtc.

The reason to add this is to (defensively) try to filter old devices which may
not implement it.

WebRTC's own Android demo app defines this.
2017-07-19 16:36:42 -05:00
Saúl Ibarra Corretgé 326ce4217f [Android] Fix gradle and plugin versions with Android Studio 3.0 Canary 6 2017-07-17 11:32:57 -05:00
Lyubo Marinov e54744e5ef [Android] Use target API 23 2017-07-16 02:26:09 -05:00
Saúl Ibarra Corretgé 96bfcafc97 [Android] Use target API 23
This reverts commit c9a29153dd.

Now that react-native-webrtc supports the permissions system in 23, use it since
it provides a more pleasant experience to users.

In addition, fix a bug in the previous code: the React Native view must be
loaded after we have acquired the permission to draw on top of other apps,
otherwise our app may crash while we accept the permission, since React may try
to draw.
2017-07-16 02:26:09 -05:00
Lyubo Marinov 9a295723cf Consistent formatting 2017-07-16 02:25:26 -05:00
Saúl Ibarra Corretgé 6fc1a3f45d [Android] Add comment on disabling JS packaging for dev builds 2017-07-10 17:42:39 +02:00
Lyubo Marinov 948d18f954 [Android] Fix "Minimum supported Gradle version is 4.1-milestone-1" 2017-07-06 15:20:09 -05:00
Saúl Ibarra Corretgé 01ac394e92 [Android] Fix compileSdkVersion
It must match the major number in buildToolsVersion.
2017-06-28 10:51:49 +02:00
Lyubo Marinov 8e4864004b Revert "Speed `react-native run-android` up (more)"
Reverts commit d117989b55 because it does
not bundle the fonts assets and the JS bundle.
2017-06-22 09:21:25 -05:00
Lyubo Marinov d117989b55 Speed `react-native run-android` up (more)
React Native's Gradle script does not bundle the JS bundle in the Debug
configuration. Copy that source code (and adapt it) into our sdk Gradle
script.
2017-06-20 13:14:30 -05:00
Lyubo Marinov 2fa7e777d6 Speed `react-native run-android` up 2017-06-20 10:32:44 -05:00
Saúl Ibarra Corretgé 617df1c69c [Android] Remove no longer used gradle options 2017-06-15 10:38:08 -05:00
Saúl Ibarra Corretgé c9a29153dd [RN] Lower Android target SDK version to 22
API level 22 is below 23 (aka Marshmallow), which included an overhaul in the
permissions system. React Native recommends 22 (it's the default when you create
a new app) and there have been reports when set higher [0] and [1].

This also fixes a critical bug, wherein Jitsi Meet wouldn't request permissions
for the camera and microphone.

Last, this change also allows us to get rid of the overlay checking code,
because it was only needed for API level 23 or higher.

[0]: https://github.com/facebook/react-native/pull/10479
[1]: https://github.com/facebook/react-native/issues/10587
2017-06-15 08:20:33 -05:00
Lyubo Marinov 4b2add7aa6 [Android] Allow multiple JitsiMeetViews 2017-06-10 03:34:11 -05:00
Lyubo Marinov 10e5e0fdf5 [iOS] Allow multiple JitsiMeetViews 2017-06-09 19:17:01 -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
Lyubo Marinov a5cd118550 [Android] Naming 2017-06-09 10:55:14 -05:00
Saúl Ibarra Corretgé a266a71999 [RN] Add JitsiMeetViewAbstractListener to Android SDK 2017-06-09 09:57:06 -05:00
Saúl Ibarra Corretgé be8694f93e [RN] Remove duplicated font on Android
Copy it from the main fonts directory instead.
2017-06-09 16:05:27 +02:00
Lyubo Marinov 90466183d6 [RN] Consistency in Jitsi Meet SDK for Android 2017-06-09 00:03:23 -05:00
Saúl Ibarra Corretgé 84463d8cf0 [RN] Add workaround for loading different URLs on Android
Changing the props from native (Java) code was only added in 0.45, so add a
workaround until we get to updating our React Native dependency.
2017-06-09 00:03:23 -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
Saúl Ibarra Corretgé ddea60efe9 [RN] Add initial Jitsi Meet SDK for Android
Dames en heren, welcome to Jitsi Meet SDK for Android, the Jitsi Meet library
for Android.

The Jitsi Meet SDK encapsulates React Native and all the dependencies Jitsi
Meet has so other aopplications can integrate it easily.

Unlike iOS, creating "fat" libraries is not allways (if at all) possible on
Android, however, effort was put into making the integration as easy as
possible.

While React Native can be embedded in native applications, I don't think it was
designed to be embedded as part of an Android library, hidden away from the
application using it. This surfaced as a number of issues which had to be
addressed specifically due to our use-case:

- Activity lifecycle methods must be linked with the React Native engine, so the
  library provides wrapper methods.
- Custom fonts have to be manually added as assets, since the provided gradle
  script doesn't work properly in a library target.
- The RN packager has to be manually triggered since the gradle script will no
  longer do it for us.

At this stage, the Jitsi Meet application is just a small single activity
application which uses the Jitsi Meet SDK to create a single activity which
represents the entire application. Events and external conference handling are
forthcoming.

PS: Yours truly would like to add that it was a lot more fun to work on the iOS
side of things.
2017-06-09 00:03:23 -05:00
Saúl Ibarra Corretgé bac191f96c [RN] Rename jitsi-meet-react to jitsi-meet 2017-05-16 12:38:36 -05:00
Lyubo Marinov 6c0ad4966e [Android] Go back to minSdkVersion 16 2017-04-19 13:55:44 -05:00
Saúl Ibarra Corretgé 5d50792a56 [RN] Make AudioMode more resilient on Android
Some devices may give an error stating that INTERACT_ACROSS_USERS_FULL
permission is neeced. This permission can only be achieved by signing the
application with the same key as the system, which is never going to happen so
deal with it by catching any exceptions setting the mode may cause and failing
as gracefully as we can.

Ref:
http://stackoverflow.com/questions/34172575/audiomanager-setmode-securityexception-on-huawei-android-4
2017-04-19 13:55:44 -05:00
Lyubo Marinov b211ce02a8 [RN] Increment short app version from 1.3 to 1.4
Now that Apple have approved build 1.3.204 for release in the App Store,
the short app version needs to be incremented; otherwise, no new builds
can be uploaded to TestFlight and, respectively, for release in the App
Store.
2017-04-09 12:00:58 -05:00
Saúl Ibarra Corretgé 13e3375e8a [RN] Use proximity sensor when in audio-only mode
When the audio-only mode is enabled, turn on the proximity sensor to dim the
screen and disable touch controls when there is an object nearby.
2017-04-05 22:06:30 -05:00
Lyubo Marinov 45e09af692 react-native 0.42.0 2017-03-07 15:09:39 -06:00
Lyubo Marinov e89c2b242d Android plugin for Gradle 2.2.3
Recent versions of the Android plugin for Gradle started to automatically
download the SDK build tools dependency if it is not installed already.
So it is no longer necessary to have the developer of the Android app
install the SDK build tools dependency in advance.
2017-02-23 13:14:19 -06:00
Yana Stamcheva 0dbbc5d8b6 [Android] Circular app/launcher icon(s) 2017-02-17 13:54:01 -06:00
Lyubomir Marinov dba1bcb0e3 [RN] Increment short app version from 1.2 to 1.3
Now that Apple have approved build 1.2.199 for release in the App Store,
the short app version needs to be incremented; otherwise, no new builds
can be uploaded to TestFlight and, respectively, for release in the App
Store.
2017-02-17 09:32:24 -06:00
Saúl Ibarra Corretgé 36f5b0218d [RN] Fix running timers in the background
Turns out React Native's timers (setTimeout / setInterval) don't run while the
app is in the background: https://github.com/facebook/react-native/issues/167

This patch replaces the global timer functions with those from the
react-native-background-timer package, which work in the background.

These timers won't magically make an application work in the background, but
they will run if an application already happens to run in the background. That's
our case while in a conference, so these timers will run, allowing XMPP pings to
be sent and the conference to stay up as long as the user desires.
2017-02-15 11:50:54 -06:00
Lyubomir Marinov 2ad869a036 Comply w/ coding style
- Use 1 name for 1 abstraction. Instead of useFullScreen and enabled use
  fullScreen.
- Comments are correct English sentences so no double spaces between
  senteces, no capitalization of the work On midsentence.
- Write as little source code as possible if readability is preserved.
- Utilize Facebook's Flow.
- The name of a private function must start with _ and the jsdoc should
  state that the function is private.
2017-02-06 15:32:03 -06:00
Saúl Ibarra Corretgé 7a8c84e990 [RN] Implement full screen mode while in a conference
The implementation varies across platforms, with the same goal: allow the app to
use the entire screen real state while in a conference.

On Android we use immersive mode, which  will hide the status and navigation bars.

https://developer.android.com/training/system-ui/immersive.html

On iOS the status bar is hidden, with a slide effect.
2017-02-06 13:51:17 -06:00
Lyubomir Marinov 0de01e93dd react-native 0.41.2 2017-02-06 12:24:38 -06:00
Lyubomir Marinov 94f3d4b279 [RN] Expand domains supported by Universal Links 2017-01-31 22:47:47 -06:00
Lyubomir Marinov fdc96044ad [RN] App-specific URL scheme 2017-01-31 22:47:47 -06:00
Lyubomir Marinov 18bc99d6b5 Split long methods into multiple shorter ones 2017-01-26 23:35:56 -06:00
Lyubomir Marinov bab94a207d Remove unnecessary source code 2017-01-26 21:08:50 -06:00
Lyubomir Marinov ef39baab47 Comply w/ coding style
- Maximum of 80 characters per line.
- Group first and then sort in alphabetical order.
- Fields should begin with a lowercase letter.
2017-01-26 21:07:35 -06:00
Saúl Ibarra Corretgé 2edaaac7bf [RN] Implement AudioMode module on Android
This module chooses the most appropriate audio default based on the specified
mode.
2017-01-26 19:18:10 -06:00
Saúl Ibarra Corretgé 113e50c074 [RN] Bump Andoroid minimum and target SDK versions
Use a minimum SDK version of 19, that is Anroid 4.4 (KitKat) and a target SDK of
23, that is, Android 6.0 (Marshmallow).
2017-01-26 19:18:10 -06:00
Lyubomir Marinov ae726cfdc0 react-native 0.40.0 2017-01-22 12:32:08 -06:00
Saúl Ibarra Corretgé 1a04e5a9af [RN] Use a translucent status bar on Android 2017-01-21 15:42:13 -06:00
Lyubomir Marinov cac68dbaba [RN] Increment short app version from 1.1 to 1.2
Now that Apple have approved build 1.1.185 for release in the App Store,
the short app version needs to be incremented; otherwise, no new builds
can be uploaded to TestFlight and, respectively, for release in the App
Store.
2017-01-20 15:01:01 -06:00
Lyubomir Marinov d1f6679f2d [RN] Remove Crashlytics 2017-01-17 21:54:17 -06:00
Saúl Ibarra Corretgé acbfe5cb09 [RN] Keep device screen on while in a conference 2017-01-16 19:12:43 -06:00
Lyubomir Marinov a887beed3a [RN] Increment short app version from 1.0 to 1.1
Now that Apple have approved build 1.0.178 for release in the App Store,
the short app version needs to be incremented; otherwise, no new builds
can be uploaded to TestFlight and, respectively, for release in the App
Store.
2017-01-06 10:34:46 -06:00
Lyubomir Marinov 4fef8a3b79 [RN] Prevent unhandled JS errors from killing the process in Release 2017-01-05 15:06:41 -06:00
yanas 5fce7f6ba2 Updates the react native font. 2016-12-21 15:00:24 -06:00
Lyubomir Marinov d939ae5fb2 Rename the package of the Android app 2016-12-06 17:23:39 -06:00
Lyubomir Marinov 727df551e6 Merge branch 'android-version' 2016-12-06 14:26:50 -06:00
damencho e5dc7058c1 Adds android version variable.
The variables in gradle.properties can be overridden on command line like: -Pversion=1.
2016-12-06 13:57:38 -06:00
Yana Stamcheva fc3e0147e0 [Android] Launcher icons 2016-11-08 10:38:13 -06:00
Lyubomir Marinov d875b35b32 [Android] Crashlytics 2016-10-30 18:12:33 -05:00
Matt Laux c18caf52d0 Fix Android launcher intent so that app appears in drawer. 2016-10-19 10:59:09 -05:00
Lyubomir Marinov 1ff0bdbcfd Fix the in-app icons on Android
Bundle our custom icon font jitsi.ttf in the Android app (which we
already do for the iOS app).

Additionally, remove icon font files which are not in use.
2016-10-19 09:10:11 -05:00
Lyubomir Marinov 7f3ff13c18 Merge jitsi-meet-react's mobile support
As a step toward merging jitsi-meet-react with jitsi-meet to share as
much source code as possible between mobile and Web, merge the part of
jitsi-meet-react's source tree which supports mobile inside the
jitsi-meet source tree and leave jitsi-meet-react's Web support in the
source code revision history but don't have it in master anymore because
it's different from jitsi-meet's Web support. In other words, the two
projects are mechanically merged at the file level and don't really
share source code between mobile and Web.
2016-10-12 10:31:52 -05:00