Compare commits

...

317 Commits

Author SHA1 Message Date
hristoterezov
9fa1b210f5 feat(loadScript): Use the function from js-utils 2018-03-22 13:15:14 -05:00
Paweł Domas
15e1633d86 fix(config): no legacy over non-legacy override (#2644)
Do not take legacy property into account if there's non-legacy value.
2018-03-22 10:57:08 -05:00
Daniel Ornelas
de0a7bfcd3 Some improvements for handling completion of transitions. Fixed a wrong conferenceEnded value when user left the conversation. 2018-03-22 00:04:25 -04:00
Daniel Ornelas
5858859838 Addressing feedback from PR 2018-03-22 00:04:25 -04:00
Daniel Ornelas
8428dd95c2 Implement Exit PiP mode in PiPWindow 2018-03-21 22:00:43 -04:00
Daniel Ornelas
a26ccf195e Added initialization of JitsiMeetManager components 2018-03-21 22:00:43 -04:00
Daniel Ornelas
0a5f60c637 Refactor PiP code into its own components 2018-03-21 22:00:43 -04:00
Daniel Ornelas
f8163de765 Implement Jitsi meet presentation interface that supports custom PiP solution 2018-03-21 22:00:43 -04:00
Daniel Ornelas
181580871f Initial work for testing PiP mode 2018-03-21 22:00:43 -04:00
damencho
ea431ca90c Adds new text for Firefox screen-sharing permission denied error. 2018-03-21 18:06:17 -05:00
damencho
a902540167 Removes Firefox extension handle (removed in FF newer than latest ESR). 2018-03-21 18:06:17 -05:00
virtuacoplenny
823481dc1d feat(recording): use google api to get stream key (#2481)
* 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
2018-03-21 11:26:52 -07:00
paweldomas
b5b99301ca fix: synchronize global 'config' var with the reducer's state 2018-03-20 21:07:45 -04:00
paweldomas
ef52f09910 ref(config): override config from URL on mobile
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.
2018-03-20 21:07:45 -04:00
Leonard Kim
6a066c3079 squash: update package-lock again for integrity shas 2018-03-20 16:06:50 -05:00
Leonard Kim
71e368f70e squash: override atlaskit styles for dropdowns to display clearer 2018-03-20 16:06:50 -05:00
Leonard Kim
134ff71c78 feat(modals): use dark theme 2018-03-20 16:06:50 -05:00
bbaldino
fef1d8b520 add a prosody module to insert identity information (when available) … (#2627)
* 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
2018-03-20 15:27:39 -05:00
virtuacoplenny
309fcf9672 fix(filmstrip): fix local video alignment with no invite button (#2629)
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.
2018-03-20 12:28:09 -07:00
virtuacoplenny
2eafbacdd4 chore(deps): update lib-jitsi-meet to 0503ec4d for edge p2p progress (#2631) 2018-03-20 11:34:57 -07:00
virtuacoplenny
26ea667170 Merge pull request #2628 from jitsi/welcome_page_analytics
fix(analytics): Init analytics for the web welcome page.
2018-03-20 10:02:07 -07:00
jitsi-pootle
5f43e8f8c7 New files added from translate.jitsi.org based on templates 2018-03-20 15:52:21 +00:00
Shikhar Agnihotri
9ef83702cf Update CONTRIBUTING.md (#2601) 2018-03-20 09:49:35 -05:00
hristoterezov
fda2548a38 fix(analytics): Init analytics for the web welcome page. 2018-03-19 17:51:22 -05:00
Дамян Минков
eb53944a4d Adds poltergeist support for locked rooms. (#2626) 2018-03-19 16:20:44 -05:00
Saumeya Katyal
2334eb9967 doc: Add dev server steps (#2610)
* doc: Add webpack-dev-server steps
2018-03-19 10:16:01 -05:00
Emil Ivov
04bd4a9038 Merge pull request #2617 from virtuacoplenny/lenny/info-dialog-again
fix(info): update copy text to find correct var
2018-03-15 12:16:20 -05:00
virtuacoplenny
eb8f34cee8 Merge pull request #2612 from jitsi/no_protocol_in_intent_uri
feat(UnsupportedMobileBrowser): do not include protocol in the intent
2018-03-15 10:01:31 -07:00
Leonard Kim
b9379f5996 fix(info): update copy text to find correct var 2018-03-15 09:42:39 -07:00
paweldomas
40d7d0c9cb feat(UnsupportedMobileBrowser): do not include protocol in the intent
Do not include the protocol part in the intent URL.
2018-03-14 17:44:32 -05:00
zbettenbuk
357f173e85 Remove obsolate PlatformElements.native.js 2018-03-13 18:04:17 -05:00
zbettenbuk
7da26042b3 Avoid asking for calendar permission on app start 2018-03-13 18:04:17 -05:00
zbettenbuk
c86c7beb24 Refactor i18n calendar formatter 2018-03-13 18:04:17 -05:00
zbettenbuk
1020a54a33 Add Android navigation bar 2018-03-13 18:04:17 -05:00
zbettenbuk
c84abd543e Add support for app link scheme 2018-03-13 18:04:16 -05:00
zbettenbuk
4b17c6f015 Add pull-to-refresh functionality 2018-03-13 18:04:16 -05:00
zbettenbuk
cb973b61aa Implement adaptive known domain list 2018-03-13 18:04:16 -05:00
zbettenbuk
b096622995 Unify recent and meeting lists 2018-03-13 18:04:16 -05:00
zbettenbuk
ae0bf876a8 Add conference notification 2018-03-13 18:04:16 -05:00
zbettenbuk
bba480f329 Add calendar-sync feature 2018-03-13 18:04:14 -05:00
paweldomas
4dbcaf851f flow(AbstractAudio): specific function types 2018-03-13 16:57:29 -05:00
paweldomas
04dff9059b ref(AudioOutputPreview): use Audio from base/media 2018-03-13 16:57:28 -05:00
paweldomas
26cd2f17f6 ref(chat): port incoming chat msg sound to react 2018-03-13 16:57:28 -05:00
paweldomas
60e03e3dec feat: add join/leave sounds on mobile
Adds base/sounds feature which allows other features to register a sound
source under specified id. A new SoundsCollection component will then
render corresponding HTMLAudioElement for each such sound. Once "setRef"
callback is called by the HTMLAudioElement, this element will be added
to the Redux store. When that happens sound can be played through the
new 'playSound' action which will call play() method on the stored
HTMLAudioElement instance.
2018-03-13 16:57:28 -05:00
virtuacoplenny
bfb45ed0e8 fix(large-video): do not try to show background on safari with webrtc (#2606)
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.
2018-03-13 14:37:35 -07:00
virtuacoplenny
e325199075 fix(invite): prefix a + when faking the validation response (#2597)
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.
2018-03-12 13:25:42 -07:00
virtuacoplenny
4e4713c3e2 feat(invite): be able to call numbers from the invite dialog (#2555)
* 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
2018-03-12 12:23:40 -07:00
Saúl Ibarra Corretgé
ff8386e931 debian: fix setting the auth domain certificates
In 94813bc0fd (diff-6e9552c9bd8e61c8f277c21220160234)
two local variables got removed (AUTH_KEY_FILE and AUTH_CRT_FILE), which are used by the sed command
below to configure the virtualhost for auth.
2018-03-11 16:05:14 -05:00
Leonard Kim
8f520086e5 fix(info): do not show dial in numbers without a room specified
For the static page an error message displays stating no room
was specified. On mobile for unsupported browsers, the dial in
info will not show.
2018-03-09 17:18:10 -06:00
Shuai Li
5cde674eff fix(android): webrtc progurd rule
The new libwebrtc.jar contains an extra unused class file, when proguard is enabled result in the following warning:

org.chromium.build.BuildHooksAndroidImpl: can't find superclass or interface org.chromium.build.BuildHooksAndroid
2018-03-09 12:29:49 -08:00
Lyubo Marinov
c018252eee [Android] Fix RuntimeException in RNImmersiveModule
java.lang.RuntimeException: Tried to access a JS module before the React instance was fully set up. Calls to ReactContext#getJSModule should only happen once initialize() has been called on your native module.
	at com.facebook.react.bridge.ReactContext.getJSModule(ReactContext.java:102)
	at com.rnimmersive.RNImmersiveModule.emitImmersiveStateChangeEvent(RNImmersiveModule.java:74)
	at org.jitsi.meet.sdk.JitsiMeetView.onWindowFocusChanged(JitsiMeetView.java:504)
	at android.view.View.dispatchWindowFocusChanged(View.java:10257)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1193)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197)
	at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3602)
	at android.os.Handler.dispatchMessage(Handler.java:102)
	at android.os.Looper.loop(Looper.java:154)
	at android.app.ActivityThread.main(ActivityThread.java:6119)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
2018-03-09 13:50:07 -06:00
George Politis
c8cab1560c Merge pull request #2589 from jitsi/update-lib-jitsi-stats
Updates lib-jitsi-meet to d4b78721.
2018-03-09 12:44:53 -06:00
damencho
d218abfd97 Updates lib-jitsi-meet to d4b78721.
Implements the promised based getStats. Enables them for Safari and FF.
2018-03-09 12:03:01 -06:00
paweldomas
9e0fee6c7d fix(android): do not require java 8 target
Updates react-native-webrtc to get rid of Java 8 requirement for
the Android app.
2018-03-08 15:47:05 -06:00
damencho
5dca9e08f4 Bumps uglifyjs-webpack-plugin and its dependencies.
Solves a GitHub warning in lib-jitsi-meet about a vulnerability in a
uglifyjs-webpack-plugin dependency.
2018-03-08 15:12:15 -06:00
Lyubo Marinov
d3a1f7d4f7 [iOS] Fix uncaught NSInvalidArgumentException in RTCPeerConnection's createAnswer
WebRTC used to report createAnswer (and createOffer) NSError with key
"error". But now the key's called "NSLocalizedDescription".

Additionally, NSMutableDictionary doesn't accept nil.
2018-03-07 15:23:20 -06:00
Leonard Kim
80bdf908ca fix(info): always remove last part of path for meeting name 2018-03-06 15:22:27 -06:00
Leonard Kim
0d3b4eedf8 fix(info): make some text selectable for manual copying 2018-03-06 13:47:55 -06:00
Leonard Kim
824a8a8864 fix(info): respect path when linking to dial in page 2018-03-06 13:47:55 -06:00
virtuacoplenny
45c1438fe6 Merge pull request #2567 from jitsi/bgrozev-patch-1
doc: Add clarifying text to the top of the readme.
2018-03-06 11:29:25 -08:00
bgrozev
8caeabf6b4 doc: Add clarifying text to the top of the readme. 2018-03-06 11:45:11 -06:00
Leonard Kim
466561f99f fix(polyfills): implement createHTMLDocument for jquery 2018-03-06 10:46:53 -06:00
zbettenbuk
8dc866fab3 Fix setTimeout polyfill 2018-03-06 09:42:25 +01:00
George Politis
1c8b8e031b feat: Whitelists the gatherStats option. (#2561)
* feat: Whitelists the gatherStats option.

* doc: Replaces obsolete disableStats option with gatherStats.
2018-03-05 11:12:39 -06:00
Lyubo Marinov
796489dc77 Coding style: naming, consistency 2018-03-04 19:28:44 -06:00
Lyubo Marinov
a30412ba65 [RN] Automatically dispatch CONFERENCE_LEFT 2018-03-04 19:28:44 -06:00
Saúl Ibarra Corretgé
8b35ea8ad5 deps: update jquery version (#2441)
* 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
2018-03-02 21:20:47 -06:00
hristoterezov
e05f2a9027 chore(package.json): Update lib-jitsi-meet. 2018-03-02 21:19:16 -06:00
George Politis
0d5cc8898d chore(lib-jitsi-meet): Update version. 2018-03-02 16:33:04 -06:00
virtuacoplenny
7672a88990 fix(dial-in): remove console.warn used for debugging (#2547)
Looks like this guy snuck into the commit.
2018-03-01 15:50:23 -08:00
virtuacoplenny
5a45b52881 fix(hangup): destroy local tracks on conference leave (#2546)
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.
2018-03-01 15:47:46 -08:00
Leonard Kim
ce6e8472f0 Revert "fix(hangup): destroy local tracks on conference leave (#2502)"
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.
2018-03-01 14:07:30 -06:00
Leonard Kim
b00aaf1de7 fix(dial-in): specify url root for more numbers link
This gets around the issue of a cdn page being opened.
2018-02-28 23:17:20 -06:00
Lyubo Marinov
e622829c1c [RN] Promised-base RTCPeerConnection API
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.
2018-02-28 17:17:08 -06:00
Lyubo Marinov
037e7f59b0 [RN] Fix a TypeError when invoking humanize() on undefined 2018-02-28 17:17:07 -06:00
hristoterezov
df754f4f41 fix(reload): Preserve URL params on reload/redirect. 2018-02-28 14:28:56 -06:00
George Politis
fd0749000e feat: Whitelists the iceTransportPolicy option. (#2535) 2018-02-28 11:28:47 -08:00
Lyubo Marinov
d727ee80b2 [RN] Fix base/profile and recent-list bugs 2018-02-27 20:52:34 -06:00
zbettenbuk
e4da0e988e Split storage keys to features 2018-02-27 07:33:33 -06:00
zbettenbuk
1474304cc5 Add the ability to do partial updates on the flatten profile object 2018-02-27 07:33:33 -06:00
zbettenbuk
d02ab2c641 Flatten the store of the profile feature 2018-02-27 07:33:33 -06:00
zbettenbuk
0e07020d09 Flatten the store of the recent-list feature 2018-02-27 07:33:33 -06:00
zbettenbuk
e0deb6d64b Prepare PersistenceRegistry for flat subtrees 2018-02-27 07:33:33 -06:00
virtuacoplenny
88325aeef2 fix(hangup): destroy local tracks on conference leave (#2502)
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.
2018-02-26 21:10:49 -08:00
Lyubo Marinov
9f69c4d730 Grow features/settings from features/app-settings and features/settings-menu 2018-02-26 19:19:01 -06:00
zbettenbuk
e23d4317eb Add hint box with dynamic join button 2018-02-26 18:39:48 -06:00
zbettenbuk
547ddee3a5 Dismiss keyboard on menu open 2018-02-26 18:39:48 -06:00
zbettenbuk
3cf9fd439b Add iOS 10 compatibility header padding 2018-02-26 18:39:48 -06:00
zbettenbuk
7cd40353e7 Remove android view clipping fix from welcome page 2018-02-26 18:39:48 -06:00
zbettenbuk
04690dfc8f Facelift Welcome screen 2018-02-26 18:39:48 -06:00
zbettenbuk
9a9890f86c Introduce SafeArea for Settings and Header 2018-02-26 18:35:13 -06:00
Leonard Kim
9b04a7852a fix(welcome-page): send analytics on join 2018-02-26 18:41:47 -05:00
Emil Ivov
df9d17ba18 Merge pull request #2523 from bgrozev/whitelist-ss-fps
config: Whitelists the desktopSharingFrameRate config key.
2018-02-26 13:18:20 -06:00
Boris Grozev
5d0ac7653d config: Whitelists the desktopSharingFrameRate config key. 2018-02-26 11:45:42 -06:00
virtuacoplenny
1ef2e2ee7e Merge pull request #2503 from jitsi/ss_fps
feat(ss_framerate): Add config option for min/max frame rate.
2018-02-23 12:28:48 -08:00
hristoterezov
b3431ab3e7 chore(lib-jitsi-meet): Update version. 2018-02-23 13:38:41 -06:00
Leonard Kim
6fbe78eb34 fix(welcome-page): change font family and spacing 2018-02-23 11:35:02 -06:00
Lyubo Marinov
b8de5bbfc3 [RN] Add Picture-in-Picture support (Coding style: naming, consistency) 2018-02-23 11:21:26 -06:00
Saúl Ibarra Corretgé
b3683068d4 [RN] Add Picture-in-Picture support
This only works automatically on Android >= 8. On other platforms / versions, it
relies on the SDK user on implementing a "reduced UI" mode and reacting to the
"request PIP" delegate method.
2018-02-23 11:21:25 -06:00
Lyubo Marinov
94473e5660 [Android] Allow accessing react-native's in-app developer menu (in the emulator) 2018-02-23 11:21:25 -06:00
virtuacoplenny
7f78050513 Merge pull request #2434 from slavakisel/external-notification-screen-sharing
Implement external API notification about screen sharing status
2018-02-22 17:39:03 -08:00
hristoterezov
2d9b906a3b feat(ss_framerate): Add config option for min/max frame rate. 2018-02-22 19:37:17 -06:00
Leonard Kim
1f82ce3d19 feat(unsupported-browser): show dial-in for mobile
- 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.
2018-02-22 17:29:03 -06:00
Leonard Kim
68b710a222 fix(dial-in): allow text select in numbers page 2018-02-22 17:29:03 -06:00
brian baldino
9fea5e89b3 don't show 'user has left' notification for hidden users 2018-02-22 13:41:24 -06:00
Slava Kisel
e1d849e3a0 Implement external API notification about screen sharing status 2018-02-22 10:25:03 +03:00
virtuacoplenny
74a92f83c7 feat(welcome): new design (#2492)
* feat(welcome): new design

* squash: update strings

* squash: copy/paste error?

* squash: remove welcome page disabling checks

* squash: change strings again

* squash: background var

* squash: title and desc css as variables
2018-02-21 22:58:55 -06:00
virtuacoplenny
e47802538e ref(invite): remove InviteDialog (#2483)
* 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
2018-02-17 13:53:39 -06:00
Lyubo Marinov
e2cf7a788d [RN] Make full-screen more resilient on Android (Coding style: consistency) 2018-02-14 12:28:22 -06:00
Saúl Ibarra Corretgé
4757c1ebca [RN] Make full-screen more resilient on Android
On Android we go into "immersive mode" when in a conference, this is our way of
being full-creen. There are occasions, however, in which Android takes us out of
immerfive mode without us (the application / SDK) knowing: when a child activity
is started, a modal window shown, etc.

In order to be resilient to any possible change in the immersive mode, register
a listener which will be called when Android changes it, so we can re-eavluate
if we need it and thus re-enable it.
2018-02-13 15:00:36 -06:00
virtuacoplenny
59d046dca9 feat(info): new dialog design (#2452)
* 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
2018-02-13 13:46:47 -06:00
Lyubo Marinov
0bbcd3181c [RN] Adjust Conference for the reduced UI mode (Coding style) 2018-02-13 13:24:10 -06:00
Saúl Ibarra Corretgé
7a9ff9975a [RN] Adjust Conference for the reduced UI mode 2018-02-13 11:59:12 -06:00
Lyubo Marinov
10f72f8e40 [RN] Unpin participant and set last N to 1 if the filmstrip is disabled (Coding style: consistency) 2018-02-13 11:58:26 -06:00
Saúl Ibarra Corretgé
417e1e83e7 [RN] Unpin participant and set last N to 1 if the filmstrip is disabled 2018-02-13 09:58:44 -06:00
Lyubo Marinov
cacc4bd769 [RN] Dynamically adjust LargeView's Avatar to available size (Coding style: comments, flow)
Flow caught an incorrect function call.
2018-02-13 09:58:43 -06:00
Saúl Ibarra Corretgé
1419247801 [RN] Dynamically adjust LargeView's Avatar to available size
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.
2018-02-13 09:58:43 -06:00
virtuacoplenny
4fb37c38eb fix(large-video): do not show background for Firefox and temasys (#2316)
* 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
2018-02-12 16:29:29 -08:00
Leonard Kim
f3b5ed2ef4 ref(notifications): convert Thank You message to a notification 2018-02-12 17:53:29 -06:00
Leonard Kim
7341c7bf84 ref(notifications): stop passing around Notifications component
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.
2018-02-12 17:53:29 -06:00
Leonard Kim
5d31532cbb fix(chat): return formatted body to show smileys 2018-02-12 15:34:21 -07:00
virtuacoplenny
423c8d3f53 Merge pull request #2479 from bgrozev/ga-tweaks
Ga tweaks
2018-02-12 12:35:23 -08:00
Boris Grozev
a1ba7beff9 feat: Do not include the callstats name in google analytics. 2018-02-12 14:00:15 -06:00
Boris Grozev
03fc711e81 feat: Makes the google analytics tracking id configurable. 2018-02-12 14:00:04 -06:00
Lyubo Marinov
a370a88d19 [RN] Add ability to enable /disable the toolbox (Coding style: comments, consistency) 2018-02-12 11:53:42 -06:00
Saúl Ibarra Corretgé
7153d94dad [RN] Add ability to enable /disable the toolbox 2018-02-12 11:52:54 -06:00
Lyubo Marinov
240fff74c7 [RN] Add ability to enable / disable the filmstrip (Coding style: comments, naming) 2018-02-12 11:52:46 -06:00
Saúl Ibarra Corretgé
7bd8b7948f [RN] Add ability to enable / disable the filmstrip
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.
2018-02-12 10:02:34 -06:00
Дамян Минков
a505c01e9e Update uninstall documentation.
The package jitsi-meet-prosody was missing from the list of packages.
2018-02-09 10:28:01 +01:00
damencho
990b1eddf2 Adds strophe.js and plugin-disco as a dependency to fix build problem.
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.
2018-02-08 23:50:45 -06:00
damencho
abbfd3de9a Adds strophe.js as a dependency to fix build problem.
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.
2018-02-08 22:48:25 -06:00
Saúl Ibarra Corretgé
bd301403c4 [RN] Fix app startup from a CallKit intent
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.
2018-02-07 10:12:10 -06:00
bgrozev
d481c6f736 chore: Updates lib-jitsi-meet to 5f8c0a662af086e7bcc19c010f1129afc9b6… (#2460)
* chore: Updates lib-jitsi-meet to 5f8c0a662af086e7bcc19c010f1129afc9b6d650

* squash: revert changes to package-lock.json except for the lib-jitsi-meet version change.
2018-02-06 21:21:39 -07:00
Дамян Минков
ba94ba30c5 Handles connection failed event details (passing them to analytics). (#2432)
* Handles connection failed event details (passing them to analytics).

* Fixing comments.

* Updates depending versions to be able to test.

* Fixing comments.

* Fixes wrong jsdoc.
2018-02-06 14:54:21 -08:00
Saúl Ibarra Corretgé
5305557ce5 [RN] Add a "reduced UI" mode
It's detected based on a size threshold.
2018-02-06 15:53:52 -06:00
Lyubo Marinov
c9d8b5c827 Finally! Let there be... responsive-ui!
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.
2018-02-06 15:53:27 -06:00
Saúl Ibarra Corretgé
0ad1c88cd2 [RN] Refactor AspectRatioDetector
Factor out the dimensions detection login into a DimensionsDetector component.
2018-02-06 11:21:12 -06:00
Saúl Ibarra Corretgé
78fbfba573 [iOS] Fix initial CallKit muted state
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.
2018-02-06 10:24:06 -06:00
Saúl Ibarra Corretgé
9e53d40b9c [RN] Honor filmstrip visibility state 2018-02-05 15:55:05 -06:00
Lyubo Marinov
aa314c10ac Coding style: consistent naming, one name per abstraction
Instead of having visible and visibility and setToolboxVisible and
setFilmstripVisibility, have only visible as a name.
2018-02-05 15:55:04 -06:00
Lyubo Marinov
62c9762793 [RN] Protect AbstractApp and localStorage initialization 2018-02-05 15:26:01 -06:00
Lyubo Marinov
d7dddb2509 Introduce base/storage to represent the Web Storage API and persistence-related customizations 2018-02-02 15:13:26 -06:00
Lyubo Marinov
83243d5980 [RN] Fix legacy recent-list storage 2018-02-02 15:13:26 -06:00
Zoltan Bettenbuk
6e05cab46e [RN] Fix legacy recent-list storage 2018-02-02 15:13:26 -06:00
Lyubo Marinov
7954d5fd39 Coding style 2018-02-02 15:13:26 -06:00
zbettenbuk
158cadf4f9 Improve persistency layer 2018-02-02 15:13:26 -06:00
Lyubo Marinov
f35578c803 [RN] Polyfill __filename ASAP 2018-02-02 15:13:26 -06:00
Saúl Ibarra Corretgé
c087e90099 [RN] Fix setReceivedVideoQuality if we are not yet in a conference
It may happen that such action is fired while joining.
2018-02-02 14:33:49 -06:00
Saúl Ibarra Corretgé
da0ae73d10 [RN] Fix pinParticipant if we are not yet in a conference
It may happen that such action is fired while joining.
2018-02-02 14:32:15 -06:00
Saúl Ibarra Corretgé
b4d44f367d [RN] aspect-ratio: preserve mode when width === height
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.
2018-02-02 14:19:08 -06:00
hristoterezov
083f6b400b chore(capabilities.json): deploy 2018-02-01 17:21:52 -06:00
Saúl Ibarra Corretgé
dd5ae49217 Merge pull request #2407 from zbettenbuk/new-welcome-screen
Add URL validation and larger distance behind the back button
2018-01-31 16:26:09 +01:00
zbettenbuk
6a9e6db3be [RN] Validate the URL in app-settings 2018-01-31 16:06:24 +01:00
virtuacoplenny
c4468cb7b8 chore(deps): update lib-jitsi-meet for connection quality logging (#2436) 2018-01-30 14:52:25 -08:00
Leonard Kim
80c4205fb8 chore(deps): update lib-jitsi-meet for ie11 browser caps fix 2018-01-29 16:16:21 -06:00
zbettenbuk
aa9efd6f69 [RN] Improve app-settings back button style 2018-01-29 10:58:46 +01:00
Piérre Reimertz
6f8f64ba48 [iOS] Fix crash if the app display name is not set
Fixes: #2377 #2267 #2158
2018-01-29 10:34:01 +01:00
Leonard Kim
1c3cef1eed fix(notifications): reduce duration of initially muted notification
The current notification for starting muted is 2 minutes, which
may seem like "forever" so reduce it to dismiss faster.
2018-01-28 18:48:56 -06:00
Leonard Kim
2720c76e4d fix(password): do not let guests edit password when roles are enabled
If config.enableUserRolesBasedOnToken is true, only let moderators
and non-guests modify the password. Otherwise, only let moderators
edit the password.
2018-01-28 18:48:24 -06:00
virtuacoplenny
4ab34589c8 Merge pull request #2431 from jitsi/recommended_browsers_link
fix(recommended-browsers): Fix link
2018-01-28 13:41:54 -08:00
hristoterezov
ed36132e94 fix(recommended-browsers): Fix link 2018-01-28 11:51:08 -06:00
virtuacoplenny
f43687944c Merge pull request #2429 from jitsi/fix_chromium
chore(lib-jitsi-meet): Update the version.
2018-01-27 11:45:46 -08:00
hristoterezov
dda0ea0ba9 chore(lib-jitsi-meet): Update the version. 2018-01-27 13:02:46 -06:00
Lyubo Marinov
e1f967869a [RN] Add builtin translations 2018-01-26 12:18:43 -06:00
Saúl Ibarra Corretgé
8673083829 [RN] Add builtin translations
Load all of them as imports, so the packager includes them in the bundle. Then
register them with the i18next library.
2018-01-26 16:27:33 +01:00
Lyubo Marinov
b52e584327 "feat(TPC): append TPC ID to stream IDs" & "fix(RTC): protect from counter overflow" 2018-01-25 11:21:40 -06:00
hristoterezov
4c65262a87 fix(browser-caps): Deploy. 2018-01-25 10:44:24 -06:00
bgrozev
7ce670df0c doc: Add -f to update-ca-certificates 2018-01-25 10:42:43 -06:00
Boris Grozev
f5f341ca9e npm: Updates lib-jitsi-meet to e895c9b86f57a288f644dcc61f81771034b932da. 2018-01-24 14:15:52 -06:00
Lyubo Marinov
f29fbb6757 [iOS] WebRTC 63 with 2 backports to fix a crash 2018-01-24 13:37:54 -06:00
virtuacoplenny
e5e3c6c6c4 Merge pull request #2410 from bgrozev/set-product
feat: Sets the "product" field in the analytics handler constructor.
2018-01-23 15:25:59 -08:00
Boris Grozev
dc92fb5073 feat: Sets the "product" field in the analytics handler constructor. 2018-01-23 16:14:31 -06:00
damencho
2478176f23 Adds uiLoaded event in iframe API, fired when all resources are loaded. 2018-01-23 15:43:49 -06:00
virtuacoplenny
12ec982067 Merge pull request #2400 from jitsi/browser_caps2
fix(lib-jitsi-meet): RTCBrowserType -> browser.
2018-01-22 13:57:50 -08:00
hristoterezov
c9e3e5052d fix(lib-jitsi-meet): RTCBrowserType -> browser. 2018-01-22 15:56:06 -06:00
Emil Ivov
22401614a7 Merge pull request #2401 from virtuacoplenny/lenny/spot-feedback-api
feat(api): expose a way to submit feedback
2018-01-19 16:57:18 -06:00
Leonard Kim
762f529f1d feat(api): expose a way to submit feedback
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.
2018-01-19 14:27:44 -08:00
Saúl Ibarra Corretgé
1f6b743bec [RN] Join room when pressing "go" on the keyboard
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.
2018-01-19 16:10:51 -06:00
Lyubo Marinov
48f4317adb [RN] Make video track fade-in effect cross-platform 2018-01-19 16:05:59 -06:00
Saúl Ibarra Corretgé
75f6786588 [RN] Make video track fade-in effect cross-platform
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.
2018-01-19 15:32:17 -06:00
Lyubo Marinov
3ec4d67a99 [RN] Strip spaces when parsing URLs 2018-01-19 15:26:13 -06:00
Saúl Ibarra Corretgé
a23eec55e8 [RN] Strip spaces when parsing URLs 2018-01-19 15:14:51 -06:00
Lyubo Marinov
bdf2ecfe4b [iOS] CocoaPods 1.4.0 2018-01-19 15:00:18 -06:00
Lyubo Marinov
fc36759114 [RN] WebRTC 63 2018-01-19 14:56:58 -06:00
Saúl Ibarra Corretgé
9c2849a663 [Android] Enable Java 1.8 compatibility support
It was recently introduced in WebRTC, so we we need to enable it project wide.
As for what features are supportd, see:
https://developer.android.com/studio/write/java8-support.html
2018-01-19 14:05:25 -06:00
Saúl Ibarra Corretgé
98ff20a026 [RN] Simplify initialization of AsyncStorage 2018-01-19 09:41:34 -06:00
Lyubo Marinov
b04661b40b [RN] Revert unintentional disabling of the yellow box 2018-01-18 21:11:24 -06:00
Lyubo Marinov
112c856850 Fix settings screen layout on iOS and add soft back button 2018-01-18 15:45:25 -06:00
zbettenbuk
410dc132e1 Fix settings screen layout on iOS and add soft back button 2018-01-18 10:06:26 -06:00
Saúl Ibarra Corretgé
b7f950f5f7 feat(analytics): shield sending analytics events
Any failure in analytics should not prevent the natural flow of the code. Shield
the function by catching and logging any exception.
2018-01-17 16:46:54 -06:00
Paweł Domas
7ad875e735 fix(RN logging): sync with logging_config.js (#2382) 2018-01-17 10:59:48 -08:00
Saúl Ibarra Corretgé
41aa704e1f [RN] Update React Native to version 0.51.0 2018-01-11 11:04:28 -06:00
Saúl Ibarra Corretgé
e00ea353e8 Merge pull request #2380 from saghul/app-settings-kbd
[RN] Use the "email" keyboard for the email field
2018-01-10 15:52:27 +01:00
Saúl Ibarra Corretgé
6f93424d7c [RN] Use the "email" keyboard for the email field 2018-01-10 14:30:34 +01:00
Saúl Ibarra Corretgé
292f3ab1bd [Android] Fix crash if settings activity cannot be opened
The documentation states this is possible, so make sure we handle such errors.

Ref:
https://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DETAILS_SETTINGS
2018-01-09 13:12:53 -06:00
Boris Grozev
a3cb081609 fix: Fixes an exception when the chat button and shortcut are clicked. 2018-01-09 10:36:55 -08:00
Leonard Kim
64c5ae1c48 fix(close): use string concatenation for ie11 2018-01-08 16:26:54 -06:00
bgrozev
259004b8bf fix: Fixes the user ID read from JWT. (#2366) 2018-01-08 11:27:08 -06:00
ibauersachs
4fea22676b Commit from translate.jitsi.org by user ibauersachs.: 410 of 410 strings translated (0 fuzzy). 2018-01-08 16:03:42 +00:00
zbettenbuk
05a492241f Fix local participant details on web 2018-01-05 12:58:58 -06:00
virtuacoplenny
8ec4697a27 Merge pull request #2353 from jitsi/suboptimal_experience
feat(notification): Add suboptimal browser exp notification.
2018-01-04 14:36:58 -08:00
hristoterezov
a357b0cf14 feat(notification): Add suboptimal browser exp notification. 2018-01-04 15:57:17 -06:00
virtuacoplenny
9eff669b0b Merge pull request #2357 from bgrozev/analytics-update
Analytics update
2018-01-04 12:32:07 -08:00
Boris Grozev
c7714959e6 feat: Passes the environment type and subproduct to the analytics handler constructor. 2018-01-04 13:12:48 -06:00
Boris Grozev
e898527294 feat: Passes the "group" from JWT to the analytics handler constructor. 2018-01-04 13:12:48 -06:00
zbettenbuk
bfcd34358b [RN] Add app-settings feature
[RN] Fix PR feedbacks, write persistency docs
2018-01-04 12:53:29 -06:00
bbaldino
871ef9ff0e change TPC logs to info by default 2018-01-04 08:14:40 -06:00
Saúl Ibarra Corretgé
178c8e02ff [RN] Disable the XHR backend on mobile
All language assets will need to be bundled.
2018-01-03 19:18:12 -06:00
bgrozev
43ac039fd6 fix: Adapts to changes in lib-jitsi-meet. (#2354) 2018-01-03 16:07:39 -08:00
bgrozev
090f2f9ccb Restructures the analytics events (#2333)
* 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.
2018-01-03 13:24:07 -08:00
zbettenbuk
d08bbae770 [RN] Add proper locale support to MomentJS 2018-01-03 10:13:15 -06:00
Дамян Минков
30b51ff384 Adds warning to manual-install doc. 2018-01-02 17:18:06 -06:00
ibauersachs
c109199e06 Commit from translate.jitsi.org by user ibauersachs.: 409 of 410 strings translated (0 fuzzy). 2017-12-29 15:21:18 +00:00
ibauersachs
0ed31f0ae8 Commit from translate.jitsi.org by user ibauersachs.: 399 of 399 strings translated (0 fuzzy). 2017-12-29 15:01:39 +00:00
jitsi-pootle
006e6cc851 New files added from translate.jitsi.org based on templates 2017-12-28 23:44:49 +00:00
Leonard Kim
0680c086df chore(deps): update lib-jitsi-meet for ie11 stringify failure 2017-12-28 14:26:35 -06:00
Leonard Kim
698ec1e2d7 Revert "feat(avatars): use initials service for getting images (#2312)"
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.
2017-12-28 14:17:33 -06:00
Leonard Kim
e217c172f8 ref(toolbar): re-wrap buttons for torture tests
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.
2017-12-26 16:08:40 -06:00
jitsi-pootle
6146c12533 New files added from translate.jitsi.org based on templates 2017-12-26 20:48:41 +00:00
damencho
eb64b74493 Commit from translate.jitsi.org by user damencho.: 399 of 399 strings translated (0 fuzzy). 2017-12-26 20:47:35 +00:00
bgrozev
1255b3349b doc: Adds a note on security (as suggested in #409). (#2322) 2017-12-26 10:49:46 -08:00
virtuacoplenny
2ea5ad68a5 feat(avatars): use initials service for getting images (#2312)
* feat(avatars): use initial service for getting images

* squash: capitalize and minor refactor of string concat
2017-12-21 13:36:00 -06:00
Lyubo Marinov
fb6f1bdba0 [RN] Accommodate iPhone X on the WelcomePage 2017-12-21 00:02:22 -06:00
Lyubo Marinov
25b130f8e8 [RN] Don't tint the children, tint the background only 2017-12-21 00:00:34 -06:00
Lyubo Marinov
9591cb54a2 [iOS] 1024x1024 AppIcon required by Apple 2017-12-20 12:38:11 -06:00
Saúl Ibarra Corretgé
ca78309427 Fix typo 2017-12-20 10:58:49 +01:00
Lyubo Marinov
65abd5efd4 [iOS] Synthesize IPv6 addresses closer to Apple's recommendation 2017-12-19 19:15:34 -06:00
Lyubo Marinov
05de599739 [iOS] Update projects to Xcode recommended settings 2017-12-19 19:15:34 -06:00
Lyubo Marinov
1e0550c746 [RN] Add recent-list feature 2017-12-19 19:15:01 -06:00
Zoltan Bettenbuk
45c405de0e [RN] Add recent-list feature 2017-12-19 18:35:51 -06:00
Leonard Kim
3aedce11f2 fix(filmstrip): prevent error on updating indicators for shared video
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.
2017-12-19 17:14:42 -06:00
Leonard Kim
f0a180cf0c fix(display-name): listen for display name changes
Make sure participants in the redux store have updated names.
This will be needed for showing avatars with user initials.
2017-12-19 17:13:10 -06:00
virtuacoplenny
28013f6ffa ref(avatars): remove Avatar.js (#2289)
* 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
2017-12-19 17:11:54 -06:00
Saúl Ibarra Corretgé
5640524647 [RN] Show an indication when connectivity problems occur
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.
2017-12-19 09:10:58 -06:00
Saúl Ibarra Corretgé
ac09233558 [RN] Add TintedView component
It's designed to cover a container and give it a "tint" by using a color and
opacity.
2017-12-19 09:10:58 -06:00
Saúl Ibarra Corretgé
9a3f98a4a0 Merge pull request #2256 from jitsi/wifistats
[Android] WiFi stats for mobile
2017-12-19 11:10:27 +01:00
damencho
2f3ea1b458 [Android] Add module that provides getWiFiStats 2017-12-19 11:07:11 +01:00
Leonard Kim
ceeefb33c1 fix(display-name): allow editing only if guest 2017-12-18 23:16:38 -06:00
hristoterezov
d6c3ab64fa fix(aot): Unmount AlwaysOnTop to remove listeners (#2307) 2017-12-18 14:35:56 -08:00
George Politis
eee87bc546 Merge pull request #2303 from jitsi/update-lib-ff-stats-fix
Updates to latest lib-jitsi-meet f71ff66.
2017-12-15 16:05:03 -06:00
damencho
9a42b866ba Updates to latest lib-jitsi-meet f71ff66.
Updates also to latest react-callstats 3.27.0 as lib-jitsi-meet already updated to it.
2017-12-15 15:24:58 -06:00
Saúl Ibarra Corretgé
b920140488 android: update Gradle plugin version for AS 3.0.1 2017-12-14 15:20:05 -06:00
Saúl Ibarra Corretgé
49acd6bf6a android: simplify using the Google Maven repo reference
Also remove mavenLocal since we don't need it.
2017-12-14 15:20:05 -06:00
Saúl Ibarra Corretgé
7001208d87 [RN] Adjust filmstrip ordering based on aspect ratio
When in wide aspect ratio,, show it with the local participant on top, and the
remote ones after, sorted by join order.
2017-12-14 12:36:03 -06:00
Saúl Ibarra Corretgé
4a0e55b1f4 deps: update lib-jitsi-meet dependency 2017-12-13 11:11:06 -06:00
Lyubo Marinov
73cc9a68c7 Full commit hash 2017-12-13 10:15:48 -06:00
Saúl Ibarra Corretgé
e9c91d194c android: update appcompat version 2017-12-13 09:35:34 -06:00
Saúl Ibarra Corretgé
3460fe03e5 android: update target SDK version
Android Oreo (API level 26) is supported since React Native 50.
2017-12-13 09:35:34 -06:00
Saúl Ibarra Corretgé
e65566ad03 Merge pull request #2288 from saghul/rn-i18n
[RN] Build react-native-locale-detector
2017-12-13 11:35:42 +01:00
Saúl Ibarra Corretgé
57206cc36a [RN] Build react-native-locale-detector
Upstream lacked a CocoaPods podspec file, PR:
https://github.com/DylanVann/react-native-locale-detector/pull/3
2017-12-13 10:17:05 +01:00
Saúl Ibarra Corretgé
c05c8e0f1e [RN] Handle config loading errors
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.
2017-12-12 22:59:04 -06:00
Saúl Ibarra Corretgé
87a87eebb9 [RN] Add reload overlay in case of connection / conference errors 2017-12-12 22:58:46 -06:00
Lyubo Marinov
ad497fed7c Reduce duplication 2017-12-12 21:58:33 -06:00
Saúl Ibarra Corretgé
0f6243ee88 feat(overlays): CallOverlay is not really an overlay
It's not supposed to go on top of everything, like an error would. It's tied to
a conference, so render it outside of the OverlayContainer.
2017-12-12 20:52:29 -06:00
Lyubo Marinov
b39b6640b4 React & React Native Fragment-like 2017-12-12 20:52:29 -06:00
Saúl Ibarra Corretgé
870e6bbddc feat(overlays): render overlays outside of Conference
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.
2017-12-12 20:52:29 -06:00
Lyubo Marinov
b93bac5aa9 feat(room-lock): hide dialog when conference fails 2017-12-12 20:51:56 -06:00
Saúl Ibarra Corretgé
c86895ae13 feat(room-lock): hide dialog when conference fails 2017-12-12 20:39:25 -06:00
Дамян Минков
e28b847fb0 Updates config feature and whitelists options that can be overridden. (#2282)
* 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.
2017-12-12 11:16:55 -08:00
Saúl Ibarra Corretgé
f6ace61674 doc: document required proguard rules 2017-12-12 10:48:51 -06:00
Saúl Ibarra Corretgé
63d661ad5e ios: remove needless method
We just call the parent class' method, so just get rid of it.
2017-12-12 11:57:18 +01:00
Дамян Минков
e0e2104723 Updates mobile browser page buttons. (#2281) 2017-12-11 15:45:57 -08:00
Lyubo Marinov
6f0b828512 Fix crash caused by "[Android] Handle disposed VideoTrack in WebRTCView" 2017-12-11 14:24:17 -06:00
virtuacoplenny
1984f8d0c0 fix(vertical-filmstrip): scope previous Firefox scroll fixes (#2276)
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.
2017-12-11 11:03:24 -08:00
virtuacoplenny
9b67e796bd ref(analytics): centralize all event names (#2272)
* ref(analytics): centralize all event names

* squash: fix typo and alpha ordering

* squash: rename file to AnalyticsEvents to parallel lib-jitsi-meet
2017-12-11 12:48:32 -06:00
hristoterezov
ee1ec42463 fix(external_api): Request feedback when using the API (#2271) 2017-12-11 09:43:52 -08:00
Saúl Ibarra Corretgé
76fb3b3c63 Merge pull request #2262 from virtuacoplenny/lenny/welcome-page-espanol
fix(welcome-page): fix alignment issues
2017-12-11 10:05:51 +01:00
damencho
b49e600267 Cleanup, removes unused obsolete files. 2017-12-07 11:14:21 -06:00
damencho
5a3f952a2f Uses prosodyctl default inputs. 2017-12-07 11:14:21 -06:00
damencho
3ac41bb0c3 Updates manual install doc with auth.domain certs instructions. 2017-12-07 11:14:21 -06:00
damencho
94813bc0fd Changes owner to prosody of newly created certificates. Fixes #2244. 2017-12-07 11:14:21 -06:00
Leonard Kim
457b4255b9 fix(welcome-page): leverage existing table display to vertical align 2017-12-06 15:55:32 -08:00
Leonard Kim
bed9bd1d5a fix(welcome-page): use inline-block for alignment 2017-12-06 15:51:21 -08:00
jitsi-pootle
0d4dcffbac New files added from translate.jitsi.org based on templates 2017-12-06 16:44:57 +00:00
Lyubo Marinov
a5538adf8a [RN] Add a timeout for loading the configuration 2017-12-05 21:07:15 -06:00
Saúl Ibarra Corretgé
38b645bc27 [RN] Add a timeout for loading the configuration 2017-12-05 17:08:10 -06:00
Saúl Ibarra Corretgé
15bf6b9e30 deps: update React to 16.2.0 2017-12-05 14:38:57 -06:00
damencho
67ac0e8b8a Updates the unsupported mobile browser page. 2017-12-05 09:52:44 -06:00
Leonard Kim
b74b29e8a0 fix(css): load css before js
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.
2017-12-05 08:50:13 -06:00
Leonard Kim
b258a9fc5e ref(css): move aui css to jitsi-meet 2017-12-05 08:50:13 -06:00
Leonard Kim
a653816f90 fix(vertical-filmstrip): prevent shared videos from displaying under avatars
- 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.
2017-12-05 08:45:45 -06:00
Дамян Минков
9ddc5a0e42 Skips empty invites for video rooms. (#2251) 2017-12-04 20:59:28 -08:00
hristoterezov
d79995e14c fix(aot): Toolbar styles (#2252)
Rounded corners on the first and last buttons. Size of the hangup button
on hover.
2017-12-04 20:23:51 -08:00
hristoterezov
5ffcaca649 feat(aot): Handle video not available use cases (#2242) 2017-12-04 19:27:17 -08:00
Leonard Kim
40df5f97d4 fix(vertical-filmstrip): no scrollbars on Firefox from single thumbnail
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...
2017-12-04 21:12:57 -06:00
Leonard Kim
aa93a78372 fix(vertical-filmstrip): allow overflow scrolling on firefox, edge, and ie
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.
2017-12-04 21:12:57 -06:00
Leonard Kim
6b8b929d92 ref(build): remove aui javascript from imports 2017-12-04 16:19:18 -06:00
Leonard Kim
c9b54845d9 ref(settings): convert panel to react
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.
2017-12-04 16:19:18 -06:00
Lyubo Marinov
0eafee2a95 feat(errors): fix error handling for connection and conference 2017-12-04 16:01:28 -06:00
Saúl Ibarra Corretgé
de0d69a20e feat(errors): fix error handling for connection and conference
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.
2017-12-04 15:52:52 -06:00
hristoterezov
eae9ddabad fix(external_api): fire videoConferenceLeft event on unload (#2243) 2017-12-04 10:33:58 -08:00
Lyubo Marinov
569b3547c8 Upgrade NPM dependencies/packages: react-native 0.50 2017-12-04 00:45:18 -06:00
Lyubo Marinov
d8bc26a8ea Upgrade NPM dependencies/packages: ESLint 2017-12-04 00:21:01 -06:00
Lyubo Marinov
61e653a510 Upgrade NPM dependencies/packages 2017-12-04 00:17:35 -06:00
Lyubo Marinov
ac3a74c47e Fix(Android): peerconnection removeStream is not working 2017-11-30 16:49:36 -06:00
Lyubo Marinov
bf7b723891 feat(conference): hide user media permission overlay when tracks are created 2017-11-29 22:47:24 -06:00
Saúl Ibarra Corretgé
4829b86352 feat(conference): hide user media permission overlay when tracks are created
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.
2017-11-29 22:39:15 -06:00
Lyubo Marinov
dda4d7a99e feat(overlays): switch to flow Props 2017-11-29 22:13:24 -06:00
Saúl Ibarra Corretgé
19702671f6 feat(overlays): switch to flow Props 2017-11-29 21:52:39 -06:00
Lyubo Marinov
d88b57d35c webpack & UglifyJS w/ cache & parallel 2017-11-29 13:41:57 -06:00
yanas
a9b8f49995 Add user id to analytics if provided in jwt 2017-11-29 10:36:57 -06:00
Lyubo Marinov
2306e26287 [RN] Fix assigning Dialog state 2017-11-29 10:21:49 -06:00
Saúl Ibarra Corretgé
3633f2aac5 [RN] Fix assigning Dialog state
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!
2017-11-29 10:18:32 -06:00
Saúl Ibarra Corretgé
c320540fa3 Merge pull request #2227 from jitsi/mobile_testing
feat: add more accessibility labels
2017-11-29 15:20:19 +01:00
Lyubo Marinov
75bf7638b3 ref: define state and property types (2) 2017-11-28 22:03:00 -06:00
paweldomas
379bad0ce6 ref: define state and property types 2017-11-28 20:36:02 -06:00
Leonard Kim
2becfd026b fix(device-selection): add proptypes shim for popup
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.
2017-11-28 15:45:56 -06:00
paweldomas
cd48ee3dbf feat: add more accessibility labels
Adds more accessibility labels required for mobile automated testing.
2017-11-28 12:28:37 -06:00
Lyubo Marinov
e4ed02815f Coding style: no runtime-dependent global values 2017-11-27 20:55:45 -06:00
Lyubo Marinov
d1e5e6b93b Coding style: consistency, jsdocs
These modification are not necessarily directly related to the
containing PR, I merely saw them while reviewing the containing PR.
2017-11-27 17:45:17 -06:00
Saúl Ibarra Corretgé
38629b437d feat(overlays): refactor logic for selecting current overlay
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.
2017-11-27 17:45:11 -06:00
Saúl Ibarra Corretgé
d0859b3ce1 feat(conference): store conference errors in redux 2017-11-27 17:45:11 -06:00
Дамян Минков
345fcefa7d On adding participant show the initial status text if any. (#2220)
* 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).
2017-11-27 15:05:53 -08:00
yanas
8e8edb0793 Renames Invite people button to Invite. 2017-11-27 15:21:13 -06:00
virtuacoplenny
4ead402388 spike: feat(notifications): prioritize based on type (appearance) (#2188)
* feat(notifications): prioritize based on type (appearance)

* squash: add return description to doc
2017-11-27 10:47:01 -06:00
Saúl Ibarra Corretgé
c51d351694 Merge pull request #2205 from virtuacoplenny/lenny/progress-bar-react
ref(overlay): convert progress bar to react
2017-11-23 15:35:27 +01:00
Leonard Kim
f0d3abffc5 ref(overlay): convert progress bar to react 2017-11-21 14:45:43 -08:00
511 changed files with 30853 additions and 20174 deletions

View File

@@ -12,21 +12,21 @@
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js
; Ignore polyfills
.*/Libraries/polyfills/.*
; Ignore packages in node_modules which we (i.e. the jitsi-meet project) have
; seen to cause errors and we have chosen not to fix.
.*/node_modules/@atlaskit/.*/*.js.flow
.*/node_modules/@atlassian
.*/node_modules/bower/lib/node_modules/bower-json/test/.*
.*/node_modules/immutable/dist/immutable.js.flow
.*/node_modules/jsonlint/test/.*
; FIXME Remove once we update past this commit:
; FIXME Remove once we update past commit
; https://github.com/facebook/react-native/commit/df8d0d1db9203cc87ad3682e6138b2a9ed714365
.*/node_modules/react-native/local-cli/link/link.js
.*/node_modules/react-native-keep-awake/.*
.*/node_modules/styled-components/.*
@@ -36,21 +36,16 @@
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
node_modules/react-native/flow/
[options]
emoji=true
module.system=haste
; FIXME: munge_underscores should be false but right now there are some errors
; if we change the value to false
; Treats class properties with underscore as private. Disabled because currently
; for us "_" can mean protected too.
; munge_underscores=false
munge_underscores=true
; FIXME Remove once we update past this commit:
; FIXME Remove once we update past commit
; https://github.com/facebook/react-native/commit/df8d0d1db9203cc87ad3682e6138b2a9ed714365
module.name_mapper='^./link/link$' -> 'emptyObject'
@@ -62,11 +57,10 @@ suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-3]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-3]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-7]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-7]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
suppress_comment=\\(.\\|\n\\)*\\$FlowDisableNextLine
unsafe.enable_getters_and_setters=true
@@ -83,4 +77,4 @@ module.file_ext=.jsx
module.file_ext=.json
[version]
^0.53.0
^0.57.0

20
.gitignore vendored
View File

@@ -7,6 +7,9 @@ all.css
.remote-sync.json
.sync-config.cson
# CocoaPods
Pods/
# The following are automatically generated by the react-native command line
# utility (either with the init or upgrade option which pull in the latest
# template files recommended by Facebook for React Native).
@@ -57,14 +60,11 @@ buck-out/
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use
# fastlane to re-generate the screenshots whenever they are needed. For more
# information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
#
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
# CocoaPods
Pods/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots

View File

@@ -21,7 +21,7 @@ license agreement as either a [corporation](https://jitsi.org/ccla) or an
in the agreement, unfortunately, we cannot accept your contribution.
## Creating Pull Requests
- Make sure your code passes the linter rules beforehand. The linter is exeuted
- Make sure your code passes the linter rules beforehand. The linter is executed
automatically when committing code.
- Perform **one** logical change per pull request.
- Maintain a clean list of commits, squash them if necessary.

View File

@@ -33,9 +33,11 @@ deploy-appbundle:
$(BUILD_DIR)/external_api.min.map \
$(BUILD_DIR)/device_selection_popup_bundle.min.js \
$(BUILD_DIR)/device_selection_popup_bundle.min.map \
$(BUILD_DIR)/dial_in_info_bundle.min.js \
$(BUILD_DIR)/dial_in_info_bundle.min.map \
$(BUILD_DIR)/alwaysontop.min.js \
$(BUILD_DIR)/alwaysontop.min.map \
$(OUTPUT_DIR)/analytics.js \
$(OUTPUT_DIR)/analytics-ga.js \
$(DEPLOY_DIR)
deploy-lib-jitsi-meet:
@@ -43,6 +45,7 @@ deploy-lib-jitsi-meet:
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.js \
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.map \
$(LIBJITSIMEET_DIR)/connection_optimization/external_connect.js \
$(LIBJITSIMEET_DIR)/modules/browser/capabilities.json \
$(DEPLOY_DIR)
deploy-css:

View File

@@ -1,13 +1,15 @@
# 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. You can see Jitsi Meet in action [here at the session #482 of the VoIP Users Conference](http://youtu.be/7vFUVClsNh0).
You can also try it out yourself at https://meet.jit.si .
The Jitsi Meet client runs in your browser, without the need for installing anything on your computer. You can also try it out yourself 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.
## Installation
On the client side, no installation is necessary. You just point your browser to the URL of your deployment. This section is about installing the Jitsi Meet suite on your server and hosting your own conferencing service.
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.
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).
@@ -88,6 +90,19 @@ cd jitsi-meet
npm unlink lib-jitsi-meet
npm install
```
## Running with webpack-dev-server for development
Use it at the CLI, type
```
node_modules/.bin/webpack-dev-server
```
By default the backend deployment used is `beta.meet.jit.si`, you can point the Jitsi-Meet app at a different backend by using a proxy server. To do this set the WEBPACK_DEV_SERVER_PROXY_TARGET variable, type
```
WEBPACK_DEV_SERVER_PROXY_TARGET=https://your-example-server.com node_modules/.bin/webpack-dev-server
```
The app should be running at https://localhost:8080/
## Contributing
@@ -98,6 +113,21 @@ see our [guidelines for contributing](CONTRIBUTING.md).
Jitsi Meet provides a very flexible way of embedding it in external applications by using the [Jitsi Meet API](doc/api.md).
## Security
WebRTC today does not provide a way of conducting multiparty conversations with
end-to-end encryption. As a matter of fact, unless you consistently vocally
compare DTLS fingerprints with your peers, the same goes for one-to-one calls.
As a result when using a Jitsi Meet instance, your stream is encrypted on the
network but decrypted on the machine that hosts the bridge.
The Jitsi Meet architecture allows you to deploy your own version, including
all server components, and in that case your security guarantees will be roughly
equivalent to these of a direct one-to-one WebRTC call. This is what's unique to
Jitsi Meet in terms of security.
The [meet.jit.si](https://meet.jit.si) service is maintained by the Jitsi team
at [Atlassian](https://atlassian.com).
## 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).

154
analytics-ga.js Normal file
View File

@@ -0,0 +1,154 @@
/* global ga */
(function(ctx) {
/**
*
*/
function Analytics(options) {
/* eslint-disable */
if (!options.googleAnalyticsTrackingId) {
console.log(
'Failed to initialize Google Analytics handler, no tracking ID');
return;
}
/**
* Google Analytics
* TODO: Keep this local, there's no need to add it to window.
*/
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', options.googleAnalyticsTrackingId, 'jit.si');
ga('send', 'pageview');
/* eslint-enable */
}
/**
* Extracts the integer to use for a Google Analytics event's value field
* from a lib-jitsi-meet analytics event.
* @param {Object} event - The lib-jitsi-meet analytics event.
* @returns {Object} - The integer to use for the 'value' of a Google
* Analytics event.
* @private
*/
Analytics.prototype._extractAction = function(event) {
// Page events have a single 'name' field.
if (event.type === 'page') {
return event.name;
}
// All other events have action, actionSubject, and source fields. All
// three fields are required, and the often jitsi-meet and
// lib-jitsi-meet use the same value when separate values are not
// necessary (i.e. event.action == event.actionSubject).
// Here we concatenate these three fields, but avoid adding the same
// value twice, because it would only make the GA event's action harder
// to read.
let action = event.action;
if (event.actionSubject && event.actionSubject !== event.action) {
// Intentionally use string concatenation as analytics needs to
// work on IE but this file does not go through babel. For some
// reason disabling this globally for the file does not have an
// effect.
// eslint-disable-next-line prefer-template
action = event.actionSubject + '.' + action;
}
if (event.source && event.source !== event.action
&& event.source !== event.action) {
// eslint-disable-next-line prefer-template
action = event.source + '.' + action;
}
return action;
};
/**
* Extracts the integer to use for a Google Analytics event's value field
* from a lib-jitsi-meet analytics event.
* @param {Object} event - The lib-jitsi-meet analytics event.
* @returns {Object} - The integer to use for the 'value' of a Google
* Analytics event, or NaN if the lib-jitsi-meet event doesn't contain a
* suitable value.
* @private
*/
Analytics.prototype._extractValue = function(event) {
let value = event && event.attributes && event.attributes.value;
// Try to extract an integer from the "value" attribute.
value = Math.round(parseFloat(value));
return value;
};
/**
* Extracts the string to use for a Google Analytics event's label field
* from a lib-jitsi-meet analytics event.
* @param {Object} event - The lib-jitsi-meet analytics event.
* @returns {string} - The string to use for the 'label' of a Google
* Analytics event.
* @private
*/
Analytics.prototype._extractLabel = function(event) {
let label = '';
// The label field is limited to 500B. We will concatenate all
// attributes of the event, except the user agent because it may be
// lengthy and is probably included from elsewhere.
for (const property in event.attributes) {
if (property !== 'permanent_user_agent'
&& property !== 'permanent_callstats_name'
&& event.attributes.hasOwnProperty(property)) {
// eslint-disable-next-line prefer-template
label += property + '=' + event.attributes[property] + '&';
}
}
if (label.length > 0) {
label = label.slice(0, -1);
}
return label;
};
/**
* This is the entry point of the API. The function sends an event to
* google analytics. The format of the event is described in
* AnalyticsAdapter in lib-jitsi-meet.
* @param {Object} event - the event in the format specified by
* lib-jitsi-meet.
*/
Analytics.prototype.sendEvent = function(event) {
if (!event || !ga) {
return;
}
const gaEvent = {
'eventCategory': 'jitsi-meet',
'eventAction': this._extractAction(event),
'eventLabel': this._extractLabel(event)
};
const value = this._extractValue(event);
if (!isNaN(value)) {
gaEvent.eventValue = value;
}
ga('send', 'event', gaEvent);
};
if (typeof ctx.JitsiMeetJS === 'undefined') {
ctx.JitsiMeetJS = {};
}
if (typeof ctx.JitsiMeetJS.app === 'undefined') {
ctx.JitsiMeetJS.app = {};
}
if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === 'undefined') {
ctx.JitsiMeetJS.app.analyticsHandlers = [];
}
ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);
})(window);
/* eslint-enable prefer-template */

View File

@@ -1,47 +0,0 @@
/* global ga */
(function(ctx) {
/**
*
*/
function Analytics() {
/* eslint-disable */
/**
* Google Analytics
*/
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-319188-14', 'jit.si');
ga('send', 'pageview');
/* eslint-enable */
}
Analytics.prototype.sendEvent = function(action, data) {
// empty label if missing value for it and add the value,
// the value should be integer or null
let value = data.value;
value = value ? Math.round(parseFloat(value)) : null;
const label = data.label || '';
// Intentionally use string concatenation as analytics needs to work on
// IE but this file does not go through babel.
// eslint-disable-next-line prefer-template
ga('send', 'event', 'jit.si', action + '.' + data.browserName,
label, value);
};
if (typeof ctx.JitsiMeetJS === 'undefined') {
ctx.JitsiMeetJS = {};
}
if (typeof ctx.JitsiMeetJS.app === 'undefined') {
ctx.JitsiMeetJS.app = {};
}
if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === 'undefined') {
ctx.JitsiMeetJS.app.analyticsHandlers = [];
}
ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);
})(window);

View File

@@ -16,7 +16,7 @@
`"file:${rootProject.projectDir}/../../../jitsi/jitsi-maven-repository/releases"`
in android/build.gradle for the third-party react-native modules which Jitsi
Meet SDK for Android depends on and are not publicly available in Maven
repositories. Generally, if you are modifying the JavaSource code of Jitsi
repositories. Generally, if you are modifying the JavaScript code of Jitsi
Meet SDK for Android only, you will very likely need to consider the former
only.
@@ -107,19 +107,19 @@ public class MainActivity extends AppCompatActivity {
JitsiMeetView.onNewIntent(intent);
}
@Override
protected void onPause() {
super.onPause();
JitsiMeetView.onHostPause(this);
}
@Override
protected void onResume() {
super.onResume();
JitsiMeetView.onHostResume(this);
}
@Override
protected void onStop() {
super.onStop();
JitsiMeetView.onHostPause(this);
}
}
```
@@ -132,6 +132,10 @@ which displays a single `JitsiMeetView`.
See JitsiMeetView.getDefaultURL.
#### getPictureInPictureEnabled()
See JitsiMeetView.getPictureInPictureEnabled.
#### getWelcomePageEnabled()
See JitsiMeetView.getWelcomePageEnabled.
@@ -144,6 +148,10 @@ See JitsiMeetView.loadURL.
See JitsiMeetView.setDefaultURL.
#### setPictureInPictureEnabled(boolean)
See JitsiMeetView.setPictureInPictureEnabled.
#### setWelcomePageEnabled(boolean)
See JitsiMeetView.setWelcomePageEnabled.
@@ -169,6 +177,12 @@ if set to `null`, the default built in JavaScript is used: https://meet.jit.si.
Returns the `JitsiMeetViewListener` instance attached to the view.
#### getPictureInPictureEnabled()
Returns `true` if Picture-in-Picture is enabled; `false`, otherwise. If not
explicitly set (by a preceding `setPictureInPictureEnabled` call), defaults to
`true` if the platform supports Picture-in-Picture natively; `false`, otherwise.
#### getWelcomePageEnabled()
Returns true if the Welcome page is enabled; otherwise, false. If false, a black
@@ -210,19 +224,30 @@ view.loadURLObject(urlObject);
Sets the default URL. See `getDefaultURL` for more information.
NOTE: Must be called before `loadURL`/`loadURLString` for it to take effect.
NOTE: Must be called before (if at all) `loadURL`/`loadURLString` for it to take
effect.
#### setListener(listener)
Sets the given listener (class implementing the `JitsiMeetViewListener`
interface) on the view.
#### setPictureInPictureEnabled(boolean)
Sets whether Picture-in-Picture is enabled. If not set, Jitsi Meet SDK
automatically enables/disables Picture-in-Picture based on native platform
support.
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take
effect.
#### setWelcomePageEnabled(boolean)
Sets whether the Welcome page is enabled. See `getWelcomePageEnabled` for more
information.
NOTE: Must be called before `loadURL`/`loadURLString` for it to take effect.
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take
effect.
#### onBackPressed()
@@ -247,7 +272,8 @@ This is a static method.
#### onHostResume(activity)
Helper method which should be called from the activity's `onResume` method.
Helper method which should be called from the activity's `onResume` or `onStop`
method.
This is a static method.
@@ -259,6 +285,13 @@ activity's `onNewIntent` method.
This is a static method.
#### onUserLeaveHint()
Helper method for integrating automatic Picture-in-Picture. It should be called
from the activity's `onUserLeaveHint` method.
This is a static method.
#### JitsiMeetViewListener
`JitsiMeetViewListener` provides an interface apps can implement to listen to
@@ -309,3 +342,79 @@ fails.
The `data` `Map` contains an "error" key with the error and a "url" key with the
conference URL which necessitated the loading of the configuration file.
## ProGuard rules
When using the SDK on a project some proguard rules have to be added in order
to avoid necessary code being stripped. Add the following to your project's
rules file:
```
# React Native
# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.proguard.annotations.DoNotStrip class *
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.proguard.annotations.DoNotStrip *;
@com.facebook.common.internal.DoNotStrip *;
}
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
void set*(***);
*** get*();
}
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
-dontwarn com.facebook.react.**
# TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
-dontwarn android.text.StaticLayout
# okhttp
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
# okio
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
# WebRTC
-keep class org.webrtc.** { *; }
-dontwarn org.chromium.build.BuildHooksAndroid
# Jisti Meet SDK
-keep class org.jitsi.meet.sdk.** { *; }
```
## Picture-in-Picture
`JitsiMeetView` will automatically adjust its UI when presented in a
Picture-in-Picture style scenario, in a rectangle too small to accommodate its
"full" UI.
Jitsi Meet SDK automatically enables (unless explicitly disabled by a
`setPictureInPictureEnabled(false)` call) Android's native Picture-in-Picture
mode iff the platform is supported i.e. Android >= Oreo.

View File

@@ -50,6 +50,10 @@
-dontwarn com.facebook.react.**
# TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
-dontwarn android.text.StaticLayout
# okhttp
-keepattributes Signature

View File

@@ -7,10 +7,12 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
android:label="@string/app_name"
android:launchMode="singleTask"
android:name=".MainActivity"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@@ -23,6 +23,8 @@ import org.jitsi.meet.sdk.JitsiMeetActivity;
import org.jitsi.meet.sdk.JitsiMeetView;
import org.jitsi.meet.sdk.JitsiMeetViewListener;
import com.calendarevents.CalendarEventsPackage;
import java.util.Map;
/**
@@ -95,11 +97,18 @@ public class MainActivity extends JitsiMeetActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// As this is the Jitsi Meet app (i.e. not the Jitsi Meet SDK), we do
// want the Welcome page to be enabled. It defaults to disabled in the
// SDK at the time of this writing but it is clearer to be explicit
// about what we want anyway.
// want to enable some options.
// The welcome page defaults to disabled in the SDK at the time of this
// writing but it is clearer to be explicit about what we want anyway.
setWelcomePageEnabled(true);
super.onCreate(savedInstanceState);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
CalendarEventsPackage.onRequestPermissionsResult(requestCode, permissions, grantResults);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

View File

@@ -2,6 +2,5 @@
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>

View File

@@ -3,11 +3,11 @@
buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.google.com' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files.
@@ -16,9 +16,8 @@ buildscript {
allprojects {
repositories {
mavenLocal()
google()
jcenter()
maven { url "https://maven.google.com" } // Required for appcompat.
// React Native (JS, Obj-C sources, Android binaries) is installed from
// npm.
maven { url "$rootDir/../node_modules/react-native/android" }
@@ -133,7 +132,7 @@ ext {
buildToolsVersion = "26.0.2"
compileSdkVersion = 26
minSdkVersion = 16
targetSdkVersion = 25
targetSdkVersion = 26
// The Maven artifact groupdId of the third-party react-native modules which
// Jitsi Meet SDK for Android depends on and which are not available in

View File

@@ -1,8 +1,8 @@
keystore(
name = 'debug',
store = 'debug.keystore',
properties = 'debug.keystore.properties',
visibility = [
'PUBLIC',
],
name = "debug",
properties = "debug.keystore.properties",
store = "debug.keystore",
visibility = [
"PUBLIC",
],
)

View File

@@ -21,15 +21,18 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:appcompat-v7:27.0.2'
compile 'com.facebook.react:react-native:+'
compile project(':react-native-background-timer')
compile project(':react-native-fetch-blob')
compile project(':react-native-immersive')
compile project(':react-native-keep-awake')
compile project(':react-native-locale-detector')
compile project(':react-native-sound')
compile project(':react-native-vector-icons')
compile project(':react-native-webrtc')
compile project(':react-native-calendar-events')
}
// Build process helpers

View File

@@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature

View File

@@ -5,11 +5,13 @@
package org.jitsi.meet.sdk;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
@@ -25,7 +27,7 @@ class AndroidSettingsModule extends ReactContextBaseJavaModule {
}
@ReactMethod
public void open() {
public void open(Promise promise) {
Context context = getReactApplicationContext();
Intent intent = new Intent();
@@ -34,6 +36,15 @@ class AndroidSettingsModule extends ReactContextBaseJavaModule {
intent.setData(
Uri.fromParts("package", context.getPackageName(), null));
context.startActivity(intent);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
// Some devices may give an error here.
// https://developer.android.com/reference/android/provider/Settings.html#ACTION_APPLICATION_DETAILS_SETTINGS
promise.reject(e);
return;
}
promise.resolve(null);
}
}

View File

@@ -17,31 +17,32 @@
package org.jitsi.meet.sdk;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import java.net.URL;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
/**
* Base Activity for applications integrating Jitsi Meet at a higher level. It
* contains all the required wiring between the {@code JKConferenceView} and
* contains all the required wiring between the {@code JitsiMeetView} and
* the Activity lifecycle methods already implemented.
*
* In this activity we use a single {@code JKConferenceView} instance. This
* In this activity we use a single {@code JitsiMeetView} instance. This
* instance gives us access to a view which displays the welcome page and the
* conference itself. All lifetime methods associated with this Activity are
* hooked to the React Native subsystem via proxy calls through the
* {@code JKConferenceView} static methods.
* {@code JitsiMeetView} static methods.
*/
public class JitsiMeetActivity
extends AppCompatActivity {
public class JitsiMeetActivity extends AppCompatActivity {
/**
* The request code identifying requests for the permission to draw on top
* of other apps. The value must be 16-bit and is arbitrarily chosen here.
@@ -67,6 +68,12 @@ public class JitsiMeetActivity
*/
private JitsiMeetView view;
/**
* Whether Picture-in-Picture is enabled. The value is used only while
* {@link #view} equals {@code null}.
*/
private Boolean pictureInPictureEnabled;
/**
* Whether the Welcome page is enabled. The value is used only while
* {@link #view} equals {@code null}.
@@ -89,6 +96,17 @@ public class JitsiMeetActivity
return view == null ? defaultURL : view.getDefaultURL();
}
/**
*
* @see JitsiMeetView#getPictureInPictureEnabled()
*/
public boolean getPictureInPictureEnabled() {
return
view == null
? pictureInPictureEnabled
: view.getPictureInPictureEnabled();
}
/**
*
* @see JitsiMeetView#getWelcomePageEnabled()
@@ -121,6 +139,10 @@ public class JitsiMeetActivity
// XXX Before calling JitsiMeetView#loadURL, make sure to call whatever
// is documented to need such an order in order to take effect:
view.setDefaultURL(defaultURL);
if (pictureInPictureEnabled != null) {
view.setPictureInPictureEnabled(
pictureInPictureEnabled.booleanValue());
}
view.setWelcomePageEnabled(welcomePageEnabled);
view.loadURL(null);
@@ -199,17 +221,26 @@ public class JitsiMeetActivity
JitsiMeetView.onHostDestroy(this);
}
// ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java
@Override
public void onNewIntent(Intent intent) {
JitsiMeetView.onNewIntent(intent);
public boolean onKeyUp(int keyCode, KeyEvent event) {
ReactInstanceManager reactInstanceManager;
if (!super.onKeyUp(keyCode, event)
&& BuildConfig.DEBUG
&& (reactInstanceManager
= JitsiMeetView.getReactInstanceManager())
!= null
&& keyCode == KeyEvent.KEYCODE_MENU) {
reactInstanceManager.showDevOptionsDialog();
return true;
}
return false;
}
@Override
protected void onPause() {
super.onPause();
JitsiMeetView.onHostPause(this);
defaultBackButtonImpl = null;
public void onNewIntent(Intent intent) {
JitsiMeetView.onNewIntent(intent);
}
@Override
@@ -220,6 +251,19 @@ public class JitsiMeetActivity
JitsiMeetView.onHostResume(this, defaultBackButtonImpl);
}
@Override
public void onStop() {
super.onStop();
JitsiMeetView.onHostPause(this);
defaultBackButtonImpl = null;
}
@Override
protected void onUserLeaveHint() {
JitsiMeetView.onUserLeaveHint();
}
/**
*
* @see JitsiMeetView#setDefaultURL(URL)
@@ -232,6 +276,19 @@ public class JitsiMeetActivity
}
}
/**
*
* @see JitsiMeetView#setPictureInPictureEnabled(boolean)
*/
public void setPictureInPictureEnabled(boolean pictureInPictureEnabled) {
if (view == null) {
this.pictureInPictureEnabled
= Boolean.valueOf(pictureInPictureEnabled);
} else {
view.setPictureInPictureEnabled(pictureInPictureEnabled);
}
}
/**
*
* @see JitsiMeetView#setWelcomePageEnabled(boolean)

View File

@@ -21,17 +21,23 @@ import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.FrameLayout;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.rnimmersive.RNImmersiveModule;
import java.net.URL;
import java.util.Arrays;
@@ -48,6 +54,12 @@ public class JitsiMeetView extends FrameLayout {
*/
private static final int BACKGROUND_COLOR = 0xFF111111;
/**
* The {@link Log} tag which identifies the source of the log messages of
* {@code JitsiMeetView}.
*/
private final static String TAG = JitsiMeetView.class.getSimpleName();
/**
* React Native bridge. The instance manager allows embedding applications
* to create multiple root views off the same JavaScript bundle.
@@ -64,7 +76,9 @@ public class JitsiMeetView extends FrameLayout {
new AppInfoModule(reactContext),
new AudioModeModule(reactContext),
new ExternalAPIModule(reactContext),
new ProximityModule(reactContext)
new PictureInPictureModule(reactContext),
new ProximityModule(reactContext),
new WiFiStatsModule(reactContext)
);
}
@@ -81,6 +95,11 @@ public class JitsiMeetView extends FrameLayout {
return null;
}
// XXX Strictly internal use only (at the time of this writing)!
static ReactInstanceManager getReactInstanceManager() {
return reactInstanceManager;
}
/**
* Internal method to initialize the React Native instance manager. We
* create a single instance in order to load the JavaScript bundle a single
@@ -95,13 +114,16 @@ public class JitsiMeetView extends FrameLayout {
.setApplication(application)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index.android")
.addPackage(new com.calendarevents.CalendarEventsPackage())
.addPackage(new com.corbt.keepawake.KCKeepAwakePackage())
.addPackage(new com.facebook.react.shell.MainReactPackage())
.addPackage(new com.i18n.reactnativei18n.ReactNativeI18n())
.addPackage(new com.oblador.vectoricons.VectorIconsPackage())
.addPackage(new com.ocetnik.timer.BackgroundTimerPackage())
.addPackage(new com.oney.WebRTCModule.WebRTCModulePackage())
.addPackage(new com.RNFetchBlob.RNFetchBlobPackage())
.addPackage(new com.rnimmersive.RNImmersivePackage())
.addPackage(new com.zmxv.RNSound.RNSoundPackage())
.addPackage(new ReactPackageAdapter() {
@Override
public List<NativeModule> createNativeModules(
@@ -235,6 +257,38 @@ public class JitsiMeetView extends FrameLayout {
}
}
/**
* Activity lifecycle method which should be called from
* {@code Activity.onUserLeaveHint} so we can do the required internal
* processing.
*
* This is currently not mandatory.
*/
public static void onUserLeaveHint() {
sendEvent("onUserLeaveHint", null);
}
/**
* Helper function to send an event to JavaScript.
*
* @param eventName {@code String} containing the event name.
* @param params {@code WritableMap} optional ancillary data for the event.
*/
private static void sendEvent(
String eventName,
@Nullable WritableMap params) {
if (reactInstanceManager != null) {
ReactContext reactContext
= reactInstanceManager.getCurrentReactContext();
if (reactContext != null) {
reactContext
.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
}
/**
* The default base {@code URL} used to join a conference when a partial URL
* (e.g. a room name only) is specified to {@link #loadURLString(String)} or
@@ -256,6 +310,13 @@ public class JitsiMeetView extends FrameLayout {
*/
private JitsiMeetViewListener listener;
/**
* Whether Picture-in-Picture is enabled. If {@code null}, defaults to
* {@code true} iff the Android platform supports Picture-in-Picture
* natively.
*/
private Boolean pictureInPictureEnabled;
/**
* React Native root view.
*/
@@ -320,6 +381,21 @@ public class JitsiMeetView extends FrameLayout {
return listener;
}
/**
* Gets whether Picture-in-Picture is enabled. Picture-in-Picture is
* natively supported on Android API >= 26 (Oreo), so it should not be
* enabled on older platform versions.
*
* @return If Picture-in-Picture is enabled, {@code true}; {@code false},
* otherwise.
*/
public boolean getPictureInPictureEnabled() {
return
PictureInPictureModule.isPictureInPictureSupported()
&& (pictureInPictureEnabled == null
|| pictureInPictureEnabled.booleanValue());
}
/**
* Gets whether the Welcome page is enabled. If {@code true}, the Welcome
* page is rendered when this {@code JitsiMeetView} is not at a URL
@@ -361,12 +437,20 @@ public class JitsiMeetView extends FrameLayout {
if (defaultURL != null) {
props.putString("defaultURL", defaultURL.toString());
}
// externalAPIScope
props.putString("externalAPIScope", externalAPIScope);
// pictureInPictureEnabled
props.putBoolean(
"pictureInPictureEnabled",
getPictureInPictureEnabled());
// url
if (urlObject != null) {
props.putBundle("url", urlObject);
}
// welcomePageEnabled
props.putBoolean("welcomePageEnabled", welcomePageEnabled);
@@ -384,7 +468,9 @@ public class JitsiMeetView extends FrameLayout {
if (reactRootView == null) {
reactRootView = new ReactRootView(getContext());
reactRootView.startReactApplication(
reactInstanceManager, "App", props);
reactInstanceManager,
"App",
props);
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
addView(reactRootView);
} else {
@@ -412,6 +498,43 @@ public class JitsiMeetView extends FrameLayout {
loadURLObject(urlObject);
}
/**
* Called when the window containing this view gains or loses focus.
*
* @param hasFocus If the window of this view now has focus, {@code true};
* otherwise, {@code false}.
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
// FIXME The singleton pattern employed by RNImmersiveModule is not
// advisable because a react-native mobule is consumable only after its
// BaseJavaModule#initialize() has completed and here we have no
// knowledge of whether the precondition is really met.
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
if (hasFocus && immersive != null) {
try {
immersive.emitImmersiveStateChangeEvent();
} catch (RuntimeException re) {
// FIXME I don't know how to check myself whether
// BaseJavaModule#initialize() has been invoked and thus
// RNImmersiveModule is consumable. A safe workaround is to
// swallow the failure because the whole full-screen/immersive
// functionality is brittle anyway, akin to the icing on the
// cake, and has been working without onWindowFocusChanged for a
// very long time.
Log.e(
TAG,
"RNImmersiveModule#emitImmersiveStateChangeEvent() failed!",
re);
}
}
}
/**
* Sets the default base {@code URL} used to join a conference when a
* partial URL (e.g. a room name only) is specified to
@@ -436,6 +559,18 @@ public class JitsiMeetView extends FrameLayout {
this.listener = listener;
}
/**
* Sets whether Picture-in-Picture is enabled. Because Picture-in-Picture is
* natively supported only since certain platform versions, specifying
* {@code true} will have no effect on unsupported platform versions.
*
* @param pictureInPictureEnabled To enable Picture-in-Picture,
* {@code true}; otherwise, {@code false}.
*/
public void setPictureInPictureEnabled(boolean pictureInPictureEnabled) {
this.pictureInPictureEnabled = Boolean.valueOf(pictureInPictureEnabled);
}
/**
* Sets whether the Welcome page is enabled. Must be called before
* {@link #loadURL(URL)} for it to take effect.

View File

@@ -0,0 +1,67 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.app.PictureInPictureParams;
import android.os.Build;
import android.util.Log;
import android.util.Rational;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class PictureInPictureModule extends ReactContextBaseJavaModule {
private final static String TAG = "PictureInPicture";
static boolean isPictureInPictureSupported() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
}
public PictureInPictureModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* Enters Picture-in-Picture (mode) for the current {@link Activity}.
* Supported on Android API >= 26 (Oreo) only.
*
* @param promise a {@code Promise} which will resolve with a {@code null}
* value upon success, and an {@link Exception} otherwise.
*/
@ReactMethod
public void enterPictureInPicture(Promise promise) {
if (isPictureInPictureSupported()) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
promise.reject(new Exception("No current Activity!"));
return;
}
Log.d(TAG, "Entering Picture-in-Picture");
PictureInPictureParams.Builder builder
= new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(1, 1));
boolean r
= currentActivity.enterPictureInPictureMode(builder.build());
if (r) {
promise.resolve(null);
} else {
promise.reject(
new Exception("Failed to enter Picture-in-Picture"));
}
return;
}
promise.reject(new Exception("Picture-in-Picture not supported"));
}
@Override
public String getName() {
return TAG;
}
}

View File

@@ -0,0 +1,208 @@
/*
* Copyright @ 2017-present Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.meet.sdk;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import org.json.JSONArray;
import org.json.JSONObject;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
/**
* Module exposing WiFi statistics.
*
* Gathers rssi, signal in percentage, timestamp and the addresses
* of the wifi device.
*/
class WiFiStatsModule extends ReactContextBaseJavaModule {
/**
* The name of {@code WiFiStatsModule} to be used in the React Native
* bridge.
*/
private static final String MODULE_NAME = "WiFiStats";
/**
* The {@code Log} tag {@code WiFiStatsModule} is to log messages with.
*/
static final String TAG = MODULE_NAME;
/**
* The scale used for the signal value.
* A level of the signal, given in the range
* of 0 to SIGNAL_LEVEL_SCALE-1 (both inclusive).
*/
public final static int SIGNAL_LEVEL_SCALE = 101;
/**
* {@link Handler} for running all operations on the main thread.
*/
private final Handler mainThreadHandler
= new Handler(Looper.getMainLooper());
/**
* Initializes a new module instance. There shall be a single instance of
* this module throughout the lifetime of the application.
*
* @param reactContext the {@link ReactApplicationContext} where this module
* is created.
*/
public WiFiStatsModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* Gets the name for this module to be used in the React Native bridge.
*
* @return a string with the module name.
*/
@Override
public String getName() {
return MODULE_NAME;
}
/**
* Returns the {@link InetAddress} represented by this int.
*
* @param value the int representation of the ip address.
* @return the {@link InetAddress}.
* @throws UnknownHostException - if IP address is of illegal length.
*/
public static InetAddress toInetAddress(int value)
throws UnknownHostException {
return InetAddress.getByAddress(
new byte[] {
(byte) value,
(byte) (value >> 8),
(byte) (value >> 16),
(byte) (value >> 24)
});
}
/**
* Public method to retrieve WiFi stats.
*
* @param promise a {@link Promise} which will be resolved if WiFi stats are
* retrieved successfully, and it will be rejected otherwise.
*/
@ReactMethod
public void getWiFiStats(final Promise promise) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
Context context
= getReactApplicationContext().getApplicationContext();
WifiManager wifiManager
= (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
promise.reject(new Exception("Wifi not enabled"));
return;
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo.getNetworkId() == -1) {
promise.reject(new Exception("Wifi not connected"));
return;
}
int rssi = wifiInfo.getRssi();
int signalLevel
= WifiManager.calculateSignalLevel(
rssi, SIGNAL_LEVEL_SCALE);
JSONObject result = new JSONObject();
result.put("rssi", rssi)
.put("signal", signalLevel)
.put("timestamp",
String.valueOf(System.currentTimeMillis()));
JSONArray addresses = new JSONArray();
InetAddress wifiAddress
= toInetAddress(wifiInfo.getIpAddress());
try {
Enumeration<NetworkInterface> e
= NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
NetworkInterface networkInterface = e.nextElement();
boolean found = false;
// first check whether this is the desired interface
Enumeration<InetAddress> as
= networkInterface.getInetAddresses();
while (as.hasMoreElements()) {
InetAddress a = as.nextElement();
if(a.equals(wifiAddress)) {
found = true;
break;
}
}
if (found) {
// interface found let's put addresses
// to the result object
as = networkInterface.getInetAddresses();
while (as.hasMoreElements()) {
InetAddress a = as.nextElement();
if (a.isLinkLocalAddress())
continue;
addresses.put(a.getHostAddress());
}
}
}
} catch (SocketException e) {
Log.wtf(TAG,
"Unable to NetworkInterface.getNetworkInterfaces()"
);
}
result.put("addresses", addresses);
promise.resolve(result.toString());
Log.d(TAG, "WiFi stats: " + result.toString());
} catch (Throwable e) {
Log.e(TAG, "Failed to obtain wifi stats", e);
promise.reject(
new Exception("Failed to obtain wifi stats"));
}
}
};
mainThreadHandler.post(r);
}
}

View File

@@ -9,7 +9,13 @@ include ':react-native-immersive'
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
include ':react-native-keep-awake'
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
include ':react-native-locale-detector'
project(':react-native-locale-detector').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-locale-detector/android')
include ':react-native-sound'
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':react-native-webrtc'
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
include ':react-native-calendar-events'
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')

5
app.js
View File

@@ -11,11 +11,6 @@ import 'jquery-contextmenu';
import 'jQuery-Impromptu';
import 'autosize';
import 'aui';
import 'aui-experimental';
import 'aui-css';
import 'aui-experimental-css';
import conference from './conference';
import API from './modules/API';
import keyboardshortcut from './modules/keyboardshortcut/keyboardshortcut';

View File

@@ -7,7 +7,7 @@ import Recorder from './modules/recorder/Recorder';
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
import { reload, reportError } from './modules/util/helpers';
import { reportError } from './modules/util/helpers';
import * as RemoteControlEvents
from './service/remotecontrol/RemoteControlEvents';
@@ -15,7 +15,19 @@ import UIEvents from './service/UI/UIEvents';
import UIUtil from './modules/UI/util/UIUtil';
import * as JitsiMeetConferenceEvents from './ConferenceEvents';
import { initAnalytics, sendAnalyticsEvent } from './react/features/analytics';
import {
createDeviceChangedEvent,
createScreenSharingEvent,
createSelectParticipantFailedEvent,
createStreamSwitchDelayEvent,
createTrackMutedEvent,
initAnalytics,
sendAnalytics
} from './react/features/analytics';
import {
redirectWithStoredParams,
reloadWithStoredParams
} from './react/features/app';
import EventEmitter from 'events';
@@ -29,6 +41,7 @@ import {
dataChannelOpened,
EMAIL_COMMAND,
lockStateChanged,
onStartMutedPolicyChanged,
p2pStatusChanged,
sendLocalParticipant
} from './react/features/base/conference';
@@ -53,8 +66,10 @@ import {
setVideoAvailable,
setVideoMuted
} from './react/features/base/media';
import { showNotification } from './react/features/notifications';
import {
dominantSpeakerChanged,
getAvatarURLByParticipantId,
getLocalParticipant,
getParticipantById,
localParticipantConnectionStatusChanged,
@@ -74,10 +89,17 @@ import {
trackAdded,
trackRemoved
} from './react/features/base/tracks';
import { getLocationContextRoot } from './react/features/base/util';
import {
getLocationContextRoot,
getJitsiMeetGlobalNS
} from './react/features/base/util';
import { statsEmitter } from './react/features/connection-indicator';
import { showDesktopPicker } from './react/features/desktop-picker';
import { maybeOpenFeedbackDialog } from './react/features/feedback';
import { appendSuffix } from './react/features/display-name';
import {
maybeOpenFeedbackDialog,
submitFeedback
} from './react/features/feedback';
import {
mediaPermissionPromptVisibilityChanged,
suspendDetected
@@ -186,7 +208,7 @@ function muteLocalVideo(muted) {
*
* @param {object} options used to decide which particular close page to show
* or if close page is disabled, whether we should show the thankyou dialog
* @param {boolean} options.thankYouDialogVisible - whether we should
* @param {boolean} options.showThankYou - whether we should
* show thank you dialog
* @param {boolean} options.feedbackSubmitted - whether feedback was submitted
*/
@@ -198,24 +220,25 @@ function maybeRedirectToWelcomePage(options) {
// save whether current user is guest or not, before navigating
// to close page
window.sessionStorage.setItem('guest', isGuest);
assignWindowLocationPathname(`static/${
redirectToStaticPage(`static/${
options.feedbackSubmitted ? 'close.html' : 'close2.html'}`);
return;
}
// else: show thankYou dialog only if there is no feedback
if (options.thankYouDialogVisible) {
APP.UI.messageHandler.openMessageDialog(
null, 'dialog.thankYou', { appName: interfaceConfig.APP_NAME });
if (options.showThankYou) {
APP.store.dispatch(showNotification({
titleArguments: { appName: interfaceConfig.APP_NAME },
titleKey: 'dialog.thankYou'
}));
}
// if Welcome page is enabled redirect to welcome page after 3 sec.
if (config.enableWelcomePage) {
setTimeout(
() => {
APP.settings.setWelcomePageEnabled(true);
assignWindowLocationPathname('./');
APP.store.dispatch(redirectWithStoredParams('/'));
},
3000);
}
@@ -231,7 +254,7 @@ function maybeRedirectToWelcomePage(options) {
* assigning it to window.location.pathname.
* @return {void}
*/
function assignWindowLocationPathname(pathname) {
function redirectToStaticPage(pathname) {
const windowLocation = window.location;
let newPathname = pathname;
@@ -291,7 +314,7 @@ class ConferenceConnector {
case JitsiConferenceErrors.NOT_ALLOWED_ERROR: {
// let's show some auth not allowed page
assignWindowLocationPathname('static/authError.html');
redirectToStaticPage('static/authError.html');
break;
}
@@ -359,7 +382,7 @@ class ConferenceConnector {
break;
case JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
reload();
APP.store.dispatch(reloadWithStoredParams());
break;
default:
@@ -632,11 +655,16 @@ export default {
});
}
// Hide the permissions prompt/overlay as soon as the tracks are
// created. 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.
tryCreateLocalTracks.then(() =>
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false)));
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
.then(([ tracks, con ]) => {
APP.store.dispatch(
mediaPermissionPromptVisibilityChanged(false));
// FIXME If there will be microphone error it will cover any
// screensharing dialog, but it's still better than in
// the reverse order where the screensharing dialog will
@@ -716,14 +744,13 @@ export default {
})
.then(([ tracks, con ]) => {
tracks.forEach(track => {
if (track.isAudioTrack() && this.isLocalAudioMuted()) {
sendAnalyticsEvent('conference.audio.initiallyMuted');
logger.log('Audio mute: initially muted');
track.mute();
} else if (track.isVideoTrack()
&& this.isLocalVideoMuted()) {
sendAnalyticsEvent('conference.video.initiallyMuted');
logger.log('Video mute: initially muted');
if ((track.isAudioTrack() && this.isLocalAudioMuted())
|| (track.isVideoTrack() && this.isLocalVideoMuted())) {
const mediaType = track.getType();
sendAnalytics(
createTrackMutedEvent(mediaType, 'initial mute'));
logger.log(`${mediaType} mute: initially muted.`);
track.mute();
}
});
@@ -1297,6 +1324,7 @@ export default {
}
options.applicationName = interfaceConfig.APP_NAME;
options.getWiFiStatsMethod = getJitsiMeetGlobalNS().getWiFiStats;
return options;
},
@@ -1312,19 +1340,35 @@ export default {
replaceLocalTrack(this.localVideo, newStream, room))
.then(() => {
this.localVideo = newStream;
this._setSharingScreen(newStream);
if (newStream) {
this.isSharingScreen = newStream.videoType === 'desktop';
APP.UI.addLocalStream(newStream);
} else {
this.isSharingScreen = false;
}
this.setVideoMuteStatus(this.isLocalVideoMuted());
APP.UI.updateDesktopSharingButtons();
});
},
/**
* Sets `this.isSharingScreen` depending on provided video stream.
* In case new screen sharing status is not equal previous one
* it updates desktop sharing buttons in UI
* and notifies external application.
*
* @param {JitsiLocalTrack} [newStream] new stream to use or null
* @private
* @returns {void}
*/
_setSharingScreen(newStream) {
const wasSharingScreen = this.isSharingScreen;
this.isSharingScreen = newStream && newStream.videoType === 'desktop';
if (wasSharingScreen !== this.isSharingScreen) {
APP.UI.updateDesktopSharingButtons();
APP.API.notifyScreenSharingStatusChanged(this.isSharingScreen);
}
},
/**
* Start using provided audio stream.
* Stops previous audio stream.
@@ -1427,9 +1471,9 @@ export default {
promise = createLocalTracksF({ devices: [ 'video' ] })
.then(([ stream ]) => this.useVideoStream(stream))
.then(() => {
sendAnalyticsEvent(
'conference.sharingDesktop.stop');
logger.log('switched back to local video');
sendAnalytics(createScreenSharingEvent('stopped'));
logger.log('Screen sharing stopped, switching to video.');
if (!this.localVideo && wasVideoMuted) {
return Promise.reject('No local video to be muted!');
} else if (wasVideoMuted && this.localVideo) {
@@ -1584,7 +1628,7 @@ export default {
},
/**
* Tries to switch to the screenshairng mode by disposing camera stream and
* Tries to switch to the screensharing mode by disposing camera stream and
* replacing it with a desktop one.
*
* @param {Object} [options] - Screen sharing options that will be passed to
@@ -1607,8 +1651,8 @@ export default {
.then(stream => this.useVideoStream(stream))
.then(() => {
this.videoSwitchInProgress = false;
sendAnalyticsEvent('conference.sharingDesktop.start');
logger.log('sharing local desktop');
sendAnalytics(createScreenSharingEvent('started'));
logger.log('Screen sharing started');
})
.catch(error => {
this.videoSwitchInProgress = false;
@@ -1665,12 +1709,6 @@ export default {
}
);
return;
} else if (error.name === JitsiTrackErrors.FIREFOX_EXTENSION_NEEDED) {
APP.UI.showExtensionRequiredDialog(
config.desktopSharingFirefoxExtensionURL
);
return;
}
@@ -1683,8 +1721,23 @@ export default {
let titleKey;
if (error.name === JitsiTrackErrors.PERMISSION_DENIED) {
descriptionKey = 'dialog.screenSharingPermissionDeniedError';
titleKey = 'dialog.screenSharingFailedToInstallTitle';
// in FF the only option for user is to deny access temporary or
// permanently and we only receive permission_denied
// we always show some info cause in case of permanently, no info
// shown will be bad experience
//
// TODO: detect interval between requesting permissions and received
// error, this way we can detect user interaction which will have
// longer delay
if (JitsiMeetJS.util.browser.isFirefox()) {
descriptionKey
= 'dialog.screenSharingFirefoxPermissionDeniedError';
titleKey = 'dialog.screenSharingFirefoxPermissionDeniedTitle';
} else {
descriptionKey = 'dialog.screenSharingPermissionDeniedError';
titleKey = 'dialog.screenSharingFailedToInstallTitle';
}
} else {
descriptionKey = 'dialog.screenSharingFailedToInstall';
titleKey = 'dialog.screenSharingFailedToInstallTitle';
@@ -1720,15 +1773,20 @@ export default {
if (user.isHidden()) {
return;
}
const displayName = user.getDisplayName();
APP.store.dispatch(participantJoined({
id,
name: user.getDisplayName(),
name: displayName,
role: user.getRole()
}));
logger.log('USER %s connnected', id, user);
APP.API.notifyUserJoined(id);
APP.API.notifyUserJoined(id, {
displayName,
formattedDisplayName: appendSuffix(
displayName || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME)
});
APP.UI.addUser(user);
// check the roles for the new user and reflect them
@@ -1736,6 +1794,9 @@ export default {
});
room.on(JitsiConferenceEvents.USER_LEFT, (id, user) => {
if (user.isHidden()) {
return;
}
APP.store.dispatch(participantLeft(id, user));
logger.log('USER %s LEFT', id, user);
APP.API.notifyUserLeft(id);
@@ -1886,6 +1947,7 @@ export default {
}
APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, id => {
APP.API.notifyOnStageParticipantChanged(id);
try {
// do not try to select participant if there is none (we
// are alone in the room), otherwise an error will be
@@ -1897,8 +1959,7 @@ export default {
room.selectParticipant(id);
} catch (e) {
sendAnalyticsEvent(
'selectParticipant.failed');
sendAnalytics(createSelectParticipantFailedEvent(e));
reportError(e);
}
});
@@ -1932,7 +1993,13 @@ export default {
id,
name: formattedDisplayName
}));
APP.API.notifyDisplayNameChanged(id, formattedDisplayName);
APP.API.notifyDisplayNameChanged(id, {
displayName: formattedDisplayName,
formattedDisplayName:
appendSuffix(
formattedDisplayName
|| interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME)
});
APP.UI.changeDisplayName(id, formattedDisplayName);
}
);
@@ -2057,7 +2124,6 @@ export default {
id: from,
avatarURL: data.value
}));
APP.UI.setUserAvatarUrl(from, data.value);
});
room.addCommandListener(this.commands.defaults.AVATAR_ID,
@@ -2067,24 +2133,16 @@ export default {
id: from,
avatarID: data.value
}));
APP.UI.setUserAvatarID(from, data.value);
});
APP.UI.addListener(UIEvents.NICKNAME_CHANGED,
this.changeLocalDisplayName.bind(this));
APP.UI.addListener(UIEvents.START_MUTED_CHANGED,
(startAudioMuted, startVideoMuted) => {
room.setStartMutedPolicy({
audio: startAudioMuted,
video: startVideoMuted
});
}
);
room.on(
JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,
({ audio, video }) => {
APP.UI.onStartMutedChanged(audio, video);
APP.store.dispatch(
onStartMutedPolicyChanged(audio, video));
}
);
room.on(JitsiConferenceEvents.STARTED_MUTED, () => {
@@ -2125,22 +2183,12 @@ export default {
APP.UI.addListener(
UIEvents.RESOLUTION_CHANGED,
(id, oldResolution, newResolution, delay) => {
const logObject = {
id: 'resolution_change',
participant: id,
oldValue: oldResolution,
newValue: newResolution,
delay
};
room.sendApplicationLog(JSON.stringify(logObject));
// We only care about the delay between simulcast streams.
// Longer delays will be caused by something else and will just
// poison the data.
if (delay < 2000) {
sendAnalyticsEvent('stream.switch.delay', { value: delay });
}
sendAnalytics(createStreamSwitchDelayEvent(
{
'old_resolution': oldResolution,
'new_resolution': newResolution,
value: delay
}));
});
/* eslint-enable max-params */
@@ -2166,7 +2214,7 @@ export default {
cameraDeviceId => {
const videoWasMuted = this.isLocalVideoMuted();
sendAnalyticsEvent('settings.changeDevice.video');
sendAnalytics(createDeviceChangedEvent('video', 'input'));
createLocalTracksF({
devices: [ 'video' ],
cameraDeviceId,
@@ -2205,8 +2253,7 @@ export default {
micDeviceId => {
const audioWasMuted = this.isLocalAudioMuted();
sendAnalyticsEvent(
'settings.changeDevice.audioIn');
sendAnalytics(createDeviceChangedEvent('audio', 'input'));
createLocalTracksF({
devices: [ 'audio' ],
cameraDeviceId: null,
@@ -2236,8 +2283,7 @@ export default {
APP.UI.addListener(
UIEvents.AUDIO_OUTPUT_DEVICE_CHANGED,
audioOutputDeviceId => {
sendAnalyticsEvent(
'settings.changeDevice.audioOut');
sendAnalytics(createDeviceChangedEvent('audio', 'output'));
APP.settings.setAudioOutputDeviceId(audioOutputDeviceId)
.then(() => logger.log('changed audio output device'))
.catch(err => {
@@ -2368,10 +2414,6 @@ export default {
APP.UI.initConference();
APP.UI.addListener(
UIEvents.LANG_CHANGED,
language => APP.translation.setLanguage(language));
APP.keyboardshortcut.init();
if (config.requireDisplayName
@@ -2382,7 +2424,20 @@ export default {
APP.store.dispatch(conferenceJoined(room));
APP.UI.mucJoined();
APP.API.notifyConferenceJoined(APP.conference.roomName);
const displayName = APP.settings.getDisplayName();
APP.API.notifyConferenceJoined(
this.roomName,
this._room.myUserId(),
{
displayName,
formattedDisplayName: appendSuffix(
displayName,
interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME),
avatarURL: getAvatarURLByParticipantId(
APP.store.getState(), this._room.myUserId())
}
);
APP.UI.markVideoInterrupted(false);
},
@@ -2494,7 +2549,9 @@ export default {
// If audio was muted before, or we unplugged current device
// and selected new one, then mute new audio track.
if (audioWasMuted) {
sendAnalyticsEvent('deviceListChanged.audio.muted');
sendAnalytics(createTrackMutedEvent(
'audio',
'device list changed'));
logger.log('Audio mute: device list changed');
muteLocalAudio(true);
}
@@ -2502,7 +2559,9 @@ export default {
// If video was muted before, or we unplugged current device
// and selected new one, then mute new video track.
if (!this.isSharingScreen && videoWasMuted) {
sendAnalyticsEvent('deviceListChanged.video.muted');
sendAnalytics(createTrackMutedEvent(
'video',
'device list changed'));
logger.log('Video mute: device list changed');
muteLocalVideo(true);
}
@@ -2588,37 +2647,6 @@ export default {
}
},
/**
* Log event to callstats and analytics.
* @param {string} name the event name
* @param {int} value the value (it's int because google analytics supports
* only int).
* @param {string} label short text which provides more info about the event
* which allows to distinguish between few event cases of the same name
* NOTE: Should be used after conference.init
*/
logEvent(name, value, label) {
sendAnalyticsEvent(name, {
value,
label
});
if (room) {
room.sendApplicationLog(JSON.stringify({ name,
value,
label }));
}
},
/**
* Methods logs an application event given in the JSON format.
* @param {string} logJSON an event to be logged in JSON format
*/
logJSON(logJSON) {
if (room) {
room.sendApplicationLog(logJSON);
}
},
/**
* Disconnect from the conference and optionally request user feedback.
* @param {boolean} [requestFeedback=false] if user feedback should be
@@ -2626,6 +2654,7 @@ export default {
*/
hangup(requestFeedback = false) {
eventEmitter.emit(JitsiMeetConferenceEvents.BEFORE_HANGUP);
APP.UI.removeLocalMedia();
let requestFeedbackPromise;
@@ -2670,7 +2699,7 @@ export default {
APP.store.dispatch(participantUpdated({
id: localId,
local: true,
formattedEmail
email: formattedEmail
}));
APP.settings.setEmail(formattedEmail);
@@ -2698,7 +2727,6 @@ export default {
}));
APP.settings.setAvatarUrl(url);
APP.UI.setUserAvatarUrl(id, url);
sendData(commands.AVATAR_URL, url);
},
@@ -2753,6 +2781,14 @@ export default {
}));
APP.settings.setDisplayName(formattedNickname);
APP.API.notifyDisplayNameChanged(id, {
displayName: formattedNickname,
formattedDisplayName:
appendSuffix(
formattedNickname,
interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME)
});
if (room) {
room.setDisplayName(formattedNickname);
APP.UI.changeDisplayName(id, formattedNickname);
@@ -2800,5 +2836,21 @@ export default {
setAudioMuteStatus(muted) {
APP.UI.setAudioMuted(this.getMyUserId(), muted);
APP.API.notifyAudioMutedStatusChanged(muted);
},
/**
* Dispatches the passed in feedback for submission. The submitted score
* should be a number inclusively between 1 through 5, or -1 for no score.
*
* @param {number} score - a number between 1 and 5 (inclusive) or -1 for no
* score.
* @param {string} message - An optional message to attach to the feedback
* in addition to the score.
* @returns {void}
*/
submitFeedback(score = -1, message = '') {
if (score === -1 || (score >= 1 && score <= 5)) {
APP.store.dispatch(submitFeedback(score, message, room));
}
}
};

View File

@@ -94,7 +94,7 @@ var config = {
// w3c spec-compliant video constraints to use for video capture. Currently
// used by browsers that return true from lib-jitsi-meet's
// RTCBrowserType#usesNewGumFlow. The constraints are independency from
// util#browser#usesNewGumFlow. The constraints are independency from
// this config's resolution value. Defaults to requesting an ideal aspect
// ratio of 16:9 with an ideal resolution of 1080p.
// constraints: {
@@ -150,22 +150,14 @@ var config = {
// Required version of Chrome extension
desktopSharingChromeMinExtVersion: '0.1',
// The ID of the jidesha extension for Firefox. If null, we assume that no
// extension is required.
desktopSharingFirefoxExtId: null,
// Whether desktop sharing should be disabled on Firefox.
desktopSharingFirefoxDisabled: false,
// The maximum version of Firefox which requires a jidesha extension.
// Example: if set to 41, we will require the extension for Firefox versions
// up to and including 41. On Firefox 42 and higher, we will run without the
// extension.
// If set to -1, an extension will be required for all versions of Firefox.
desktopSharingFirefoxMaxVersionExtRequired: 51,
// The URL to the Firefox extension for desktop sharing.
desktopSharingFirefoxExtensionURL: null,
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
// desktopSharingFrameRate: {
// min: 5,
// max: 5
// },
// Try to start calls with screen-sharing instead of camera video.
// startScreenSharing: false,
@@ -239,8 +231,11 @@ var config = {
// Stats
//
// Whether to enable stats collection or not.
// disableStats: false,
// Whether to enable stats collection or not in the TraceablePeerConnection.
// This can be useful for debugging purposes (post-processing/analysis of
// the webrtc stats) as it is done in the jitsi-meet-torture bandwidth
// estimation tests.
// gatherStats: false,
// To enable sending statistics to callstats.io you must provide the
// Application ID and Secret.
@@ -307,16 +302,73 @@ var config = {
// backToP2PDelay: 5
},
// A list of scripts to load as lib-jitsi-meet "analytics handlers".
// analyticsScriptUrls: [
// "libs/analytics-ga.js", // google-analytics
// "https://example.com/my-custom-analytics.js"
// ],
// The Google Analytics Tracking ID
// googleAnalyticsTrackingId = 'your-tracking-id-here-UA-123456-1',
// Information about the jitsi-meet instance we are connecting to, including
// the user region as seen by the server.
//
deploymentInfo: {
// shard: "shard1",
// region: "europe",
// userRegion: "asia"
}
// List of undocumented settings used in jitsi-meet
/**
alwaysVisibleToolbar
autoEnableDesktopSharing
autoRecord
autoRecordToken
debug
debugAudioLevels
deploymentInfo
dialInConfCodeUrl
dialInNumbersUrl
dialOutAuthUrl
dialOutCodesUrl
disableRemoteControl
displayJids
enableLocalVideoFlip
etherpad_base
externalConnectUrl
firefox_fake_device
googleApiApplicationClientID
iAmRecorder
iAmSipGateway
peopleSearchQueryTypes
peopleSearchUrl
requireDisplayName
tokenAuthUrl
*/
// List of undocumented settings used in lib-jitsi-meet
/**
_peerConnStatusOutOfLastNTimeout
_peerConnStatusRtcMuteTimeout
abTesting
avgRtpStatsN
callStatsConfIDNamespace
callStatsCustomScriptUrl
desktopSharingSources
disableAEC
disableAGC
disableAP
disableHPF
disableNS
enableLipSync
enableTalkWhileMuted
forceJVB121Ratio
hiddenDomain
ignoreStartMuted
nick
startBitrate
*/
};
/* eslint-enable no-unused-vars, no-var */

View File

@@ -94,12 +94,15 @@ function connect(id, password, roomName) {
JitsiConnectionEvents.CONNECTION_FAILED,
connectionFailedHandler);
/* eslint-disable max-params */
/**
*
*/
function connectionFailedHandler(error, message, credentials) {
function connectionFailedHandler(error, message, credentials, details) {
/* eslint-enable max-params */
APP.store.dispatch(
connectionFailed(connection, error, message, credentials));
connectionFailed(
connection, error, message, credentials, details));
if (isFatalJitsiConnectionError(error)) {
connection.removeEventListener(

View File

@@ -16,14 +16,17 @@ import parseURLParams from '../react/features/base/config/parseURLParams';
*/
if (typeof createConnectionExternally === 'function') {
// URL params have higher proirity than config params.
// URL params have higher priority than config params.
let url
= parseURLParams(window.location, true, 'hash')[
'config.externalConnectUrl']
|| config.externalConnectUrl;
const isRecorder
= parseURLParams(window.location, true, 'hash')['config.iAmRecorder'];
let roomName;
if (url && (roomName = getRoomName())) {
if (url && (roomName = getRoomName()) && !isRecorder) {
url += `?room=${roomName}`;
const token = parseURLParams(window.location, true, 'search').jwt;

229
css/_aui_reset.scss Normal file
View File

@@ -0,0 +1,229 @@
/* Fonts and line heights */
/**
* RESET
*/
html,
body,
p,
div,
h1,
h2,
h3,
h4,
h5,
h6,
img,
pre,
form,
fieldset {
margin: 0;
padding: 0;
}
ul,
ol,
dl {
margin: 0;
}
img,
fieldset {
border: 0;
}
@-moz-document url-prefix() {
img {
font-size: 0;
}
img:-moz-broken {
font-size: inherit;
}
}
/* https://github.com/necolas/normalize.css */
/* Customised to remove styles for unsupported browsers */
details,
main,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
input[type="button"],
input[type="submit"],
input[type="reset"] {
-webkit-appearance: button;
}
/**
* TYPOGRAPHY - 14px base font size, agnostic font stack
*/
body {
color: #333;
font-family: Arial, sans-serif;
font-size: 14px;
line-height: 1.42857142857143;
}
/* International Font Stacks*/
[lang|=en] {
font-family: Arial, sans-serif;
}
[lang|=ja] {
font-family: "Hiragino Kaku Gothic Pro", "ヒラギノ角ゴ Pro W3", "メイリオ", Meiryo, " Pゴシック", Verdana, Arial, sans-serif;
}
/* Default margins */
p,
ul,
ol,
dl,
h1,
h2,
h3,
h4,
h5,
h6,
blockquote,
pre {
margin: 10px 0 0 0;
}
/* No top margin to interfere with box padding */
p:first-child,
ul:first-child,
ol:first-child,
dl:first-child,
h1:first-child,
h2:first-child,
h3:first-child,
h4:first-child,
h5:first-child,
h6:first-child,
blockquote:first-child,
pre:first-child {
margin-top: 0;
}
/* Headings: desired line height in px / font size = unitless line height */
h1 {
color: #333;
font-size: 32px;
font-weight: normal;
line-height: 1.25;
text-transform: none;
margin: 30px 0 0 0;
}
h2 {
color: #333;
font-size: 24px;
font-weight: normal;
line-height: 1.25;
text-transform: none;
margin: 30px 0 0 0;
}
h3 {
color: #333;
font-size: 20px;
font-weight: normal;
line-height: 1.5;
text-transform: none;
margin: 30px 0 0 0;
}
h4 {
font-size: 16px;
font-weight: bold;
line-height: 1.25;
text-transform: none;
margin: 20px 0 0 0;
}
h5 {
color: #333;
font-size: 14px;
font-weight: bold;
line-height: 1.42857143;
text-transform: none;
margin: 20px 0 0 0;
}
h6 {
color: #707070;
font-size: 12px;
font-weight: bold;
line-height: 1.66666667;
text-transform: uppercase;
margin: 20px 0 0 0;
}
h1:first-child,
h2:first-child,
h3:first-child,
h4:first-child,
h5:first-child,
h6:first-child {
margin-top: 0;
}
/* Nice styles for using subheadings */
h1 + h2,
h2 + h3,
h3 + h4,
h4 + h5,
h5 + h6 {
margin-top: 10px;
}
/* Other typographical elements */
small {
color: #707070;
font-size: 12px;
line-height: 1.33333333333333;
}
code,
kbd {
font-family: monospace;
}
var,
address,
dfn,
cite {
font-style: italic;
}
cite:before {
content: "\2014 \2009";
}
blockquote {
border-left: 1px solid #ccc;
color: #707070;
margin-left: 19px;
padding: 10px 20px;
}
blockquote > cite {
display: block;
margin-top: 10px;
}
q {
color: #707070;
}
q:before {
content: open-quote;
}
q:after {
content: close-quote;
}
abbr {
border-bottom: 1px #707070 dotted;
cursor: help;
}
a {
color: #3572b0;
text-decoration: none;
}
a:focus,
a:hover,
a:active {
text-decoration: underline;
}

View File

@@ -123,6 +123,9 @@ form {
* Dialogs fade
*/
.aui-blanket {
background: #000;
transition: opacity 0.2s, visibility 0.2s;
transition-delay: 0.1s;
visibility: visible;
}

View File

@@ -13,11 +13,6 @@
.clickable {
cursor: pointer;
}
.icon-security,
.icon-security-locked {
font-size: 16px;
}
}
#contacts {

View File

@@ -1,81 +0,0 @@
/**
* The dialog content element.
*/
.dial-out-content {
margin-top: 5px;
/**
* Wrap the contents in flex so items can be aligned on the same line.
*/
.form-control {
display: flex;
}
/**
* The style of the flag icon.
*/
.dial-out-flag-icon {
position: absolute;
left: 5px;
top: 50%;
transform: translate(0, -50%);
}
/**
* The style of the dial code element.
*/
.dial-out-code {
margin-bottom: 0;
padding-left: 25px;
}
/**
* The dial-out dialog error element.
*/
.dial-out-error {
color: $errorColor;
}
/**
* The style of the dial input element.
*/
.dial-out-input {
display: inline-block;
flex: 1;
margin-left: 5px;
}
/**
* Re-styling the default dropdown inside the dial-out-content.
*/
.dropdown {
position: relative;
width: 65px;
}
/**
* Re-styling the default form-control inside the dial-out-content.
*/
.form-control {
margin-bottom: 8px;
}
.dropdown {
position: relative;
input {
padding-left: 16px;
&:read-only {
color: inherit;
}
}
}
.dropdown-trigger-icon {
position: absolute;
right: 0;
top: 50%;
transform: translate(0, -50%);
}
}

View File

@@ -64,7 +64,7 @@
* The local video identifier.
*/
&#filmstripLocalVideo {
bottom: 32px;
align-self: flex-end;
display: block;
/**

View File

@@ -1,35 +0,0 @@
.flag-icon-background {
background-size: contain;
background-position: 50%;
background-repeat: no-repeat;
}
.flag-icon {
background-size: contain;
background-position: 50%;
background-repeat: no-repeat;
position: relative;
display: inline-block;
width: 1.33333333em;
line-height: 1em;
}
.flag-icon:before {
content: "\00a0";
}
.flag-icon-au {
background-image: url(../images/countries/au.svg);
}
.flag-icon-ca {
background-image: url(../images/countries/ca.svg);
}
.flag-icon-de {
background-image: url(../images/countries/de.svg);
}
.flag-icon-gb {
background-image: url(../images/countries/gb.svg);
}
.flag-icon-fr {
background-image: url(../images/countries/fr.svg);
}
.flag-icon-us {
background-image: url(../images/countries/us.svg);
}

View File

@@ -24,7 +24,30 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-arrow_back:before {
content: "\e5c4";
}
.icon-event_note:before {
content: "\e616";
}
.icon-menu:before {
content: "\e5d2";
}
.icon-navigate_before:before {
content: "\e408";
}
.icon-navigate_next:before {
content: "\e409";
}
.icon-public:before {
content: "\e80b";
}
.icon-restore:before {
content: "\e8b3";
}
.icon-timer:before {
content: "\e425";
}
.icon-thumb-menu:before {
content: "\e5d4";
}

View File

@@ -56,9 +56,6 @@
margin-bottom: 0px;
width: 100%;
border-radius: 0px;
> .aui-progress-indicator-value {
border-radius: 0px;
}
}
}
&__title {

View File

@@ -1,3 +1,81 @@
.recordingSpinner {
vertical-align: top;
}
.live-stream-dialog {
/**
* Set font-size to be consistent with Atlaskit FieldText.
*/
font-size: 14px;
.broadcast-dropdown,
.broadcast-dropdown-trigger {
text-align: left;
}
.form-footer {
text-align: right;
}
.live-stream-cta {
a {
cursor: pointer;
}
}
.google-api {
margin-top: 10px;
min-height: 36px;
text-align: center;
width: 100%;
}
/**
* The Google sign in button must follow Google's design guidelines.
* See: https://developers.google.com/identity/branding-guidelines
*/
.google-sign-in {
background-color: #4285f4;
border-radius: 2px;
cursor: pointer;
display: inline-flex;
font-family: Roboto, arial, sans-serif;
font-size: 14px;
padding: 1px;
.google-cta {
color: white;
display: inline-block;
/**
* Hack the line height for vertical centering of text.
*/
line-height: 32px;
margin: 0 15px;
}
.google-logo {
background-color: white;
border-radius: 2px;
display: inline-block;
padding: 8px;
height: 18px;
width: 18px;
}
}
.google-panel {
align-items: center;
border-bottom: 2px solid rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
padding-bottom: 10px;
}
.stream-key-form {
.helper-link {
display: inline-block;
cursor: pointer;
margin-top: 5px;
}
}
}

View File

@@ -22,8 +22,10 @@
/**
* Form elements and blocks.
*/
input, select, a,
.sideToolbarBlock, .form-control, .button-control {
input,
a,
.sideToolbarBlock,
.form-control {
display: block;
margin-top: 15px;
margin-left: 10%;
@@ -34,19 +36,11 @@
* Specify styling of elements inside a block.
*/
.sideToolbarBlock {
input, button, a, select {
input, a {
margin-left: 0;
margin-top: 5px;
width: 100%;
}
input[type='checkbox'] {
display: inline;
width: auto !important;
> label {
margin-top: 5px;
width: 80%;
}
}
}
/**
@@ -80,42 +74,35 @@
font-size: $toolbarTitleFontSize;
}
/**
* Subtitle specific properties.
*/
div.subTitle {
color: $defaultSideBarFontColor !important;
font-size: 11px;
font-weight: 500;
margin-left: 10%;
text-align: left;
}
/**
* First element after a title.
*/
.first {
margin-top: 0 !important;
}
/**
* Buttons in the side toolbar container.
*/
.button-control {
margin: 9px 0;
width: 100%;
}
}
}
#device_settings {
width : auto !important;
text-align: center;
}
.settings-menu {
display: flex;
flex-direction: column;
padding-left: 10%;
padding-right: 10%;
#deviceOptionsWrapper {
button {
float: none;
.moderator-checkbox {
display: inline-block;
margin: 0 5px 0;
width: auto;
}
.moderator-option {
margin-top: 15px;
}
.subTitle {
color: $defaultSideBarFontColor;
font-size: 11px;
font-weight: 500;
}
}
}

View File

@@ -56,11 +56,14 @@
/**
* Toolbar button styles for always on top.
*/
> .button {
.button {
font-size: $alwaysOnTopToolbarFontSize;
height: $alwaysOnTopToolbarSize;
line-height: $alwaysOnTopToolbarSize;
width: $alwaysOnTopToolbarSize;
&_hangup, &_hangup:hover {
font-size: $alwaysOnTopToolbarFontSize;
}
}
}
@@ -150,10 +153,13 @@
@include transform(translateX(-50%));
> a:first-child.button,
> div:first-child .button {
border-bottom-left-radius: 3px;
border-top-left-radius: 3px;
}
> a:last-child.button,
> div:last-child .button {
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
@@ -183,6 +189,7 @@
justify-content: flex-start;
left: 0;
padding-top: 24px;
pointer-events: none;
top: 0;
transform: translateX(-100%);
width: $defaultToolbarSize;
@@ -194,6 +201,10 @@
line-height: $secToolbarLineHeight;
}
> * {
pointer-events: auto
}
.button.toggled:not(.icon-raised-hand):not(.button-active) {
background: $secondaryToolbarBg;
cursor: pointer;

View File

@@ -1,3 +1,11 @@
.flip-x {
transform: scaleX(-1);
}
.hidden {
display: none;
}
/**
* Hides an element.
*/
@@ -5,6 +13,10 @@
display: none !important;
}
.invisible {
visibility: hidden;
}
/**
* Shows an element.
*/
@@ -35,4 +47,4 @@
display: -ms-flexbox !important;
display: -webkit-flex !important;
display: flex !important;
}
}

View File

@@ -138,8 +138,8 @@ $formPadding: 16px;
/**
* Unsupported browser
*/
$primaryUnsupportedBrowserButtonBgColor: #17a0db;
$unsupportedBrowserButtonBgColor: #ff9a00;
$primaryUnsupportedBrowserButtonBgColor: #0052CC;
$unsupportedBrowserButtonBgColor: rgba(9, 30, 66, 0.04);
$unsupportedBrowserTextColor: #4a4a4a;
$unsupportedBrowserTextSmallFontSize: 17px;
$unsupportedBrowserTitleColor: #fff;
@@ -151,4 +151,12 @@ $unsupportedDesktopBrowserTextFontSize: 21px;
* The size of the default watermark.
*/
$watermarkWidth: 186px;
$watermarkHeight: 74px;
$watermarkHeight: 74px;
/**
* Welcome page variables.
*/
$welcomePageDescriptionColor: #fff;
$welcomePageFontFamily: inherit;
$welcomePageHeaderBackground: linear-gradient(#165ecc, #44A5FF);
$welcomePageTitleColor: #fff;

View File

@@ -2,6 +2,23 @@
* Override other styles to support vertical filmstrip mode.
*/
.vertical-filmstrip {
/*
* Firefox sets flex items to min-height: auto and min-width: auto,
* preventing flex children from shrinking like they do on other browsers.
* Setting min-height and min-width 0 is a workaround for the issue so
* Firefox behaves like other browsers.
* https://bugzilla.mozilla.org/show_bug.cgi?id=1043520
*/
@mixin minHWAutoFix() {
min-height: 0;
min-width: 0;
}
#etherpad,
#sharedvideo {
text-align: left;
}
.filmstrip {
align-items: flex-end;
box-sizing: border-box;
@@ -55,6 +72,7 @@
* vertical filmstrip layout.
*/
#filmstripLocalVideo {
align-self: initial;
bottom: 5px;
display: flex;
flex-direction: column-reverse;
@@ -78,6 +96,8 @@
}
#filmstripRemoteVideos {
@include minHWAutoFix();
display: flex;
flex: 1;
flex-direction: column;
@@ -86,6 +106,11 @@
#filmstripRemoteVideosContainer {
flex-direction: column-reverse;
/**
* Add padding as a hack for Firefox not to show scrollbars when
* unnecessary.
*/
padding: 1px 0;
overflow-x: hidden;
}
}
@@ -115,6 +140,8 @@
}
#remoteVideos {
@include minHWAutoFix();
flex-direction: column;
flex-grow: 1;
}
@@ -224,3 +251,35 @@
}
}
}
/**
* Workarounds for Edge, IE11, and Firefox not handling scrolling properly
* with flex-direction: column-reverse. The remove videos in filmstrip should
* start scrolling from the bottom of the filmstrip, but in those browsers the
* scrolling won't happen. Per W3C spec, scrolling should happen from the
* bottom. As such, use css hacks to get around the css issue, with the intent
* being to remove the hacks as the spec is supported.
*/
@mixin undoColumnReverseVideos() {
.vertical-filmstrip {
#remoteVideos #filmstripRemoteVideos #filmstripRemoteVideosContainer {
flex-direction: column;
}
}
}
/** Firefox detection hack **/
@-moz-document url-prefix() {
@include undoColumnReverseVideos();
}
/** IE11 detection hack **/
@media screen and (-ms-high-contrast: active),
screen and (-ms-high-contrast: none) {
@include undoColumnReverseVideos();
}
/** Edge detection hack **/
@supports (-ms-ime-align:auto) {
@include undoColumnReverseVideos();
}

View File

@@ -12,7 +12,8 @@
overflow: hidden;
}
.video_blurred_container {
#largeVideoBackgroundContainer,
.large-video-background {
height: 100%;
filter: blur(40px);
left: 0;
@@ -20,6 +21,16 @@
position: absolute;
top: 0;
width: 100%;
&.fit-full-height #largeVideoBackground {
height: 100%;
width: auto;
}
.fit-full-width #largeVideoBackground {
height: auto;
width: 100%;
}
}
.videocontainer {
@@ -250,6 +261,7 @@
/**
* Positions video thumbnail display name and editor.
*/
#alwaysOnTop .displayname,
.videocontainer .displayname,
.videocontainer .editdisplayname {
display: inline-block;
@@ -269,6 +281,15 @@
z-index: $zindex2;
}
#alwaysOnTop .displayname {
font-size: 15px;
position: inherit;
width: 100%;
left: 0px;
top: 0px;
margin-top: 10px;
}
/**
* Positions video thumbnail display name editor.
*/
@@ -507,6 +528,20 @@
width: auto;
}
#videoNotAvailableScreen {
text-align: center;
#avatarContainer {
height: 50vh;
display:inline-block;
margin-top: 25vh;
#avatar {
border-radius: 50%;
height: 100%;
}
}
}
.sharedVideoAvatar {
height: 100%;
width: 100%;

View File

@@ -1,206 +1,87 @@
#welcome_page {
.welcome {
font-family: $welcomePageFontFamily;
height: 100%;
overflow: auto;
position: relative;
}
#disable_welcome {
display:none;
}
.disable_welcome_position
{
margin: -139px auto 0px auto;
padding-left: 39px;
padding-top: 7px;
width: 269px;
height: 31px;
display:block;
}
#disable_welcome + label
{
background-image: url(../images/welcome_page/disable-welcome.png);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
background-repeat: no-repeat;
font-weight: 500;
font-size: 16px;
color: #acacac;
z-index: $zindex2;
}
#disable_welcome:checked + label
{
background-image: url(../images/welcome_page/disable-welcome-selected.png);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
background-repeat: no-repeat;
font-weight: 500;
font-size: 16px;
color: #acacac;
z-index: $zindex2;
}
#enter_room_form {
border-radius: 1px;
background-color: #FFFFFF;
border: none;
-moz-border-radius: 1px;
-webkit-border-radius: 1px;
-webkit-appearance: none;
height: 55px;
box-shadow: none;
float: left;
}
.domain-name
{
float: left;
height: 55px;
line-height: 55px;
font-size: 18px;
font-weight: 500;
padding-left: 20px;
color: $defaultDarkColor;
}
.enter-room {
&__field {
font-size: 15px;
border: none;
-webkit-appearance: none;
width: 228px;
height: 55px;
line-height: 55px;
font-weight: 500;
box-shadow: none;
float: left;
background-color: #FFFFFF;
.header {
align-items: center;
background: $welcomePageHeaderBackground;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
z-index: $zindex2;
}
&__reload {
display: block;
width: 30px;
color: #acacac;
font-size: 1.9em;
line-height: 55px;
z-index: $zindex3;
float: left;
cursor: pointer;
text-align: center;
.header-text {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-top: 120px;
margin-bottom: 20px;
min-height: 286px;
width: 645px;
}
.header-text-title {
color: $welcomePageTitleColor;
font-size: 48px;
letter-spacing: -1px;
line-height: 58px;
margin-bottom: 20px;
}
.header-text-description {
color: $welcomePageDescriptionColor;
font-size: 20px;
line-height: 28px;
opacity: 0.8;
}
.header-image {
background-image: url(../images/welcome_page/curves.png);
background-size: contain;
height: 209px;
position: absolute;
width: 1070px;
}
#new_enter_room {
align-items: center;
display: flex;
margin-bottom: 20px;
position: relative;
z-index: 2;
.enter-room-input {
display: inline-block;
margin-right: 15px;
width: 350px;
}
}
}
&__button {
width: 73px;
height: 45px;
background-color: #21B9FC;
moz-border-radius: 1px;
-webkit-border-radius: 1px;
color: #ffffff;
font-weight: 600;
border: none;
margin-top: 5px;
font-size: 19px;
padding-top: 6px;
outline: none;
float:left;
position: relative;
z-index: $zindex2;
.welcome-page-button {
font-size: 16px;
}
}
#enter_room_container {
margin: 70px auto 0px auto;
display: table;
.welcome.with-content {
.header {
min-height: 552px;
}
.header-image {
left: -61px;
top: 401px;
}
}
#enter_room{
float:left;
padding-right: 5px;
}
#welcome_page_header
{
background-image: url(../images/welcome_page/pattern-header.png);
height: 290px;
width: 100%;
position: absolute;
}
#welcome_page_main
{
background-image:url(../images/welcome_page/pattern-body.png);
width: 100%;
position: absolute;
margin-top: 290px;
}
#brand_header
{
background-image:url(../images/welcome_page/header-big.png);
width: 583px;
height: 274px;
margin: -110px auto 0px auto;
}
#header_text
{
width: 885px;
height: 100px;
color: #ffffff;
font-size: 24px;
text-align: center;
margin: 0px auto 0px auto;
}
#features
{
margin-top: 30px;
position: relative;
}
.feature_row
{
position: relative;
width: 976px;
margin: 0px auto 30px auto;
padding-right: 75px;
}
.feature_holder
{
float:left;
width: 169px;
padding-left: 75px;
padding-bottom: 30px;
}
.feature_icon
{
background-image:url(../images/welcome_page/bubble.png);
background-repeat: no-repeat;
width: 169px;
height: 169px;
color: #ffffff;
font-size: 22px;
/*font-weight: bold;*/
text-align: center;
display: table-cell;
padding: 50px 26px 0px 20px;
}
.feature_description
{
width: 190px;
color: #ffffff;
font-size: 16px;
padding-top: 30px;
line-height: 22px;
font-weight: 200;
.welcome.without-content {
.header {
height: 100%;
}
.header-image {
bottom: -20px;
left: 0;
}
}

View File

@@ -0,0 +1 @@
/** Insert custom CSS for any additional content in the welcome page **/

View File

@@ -28,11 +28,9 @@
@import 'font-awesome';
/* Fonts END */
@import 'flag-icon';
/* Modules BEGIN */
@import 'dial-out';
@import 'aui_reset';
@import 'base';
@import 'utils';
@import 'overlay/overlay';
@@ -54,6 +52,7 @@
@import 'chat';
@import 'ringing/ringing';
@import 'welcome_page';
@import 'welcome_page_content';
@import 'toolbars';
@import 'side_toolbar_container';
@import 'jquery.contextMenu';
@@ -64,7 +63,6 @@
@import 'components/button-control';
@import 'components/input-control';
@import 'components/input-slider';
@import "modals/invite/invite";
@import "connection-info";
@import 'aui-components/dropdown';
@import '404';

View File

@@ -1,6 +1,10 @@
.dialog {
visibility: visible;
box-sizing: border-box;
height: auto;
min-height: 131px;
overflow: visible;
visibility: visible;
width: 400px;
h1, h2, h3, h4, h5, h6 {
color: $auiDialogColor;
@@ -10,10 +14,27 @@
&-icon {
color: $auiDialogColor;
text-indent: -999em;
&-small {
width: 14px;
height: 14px;
&:before {
color: inherit;
font-family: "FontAwesome";
font-size: 16px;
-webkit-font-smoothing: antialiased;
font-style: normal;
font-weight: normal;
left: 0;
line-height: 1;
margin-top: -8px;
position: absolute;
text-indent: 0;
speak: none;
top: 50%;
}
}
}
@@ -22,6 +43,10 @@
right: 20px;
position: absolute;
top: -49px;
&:before {
content: "\f00d";
}
}
&-dialog2 {
@@ -31,8 +56,16 @@
}
&-header {
height: em(58, 12);
border-bottom: 1px solid $auiBorderColor;
border-radius: 5px 5px 0 0;
box-sizing: border-box;
color: #333;
display: table;
font-weight: normal;
height: em(58, 12);
margin-top: -69px;
padding: 0 20px;
width: 100%;
h2 {
font-size: em(20, 12);
@@ -41,19 +74,40 @@
}
&-main {
display: table-cell;
padding-right: 0;
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}
}
&-footer {
border-top: 1px solid $auiBorderColor;
border-radius: 0 0 5px 5px;
box-sizing: border-box;
height: 51px;
overflow: hidden;
padding: 10px 20px;
width: 100%;
&:empty {
height: 5px;
padding: 0;
}
}
&-content {
font-size: em(14, 12);
min-height: 0;
background-color: $auiDialogContentBg;
background-color: $auiDialogBg;
box-sizing: border-box;
color: $auiDialogColor;
font-size: em(14, 12);
overflow: auto;
max-height: 100%;
padding: 20px;
p,span, h3 {
font-weight: $labelFontWeight;
@@ -72,13 +126,23 @@
}
}
.input-control {
background-color: $auiDialogContentBg;
color: $auiDialogColor;
}
.form-control:not(:last-child) {
border-bottom: 1px solid $auiBorderColor;
}
}
@media all and (max-width: 420px) {
.aui-dialog2-small .aui-dialog2-content {
height: 100%;
}
}
.modal-dialog-form {
color: $modalTextColor;
margin-top: 5px !important;
.input-control {
@@ -90,6 +154,14 @@
&-error {
margin-bottom: 8px;
}
/**
* Override Atlaskit dropdown styling when in a modal because the dropdown
* backgrounds clash with the modal backgrounds.
*/
.htclLc[data-role=droplistContent] {
border: 1px solid #455166;
}
}
.modal-dialog-footer {
font-size: $modalButtonFontSize;

View File

@@ -36,13 +36,12 @@
}
.desktop-picker-source {
color: $defaultDarkFontColor;
margin-top: 10px;
text-align: center;
&.is-selected {
.desktop-source-preview-image-container {
background: rgba(0, 0, 0, 0.1);
background: rgba(255,255,255,0.3);
border-radius: $borderRadius;
}
}

View File

@@ -1,6 +1,4 @@
.device-selection {
color: $feedbackInputTextColor;
.device-selectors {
font-size: 14px;
@@ -22,19 +20,15 @@
/* device-selector-trigger stylings attempt to mimic AtlasKit button */
.device-selector-trigger {
background-color: rgba(9, 30, 66, 0.04);
border-radius: 3px;
color: #505f79;
background-color: #0E1624;
border: 1px solid #455166;
border-radius: 5px;
display: flex;
height: 2.3em;
justify-content: space-between;
line-height: 2.3em;
overflow: hidden;
padding: 0 8px;
&:hover {
background-color: rgba(9,30,66,.08);
}
}
.device-selector-trigger-disabled {
.device-selector-trigger {
@@ -108,19 +102,21 @@
.audio-output-preview {
font-size: 14px;
margin-top: 10px;
a {
color: 4C9AFF;
cursor: pointer;
text-decoration: none;
}
}
.audio-input-preview {
background: #f4f5f7;
background: #7b7b7b;
border-radius: 5px;
height: 6px;
.audio-input-preview-level {
background: #0052cc;
background: #4C9AFF;
border-radius: 5px;
height: 100%;
-webkit-transition: width .1s ease-in-out;

View File

@@ -11,17 +11,11 @@
padding-left: 5px;
}
}
}
}
/**
* Styles the loading element in the MultiSelectAutocomplete.
*/
.autocomplete-loading {
justify-content: center;
display: flex;
min-width: 260px;
padding: 20px;
.add-telephone-icon {
transform: scaleX(-1);
}
}
}
/**

View File

@@ -4,16 +4,20 @@
.info-dialog-action-link {
display: inline-block;
line-height: 1.5em;
a {
cursor: pointer;
vertical-align: middle;
}
}
.info-dialog-action-link:before {
color: $linkFontColor;
content: '\2022';
font-size: 1.5em;
padding: 0 10px;
vertical-align: middle;
}
.info-dialog-action-link:first-child:before {
@@ -22,6 +26,8 @@
}
.info-dialog-action-links {
font-weight: bold;
margin-top: 10px;
white-space: nowrap;
}
@@ -39,16 +45,33 @@
.info-dialog-column {
margin-right: 10px;
overflow: hidden;
a,
a:active,
a:focus,
a:hover {
text-decoration: none;
}
}
.info-dialog-conference-url {
margin: 10px 0;
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis;
user-select: text;
white-space: nowrap;
}
.info-dialog-dial-in {
white-space: nowrap;
.conference-id,
.phone-number {
user-select: text;
}
}
.info-dialog-icon {
color: #6453C0;
font-size: 16px;
@@ -56,5 +79,63 @@
.info-dialog-title {
font-weight: bold;
margin-bottom: 10px;
}
.info-password,
.info-dialog-password,
.info-password-form {
display: flex;
}
.info-password-field {
margin-left: 2px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info-password-none,
.info-password-remote {
opacity: 0.5;
}
.info-password-input {
background-color: transparent;
border: none;
color: inherit;
padding-left: 0;
}
.info-password-local {
user-select: text;
}
.conference-id {
margin-left: 5px;
}
}
.dial-in-page {
align-items: center;
display: flex;
flex-direction: column;
font-size: 24px;
height: 100%;
justify-content: center;
width: 100%;
* {
user-select: text;
}
.dial-in-numbers-list {
font-size: 24px;
margin-top: 20px;
}
.dial-in-conference-id {
text-align: center;
width: 30%;
}
}

View File

@@ -1,96 +0,0 @@
/*
* Sets the default cursor the remove password link. The link doesn't use
* the href attribute, so we need to set the cursor manually.
*/
#inviteDialogRemovePassword {
cursor: hand;
}
.invite-dialog {
.dial-in-numbers {
.dial-in-numbers-conference-id {
color: orange;
margin-left: 3px;
}
/*
* dial-in-numbers-copy styling is needed for the feature of copying
* text to the clipboard. The styling keeps the element invisible
* to the user but still programmatically selectable for copying.
*/
.dial-in-numbers-copy {
opacity: 0;
pointer-events: none;
position: fixed;
-webkit-user-select: text;
user-select: text;
}
.is-disabled,
.is-loading {
.dial-in-numbers-trigger-icon {
display: none;
}
}
}
.form-control {
padding: 0;
&__container {
/**
* Ensure contents display in a line and vertically centered.
*/
align-items: center;
button {
font-size: $modalButtonFontSize;
}
}
&__input-container {
flex: 1;
margin-right: 10px;
.dropdown-button-trigger {
text-align: left;
}
}
}
.inviteLink {
color: $readOnlyInputColor;
}
.lock-state {
display: flex;
}
.password-overview {
margin-top: 10px;
.form-control {
margin-top: 10px;
}
.password-overview-status,
.remove-password {
display: flex;
justify-content: space-between;
}
.password-overview-toggle-edit,
.remove-password-link {
cursor: pointer;
text-decoration: none;
}
.remove-password {
margin-top: 15px;
}
}
.remove-password-current {
color: $inputControlEmColor;
}
}

View File

@@ -42,10 +42,6 @@
width: 55%;
}
.speaker-stats-item:nth-child(even) {
background: whitesmoke;
}
.speaker-stats-item__name,
.speaker-stats-item__time {
overflow: hidden;

View File

@@ -11,9 +11,16 @@
}
#reloadProgressBar {
width: 180px;
background: #e9e9e9;
border-radius: 3px;
height: 5px;
margin: 5px auto;
> .aui-progress-indicator-value {
overflow: hidden;
width: 180px;
.progress-indicator-fill {
background: $reloadProgressBarBg;
height: 100%;
transition: width .5s;
}
}

View File

@@ -14,11 +14,11 @@ $sliderThumbBackground: #3572b0;
/**
* Buttons
*/
$buttonBackground: #f5f5f5;
$buttonHoverBackground: #e9e9e9;
$buttonBorder: #ccc;
$buttonHoverBorder: #999;
$buttonColor: #333;
$buttonBackground: #44A5FF;
$buttonHoverBackground: #2c4062;
$buttonBorder: transparent;
$buttonHoverBorder: transparent;
$buttonColor: #eceef1;
$buttonLightBackground: #f5f5f5;
$buttonLightHoverBackground: #e9e9e9;
@@ -47,10 +47,10 @@ $reloadProgressBarBg: #0074E0;
/**
* Dialog colors
**/
$auiDialogColor: #333;
$auiDialogBg: #f5f5f5;
$auiDialogContentBg: $baseLight;
$auiBorderColor: #ccc;
$auiDialogColor: #eceef1;
$auiDialogBg: #253858;
$auiDialogContentBg: #344563;
$auiBorderColor: #253858;
$dialogTitleFontWeight: 400;
$dialogErrorText: #344563;
@@ -58,7 +58,7 @@ $dialogErrorText: #344563;
* Inlay colors
**/
$inlayColorBg: lighten($defaultBackground, 20%);
$inlayBorderColor: lighten($auiDialogContentBg, 10%);
$inlayBorderColor: lighten($baseLight, 10%);
$inlayIconBg: #000;
$inlayIconColor: #fff;
$inlayFilmstripOnlyColor: #474747;

View File

@@ -5,7 +5,7 @@
width: auto;
&__title {
border-bottom: 1px solid $auiBorderColor;
border-bottom: 1px solid $inlayBorderColor;
color: $unsupportedBrowserTitleColor;
font-weight: 400;
letter-spacing: 0.5px;

View File

@@ -1,13 +1,19 @@
.unsupported-mobile-browser {
background-color: #fff;
height: 100vh;
padding: 35px 0;
overflow: auto;
position: relative;
width: 100vw;
a {
text-decoration: none
}
&__body {
color: $unsupportedBrowserTextColor;
margin: auto;
max-width: 40em;
padding: 35px 0 40px 0;
text-align: center;
width: 75%;
@@ -16,8 +22,9 @@
}
}
&__text {
font-size: 1.8em;
&__text,
.unsupported-dial-in {
font-size: 1.2em;
line-height: em(29px, 21px);
margin-bottom: 0.65em;
@@ -39,20 +46,14 @@
&__button {
border: 0;
height: 42px;
margin: 0 auto;
height: 2.2857142857142856em;
line-height: 2.2857142857142856em;
margin: 18px auto 20px;
max-width: 300px;
width: 98%;
@include border-radius(8px);
width: auto;
@include border-radius(3px);
background-color: $unsupportedBrowserButtonBgColor;
font-size: 1.5em;
font-weight: 300;
letter-spacing: 0.5px;
text-shadow: 0px 1px 2px $unsupportedBrowserTextColor;
// Disable standard button effects.
box-shadow: none;
outline: none;
color: #505F79;
&:active {
background-color: $unsupportedBrowserButtonBgColor;
@@ -60,10 +61,29 @@
&_primary {
background-color: $primaryUnsupportedBrowserButtonBgColor;
color: #FFFFFF;
&:active {
background-color: $primaryUnsupportedBrowserButtonBgColor;
}
}
}
.unsupported-dial-in {
display: none;
&.has-numbers {
align-items: center;
display: flex;
flex-direction: column;
}
.dial-in-numbers-list {
color: $unsupportedBrowserTextColor;
}
.dial-in-numbers-body {
vertical-align: top;
}
}
}

View File

@@ -112,23 +112,18 @@ case "$1" in
fi
if [ ! -f /var/lib/prosody/$JVB_HOSTNAME.crt ]; then
HOST="$( (hostname -s; echo localhost) | head -n 1)"
DOMAIN="$( (hostname -d; echo localdomain) | head -n 1)"
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj \
"/O=$DOMAIN/OU=$HOST/CN=$JVB_HOSTNAME/emailAddress=webmaster@$HOST.$DOMAIN" \
-keyout /var/lib/prosody/$JVB_HOSTNAME.key \
-out /var/lib/prosody/$JVB_HOSTNAME.crt
# prosodyctl takes care for the permissions
# echo for using all default values
echo | prosodyctl cert generate $JVB_HOSTNAME
ln -sf /var/lib/prosody/$JVB_HOSTNAME.key /etc/prosody/certs/$JVB_HOSTNAME.key
ln -sf /var/lib/prosody/$JVB_HOSTNAME.crt /etc/prosody/certs/$JVB_HOSTNAME.crt
fi
if [ ! -f /var/lib/prosody/$JICOFO_AUTH_DOMAIN.crt ]; then
HOST="$( (hostname -s; echo localhost) | head -n 1)"
DOMAIN="$( (hostname -d; echo localdomain) | head -n 1)"
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj \
"/O=$DOMAIN/OU=$HOST/CN=$JICOFO_AUTH_DOMAIN/emailAddress=webmaster@$HOST.$DOMAIN" \
-keyout /var/lib/prosody/$JICOFO_AUTH_DOMAIN.key \
-out /var/lib/prosody/$JICOFO_AUTH_DOMAIN.crt
# prosodyctl takes care for the permissions
# echo for using all default values
echo | prosodyctl cert generate $JICOFO_AUTH_DOMAIN
AUTH_KEY_FILE="/etc/prosody/certs/$JICOFO_AUTH_DOMAIN.key"
AUTH_CRT_FILE="/etc/prosody/certs/$JICOFO_AUTH_DOMAIN.crt"

View File

@@ -1,24 +0,0 @@
jitsi-meet for Debian
---------------------
The jitsi-meet package is built from the sources of Jitsi Meet.
Jitsi Meet is downloaded from https://github.com/jitsi/jitsi-meet and the git files are removed. you can recreate the source with 'git clone https://github.com/jitsi/jitsi-meet.git'.
Use something like the script below to update from Git
#!/bin/bash
VERSION=1.0.1
echo "*.min.js export-ignore" > .gitattributes
echo "jquery-2.1.1.* export-ignore" >> .gitattributes
echo "jquery-ui.js export-ignore" >> .gitattributes
echo ".gitignore export-ignore" >> .gitattributes
sed -i "s/1.0.1/$VERSION/g" debian/changelog
git archive --worktree-attributes --format tar --prefix jitsi-meet-$VERSION/ -o ../jitsi-meet_${VERSION}.orig.tar master
tar --transform "s,^,jitsi-meet-$VERSION/," -rf ../jitsi-meet_${VERSION}.orig.tar
cd ..
bzip2 jitsi-meet_${VERSION}.orig.tar

View File

@@ -1,22 +0,0 @@
Description: Update the used js files for jquery to generic ones, to be able to use local system installed version (through symlinks).
Index: jitsi-meet/index.html
===================================================================
--- jitsi-meet.orig/index.html
+++ jitsi-meet/index.html
@@ -10,13 +10,13 @@
<meta itemprop="description" content="Join a WebRTC video conference powered by the Jitsi Videobridge"/>
<meta itemprop="image" content="/images/jitsilogo.png"/>
<script src="https://api.callstats.io/static/callstats.min.js"></script>
- <script src="libs/jquery-2.1.1.min.js"></script>
+ <script src="libs/jquery.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/1.5.0/sha.js"></script>
<script src="config.js?v=11"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="libs/strophe/strophe.min.js?v=2"></script>
<script src="libs/strophe/strophe.disco.min.js?v=1"></script>
<script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
- <script src="libs/jquery-ui.js"></script>
+ <script src="libs/jquery-ui.min.js"></script>
<script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
- <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->

View File

@@ -1 +0,0 @@
jquery-package

View File

@@ -2,11 +2,12 @@
1. Go to https://icomoon.io/app/
2. Go to "Manage Projects" from the menu on the top left.
3. Use "Import project" and select <code>fonts/selection.json</code> from Jitsi Meet.
4. Import icons (e.g. svg files) using the "import items" button.
5. Go to "generate font" and make sure the identifiers for the new icons are correct.
6. Download the result in a zip file using the "download" button.
7. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
8. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/font.css</code> in Jitsi Meet (do *not* copy the whole file)
4. Click "load".
5. Add the new icons using the "Add icons from library" button...
6. Go to "generate font" and make sure the identifiers for the new icons are correct.
7. Download the result in a zip file using the "download" button.
8. Copy <code>selection.json</code> and <code>fonts/jitsi.*</code> from the zip file to <code>fonts/</code> in Jitsi Meet
9. Copy the class for the new icon from <code>style.css</code> in the zip file to <code>css/_font.scss</code> in Jitsi Meet (do *not* copy the whole file)
10. Copy the <code>selection.json</code> file to <code>react/features/base/font-icons</code> overwriting <code>jitsi.json</code>
Sample commit: https://github.com/jitsi/jitsi-meet/commit/68bc819b89aec12364fcf07b81efa83a1900eed6

View File

@@ -27,6 +27,7 @@ Its constructor gets a number of options:
* **interfaceConfigOverwrite**: (optional) JS object with overrides for options defined in [interface_config.js].
* **noSSL**: (optional, defaults to true) Boolean indicating if the server should be contacted using HTTP or HTTPS.
* **jwt**: (optional) [JWT](https://jwt.io/) token.
* **onload**: (optional) handler for the iframe onload event.
Example:
@@ -140,18 +141,33 @@ The `event` parameter is a String object with the name of the event.
The `listener` parameter is a Function object with one argument that will be notified when the event occurs with data related to the event.
The following events are currently supported:
* **avatarChanged** - event notifications about avatar
changes. The listener will receive an object with the following structure:
```javascript
{
"id": id, // the id of the participant that changed his avatar.
"avatarURL": avatarURL // the new avatar URL.
}
```
* **audioAvailabilityChanged** - event notifications about audio availability status changes. The listener will receive an object with the following structure:
```javascript
{
"available": available // new available status - boolean
"available": available // new available status - boolean
}
```
* **audioMuteStatusChanged** - event notifications about audio mute status changes. The listener will receive an object with the following structure:
```javascript
{
"muted": muted // new muted status - boolean
"muted": muted // new muted status - boolean
}
```
* **screenSharingStatusChanged** - receives event notifications about turning on/off the local user screen sharing. The listener will receive object with the following structure:
```javascript
{
"on": on //whether screen sharing is on
}
```
@@ -159,9 +175,9 @@ The following events are currently supported:
messages. The listener will receive an object with the following structure:
```javascript
{
"from": from, // JID of the user that sent the message
"nick": nick, // the nickname of the user that sent the message
"message": txt // the text of the message
"from": from, // The id of the user that sent the message
"nick": nick, // the nickname of the user that sent the message
"message": txt // the text of the message
}
```
@@ -169,7 +185,7 @@ messages. The listener will receive an object with the following structure:
messages. The listener will receive an object with the following structure:
```javascript
{
"message": txt // the text of the message
"message": txt // the text of the message
}
```
@@ -177,50 +193,54 @@ messages. The listener will receive an object with the following structure:
changes. The listener will receive an object with the following structure:
```javascript
{
"jid": jid, // the JID of the participant that changed his display name
"displayname": displayName // the new display name
"id": id, // the id of the participant that changed his display name
"displayname": displayName // the new display name
}
```
* **participantJoined** - event notifications about new participants who join the room. The listener will receive an object with the following structure:
```javascript
{
"jid": jid // the JID of the participant
"id": id, // the id of the participant
"displayName": displayName // the display name of the participant
}
```
* **participantLeft** - event notifications about participants that leave the room. The listener will receive an object with the following structure:
```javascript
{
"jid": jid // the JID of the participant
"id": id // the id of the participant
}
```
* **videoConferenceJoined** - event notifications fired when the local user has joined the video conference. The listener will receive an object with the following structure:
```javascript
{
"roomName": room // the room name of the conference
"roomName": room, // the room name of the conference
"id": id, // the id of the local participant
"displayName": displayName, // the display name of the local participant
"avatarURL": avatarURL // the avatar URL of the local participant
}
```
* **videoConferenceLeft** - event notifications fired when the local user has left the video conference. The listener will receive an object with the following structure:
```javascript
{
"roomName": room // the room name of the conference
"roomName": room // the room name of the conference
}
```
* **videoAvailabilityChanged** - event notifications about video availability status changes. The listener will receive an object with the following structure:
```javascript
{
"available": available // new available status - boolean
"available": available // new available status - boolean
}
```
* **videoMuteStatusChanged** - event notifications about video mute status changes. The listener will receive an object with the following structure:
```javascript
{
"muted": muted // new muted status - boolean
"muted": muted // new muted status - boolean
}
```
@@ -264,6 +284,16 @@ You can get the number of participants in the conference with the following API
var numberOfParticipants = api.getNumberOfParticipants();
```
You can get the avatar URL of a participant in the conference with the following API function:
```javascript
var avatarURL = api.getAvatarURL(participantId);
```
You can get the display name of a participant in the conference with the following API function:
```javascript
var displayName = api.getDisplayName(participantId);
```
You can get the iframe HTML element where Jitsi Meet is loaded with the following API function:
```javascript
var iframe = api.getIFrame();

View File

@@ -45,7 +45,7 @@ modules_enabled = {
-- Not essential, but recommended
"private"; -- Private XML storage (for room bookmarks, etc.)
"vcard"; -- Allow users to set vCards
-- These are commented by default as they have a performance impact
--"privacy"; -- Support privacy lists
"compression"; -- Stream compression (requires the lua-zlib package installed)
@@ -181,6 +181,13 @@ VirtualHost "jitsi.example.com"
c2s_require_encryption = false
VirtualHost "auth.jitsi.example.com"
ssl = {
key = "/var/lib/prosody/auth.jitsi.example.com.key";
certificate = "/var/lib/prosody/auth.jitsi.example.com.crt";
}
authentication = "internal_plain"
------ Components ------
-- You can specify components to add hosts that provide special services,
-- like multi-user conferences, and transports.

View File

@@ -1,5 +1,10 @@
# Server Installation for Jitsi Meet
:warning: **WARNING:** Manual installation is not recommended. We recommend following the [quick-install](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md) document. The current document describes the steps that are needed to install a working deployment, but steps are easy to mess up, and the debian packages are more up-to-date, where this document sometimes is not updated to latest changes.
This describes configuring a server `jitsi.example.com` running Debian or a Debian Derivative. You will need to
change references to that to match your host, and generate some passwords for
`YOURSECRET1`, `YOURSECRET2` and `YOURSECRET3`.
@@ -60,6 +65,10 @@ VirtualHost "jitsi.example.com"
- add domain with authentication for conference focus user:
```
VirtualHost "auth.jitsi.example.com"
ssl = {
key = "/var/lib/prosody/auth.jitsi.example.com.key";
certificate = "/var/lib/prosody/auth.jitsi.example.com.crt";
}
authentication = "internal_plain"
```
- add focus user to server admins:
@@ -83,8 +92,16 @@ ln -s /etc/prosody/conf.avail/jitsi.example.com.cfg.lua /etc/prosody/conf.d/jits
Generate certs for the domain:
```sh
prosodyctl cert generate jitsi.example.com
prosodyctl cert generate auth.jitsi.example.com
```
Add auth.jitsi.example.com to the trusted certificates on the local machine:
```sh
ln -sf /var/lib/prosody/auth.jitsi.example.com.crt /usr/local/share/ca-certificates/auth.jitsi.example.com.crt
update-ca-certificates -f
```
Note that the `-f` flag is necessary if there are symlinks left from a previous installation.
Create conference focus user:
```sh
prosodyctl register focus auth.jitsi.example.com YOURSECRET3

View File

@@ -84,7 +84,7 @@ Enjoy!
## Uninstall
```sh
apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-web jicofo jitsi-videobridge
apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-web jicofo jitsi-videobridge
```
Sometimes the following packages will fail to uninstall properly:

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,5 @@
// flow-typed signature: 4e93c65cedbfbf7f1ab3fe4e800943d3
// flow-typed version: 9092387fd2/react-redux_v5.x.x/flow_>=v0.53.x <=v0.53.x
// flow-typed signature: 8db7b853f57c51094bf0ab8b2650fd9c
// flow-typed version: ab8db5f14d/react-redux_v5.x.x/flow_>=v0.30.x
// flow-typed signature: 59b0c4be0e1408f21e2446be96c79804
// flow-typed version: 9092387fd2/react-redux_v5.x.x/flow_>=v0.54.x
import type { Dispatch, Store } from "redux";
@@ -34,6 +31,22 @@ declare module "react-redux" {
declare type Context = { store: Store<*, *> };
declare type ComponentWithDefaultProps<DP: {}, P: {}, CP: P> = Class<
React$Component<CP>
> & { defaultProps: DP };
declare class ConnectedComponentWithDefaultProps<
OP,
DP,
CP
> extends React$Component<OP> {
static defaultProps: DP, // <= workaround for https://github.com/facebook/flow/issues/4644
static WrappedComponent: Class<React$Component<CP>>,
getWrappedInstance(): React$Component<CP>,
props: OP,
state: void
}
declare class ConnectedComponent<OP, P> extends React$Component<OP> {
static WrappedComponent: Class<React$Component<P>>,
getWrappedInstance(): React$Component<P>,
@@ -41,13 +54,18 @@ declare module "react-redux" {
state: void
}
declare type ConnectedComponentWithDefaultPropsClass<OP, DP, CP> = Class<
ConnectedComponentWithDefaultProps<OP, DP, CP>
>;
declare type ConnectedComponentClass<OP, P> = Class<
ConnectedComponent<OP, P>
>;
declare type Connector<OP, P> = (
component: React$ComponentType<P>
) => ConnectedComponentClass<OP, P>;
declare type Connector<OP, P> = (<DP: {}, CP: {}>(
component: ComponentWithDefaultProps<DP, P, CP>
) => ConnectedComponentWithDefaultPropsClass<OP, DP, CP>) &
((component: React$ComponentType<P>) => ConnectedComponentClass<OP, P>);
declare class Provider<S, A> extends React$Component<{
store: Store<S, A>,
@@ -77,12 +95,12 @@ declare module "react-redux" {
options: ConnectOptions
): Connector<OP, $Supertype<{ dispatch: Dispatch<A> } & OP>>;
declare function connect<S, A, OP, SP>(
mapStateToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: Null,
mergeProps: Null,
options?: ConnectOptions
): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
// declare function connect<S, A, OP, SP>(
// mapStateToProps: MapStateToProps<S, OP, SP>,
// mapDispatchToProps: Null,
// mergeProps: Null,
// options?: ConnectOptions
// ): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>;
declare function connect<A, OP, DP>(
mapStateToProps: Null,
@@ -93,7 +111,7 @@ declare module "react-redux" {
declare function connect<S, A, OP, SP, DP>(
mapStateToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
mapDispatchToProps: MapDispatchToProps<A, OP, DP> | Null,
mergeProps: Null,
options?: ConnectOptions
): Connector<OP, $Supertype<SP & DP & OP>>;

View File

@@ -1,5 +1,5 @@
// flow-typed signature: 33b83b6284653250e74578cf4dbe6124
// flow-typed version: e282e4128f/redux_v3.x.x/flow_>=v0.33.x
// flow-typed signature: ec7daead5cb4fec5ab25fedbedef29e8
// flow-typed version: 2c04631d20/redux_v3.x.x/flow_>=v0.55.x
declare module 'redux' {
@@ -55,55 +55,5 @@ declare module 'redux' {
declare export function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
declare export function compose<A, B>(ab: (a: A) => B): (a: A) => B
declare export function compose<A, B, C>(
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => C
declare export function compose<A, B, C, D>(
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => D
declare export function compose<A, B, C, D, E>(
de: (d: D) => E,
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => E
declare export function compose<A, B, C, D, E, F>(
ef: (e: E) => F,
de: (d: D) => E,
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => F
declare export function compose<A, B, C, D, E, F, G>(
fg: (f: F) => G,
ef: (e: E) => F,
de: (d: D) => E,
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => G
declare export function compose<A, B, C, D, E, F, G, H>(
gh: (g: G) => H,
fg: (f: F) => G,
ef: (e: E) => F,
de: (d: D) => E,
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => H
declare export function compose<A, B, C, D, E, F, G, H, I>(
hi: (h: H) => I,
gh: (g: G) => H,
fg: (f: F) => G,
ef: (e: E) => F,
de: (d: D) => E,
cd: (c: C) => D,
bc: (b: B) => C,
ab: (a: A) => B
): (a: A) => I
}
declare export var compose: $Compose;
}

Binary file not shown.

View File

@@ -11,11 +11,19 @@
<glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
<glyph unicode="&#xe1aa;" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
<glyph unicode="&#xe310;" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
<glyph unicode="&#xe408;" glyph-name="navigate_before" d="M658 708l-196-196 196-196-60-60-256 256 256 256z" />
<glyph unicode="&#xe409;" glyph-name="navigate_next" d="M426 768l256-256-256-256-60 60 196 196-196 196z" />
<glyph unicode="&#xe425;" glyph-name="timer" d="M512 170c166 0 298 134 298 300s-132 298-298 298-298-132-298-298 132-300 298-300zM812 708c52-66 84-148 84-238 0-212-172-384-384-384s-384 172-384 384 172 384 384 384c90 0 174-34 240-86l60 62c22-18 42-38 60-60zM470 426v256h84v-256h-84zM640 982v-86h-256v86h256z" />
<glyph unicode="&#xe5c4;" glyph-name="arrow_back" d="M854 554v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
<glyph unicode="&#xe5d2;" glyph-name="menu" d="M128 768h768v-86h-768v86zM128 470v84h768v-84h-768zM128 256v86h768v-86h-768z" />
<glyph unicode="&#xe5d4;" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
<glyph unicode="&#xe603;" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
<glyph unicode="&#xe613;" glyph-name="recDisable" horiz-adv-x="1140" d="M1123.444 1003.015c-23.593 26.481-64.131 28.989-90.74 5.395l-1008.269-893.436c-26.609-23.468-28.991-64.131-5.46-90.676 12.674-14.306 30.308-21.649 48.126-21.649 15.123 0 30.372 5.401 42.544 16.195l130.045 115.22c90.743-81.844 210.569-132.165 342.473-132.101 282.816 0.061 510.913 227.969 511.287 510.972 0.126 109.934-34.682 211.367-93.499 294.72l118.088 104.625c26.483 23.526 28.997 64.129 5.404 90.735zM944.422 513.818c0.128-200.922-161.896-363.201-362.509-362.952-87.56 0.123-167.573 31.151-230.061 82.569l331.277 293.509v-73.176c1.071-60.993 32.696-92.18 94.944-93.692 61.997 1.512 93.686 32.763 95.131 93.756v41.096h-72.227v-47.499c0.251-4.642-0.564-10.607-2.511-17.949-1.25-3.261-3.448-6.020-6.525-8.093-3.197-2.572-7.845-3.828-13.868-3.828-10.543 0.31-17.132 4.268-19.827 11.921-1.068 3.512-1.947 6.905-2.508 10.163-0.254 2.887-0.377 5.532-0.377 7.786v143.511l42.477 37.634c0.215-0.432 0.452-0.851 0.63-1.303 1.947-6.467 2.762-12.799 2.511-19.076v-36.772h72.227v30.121c-0.246 31.245-9.086 54.699-26.363 70.447l40.711 36.069c35.787-56.055 56.803-122.585 56.867-194.244zM239.795 395.47c-12.613 37.023-19.827 76.557-19.827 117.913-0.19 200.236 161.584 362.009 361.945 362.135 56.853 0 110.313-13.302 158.133-36.398l117.846 104.421c-79.444 50.952-173.758 80.817-275.292 80.948-283.377 0.181-511.354-227.729-511.789-511.675-0.126-79.567 18.636-154.679 51.137-221.882l117.848 104.538zM388.576 690.020h-97.514v-249.057l72.23 64.070v0.689h0.815l117.72 104.418c0 0.564 0.123 0.94 0.123 1.509 0.753 53.898-30.369 80.069-93.374 78.37zM405.959 625.517c1.942-2.767 3.074-6.469 3.323-11.112 0.312-4.452 0.438-9.6 0.438-15.246 0.251-10.916-0.689-19.83-2.949-26.985-2.952-7.594-10.983-11.357-24.159-11.357h-19.325v74.043h15.31c7.842 0 13.865-0.683 18.072-2.19 4.397-1.573 7.468-3.953 9.29-7.153z" />
<glyph unicode="&#xe614;" glyph-name="recEnable" horiz-adv-x="1142" d="M581.278 1025.708c284.857-0.19 514.807-230.517 514.427-514.997-0.378-285.047-230.073-514.553-514.869-514.615-284.541-0.062-515.311 230.517-514.933 514.422 0.439 285.936 230.009 515.439 515.375 515.19zM580.579 875.756c-201.764-0.123-364.666-163.032-364.478-364.663 0-202.018 162.524-364.735 364.478-364.984 202.018-0.316 365.174 163.030 365.048 365.423-0.252 201.767-163.156 364.35-365.048 364.224zM287.698 688.907h98.196c63.442 1.767 94.785-24.518 94.027-78.863 0.254-19.081-2.211-34.882-7.456-47.521-6.005-12.508-18.706-21.988-38.167-28.181v-0.819c28.373-6.259 43.031-23.573 43.981-51.946v-57.689c0-11.247 0.254-22.813 0.758-34.756 0.819-12.005 3.033-20.979 6.696-27.043h-71.846c-3.727 6.064-6.128 15.038-7.14 27.043-1.012 11.943-1.454 23.509-1.138 34.756v52.321c0 9.603-2.214 16.553-6.573 20.979-4.675 4.107-12.701 6.19-24.012 6.19h-14.599v-141.291h-72.73v326.82zM360.428 558.861h19.463c13.271 0 21.359 3.794 24.331 11.375 2.276 7.204 3.221 16.304 2.969 27.171 0 5.815-0.126 10.867-0.442 15.418-0.252 4.675-1.392 8.404-3.352 11.247-1.831 3.157-4.926 5.561-9.352 7.14-4.233 1.454-10.299 2.211-18.2 2.211h-15.418v-74.564zM498.372 688.907h162.082v-62.687h-89.35v-65.587h78.103v-62.685h-78.103v-73.11h92.822v-62.749h-165.557v326.818zM682.507 599.999c0.316 31.782 9.416 55.542 27.425 71.407 17.44 15.29 40.185 22.936 68.181 22.936 28.247 0 51.119-7.646 68.623-23 17.82-15.798 26.92-39.623 27.171-71.407v-30.333h-72.73v37.031c0.254 6.192-0.57 12.639-2.527 19.209-1.264 3.157-3.475 5.938-6.573 8.214-3.221 1.515-7.898 2.404-13.964 2.404-10.615-0.316-17.249-3.855-19.967-10.618-2.211-6.573-3.223-13.017-2.907-19.209v-161.956c0-2.273 0.126-4.865 0.38-7.772 0.568-3.411 1.454-6.824 2.527-10.233 2.717-7.775 9.352-11.756 19.967-12.007 6.067 0 10.744 1.261 13.964 3.791 3.098 2.15 5.309 4.867 6.573 8.216 1.96 7.33 2.782 13.33 2.527 18.007v47.837h72.73v-41.328c-1.451-61.547-33.364-93.015-95.794-94.469-62.685 1.454-94.53 32.922-95.607 94.343v148.937z" />
<glyph unicode="&#xe616;" glyph-name="event_note" d="M598 426v-84h-300v84h300zM810 214v468h-596v-468h596zM810 896c46 0 86-40 86-86v-596c0-46-40-86-86-86h-596c-48 0-86 40-86 86v596c0 46 38 86 86 86h42v86h86v-86h340v86h86v-86h42zM726 598v-86h-428v86h428z" />
<glyph unicode="&#xe61d;" glyph-name="phone-talk" d="M640 512c0 70-58 128-128 128v86c118 0 214-96 214-214h-86zM810 512c0 166-132 298-298 298v86c212 0 384-172 384-384h-86zM854 362c24 0 42-18 42-42v-150c0-24-18-42-42-42-400 0-726 326-726 726 0 24 18 42 42 42h150c24 0 42-18 42-42 0-54 8-104 24-152 4-14 2-32-10-44l-94-94c62-122 162-220 282-282l94 94c12 12 30 14 44 10 48-16 98-24 152-24z" />
<glyph unicode="&#xe80b;" glyph-name="public" d="M764 282c56 60 90 142 90 230 0 142-88 266-214 316v-18c0-46-40-84-86-84h-84v-86c0-24-20-42-44-42h-84v-86h256c24 0 42-18 42-42v-128h42c38 0 70-26 82-60zM470 174v82c-46 0-86 40-86 86v42l-204 204c-6-24-10-50-10-76 0-174 132-318 300-338zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe8b3;" glyph-name="restore" d="M512 682h64v-180l150-90-32-52-182 110v212zM554 896c212 0 384-172 384-384s-172-384-384-384c-106 0-200 42-270 112l60 62c54-54 128-88 210-88 166 0 300 132 300 298s-134 298-300 298-298-132-298-298h128l-172-172-4 6-166 166h128c0 212 172 384 384 384z" />
<glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
<glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
<glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,222 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M512 342h64v180l150 90-32 52-182-110v-212zM554 128c212 0 384 172 384 384s-172 384-384 384c-106 0-200-42-270-112l60-62c54 54 128 88 210 88 166 0 300-132 300-298s-134-298-300-298-298 132-298 298h128l-172 172-4-6-166-166h128c0-212 172-384 384-384z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"restore"
],
"defaultCode": 59571,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "history, restore",
"id": 385,
"order": 930,
"prevSize": 24,
"code": 59571,
"name": "restore"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 385
},
{
"icon": {
"paths": [
"M426 256l256 256-256 256-60-60 196-196-196-196z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"navigate_next"
],
"defaultCode": 58377,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "chevron_right, navigate_next",
"id": 153,
"order": 927,
"prevSize": 24,
"code": 58377,
"name": "navigate_next"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 0
},
{
"icon": {
"paths": [
"M128 256h768v86h-768v-86zM128 554v-84h768v84h-768zM128 768v-86h768v86h-768z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"menu"
],
"defaultCode": 58834,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "menu",
"id": 489,
"order": 926,
"prevSize": 24,
"code": 58834,
"name": "menu"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 1
},
{
"icon": {
"paths": [
"M854 470v84h-520l238 240-60 60-342-342 342-342 60 60-238 240h520z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"arrow_back"
],
"defaultCode": 58820,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "arrow_back",
"id": 45,
"order": 924,
"prevSize": 24,
"code": 58820,
"name": "arrow_back"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 2
},
{
"icon": {
"paths": [
"M658 316l-196 196 196 196-60 60-256-256 256-256z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"navigate_before"
],
"defaultCode": 58376,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "chevron_left, navigate_before",
"id": 152,
"order": 923,
"prevSize": 24,
"code": 58376,
"name": "navigate_before"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 3
},
{
"icon": {
"paths": [
"M764 742c56-60 90-142 90-230 0-142-88-266-214-316v18c0 46-40 84-86 84h-84v86c0 24-20 42-44 42h-84v86h256c24 0 42 18 42 42v128h42c38 0 70 26 82 60zM470 850v-82c-46 0-86-40-86-86v-42l-204-204c-6 24-10 50-10 76 0 174 132 318 300 338zM512 86c236 0 426 190 426 426s-190 426-426 426-426-190-426-426 190-426 426-426z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"public"
],
"defaultCode": 59403,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "public",
"id": 605,
"order": 920,
"prevSize": 24,
"code": 59403,
"name": "public"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 4
},
{
"icon": {
"paths": [
"M598 598v84h-300v-84h300zM810 810v-468h-596v468h596zM810 128c46 0 86 40 86 86v596c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h42v-86h86v86h340v-86h86v86h42zM726 426v86h-428v-86h428z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"event_note"
],
"defaultCode": 58902,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "event_note",
"id": 252,
"order": 919,
"prevSize": 24,
"code": 58902,
"name": "event_note"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 5
},
{
"icon": {
"paths": [
"M512 854c166 0 298-134 298-300s-132-298-298-298-298 132-298 298 132 300 298 300zM812 316c52 66 84 148 84 238 0 212-172 384-384 384s-384-172-384-384 172-384 384-384c90 0 174 34 240 86l60-62c22 18 42 38 60 60zM470 598v-256h84v256h-84zM640 42v86h-256v-86h256z"
],
"attrs": [],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"timer"
],
"defaultCode": 58405,
"grid": 24
},
"attrs": [],
"properties": {
"ligatures": "timer",
"id": 760,
"order": 928,
"prevSize": 24,
"code": 58405,
"name": "timer"
},
"setIdx": 1,
"setId": 1,
"iconIdx": 6
},
{
"icon": {
"paths": [
@@ -24,9 +240,9 @@
"code": 57770,
"name": "bluetooth"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 79
"setIdx": 1,
"setId": 1,
"iconIdx": 7
},
{
"icon": {
@@ -51,9 +267,9 @@
"code": 58128,
"name": "headset"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 376
"setIdx": 1,
"setId": 1,
"iconIdx": 8
},
{
"icon": {
@@ -78,9 +294,9 @@
"code": 58909,
"name": "phone-talk"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 566
"setIdx": 1,
"setId": 1,
"iconIdx": 9
},
{
"icon": {
@@ -107,7 +323,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 40
"iconIdx": 10
},
{
"icon": {
@@ -136,7 +352,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 41
"iconIdx": 11
},
{
"icon": {
@@ -163,7 +379,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 42
"iconIdx": 12
},
{
"icon": {
@@ -190,7 +406,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 43
"iconIdx": 13
},
{
"icon": {
@@ -219,7 +435,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 0
"iconIdx": 14
},
{
"icon": {
@@ -248,7 +464,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 1
"iconIdx": 15
},
{
"icon": {
@@ -277,7 +493,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 2
"iconIdx": 16
},
{
"icon": {
@@ -306,7 +522,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 3
"iconIdx": 17
},
{
"icon": {
@@ -335,7 +551,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 4
"iconIdx": 18
},
{
"icon": {
@@ -361,7 +577,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 5
"iconIdx": 19
},
{
"icon": {
@@ -387,7 +603,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 6
"iconIdx": 20
},
{
"icon": {
@@ -413,7 +629,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 7
"iconIdx": 21
},
{
"icon": {
@@ -439,7 +655,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 8
"iconIdx": 22
},
{
"icon": {
@@ -465,7 +681,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 9
"iconIdx": 23
},
{
"icon": {
@@ -491,7 +707,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 10
"iconIdx": 24
},
{
"icon": {
@@ -517,7 +733,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 11
"iconIdx": 25
},
{
"icon": {
@@ -535,7 +751,7 @@
"attrs": [],
"properties": {
"id": 10,
"order": 900,
"order": 922,
"ligatures": "expand_less",
"prevSize": 32,
"code": 59679,
@@ -543,7 +759,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 12
"iconIdx": 26
},
{
"icon": {
@@ -569,7 +785,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 13
"iconIdx": 27
},
{
"icon": {
@@ -595,7 +811,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 14
"iconIdx": 28
},
{
"icon": {
@@ -621,7 +837,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 15
"iconIdx": 29
},
{
"icon": {
@@ -647,7 +863,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 16
"iconIdx": 30
},
{
"icon": {
@@ -673,7 +889,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 17
"iconIdx": 31
},
{
"icon": {
@@ -699,7 +915,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 18
"iconIdx": 32
},
{
"icon": {
@@ -725,7 +941,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 19
"iconIdx": 33
},
{
"icon": {
@@ -751,7 +967,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 20
"iconIdx": 34
},
{
"icon": {
@@ -777,7 +993,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 21
"iconIdx": 35
},
{
"icon": {
@@ -803,7 +1019,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 22
"iconIdx": 36
},
{
"icon": {
@@ -829,7 +1045,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 23
"iconIdx": 37
},
{
"icon": {
@@ -855,7 +1071,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 24
"iconIdx": 38
},
{
"icon": {
@@ -881,7 +1097,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 25
"iconIdx": 39
},
{
"icon": {
@@ -907,7 +1123,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 26
"iconIdx": 40
},
{
"icon": {
@@ -933,7 +1149,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 27
"iconIdx": 41
},
{
"icon": {
@@ -959,7 +1175,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 28
"iconIdx": 42
},
{
"icon": {
@@ -985,7 +1201,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 29
"iconIdx": 43
},
{
"icon": {
@@ -1011,7 +1227,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 30
"iconIdx": 44
},
{
"icon": {
@@ -1037,7 +1253,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 31
"iconIdx": 45
},
{
"icon": {
@@ -1063,7 +1279,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 32
"iconIdx": 46
},
{
"icon": {
@@ -1089,7 +1305,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 33
"iconIdx": 47
},
{
"icon": {
@@ -1118,7 +1334,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 34
"iconIdx": 48
},
{
"icon": {
@@ -1148,7 +1364,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 35
"iconIdx": 49
},
{
"icon": {
@@ -1178,7 +1394,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 36
"iconIdx": 50
},
{
"icon": {
@@ -1204,7 +1420,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 37
"iconIdx": 51
},
{
"icon": {
@@ -1230,7 +1446,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 38
"iconIdx": 52
},
{
"icon": {
@@ -1256,7 +1472,7 @@
},
"setIdx": 1,
"setId": 1,
"iconIdx": 39
"iconIdx": 53
}
],
"height": 1024,

BIN
images/calendar@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images/calendar@3x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<g stroke-width="1pt">
<path fill="#006" d="M0 0h640v480H0z"/>
<path d="M0 0v27.95L307.037 250h38.647v-27.95L38.647 0H0zm345.684 0v27.95L38.647 250H0v-27.95L307.037 0h38.647z" fill="#fff"/>
<path d="M144.035 0v250h57.614V0h-57.615zM0 83.333v83.333h345.684V83.333H0z" fill="#fff"/>
<path d="M0 100v50h345.684v-50H0zM155.558 0v250h34.568V0h-34.568zM0 250l115.228-83.334h25.765L25.765 250H0zM0 0l115.228 83.333H89.463L0 18.633V0zm204.69 83.333L319.92 0h25.764L230.456 83.333H204.69zM345.685 250l-115.228-83.334h25.765l89.464 64.7V250z" fill="#c00"/>
<path d="M299.762 392.523l-43.653 3.795 6.013 43.406-30.187-31.764-30.186 31.764 6.014-43.406-43.653-3.795 37.68-22.364-24.244-36.495 40.97 15.514 13.42-41.713 13.42 41.712 40.97-15.515-24.242 36.494m224.444 62.372l-10.537-15.854 17.81 6.742 5.824-18.125 5.825 18.126 17.807-6.742-10.537 15.854 16.37 9.718-18.965 1.65 2.616 18.85-13.116-13.793-13.117 13.794 2.616-18.85-18.964-1.65m16.368-291.815l-10.537-15.856 17.81 6.742 5.824-18.122 5.825 18.12 17.807-6.74-10.537 15.855 16.37 9.717-18.965 1.65 2.616 18.85-13.116-13.793-13.117 13.794 2.616-18.85-18.964-1.65m-89.418 104.883l-10.537-15.853 17.808 6.742 5.825-18.125 5.825 18.125 17.808-6.742-10.536 15.853 16.37 9.72-18.965 1.65 2.615 18.85-13.117-13.795-13.117 13.795 2.617-18.85-18.964-1.65m216.212-37.929l-10.558-15.854 17.822 6.742 5.782-18.125 5.854 18.125 17.772-6.742-10.508 15.854 16.362 9.718-18.97 1.65 2.608 18.85-13.118-13.793-13.117 13.793 2.61-18.85-18.936-1.65m-22.251 73.394l-10.367 6.425 2.914-11.84-9.316-7.863 12.165-.896 4.605-11.29 4.606 11.29 12.165.897-9.317 7.863 2.912 11.84" fill-rule="evenodd" fill="#fff"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<g transform="translate(74.118) scale(.9375)">
<path fill="#fff" d="M81.137 0h362.276v512H81.137z"/>
<path fill="#bf0a30" d="M-100 0H81.138v512H-100zm543.413 0H624.55v512H443.414zM135.31 247.41l-14.067 4.808 65.456 57.446c4.95 14.764-1.72 19.116-5.97 26.86l71.06-9.02-1.85 71.512 14.718-.423-3.21-70.918 71.13 8.432c-4.402-9.297-8.32-14.233-4.247-29.098l65.414-54.426-11.447-4.144c-9.36-7.222 4.044-34.784 6.066-52.178 0 0-38.195 13.135-40.698 6.262l-9.727-18.685-34.747 38.17c-3.796.91-5.413-.6-6.304-3.808l16.053-79.766-25.42 14.297c-2.128.91-4.256.125-5.658-2.355l-24.45-49.06-25.21 50.95c-1.9 1.826-3.803 2.037-5.382.796l-24.204-13.578 14.53 79.143c-1.156 3.14-3.924 4.025-7.18 2.324l-33.216-37.737c-4.345 6.962-7.29 18.336-13.033 20.885-5.744 2.387-24.98-4.823-37.873-7.637 4.404 15.895 18.176 42.302 9.46 50.957z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 934 B

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<path fill="#ffce00" d="M0 320h640v160.002H0z"/>
<path d="M0 0h640v160H0z"/>
<path fill="#d00" d="M0 160h640v160H0z"/>
</svg>

Before

Width:  |  Height:  |  Size: 220 B

View File

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<g fill-rule="evenodd" stroke-width="1pt">
<path fill="#fff" d="M0 0h640v480H0z"/>
<path fill="#00267f" d="M0 0h213.337v480H0z"/>
<path fill="#f31830" d="M426.662 0H640v480H426.662z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 301 B

View File

@@ -1,15 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<defs>
<clipPath id="a">
<path fill-opacity=".67" d="M-85.333 0h682.67v512h-682.67z"/>
</clipPath>
</defs>
<g clip-path="url(#a)" transform="translate(80) scale(.94)">
<g stroke-width="1pt">
<path fill="#006" d="M-256 0H768.02v512.01H-256z"/>
<path d="M-256 0v57.244l909.535 454.768H768.02V454.77L-141.515 0H-256zM768.02 0v57.243L-141.515 512.01H-256v-57.243L653.535 0H768.02z" fill="#fff"/>
<path d="M170.675 0v512.01h170.67V0h-170.67zM-256 170.67v170.67H768.02V170.67H-256z" fill="#fff"/>
<path d="M-256 204.804v102.402H768.02V204.804H-256zM204.81 0v512.01h102.4V0h-102.4zM-256 512.01L85.34 341.34h76.324l-341.34 170.67H-256zM-256 0L85.34 170.67H9.016L-256 38.164V0zm606.356 170.67L691.696 0h76.324L426.68 170.67h-76.324zM768.02 512.01L426.68 341.34h76.324L768.02 473.848v38.162z" fill="#c00"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 956 B

View File

@@ -1,18 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="640" viewBox="0 0 640 480">
<g fill-rule="evenodd" transform="scale(.9375)">
<g stroke-width="1pt">
<path d="M0 0h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#bd3d44"/>
<path d="M0 39.385h972.81V78.77H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0zm0 78.77h972.81v39.385H0z" fill="#fff"/>
</g>
<path fill="#192f5d" d="M0 0h389.12v275.69H0z"/>
<g fill="#fff">
<path d="M32.427 11.8l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 39.37l3.54 10.896h11.458L70.583 57l3.542 10.897-9.27-6.734-9.269 6.734L59.126 57l-9.269-6.734h11.458zm64.852 0l3.54 10.896h11.457L135.435 57l3.54 10.897-9.268-6.734-9.27 6.734L123.978 57l-9.27-6.734h11.458zm64.855 0l3.54 10.896h11.458L200.29 57l3.541 10.897-9.27-6.734-9.268 6.734L188.833 57l-9.269-6.734h11.457zm64.855 0l3.54 10.896h11.458L265.145 57l3.541 10.897-9.269-6.734-9.27 6.734L253.69 57l-9.27-6.734h11.458zm64.852 0l3.54 10.896h11.457L329.997 57l3.54 10.897-9.268-6.734-9.27 6.734L318.54 57l-9.27-6.734h11.458zM32.427 66.939l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 94.508l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zM32.427 122.078l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 149.647l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
<g>
<path d="M32.427 177.217l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458zM64.855 204.786l3.54 10.897h11.458l-9.27 6.734 3.542 10.897-9.27-6.734-9.269 6.734 3.54-10.897-9.269-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.27-6.734-9.268 6.734 3.54-10.897-9.269-6.734h11.457zm64.855 0l3.54 10.897h11.458l-9.27 6.734 3.541 10.897-9.269-6.734-9.27 6.734 3.542-10.897-9.27-6.734h11.458zm64.852 0l3.54 10.897h11.457l-9.269 6.734 3.54 10.897-9.268-6.734-9.27 6.734 3.541-10.897-9.27-6.734h11.458z"/>
</g>
<g>
<path d="M32.427 232.356l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.853 0l3.541 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735H93.74zm64.856 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.269 6.734 3.54-10.896-9.269-6.735h11.458zm64.852 0l3.54 10.896h11.457l-9.269 6.735 3.54 10.896-9.268-6.734-9.27 6.734 3.541-10.896-9.27-6.735h11.458zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.27-6.734-9.268 6.734 3.54-10.896-9.269-6.735h11.457zm64.855 0l3.54 10.896h11.458l-9.27 6.735 3.541 10.896-9.269-6.734-9.27 6.734 3.542-10.896-9.27-6.735h11.458z"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

11
images/googleLogo.svg Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" viewBox="0 0 48 48" class="abcRioButtonSvg">
<g>
<path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"></path>
<path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"></path>
<path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"></path>
<path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"></path>
<path fill="none" d="M0 0h48v48H0z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@@ -4,6 +4,9 @@
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--#include virtual="base.html" -->
<link rel="stylesheet" href="css/all.css">
<script>
window.indexLoadedTime = window.performance.now();
console.log("(TIME) index.html loaded:\t", indexLoadedTime);
@@ -134,8 +137,8 @@
<script src="libs/lib-jitsi-meet.min.js?v=139"></script>
<script src="libs/app.bundle.min.js?v=139"></script>
<!--#include virtual="title.html" -->
<link rel="stylesheet" href="css/all.css">
<!--#include virtual="plugin.head.html" -->
<!--#include virtual="static/welcomePageAdditionalContent.html" -->
</head>
<body>
<div id="react"></div>

View File

@@ -24,6 +24,7 @@ var interfaceConfig = {
BRAND_WATERMARK_LINK: '',
SHOW_POWERED_BY: false,
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
DISPLAY_WELCOME_PAGE_CONTENT: true,
APP_NAME: 'Jitsi Meet',
LANG_DETECTION: false, // Allow i18n to detect the system language
INVITATION_POWERED_BY: true,
@@ -40,7 +41,7 @@ var interfaceConfig = {
TOOLBAR_BUTTONS: [
// main toolbar
'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup',
'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup',
// extended toolbar
'profile', 'contacts', 'info', 'chat', 'recording', 'etherpad', 'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip' ],
@@ -49,7 +50,7 @@ var interfaceConfig = {
* Main Toolbar Buttons
* All of them should be in TOOLBAR_BUTTONS
*/
MAIN_TOOLBAR_BUTTONS: [ 'microphone', 'camera', 'desktop', 'invite', 'fullscreen', 'fodeviceselection', 'hangup' ],
MAIN_TOOLBAR_BUTTONS: [ 'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup' ],
SETTINGS_SECTIONS: [ 'language', 'devices', 'moderator' ],
INVITE_OPTIONS: [ 'invite', 'dialout', 'addtocall' ],
@@ -150,6 +151,21 @@ var interfaceConfig = {
* @type {boolean}
*/
VIDEO_QUALITY_LABEL_DISABLED: false
/**
* Specify custom URL for downloading android mobile app.
*/
// MOBILE_DOWNLOAD_LINK_ANDROID: 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
/**
* Specify URL for downloading ios mobile app.
*/
// MOBILE_DOWNLOAD_LINK_IOS: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905',
/**
* Specify mobile app scheme for opening the app from the mobile browser.
*/
// MOBILE_APP_SCHEME: 'org.jitsi.meet'
};
/* eslint-enable no-unused-vars, no-var, max-len */

View File

@@ -25,8 +25,13 @@ target 'JitsiMeet' do
:path => '../node_modules/react-native-fetch-blob'
pod 'react-native-keep-awake',
:path => '../node_modules/react-native-keep-awake'
pod 'react-native-locale-detector',
:path => '../node_modules/react-native-locale-detector'
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
pod 'RNSound', :path => '../node_modules/react-native-sound'
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
pod 'react-native-calendar-events',
:path => '../node_modules/react-native-calendar-events'
end
post_install do |installer|

View File

@@ -1,52 +1,63 @@
PODS:
- React (0.49.5):
- React/Core (= 0.49.5)
- React (0.51.0):
- React/Core (= 0.51.0)
- react-native-background-timer (2.0.0):
- React
- react-native-calendar-events (1.4.3):
- React
- react-native-fetch-blob (0.10.6):
- React/Core
- react-native-keep-awake (2.0.6):
- React
- react-native-locale-detector (1.0.0):
- React
- react-native-webrtc (1.58.2)
- React/BatchedBridge (0.49.5):
- React/BatchedBridge (0.51.0):
- React/Core
- React/cxxreact_legacy
- React/Core (0.49.5):
- yoga (= 0.49.5.React)
- React/cxxreact_legacy (0.49.5):
- React/Core (0.51.0):
- yoga (= 0.51.0.React)
- React/cxxreact_legacy (0.51.0):
- React/jschelpers_legacy
- React/DevSupport (0.49.5):
- React/DevSupport (0.51.0):
- React/Core
- React/RCTWebSocket
- React/fishhook (0.49.5)
- React/jschelpers_legacy (0.49.5)
- React/RCTActionSheet (0.49.5):
- React/fishhook (0.51.0)
- React/jschelpers_legacy (0.51.0)
- React/RCTActionSheet (0.51.0):
- React/Core
- React/RCTAnimation (0.49.5):
- React/RCTAnimation (0.51.0):
- React/Core
- React/RCTBlob (0.49.5):
- React/RCTBlob (0.51.0):
- React/Core
- React/RCTImage (0.49.5):
- React/RCTImage (0.51.0):
- React/Core
- React/RCTNetwork
- React/RCTLinkingIOS (0.49.5):
- React/RCTLinkingIOS (0.51.0):
- React/Core
- React/RCTNetwork (0.49.5):
- React/RCTNetwork (0.51.0):
- React/Core
- React/RCTText (0.49.5):
- React/RCTText (0.51.0):
- React/Core
- React/RCTWebSocket (0.49.5):
- React/RCTWebSocket (0.51.0):
- React/Core
- React/fishhook
- React/RCTBlob
- RNSound (0.10.4):
- React/Core
- RNSound/Core (= 0.10.4)
- RNSound/Core (0.10.4):
- React/Core
- RNVectorIcons (4.4.2):
- React
- yoga (0.49.5.React)
- yoga (0.51.0.React)
DEPENDENCIES:
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- react-native-calendar-events (from `../node_modules/react-native-calendar-events`)
- react-native-fetch-blob (from `../node_modules/react-native-fetch-blob`)
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
- react-native-locale-detector (from `../node_modules/react-native-locale-detector`)
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
- React/BatchedBridge (from `../node_modules/react-native`)
- React/Core (from `../node_modules/react-native`)
@@ -58,6 +69,7 @@ DEPENDENCIES:
- React/RCTNetwork (from `../node_modules/react-native`)
- React/RCTText (from `../node_modules/react-native`)
- React/RCTWebSocket (from `../node_modules/react-native`)
- RNSound (from `../node_modules/react-native-sound`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
@@ -66,26 +78,35 @@ EXTERNAL SOURCES:
:path: ../node_modules/react-native
react-native-background-timer:
:path: ../node_modules/react-native-background-timer
react-native-calendar-events:
:path: ../node_modules/react-native-calendar-events
react-native-fetch-blob:
:path: ../node_modules/react-native-fetch-blob
react-native-keep-awake:
:path: ../node_modules/react-native-keep-awake
react-native-locale-detector:
:path: ../node_modules/react-native-locale-detector
react-native-webrtc:
:path: ../node_modules/react-native-webrtc
RNSound:
:path: ../node_modules/react-native-sound
RNVectorIcons:
:path: ../node_modules/react-native-vector-icons
yoga:
:path: ../node_modules/react-native/ReactCommon/yoga
SPEC CHECKSUMS:
React: 9d5a23842dcc75ffef540ee2d2ef0eee1904ee58
react-native-background-timer: 10063c04bf85d7f8811dff8c74399f0aa715245f
react-native-fetch-blob: 2bef9be702de8726f4d7bf58d2345579aaaee60d
react-native-keep-awake: bb4dbb6fd21a7879432f9538b0b7d71398fe9f81
react-native-webrtc: 6fd0b3aa890d7a9b9b4d01d30f958d17ae88a785
RNVectorIcons: c1821d56c775cc5a3bca66c77dfc8cb4a90d27e2
yoga: 596e987aa8aac0165abb235d2977982f090476a0
React: 541ba768b9855e10cdc76f55427a5cd0653ca806
react-native-background-timer: 63dcbf37dbcf294b5c6c071afcdc661fa06a7594
react-native-calendar-events: fe6fbc8ed337a7423c98f2c9012b25f20444de09
react-native-fetch-blob: 63394b1d7b0781547b3e4463b3195790177b1222
react-native-keep-awake: 0de4bd66de0c23178107dce0c2fcc3354b2a8e94
react-native-locale-detector: d1b2c6fe5abb56e3a1efb6c2d6f308c05c4251f1
react-native-webrtc: bc044ca9530fc802e7533f247aa08fe1b6bf8dc5
RNSound: d0818fe2435254fe30540fae48a429c5ffb72e09
RNVectorIcons: c0dbfbf6068fefa240c37b0f71bd03b45dddac44
yoga: 17521bbb0dd54a47c0b3ac43253e78cdac7488e0
PODFILE CHECKSUM: a7cb8c7365f8cf9a01ee4eb78325139933776faf
PODFILE CHECKSUM: 4a5a310403b99b9c2d619e0b18da89bf0fe5858c
COCOAPODS: 1.3.1
COCOAPODS: 1.4.0

View File

@@ -53,14 +53,24 @@ partial URL (e.g. a room name only) is specified to
`loadURLString:`/`loadURLObject:`. If not set or if set to `nil`, the default
built in JavaScript is used: https://meet.jit.si.
NOTE: Must be set before `loadURL:`/`loadURLString:` for it to take effect.
NOTE: Must be set (if at all) before `loadURL:`/`loadURLString:` for it to take
effect.
#### pictureInPictureEnabled
Property to get / set whether Picture-in-Picture is enabled. Defaults to `YES`
if `delegate` implements `enterPictureInPicture:`; otherwise, `NO`.
NOTE: Must be set (if at all) before `loadURL:`/`loadURLString:` for it to take
effect.
#### welcomePageEnabled
Property to get/set whether the Welcome page is enabled. If `NO`, a black empty
view will be rendered when not in a conference. Defaults to `NO`.
NOTE: Must be set before `loadURL:`/`loadURLString:` for it to take effect.
NOTE: Must be set (if at all) before `loadURL:`/`loadURLString:` for it to take
effect.
#### loadURL:NSURL
@@ -170,6 +180,16 @@ Called before a conference is left.
The `data` dictionary contains a "url" key with the conference URL.
#### enterPictureInPicture
Called when entering Picture-in-Picture is requested by the user. The app should
now activate its Picture-in-Picture implementation (and resize the associated
`JitsiMeetView`. The latter will automatically detect its new size and adjust
its user interface to a variant appropriate for the small size ordinarily
associated with Picture-in-Picture.)
The `data` dictionary is empty.
#### loadConfigError
Called when loading the main configuration file from the Jitsi Meet deployment
@@ -178,3 +198,17 @@ fails.
The `data` dictionary contains an "error" key with the error and a "url" key
with the conference URL which necessitated the loading of the configuration
file.
### Picture-in-Picture
`JitsiMeetView` will automatically adjust its UI when presented in a
Picture-in-Picture style scenario, in a rectangle too small to accommodate its
"full" UI.
Jitsi Meet SDK does not currently implement native Picture-in-Picture on iOS. If
desired, apps need to implement non-native Picture-in-Picture themselves and
resize `JitsiMeetView`.
If `pictureInPictureEnabled` is set to `YES` or `delegate` implements
`enterPictureInPicture:`, the in-call toolbar will render a button to afford the
user to request entering Picture-in-Picture.

View File

@@ -138,7 +138,7 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0920;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
@@ -321,14 +321,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -371,14 +377,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "0920"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
@@ -40,6 +40,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -59,6 +60,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -2,103 +2,109 @@
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
"size" : "29x29",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
"scale" : "2x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
"size" : "40x40",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
"scale" : "2x"
},
{
"filename" : "AppIcon-83.5@2x.png",
"size" : "83.5x83.5",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
"filename" : "AppIcon-83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "AppIcon-1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

View File

@@ -2,103 +2,109 @@
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
"scale" : "3x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
"size" : "29x29",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
"scale" : "2x"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
"size" : "40x40",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
"scale" : "2x"
},
{
"filename" : "AppIcon-83.5@2x.png",
"size" : "83.5x83.5",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
"filename" : "AppIcon-83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "AppIcon-1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
"version" : 1,
"author" : "xcode"
}
}

Some files were not shown because too many files have changed in this diff Show More