Samsung devices (of course) seem to stick with the earpiece if we first select
Bluetooth but then set speaker to false. Reverse the order to make everyone
happy.
This only applies to the generic and legacy handlers.
When ConnectionService is used (the default) we were attaching the handlers too
early, and since attaching them requires that the RNConnectionService module is
loaded, it silently failed. Instead, use the initialize() method, which gets
called after all the Catalyst (aka native) modules have been loaded.
It was introduced in Xcode 9 and made the default in Xcode 10. We were forcing
the use of the legacy version, which doesn't support some new features that we
wish to enable, such as building the SDK for distribution.
It crashes on Android. Well, on the JSC version React Native uses on Android.
While we could use this fallback only on Android, we have decided to use it
on all mobile platforms for consistency.
It crashes on Android. Well, on the JSC version React Native uses on Android.
While we could use this fallback only on Android, we have decided to use it
on all mobile platforms for consistency.
Separate each implementation (3 as of this writing) into each own "handler"
class.
This should make the code easier to understand, maintain and extend.
- Remove network-activity "feature"
- It wasn't in use
- It relied on internal React Native components, bound to break anytime
- Show an infinite loading indicator
- Style it just like the LoadConfigOverlay
- Since it kinda represents the opposite, an "unload" then SDK is done
We are downloading code off the Internet and executing it on the user's device,
so run it sandboxed to avoid potential bad actors.
Since it's impossible to eval() safely in JS and React Native doesn't offer
something akin to Node's vm module, here we are rolling our own.
On Android it uses the Duktape JavaScript engine and on iOS the builtin
JavaScriptCore engine. The extra JS engine is *only* used for evaluating the
downloaded code and returning a JSON string which is then passed back to RN.
- use AbortController for setting the fetch timeout
- use async / await syntax for clarify
- set the default timeout to 5s (previously non-existent, aka 0)
- add ability to load but not evaluate a script
They never worked on mobile and pose an impediment for makinf config.js more
future proof. Specially if we want to move to a non-executable form of
configuration.
This adds an option to disable video autoplay that will be used mostly with maleus (our selenium-based load testing tool for testing the new bridge). Disabling video rendering lowers the resource utilisation of the selenium nodes.
If the Activity is put into the background before the ReactContext is created we
get an NPE here. While the window might be short, it's thechnically possible to
hit this, as our Crashlytics reports show.
Bring back the workaround introduced in afd2aea7
but removed in 21dcc41d. On conference join,
several other actions have already been fired
that try to set the large video participant
and select the participant on the bridge.
The problem is there is no conference during
these actions so the select participant
never fires. Then subsequent actions do not
fire select participant because the large
video participant has not changed.
This commit changes how the SmallVideo.isVideoPlayable method works.
1st we remove the check on the video stream muted field (materialized with the
!this.videoStream.isMuted() guard). This check is redundant as it is
already materialized in the !this.isVideoMuted check (the isVideoMuted
field is updated with the return value of the videoStream.isMuted()
method).
2nd we return false if we're in audio only mode, because it's
(obviously) undesirable to have a playable video when in audio only
mode.
We try to load the configuration with every room change, even when there is no
room. There is a bad (corner) case: when we have no config cached (first boot or
wiped app data). In such case the user is trapped in an infinite loop because we
require the config to show the welcome page, oh well.
Pretend we have a configuration by creating the most minimal one to at least get
to the welcome page.
Audio streams are automatically played by WebRTC and this won't change, probably
ever. There is no point in having checks and an Audio component which does
nothing.
In iOS 13 if the call is not unmuted when we report it to the system as started,
an action to unmute it is dispatched automagically. Thanks, Apple.
So, delay synchronizing the muted state until the conference is started (after
the join action). This creates a small window for de-synchronization, but it's
very short and it seems unavoidable.
This change is only applied to operating systems built by the fruit company in
Cupertino.
The currently selected values are a bit above the actual sizes, so if a PR
increases the bundle size enough to trigger the failure, it should bump it.
It better have a good reason for it though!
Build as follows to build (production) bundle size stats:
npx webpack -p --progress --analyze-bundle
Then open the report:
npx webpack-bundle-analyzer build/stats.json build/
In
b53a034aaf (diff-0339cf92cc68bc5981fe6df601316c1c)
I removed this, because RN has updated the builtin JSC version. On the next
release, however, RN introduced a new JS interpreter (Hermes) so JSC is now a RN
dependency. Thus, add the magic spells to publish the AARs to Maven.
These provide the ability to integrate the SDK with some other application
loggers.
At the time this was written we use Timber on Android and CocoaLumberjack on iOS.
In addition to the integration capabilities, a LogBridge React Native module
provides log transports for JavaScript code, thus centralizing all logs on the
native loggers.
Will emit new 'network.info' action with the online/offline status and
extra details for native like the network type and
'isConnectionExpensive' flag.
* Get participant specific video element
We now have the ability to select the video element for specific participants. I'm tweaking the jitsi-meet-electron app for my use case. I need to open Always On Top windows for specific participants, so the current _getLargeVideo() wont suffice.
I made a post about this in the Developers section on the Jitsi Community Forum, but it got blocked by Akismet.
* Add dots at end of sentence.
* Fixed ESlint errors and add additional check for iframe.
* Use _myUserID instead of string.
* Return the local video by default if participantId is undefined.
* Fixed mistake in string template.
It need not always exist, since it's created asynchronousluy on app
initiualization. Make sure we are ready for it.
I've seen backtraces because of this.
Any overrides set on interfaceConfig are not
applied on module load. As such, call to get
the value of the auto pin setting, providing
time for the bootstrapping to set overrides.
Otherwise iframe api users cannot override
the setting.
React Native doesn't define __filename nor __dirname so do it artisanally. In
addition, this helps with centralizing the configuration passed to loggers.
Mobile uses a different logic for deciding whether to show the filmstrip or not:
if there are more than 1 participants or not, and there is no way to manually
toggle it.
This commit refactors device selection (more heavily on iOS) to make it
consistent across platforms.
Due to its complexity I couldn't break out each step into separate commits,
apologies to the reviewer.
Changes made to device handling:
- speaker is always the default, regardless of the mode
- "Phone" shows as a selectable option, even in video call mode
- "Phone" is not displayed when wired headphones are present
- Shared device picker between iOS and Android
- Runtime device updates while the picker is open
In case of hitting errors like max participant limit reached and when clicking hangup, the attempt to leave room second time results error and reload screen.
It's an evolution of audio-only mode, where we also allow for receiving a remote
screen-share.
Diving deeper: this basically sets last N to 1 or 0 depending on the
availability of a screen-share.
This prevents inserting any user overridden APP_NAME
values into html. A new translation key is being used
to immediately stop non-english languages from using the
problematic string.
Also tweaked the copy to remove the "eer" and fix
some grammar.
This refactors all handling of audio-only and last N to 2 features in preparation
for "low bandwidth mode".
The main motivation to do this is that lastN is a "global" setting so it helps
to have all processing for it in a single place.
* ref(feedback): emit api feedback submitted on completion
Compared to firing the event on submission because
the submission ajax will not be completed at that
time..
* squash: update package.json
When a participant is pinned in the UI we then proceed to mark it as selected on
the JVB. This will make the participant part of the last N set and will receive
the highest (or configured highest) video quality.
Pinning a participant at the JVB level just makes sure it will be part of the
last N set.
Since only one participant can be pinned in the UI, there is no point in pinning
it at the JVB level, since selecting it already achieved the same result.
Moves getCurrentConferenceUrl method to base/connection to allow reuse.
The new location is not ideal, but looks the best based on the imports
required (trying to avoid circular dependencies).
* Moves talk while muted as a new feature.
* Adds sound notification for talk while muted.
* Reorder imports and changes the dispatch of the notification.
* Introduces sounds.js for talk while muted.
* Removes unused translations.
* Fixes using translated strings.
* Moves using latest i18next versions and stop using compatibility modes.
* Sorts i18next options.
* Fixes defaultNS used by i18next.
This is used when translating html tags with data-i18n keys as attributes, used by jQuery-Impromptu.
* ref(user-interaction): remove storing of listener
* ref(user-interaction): move browser requirement check to lib-jitsi-meet
* ref(user-interaction): no inner function for listener, use module scope
* Listens for suspend events from jitsi-power-monitor on postis channel.
* Removes duplicated type and actions.
* Moves suspendDetected state from overlay to power-monitor feature.
Set our own audio device manager so we can tweak it if need be (enabling /
disabling the HW AEC on specific devices).
Switch to using the software video encoder / decoder. This may feel like a
downgrade, but it has advantages:
- simulcast is now working (on par with iOS)
- certain devices have broken VP8 HW encoders (I'm looking at you Samsung Galaxy
S7) so this fixes that
Multiple requests for checkUserRemoteControlSupport can be in
flight simultaneously. Order of promise resolution is not
guaranteed. It is possible for Request A and Request B to be
in flight and then Request B's promise chain resolves first.
Request A could have encountered errors and then resolve. Then
what could happen is checkUserRemoteControlSupport returns true
for remote control support due to Request B and the UI updates.
But then checkUserRemoteControlSupport returns false for
remote control support due to Request A's error and the UI
updates to hide remote control.
* fix(invite): decode the meeting name
* squash: try to make mobile join same encoded meeting name as web
* Decodes and generated texts for share and copy meeting info.
Decodes in all cases except when it contains a space, as it will generate wrong links when pasted/shared in external applications.
After calling startService we are supposed to have a bit of time before turning
the service into a foreground service, but certain devices seem to be more
spartan and we've seen the following failure:
Caused by java.lang.IllegalStateException: Not allowed to start service Intent { act=JitsiMeetOngoingConferenceService:START cmp=org.jitsi.meet/.sdk.JitsiMeetOngoingConferenceService }: app is in background uid UidRecord{f6778d5 u0a220 CAC bg:+1m1s417ms idle change:idle procs:1 proclist:15604, seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon + 1600(ContextImpl.java:1600)
at android.app.ContextImpl.startService + 1546(ContextImpl.java:1546)
at android.content.ContextWrapper.startService + 669(ContextWrapper.java:669)
at org.jitsi.meet.sdk.JitsiMeetOngoingConferenceService.launch + 50(JitsiMeetOngoingConferenceService.java:50)
Be expliocit and call startForegroundService, on supported platforms.
The app is about to crash at that stage so it was a moot point to try to leave
the conference anyway.
Stopping ConnectionServers is still a good idea though, since a crash may leave
the device in a bad state otherwise.
Fixes this issue:
~~~
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1441)
at java.util.HashMap$KeyIterator.next(HashMap.java:1465)
at org.jitsi.meet.sdk.OngoingConferenceTracker.updateListeners(OngoingConferenceTracker.java:89)
at org.jitsi.meet.sdk.OngoingConferenceTracker.onExternalAPIEvent(OngoingConferenceTracker.java:74)
at org.jitsi.meet.sdk.ExternalAPIModule.sendEvent(ExternalAPIModule.java:71)
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:158)
at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
at android.os.Looper.loop(Looper.java:214)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:232)
at java.lang.Thread.run(Thread.java:764)
~~~
this._room should be used only by jitsi-meet-torture and for test purposes. Also this._room is assigned later than room. This may cause some issues, for example conference.getMyUserId() may return undefined while the user id is already available beacuse this._room hasn't been assigned yet.
* Adds a notification when remote lock happens.
* Updates translations.
Removes unused strings and extracts room password to separate translation, to be able to change it when deployment uses only digits.
* Formats the conference pin when showing it.
* Removes member from translation in favour of participant.
* Updates formatting of the pin.
* Adds a notification when password is remotely removed.
Update LJM to 9bcc2a26cc94683b8ed302418695a331b450df97 in order to bring
in the analytics update which will add a property indicating how much
time has passed since the last successful XMPP request came through.
Join notifications are already supressed for the local
participant, so hide the left notification. For now
the notification is not being shown on mobile to keep
the same existing behavior and because a copy change
will be needed, but will be added once batching is
implemented.
This helper method gets the current Activity attached to React Native (via the
ReactContext). This is useful for modules which need access to it, without being
actual React Native modules.
When native SDK users end a meeting the view gets disposed and detached from
React, and then the entire app gets destroyed and these errors get printed at
the error level, throwing some people off.
* Fixes inviting more than one participant.
* Shows a notification when participants are invited.
* Adds support for both .id and .user_id props for people query results.
This was hit on a corner case when ConnectionService will deny
the request to start the call. I am not sure, but it could have been
that the conference object has been disposed or closed or something
else, but the fact is that 'conference.room' was not defined and things
crashed. It is not safe to access conference's private field 'room'. It
is true JitsiConference doesn't follow the practice of marking this
field as private with the underscore '_', but it is not a public field.
Its main task is to cleanup conferences (specially the connection services
stuff) to make sure the system is left in a working state even when the
unexpected happens.
* Updates kick showing who kicked us.
* Notify participants that someone was kicked.
* Shows notification to user who is remotely muted.
* Updates the notification type.
* Muted by notification for mobile.
* Moves code to react and adds the kick notifications to mobile.
* Updates lib-jitsi-meet.
* Updates start silent, turning on startWithAudioMuted and few UI tweaks.
Disabled mic unmute button and removes remote participants volume slider.
* Adds analytics for start silent.
* Removes extra semi colon.
* Updates lib-jitsi-meet and updates meeting info text.
Checking if the calendar support in the reducer is not only useless but wrong,
since we don't have access to the entire store (the calendar support is checked
in the base/config feature). If calendar support is not enabled the actions
being reduced won't be dispatched anyway, so no harm is done by removing the
check.
When the video unmute button disabled audio-only, also unmute video. This fixes
a weird case in which the user need to "unmute twice" if they were muted beofre
they enabled audio-only mode. That's ok if the audio-only button was used, but
not if the video-unmute button was used, since the expectation is to have video,
of course.
Re-structure the custom routing to split between
platforms instead of between intended route features.
This made it easier for me to understand where to
do the checks for unsupported browser after deep-linking
had been checked.
If a value is not set in localStorage then null is
returned. null should not be converted to an empty
string (via _.escape) because that will then be
stored in localStorage as the user set preference
and will keep overriding any other values set
in localStorage for the displayname.
VideoLayout schedules a large video update by passing in
the video stream on the small video instance. When a stream
is removed, the UI is removed from the small video instance
but a reference to the stream is left. So when VideoLayout
schedules the large video update after a stream removal,
the old stream from the small video instance is re-used,
even though it has been removed.
This change also brings balance with RemoteVideo method
"addRemoteStreamElement" which sets the stream on the
small video instance, so now "removeRemoteStreamElement
unsets it.
- Use actions to notify the rest of the app that
a mic or camera error has occurred
- Use middleware to respond to those notifications
of errors by showing in-app notifications and
notifying the external api
This reverts commit f42d0411b1.
The UX provided by this feature flag in its current state is not
desired. Also, I noticed filmstrip sometimes failing to properly
update small video display mode on pin/unpin. The feature is
being left in for consumers of jitsi-meet to enable as needed.
When in a conference, try to enter PiP when pressing the back button. If this is
not possible (because it's unsupported, not enabled, etc.) fall back to the
previous behavior of simply hanging up.
This PR changes the logic for connecting / disconnecting conferences. Instead of
doing it in mount / unmount events from the Conference component, it moves the
logic to the appNavigatee action.
This fixes a regression introduced in 774c5ecd when trying to make sure the
conference terminated event is always sent.
By moving the logic to appNavigate we no longer depend on side-effects for
connecting / disconnecting, and the code should be more maintainable moving
forward.
An improvement to this is the concept of sessions, which, while not tackled
here, was taken into consideration.
For the external api to fire update events out of the iframe, it
must first be initialized within the jitsi app. Any invocations
by the app to send updates events before initialization will
cause the api to swallow the events. The chosen fix is to
initialize the api earlier so the first update of app's redux
store fires update events that the api will also fire out of
the iframe.
This change will affect current behavior in that right now
the update event of the initial set of the avatar url is
blocked, but the change will make that event fire out of the
iframe.
Currently devices set through the api are stored
as ids, and not user selected. This can cause
other existing user selected devices to take
precedence over the devices passed into the api.
Stop using special case logic for aligning screenshare videos.
It may be possible to have positioning all done using CSS but that
seems to be a more significant refactoring.
It's possible a CallKit event arrives when the React Bridge has been torn down
and there is an assert that checks this. In order to avoid a crash, just skip
the event.
Entering PiP mode while the permissions dialog is display will not only
fail, but also mess up the Activity lifecycle on some OS versions.
We may end up with two activity/fragment instances and a situation where
the onStop callback was not called yet on the instance #1 while
the onResume has been already called on instance #2.
By making the container 100% height and position relative, that
would cause it to overlap any static-positioned elements below it.
The 100% makes it so that any watermarks intended for the bottom
of the page show up on the bottom of the page. However, it's not
needed because watermark stylings already try to position the
watermarks at the bottom.
Time has come. We need to enable bitcode. It's optional for iOS targets, but
mandatory for the entire project if there is a watchOS target. Since we have a
watchOS target, it's time to enable it.
* Fix detecting preferred audio output.
Fixes detecting when a new output device is found and we have stored user preference of using that device.
* Does not store which is the currently open device on save.
Does not save the currently opened device when saving settings dialog, this will be done once we successfully replace the tracks to use the new devices.
* Saves opened audio device after successfully changing it.
If we do it earlier _updateAudioDeviceId is using localAudio and can store wrong value.
* Adds notification for new non preferred devices.
A notification is shown which gives an option to the user to select and use the newly plugged devices.
Adding custom button and handler for the action to the notifications.
* Changes logic to search and handle all newly added devices from array.
* Moves some utility methods to features/base/devices.
The state about currently opened devices is filtered and not stored, where we only store when user selects a device preferences.
Also allow changing input devices for Firefox when we are not in a conference.
* Prints errors in case of wrong initialization.
Not printing can masks some errors in the code.
* Allow only one Follow Me moderator in a meeting.
* Sends Follow Me state with all presences of the moderator.
This fixes an issue where the moderator sends the Follow Me state and then for example mute or unmute video (this will produce a presence without Follow Me state) and the new comers will not reflect current Follow Me state till a change of it comes.
* Changes fixing comments.
* Changes fixing comments.
Replace the Swift array with an Objective-C one, since it's going to store
Objective-C objects and not Swift objects (or Swift objects which inherit from
NSObject, which is equivalent).
This avoids the need for JMCallKitEventListenerWrapper entirely, since an
NSArray can store NSObjectProtocol objects, unlike a Swift array, which prompted
the creation of the wrapper in the first place.
Dear reader, I'm not proud at all of what you are about to read, but sometimes
life just gives you lemons, so enjoy some lemonade!
Joining a conference implies first creating the XMPP connection and then joining
the MUC. It's very possible the XMPP connection was made but there was no chance
for the conference to be created.
This patch fixes this case by artificially genrating a conference terminated
event in such case. In order to have all the necessary knowledge for this event
to be sent the connection now keeps track of the conference that runs it.
In addition, there is an even more obscure corner case: it's not impossible to
try to disconnect when there is not even a connection. This was fixed by
creating a fake disconnect event. Alas the location URL is lost at this point,
but it's better than nothing I guess.
The SDK will now search for an asset called "CallKitIcon" on the main bundle,
and fallback to a built-in asset it it's not there, allowing SDK users to
customize it by just adding asset with that name.
Ever since we switched to handling track events instead of mute actions this has
been dead code. It was also added in the wrong place, since it's responsibility
of the JS code to solve the ping-pong problem.
The chat icons are different on windows and mac, with
windows icons being bigger. By settings a specific
width on the smiley container, windows would see
part of the smiley cut off.
When a fade in/out animation is in progress, another large
video update can be queued but can try to force itself onto
large video. For example a pin can be in progress and while
the fade in/out animation plays, local video can change its
video type during the animation and forcing an update of
large video. This results in local video getting forcible
updated onto large video while the pinned video is left on
small video only.
The Audio.js setRef callback does not behave like react ref callback
in that the former will not have fired before componentDidMount
but the later will have. So for audio output preview, trying to set
sink id on mount will no-op because it does not have a ref yet to
Audio.js, possibly leading to audio output previews playing on
the default speaker device. This generally has not been a user
visible problem due to coincidence; other re-renders necessary
by the parent of audio output preview will have triggered
componentDidUpdates on the audio out preview, which would then
set the sink id on the Audio.js ref it should have received
by then.
Searching for a device (id) by label alone can result in
false results when devices share labels, such as a mic
and speaker having the same label. To prevent such,
specify the device kind to be found instead of iterating
over all device kinds.
When the iFrame api is used to set a preferred audio output using
options passed into the JitsiMeetExternalAPI constructor, no logic
fires to actually change the audio output destination.
Devices of different kinds can have the same id, such as speaker
and mic both being default. Using id only can then lead to
incorrectly setting device descriptions in the current devices
object.
On some Samsung devices the call done with the ConnectionService end up
in the native call history which we don't want. That's fixable by
marking the Connection as "external" just before the call is
disconnected.
Another issue specific to Samsung devices about the audio focus not
always being release when that call ends. That's fixable by marking
the call as holding just before disconnecting it.
They greatly simplify starting a JitsiMeetActivity by encapsulating the creation
of the Intent adn extras placement.
In order to make this possible JitsiMeetConferenceOptions now implements
Parcelable so it can be serialized and passed around when creating an Intent.
Now that we have both a Fragment and an Activity there are lifecycle methods
that overlap. If a Fragment requests permission by calling requestPermissions
then the result handler will be called on itself. React Native's permissions
module, however, calls ActivityCompat.requestPermissions on the Activity, thus
we need to handle the results at the Activity level and not at the Fragment
level.
* ref(display-name): do not pass in display name
The component gets the state itself from redux.
* fix(display-name): do not default name to placeholder name
The web display name component supports inline editing of
the name. Problems can occur when the displayed name
differs from the actual saved name, because participants
without a display name, including the local user, have
a different, default display name displayed. So when
editing starts, the input field is populated with the
default name. To workaround such while supporting fetching
the display name using mapStateToProps, pass in both the
name which should be shown and the name value saved in
settings.
* ref(display-name): rename methods
It's a number whichb must be ever increasing with each build submitted to the
store.
Automate its value by using the number of seconds since 1st of January 2019.
That should be enough for ~680 years.
Turns out that on Samsung phones the calls placed with
the ConnectionService appear in the calls log as weird long numbers.
The system mangles the address we give it ("sip:meet.jit.si/something")
into this weird long number and the call to request.getAddress() returns
that. Turn off the presentation as neither this number nor our address
makes sense. This way the call appears as from "Unknown" caller in call
history which is still not perfect, but better than the random number.
Note that other phones will preserve the originally passed address value
(tested on One Plus 5).
Turns out the microphone will not work on some devices when starting in
"audio only", because the audio mode is not set to the MODE_IN_COMMUNICATION,
but to the MODE_IN_CALL. Calling setAudioModeIsVoip(true) makes
the system adjust to MODE_IN_COMMUNICATION and the mic works fine.
If user dismisses the not topmost notification the timeout will be
cleared and a new one will not be set, because the top notification
remained the same (see the if at line 90).
The docs of 'componentDidUpdate' say that it's not called for the
initial render. If the component is added to the DOM with 1 notification
already, then the update will not happen and timeout will never be set
which will effectively break the timeouts chain.
When running the app from Android Studio the React packager is not automatically
started. In vanilla RN projects this is done by the "react-native run-android"
command, but often times it is desired to run from Android Studio.
This fixes that by starting the packager from Gradle.
It's enabled by default, but marked as experimental (uh?!). It creates trouble
as sometimes the packager goes bananas. Disable them until further notice, our
bundle is not that large anyway.
NSURLConnection sendSynchronousRequest is deprecated since iOS 9. Replace the
method by whjat's currently on RN master, which implements a modern alternative.
Using anything non-serializable for action types is discouraged:
https://redux.js.org/faq/actions#actions
In fact, this is the Flow definition for dispatching actions:
declare export type DispatchAPI<A> = (action: A) => A;
declare export type Dispatch<A: { type: $Subtype<string> }> = DispatchAPI<A>;
Note how the `type` field is defined as a subtype of string, which Symbol isn’t.
* Removes unused ADD_PEOPLE_APP_NAME
* Moves deep-link header background and logo size as variables.
* Fixes more numbers page space in the header.
* Fixes left padding on deep-linking mobile page.
Consolidate all failure cases into a single one: CONFERENCE_TERMINATED. If the
conference ended gracefully no error indicator will be present, otherwise there
will be.
In practice, we are never going to be in a position where we don't have a
ReactContext but we do have some React Native code running. So let's not expect
the impossible.
It was never used and typicallt the Activity / Fragment holding the
JitsiMeetView object will be the listener.
In addition, once we refactor the events they will be reduced into far fewer.
There is no need for AbstractApp to require some getWindowLocation function.
It's only used in one place and we even polyfill it on mobile.
Thus replace it's usage with more specific functions.
Since the SDK may be embedded with other apps, we need to recognize our custom
URL scheme and universal links in order to tell the user if we will process the
request or not.
Make them configurable with sane defaults.
Bring over two fixes for spot. One is for
identifying the screenshare type when using
a camera for screenshare or when using a proxy
stream. Also bring in a fix to avoid a js error
in chrome ios.
* Adds new format of phoneList service and re-design dial in numbers page.
Adds flags and country names (with translations) for the numbers if using the new format.
* Fixes tests and fixes get default number.
* Updates swagger with new format.
* Moves html back yo table.
Fixes displaying on mobile and also the tel: URI generation. The tel: URI is tested on Android and iOS and seems to work (Android was not interpreting 'p', but both seems to like ',').
* Fixes a wrong return statement.
* Small fixes.
When a conference is started, the currently used
camera device id is saved. I believe this is happening
because lib-jitsi-meet does not use exact device id
mathcing when calling getUserMedia, so it's possibl
to request camera A but get camera B back because
camera A is not available. When config.startScreenSharing
is true, the syncing occurs and saves the desktop
source id. So when screensharing is stopped, jitsi-meet
requests that desktop source id instead of the preferred
camera.
The conference disconnection process is asynchronous which means there's
no guarantee that there will be CONFERENCE_LEFT event for the old
conference, before the next conference is joined. Because of that we can
end up with two simultaneous calls on the native side which is not
always supported. End the call on CONFERENCE_WILL_LEAVE to fix this
corner case.
RTCAudioSession is a thin wrapper around AVAudioSession provided by the WebRTC
framework. It makes some use-cases easier, and leads us closer to manual audio
unit management, which we will likely need in the near future.
Both Chrome and Firefox can work without extensions now, so it no longer makes
sense to default to disabling it in Chrome. Moreover, rely on the fact that
undefined is falsey so no actual config needs to be provided.
* fix(large-video): do not show avatar if no url
By default the large video dominant speaker avatar
has an empty src, which will result in a broken
image displaying. There is also disconnect with
non-react code trying to set an undefined src.
To prevent such until local avatar generation
work is done in the future, just don't show the
avatar.
* fix(conference): set the room instance earlier
Set the room instance on APP.conference before triggering
a redux update of the conference being set,, because
middleware can then fire and call methods on APP.conference
that depend on the room being set.
* get local participant directly from store instead of from global
This reverts commit 7c911eca96.
I'm dumb. We need global mode because otherwise lastIndex is not updated in the
regex object, which we rely upon, so this is intentional.
When we are in the default state (ie, not in a meeting) we shouldn't override
the AVAudioSession category and mode. It's a singleton and we might be bothering
other components of the host app which use it.
e729f0948c contained an off-by-one error:
URI_PROTOCOL_PATTERN includes the colon, so after applyting the regex we are
left with something like '//example.com/room' thus we only need to strip the
first 2 characters.
🤦
Looks like custom-scheme links no longer work in all browsers. They do on
Firefox, but the don't in Chrome and other default browsers.
So, switch to intent links on Android:
https://developer.chrome.com/multidevice/android/intents
Example:
```
<a href="intent://meet.jit.si/test123#Intent;scheme=org.jitsi.meet;package=org.jitsi.meet;end">Open Jitsi Meet</a>
```
Dominant speaker events can trigger local participant updates
without a display name. Do not update the name unless there
is an explicit update in the action.
Instead of bundling it in lib-jitsi-meet, which unnecessarily increases
lib-jitsi-meet's bundle size, polyfill it here so it's available in the global
scope, just like the web does.
* feat(Android): implement ConnectionService
Adds basic integration with Android's ConnectionService by implementing
the outgoing call scenario.
* ref(callkit): rename _SET_CALLKIT_SUBSCRIPTIONS
* ref(callkit): move feature to call-integration directory
* feat(ConnectionService): synchronize video state
* ref(AudioMode): use ConnectionService on API >= 26
Not ready yet - few details left mentioned in the FIXMEs
* feat(ConnectionService): add debug logs
Adds logs to trace the calls.
* fix(ConnectionService): leaking ConnectionImpl instances
Turns out there is no callback fired back from the JavaScript side after
the disconnect or abort event is sent from the native. The connection
must be marked as disconnected and removed immediately.
* feat(ConnectionService): handle onCreateOutgoingConnectionFailed
* ref(ConnectionService): merge classes and move to the sdk package
* feat(CallIntegration): show Alert if outgoing call fails
* fix(ConnectionService): alternatively get call UUID from the account
Some Android flavours (or versions ?) do copy over extras to
the onCreateOutgoingConnectionFailed callback. But the call UUID is also
set as the PhoneAccount's label, so eventually it should be available
there.
* ref(ConnectionService): use call UUID as PhoneAccount ID.
The extra is not reliable on some custom Android flavours. It also makes
sense to use unique id for the account instead of the URL given that
it's created on the per call basis.
* fix(ConnectionService): abort the call when hold is requested
Turns out Android P can sometimes request HOLD even though there's no
HOLD capability added to the connection (what!?), so just abort the call
in that case.
* fix(ConnectionService): unregister account on call failure
Unregister the PhoneAccount onCreateOutgoingConnectionFailed. That's
before the ConnectionImpl instance is created which is normally
responsible for doing that.
* fix(AudioModeModule): make package private and run on the audio thread
* address other review comments
* fix(local-recording): allow config override to enable
Config overrides are not set until some time after
APP_WILL_MOUNT has completed and not in the same execution
context as when APP_WILL_MOUNT is called. So instead
choose recording controller initialization at a later time.
The time chosen is after conference join because the
controller needs the conference instance to work.
* remove redundant conditional check
* feat(screenshare): support remote wireless screensharing
- Pass events to the ProxyConnectionService so it can
handle establishing a peer connection so a remote
participant, not in the conference, can send a
video stream to the local participant to use as a
local desktop stream.
- Modify the existing start screensharing flow to accept
a desktop stream instead of always trying to create one.
* adjust ProxyConnectionService for lib review changes
Delay removing the room reference. This is in case a
consumer of the API is attempting to submit feedback
after hangup but before redirecting to another page.
If the room reference is removed, feedback submission
will fail during this period.
Analytics is erroring when unpinning because the logged
event sends null for the objectId. The objectId should
be the id of the person getting unpinned.
This feature is intended for spot. Spot can have an
HDMI -> usb adapter hooked up to it. In that case,
attempting to screenshare should use that adapter
as a screensharing source. Jitsi-Meet should pass
a configured screenshare source into lib-jitsi-meet
so it can be used as a source.
This is done to kill off the last deprecated lifecycle
usage. There is special logic within index.native to get a
default meeting url by asynchronously fetching it, if
a url is not passed initially. The url is then put onto
state and overridable on subsequent prop updates.
This is mostly implemented in the app, with the needed support in the SDK. Since
the app needs to donate intents and deal with creating NSUserActivity objects it
doesn't feel right to do this in a library. Instead, we donate the intents from
the app, but the SDK is ready to extract conference URLs from any intent which
was registered as a conference activity.
This also opens the door for eventually adding Handoff support.
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.
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.
- bump expose-loader to 0.7.5
- remove unused file-loader
NOTE: The first incarnation of this commmit also removed string-replace-loader,
but alas lib-jitsi-meet lists it as a devDependency so it's not installed and we
are currently running webpack on install. This is arguably wrong, but that's a
discussion for another day.
Instead of handling the side effect of navigating to another
url from within componentWillReceiveProps, try to match the
same logic instead in componentDidUpdate.
Touch feedback manifests in some ugly black border bleeding out of the thumbnail
itself. Since we already provide feedback (be that by adding the blue border in
case of pinning, or showing the menu in case of long press) the perception is
the same, without the graphical glitch.
- Change the existing overrides to move the flags
so the first flag does not cover the toolbar.
- Add a new override to disable the slide in
animation, as it will play for each flag once
it becomes the first flag--instead of playing
only once when the flag queue has items.
A CSS override prevents atlaskit theme from setting a
dark background on the top toolbar. With the upgrade
of the theme package the CSS class names changed.
- Reset some state on the singletons conference
and VideoLayout.
- Add a way for LocalVideo to clean itself up
by sharing logic with the other SmallVideos.
- Add clearing of chat messages so they don't
linger.
- Remove some UI event listeners.
componentWillMount is a deprecated lifecycle method;
componentDidMount should be used to kick off things
like ajax. In the case of the _App hierarchy, a promise
chain is used to perform initialization, and it is
first started in the constructor by initializing
storage. However, by the time storage is initialized,
resolving the first promise, _App has already mounted.
So, move it all to the componentDidMount lifecycle.
WelcomePage used to use @atlaskit/tabs to switch between
recent meetings and calendar meetings. @atlaskit/tabs is
no longer used there so remove the css hacks which made
it look more presentable.
* Fix LoginDialog hidden by gUM-Overlay
Running FF46 on Linux and Android. The gUM Dialog (zIndex 1013) hides the LoginDialog (zIndex 999 by default) , but the gUM Dialog will only be resolved when connection is completed (aka hideUserMediaPermissionsGuidanceOverlay is called once the Promise.all in createInitialLocalTracksAndConnect is resolved and that Promise includes "connect").
Fix this by increasing the connection dialog zIndex.
Alternatively this could by fixed by handling gUM and connection one after the other.
* remove whitespace change
Adds the component which receives the messages from client and a module which enabled on a virtual host will start advertising the component. When clients discover the component they will send message to the component with the name of the room where the dominant speaker event happen.
The package now requires using a ModalTransition component
to handle animations. The existing DialogContainer component
has been split into native and web implementations to support
this change.
The avid reader may notice we have switched to using our own fork. That is
indeed the case. The upstream author hasn't maintained the library in months,
and changes to the Android build system are required at this point, hence the
fork.
It's possible for the YouTube api to return zero broadcasts
or broadcasts without any streams--streams are what are
associated with stream keys. In this case, instead of showing
an empty selector or no selector, show a message with a link
to where the stream key can be obtained.
On tile view enter/exit, local video is moved in the DOM (an effect
of not being reactified and moving being easier) and play is called
on its video element. The race condition setup is such: in tile
view with other participants and local video is on large (not
visible in the UI but visible in the app state and pip popout).
The race is such: pin a remote video, large video update is queued,
tile view is exited, local video is moved, play is called,,
onVideoPlaying callback executed, middleware fires mute update,
which checks if local is on large (it is), previous large video
update is cleared, and local is placed on large.
The fix is ensuring the redux representation of local video is
passed in, which holds the boolean videoStarted, which prevents
the onVideoPlaying callback from firing on subsequent plays.
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.
Provide a client-side notice if the YouTube live stream key
looks like it might be in the wrong format. Normally the
stream key looks like 4 groups of 4 numbers and letters,
each separated by a dash. The warning does not block submission
in case YouTube changes their stream key format.
* chore(deps): bump lib-jitsi-meet
Brings in a fix for getDisplayMedia being moved onto
navigator.mediaDevices and a hack fix for SDP
interop between Chrome and Firefox.
* Update package lock file sed/http/https.
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.
Updating react-native-fast-image brings a couple of interesting changes:
- onLoad is not called for cached images (reported and ignored upstream)
- load progress not working if component not displayed (on Android)
In order to fix this, a combination of 2 approaches was used:
- onLoadEnd / onError are used to detect if the image is loaded
- off-screen rendering is used on Android to get progress events
While implementing the above, yours truly noticed the complexity was increasing
way too much, so some extra refactoring was also performed:
- componentWillReceiveProps is dropped
- an auxiliary component (AvatarContent) is used for the actual content of the
Avatar, with the former passing the key prop to the latter
Using the key prop ensures AvatarContent will be recreated if the URI changes,
which is not a bad idea anyway, since the new image needs to be downloaded.
Xcode 10 introduced a new build system. Alas, it breaks a number of important
flows, such as creating an archive for the framework (ie SDK) target.
In order to "fix" this, switch back to the former (Xcode 9) build system for the
time being.
* Replaces smileys and the logic of replacing links/emails.
Now using react-emoji-render and react-linkify.
* Fixes heart emoji.
It is known that current implementation doesn't work with ascii emojis that contain < or >, like >:( >:-( </3 <\3 <3. Making those work may bring some xss issues.
* Adds '_blank' and 'noopener noreferrer' to the replaced links.
* Fixes package-lock links (http vs https).
* Fixes comments.
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.
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.
It doesn't seem like videoTrack needs to be set onto state
if it can be accessed directly from props. Removing the state
automatically removes the deprecated componentWillReceiveProps.
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
Video elements may have problems scaling to cover pixel fractions,
so there could be a 1px black border line displaying in the
thumbnail. It's most visible in tile view. Flooring the sizing
calculations hides the border.
Filmstrip remote thumbnails display under certain conditions, as
defined in filmstrip/functions.web.js. Previously the raw
participant count was used, which included fake participants.
Using the selector getParticipantCount excludes fake participants,
causing YouTube thumbnails to remain hidden in a 1-on-1 call.
- Derive the showOverlay state. When the sidebar should be hidden,
the internal showOverlay state should remain true until the
animation hides it. When the sidebar should show, the showOverlay
state should become true immediately.
- Use PureComponent to prevent additional animation triggers
instead of explicitly checking changes to the "show" prop.
Based on react-native docs, looks like animations should be
started after mount. Updating animation states I'm not certain
on so I moved it to componentDidUpdate and tested with the
live streaming label to ensure the component still animated fine.
To kill componentWillMount, call destroyLocalTrack after mount.
Navigation to the blank page was synthetically forced and no
UI issues were noticed, possibly because destroyLocalTrack may
already be async so destruction may already have been occurring
after mount.
For the most part the changes are taking the "static propTypes" declaration off
of components and declaring them as Flow types. Sometimes to support flow some
method signatures had to be added. There are some exceptions in which more had
to be done to tame the beast:
- AbstractVideoTrack: put in additional truthy checks for videoTrack.
- Video: add truthy checks for the _videoElement ref.
- shouldRenderVideoTrack function: Some component could pass null for the
videoTrack argument and Flow wanted that called out explicitly.
- DisplayName: Add a truthy check for the input ref before acting on it.
- NumbersList: Move array checks inline for Flow to comprehend array methods
could be called. Add type checks in the Object.entries loop as the value is
assumed to be a mixed type by Flow.
- AbstractToolbarButton: add additional truthy check for passed in type.
None of the breaking changes seemed to affect current
usage of react-i18next and light testing of features
and language switching did not produce issues.
This update is a pre-requisite for removing deprecated react
lifecycle methods, as older versions of react-i18next
have a higher order component that uses the deprecated
componentWillMount, and that issue has been fixed since 7.8.0.
When a native iOS module implements `constantsToExport` it must define
`requiresMainQueueSetup`. In this case we don't do any UI stuff so it doesn't
need to be initialized in the main thread.
- Change "features/chat" to support listening for new chat messages
and storing them, removing that logic from conference.js.
- Combine chat.scss and side_toolbar_container.css, and remove unused
scss files. Chat is the only side panel so the two concepts have
been merged.
- Remove direct access to the chat feature from non-react and non-redux
flows.
- Modify the i18n translate function to take in an options object.
By default the option "wait" is set to true, but that causes
components to mount after the parent has been notified of
an update, which means autoscrolling down to the latest rendered
messages does not work. With "wait" set to false, the children
will mount and then the parent will trigger componentDidUpdate.
- Create react components for chat. Chat is the side panel
plus the entiren chat feature. ChatInput is a child of Chat and
is used for composing messages. ChatMessage displays one message
and extends PureComponent to limit re-renders.
- Fix a bug where the toolbar was not showing automatically when
chat is closed and a new message is received.
- Import react-transition-group to time the animation of the
side panel showing/hiding and unmounting the Chat component.
This gets around the issue of having to control autofocus if the
component were always mounted and visibility toggled, but
introduces not being able to store previous scroll state
(without additional work or re-work).
This is a workaround suggested by Travis support to workaround the
"The job exceeded the maximum log length, and has been terminated."
error.
Another option would be to upload the logs somewhere, but actually it
might be more convenient not having to scroll down all those logs. We
can revisit this case if some problems will be encountered (like for
example if there's need to see something in the middle).
The code for handling device availability has been disabled for a long time,
plus it's ill named since it represents 2 abstractions: lack of permissions and
lack of devices.
Time for it to rest in the git graveyard.
* feat: Displays the server region in the stats panels.
* feat: Displays the server count in the local stats panel.
* ref: Renames a variable.
* fix: Makes bridgeCount a number, clarifies docs.
* chore: Updates lib-jitsi-meet to 1ac6df97e3aa5ff880129a95754d491d89ea8c25.
There are (at least) two changes that are breaking:
- defaultTab is gone
- The re-rendering logic looks to have been re-written so that
passing in a new array of tabs causes a re-render, which can
reset the currently selected tab.
The fixes involved removing defaultTab from each tab configuration,
as it is no longer respected anyway. Also, instead of letting Tabs
be uncontrolled and allowing it to set its own selected, which
would result in the first tab automatically being selected on
Tabs re-render, use Tabs a controlled prop to dicate which
tab is selected; this is accomplished by specifying a selected
prop.
This is a pre-requisite to updating atlaskit/tabs to 8.0.8.
Without updating, clicking a dropdown menu within a tab
component within a modal, such as the language selector in
the settings dialog, will lock the browser.
* feat(tile-view): initial implementation for mobile
- Create a tile view component for displaying thumbnails in a
two-dimensional grid.
- Update the existing TileViewButton so it shows a label in the
overflow menu.
- Modify conference so it can display TileView while hiding
Filmstrip.
- Modify Thumbnail so its width/height can be set and to prevent
pinning while in tile view mode.
* use style array for thumbnail styles
* change ternary to math.min for expressiveness
* use dimensiondetector
* pass explicit disableTint prop
* use makeAspectRatioAware instead of aspectRatio prop
* update docs
* fix docs again (fix laziest copy/paste job I've ever done)
* large-video: rename onPress prop to onClick
* change forEach to for...of
* use truthy check fallthrough logic instead of explicit if
* put tile view button second to last in menu
* move spacer to a constant
* the magical incantation to make flow shut up
Update the following to the latest:
avatar
button
checkbox
field-text
field-text-area
icon
inline-message
layer-manager
lozenge
modal-dialog (one version before breaking changes)
multi-select
spinner
theme
tooltip
The following were not updated:
- droplist was removed because usage could not be found
- flag was not updated due to regressions with stacking animations
- inline-dialog was not updated because it requires (likely simple)
fixing of position props
Extracts methods which share the common logic. There are still some
leftovers on the web side left which are not used on RN. But this can be
a first step.
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.
The process for doing a replaceLocalTrack is async. Is it
possible to trigger replaceLocalTrack multiple times before
each call is finished. This leads to situations where
replaceLocalTrack is called multiple times with oldTrack being
null and a new track. In this scenario, each new track will be
added, causing UI issues such as the local participant's
large video not displaying for remote participants.
The action replaceLocalTrack is used when unmuting audio or
video, when creating new tracks on device switch, and when
toggling screensharing. These actions can collide with each
other. One way to fix this would be to queue replaceLocalTrack.
The instance variable is not accurate. By default isVisible is
set to false but nothing sets the video container to actually
not be visible. As such it is possible for the video element
itself to autoplay, thereby making video visible, while the
isVisible boolean is still false. The fix chosen is to remove
instance variable and always respect calls to show/hide so
that the video container can be set to hidden.
* Add joing button to the calendar events.
* Add space between calendar lines.
* Adjust recent list name.
* Fixes test failure.
* Restyle mobile recent list message.
* Add analytics events.
* Addressing PR review comments.
App Store Connect reported the following issues in (and rejected the binary
of) Jitsi Meet 1.18.x:
NSBluetoothPeripheralUsageDescription
NSAppleMusicUsageDescription
NSMotionUsageDescription
NSSpeechRecognitionUsageDescription
Starting spring 2019, all apps submitted to the App Store that access user
data will be required to include a purpose string for the following:
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
The current code was splitting it on a space, which made nicknames such as “Link Mauve” appear as “Link”, whereas it gets displayed correctly everywhere else in the UI.
* Implements calendar entries edit.
Share text generation between calendar-sync and the share-room feature.
* Fixing comments.
* Clone the event element we modify on update.
If a relative BOSH URL is found (as docker-jitsi-meet does) construct a full URL
based on the location URL and context root.
Also remove some default options since we need the config file anyway, so I see
no point in doing the extra work.
Yours truly refactored routing in https://github.com/jitsi/jitsi-meet/pull/3222
and broke it. When a bare room is entered the pathname was not updated when
applying the default URL.
* Refactor calendar-sync feature to be loaded on web.
For the web part it just adds new property to enable/disable calendar web integration, disabled by default.
* Initial implementation of retrieving google calendar events.
* Initial implementation of retrieving microsoft calendar events.
* Fixes comments.
* Rework to use the promise part of microsoft-graph-client api.
* Moves dispatching some actions, fixing comments.
* Makes sure we do not initializeClient google-api client multiple times.
* Do not try to login when fetching calendar entries.
The case where there is a calendar type google selected, but not logged in, trying to login on loading welcome page will show a warning that it tried to open a popup, which was denied by browser.
* Updates profile display data on sign in.
* Propagate google-api state to calendar-sync only if we use google cal.
* Adds sign out action.
* Clears the event listener when the popup closes.
* Clears calendarIntegrationInstance on signOut.
* WIP: UI for calendar settings, refactor auth flows
* Clean up some unused constants, functions and exports.
* break circular dependency of function and constant
* Exports only isCalendarEnabled from functions.
* Checks isSignedIn when doing fetchCalendarEntries on web.
* address comments
List microsoftApiApplicationClientID in undocument config.
remove unused SET_CALENDAR_TYPE action
use helper for calendar enabled in bootstrap
reorder actions
reorder imports
change order of signin -> set type -> update profile
add logging for signout error
reword setting dialog desc to avoid redundancy
add jsdoc to microsoft button props
reorder calendar constants
move default state to reducer (not reused anywhere)
update comment about calendar-sync due to removal of getCalendarState
update comment for getCalendarIntegration
remove vague comment
alpha order reducer, return default state on reset
alpha order persistence registry
remove unnecessary getType from apis
update comments in microsoftCalendar
alpha order google-api exports, use api.get in loadGoogleAPI
set jsdoc for google signin props
alpha order googleapi methods
fix calendartab docs
* Moves fetching calendar from APP_WILL_MOUNT to SET_CONFIG.
The web part needs configuration in order to refresh tokens (Microsoft).
* Fixes storing token expire time and refreshing tokens in Microsoft impl.
* Address comments
updateProfile changed to getCurrentEmail
rename result to results
stop storing integration in redux, store if ready for use
use existing helpers to parse redirect url
* update jsdocs, get google app id from redux
* clear integration instead of actual sign out
* feat(tile-view): initial implementation for tile view
- Modify the classname on the app root so layout can adjust
depending on the desired layout mode--vertical filmstrip,
horizontal filmstrip, and tile view.
- Create a button for toggling tile view.
- Add a StateListenerRegistry to automatically update the
selected participant and max receiver frame height on tile
view toggle.
- Rezise thumbnails when switching in and out of tile view.
- Move the local video when switching in and out of tile view.
- Update reactified pieces of thumbnails when switching in and
out of tile view.
- Cap the max receiver video quality in tile view based on tile
size.
- Use CSS to hide UI components that should not display in tile
view.
- Signal follow me changes.
* change local video id for tests
* change approach: leverage more css
* squash: fix some formatting
* squash: prevent pinning, hide pin border in tile view
* squash: change logic for maxReceiverQuality due to sidestepping resizing logic
* squash: fix typo, columns configurable, remove unused constants
* squash: resize with js again
* squash: use yana's math for calculating tile size
When newly joined clients register for XMPP events upon
CONFERENCE_JOINED, those events that is carried by presence (e.g. START_COMMAND) was
already fired.
Temporary solution is to let the client send a ping message after
registering XMPP event listeners. The moderator will respond with
pong, which forces the presence to be resent.
index.js of local recording
local-recording(ui): recording button
local-recording(encoding): flac support with libflac.js
Fixes in RecordingController; integration with UI
local-recording(controller): coordinate recording on different clients
local-recording(controller): allow recording on remote participants
local-recording(controller): global singleton
local-recording(controller): use middleware to init LocalRecording
cleanup and documentation in RecordingController
local-recording(refactor): "Delegate" -> "Adapter"
code style
stop eslint and flow from complaining
temp save: client status
fix linter issues
fix some docs; remove global LocalRecording instance
use node.js packaging for libflac.js; remove vendor/ folder
code style: flacEncodeWorker.js
use moment.js to do time diff
remove the use of console.log
code style: flac related files
remove excessive empty lines; and more docs
remove the use of clockTick for UI updates
initalize flacEncodeWorker properly, to avoid premature audio data transmission
move the realization of recordingController events
from LocalRecordingButton to middleware
i18n strings
minor markup changes in LocalRecordingInfoDialog
fix documentation
* feat: Displays the E2E RTT in the connection stats table.
* fix: Whitelists the ping config properties.
* ref: Addresses feedback.
* npm: Updates lib-jitsi-meet to e097a1189ed99838605d90b959e129155bc0e50a.
* ref: Moves the e2ertt and region to the existing stats object.
* feat(welcome-page): be able to open settings dialog
- Create a getter for getting a settings tab's props so the device
selection tab can get updated available devices.
- Be able to call a function from a tab after it has mounted. This is
used for device selection to essentially call enumerateDevices on
the welcome page so the device selectors are populated.
- Remove event UIEvents.AUDIO_OUTPUT_DEVICE_CHANGED. Instead directly call
setAudioOutputDeviceId where possible.
- Fix initialization of the audioOutputDeviceId in settings by defaulting
the audio output device to the one set in settings.
* squash: updateAvailableDevices -> getAvailableDevices, add comment for propsUpdateFunction
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.
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.
There is no reason for them to run on the main thread, it's safe to call
AVFoundation functions on threads other than the main thread.
The previous code made an incorrect claim about the thread in which the audio
route change notification selector is called: it's called on a secondary thread:
https://developer.apple.com/documentation/avfoundation/avaudiosessionroutechangenotification
* ref(filmstrip): create an empty container for local filmstrip move
This might be necessary for tile view. To support making the
local video display at the end of remote videos while in tile
view, but separateed from scrollable remote videos, moving
the local video might be necessary. By creating an empty
container, there is a target for local video to move to.
* squash: rename id
* [WEB] add UI for transcription
* add analytics event for button, do not use global APP object
* use props instead of state, use local conference to kick participant
* put imports in alphabetical order
* add translation for TranscribingLabel
* fix merge conflict
* add closed caption button
* purge OverFlowMenuItem which starts and stops Transcription
* readd closed caption icon and fix small issues due to purge
* delete unused icon in _font.scss
* ref(filmstrip): apply filmstrip class to Conference root
Instead of apply the layout class to the body, it can be
applied to Conference. This will allow easier switching
between tile filmstrip and horizontal/vertical filmstrip.
* squash: fix typo filstrip
Move away from middleware and instead update video quality
when the selected video quality updates in redux. This also
lead to removing of automatically exiting audio only because
with the change it's not so readily possible to tell if the
user switched off audio only by re-selecting the already
preferred video quality. Removing this automagic removed
some additional checking done for mobile.
The internal max will be used for tile view. Whatever the
user has set for preferred video quality, the internal
maximum will be respected. This allows for the case where
the user prefers high definition video, but in tile view
it only makes sense to send low definition; ux wise the
user is allowed to continue messing with the video quality
slider.
- "preferred" is being appended because in tile view there is a
concept of what the user prefers to be the maximum video quality
but there is also a maximum respected internall. For example,
the user may prefer HD, but in tile view the tiles may be small
so internall the preferred would be set to LD.
- "receive" is being renamed to "receiver" to be consistent with
the naming in lib-jitsi-meet.
* Get back the Notice class
* Add Notice component in the Conference web view
* Notice is not exported in index.js. Only used internally by
Conference.
* noticeMessage value obtained from features/base/config
* using mapStateToProps
* value is stored in the internal _message property
* Notice component, orignal in `toolbox` is moved from
`toolbox/components` to `conference/components`
* Notice component only implemented and renderable in web views
* Dummy `conference/components/Notice.naive.js`
This patch is partially based in the removed logic included
originally in:
commit 59a74153dc
(tag: jitsi-meet_1886, tag: jitsi-meet_1885, tag: 1797, tag: 1796)
Author: Ilya Daynatovich <shupuercha@gmail.com>
Date: Mon Mar 20 11:04:54 2017 -0500
Toolbar notice as React Component
In reply to: Saúl Ibarra Corretgé @saghul> comments
Signed-off-by: Pablo Saavedra <psaavedra@igalia.com>
* ref(popover): allow for popover content from the right
Popovers contents can display to the left of the trigger
and above the trigger. Add the ability to display to the
right of the trigger my adding mouseover padding. This
may be needed for tile view, depending on where the triggers
are located.
* squash: abstract common css proprties into placeholder class
* fix(welcome-page): css tweaks in prep for branded welcome page
- Watermarks should no longer depend on toolbar size. The left watermark made
room for the toolbar when the toolbar was on the left side of the screen, but
the toolbar has been moved to the bottom. The right watermark...well it'll
clash with the vertical filmstrip but at least the margins will be consistent
with the left watermark.
- Apply new font-family so fonts are more likely to be consistent across the
app. Design likes SF UI and keeps requesting it so use it by default.
- Change sizings of welcome page header to be more responsive. This will help
the header be scrollable when there is no additional content and the header
overflows.
- Change colors of the welcome page header and remove background image that
was in the header. Leave in the dom for the background image in case other
deployments need to continue showing an image.
- Add a period to the title of the welcome page.
- Move watermarks dom location as it is not part of the header; it's part of the
whole page.
* [squash] Size and font adjustments. Renaming.
* ref(large-video): combine selectParticipant logic from web
Currently native/middleware/redux has its own logic for selecting a participant
on the bridge. To have the logic web respect that logic, a few changes are
needed.
- Web no longer has its own call to selectParticipant.
- To keep in line with web logic selectParticipant action should act even when
there is no track. This makes it so that when a participant does get a track
that the bridge will send high quality. The bridge can already handle when the
selected participant does not have a video track.
- The timing of web is such that on joining an existing conference, a
participant joins and the participant's tracks get updated and then the
conference is joined. The result is selectParticipant does not get fired
because it no-ops when there is no conference. To avoid having to make
uncertain changes (to be lazy), update the selected participant on conference
join as well.
* squash: update comment, pass message to error handler
It will only be requested if a user joins a meeting or flips the switch from
video to audio and back, but never as the first thing when the welcome page is
mounted.
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>
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
* Show subtitles when Jigasi sends transcription results in JSON
* fix: Import PropTypes from prop-types.
* apply feedback on initial PR
* Changed Object to Map, alphabetic ordering fixes ,css changes in transcription subtitles
* Sends Map of transcriptMessages as prop to Component
* Documentation fixes and uses config in redux state
* Minor doc fix
* rename feature 'transcription' to 'subtitles'
* Moves subtitles config to interfaceConfig and minor fixes
* minor lint fix
* ref(device-selection): do not override var that is not reference again
* ref(device-selection): do not override var that is not reference again
* ref(device-selection): always update known devices on device list update
* ref(device-selection): replace call to get devices from legacy to redux
* ref(device-selection): remove unused device list state from mediaDeviceHelper
* ref(device-selection): update store before updating UI
BaseApp does all the heavy-lifting related to creating the redux store,
navigation, and so on.
App currently handles URL props and actually triggering navigation based on
them.
Move it away from AbstractApp into an auxiliary function. In addition, introduce
a new `getServerURL` function which gets the configured server URL and defaults
to meet.jit.si as before.
It was never used in practice, and it would be very cumbersome to use, since it
would have to bcreated with all the middlewares and reducers we need. After
discussing this with Lyubomir, we are confident this is not going to be needed
so it can go.
Unfortunately, as the Jitsi Meet development evolved the routing mechanism
became more complex and thre logic ended up spread across multiple parts of the
codebase, which made it hard to follow and extend.
This change aims to fix that by rewriting the routing logic and centralizing it
in (pretty much) a single place, with no implicit inter-dependencies.
In order to arrive there, however, some extra changes were needed, which were
not caught early enough and are thus part of this change:
- JitsiMeetJS initialization is now synchronous: there is nothing async about
it, and the only async requirement (Temasys support) was lifted. See [0].
- WebRTC support can be detected early: building on top of the above, WebRTC
support can now be detected immediately, so take advantage of this to simplify
how we handle unsupported browsers. See [0].
The new router takes decissions based on the Redux state at the time of
invocation. A route can be represented by either a component or a URl reference,
with the latter taking precedence. On mobile, obviously, there is no concept of
URL reference so routing is based solely on components.
[0]: https://github.com/jitsi/lib-jitsi-meet/pull/779
It can be that deviceChangeListener is never defined because
the isDeviceList call never completes. On hangup, that would
cause an error to be thrown within lib-jitsi-meet because of
an attempt to remove an undefined event handler. That is
what happens on Safari right now.
When replace track is called in JitsiConference, there is no
guarantee a videoType update will come in presence before
the track added event. This can lead to the situation in
LargeVideoManager where an update is called with a track
with an undefined videoType.
* fix(connection): reload immediately on possible split-brain
There isn't an explicit way to know when a split brain
scenario has happened. It is assumed it arises when an
"item-not-found" connection error is encountered early
on in the conference. So, store when a connection has
happened so it be calculated how much time has
elapsed and if the threshold has not been exceeded
then do an immediate reload of the app instead of
showing the overlay with a reload timer.
* squash: rename isItemNotFoundError -> isShardChangedError
This commit adds a state getter that considers checking the enabled/disabled state of the calendar feature, so then other features don’t have to do it manually.
Adds a fatal error state on which will depend whether or not the reload
screen is to be displayed. It is to happen when a relevant fatal error
action is not claimed by any feature for error recovery (the recoverable
flag is not set).
- Instead of having 4 listeners for local connection status
updates and 1 for remote, remove two of the redundant listeners.
- Instead of calling into 4 separate VideoLayout methods to update a
participant's connection status, expose one handler.
Up until now, mobile was oblivious to participants' presence state. Presence
state handling is required (probably, amongst other things) for "call flows".
So, let's add it! This is done by gathering the presence state when a
participant first joins, and handling subsequent changes.
Fix the "mute ping pong" for once and for all. This patch takes a new approach
to the problem: it keeps track of the user generated CallKit transaction ations
and avoids calling the delegate method in those cases.
This results in a much cleaner and easier to understand handling of the flow: if
the delegate method is called it means the user tapped on the mute button. When
we sync the muted state in JS with CallKit the delegate method won't be called
at all, thus avoiding the ping-pong altogether.
In addition, make sure all CallKit methods run in the UI thread. CallKit will
call our delegate methods in the UI thread too, thsu there is no need to
synchronize access to the listener / pending action sets.
This is needed for newer versions of electron that might
use the iframe integration of jitsi-meet. Newer versions
seem to have some kind of regression with setting height
and width to 100%.
* feat(settings): setting dialog
- Move device selection, profile edit, language select, moderator
options, and server auth into one modal with tabs.
- Remove side panel profile and settings and logic used to update
them.
- Pipe server auth status into redux to display in the settings
dialog.
- Change filmstrip only device selection popup to use the new
stateless settings dialog component.
* squash: do not show profile tab if not guest
* squash: profile button not clickable if no profile to show
* squash: nits
* ref: Settings dialog.
The original presence stanza generation code for a poltergeist
has been re-factored and simplified a bit. Every time a
poltergeist presence is updated we first check that the poltergeist
still exists.
Emits CONFERENCE_FAILED in response to CONNECTION_FAILED event
which then triggers JitsiConference.leave() through the middleware
processing. Also base/conference state will be adjusted. It is to have
a consistent redux state in which both connection and conference are
failed. It could happen that in a buggy environment the XMPP connection
is dropped, but the media is still flowing which would result in weird
user experience.
The change to mobile/external-api is required to not emit
CONFERENCE_FAILED for CONNECTION_FAILED if the conference has been
started, because base/conference state will still hold conference
instances which are to be ended by other means and result in the
appropriate event (which will adjust the base/conference state).
Currently the listeners for disconnected and failed connection events
are unsubscribed as soon as the connection is established, so
the CONNECTION_DISCONNECTED is never triggered which would clear the
'connection' field. This commit will clear the 'connection' state on
CONNECTION_WILL_CONNECT. It's needed anyway given that there's no
guarantee on when and if the async disconnect operation will finish.
One issue caused by the 'connection' not cleared was that
CONNECTION_FAILED was not reduced correctly and the reload screen was
not displayed for the following scenario:
1. Join and leave any working conference.
2. Turn off network connectivity on the device.
3. Wait for CONNECTION_FAILED. The reload screen will not be displayed,
because CONNECTION_FAILED is not reduced correctly, because the old
'connection' value is still there.
Your truly introduced this regression in
8c7a3f16b1, alas.
The audio only mode is used to set the CallKit call type. This affects the
behavior on the recent calls entries (calls are marked either as audio or video
calls).
Sync both at the start and for transitions. The previous code was working by
chance (in a way): when the CallKit UI is presented the local video is muted,
which triggers a SET_VIDEO_MUTED action, at which point the audio-only mode was
checked for. Now we are more explicit and act on SET_AUDIO_MUTED.
Read the muted state from the track itself instead of from base/media. This
avoid expressing the incorrect desire when the call starts muted because
permission was never granted.
In the current middleware logic, when the local participant becomes
dominant speaker, a new participant can be selected to receive
high quality video from. This means large-video could potentially
do a switch to another participant when the local participant
becomes dominant speaker. Prevent such behavior.
* Adds an option to disable features based on token data.
Reverts changes from b84e910086, removes disableDesktopSharing option and an interface_config option.
* Disable recording button based on token features data.
Hide recording if local participant isGuest and roles based on token.
When enableUserRolesBasedOnToken is enabled we were not hiding the record button for guests.
* Adds filtering of jibri iqs and rayo based on features.
Moves feature checking in separate utility function.
Renames utility method.
* Adds a footer text when outbound-call is not feature enabled.
* Fixes comments.
Fixes the following warning:
~~~
Module XXX requires main queue setup since it overrides `constantsToExport` but doesn't implement `requiresMainQueueSetup`. In a future release React Native will default to initializing all native modules on a background thread unless explicitly opted-out of.
~~~
For AppInfo and AuioMode, there is no need to initialize anything in the UI
thread, so just return NO.
Use it unless the connection is not ACTIVE. We don't really care if it's
recovering or whatever, if it's not active it has problems, so that's that.
This fixes a potential edge case in which the connection remains in RESTORING
state for some time.
* ref(toolbar): show recording features based on explicit configs
* squash: bring back button configs, use final config names
* squash: update interfaceConfig comment, remove unused config whitelist
* squash: change order of button enabled checks to reduce diff
* squash: fileRecording -> fileRecordings
* 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
Layout:
Use an absolute-fill view as the background with the sidebar on top of. This
greatly simplifies styling, as there is no need to calculate how large the
backdrop needs to be.
Animation:
Switch to a translateX transform animation. This serves 2 purposes: first,
there seems to be a bug somewhere in React Native 0.51-0.55 where the content
that is being animated starts to be clipped. Very weird! But more importantly,
translateX transmorm animations are supported by the native animation driver!
https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html8f5ebe5952/Libraries/Animated/src/NativeAnimatedHelper.js (L138-L176)
This makes the animation more performant and buttery smooth.
Some small cleanups are also included here.
Previously a new call id was generated for INVITE and CANCEL.
Now the id generated during the initial INVITE will be used for
corresponding CANCEL events. Also, adding the ability to
trigger a call cancel via the poltergeist update api.
Instead of keeping dominant speaker locally, get it from redux and be
updated when the dominant speaker changes. This is in an attempt to mimic
the video layout being reactified and connected to redux.
The current poltergeist http api immediately returns
and does not wait for async work in the handler to finish. This
mostly occurs when a public asap key needs to be fetched due
to a cache miss. The fix implements the strategy described at
https://prosody.im/doc/developers/http.html
The visibility of the toolbar can be toggled by interacting with the main screen.
This change allows the toolbar to be configured to be 'always visible'. This voids
the 'toggle' functionality.
Simplify parts of the logic introduced in
11b7144ad0.
Specificaly, using all the state change avoiding functions doesn't give us much
since we need to copy the state for sure.
Makes sure that whenever a conference is left or switched, the local
participant's id will be equal to the default value.
The problem fixed by this commit is a situation where the local
participant may end up sharing the same ID with it's "ghost" when
rejoining a disconnected conference. The most important and easiest to
hit case is when the conference is left after the CONFERENCE_FAILED
event.
Another rare and harder to encounter in the real world issue is
where CONFERENCE_LEFT may come with the delay due to it's asynchronous
nature. The step by step scenario is as follows: trying to leave a
conference, but the network is not doing well, so it takes time,
requests are timing out. After getting back to the welcome page the
the CONFERENCE_LEFT has not arrived yet. The same conference is joined
again and the load config may timeout, but it will be read from the
cache. Now the network gets better and conference is joining which
results in our ghost participant added to the redux state. At this point
there's the root issue: two participants with the same id, because the
local one was neither cleared nor set to the new one yet
(PARTICIPANT_JOINED come, before CONFERENCE_JOINED where we adjust the
id). Then comes CONFERENCE_JOINED and we try to update our local id.
We're updating the ID of both ghost and local participant. It could be
also that the delayed CONFERENCE_LEFT comes for the old conference, but
it's too late and it would update the id for both participants.
The approach here reasons that the ID of the local participant
may be reset as soon as the local participant and, respectively, her ID
is no longer involved in a recoverable JitsiConference of interest to
the user and, consequently, the app.
Co-authored-by: Pawel Domas <pawel.domas@jitsi.org>
Co-authored-by: Lyubo Marinov <lmarinov@atlassian.com>
If the ID of a remote participant was the same as the ID of the local
participant (across multiple conferences), removing the remote
participant on PARTICIPANT_LEFT would remove the local participant.
Like the preceding commit "ref(base/conference): clear the 'conference'
field on WILL_LEAVE", this commit is part of the story how we are to
deal with conferences which take noticeable time to leave.
Like the preceding commit "ref(base/conference): clear the 'conference'
field on WILL_LEAVE", this commit is part of the story how we are to
deal with conferences which take noticeable time to leave.
If a leave is delayed and the leaving JitsiConference manages to sneak a
PARTICIPANT_JOINED in, it may create a remote participant who even
collides with the local participant.
With so many abstractions called conference, I'm not surprised I made a
mistake and my reviewer didn't catch it.
As we are transitioning from remote participants identified by ID alone
to an ID-conference pair, the subsequent commits "Protect against late
PARTICIPANT_JOINED" and "Refine PARTICIPANT_LEFT for ID collisions"
caught the error.
Pawel Domas said:
The conference state field is referring to the current conference in
progress, so it feels like this field should be cleared as soon as we
declare that the conference is being left and the asynchronous process
of leaving the conference starts (which happens on
CONFERENCE_WILL_LEAVE).
Lyubo Marinov said:
Merely setting conference to undefined is incomplete because there are
other redux state properties associated with conference.
What we're doing here is redefining the redux action
CONFERENCE_WILL_LEAVE:
The redux action CONFERENCE_WILL_LEAVE represents the order of the user
to leave a JitsiConference instance. From the user's perspective, there's
no going back (with respect to the instance itself). The app will perform
due clean-up like leaving the associated room, but the instance is no
longer the focus of the attention of the user and, consequently, the app.
Now CONFERENCE_LEFT and CONFERENCE_WILL_LEAVE have more in common than
before and we can do a much better job by expressing the common parts in
source code. Additionally, our source code can be rewritten to better
express the meaning of any of these two actions.
Co-authored-by: Pawel Domas <pawel.domas@jitsi.org>
Co-authored-by: Lyubo Marinov <lmarinov@atlassian.com>
Add ability to provide a display name in the configOverwrite object that
when available it will be used to customize the name of the meeting in
callkit screen and recent call list.
Co-authored-by: Daniel Ornelas <daniel.ob64@gmail.com>
Co-authored-by: Lyubo Marinov <lmarinov@atlassian.com>
This zOrder change fixes the issue that the scrollable filmstrip videos
rendered in front of the local participant, however there is still an
issue that needs to be fixed later: The rendered videos should have
overflow: 'hidden' property applied so then they don't get rendered when
scrolled out of the ScrollView, that property however doesn't seem to
work for Video components.
This fix is based on storing the location URL object we are loading the
configuration for in the redux store. Once the config has been loaded (or it has
failed, for that matter!) we'll check if the current "config URL" is the same we
set, and discard the old one if they don't match.
With some of the preceding commits in the "multiplying remote
thumbnails" story line, I started hitting this error with 100%
reproducibility:
1. Have a remote participant prepared in conferenceA. Web will do as
well.
2. On iOS prepare to join conferenceB in Safari and use the same device
for step 3.
3. Join conferenceA on the iOS device from step 2 with audio-only. The
audio-only is so that avatars are always visible. Wait for the remote
participant prepared in step 1 to appear.
4. Switch to Safari and hit "Continue in the app" to have the app leave
conferenceA and join conferenceB.
What happens:
After the iOS device joins conferenceB in the Jitsi Meet app, the local
participant is on the large video (as expected) but the avatar of the
local participant is the default audo-generated auto-colored
placeholder. That's because this error was hit and the avatar couldn't
be "fetched".
The Jitsi Meet app always has at most 1 conference of primary interest.
It may have to juggle with 2 JitsiConference instances at the same time
if 1 is in the process of being left and one is joining/joined. But the
one which is joining or joined (which we call conference in the
features/base/conference redux state) is the one "of interest", the
other one is "clean up". Consequently, the remote participants of the
conference "of interest" are the remote participants "of interest" and
the others are "clean up". In order to reduce the time during which
there may be multiplying remote thumbnails, clean the remote
participants who are no longer "of interest" up.
As part of the work on fixing the problem with the multiplying
thumbnails, we've associated remote participant w/ JitsiConference.
However, there are periods of time when multiple JitsiConferences are in
the redux state (and that period is going to be shorted by
StateListenerRegistry). In order to give more control to the feature
base/participants, reduce the occurrences of direct access to the
features/base/participants redux state and utilize the feature's
existing read access functions. Which will allow us in the future to
enhance these functions to access participants which are relevant to the
current conference of interest to the user only.
The commit message of "Associate remote participant w/ JitsiConference
(_JOINED)" explains the motivation for this commit.
Practically, _JOINED and _LEFT combined with "Remove remote participants
who are no longer of interest" should alleviate the problem with
multiplying remote participants to an acceptable level of annoyance.
Technically though, a remote participant cannot be identified by an ID
only. The ID is (somewhat) "unique" in the context of a single
JitsiConference instance. So in order to not have to scratch our heads
over an obscure corner, racing case, it's better to always identify
remote participants by the pair id-conference. Unfortunately, that's a
bit of a high order given the existing source code. So I've implemented
the cases which are the easiest so that new source code written with
participantUpdated is more likely to identify a remote participant with
the pair id-conference.
Additionally, the commit "Reduce direct read access to the
features/base/participants redux state" brings more control back to the
functions of the feature base/participants so that one day we can (if we
choose to) do something like, for example:
If getParticipants is called with a conference, it returns the
participants from features/base/participants who are associated with the
specified conference. If no conference is specified in the function
call, then default to the conference which is the primary focus of the
app at the time of the function call. Added to the above, this should
allow us to further reduce the cases in which we're identifying remote
participants by id only and get us even closer to a more "predictable"
behavior in corner, racing cases.
The plan set in motion here is to associate remote participants with the
JitsiConference instances that created them in order to be able to
remove remote participants when a JitsiConference is no longer the
primary focus of the jitsi-meet app. And that's supposed to alleviate a
problem with multiplying remote thumbnails.
Doing all of the above in a single commit is a bit of a high order. So
I'm splitting the whole into multiple successive commits for the
purposes of observability, comprehension. Each commit is supposed to be
safe even if subsequent commits are not accepted, are reverted,
whatever. Obviously, without the successive commits, a commit may be
"unused".
One of the important pieces of the multiplying remote thumbnails "fix"
offered is removing remote participants who are no longer of interest
i.e. PARTICIPANT_LEFT. But in order for _LEFT to be implemented, _JOINED
must be implemented first.
Thsi fixed a regression in 8f75c2e279
The bundler script doesn't do anything (it literally exits right at the top)
when skipping the bundle. This is arguably wrong, because it doesn't generate
"ip.txt", the file with the bundler IP address either!
So, generate that ourselves. While ding this, also drop the need for xip.io,
which has also been removed from RN, since it gives more trouble than it solves.
Because a conference can fail before or after it's joined it must be
"left" in order to release any allocated resources like peerconnections,
tracks and all the other things.
- add 10px of padding on the sizes of the toolbar
- make the button margin smaller (from 10 to 7)
- increate the secondary button factor to 85%, thus rising the maximum secondary
button size to 50 (from the previous 48)
Doing so in CONFERENCE_JOINED is too late because if we are moderators that
event will come first and we won't know what ID to match it with.
This is safe because our local ID is created early.
* feat(recording): frontend logic can support live streaming and recording
Instead of either live streaming or recording, now both can live together. The
changes to facilitate such include the following:
- Killing the state storing in Recording.js. Instead state is stored in the lib
and updated in redux for labels to display the necessary state updates.
- Creating a new container, Labels, for recording labels. Previously labels were
manually created and positioned. The container can create a reasonable number
of labels and only the container itself needs to be positioned with CSS. The
VideoQualityLabel has been shoved into the container as well because it moves
along with the recording labels.
- The action for updating recording state has been modified to enable updating
an array of recording sessions to support having multiple sessions.
- Confirmation dialogs for stopping and starting a file recording session have
been created, as they previously were jquery modals opened by Recording.js.
- Toolbox.web displays live streaming and recording buttons based on
configuration instead of recording availability.
- VideoQualityLabel and RecordingLabel have been simplified to remove any
positioning logic, as the Labels container handles such.
- Previous recording state update logic has been moved into the RecordingLabel
component. Each RecordingLabel is in charge of displaying state for a
recording session. The display UX has been left alone.
- Sipgw availability is no longer broadcast so remove logic depending on its
state. Some moving around of code was necessary to get around linting errors
about the existing code being too deeply nested (even though I didn't touch
it).
* work around lib-jitsi-meet circular dependency issues
* refactor labels to use html base
* pass in translation keys to video quality label
* add video quality classnames for torture tests
* break up, rearrange recorder session update listener
* add comment about disabling startup resize animation
* rename session to sessionData
* chore(deps): update to latest lib for recording changes
Contributing all buttons in one place goes against the designs that we
set out at the beginning of the project's rewrite and that multiple of
us have been following since then.
Currently the following are implemented:
- AudioMuteButton
- HangupButton
- VideoMuteButton
In order to implement these new buttons a new abstract class was introduced,
which abstracts the ToolboxItem into a button with enough hooks so a stateful
and a stateless version of it can be created.
This patch only adds the stateful implementation of the aforementioned buttons.
This abstraction represents an action which can go anywhere in a toolbox (be
that the main toolbar or the overflow menu) and it's platform independent.
It does not depend on Redux, thus making it stateless, which facilitates its use
in stateful button implementations as well as stateless ones.
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.
Knowledge is power, man!
The config.js cache predates the feature base/known-domains.
Technically, it's also able to recall more domains that the feature
recent-list can (because the latter limits its entries).
Knowledge is power, man!
We moved "knownDomains" from calendar-sync to base/known-domains.
However, we do have an official release in the app stores and I'd like
us to not throw away the knowledge it has acquired.
If multiple JitsiMeetView instances are created (not necessarily
existing at once), it's possible to hit a TypeError when reading the
React Component props of the currently mounted App. Anyway, in certain
places we're already protecting against that out of abundance of caution
so it makes no sense to not protect everywhere.
Make it more generic by accepting any content except of just rows with text and
icons.
In addition, rework its structure so the animation is smoother, by putting the
background overlay outside of the Modal. This way, the animation doesn't affect
the background, which won't slide down.
* fix(toolbar): make button hover bigger
* fix(toolbar): make hangup button bigger
* fix(always-on-top): make toolbar and buttons same sizes as main toolbar
* fix(toolbar): change some tooltips
* fix(toolbar): adjust side panel and filmstrip for new toolbar sizes
It seems that the external API will not send any event to let the sdk
consumer know that the conference has failed if the problem occurs at
the establishing of XMPP connection stage. That's because the config was
loaded successfully, but the conference instance does not exist yet, so
neither base/config nor base/conference will emit any failure.
Make the external API emit CONFERENCE_WILL_JOIN early on SET_ROOM action
which occurs before the XMPP connection is created. At this point we
know that config has loaded and if there's a valid conference room to
be joined. We were thinking of doing that even on CONFIG_WILL_LOAD,
but that seemed to be to risky at this point.
With this the RN component and the consumer app can share same CallKit
provider, configuration, and enable to be part of multiple listeners of
the CallKit flow events. The main driver of this is to enable the
consumer app to be able to report an incoming call to the OS before
loading the JitsiMeetView. Once the user answers the call, the app can
instantiate a JitsiMeetView, pass the CallKit call UUIID, and the Jitsi
Meet components will handle the connection and report back to CallKit
that the call has been established.
Hristo Terezov, Chris Cordle, and I/Lyubomir Marinov agreed that we'd
try to use "invite" & "invitee(s)" in Web/React's iframe API,
mobile/react-native's SDK invite API, and internally for the purposes of
consistency, ease of understanding, etc.
I'm unsure why all textareas need overflow hidden. Doing so
essentially overrides what I would expect to be standard textarea
behavior. I would rather remove the reset and fix any areas that
have issues.
This can happen if there are multiple JitsiMeetView instances are active at the
same time, because there is a single bridge, which means all of them would get
the events.
Currently enterPictureInPicture action can only be dispatched when
the app is on the conference view and the enter PiP button is displayed,
so no check should be necessary.
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.
To reduce the amount of motion that has to be blurred, use a canvas
to essentially set the FPS of the video background. This canvas
component is behind a temporary feature flag, as well as being able
to disable the blur, so it can be played around with on deployed
environments.
When closing and reopening a notebook, the browser will fire
a devicechange event. This event should not be listened to
after hangup because the current listener will call gum if
there is no current audio/video, which is the case after
hangup.
Initially this change was going to be remove all conference
listeners but then I noticed that the listener for devicechange
is set differently. It might be worthwhile future work, although
potentially unnecessary right now, to ensure all listeners
registered in conference.js are properly cleaned up on hangup.
* Creates conf.d in /etc/prosody if missing.
Fixes a problem installing prosody 0.10 when using prosody repositories.
* Cleanups certificates on purge.
There are various occasions where users purge packages and the new installations after that generate certificate which doesn't end up in the java trust store on the target machine.
* Generate jicofo user and component passwords if missing.
There are situations where if prosody is already installed, the order of configuring the packages is not in the correct order. In those situations jitsi-meet-prosody got configured before jicofo and the user password and the component secret are not available and we ask the user for that and later when jicofo is configured we generate new set of them. Now we will end up always generating them in jitsi-meet-prosody or jicofo and we will reuse them. See https://github.com/jitsi/jicofo/pull/283.
- Update font files to add new icon.
- Update markup and style so the icon has a small background
to fill in the text of the icon.
- Remove some css transitions that don't seem to do much.
In order to be able to add analytics to the deep-linking pages the
lib-jitsi-meet initialization has been moved so it happens earlier.
The introduced `initPromise` will eventually disappear, once conference is
migrated into React and / or support for Temasys is dropped. At that stage, it
can be turned into a sync function which all platforms share.
* 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>
* Adds in memory log storage, to be used while testing.
Enabling it only when config.debug is set, a configuration provided by jitsi-meet-torture.
* Moves to using config.testing.testMode property for logs storage.
* Fixes comments.
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.
* feat(recording): show the YouTube live stream URL
- From the start live stream dialog, push up the broadcast ID
of the chosen broadcast. It is assumed the ID can be used to
create the YouTube link.
- Listen for lib-jitsi-meet to emit updates of the known live
stream URL, shove it into redux, and have InfoDialog display
it.
* ref(info): pass in dial in and live stream url
Passing these values in should trigger AtlasKit InlineDialog
to re-render and reposition itself.
* ref(info): use conference existence as trigger for autoshowing dialog
* feat(info): add live stream link to invite copy
* Revert "ref(info): use conference existence as trigger for autoshowing dialog"
This reverts commit 1072102267.
* hidden -> url
* _onClickHiddenURL -> _onClickURLText
Since the main conference container is no longer "clickable" there must
be a way for clicking on the "large video". A clickable TestHint nested
in ParticipantView makes it easier for dealing with the fact that the
click handler is not always on the same component (required for the
pinch and zoom feature to work correctly).
Allows to bind a click handler to a TestHint.
When a mobile test wants to click an UI element it must be able to
locate it through the accessibility layer. Now the problem with that is
that there is currently no uniform way for finding element on both iOS
and Android. This problem is solved by TestHint component which takes
an id parameter which then can be specified in the corresponding java
TestHint class in jitsi-meet-torture to easily find it. By being able to
add a click handler to a TestHint, it's possible to duplicate original
handler under nested TestHint and then find it easily on the torture
side.
Adds the logic to render TestHint only when the test mode is enabled
in order to be able to put independent TestHints in other places than
the TestConnectionInfo component.
Be explciit about the appearance we desire, since each mounted StaturBar
component will override the existing values. In this case, the problem was
caused because the default on iOS is dark, whereas it's light on Android.
Set it to light so it works consistently across both, which is what we want.
There is a slight moment when the recording icon is loading that
its container does not have width. Set the width of the container
so it doesn't collapse. Also, push it a little to the right so
it aligns better with other icons.
The chat counter needs to be moved out of the way of the chat
button. The counter started covering the button when all the
toolbar buttons were made smaller. Also, turning off the
counters pointer events should at least make the button
clickable if this ever happens again.
It's too sensitive and most of the time I cannot perform an onPress. In
contrast, the builtin/default/standard onPress is noticeably more
forgiving. While we fix the sensitivity of "pinch to zoom", don't use
its onPress unless absolutely necessary i.e. use it only for desktop
streams.
Zoltan Bettenbuk suggested the following:
const state = getState();
if (desiredTypes.length === 0) {
- const { audio, video } = state['features/base/media'];
-
- audio.muted || desiredTypes.push(MEDIA_TYPE.AUDIO);
- video.muted || desiredTypes.push(MEDIA_TYPE.VIDEO);
+ const startAudioOnly = getPropertyValue(state, 'startAudioOnly');
+ const startWithAudioMuted
+ = getPropertyValue(state, 'startWithAudioMuted');
+ const startWithVideoMuted
+ = getPropertyValue(state, 'startWithVideoMuted');
+
+ if (!startWithAudioMuted) {
+ desiredTypes.push(MEDIA_TYPE.AUDIO);
+ }
+ if (!startAudioOnly && !startWithVideoMuted) {
+ desiredTypes.push(MEDIA_TYPE.VIDEO);
+ }
}
const availableTypes
The final commit is really a different implementation of the same idea
but takes into account that the state of base/media already contains the
intent of the URL and notices the delay in the realization of the
background app state.
Additionally, unbreaks one more case where setAudioOnly is incorrectly
dispatched on CONFERENCE_LEFT or CONFERENCE_FAILED and, consequently,
overrides the intent of the URL.
* fix(keyboard-shortcuts): process Unidentified keys
When processing keyboard events for keyboard shortcuts,
if the value of an event's "key" attribute is "Unidentified",
the event should be further processed instead of the "key"
being returned to be mapped to a registered keyboard shortcut.
This occurs on edge, where question mark has the key
"Unidentified" but has the proper keyCode of 191.
* squash: add comment
* feat(Deeplinking): Implement for web.
* ref(unsupported_browser): Move the mobile version to deeplinking feature
* feat(deeplinking_mobile): Redesign.
* fix(deeplinking): Use interface.NATIVE_APP_NAME.
* feat(dial_in_summary): Add the PIN to the number link.
* fix(deep_linking): Handle use case when there isn't deep linking image.
* fix(deep_linking): css
* fix(deep_linking): deeplink -> "deep linking"
* fix(deeplinking_css): Remove position: fixed
* docs(deeplinking): Add comment for the openWebApp action.
* fix(recording): fetch events also for available broadcasts
Only "persistent" broadcasts were being fetched using the
YouTube API. Fetching "all" will get persistent broadcasts
and events. If events use a custom encoder then the stream
key can be obtained. If google hangouts is used for the event
then a stream key will not be obtainable; in those cases
input empty string as the stream key.
* squash: fix typos, reword comments, use object for preventing duplicate broadcasts
The call url is an anchor element so that right clicking it
can bring up the copy link option in the context menu.
Clicking on it does a no-op so the anchor was colored to
look like plain text. Hovering over it right now makes it
look like an anchor due to some atlaskit color, so supress
the coloring.
On hangup while audio only, audio only is set to false on
conference leave to reset redux state on mobile. Large video will
update itself on conference leave, but large video has been cleaned
up by that time so trying to directly access the user ID on large
video will fail. Be defensive about this check, because its
callers are already defensive about its return value.
The feature was not ported to the new toolbar. Arguable these
can all be moved into notification but for now simply the
logic will be removed and worked on again as demand arised.
Adds TestConnectionInfo component which exposes some internal app state
to the jitsi-meet-torture through the UI accessibility layer. This
component will render only if config.testing.testMode is set to true.
Moves the statsEmitter.start() invocation to the middleware of
the connection-indicator feature, so that it's started for both mobile
and web (now mobile needs RTP stats for the tests).
The animate flag is always being passed in as false, so
essentially the animation isn't needed, unless a setTimeout 0
behavior is for some reason required...
jquery animate during animations sets an element's overflow to
hidden and then back to the overflow declared before the start
of the animation. If multiple animations are fired, then the
overflow could be set to hidden permanently. No calls
to Filmstrip#resizeThumbnails have animate set to true, so the
animate call is not even needed.
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.
TouchableWithoutFeedback and TouchableHighlight interfere with the
implementation of 'pinch to zoom' to come. We prepare for it by driving
the onClick/onPress handler(s) out of Conference, through LargeVideo and
ParticipantView into Video itself where the bulk of 'pinch to zoom' will
be implemented.
In preparation for "pinch to zoom" support in desktop streams on mobile, make
certain Views not intervene in touch event handling. While the modification is
necessary for "pinch to zoom" which is coming later, it really makes sense for
the modified Views to not be involved in touching because they're used to aid
layout and/or animations and are to behave to the user as if they're not there.
Update RNFetchBlob to use a commit that fixes issues with calling UI API
on a background thread. Note: The commit used is from a forked repo that
is not yet merged on the new source for this RN component, eventually we
should be consuming from this repo instead
https://github.com/joltup/react-native-fetch-blob
When combined with mod_muc_poltergeist mod_muc_call allows
for enabling call features using a proper ext_events.lib.lua
implementation. By default when the module is configured only
stub implementations are used for ext_events.lib.lua as these
are unique between deployments.
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.
Being kicked out of the conference will result with a conference failed
event with 'conference.kicked' reason and take the user back to
the welcome page by navigating to 'undefined'.
Electron generally can bypass having to get permission for
audio and video. In the case it doesn't have it, and the
permission screen is displayed, a string should still display
prompting the user to click allow. Right now the string id
displays.
I don't understand the old showDesktopSharingButton action
but I've tried my best to copy it over. There is an existing
issue where the keyboard shortcut gets registered when it
probably shouldn't because screensharing is disabled. It will
be fixed soon with refactoring of the entire logic determining
whether or not to show the screensharing button.
The onPresence parsing was refactored to remove use of jQuery.
This exposed three methods not available in react-native:
ParentNode.children, ChildNode.remove, and
document.querySelectorAll. The querySelectorAll change could
be swapped for the already polyfilled querySelector, but
children and remove had to be added. The polyfills are based
on those supplied by MDN web docs, but modified to pass jitsi
linting.
* fix(invite): do not send empty queries for people search
The endpoint might return an error if an empty query is sent.
* fix(invite): add error logging for failed people directory requests
The error currently being passed through from $.getJSON ended up
being an empty string plus was not getting logged. So switch to
fetch to move along with jquery killing and log the error.
* fix(dial-in): add error logging for failed requests
* ref(invite): create a fetch helper to remove duplicate logic
* feat(invite): add basic analytics for AddPeople dialog
Analytics for opening the dialog, closing the dialog, the
count of invites sent, and the count of invites errored.
* squash: fix typo, change default count init, remove extra analytics param
* feat(recording): use google api to get stream key
* squash: renaming pass
* squash: return full load promise
* sqush: use google api state enum
* squash: workaround for lib not loading
* another new design...
* increase timeout workaround for gapi load issue
* styling pass
* tweak copy
* squash: auto select first broadcast
Moves the things around to be able to override the config with the URL
params specified in the hash part of the location URI to which the app
is navigating to.
* add a prosody module to insert identity information (when available) into
presence
prosody will check for jitsi_meet_context_user and
jitsi_meet_context_group in the session and, if they are present, insert
them into presence (we do this in prosody so they cannot be spoofed).
* remove unused 'presence' variable
* refactor to modify presence message in place
* make object member access consistent
* make the group information optional
Hardcoding an offset from the bottom of 32px causes issues in
horizontal filmstrip when there is no invite button, because
then the local video just displays 32px from the bottom as there
is no button to take up space above it. Instead leverage flex
alignments to align the bottom of the video to the bototm of
the filmstrip.
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.
The animation for toggling filmstrip visibility was lagging on
Safari. Even though the background video is set to hidden, it is
still causing issues. Setting the background to display none
instead does help but might interfere with animations. So instead
do the easy thing and re-use logic used for Firefox to not show
the background video.
Pre-existing logic made it so numbers were assumed as valid
if no validation url was specified. To be consistent with
the validation server, the faked number should include a
+ at the beginning.
* feat(invite): be able to call numbers from the invite dialog
The major changes:
- Remove DialOutDialog, its views, redux hooks, css, and images.
Its main functionality has been moved into AddPeopleDialog.
- Modify the AppPeopleDialog styling a bit so it is wider.
- Add phone numbers to AddPeopleDialog search results. Phone
numbers are validated in parallel with the request for people
and then appended to the result. The validation includes
an ajax to validate the number is recognized as dialable by
the server. The trigger for the validation is essentially if
the entered input is numbers only.
- AddPeopleDialog holds onto the full object representation of
an item selected in MultiSelectAutocomplete. This is so
selected items can be removed on successful invite, leaving
only unsuccessful items.
- More granular error handling on invite so individual invitees
can be removed from the selected items list.
* squash: change load state, new regex for numbers
* squash: change strings, auto prepend 1 if no country code, add reminders
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
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)
WebRTC used to report createAnswer (and createOffer) NSError with key
"error". But now the key's called "NSLocalizedDescription".
Additionally, NSMutableDictionary doesn't accept nil.
* deps: update jquery version
* squash: resize thumbnails after appending shared thumb
This forces jquery animate to show the thumbnail somehow...
Remote thumbnails basically work this way (append to filmstrip
and then resize filmstrip thumbnails) so I just copied that
implementation. ... So I admit I lost this fight because
even after looking at jquery I couldn't understand why
it doesn't work on the first resize but does on the second.
Plus I'm being put on a strict timebox to update jquery.
* squash: getJSON no longer supports .success
The difference from this change and 88325ae is there is no
attempt to do this in redux. This is the safer change in that
the cleanup logic is known only to trigger on hangup.
This reverts commit 88325aeef2.
Turns out a conference with a password triggers a failed conference
join. It's going to be tricky to decipher when to do actual
cleanup, and where to shove that code, so reverting is easier for
now.
Recent changes in lib-jitsi-meet probably led to (1) our
RTCPeerConnection customizations on react-native not being used which is
a problem because we need them for at least NAT64 on iOS in order to
pass the review in Apple's App Store and (2) unexpected exceptions
inside react-native-webrtc.
The Promise-based WebRTC API should be merged from react-native-webrtc's
upstream but I don't want to do it right now because last time we got
multiple bugs in addition.
Destroy local tracks and also destroy large video so the
user does not wonder why camera (and mic) are still enabled
even though hangup has been pressed.
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.
- Move the existing components for the static dial in page into
a separate folder for easier reuse.
- Reuse those components for displaying dial-on numbers on the
mobile page for unsupported browsers.
- Modify those components to support having tel protocol
links on the dial-in numbers.
- Have DialInSummary, formerly DialInInfoPage, respect a
passed in className prop for easier styling differences.
* ref(invite): remove InviteDialog
InviteDialog functionality has been moved into InfoDialog.
The InviteButton has been temporarily hacked to show one
of its dropdown options instead as the button. Future
work will bring in a redesigned InviteModal that the button
will open.
* squash: filter invalid options and map valid options
* squash: update strings
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.
* feat(info): new dialog design
- Add display of a dial in number.
- Add a static page to show a full list of dial in numbers.
- Add password management.
- Invite modal will be changed soon to remove password and
dial-in.
* squash: add classes for torture tests
* squash: class for local lock for torture tests
* squash: more classes for torture tests
* squash: more classes, work around linter
* squash: remove unused string?
* squash: work around linter and avoid react warnings
* squash: pixel push, add bold
* squash: font size bump
* squash: NumbersTable -> NumbersList
* squash: document response from fetching numbers
* squash: showEdit -> editEnabled, pixel push padding for alignment
* squash: pin -> conferenceID
* squash: prepare to receive defaultCountry from api
When in PiP mode the LargeView will not be large enough to hold the avatar (for
those interested in the details, our avatar's size is 200, and in PiP mode the
app is resized to about 150).
In order to solve it, this PR refactors how the avatar style is passed along,
reducing it to a single "size" prop. With this only prop, the Avatar compononent
will compute the width, height and borderRadius, plus deal with some Android
shenanigans.
In addition, the LargeView component now uses DimensionsDetector to check its
own size and adjust the size prop passed to the Avatar component as needed.
* ref(large-video): reactify background
This is pre-requisite work for disabling the background on
certain browsers, namely Firefox. By moving the component
to react, and in general encapsulating background logic,
selectively disabling the background will be easier.
The component was left for LargeVideo to update so it can
continue to coordinate update timing with the actual large
video display. If the background were moved completely into
react and redux with LargeVideo, then background updates would
occur before large video updates causing visual jank.
* fix(large-video): do not show background for Firefox and temasys
Firefox has performance issues with adding filter effects on
animated elements. On temasys, the background videos weren't
really displaying anyway.
* some props refactoring
Instead of passing in classes to LargeVideoBackground, rely on
explicit props. At some point LargeVideo will have to be reactified
and the relationsihp between it and LargeVideoBackground might
change, so for now make use of props to be explicit about
how LargeVideoBackground can be modified.
Also, set the jitsiTrack to display on LargeVideoBackground to
null if the background is not displayed. This was an existing
optimization, although previously done with pausing and playing.
* squash: use newly exposed RTCBrowserType
* squash: rebase and use new lib browser util
* squash: move hiding logic all into LargeVideo
* squash: remove hiding of background on stream change. hopefully doesnt break anything
Passing around of the component was used when there were two
independent Notification components. Now that there is only
one Notification component, it is not necessary to pass
around the component.
This is only implemented for mobile at the moment, since web doesn't handle
visibility within the Filmstrip component yet, so this should be added right
then, too.
Bumps lib-jitsi-meet to latest. There was a problem that jitsi-meet build fail if anybody touches package.json (including PR testing), this happen after start using custom strophe.js from github:jitsi/strophejs.
The error:
ERROR in ../strophejs-plugin-disco/lib/strophe.disco.js
Module not found: Error: Can't resolve 'strophe.js' in '/Users/dminkov/dev/jitsi-meet/node_modules/strophejs-plugin-disco/lib'
@ ../strophejs-plugin-disco/lib/strophe.disco.js 4:126-147 4:196-227
@ ./modules/xmpp/xmpp.js
@ ./JitsiConnection.js
@ ./JitsiMeetJS.js
@ ./index.js
Without strophejs-plugin-disco jitsi-meet builds but on runtime loading fail with:
Error: Missing strophe-plugins (disco plugin is required)!
FIXME: We should remove this once strophe.js releases new version and we are back to the official one inside lib-jitsi-meet.
Bumps lib-jitsi-meet to latest. There was a problem that jitsi-meet build fail if anybody touches package.json (including PR testing), this happen after start using custom strophe.js from github:jitsi/strophejs.
The error:
ERROR in ../strophejs-plugin-disco/lib/strophe.disco.js
Module not found: Error: Can't resolve 'strophe.js' in '/Users/dminkov/dev/jitsi-meet/node_modules/strophejs-plugin-disco/lib'
@ ../strophejs-plugin-disco/lib/strophe.disco.js 4:126-147 4:196-227
@ ./modules/xmpp/xmpp.js
@ ./JitsiConnection.js
@ ./JitsiMeetJS.js
@ ./index.js
FIXME: We should remove this once strophe.js releases new version and we are back to the official one inside lib-jitsi-meet.
Story time. Currently the app can be started in 4 ways:
- just tapping on the icon
- via a deep link
- via a universal link
- via the phone's recent calls list
The last 3 options will make the app join the specified room upon launch. React
Native's Linking module implements the necessary bits to handle deep or
universal linking, but CallKit is out of its scope.
In order to blend any type of app startup mode, a new LaunchOptions module (iOS
only) exports a getInitialURL function, akin to the one in the Linking module,
but taking CallKit instents into consideration. This function is then used to
make app startup with a URL consistent across all different modes.
* chore: Updates lib-jitsi-meet to 5f8c0a662af086e7bcc19c010f1129afc9b6d650
* squash: revert changes to package-lock.json except for the lib-jitsi-meet version change.
* Handles connection failed event details (passing them to analytics).
* Fixing comments.
* Updates depending versions to be able to test.
* Fixing comments.
* Fixes wrong jsdoc.
We started on the way to responsive UI and its design with aspect ratio
and keeping the filmstrip on the short side of the app's visible
rectangle.
Shortly, we're going to introduce reduced UI for Picture-in-Picture. And
that's where we'll need another dimensions-based detector akin to the
aspect ratio detector.
While the AspectRatioDetector, the up-and-coming ReducedUIDetector, and
their base DimensionsDetector are definitely separate abstractions and
implementations not mixed for the purposes of easy extensibility and
maintenance, the three of them are our building blocks on top of which
we'll build our responsive UI.
Turns out this was a bit more involved than I originally thought due to an
interesting (corner) case: IFF the user was never asked about microphone
permissions and the call starts with audio muted, unmuting from the CallKit
interface won't work (iOS won't show the prompt, it fails immediately) and we
need to sync the mute state back.
If the view gets resized to a 1:1 aspect ratio, remember the previous mode to
avoid flickering when going back to a larger size or different aspect ratio.
If config.enableUserRolesBasedOnToken is true, only let moderators
and non-guests modify the password. Otherwise, only let moderators
edit the password.
Spot will need a way to submit call feedback using the iframe
api. For now expose a method on conference.js to submit that
feedback. Exposing on conference.js looks to be the existing
pattern... Also add an event to notify consumers of the iframe
api that feedback was submitted, as postMessage is async
and the notification can at least give some guarantee maybe.
I haven't updated documentation yet as I'm not confident
about this api.
Improve the experience when joining a room by removing the need to tap the join
button. The keyboard type has also been set to "go", which translated on the
builtin keyboard button label to be "go" (it's builtin, the operating system
translates it). This works on both Android and iOS.
Android uses a SurfaceView to render video, which is not quite a View, so the
fade-in animation (which varies the opacity) doesn't work.
Instead, add an opaque black view covering the video, which transitions to
transparent. This creates much smoother transitions on Android, while behaving
the same.
In addition, I removed the flip animation for local tracks, which is no longer
used, since the camera is switched without changing tracks.
* ref: Restructures the pinned/unpinned events.
* ref: Refactors the "audio only disabled" event.
* ref: Refactors the "stream switch delay" event.
* ref: Refactors the "select participant failed" event.
* ref: Refactors the "initially muted" events.
* ref: Refactors the screen sharing started/stopped events.
* ref: Restructures the "device list changed" events.
* ref: Restructures the "shared video" events.
* ref: Restructures the "start muted" events.
* ref: Restructures the "start audio only" event.
* ref: Restructures the "sync track state" event.
* ref: Restructures the "callkit" events.
* ref: Restructures the "replace track".
* ref: Restructures keyboard shortcuts events.
* ref: Restructures most of the toolbar events.
* ref: Refactors the API events.
* ref: Restructures the video quality, profile button and invite dialog events.
* ref: Refactors the "device changed" events.
* ref: Refactors the page reload event.
* ref: Removes an unused function.
* ref: Removes a method which is needlessly exposed under a different name.
* ref: Refactors the events from the remote video menu.
* ref: Refactors the events from the profile pane.
* ref: Restructures the recording-related events.
Removes events fired when recording with something other than jibri
(which isn't currently supported anyway).
* ref: Cleans up AnalyticsEvents.js.
* ref: Removes an unused function and adds documentation.
* feat: Adds events for all API calls.
* fix: Addresses feedback.
* fix: Brings back mistakenly removed code.
* fix: Simplifies code and fixes a bug in toggleFilmstrip
when the 'visible' parameter is defined.
* feat: Removes the resolution change application log.
* ref: Uses consistent naming for events' attributes.
Uses "_" as a separator instead of camel case or ".".
* ref: Don't add the user agent and conference name
as permanent properties. The library does this on its own now.
* ref: Adapts the GA handler to changes in lib-jitsi-meet.
* ref: Removes unused fields from the analytics handler initializaiton.
* ref: Renames the google analytics file and add docs.
* fix: Fixes the push-to-talk events and logs.
* npm: Updates lib-jitsi-meet to 515374c8d383cb17df8ed76427e6f0fb5ea6ff1e.
* fix: Fixes a recently introduced bug in the google analytics handler.
* ref: Uses "value" instead of "delay" since this is friendlier to GA.
There is more avatar work coming down the line for mobile,
which should also affect web, assuming the same getAvatarURL
helper will be used. As such, instead of continuing to
support the initials service and tweaking UI, revert to
make way for the future avatar work.
This reverts commit 2ea5ad68a5.
The inline classes for the toolbars were re-arranged
to fix non-rounded corners in the always-on-top window's
toolbar. However, those classes were also used by the
torture tests as a way to find stable elements that will
not get blown away by a react re-render. So re-wrap the
buttons with a div that will not get blown away,
add back the inline classes to those divs, and change
the CSS to round the corners in the always-on-top
window's toolbar.
Shared video (youtube videos) do not have indicator icons about
dominant speaker and raised hand. Add a check to see if the
indicator icon container exists before trying to attach react
icons to it. The error thrown didn't seem to be causing any
UI issues though.
While this truthy check before doing ReactDOM.render seems
like it should be a general practice, I'm hesistatnt to make
the change broadly because it hasn't been a problem so far.
* ref(avatars): remove Avatar.js
- Rely on redux getting updated with new participant state
and any calls to getAvatarURL passing in the redux
participant state. This way the state within Avatar.js can
be removed.
- Clean up methods on UI.js. Because all state is in the
store, separate methods for updating the avatar aren't as
necessary. Instead centralize accessing of the avatar for
components outside of redux and centralize the call to
update avatars for non-react components.
- Controversial: cache a participant's avatarURL on the
participant state. Currently the participant's avatarURL
that is generated without jwt (which sets the avatarURL directly)
is not cached. Without cache, there can be many redundant
calls to APP.API.notifyAvatarChanged.
* Leverage middleware timing to diff avatars
One alternative implementation is to leverage middleware's
ability to intercept updates before and after redux has
upated and then compare avatarURLs.
* kill UI.getAvatarUrl
* profile button sets its own avatar url (solves update timing)
* remove calls to updating avatar outside of middleware
* update UI.js doc
* remove left over logic from initial implementation
* try to move local user fallback into selector func
* default to id 'local' in selector
The video will switch to the avatar and be tinted with gray. On the large view,
a text message indicating the user has connectivity issues will be shown.
They will be stored in redux and the PageReloadOverlay will be displayed.
Note that this commit also introduces a subtle (and yet important!) change:
the location URL is now always set, regardless of the configuration loading or
not. This is needed in order for the retry logic to pick it up.
On web Conference is pretty much all there is, but on mobile we have the welcome
page and the blank page. If we fail to load config.js, for example we will still
be in the welcome page *and* we want to show an error overlay.
* Removes unused config logic.
* Whitelists config options that can be overridden using the URL.
* Recorder login with credentials, not supported by externalconnect.
Jibri uses xmpp credentials to login, which is not supported by externalconnect, so we want to skip it till that is supported.
* Whitelist only config.js
* Extracts whitelisting in separate function.
In aa93a783, remote videos not scrolling on Firefox, IE, and
Edge was worked around using CSS. The CSS selector is too vague
and also catches horizontal filmstrip. The selector should
apply to vertical filmstrip only.
Currently all.css is loaded after app.js. This means there may
not be a guarantee that the css is loaded before the js, which
is bad because the js does dom querying for sizes on elements,
but some element sizes will be affected by js. So instead load
css upfront and let the browser block as needed or at least
give the css a head start in racing javascript to load.
- Modify Etherpad and SharedVideo so their resizing takes into account
the width of the filmstrip in vertical filmstrip mode.
- Modify Filmstrip's getFilmstripWidth to account for when the filmstrip
is hidden.
- modify VideoContainer so in vertical filmstrip mode it centers the
shared desktop stream in the middle of the available space not taken
by filmstrip.
- Also allow clickthrough on the secondary toolbar itself while still
allowing clicks on the toolbar's buttons. This allows clicks on
shared videos to go through.
Something is causing firefox to show scrollbars on the remote videos
container even though there is plenty of room. I lost this battle
and just made the container taller...
Using column-reverse prevents proper scrolling on browsers other than Safari
and Chrome. Additionally, Firefox has an issue where flex containers have
dimensions set to auto, preventing resize. So, add hacks to maintain Chrome
and Safari's behavior while allowing for some kind of scrolling on other
browsers.
The goal is to reduce usage on atlassian/aui. New components
have been created to display the settings panel. Language
selection will reach into i18n for state whereas moderator
options will keep state in redux.
Properly handle errors while connecting or joining a conference. Prior to this
patch, only errors on established conferences / connections were saved to the
redux store.
Don't wait for the connection to be made, since in some cases, when auth is
rquired, for instance, that won't happen until the user inputs their
credentials, but the dialog would be overshadowed by the overlay.
75bf7638b3 introduced this regression, state must
be assigned as an object, even though one would think it's automagically
initialized to an object. Oh well!
AtlasKit is not fully compatible with React 16. One problem
is PropTypes will not be defined on the React object. So,
add the prop-types shim to the popup bundle.
Do the selection in mapStateToProps so the container itself doesn't need to
receive all the props that each overlay needs.
Each overlay is responsible for fetching their own props and for providing a
"needsDisplay" static method wich will be called with the full redux state and
should return true if the overlay needs displaying.
Also eliminate duplicated state keeping: the connection and conference error
states can be fetched from their respective base features.
* On adding participant show the initial status text if any.
When participant joins and there is an initial status we show it, instead of the connected notification. If initial status is missing proceed with the default user connected notification.
* Updates to latest lib-jitsi-meet (365bd886ee).
* Adds a fixme comment.
* Updates to latest lib-jitsi-meet (365bd886ee).
Initializing UI features, like keyboard shortcuts, by chaining
onto APP.conference.init is not safe because init can fail,
skipping the initializing of UI features. This can happen when
the room is locked and then a failure event is dispatched into
middleware. I couldn't find a place to properly chain onto
in the APP.conference.init promise chain, primarily due
to the flow continued within middleware, so instead I
leveraged an existing listener for CONFERENCE_JOINED.
* Adds initial documentation for sipgw jibri.
Also explains enabling the people search service and the request/response that are made around sipgw jibri service.
* Fixes add people dialog to invite users and rooms.
No invitation is sent when there is nobody to invite.
* Reuse some recording strings, by using arguments.
* Make sure web also dispatches CONFERENCE_WILL_JOIN.
* Introduces new feature videosipgw.
* Fixes lint errors.
* Renames methods to use people, chatRooms and videoRooms.
* Updates to latest lib-jitsi-meet (dc3397b18b).
It was decided along with the mute participant dialog reactification
that these types of warning messages should not be toggleable--that
they should simply always display because there is no undo action.
As such, the component NotificationWithToggle is no longer needed.
* fix(notifications): throttle and batch join notifications
Instead of directly calling to show a join notification,
go through a specific method. This method will queue
names for display while a throttled function pulls
the names and shows a notification.
* squash: remove unused translation key
* squash: use default display name
* squash: move into participant actions
After looking at the jquery-ui documentation, I believe it
is being used only in one place, when toggling the smiley
menu. That toggling has been quickly replaced with a normal
jquery call.
Note: @atlassian/aui also uses jquery-ui but killing that
off will be more difficult due to its CSS being used.
While having configuration-specific AppIcons may be of questionable use,
I'm more interested in using the Debug version for enterprise
distribution and the Release version for AppStore distribution.
Overflow on body was set to hidden, likely because of
various tricks used to hide elements off screen in the
SPA. Overflow hidden also has the benefit of hiding
scroll bounce when using a MacBook touchpad. The
welcome page is the exception that needs scrolling,
so style welcome page to scroll.
A couple others had made pull requests to addrses this issue
but there hasn't been follow up.
Click handling was added to the local thumbnail only after
receiving video. Click handling was added to remote thumbnails
only after receiving a stream. To allow for pinning through
the filmstrip in any case, always attach the click handler
on thumbnail init.
Checks exist when clicking a contact list to prevent the pinning
UI from updating if a remote thumbnail has not loaded video.
This was unexpected UX so instead go ahead and pin. This is
accomplished by having contact list clicks to more directly
trigger the flow of a thumbnail being clicked.
Rearrange the ToolbarButtons in the secondary Toolbar in order to mostly
group the media-related ones such as the AudioRouteButton, the
switchCamera button, and the audio-only mode button.
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.
It emulates Android's BottomSheet in pure JavaScript. It's implemented as
another Dialog, so it can be used instead of one.
The implementation only supports text options with an associated icon, and an
optional 'selected' marker.
While reviewing "[PREVIEW|RN]: Handle getUserMedia in progress" I
discovered JSDoc comments which could be improved. They are not
necessarily 100% related to the PR.
This commit adds extra actions/Redux state to be able to deal with
the GUM operation being in progress. There will be early local track
stub in the Redux state for any a local track for which GUM has been
called, but not completed yet.
Local track is considered valid only after TRACK_ADDED event when it
will have JitsiLocalTrack instance set.
The YouTube api removed player#getVideoData years ago.
I am completely baffled as to how the feature kept working.
The title of the video is no longer obtainable through
the player itself, so instead call the bot participant
"YouTube."
* feat(keyboard-shortcuts): show help in a react dialog
- Move shortcut help dom declaration to a react component
- Let open/close logic be handled by AtlasKit Dialog
- Remove static html for help from index.html
- Consolidate keyboard shortcut css
* squash: use lozenge for key styling
* squash: use different iteration style
* squash: update package-lock for lozenge
* feat(audio-only): be able to lock a browser into capturing audio only
* squash: try to make string more clear about audio only support
* squash: final strings
With the introduction of wide and narrow layouts the margins of the
Filmstrip and the Toolbox became inconsistent. For example, the
Filmstrip's top in the wide layout was nearer to the top than the
secondary Toolbar.
Adds the ability to detect app area's aspect ratio on react-native
through the features/base/aspect-ratio.
Makes conference, filmstrip and toolbox react to the aspect ratio
changes and display filmstrip on the shorter side of the screen.
* ref(notifications): convert some dialogs to error or warning notifications
- Expand the configurability of the Notification component so warnings
and errors can be displayed.
- Allow Notification to take in arbitrary text for the body.
- Rename defaultTitleKey to titleKey for consistency with descriptionKey.
* ref(notifications): remove openReportDialog method
openReportDialog is a wrapper around showError that adds
a logger statement. It is being called in one place only
so remove the method and have that one place call logger.
* ref(notifications): UI.showTrackNotWorkingDialog takes a boolean
Change UI.showTrackNotWorkingDialog so it takes a boolean
arguments instead of the entire track. A small refactor so
the method needs to know less.
* [squash] Fixes eslint errors
* WiP: Fixes desktop sharing error strings and adds support button
* [squash] Fix icons appearances
* [squash] Fix translate titles and messages
* [squash] fix(translation): Fixes incorrect password string
* [squash] fix(recording): Fixes recording message
* [squash] fix(warning): Turns some warnings to errors and makes support link optional.
* [squash] fix(translation): Addressing language comments
* [squash] Fixes jsdoc and formatting
* [squash] fix(noopener): Fixes window.open noopener
* [squash] fix(constants): Extract constants and refactor NotificationWithToggle
* [squash] fix(lang): Fixes camera and mic error titles
* [squash] fix(supportLink): Renames addSupportLink to hideErrorSupportLink
Instead of targetting a div that contains multiple elements
and risking the elements appearing out of order, create a
specific div for local video to append to.
Removes hasRemoteVideoMenu from RemoteVideo.
In some cases where mod_muc_allowners is enabled we do not see the remote video menu. The problem was in the order of initialization of remote video component.
RemoteVideo#constructor -> Remotevideo#addaddRemoteVideoContainer -> Remotevideo#addRemoteVideoMenu -> RemoteVideo#hasRemoteVideoMenu = true
Then in VideoLayout#showModeratorIndicator -> !remoteVideo.hasRemoteVideoMenu -> remoteVideo.addRemoteVideoMenu().
The intention of the code is (1) to return target if none of the setters lead
to an actual change, (2) to not modify target, and (3) to do it with a 1
copyOnWrite at most.
The lib will accept new style constraints and use those
to capture audio/video. By defining the constraints in
config, there is greater flexibility for defining
and changing constraints.
The popovers in filmstrip only are displaying thinly.
As a quick workaround, set a width on them. There
should only be one anyway, which shows up when
talking while muted.
Firefox flex behaves differently from chrome. In firefox, flex
is not allowing the local video and invite button to exceed
the height of the parent, causing the local video to display
shorter than expected due to the invite button. Flex doesn't
need to be applied for local video in horizontal filmstrip
mode as it's only needed in vertical filmstrip mode to
flip the position of the invite button from above the local
video to below. Honestly, this could be better off done
declaratively in the html, but that's not as straigtforward
in this jquery+react world.
The bottom alignment of the local video container is adjusted
in horizontal filmstrip mode so that the videos remain evenly
aligned at the top but the invite button sticks out. With
the invite button hidden in filmstrip only, this only caused
misalignment. Re-adjust the local video container back down
and put transitions on the filmstrip wrapper itself, instead
of on the thumbnail wrapper level to avoid transitions
when re-adjusting.
All toolbar buttons (which have the class .button) got wrapped
in additional elements due to atlaskit tooltips. This changed
parent/child relationships within the html hierarchy, and the
filmstrip only toolbar selectors needed updating.
It seems to me that npm 5 starting adding github: as the protocol of
dependencies in package.json which are from GitHub. I personally don't
know which npm version supports these and whether we care about such a
support. Anyway, having some use github: and most not is not consistent.
This was broken with commit c1fb1a7def, which splits the result in order to print the error reason and in case of error was not returning the error and the message to prosody internals.
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.
Triggering the 'conference left' action when the wait for owner dialog
is dismissed will let the Call Kit implementation end the call, after
a recoverable conference failed event was emitted.
Also fixes conference state reduction when 'conference left' is emitted
by room lock or auth features where the conference has not been joined
yet.
The feature authentication affords recovery from CONFERENCE_FAILED
caused by AUTHENTICATION_REQUIRED. (Like the feature room-lock afforded
recovery from CONFERENCE_FAILED caused by PASSWORD_REQUIRED.)
Recently/as part of the work on taking into account the user defined by
JWT, the local participant (on mobile) started telling the remote
participants that he/she had the display name "me". Obviously, that's
incorrect. Do not store the default display name in redux. While it may
be argues that redux is the place for all states, base/participants and
the name property of Participant is not meant to be that display name
because that is being sent to remote participants, the default name
needs to be internationalized, etc. So it's better to not store the
default display name at this time at all because it's not used by mobile
anyway and Web already deals with remote participants who don't share
their display names.
A few occurrences of coding style/formatting which I noticed while
reviewing 'feat(eslint): Enable for non react files'. These are
definitely not all occurrences I could've noticed during the review
but... we're talking about files outside react/ anyway.
Will override email, display name and avatar URL with the values
provided in 'context.user' structure of the JWT token.
Settings will no longer be used to retrieve local display name,
email and avatar URL. Now those values will be obtained from
the /features/base/participants Redux state.
fix(jwt/middleware): use const for default name
fix: wrong default display name on web
ref(base/participants): remove getDisplayName functions
ref(jwt): do not accept unknown user fields
Instead of assuming the initial info dialog open should auto
close, explicitly call opening of the dialog with a flag for
auto closing. This better facilitates the auto close timeout
being set at any time.
The changes led to refactoring out state in the InfoDialogButton
in preference for always clearing the timeout instead of
first checking for interaction before clearing.
Delay showing the dialog until after joining the conference
instead of as soon as possible. This resolves a few issues.
One is the dialog displaying right before the permissions
overlay is shown. Another is that logically it does not
make sense to show the invite options when unable to invite.
It also sidesteps the initial react UI bootstrapping that
can cause race conditions with toolbar re-renders causing
misalignment. Lastly, it prepares prematurely for what I
assume will be changes for when the info dialog will
actually be shown automatically.
When _setLoggingConfig is invoked for the first time old and new config
are equal and _initLogging is not called. Currently, there is no way to
detect when the first time we call it is. We could use APP.logCollector
but it should go away at some point in the future.
Revert "[RN] Remove unnecessary source code" (commit
a3441030a3). But since the project file
needs to explicitly mention the CallKit and Intents framework, do not
use the semantic @import as that's confusing in the case.
Never show the local participant in the large view unless it's the only
participant.
This fixes 2 issues:
- selecting the local participant when the camera permission wasn't granted
- selecting the other participant when they join a 1-1 call with video muted
The certificates are generated on new install or upgrade and added to the current configuration and also to the trusted certificates on the local machine.
# Jitsi Meet - Secure, Simple and Scalable Video Conferences
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, scalable video conferences. You can see [Jitsi Meet in action](http://youtu.be/7vFUVClsNh0) here at the session #482 of the VoIP Users Conference.
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, [secure](#security) and scalable video conferences. Jitsi Meet in action can be seen at [here at the session #482 of the VoIP Users Conference](http://youtu.be/7vFUVClsNh0).
You can also try itout yourself at https://meet.jit.si .
The Jitsi Meet client runs in your browser, without installing anything on your computer. You can try it out at https://meet.jit.si .
Jitsi Meet allows for very efficient collaboration. It allows users to stream their desktop or only some windows. It also supports shared document editing with Etherpad.
Jitsi Meet allows very efficient collaboration. Users can stream their desktop or only some windows. It also supports shared document editing with Etherpad.
## Installation
Installing Jitsi Meet is quite a simple experience. For Debian-based systems, we recommend following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document, which uses the package system.
On the client side, no installation is necessary. You just point your browser to the URL of your deployment. This section is about installing a Jitsi Meet suite on your server and hosting your own conferencing service.
Installing Jitsi Meet is a simple experience. For Debian-based system, following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document, which uses the package system. You can also see a demonstration of the process in [this tutorial video](https://jitsi.org/tutorial).
For other systems, or if you wish to install all components manually, see the [detailed manual installation instructions](https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md).
To make the project you must force it to take the sources as 'npm update' will not do it.
```
npm install lib-jitsi-meet --force && make
```
Or if you are making only changes to the library:
```
npm install lib-jitsi-meet --force && make deploy-lib-jitsi-meet
```
Alternative way is to use [npm link](https://docs.npmjs.com/cli/link).
It allows to link `lib-jitsi-meet` dependency to local source in few steps:
```bash
cd lib-jitsi-meet
# create global symlink for lib-jitsi-meet package
npm link
cd ../jitsi-meet
# create symlink from the local node_modules folder to the global lib-jitsi-meet symlink
npm link lib-jitsi-meet
```
So now after changes in local `lib-jitsi-meet` repository you can rebuild it with `npm run install` and your `jitsi-meet` repository will use that modified library.
Note: when using node version 4.x, the make file of jitsi-meet do npm update which will delete the link, no longer the case with version 6.x.
If you do not want to use local repository anymore you should run
```bash
cd jitsi-meet
npm unlink lib-jitsi-meet
npm install
```
For web development see [here](doc/development.md), and for mobile see [here](doc/mobile.md).
## Contributing
@@ -96,12 +42,30 @@ see our [guidelines for contributing](CONTRIBUTING.md).
## Embedding in external applications
Jitsi Meet provides a very flexible way of embedding it in external applications by using the [Jitsi Meet API](doc/api.md).
Jitsi Meet provides a very flexible way of embedding in external applications by using the [Jitsi Meet API](doc/api.md).
## Mobile app
Jitsi Meet is also available as a React Native app for Android and iOS.
Instructions on how to build it can be found [here](doc/mobile.md).
## Security
WebRTC does not (yet) provide a way of conducting multi-party conversations with end-to-end encryption.
Unless you consistently compare DTLS fingerprints with your peers vocally, the same goes for one-to-one calls.
As a result, your stream is encrypted on the network but decrypted on the machine that hosts the bridge when using Jitsi Meet.
The Jitsi Meet architecture allows you to deploy your own version, including
all server components. In that case, your security guarantees will be roughly
equivalent to a direct one-to-one WebRTC call. This is the uniqueness of
Jitsi Meet in terms of security.
The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
at [8x8](https://8x8.com).
## Security issues
We take security very seriously and develop all Jitsi projects to be secure and safe.
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**
## Acknowledgements
Jitsi Meet started out as a sample conferencing application using Jitsi Videobridge. It was originally developed by then ESTOS' developer Philipp Hancke who then contributed it to the community where development continues with joint forces!
Jitsi Meet started out as a sample conferencing application using Jitsi Videobridge. It was originally developed by ESTOS' developer Philipp Hancke who then contributed it to the community where development continues with joint forces!
Start by making sure that your development environment [is set up correctly](https://github.com/jitsi/jitsi-meet/blob/master/doc/mobile.md).
A note on dependencies: Apart from the SDK, Jitsi also publishes a binary Maven artifact for some of the SDK dependencies (that are not otherwise publicly available) to the Jitsi Maven repository. When you're planning to use a SDK that is built from source, you'll likely use a version of the source code that is newer (or at least _different_) than the version of the source that was used to create the binary SDK artifact. As a consequence, the dependencies that your project will need, might also be different from those that are published in the Jitsi Maven repository. This might lead to build problems, caused by dependencies that are unavailable.
If you want to use a SDK that is built from source, you will likely benefit from composing a local Maven repository that contains these dependencies. The text below describes how you create a repository that includes both the SDK as well as these dependencies. For illustration purposes, we'll define the location of this local Maven repository as `/tmp/repo`
In source code form, the Android SDK dependencies are locked/pinned by package.json and package-lock.json of the Jitsi Meet project. To obtain the data, execute NPM in the jitsi-meet project directory:
npm install
This will pull in the dependencies in either binary format, or in source code format, somewhere under /node_modules/
Third-party React Native _modules_, which Jitsi Meet SDK for Android depends on, are download by NPM in source code
or binary form. These need to be assembled into Maven artifacts, and then published to your local Maven repository.
A script is provided to facilitate this. From the root of the jitsi-meet project repository, run:
./android/scripts/release-sdk.sh /tmp/repo
This will build and publish the SDK, and all of its dependencies to the specified Maven repository (`/tmp/repo`) in
this example.
You're now ready to use the artifacts. In _your_ project, add the Maven repository that you used above (`/tmp/repo`) into your top-level `build.gradle` file:
allprojects {
repositories {
maven { url "file:/tmp/repo" }
google()
jcenter()
}
}
You can use your local repository to replace the Jitsi repository (`maven { url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases" }`) when you published _all_ subprojects. If you didn't do that, you'll have to add both repositories. Make sure your local repository is listed first!
Then, define the dependency `org.jitsi.react:jitsi-meet-sdk` into the `build.gradle` file of your module:
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.