Compare commits

...

107 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
87d6eed612 rn,sdk: bump version to 2.7.0 2020-03-25 09:29:55 +01:00
Saúl Ibarra Corretgé
cdc14586de invite: remove duplicated code
Add ability to invite users which will use the share sheet or dialog
dynamically.
2020-03-24 14:28:26 +01:00
Saúl Ibarra Corretgé
a7f8bf2d8f rn,overflowmenu: reorder 2020-03-24 14:28:26 +01:00
Saúl Ibarra Corretgé
8cd881945a invite: merge InviteButton and InfoDialogButton on mobile 2020-03-24 14:28:26 +01:00
Saúl Ibarra Corretgé
579d08e27e bottom-sheet: tweak UI
- re-add thepand icon, shaped like a pill
- round top corners
2020-03-24 14:28:26 +01:00
Ansgar Burchardt
5148c81dd8 doc: quick-install.md: link to english version of doc how to change hostname 2020-03-24 14:09:45 +01:00
skiqoapsdt20
40bc844caa Update README.md (#5347) 2020-03-24 11:57:46 +01:00
Saúl Ibarra Corretgé
c990a64ba9 blur: don't persist settings 2020-03-24 11:56:01 +01:00
damencho
f5a0a1ef8c Use community forum for support not github. 2020-03-24 06:31:15 +01:00
Jaya Allamsetty
58018a086c fix(blur): Disable blur on conference leave 2020-03-23 20:55:46 -04:00
damencho
b3a7f5f38b Removes not needed file. 2020-03-23 17:33:10 -05:00
damencho
435d11793d Updates debian compat level. 2020-03-23 17:33:10 -05:00
Saúl Ibarra Corretgé
9ec3faa6b3 lint: run linter using GH Actions 2020-03-23 22:13:22 +01:00
Kenneth Thorman
959d61468e lang: add danish translation 2020-03-23 20:19:37 +01:00
bgrozev
9f28048742 Fix eslint errors. (#5341) 2020-03-23 13:56:32 -05:00
Ravinou
19c9a808cf Update main-fr.json (#5301)
"cryptée" does not exist in french, it's "chiffrée" here. More informations about this here : https://chiffrer.info/
2020-03-23 14:56:25 +01:00
Felix Wolfsteller
7576f850e9 config: add trailing commas and 'end' entry for peacy JSON
Prevent possible json parse errors when the configuration values are
commented or commented out.
2020-03-23 14:06:51 +01:00
Anna-Katharina Wickert
7970b38823 lang: change inaccurate translation of toggle camera (german)
Change inaccurate translation of toggle camera.
2020-03-23 14:01:34 +01:00
simevo
b40363be31 doc: make clear that /etc/hostname must match /etc/hosts
fixes #5260 (#5279)
2020-03-23 13:53:27 +01:00
yanas
9a0b924f99 Merge pull request #5322 from jitsi/update-js-utils
chore(package.json): Update js-utils.
2020-03-22 13:49:53 -05:00
Hristo Terezov
52def54cd9 chore(package.json): Update js-utils. 2020-03-22 13:13:22 -05:00
Zoltan Bettenbuk
8d3b59a0d0 rn: lonely meeting experience 2020-03-20 18:30:46 +01:00
Saúl Ibarra Corretgé
b0e7471a83 android: revert back to SW decoding
We see tons of crashes on Samsung and Huawei devices. It's really not worth the
headache anymore.
2020-03-20 13:39:48 +01:00
horymury
4616065b1d external_api: add ability to send a text message through datachannels 2020-03-20 12:51:26 +01:00
paweldomas
14855f3255 fix(features/notifications): crash on undefined participant 2020-03-20 05:43:44 -05:00
Julian1203
c40a7f736e Update main-de.json
Fixed a lot of punctuation and spelling mistakes. "Speaker" means "Lautsprecher" in the context of audio devices. Rephrased a sentence to make it sound better.
2020-03-20 05:42:49 -05:00
Martin Myska
8ffd226159 updated translation and added missing strings 2020-03-19 12:30:12 -05:00
filippogiordano
b8dda4c6c2 Update main-it.json
Error correction in "appDescription" (open course instead of open source).
2020-03-19 12:50:34 +01:00
Дамян Минков
fca4977987 Merge pull request #5235 from chipechop/patch-2
ITALIAN translation - added last missing string
2020-03-18 14:50:38 -05:00
chipechop
7bcece52ea Missing and wrong Italian translation
Hi,
I added some missing translations and changed some that were wrong, or improvable: from a 70% translation and a 30% missing, to what I think should be an 85%-90% of translated lines.

I really wish to express my personal compliments to the persons that made the core translation, because it is very fluid, original and smart.

(tell me what I should have to do: I'm pretty new to GitHub)
2020-03-18 14:50:28 -05:00
chipechop
155c6de822 ITALIAN translation - added last missing string
I added Afrikaans missing string
2020-03-18 18:48:42 +01:00
Horatiu Muresan
d0bc3da0f5 Disable kick participant button for guests 2020-03-18 15:26:11 +01:00
Arzar
011b7f9d00 fix(external_api): Pass Feature-Policy display-capture to the iframe
Starting from version 74, firefox need to be explicitly allowed to capture the screen from an iframe for screensharing. This new Feature-Policy is called "display-capture".
See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy/display-capture
2020-03-18 08:57:11 -04:00
James Addison
9b0f5b0299 doc(quick install) Minor typo fixup (#5222) 2020-03-18 13:19:51 +01:00
Falco Nogatz
7e21c277b3 lang: fix spelling mistake in translations of "feedback" 2020-03-18 11:43:03 +01:00
raphj
e6ade2cf84 doc (quick install): Add the domain to /etc/hosts 2020-03-18 11:40:27 +01:00
Cyril Brulebois
99b21cdb2a doc: fix typos in quick install guide 2020-03-18 10:52:09 +01:00
sicherist
677752c78d lang: fix inaccurate translation of "toggleCamera" 2020-03-18 10:14:32 +01:00
yanas
2dd5d0a180 Merge pull request #5205 from jitsi/update-lib
chore(package.json): Update lib-jitsi-meet.
2020-03-17 09:54:53 -05:00
Hristo Terezov
ccdfff8e9a chore(package.json): Update lib-jitsi-meet. 2020-03-17 09:23:55 -05:00
Martin
829e3bfe15 doc: add nginx config for the electron version in manual install doc 2020-03-17 11:41:21 +01:00
Jaya Allamsetty
e90cc0a615 fix(Amplitude): Blacklist 'peer.conn.status.duration' stats 2020-03-16 15:55:11 -04:00
KwadroNaut
b6ccc91038 Correct link regarding FAQ NAT install
Broken link, I presume this one was meant.
2020-03-16 12:57:38 -05:00
Jaya Allamsetty
beb4487044 deps: update LJM for adding p2p status to transport.stats in Amplitude 2020-03-16 13:46:16 -04:00
damencho
add84af7b6 deps: update LJM, updates the params passed to statistics (disable app logs) 2020-03-15 17:13:59 -05:00
damencho
cb0d10fbe1 deps: update LJM for adding new option to disable callstats app logs 2020-03-15 15:48:41 -05:00
Jaya Allamsetty
9a162c266c deps: update LJM for adding the transport type Amplitude event 2020-03-13 18:56:49 -04:00
paweldomas
6654531112 desp: update LJM to bring in fix for a crash on BOSH item-not-found
Updates lib-jitsi-meet to e3533220023cb3f5c727ac5b27dc18552acef5c9
2020-03-13 11:57:11 -07:00
Mihai Uscat
b9cc6b6f96 fix(mute): Replace icon 2020-03-13 14:55:29 +01:00
paweldomas
6cbc04175c deps: update LJM to bring in unload fix
Updates lib-jitsi-meet to b8f68b98be21dd1956238da6a53d1503b7ceaf7d
which brings in feature discovery optimization and the unload handler
fix for BOSH.
2020-03-12 13:21:05 -07:00
paweldomas
fb23aa54e8 ref(VideoLayout): log participant name on feature discovery failure 2020-03-12 13:21:05 -07:00
Дамян Минков
b73d98f863 Updates jvb pid file path. 2020-03-12 14:58:27 -05:00
Tudor-Ovidiu Avram
0289a93e5a feat(close) Add promotional close page 2020-03-12 20:07:23 +01:00
paweldomas
401003b907 deps: update LJM to fix Strophe.attach not handled correctly
Updates lib-jitsi-meet to aadfce2283cad4de3cb58c2eed8e14d2ce62c465 in
order to fix "not connected" error when jiconop is enabled.
2020-03-11 10:01:44 -07:00
Saúl Ibarra Corretgé
025e2b1ecb android: simplify the creation of AudioManager
Do so on the main thread at startup and pass it along.
2020-03-11 16:27:42 +01:00
Saúl Ibarra Corretgé
05a8591110 android: make sure all AudioMode operations run in the audio thread 2020-03-11 16:27:42 +01:00
paweldomas
d2e6d57be8 deps: update LJM to fix ATTACHED state not connected
Updates lib-jitsi-meet to 567ba72675b1bfd5931e7d4936a4e53ebb4ef5f2 in
order to fix "not connected" error when jiconop is enabled.
2020-03-11 08:14:23 -07:00
paweldomas
41fd142977 deps: update LJM to bring in XMPP resume
Updates lib-jitsi-meet to 8a41d024077d1e19e41bf15ea2edd8ed8b02b85f in
order to bring in the XMPP stream resume functionality.
2020-03-11 06:56:40 -07:00
paweldomas
04c0945930 add mod_websocket_smacks.patch
The patch and Prosody 0.11 is required for the XMPP stream resume
2020-03-11 06:56:40 -07:00
paweldomas
5f2acb70de add mod_smacks.lua version c49fea05772e
https://hg.prosody.im/prosody-modules/raw-file/c49fea05772e/mod_smacks/mod_smacks.lua
2020-03-11 06:56:40 -07:00
paweldomas
4dc10e82f1 feat(mod_auth_token): add support for 'previd' query param
The 'previd' query parameter will be use to match user id of the session
being resumed when the smacks module and token authentication are
enabled in Prosody. Otherwise user gets new random id every time and
this doesn't work with the smacks module.
2020-03-11 06:56:40 -07:00
Saúl Ibarra Corretgé
582d4aff1c deps: sync package-lock.json 2020-03-10 21:04:01 +01:00
Saúl Ibarra Corretgé
b13200ac92 video-layout: fix calculating tile size for recorder
When the reccorder joins, they have a local participant, which is not rendered,
so don't count it towards the partcipant count used for computing the tile
sizes.
2020-03-10 21:04:01 +01:00
C0rn3j
53f937ba4e Update and improve manual install doc 2020-03-09 08:00:23 -05:00
paweldomas
b9addaed71 ref(log): logs device list and selected devices
Logs the device list when is updated in the reducer and removes
"button enabled" logging which used to dump the device list, but
in a useless way(Object[Object]).

Makes an attempt to log currently selected device, but because of
multiple possible paths it's impossible to find one reliable spot to log
selected device. One has to rely on device list and the GUM call logged
to figure things out.
2020-03-06 16:19:20 +01:00
Luca Bösch
fd8fb58eaf Missing german translations.
Due to the outage it wasn't possible to submit them using https://translate.jitsi.org.
Please consider adding them this way.
2020-03-06 13:19:57 +01:00
Saúl Ibarra Corretgé
38d1032fec android: disable HW accelerated decoding on Samsung
They just keep crashing.
2020-03-06 12:42:16 +01:00
Saúl Ibarra Corretgé
073fdc7b0e sperakerstats: prevent access of nil object (#5112)
If the dominant speaker leaves their object will be gone from the mapping.
2020-03-06 12:33:41 +01:00
PanderMusubi
fedaa0ae6e minimized size without quality loss via optipng 2020-03-05 15:19:26 +01:00
Gabriel Imre
f06fe69167 fix(mute): remove interface config bypass for mute-everyone button 2020-03-05 13:54:58 +01:00
bgrozev
16c09c9645 Upadte ljm (configurable pc stats interval), whitelist config options. (#5106) 2020-03-04 15:11:27 -06:00
Gabriel Imre
24a1a60f04 feat(mute): mute everyone / everyone else 2020-03-04 17:07:12 +01:00
Saúl Ibarra Corretgé
d7ece58c6f fix(optimise): cope with URL interface config overrides
Regresssion from bd8a7edbd2.

When the toolbar buttons are overridden with URL parameters, our computed set of
buttons will be wrong. Thus, compute it every time and check for the
differences.
2020-03-04 07:43:52 -06:00
Andrei Gavrilescu
aa11535db7 change you are nosiy message (#5101) 2020-03-04 15:35:22 +02:00
Hristo Terezov
eea87be801 fix(electron7):memory leak when the page is hidden
It happens when you are drawing into hidden canvas.
2020-03-03 09:28:23 +00:00
Hristo Terezov
809ac42e4c fix(largeVideo-bg):render canvas only when visible 2020-03-03 09:28:23 +00:00
Hristo Terezov
cf27ad0dde fix(stream-presenter-effect): Prevent memory leak.
On electron 7 drawing on hidden canvas will trigger a memory leak.
Not appending the canvas for the DOM seems to solve the problem.
2020-03-03 09:28:23 +00:00
Mihai Uscat
2064fc8937 fix(screenshot-capture): Prevent effect initialization on each toggle 2020-03-02 10:24:02 -05:00
Saúl Ibarra Corretgé
95eb551156 android: disable ConnectionService for the Jitsi Meet app
It's the source of uncountable problems for which we don't have a good
solution, since they are caused by buggy implementations of self-managed
connection services by manufacturers.
2020-02-26 17:09:39 +01:00
Hristo Terezov
a7ac7790a8 fix(avatars): optimise 2020-02-26 14:32:37 +00:00
Leonard Kim
94c48ec838 chore(deps): update lib to 47c2bc6
To get a workaround in for wired desktop
screensharing in spot in electron 8. With
the change, no "exact" is used in gum
constraints while attempting to get the
wired screensharing device, as that
triggers overconstrainederror.
2020-02-25 15:22:03 -08:00
Jaya Allamsetty
da68b9882d fix(screenshot-capture): Do not switch streams at the conference level.
This effect doesn't modify the media stream, so its safe to start/stop effect and not apply it on the JitsiLocalTrack. This way we can make sure that this effect is not switched out when presenter effect is applied.
2020-02-25 10:51:44 -05:00
Hristo Terezov
bd8a7edbd2 fix(optimise): mapStateToProps for some components (#5085) 2020-02-25 15:09:52 +00:00
Saúl Ibarra Corretgé
bde2343951 filmstrip: don't display toolbar for SIP gateways
Note that in the usual (vertical) setup, the "toolbar" is just the hide button.
2020-02-25 15:45:41 +01:00
Saúl Ibarra Corretgé
9b141816d6 filmstrip: hide scrollbar on SIP gateways 2020-02-25 15:45:41 +01:00
Saúl Ibarra Corretgé
6a7594cd9c toolbox: always hide for SIP gateways 2020-02-25 15:45:41 +01:00
Saúl Ibarra Corretgé
cdbc5976a0 notifications: hdie all (visual) notifications for SIP gateways 2020-02-25 15:45:41 +01:00
Saúl Ibarra Corretgé
8fd0f56be7 info-dialog: don't show when a SIP gateway joins alone 2020-02-25 15:45:41 +01:00
Saúl Ibarra Corretgé
5b0c6e088a deps: node-sass@4.13.1 2020-02-25 15:45:41 +01:00
horymury
202abf2a9a chrome-banner: add analytics 2020-02-25 13:41:13 +01:00
Horatiu Muresan
fb8ef366c6 Pass room name to IE page 2020-02-21 13:37:58 +01:00
Saúl Ibarra Corretgé
7446e6165e rn: now working on version 20.1 2020-02-21 12:47:07 +01:00
Hristo Terezov
5feaa421a8 fix(tests): bring back APP.conference.listMembers 2020-02-21 11:16:33 +00:00
Saúl Ibarra Corretgé
a4333d3a80 rn,overflow-menu: add a "more options" button 2020-02-20 17:23:13 +01:00
Saúl Ibarra Corretgé
02131f3346 full-screen: fix not re-entering full-screen after dialog is shown
This has the side effect of showing the bottom navbar when the toolbox is open,
which is a nice thing since back is accessible.
2020-02-20 16:49:20 +01:00
Jaya Allamsetty
8dbd1ba1b7 fix(presenter): go back to using standard resolutions for presenter 2020-02-19 16:02:42 -05:00
Saúl Ibarra Corretgé
4c065f2de1 android: fix getting RN version in release script 2020-02-19 15:05:32 +01:00
Saúl Ibarra Corretgé
df895e5a61 deps: react-native@custom-patched
Update the version to 0.61.5-jitsi.1 to avoid build aching problems due to the
version not changing.
2020-02-19 15:05:17 +01:00
Hristo Terezov
bbf1927c70 fix(thumbnail): Optimize status bar moderator icon (#5076)
* fix(thumbnail): Optimize status bar moderator icon

Moved all moderator functionality to react to optimize the number of
status bar updates.

* fix(RemoteVideoMenuTriggerButton): Use nullish coalescing

Co-Authored-By: Saúl Ibarra Corretgé <saghul@jitsi.org>

* ref(StatusBar): rename to StatusIndicators

* fix(RemoteVideoMenu): isModerator value.

* fix(notification): mobile.

Co-authored-by: Saúl Ibarra Corretgé <s@saghul.net>
2020-02-18 16:31:04 +00:00
horymury
86130c1478 chrome-banner: log success of retrieving configs 2020-02-18 10:56:09 +01:00
damencho
15fb8a1525 Adds a disco feature to distinguish jibri participants. 2020-02-14 21:44:19 +00:00
Saúl Ibarra Corretgé
64cbfb648f deps: react-native@custom-patched
Use RN 0.61.5 + a custom patch (submitted upstream) for fixing a crash in JSI.
2020-02-14 17:22:58 +01:00
Vincent Hou
3e40bb19cd fixed the encoded tiltle issue in chinese
Checked the code of react.native part, there's no issue by using safeDecodeURIComponent.
So fixed it in same way.
2020-02-12 15:50:55 +01:00
Bettenbuk Zoltan
bbca0fc357 allow setting the feedback percentage 2020-02-12 10:59:54 +01:00
Дамян Минков
9bb789472e Uses correct scopes for google API based on config.js values. (#5066)
* Uses correct scopes for google API based on config.js values.

* Lower the number of parameters that we pass around.

* Fixes googleAPIState state checking.
2020-02-11 15:14:01 +00:00
Hristo Terezov
06fa175a6c fix(large-video): Resize calculations.
Since the verical filmstrip doesn't set its width explicitly anymore,
calculating the available area for the large video based on the
filmstrip width retrieved from the HTML element was wrong
in the cases when the rendering and cleanup of the filmstrip hasn't
finish yet. For example when switching from tile view to stage view.
2020-02-10 20:23:37 +02:00
Hristo Terezov
5940f2890a fix(remote-control): mouse events 2020-02-07 18:57:59 +02:00
139 changed files with 4033 additions and 1277 deletions

15
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Linter
on: [pull_request]
jobs:
run-linter:
name: Run Linter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm install
- run: npm run lint

View File

@@ -2,7 +2,7 @@
Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses [Jitsi Videobridge](https://jitsi.org/videobridge) to provide high quality, [secure](#security) and scalable video conferences. Jitsi Meet in action can be seen at [here at the session #482 of the VoIP Users Conference](http://youtu.be/7vFUVClsNh0).
The Jitsi Meet client runs in your browser, without installing anything on your computer. You can try it out at https://meet.jit.si .
The Jitsi Meet client runs in your browser, without installing anything else on your computer. You can try it out at https://meet.jit.si .
Jitsi Meet allows very efficient collaboration. Users can stream their desktop or only some windows. It also supports shared document editing with Etherpad.

View File

@@ -1,6 +1,5 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
* Copyright @ 2017-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,6 +90,7 @@ public class MainActivity extends JitsiMeetActivity {
= new JitsiMeetConferenceOptions.Builder()
.setWelcomePageEnabled(true)
.setServerURL(buildURL("https://meet.jit.si"))
.setFeatureFlag("call-integration.enabled", false)
.build();
JitsiMeet.setDefaultConferenceOptions(defaultOptions);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 KiB

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 MiB

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 948 KiB

After

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 983 KiB

After

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 950 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1000 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -20,5 +20,5 @@
android.useAndroidX=true
android.enableJetifier=true
appVersion=20.0.0
sdkVersion=2.6.0
appVersion=20.1.0
sdkVersion=2.7.0

View File

@@ -9,7 +9,7 @@ THE_MVN_REPO=${MVN_REPO:-${1:-$DEFAULT_MVN_REPO}}
MVN_HTTP=0
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
RN_VERSION=$(jq -r '.dependencies."react-native"' ${THIS_DIR}/../../package.json)
RN_VERSION=$(jq -r '.version' ${THIS_DIR}/../../node_modules/react-native/package.json)
HERMES_VERSION=$(jq -r '.dependencies."hermes-engine"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -c 2-)
DO_GIT_TAG=${GIT_TAG:-0}

View File

@@ -108,7 +108,8 @@ class AudioDeviceHandlerConnectionService implements
*/
private int supportedRouteMask = -1;
public AudioDeviceHandlerConnectionService() {
public AudioDeviceHandlerConnectionService(AudioManager audioManager) {
this.audioManager = audioManager;
}
@Override
@@ -136,11 +137,10 @@ class AudioDeviceHandlerConnectionService implements
}
@Override
public void start(Context context, AudioModeModule audioModeModule) {
public void start(AudioModeModule audioModeModule) {
JitsiMeetLogger.i("Using " + TAG + " as the audio device handler");
module = audioModeModule;
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
RNConnectionService rcs = ReactInstanceManagerHolder.getNativeModule(RNConnectionService.class);
if (rcs != null) {

View File

@@ -117,7 +117,8 @@ class AudioDeviceHandlerGeneric implements
}
};
public AudioDeviceHandlerGeneric() {
public AudioDeviceHandlerGeneric(AudioManager audioManager) {
this.audioManager = audioManager;
}
/**
@@ -178,11 +179,10 @@ class AudioDeviceHandlerGeneric implements
}
@Override
public void start(Context context, AudioModeModule audioModeModule) {
public void start(AudioModeModule audioModeModule) {
JitsiMeetLogger.i("Using " + TAG + " as the audio device handler");
module = audioModeModule;
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
// Setup runtime device change detection.
audioManager.registerAudioDeviceCallback(audioDeviceCallback, null);

View File

@@ -59,7 +59,8 @@ class AudioDeviceHandlerLegacy implements
*/
private BluetoothHeadsetMonitor bluetoothHeadsetMonitor;
public AudioDeviceHandlerLegacy() {
public AudioDeviceHandlerLegacy(AudioManager audioManager) {
this.audioManager = audioManager;
}
/**
@@ -155,11 +156,11 @@ class AudioDeviceHandlerLegacy implements
}
@Override
public void start(Context context, AudioModeModule audioModeModule) {
public void start(AudioModeModule audioModeModule) {
JitsiMeetLogger.i("Using " + TAG + " as the audio device handler");
module = audioModeModule;
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
Context context = module.getContext();
// Setup runtime device change detection.
//

View File

@@ -17,6 +17,7 @@
package org.jitsi.meet.sdk;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import com.facebook.react.bridge.Arguments;
@@ -85,6 +86,12 @@ class AudioModeModule extends ReactContextBaseJavaModule {
return supportsConnectionService && useConnectionService_;
}
/**
* {@link AudioManager} instance used to interact with the Android audio
* subsystem.
*/
private AudioManager audioManager;
private AudioDeviceHandlerInterface audioDeviceHandler;
/**
@@ -136,6 +143,8 @@ class AudioModeModule extends ReactContextBaseJavaModule {
*/
public AudioModeModule(ReactApplicationContext reactContext) {
super(reactContext);
audioManager = (AudioManager)reactContext.getSystemService(Context.AUDIO_SERVICE);
}
/**
@@ -198,7 +207,12 @@ class AudioModeModule extends ReactContextBaseJavaModule {
*/
@Override
public void initialize() {
setAudioDeviceHandler();
runInAudioThread(new Runnable() {
@Override
public void run() {
setAudioDeviceHandler();
}
});
}
private void setAudioDeviceHandler() {
@@ -207,14 +221,14 @@ class AudioModeModule extends ReactContextBaseJavaModule {
}
if (useConnectionService()) {
audioDeviceHandler = new AudioDeviceHandlerConnectionService();
audioDeviceHandler = new AudioDeviceHandlerConnectionService(audioManager);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
audioDeviceHandler = new AudioDeviceHandlerGeneric();
audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
} else {
audioDeviceHandler = new AudioDeviceHandlerLegacy();
audioDeviceHandler = new AudioDeviceHandlerLegacy(audioManager);
}
audioDeviceHandler.start(getReactApplicationContext(), this);
audioDeviceHandler.start(this);
}
/**
@@ -292,9 +306,14 @@ class AudioModeModule extends ReactContextBaseJavaModule {
* @param use Boolean indicator of where it should be used or not.
*/
@ReactMethod
public void setUseConnectionService(boolean use) {
useConnectionService_ = use;
setAudioDeviceHandler();
public void setUseConnectionService(final boolean use) {
runInAudioThread(new Runnable() {
@Override
public void run() {
useConnectionService_ = use;
setAudioDeviceHandler();
}
});
}
/**
@@ -408,16 +427,24 @@ class AudioModeModule extends ReactContextBaseJavaModule {
}
}
/**
* Needed on the legacy handler...
*
* @return Context for the application.
*/
Context getContext() {
return getReactApplicationContext();
}
/**
* Interface for the modules implementing the actual audio device management.
*/
interface AudioDeviceHandlerInterface {
/**
* Start detecting audio device changes.
* @param context Android {@link Context} where detection should take place.
* @param audioModeModule Reference to the main {@link AudioModeModule}.
*/
void start(Context context, AudioModeModule audioModeModule);
void start(AudioModeModule audioModeModule);
/**
* Stop audio device detection.

View File

@@ -17,6 +17,7 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import androidx.annotation.Nullable;
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
@@ -31,16 +32,11 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import com.oney.WebRTCModule.EglUtils;
import com.oney.WebRTCModule.RTCVideoViewManager;
import com.oney.WebRTCModule.WebRTCModule;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.EglBase;
import org.webrtc.SoftwareVideoDecoderFactory;
import org.webrtc.SoftwareVideoEncoderFactory;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.audio.AudioDeviceModule;
import org.webrtc.audio.JavaAudioDeviceModule;
@@ -89,19 +85,8 @@ class ReactInstanceManagerHolder {
.createAudioDeviceModule();
options.setAudioDeviceModule(adm);
VideoEncoderFactory videoEncoderFactory = new SoftwareVideoEncoderFactory();
VideoDecoderFactory videoDecoderFactory;
// Initialize EGL context required for HW acceleration. We are only going to use it for
// decoding.
EglBase.Context eglContext = EglUtils.getRootEglBaseContext();
if (eglContext == null) {
// Fallback to the software decoder.
videoDecoderFactory = new SoftwareVideoDecoderFactory();
} else {
videoDecoderFactory = new DefaultVideoDecoderFactory(eglContext);
}
options.setVideoDecoderFactory(videoDecoderFactory);
options.setVideoEncoderFactory(videoEncoderFactory);
options.setVideoDecoderFactory(new SoftwareVideoDecoderFactory());
options.setVideoEncoderFactory(new SoftwareVideoEncoderFactory());
nativeModules.add(new WebRTCModule(reactContext, options));

View File

@@ -2,6 +2,7 @@
import { openConnection } from './connection';
import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants';
import AuthHandler from './modules/UI/authentication/AuthHandler';
import Recorder from './modules/recorder/Recorder';
@@ -435,7 +436,6 @@ export default {
* the tracks won't exist).
*/
_localTracksInitialized: false,
isModerator: false,
isSharingScreen: false,
/**
@@ -926,14 +926,6 @@ export default {
this.muteVideo(!this.isLocalVideoMuted(), showUI);
},
/**
* Retrieve list of conference participants (without local user).
* @returns {JitsiParticipant[]}
*/
listMembers() {
return room.getParticipants();
},
/**
* Retrieve list of ids of conference participants (without local user).
* @returns {string[]}
@@ -953,6 +945,16 @@ export default {
return user && user.isModerator();
},
/**
* Retrieve list of conference participants (without local user).
* @returns {JitsiParticipant[]}
*
* NOTE: Used by jitsi-meet-torture!
*/
listMembers() {
return room.getParticipants();
},
get membersCount() {
return room.getParticipants().length + 1;
},
@@ -1425,6 +1427,9 @@ export default {
}
this._stopProxyConnection();
if (config.enableScreenshotCapture) {
APP.store.dispatch(toggleScreenshotCaptureEffect(false));
}
// It can happen that presenter GUM is in progress while screensharing is being turned off. Here it needs to
// wait for that GUM to be resolved in order to prevent leaking the presenter track(this.localPresenterVideo
@@ -1460,9 +1465,6 @@ export default {
} else {
promise = promise.then(() => this.useVideoStream(null));
}
if (config.enableScreenshotCapture) {
APP.store.dispatch(toggleScreenshotCaptureEffect(false));
}
return promise.then(
() => {
@@ -1894,9 +1896,6 @@ export default {
logger.log(`USER ${id} connnected:`, user);
APP.UI.addUser(user);
// check the roles for the new user and reflect them
APP.UI.updateUserRole(user);
});
room.on(JitsiConferenceEvents.USER_LEFT, (id, user) => {
@@ -1927,19 +1926,8 @@ export default {
logger.info(`My role changed, new role: ${role}`);
APP.store.dispatch(localParticipantRoleChanged(role));
if (this.isModerator !== room.isModerator()) {
this.isModerator = room.isModerator();
APP.UI.updateLocalRole(room.isModerator());
}
} else {
APP.store.dispatch(participantRoleChanged(id, role));
const user = room.getParticipantById(id);
if (user) {
APP.UI.updateUserRole(user);
}
}
});
@@ -2054,7 +2042,22 @@ export default {
room.on(
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
(...args) => APP.store.dispatch(endpointMessageReceived(...args)));
(...args) => {
APP.store.dispatch(endpointMessageReceived(...args));
if (args && args.length >= 2) {
const [ sender, eventData ] = args;
if (eventData.name === ENDPOINT_TEXT_MESSAGE_NAME) {
APP.API.notifyEndpointTextMessageReceived({
senderInfo: {
jid: sender._jid,
id: sender._id
},
eventData
});
}
}
});
room.on(
JitsiConferenceEvents.LOCK_STATE_CHANGED,
@@ -2287,7 +2290,7 @@ export default {
})
.then(stream => this.useAudioStream(stream))
.then(() => {
logger.log('switched local audio device');
logger.log(`switched local audio device: ${this.localAudio?.getDeviceId()}`);
this._updateAudioDeviceId();
})
@@ -2664,12 +2667,6 @@ export default {
// audio devices detected or if the local audio stream already exists.
const available = audioDeviceCount > 0 || Boolean(this.localAudio);
logger.debug(
`Microphone button enabled: ${available}`,
`local audio: ${this.localAudio}`,
`audio devices: ${audioMediaDevices}`,
`device count: ${audioDeviceCount}`);
APP.store.dispatch(setAudioAvailable(available));
APP.API.notifyAudioAvailabilityChanged(available);
},
@@ -2690,12 +2687,6 @@ export default {
// config).
const available = videoDeviceCount > 0 || Boolean(this.localVideo);
logger.debug(
`Camera button enabled: ${available}`,
`local video: ${this.localVideo}`,
`video devices: ${videoMediaDevices}`,
`device count: ${videoDeviceCount}`);
APP.store.dispatch(setVideoAvailable(available));
APP.API.notifyVideoAvailabilityChanged(available);
},

View File

@@ -75,6 +75,7 @@ var config = {
// Disable measuring of audio levels.
// disableAudioLevels: false,
// audioLevelsInterval: 200,
// Enabling this will run the lib-jitsi-meet no audio detection module which
// will notify the user if the current selected microphone has no audio
@@ -301,16 +302,19 @@ var config = {
// estimation tests.
// gatherStats: false,
// The interval at which PeerConnection.getStats() is called. Defaults to 10000
// pcStatsInterval: 10000,
// To enable sending statistics to callstats.io you must provide the
// Application ID and Secret.
// callStatsID: '',
// callStatsSecret: '',
// enables sending participants display name to callstats
// enableDisplayNameInStats: false
// enableDisplayNameInStats: false,
// enables sending participants email if available to callstats and other analytics
// enableEmailInStats: false
// enableEmailInStats: false,
// Privacy
//
@@ -386,7 +390,7 @@ var config = {
// shard: "shard1",
// region: "europe",
// userRegion: "asia"
}
},
// Information for the chrome extension banner
// chromeExtensionBanner: {
@@ -400,7 +404,7 @@ var config = {
// path: 'jitsi-logo-48x48.png'
// }
// ]
// }
// },
// Local Recording
//
@@ -418,7 +422,7 @@ var config = {
// format: 'flac'
//
// }
// },
// Options related to end-to-end (participant to participant) ping.
// e2eping: {
@@ -430,22 +434,22 @@ var config = {
// // with the measured RTT will be sent. Defaults to 60000, set
// // to <= 0 to disable.
// analyticsInterval: 60000,
// }
// },
// If set, will attempt to use the provided video input device label when
// triggering a screenshare, instead of proceeding through the normal flow
// for obtaining a desktop stream.
// NOTE: This option is experimental and is currently intended for internal
// use only.
// _desktopSharingSourceDevice: 'sample-id-or-label'
// _desktopSharingSourceDevice: 'sample-id-or-label',
// If true, any checks to handoff to another application will be prevented
// and instead the app will continue to display in the current browser.
// disableDeepLinking: false
// disableDeepLinking: false,
// A property to disable the right click context menu for localVideo
// the menu has option to flip the locally seen video for local presentations
// disableLocalVideoFlip: false
// disableLocalVideoFlip: false,
// Deployment specific URLs.
// deploymentUrls: {
@@ -455,7 +459,7 @@ var config = {
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
// // to the specified URL for an app download page.
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
// }
// },
// List of undocumented settings used in jitsi-meet
/**
@@ -507,6 +511,12 @@ var config = {
startBitrate
*/
// Allow all above example options to include a trailing comma and
// prevent fear when commenting out the last value.
makeJsonParserHappy: 'even if last key had a trailing comma'
// no configuration value should follow this line.
};
/* eslint-enable no-unused-vars, no-var */

View File

@@ -15,6 +15,13 @@ import {
const logger = require('jitsi-meet-logger').getLogger(__filename);
/**
* The feature announced so we can distinguish jibri participants.
*
* @type {string}
*/
export const DISCO_JIBRI_FEATURE = 'http://jitsi.org/protocol/jibri';
/**
* Checks if we have data to use attach instead of connect. If we have the data
* executes attach otherwise check if we have to wait for the data. If we have
@@ -91,6 +98,10 @@ function connect(id, password, roomName) {
jwt && issuer && issuer !== 'anonymous' ? jwt : undefined,
connectionConfig);
if (config.iAmRecorder) {
connection.addFeature(DISCO_JIBRI_FEATURE);
}
return new Promise((resolve, reject) => {
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,

View File

@@ -136,6 +136,13 @@
display: flex;
transition: opacity 1s;
}
.hide-scrollbar#filmstripRemoteVideos {
margin-right: 7px; // Scrollbar size
&::-webkit-scrollbar {
display: none;
}
}
}
/**

2
debian/compat vendored
View File

@@ -1 +1 @@
8
12

View File

@@ -270,6 +270,11 @@ api.executeCommand('email', 'example@example.com');
api.executeCommand('avatarUrl', 'https://avatars0.githubusercontent.com/u/3671647');
```
* **sendEndpointTextMessage** - Sends a text message to another participant through the datachannels.
```javascript
api.executeCommand('receiverParticipantId', 'text');
```
You can also execute multiple commands using the `executeCommands` method:
```javascript
api.executeCommands(commands);
@@ -323,6 +328,21 @@ changes. The listener will receive an object with the following structure:
}
```
* **endpointTextMessageReceived** - event notifications about a text message received through datachannels.
The listener will receive an object with the following structure:
```javascript
{
senderInfo: {
jid: string, // the jid of the sender
id: string // the participant id of the sender
},
eventData: {
name: string // the name of the datachannel event: `endpoint-text-message`
text: string // the received text from the sender
}
}
```
* **micError** - event notifications about Jitsi-Meet having failed to access the mic. The listener will receive an object with the following structure:
```javascript
{

View File

@@ -4,4 +4,4 @@ A. In general, if the tool ifconfig (or ipconfig) shows the assigned IP address
**2. Clients could communicate well in room created at meet.jit.si . The same clients still could connect to my self-hosted instance but can neither hear nor see one another. What's wrong?**
A. Most probably, the server is behind NAT. See this [resolved question](https://community.jitsi.org/t/cannot-see-video-or-hear-audio-on-self-hosted-instance/). You need to follow the steps detailed [here](https://github.com/jitsi/ice4j/blob/master/doc/quick-install.md#Advanced-configuration)
A. Most probably, the server is behind NAT. See this [resolved question](https://community.jitsi.org/t/cannot-see-video-or-hear-audio-on-self-hosted-instance/). You need to follow the steps detailed [here](https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md#Advanced-configuration)

View File

@@ -1,9 +1,6 @@
# 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.
: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 is sometimes not updated to reflect 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
@@ -22,7 +19,7 @@ This is how the network looks:
443 |
+-------+ |
| | |
| NginX | |
| Nginx | |
| | |
+--+-+--+ |
| | |
@@ -31,7 +28,7 @@ This is how the network looks:
| jitsi-meet +<---+ +--->+ prosody/xmpp | |
| |files 5280 | | |
+------------+ +--------------+ v
5222,5347^ ^5347 4443
5222,5347^ ^5347 4443,10000
+--------+ | | +-------------+
| | | | | |
| jicofo +----^ ^----+ videobridge |
@@ -112,7 +109,7 @@ Restart prosody XMPP server with the new config
prosodyctl restart
```
## Install nginx
## Install Nginx
```sh
apt-get install nginx
```
@@ -122,12 +119,13 @@ Add a new file `jitsi.example.com` in `/etc/nginx/sites-available` (see also the
server_names_hash_bucket_size 64;
server {
listen 443;
listen 0.0.0.0:443 ssl http2;
listen [::]:443 ssl http2;
# tls configuration that is not covered in this guide
# we recommend the use of https://certbot.eff.org/
server_name jitsi.example.com;
# set the root
root /srv/jitsi.example.com;
root /srv/jitsi-meet;
index index.html;
location ~ ^/([a-zA-Z0-9=\?]+)$ {
rewrite ^/(.*)$ / break;
@@ -142,6 +140,12 @@ server {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
# external_api.js must be accessible from the root of the
# installation for the electron version of Jitsi Meet to work
# https://github.com/jitsi/jitsi-meet-electron
location /external_api.js {
alias /srv/jitsi-meet/libs/external_api.min.js;
}
}
```
@@ -152,6 +156,7 @@ ln -s ../sites-available/jitsi.example.com jitsi.example.com
```
## Install Jitsi Videobridge
Visit https://download.jitsi.org/jitsi-videobridge/linux to determine the current build number, download and unzip it:
```sh
wget https://download.jitsi.org/jitsi-videobridge/linux/jitsi-videobridge-linux-{arch-buildnum}.zip
unzip jitsi-videobridge-linux-{arch-buildnum}.zip
@@ -164,9 +169,15 @@ apt-get install openjdk-8-jre
_NOTE: When installing on older Debian releases keep in mind that you need JRE >= 1.7._
In the user home that will be starting Jitsi Videobridge create `.sip-communicator` folder and add the file `sip-communicator.properties` with one line in it:
```
Create `~/.sip-communicator/sip-communicator.properties` in the home folder of the user that will be starting Jitsi Videobridge:
```sh
mkdir -p ~/.sip-communicator
cat > ~/.sip-communicator/sip-communicator.properties << EOF
org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false
# The videobridge uses 443 by default with 4443 as a fallback, but since we're already
# running nginx on 443 in this example doc, we specify 4443 manually to avoid a race condition
org.jitsi.videobridge.TCP_HARVESTER_PORT=4443
EOF
```
Start the videobridge with:
@@ -191,7 +202,7 @@ Clone source from Github repo:
```sh
git clone https://github.com/jitsi/jicofo.git
```
Build distribution package. Replace {os-name} with one of: 'lin', 'lin64', 'macosx', 'win', 'win64'.
Build the package.
```sh
cd jicofo
mvn package -DskipTests -Dassembly.skipAssembly=false
@@ -199,8 +210,8 @@ mvn package -DskipTests -Dassembly.skipAssembly=false
Run jicofo:
```sh
=======
unzip target/jicofo-{os-name}-1.0-SNAPSHOT.zip
cd jicofo-{os-name}-1.0-SNAPSHOT'
unzip target/jicofo-1.1-SNAPSHOT-archive.zip
cd jicofo-1.1-SNAPSHOT-archive'
./jicofo.sh --host=localhost --domain=jitsi.example.com --secret=YOURSECRET2 --user_domain=auth.jitsi.example.com --user_name=focus --user_password=YOURSECRET3
```
@@ -209,13 +220,12 @@ Checkout and configure Jitsi Meet:
```sh
cd /srv
git clone https://github.com/jitsi/jitsi-meet.git
mv jitsi-meet/ jitsi.example.com
cd jitsi.example.com
cd jitsi-meet
npm install
make
```
Edit host names in `/srv/jitsi.example.com/config.js` (see also the example config file):
Edit host names in `/srv/jitsi-meet/config.js` (see also the example config file):
```
var config = {
hosts: {
@@ -231,15 +241,19 @@ var config = {
};
```
Restart nginx to get the new configuration:
Verify that nginx config is valid and reload nginx:
```sh
invoke-rc.d nginx restart
nginx -t && nginx -s reload
```
## Running behind NAT
Jitsi-Videobridge can run behind a NAT, provided that all required ports are routed (forwarded) to the machine that it runs on. By default these ports are (TCP/443 or TCP/4443 and UDP 10000).
Jitsi Videobridge can run behind a NAT, provided that both required ports are routed (forwarded) to the machine that it runs on. By default these ports are `TCP/4443` and `UDP/10000`.
The following extra lines need to be added the file `~/.sip-communicator/sip-communicator.properties` (in the home directory of the user running the videobridge):
If you do not route these two ports, Jitsi Meet will only work with video for two people, breaking upon 3 or more people trying to show video.
`TCP/443` is required for the webserver which can be running on another machine than the Jitsi Videobrige is running on.
The following extra lines need to be added to the file `~/.sip-communicator/sip-communicator.properties` (in the home directory of the user running the videobridge):
```
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=<Local.IP.Address>
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<Public.IP.Address>
@@ -248,6 +262,5 @@ org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<Public.IP.Address>
# Hold your first conference
You are now all set and ready to have your first meet by going to http://jitsi.example.com
## Enabling recording
[Jibri](https://github.com/jitsi/jibri)is a set of tools for recording and/or streaming a Jitsi Meet conference.
[Jibri](https://github.com/jitsi/jibri) is a set of tools for recording and/or streaming a Jitsi Meet conference.

View File

@@ -14,6 +14,16 @@ b.) You only need to do this if you want to ___host your own Jitsi server___. If
## Basic Jitsi Meet install
### Set up the Fully Qualified Domain Name (FQDN) (optional)
If the machine used to host the Jitsi Meet instance has a FQDN (for example `meet.example.org`) already set up in DNS, `/etc/hostname` must contain this FQDN; if this is not the case yet, [change the hostname](https://wiki.debian.org/HowTo/ChangeHostname).
Then add the same FQDN in the `/etc/hosts` file, associating it with the loopback address:
127.0.0.1 localhost meet.example.org
Finally on the same machine test that you can ping the FQDN with: `ping "$(hostname)"`-
### Add the repository
```sh
echo 'deb https://download.jitsi.org stable/' >> /etc/apt/sources.list.d/jitsi-stable.list
@@ -36,7 +46,7 @@ apt-get install apt-transport-https
### Install Jitsi Meet
Note : Something to consider before installation is how you're planning to serve Jitsi Meet. The installer will check if Nginx or Apache is present (with this order) and configure a virtualhost within the web server it finds to serve Jitsi Meet. If none of the above is found it then configures itself to be served via jetty. So if for example you are planning on deploying Jitsi Meet with a web server, you have to make sure to install the server **before** installing jitsi-meet.
Note: Something to consider before installation is how you're planning to serve Jitsi Meet. The installer will check if Nginx or Apache is present (with this order) and configure a virtualhost within the web server it finds to serve Jitsi Meet. If none of the above is found it then configures itself to be served via jetty. So if for example you are planning on deploying Jitsi Meet with a web server, you have to make sure to install the server **before** installing jitsi-meet.
```sh
apt-get -y install jitsi-meet
@@ -62,7 +72,7 @@ The following extra lines need to be added the file `/etc/jitsi/videobridge/sip-
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=<Local.IP.Address>
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<Public.IP.Address>
```
See [the documenation of ice4j](https://github.com/jitsi/ice4j/blob/master/doc/configuration.md)
See [the documentation of ice4j](https://github.com/jitsi/ice4j/blob/master/doc/configuration.md)
for details.
Default deployments on systems using systemd will have low default values for maximum processes and open files. If the used bridge will expect higher number of participants the default values need to be adjusted (the default values are good for less than 100 participants).
@@ -74,7 +84,7 @@ DefaultTasksMax=65000
```
To load the values and check them look [here](#systemd-details) for details.
By default, anyone who has access to your jitsi instance will be able to start a conferencee: if your server is open to the world, anyone can have a chat with anyone else. If you want to limit the ability to start a conference to registered users, set up a "secure domain". Follow the instructions at https://github.com/jitsi/jicofo#secure-domain.
By default, anyone who has access to your jitsi instance will be able to start a conference: if your server is open to the world, anyone can have a chat with anyone else. If you want to limit the ability to start a conference to registered users, set up a "secure domain". Follow the instructions at https://github.com/jitsi/jicofo#secure-domain.
### Open a conference
@@ -124,7 +134,7 @@ The reason for failure is that sometimes, the uninstall script is faster than th
#### Systemd details
To reload the systemd changes on a running system execute `systemctl daemon-reload` and `service jitsi-videobridge restart`.
To check the tasks part execute `service jitsi-videobridge status` and you should see `Tasks: XX (limit: 65000)`.
To check the files and process part execute ```cat /proc/`cat /var/run/jitsi-videobridge.pid`/limits``` and you should see:
To check the files and process part execute ```cat /proc/`cat /var/run/jitsi-videobridge/jitsi-videobridge.pid`/limits``` and you should see:
```
Max processes 65000 65000 processes
Max open files 65000 65000 files

View File

@@ -13,7 +13,8 @@
// IE11 and earlier can be identified via their user agent and be
// redirected to a page that is known to have no newer js syntax.
if (window.navigator.userAgent.match(/(MSIE|Trident)/)) {
window.location.href = "static/recommendedBrowsers.html";
var roomName = encodeURIComponent(window.location.pathname);
window.location.href = "static/recommendedBrowsers.html" + "?room=" + roomName;
}
window.indexLoadedTime = window.performance.now();

View File

@@ -51,7 +51,7 @@ var interfaceConfig = {
'fodeviceselection', 'hangup', 'profile', 'info', 'chat', 'recording',
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
'tileview', 'videobackgroundblur', 'download', 'help'
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone'
],
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ],
@@ -74,6 +74,7 @@ var interfaceConfig = {
// A html text to be shown to guests on the close page, false disables it
CLOSE_PAGE_GUEST_HINT: false,
SHOW_PROMOTIONAL_CLOSE_PAGE: false,
RANDOM_AVATAR_URL_PREFIX: false,
RANDOM_AVATAR_URL_SUFFIX: false,
FILM_STRIP_MAX_HEIGHT: 120,
@@ -127,7 +128,7 @@ var interfaceConfig = {
* If indicated some of the error dialogs may point to the support URL for
* help.
*/
SUPPORT_URL: 'https://github.com/jitsi/jitsi-meet/issues/new',
SUPPORT_URL: 'https://community.jitsi.org/',
/**
* Whether the connection indicator icon should hide itself based on
@@ -207,6 +208,11 @@ var interfaceConfig = {
*/
SHOW_CHROME_EXTENSION_BANNER: false
/**
* When enabled, the kick participant button will not be presented for users without a JWT
*/
// HIDE_KICK_BUTTON_FOR_GUESTS: false
/**
* How many columns the tile view can expand to. The respected range is
* between 1 and 5.

View File

@@ -15,14 +15,14 @@ PODS:
- Fabric (~> 1.9.0)
- DoubleConversion (1.1.6)
- Fabric (1.9.0)
- FBLazyVector (0.61.5)
- FBReactNativeSpec (0.61.5):
- FBLazyVector (0.61.5-jitsi.1)
- FBReactNativeSpec (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.61.5)
- RCTTypeSafety (= 0.61.5)
- React-Core (= 0.61.5)
- React-jsi (= 0.61.5)
- ReactCommon/turbomodule/core (= 0.61.5)
- RCTRequired (= 0.61.5-jitsi.1)
- RCTTypeSafety (= 0.61.5-jitsi.1)
- React-Core (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- Firebase/Core (5.18.0):
- Firebase/CoreOnly
- FirebaseAnalytics (= 5.7.0)
@@ -103,169 +103,169 @@ PODS:
- nanopb/decode (0.3.901)
- nanopb/encode (0.3.901)
- ObjectiveDropboxOfficial (3.9.4)
- RCTRequired (0.61.5)
- RCTTypeSafety (0.61.5):
- FBLazyVector (= 0.61.5)
- RCTRequired (0.61.5-jitsi.1)
- RCTTypeSafety (0.61.5-jitsi.1):
- FBLazyVector (= 0.61.5-jitsi.1)
- Folly (= 2018.10.22.00)
- RCTRequired (= 0.61.5)
- React-Core (= 0.61.5)
- React (0.61.5):
- React-Core (= 0.61.5)
- React-Core/DevSupport (= 0.61.5)
- React-Core/RCTWebSocket (= 0.61.5)
- React-RCTActionSheet (= 0.61.5)
- React-RCTAnimation (= 0.61.5)
- React-RCTBlob (= 0.61.5)
- React-RCTImage (= 0.61.5)
- React-RCTLinking (= 0.61.5)
- React-RCTNetwork (= 0.61.5)
- React-RCTSettings (= 0.61.5)
- React-RCTText (= 0.61.5)
- React-RCTVibration (= 0.61.5)
- React-Core (0.61.5):
- RCTRequired (= 0.61.5-jitsi.1)
- React-Core (= 0.61.5-jitsi.1)
- React (0.61.5-jitsi.1):
- React-Core (= 0.61.5-jitsi.1)
- React-Core/DevSupport (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-RCTActionSheet (= 0.61.5-jitsi.1)
- React-RCTAnimation (= 0.61.5-jitsi.1)
- React-RCTBlob (= 0.61.5-jitsi.1)
- React-RCTImage (= 0.61.5-jitsi.1)
- React-RCTLinking (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTSettings (= 0.61.5-jitsi.1)
- React-RCTText (= 0.61.5-jitsi.1)
- React-RCTVibration (= 0.61.5-jitsi.1)
- React-Core (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-Core/Default (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/CoreModulesHeaders (0.61.5):
- React-Core/CoreModulesHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/Default (0.61.5):
- React-Core/Default (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/DevSupport (0.61.5):
- React-Core/DevSupport (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5)
- React-Core/RCTWebSocket (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-jsinspector (= 0.61.5)
- React-Core/Default (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- React-jsinspector (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTActionSheetHeaders (0.61.5):
- React-Core/RCTActionSheetHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTAnimationHeaders (0.61.5):
- React-Core/RCTAnimationHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTBlobHeaders (0.61.5):
- React-Core/RCTBlobHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTImageHeaders (0.61.5):
- React-Core/RCTImageHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTLinkingHeaders (0.61.5):
- React-Core/RCTLinkingHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTNetworkHeaders (0.61.5):
- React-Core/RCTNetworkHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTSettingsHeaders (0.61.5):
- React-Core/RCTSettingsHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTTextHeaders (0.61.5):
- React-Core/RCTTextHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTVibrationHeaders (0.61.5):
- React-Core/RCTVibrationHeaders (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-Core/RCTWebSocket (0.61.5):
- React-Core/RCTWebSocket (0.61.5-jitsi.1):
- Folly (= 2018.10.22.00)
- glog
- React-Core/Default (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsiexecutor (= 0.61.5)
- React-Core/Default (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsiexecutor (= 0.61.5-jitsi.1)
- Yoga
- React-CoreModules (0.61.5):
- FBReactNativeSpec (= 0.61.5)
- React-CoreModules (0.61.5-jitsi.1):
- FBReactNativeSpec (= 0.61.5-jitsi.1)
- Folly (= 2018.10.22.00)
- RCTTypeSafety (= 0.61.5)
- React-Core/CoreModulesHeaders (= 0.61.5)
- React-RCTImage (= 0.61.5)
- ReactCommon/turbomodule/core (= 0.61.5)
- React-cxxreact (0.61.5):
- RCTTypeSafety (= 0.61.5-jitsi.1)
- React-Core/CoreModulesHeaders (= 0.61.5-jitsi.1)
- React-RCTImage (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- React-cxxreact (0.61.5-jitsi.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsinspector (= 0.61.5)
- React-jsi (0.61.5):
- React-jsinspector (= 0.61.5-jitsi.1)
- React-jsi (0.61.5-jitsi.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsi/Default (= 0.61.5)
- React-jsi/Default (0.61.5):
- React-jsi/Default (= 0.61.5-jitsi.1)
- React-jsi/Default (0.61.5-jitsi.1):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-jsiexecutor (0.61.5):
- React-jsiexecutor (0.61.5-jitsi.1):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-jsinspector (0.61.5-jitsi.1)
- react-native-background-timer (2.1.1):
- React
- react-native-calendar-events (1.7.3):
@@ -278,60 +278,60 @@ PODS:
- React
- react-native-webview (7.4.1):
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
- React-RCTAnimation (0.61.5):
- React-Core/RCTAnimationHeaders (= 0.61.5)
- React-RCTBlob (0.61.5):
- React-Core/RCTBlobHeaders (= 0.61.5)
- React-Core/RCTWebSocket (= 0.61.5)
- React-jsi (= 0.61.5)
- React-RCTNetwork (= 0.61.5)
- React-RCTImage (0.61.5):
- React-Core/RCTImageHeaders (= 0.61.5)
- React-RCTNetwork (= 0.61.5)
- React-RCTLinking (0.61.5):
- React-Core/RCTLinkingHeaders (= 0.61.5)
- React-RCTNetwork (0.61.5):
- React-Core/RCTNetworkHeaders (= 0.61.5)
- React-RCTSettings (0.61.5):
- React-Core/RCTSettingsHeaders (= 0.61.5)
- React-RCTText (0.61.5):
- React-Core/RCTTextHeaders (= 0.61.5)
- React-RCTVibration (0.61.5):
- React-Core/RCTVibrationHeaders (= 0.61.5)
- ReactCommon/jscallinvoker (0.61.5):
- React-RCTActionSheet (0.61.5-jitsi.1):
- React-Core/RCTActionSheetHeaders (= 0.61.5-jitsi.1)
- React-RCTAnimation (0.61.5-jitsi.1):
- React-Core/RCTAnimationHeaders (= 0.61.5-jitsi.1)
- React-RCTBlob (0.61.5-jitsi.1):
- React-Core/RCTBlobHeaders (= 0.61.5-jitsi.1)
- React-Core/RCTWebSocket (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTImage (0.61.5-jitsi.1):
- React-Core/RCTImageHeaders (= 0.61.5-jitsi.1)
- React-RCTNetwork (= 0.61.5-jitsi.1)
- React-RCTLinking (0.61.5-jitsi.1):
- React-Core/RCTLinkingHeaders (= 0.61.5-jitsi.1)
- React-RCTNetwork (0.61.5-jitsi.1):
- React-Core/RCTNetworkHeaders (= 0.61.5-jitsi.1)
- React-RCTSettings (0.61.5-jitsi.1):
- React-Core/RCTSettingsHeaders (= 0.61.5-jitsi.1)
- React-RCTText (0.61.5-jitsi.1):
- React-Core/RCTTextHeaders (= 0.61.5-jitsi.1)
- React-RCTVibration (0.61.5-jitsi.1):
- React-Core/RCTVibrationHeaders (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (0.61.5-jitsi.1):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-cxxreact (= 0.61.5)
- ReactCommon/turbomodule (0.61.5):
- React-cxxreact (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule (0.61.5-jitsi.1):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- ReactCommon/jscallinvoker (= 0.61.5)
- ReactCommon/turbomodule/core (= 0.61.5)
- ReactCommon/turbomodule/samples (= 0.61.5)
- ReactCommon/turbomodule/core (0.61.5):
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/samples (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (0.61.5-jitsi.1):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- ReactCommon/jscallinvoker (= 0.61.5)
- ReactCommon/turbomodule/samples (0.61.5):
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/samples (0.61.5-jitsi.1):
- DoubleConversion
- Folly (= 2018.10.22.00)
- glog
- React-Core (= 0.61.5)
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- ReactCommon/jscallinvoker (= 0.61.5)
- ReactCommon/turbomodule/core (= 0.61.5)
- React-Core (= 0.61.5-jitsi.1)
- React-cxxreact (= 0.61.5-jitsi.1)
- React-jsi (= 0.61.5-jitsi.1)
- ReactCommon/jscallinvoker (= 0.61.5-jitsi.1)
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
- RNCAsyncStorage (1.3.4):
- React
- RNGoogleSignin (3.0.1):
@@ -504,8 +504,8 @@ SPEC CHECKSUMS:
Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
Fabric: f988e33c97f08930a413e08123064d2e5f68d655
FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f
FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75
FBLazyVector: 4a5251159a3ed05dc11cc8b74cf937869935814b
FBReactNativeSpec: 6fa602a20993212cc9877a81838578ffb0008bc9
Firebase: 02f3281965c075426141a0ce1277e9de6649cab9
FirebaseAnalytics: 23851fe602c872130a2c5c55040b302120346cc2
FirebaseAnalyticsInterop: efbe45c8385ec626e29f9525e5ebd38520dfb6c1
@@ -521,37 +521,37 @@ SPEC CHECKSUMS:
GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
ObjectiveDropboxOfficial: a5afefc83f6467c42c45f2253f583f2ad1ffc701
RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1
RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320
React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78
React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04
React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb
React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
RCTRequired: f63dd90a89a60602acdd44c42e5d2645ca60ab79
RCTTypeSafety: 24a3c6d55684046ed550b1d0ef083a9bf71c8bd4
React: 71c5a51135f291c3b32c0b558e167b858ae50e84
React-Core: e82c03ff91062abf963f35bf99a357154e570285
React-CoreModules: e236aeecd18cec37743c8c50562431db5302f668
React-cxxreact: 526ec106aa1bf2b3f6aab2a7d528d1d23d5f59c2
React-jsi: 4f35c1a2273d193a80c1c3831c808413840c260c
React-jsiexecutor: de1c37cf59ae9adcbf2be82eea0e090dc3f3205e
React-jsinspector: b76c4e84a7833bb4c90549d59ed53ec299ff912b
react-native-background-timer: 0d34748e53a972507c66963490c775321a88f6f2
react-native-calendar-events: 2fe35a9294af05de0ed819d3a1b5dac048d2c010
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
react-native-webrtc: 86d841823e66d68cc1f86712db1c2956056bf0c2
react-native-webview: 4dbc1d2a4a6b9c5e9e723c62651917aa2b5e579e
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e
React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5
React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a
React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640
React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe
React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad
ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
React-RCTActionSheet: b72ddbfbe15b44ce691d128e4b582f4bb9abb540
React-RCTAnimation: cfaefba5024499d336b76ab850e6bd33b232b5e3
React-RCTBlob: c427e643bef82999deeab97489ba43298ecfbe24
React-RCTImage: 79934bc96f3349da6a75b1d61cad594a932e4097
React-RCTLinking: 12b153399567c30efac0b32bb00f9c064587dc26
React-RCTNetwork: 603ad75778a54521b7797fd07c67dff562317526
React-RCTSettings: 8d45fcf14513582539ea1ddea69391207de7f046
React-RCTText: b4c29897c3df0c9f112e29aa3167fa6caf40b690
React-RCTVibration: a1bcfcdc0b5a73a1b0829a34cee22bd0e95bacba
ReactCommon: 675681aba4fecff5acbc0e440530cc422103c610
RNCAsyncStorage: 8e31405a9f12fbf42c2bb330e4560bfd79c18323
RNGoogleSignin: 39336070b35fc4cea6a98cf111e00480317be0ae
RNSound: c980916b596cc15c8dcd2f6ecd3b13c4881dbe20
RNSVG: aac12785382e8fd4f28d072fe640612e34914631
RNWatch: 09738b339eceb66e4d80a2371633ca5fb380fa42
Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
Yoga: 7b4209fda2441f99d54dd6cf4c82b094409bb68f
PODFILE CHECKSUM: 0fdfa45ae809c9460c80be3e0d4bbb822fccc418

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>20.0.0</string>
<string>20.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>20.0.0</string>
<string>20.1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UISupportedInterfaceOrientations</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>20.0.0</string>
<string>20.1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CLKComplicationPrincipalClass</key>

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.6.0</string>
<string>2.7.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

33
lang/languages-da.json Normal file
View File

@@ -0,0 +1,33 @@
{
"en": "Engelsk",
"af": "Sydafrikansk",
"bg": "Bulgarsk",
"ca": "Katalansk",
"cs": "Tjekkisk",
"da": "Dansk",
"de": "Tysk",
"el": "Græsk",
"enGB": "Engelsk (Storbritannien)",
"eo": "Esperanto",
"es": "Spansk",
"esUS": "Spansk (Latin Amerika)",
"fi": "Finsk",
"fr": "Fransk",
"frCA": "Fransk (Canada)",
"hr": "Kroatisk",
"hu": "Ungarsk",
"hy": "Armensk",
"it": "Italiensk",
"ja": "Japansk",
"ko": "Koreansk",
"nl": "Hollandsk",
"oc": "Occitansk",
"pl": "Polsk",
"ptBR": "Portugisisk (Brazilien)",
"ru": "Russisk",
"sv": "Svensk",
"tr": "Tyrkisk",
"vi": "Vietnamesisk",
"zhCN": "Kinesisk (China)",
"zhTW": "Kinesisk (Taiwan)"
}

View File

@@ -1,6 +1,6 @@
{
"en": "Inglese",
"af": "",
"af": "Afrikaans",
"az": "Azero",
"bg": "Bulgaro",
"cs": "Ceco",
@@ -24,4 +24,4 @@
"tr": "Turco",
"vi": "Vietnamita",
"zhCN": "Cinese (Cina)"
}
}

View File

@@ -4,6 +4,7 @@
"bg": "Bulgarian",
"ca": "Catalan",
"cs": "Czech",
"da": "Danish",
"de": "German",
"el": "Greek",
"enGB": "English (United Kingdom)",

View File

@@ -24,7 +24,7 @@
"speaker": "Řečník"
},
"audioOnly": {
"audioOnly": "Jen zvuk"
"audioOnly": "Pouze zvuk"
},
"calendarSync": {
"addMeetingURL": "",
@@ -46,7 +46,7 @@
},
"chat": {
"error": "",
"messagebox": "",
"messagebox": "Prostor pro zprávu",
"nickname": {
"popover": "Zvolte si přezdívku",
"title": ""
@@ -73,7 +73,7 @@
"address": "Adresa:",
"bandwidth": "Odhadovaná šířka pásma:",
"bitrate": "Přenosová rychlost:",
"bridgeCount": "",
"bridgeCount": "Počet serverů:",
"connectedTo": "",
"framerate": "Rychlost snímkování:",
"less": "Zobrazit méně",
@@ -86,7 +86,7 @@
"more": "Zobrazit více",
"packetloss": "Ztracené pakety:",
"quality": {
"good": "",
"good": "Dobré",
"inactive": "Neaktivní",
"lost": "Ztraceno",
"nonoptimal": "Není optimální",
@@ -122,16 +122,16 @@
},
"defaultLink": "např. {{url}}",
"deviceError": {
"cameraError": "",
"cameraPermission": "",
"microphoneError": "",
"microphonePermission": ""
"cameraError": "Chyba při přístupu ke kameře",
"cameraPermission": "Aplikace nemá oprávnění přistupovat ke kameře",
"microphoneError": "Chyba při přístupu k mikrofonu",
"microphonePermission": "Aplikace nemá oprávnění přistupovat k mikrofonu"
},
"deviceSelection": {
"noPermission": "",
"previewUnavailable": "",
"selectADevice": "",
"testAudio": ""
"noPermission": "Oprávnění není uděleno",
"previewUnavailable": "Náhled není dostupný",
"selectADevice": "Zvolte zvukové zařízení",
"testAudio": "Vyzkoušet zvuk"
},
"dialog": {
"accessibilityLabel": {
@@ -150,7 +150,7 @@
"cameraUnknownError": "",
"cameraUnsupportedResolutionError": "",
"Cancel": "Storno",
"close": "",
"close": "Zavřít",
"conferenceDisconnectMsg": "Možná byste měli zkontrolovat připojení k síti. Znovu se připojíte za {{seconds}} s...",
"conferenceDisconnectTitle": "Byl jste odhlášen.",
"conferenceReloadMsg": "Pokoušíme se to opravit. Znovu se připojíte za {{seconds}} s...",
@@ -223,7 +223,7 @@
"remoteControlStopMessage": "",
"remoteControlTitle": "",
"Remove": "Odstranit",
"removePassword": "",
"removePassword": "Zrušit heslo",
"removeSharedVideoMsg": "",
"removeSharedVideoTitle": "",
"reservationError": "",
@@ -239,7 +239,7 @@
"Share": "Sdílet",
"shareVideoLinkError": "Zadejte prosím správný odkaz na youtube video.",
"shareVideoTitle": "Sdílet obraz",
"shareYourScreen": "",
"shareYourScreen": "Sdílet obrazovku",
"shareYourScreenDisabled": "",
"shareYourScreenDisabledForGuest": "",
"startLiveStreaming": "",
@@ -285,34 +285,34 @@
"videoCallTitle": ""
},
"info": {
"accessibilityLabel": "",
"addPassword": "",
"cancelPassword": "",
"conferenceURL": "",
"country": "",
"accessibilityLabel": "Více info",
"addPassword": "Nastavit heslo",
"cancelPassword": "Zrušit heslo",
"conferenceURL": "Odkaz:",
"country": "Země",
"dialANumber": "",
"dialInConferenceID": "",
"dialInNotSupported": "",
"dialInNumber": "",
"dialInSummaryError": "",
"dialInTollFree": "",
"genericError": "",
"inviteLiveStream": "",
"invitePhone": "",
"genericError": "Ups, něco se pokazilo.",
"inviteLiveStream": "K zobrazení živého vysílání tohoto meetingu, klikněte na tento odkaz: {{url}}",
"invitePhone": "One tap audio Dial In: {{number}},,{{conferenceID}}#",
"invitePhoneAlternatives": "",
"inviteURLFirstPartGeneral": "",
"inviteURLFirstPartPersonal": "",
"inviteURLSecondPart": "",
"liveStreamURL": "",
"moreNumbers": "",
"noNumbers": "",
"noPassword": "Hotovo",
"noRoom": "",
"numbers": "",
"password": "",
"liveStreamURL": "Živé vysílání:",
"moreNumbers": "More numbers",
"noNumbers": "No dial-in numbers.",
"noPassword": "Bez hesla",
"noRoom": "No room was specified to dial-in into.",
"numbers": "Dial-in Numbers",
"password": "Heslo:",
"title": "Sdílet",
"tooltip": "",
"label": ""
"tooltip": "Sdílet odkaz k tomuto meetingu",
"label": "Informace o meetingu"
},
"\u0005info": {},
"inviteDialog": {
@@ -334,16 +334,16 @@
"focusRemote": "Vybrat obraz jiného volajícího",
"fullScreen": "Zobrazení / Opuštění režimu celé obrazovky",
"keyboardShortcuts": "Klávesové zkratky",
"localRecording": "",
"localRecording": "Spravovat kvalitu hovoru",
"mute": "Ztlumení nebo zesílení vašeho mikrofonu",
"pushToTalk": "Zmáčknout a mluvit",
"raiseHand": "Přihlásit nebo odhlásit se o slovo",
"showSpeakerStats": "Zobrazení statistiky řečníka",
"toggleChat": "Otevřít nebo zavřít chat",
"toggleFilmstrip": "",
"toggleFilmstrip": "Zobrazit / Skrýt videonáhledy účastníků",
"toggleScreensharing": "Přepnutí mezi kamerou a sdílením obrazovky",
"toggleShortcuts": "",
"videoMute": "Spuštění nebo vypnutí vaší kamery"
"toggleShortcuts": "Zobrazení / Skrytí klávesových zkratek",
"videoMute": "Spuštění / Vypnutí vaší kamery"
},
"\u0005keyboardShortcuts": {},
"liveStreaming": {
@@ -397,23 +397,23 @@
"moderator": "Moderátor",
"no": "",
"participant": "",
"participantStats": "",
"participantStats": "Zobrazit statistiku účastníků",
"sessionToken": "",
"start": "",
"stop": "",
"yes": ""
},
"lockRoomPassword": "Heslo",
"lockRoomPassword": "heslo",
"lockRoomPasswordUppercase": "Heslo",
"me": "já",
"notify": {
"connectedOneMember": "",
"connectedThreePlusMembers": "",
"connectedOneMember": "{{name}} se připojil",
"connectedThreePlusMembers": "{{name}} a {{count}} dalších se připojili",
"connectedTwoMembers": "",
"disconnected": "odpojeno",
"focus": "Vybrat konferenci",
"focusFail": "{{component}} není k dispozici - další pokus za {{ms}} sec",
"grantedTo": "Moderátorská práva přidělena účastníkovi{{to}}!",
"grantedTo": "Moderátorská práva přidělena účastníkovi {{to}}!",
"invitedOneMember": "",
"invitedThreePlusMembers": "",
"invitedTwoMembers": "",
@@ -440,27 +440,27 @@
"\u0005notify": {},
"passwordSetRemotely": "",
"passwordDigitsOnly": "",
"poweredby": "poháněno",
"poweredby": "Poháněno",
"presenceStatus": {
"busy": "",
"calling": "",
"connected": "",
"connecting": "Připojení:",
"connecting2": "Připojení:",
"disconnected": "odpojeno",
"expired": "",
"ignored": "",
"initializingCall": "",
"invited": "",
"rejected": "",
"ringing": ""
"busy": "Obsazeno",
"calling": "Vytáčím...",
"connected": "Spojování",
"connecting": "Spojování...",
"connecting2": "Spojování*...",
"disconnected": "Odpojeno",
"expired": "Spojení vypršelo",
"ignored": "Spojení ignorováno",
"initializingCall": "Nastavuji hovor...",
"invited": "Pozván",
"rejected": "Odmítnuto",
"ringing": "Zvoní..."
},
"\u0005presenceStatus": {},
"profile": {
"setDisplayNameLabel": "Nastavte si jméno",
"setEmailInput": "Zadejte e-mail",
"setEmailLabel": "Nastavte si email vašeho gravataru",
"title": ""
"title": "Profil"
},
"recording": {
"authDropboxText": "",
@@ -498,20 +498,20 @@
"signedIn": "",
"title": "Kalendář"
},
"devices": "",
"devices": "Zařízení",
"followMe": "Všichni sledují mě",
"language": "",
"loggedIn": "",
"language": "Jazyk",
"loggedIn": "Přihlášen jako {{name}}",
"moderator": "Moderátor",
"more": "",
"name": "",
"noDevice": "Hotovo",
"more": "Více",
"name": "Jméno",
"noDevice": "Žádné zařízení",
"selectAudioOutput": "Zvukový výstup",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"startAudioMuted": "Při připojení všem zlumit zvuk",
"startVideoMuted": "Všechny připojovat jako skrýté",
"title": ""
"title": "Nastavení"
},
"\u0005settings": {
"calendar": {}
@@ -539,10 +539,10 @@
"speakerStats": {
"hours": "",
"minutes": "",
"name": "",
"name": "Řečník",
"seconds": "",
"speakerStats": "",
"speakerTime": ""
"speakerStats": "Statistika řečníků",
"speakerTime": "Mluvil již"
},
"startupoverlay": {
"policyText": " ",
@@ -568,7 +568,7 @@
"kick": "",
"localRecording": "",
"lockRoom": "",
"moreActions": "",
"moreActions": "Více možností",
"moreActionsMenu": "",
"mute": "",
"pip": "",
@@ -579,11 +579,11 @@
"Settings": "",
"sharedvideo": "",
"shareRoom": "",
"shareYourScreen": "",
"shortcuts": "",
"shareYourScreen": "Sdílet obrazovku",
"shortcuts": "Zobrazit zkratky",
"show": "",
"speakerStats": "",
"tileView": "",
"speakerStats": "Statistika řečníků",
"tileView": "Přepnout režim zobrazení",
"toggleCamera": "",
"videomute": "",
"videoblur": ""
@@ -593,13 +593,13 @@
"audioOnlyOn": "",
"audioRoute": "",
"authenticate": "Ověřit",
"callQuality": "",
"callQuality": "Kvalita hovoru",
"chat": "Otevřít / Zavřít chat",
"closeChat": "",
"documentClose": "Otevřít / Zavřít sdílený dokument",
"documentOpen": "Otevřít / Zavřít sdílený dokument",
"enterFullScreen": "",
"enterTileView": "",
"enterFullScreen": "Přepnout na celou obrazovku",
"enterTileView": "Přepnout režim zobrazení",
"exitFullScreen": "",
"exitTileView": "",
"feedback": "",
@@ -608,29 +608,29 @@
"login": "Přihlásit se",
"logout": "Odhlásit",
"lowerYourHand": "",
"moreActions": "",
"moreActions": "Více možností",
"mute": "Ztlumit / Zesílit",
"openChat": "",
"pip": "",
"profile": "Upravit váš profil",
"raiseHand": "Příhlásit / Odhlásit se o slovo",
"raiseYourHand": "",
"Settings": "",
"sharedvideo": "Sdílet YouTube video",
"Settings": "Nastavení",
"sharedvideo": "Sdílet obraz YouTube videa",
"shareRoom": "",
"shortcuts": "",
"speakerStats": "",
"shortcuts": "Klávesové zkratky",
"speakerStats": "Statistiky řečníků",
"startScreenSharing": "",
"startSubtitles": "",
"stopScreenSharing": "",
"stopSubtitles": "",
"stopSharedVideo": "",
"talkWhileMutedPopup": "Snažíte se mluvit? Máte ztlumené audio.",
"tileViewToggle": "",
"tileViewToggle": "Přepnout režim zobrazení",
"toggleCamera": "",
"videomute": "Zapnutí / Vypnutí kamery",
"startvideoblur": "",
"stopvideoblur": ""
"startvideoblur": "Rozmazat pozadí",
"stopvideoblur": "Zrušit rozmazání"
},
"\u0005toolbar": {
"accessibilityLabel": {}
@@ -670,22 +670,25 @@
"pending": ""
},
"videoStatus": {
"audioOnly": "",
"audioOnly": "AU",
"audioOnlyExpanded": "",
"callQuality": "",
"callQuality": "Nastavení kvality hovoru",
"hd": "",
"highDefinition": "",
"hdTooltip": "Sledujete obraz ve vysoké kvalitě",
"highDefinition": "Vysoká kvalita",
"labelTooiltipNoVideo": "",
"labelTooltipAudioOnly": "",
"ld": "",
"lowDefinition": "",
"ldTooltip": "Sledujete obraz v nízké kvalitě",
"lowDefinition": "Nizká kvalita",
"onlyAudioAvailable": "",
"onlyAudioSupported": "",
"p2pEnabled": "",
"p2pVideoQualityDescription": "",
"recHighDefinitionOnly": "",
"sd": "",
"standardDefinition": ""
"sdTooltip": "Sledujete obraz v běžné kvalitě",
"standardDefinition": "Běžná kvalita"
},
"videothumbnail": {
"domute": "Ztlumený zvuk",
@@ -704,7 +707,7 @@
"join": "",
"roomname": "Zadejte jméno místnosti"
},
"appDescription": "Jděte na to, videokonference v rámci celého týmu. Do konference můžete pozvat kohokoliv. Veškerá komunikace přes aplikaci {{app}} je plně šifrovaná, 100% open source zajištuje, že aplikaci můžete využívat bez omezení a navíc se nemusíte ani registrovat.",
"appDescription": "Videokonference pro celý Váš tým, zdarma, bez nároků na Vaše data. Do konference můžete pozvat kohokoliv. Veškerá komunikace přes aplikaci {{app}} je plně šifrovaná, 100% open source zajištuje, že aplikaci můžete využívat bez omezení a navíc se nemusíte ani registrovat.",
"audioVideoSwitch": {
"audio": "Hlas",
"video": "Obraz"
@@ -712,19 +715,19 @@
"calendar": "Kalendář",
"connectCalendarButton": "",
"connectCalendarText": "",
"enterRoomTitle": "",
"enterRoomTitle": "Začít nový videohovor",
"go": "ZAČÍT",
"join": "PŘIPOJIT",
"info": "",
"privacy": "Soukromí",
"recentList": "",
"recentListDelete": "",
"recentListEmpty": "",
"recentListEmpty": "Váš seznam nedávných hovorů je prázdný. Spojte se s kolegy z Vašeho týmu, poté zde naleznete seznam nedávných hovorů.",
"reducedUIText": "",
"roomname": "Zadejte jméno místnosti",
"roomnameHint": "Zadejte název nebo URL odkaz místnosti ke které se chcete připojit. Pokud jste místnost vytvořili, ujistěte se, že ostatní účastníci schůzky zadají stejné jméno jako vy.",
"sendFeedback": "Poslat zpětnou vazbu",
"terms": "Podmínky používání",
"title": ""
"title": "Bezpečné, plnotučné videokonference, zcela zdarma a soukromě, od lidí pro lidi."
}
}
}

772
lang/main-da.json Normal file
View File

@@ -0,0 +1,772 @@
{
"addPeople": {
"add": "Inviter",
"countryNotSupported": "Vi supporterer ikke dette land endnu.",
"countryReminder": "Ringer du til uden for USA? Benyt venligst landekode!",
"disabled": "Du kan ikke invitere deltagere.",
"failedToAdd": "Kunne ikke tilføje deltagere.",
"footerText": "Udgående opkald er slået fra.",
"loading": "Søger efter personer og telefonnumre.",
"loadingNumber": "Validerer telefonnummer",
"loadingPeople": "Søger efter folk der kan inviteres",
"noResults": "Der blev ikke fundet noget",
"noValidNumbers": "Indtast venligst er telefonnummer",
"searchNumbers": "Tilføj telefonnummer",
"searchPeople": "Søg efter personer",
"searchPeopleAndNumbers": "Søg efter personer eller tilføj deres telefonnummer",
"telephone": "Telefon: {{number}}",
"title": "Inviter personer til dette møde"
},
"audioDevices": {
"bluetooth": "Bluetooth",
"headphones": "Høretelefoner",
"phone": "Telefon",
"speaker": "Højtaler",
"none": "Der er ikke nogen lyd enheder tilgængelige"
},
"audioOnly": {
"audioOnly": "Kun lyd"
},
"calendarSync": {
"addMeetingURL": "Tilføj et mødelink",
"confirmAddLink": "Ønsker du at tilføj et Jitsi link til denne aftale?",
"error": {
"appConfiguration": "Kalender integration er ikke sat korrekt op.",
"generic": "Der er sket en fejl. Verificer venligst dine kalenderindstilliinger eller prøv på at genopfriske din kalender.",
"notSignedIn": "Der er sket en fejl under log ind for at hente kalenderaftalerne. Kontroller venligst dine kalenderindstilliinger og forsøg at logge ind igen."
},
"join": "Deltag",
"joinTooltip": "Deltag i mødet",
"nextMeeting": "næste møde",
"noEvents": "Der er ikke nogen kommande aftaler i kalenderen.",
"ongoingMeeting": "igangværende møde",
"permissionButton": "Åben indstillinger",
"permissionMessage": "Kalender tilladelsen er nødvendig for at kunne se dine aftaler i appen.",
"refresh": "Genopfrisk aftaler",
"today": "I dag"
},
"chat": {
"error": "Fejl: din besked \"{{originalText}}\" blev ikke sendt. Årsag: {{error}}",
"fieldPlaceHolder": "Skriv din besked her",
"messagebox": "Indtast en besked",
"messageTo": "Privat besked til {{recipient}}",
"noMessagesMessage": "Der er ikke nogen beskeder i mødet endnu. Skriv noget!",
"nickname": {
"popover": "Vælg dit navn/alias",
"title": "Indtast et navn/alias for at deltage i chatten"
},
"privateNotice": "Privat besked til {{recipient}}",
"title": "Chat",
"you": "dig"
},
"chromeExtensionBanner": {
"installExtensionText": "Installér plugin for Google Kalender og Office 365 integration",
"buttonText": "Installér Chrome plugin",
"dontShowAgain": "Vis ikke dette igen"
},
"connectingOverlay": {
"joiningRoom": "Forbinder dig til mødet..."
},
"connection": {
"ATTACHED": "Forbundet",
"AUTHENTICATING": "Autoriserer",
"AUTHFAIL": "Autorisation lykkedes ikke",
"CONNECTED": "Forbundet",
"CONNECTING": "Forbinder",
"CONNFAIL": "Forbindelse kunne ikke oprettes",
"DISCONNECTED": "Frakoblet",
"DISCONNECTING": "Frakobler",
"ERROR": "Fejl",
"RECONNECTING": "Et netværksproblem opstod. Forbinder igen...",
"GET_SESSION_ID_ERROR": "Hent session-id fejl: {{code}}",
"GOT_SESSION_ID": "HEnter session-id... Udført",
"LOW_BANDWIDTH": "Video for {{displayName}} er slået fra for at spare båndbredde"
},
"connectionindicator": {
"address": "Adresse:",
"bandwidth": "Estimeret båndbredde:",
"bitrate": "Bitrate:",
"bridgeCount": "Server antal: ",
"connectedTo": "Forbundet til:",
"e2e_rtt": "E2E RTT:",
"framerate": "Frame rate:",
"less": "Vis mindre",
"localaddress": "Lokal adresse:",
"localaddress_plural": "Lokale adresser:",
"localport": "Lokal port:",
"localport_plural": "Lokale porte:",
"more": "Vis mere",
"packetloss": "Pakke tab:",
"quality": {
"good": "God",
"inactive": "Inaktiv",
"lost": "Tabt",
"nonoptimal": "Ikke optimal",
"poor": "Dårlig"
},
"remoteaddress": "Fjern adresse:",
"remoteaddress_plural": "Fjern adresser:",
"remoteport": "Fjern port:",
"remoteport_plural": "Fjern porte:",
"resolution": "Opløsning:",
"status": "Forbindelse:",
"transport": "Transport:",
"transport_plural": "Transporter:",
"turn": " (turn)"
},
"dateUtils": {
"earlier": "Tidligere",
"today": "I dag",
"yesterday": "I går"
},
"deepLinking": {
"appNotInstalled": "Du skal bruge {{app}} mobil appen for at forbinde til dette møde med din mobiltelefon.",
"description": "Skete der ikke noget? Vi forsøgte at åbne dit videomøde i {{app}} desktop appen. Prøv igen eller start mødet på {{app}} web app.",
"descriptionWithoutWeb": "",
"downloadApp": "Download appen",
"launchWebButton": "Start på web",
"openApp": "Fortsæt til appen",
"title": "Start dit møde i {{app}}...",
"tryAgainButton": "Prøv igen"
},
"defaultLink": "e.g. {{url}}",
"defaultNickname": "ex. Jane Pink",
"deviceError": {
"cameraError": "Kunne ikke forbinde til dit kamera",
"cameraPermission": "Kamera tilladelse mangler",
"microphoneError": "Kunne ikke forbinde til din mikrofon",
"microphonePermission": "Mikrofon tilladelse mangler"
},
"deviceSelection": {
"noPermission": "Tilladelse ikke givet",
"previewUnavailable": "Forhåndsvisning mangler",
"selectADevice": "Vælg en enhed",
"testAudio": "Afspil testlyd"
},
"dialog": {
"accessibilityLabel": {
"liveStreaming": "Live Stream"
},
"allow": "Tillad",
"alreadySharedVideoMsg": "En anden deltager deler allerede en video. Denne konference tillader kun en delt video af gangen.",
"alreadySharedVideoTitle": "Det er kun muligt at dele en video af gangen",
"applicationWindow": "Applikations vindue",
"Back": "Tilbage",
"cameraConstraintFailedError": "Dit kamera lever ikke op til de nødvendige krav..",
"cameraNotFoundError": "Kamera kunne ikke findes.",
"cameraNotSendingData": "Vi kan ikke tilgå dit kamera. Kontroller venligst om der er en anden applikation der gør brug af dit kamera, eller vælg en andet kamera og genindlæs siden.",
"cameraNotSendingDataTitle": "Kan ikke tilgå kamera",
"cameraPermissionDeniedError": "Du har ikke givet tilladelse til at bruge dit kamera. Du kan stadig deltage i mødet men de andre deltagere vil ikke kunne se dig. Gør brug af kamera knappen i adressebaren for at give tilladelse.",
"cameraUnknownError": "Kan ikke gør brug af dit kamera, årsag ukendt.",
"cameraUnsupportedResolutionError": "Dit kamera supporterer ikke den nødvendige opløsning.",
"Cancel": "Afbryd",
"close": "Luk",
"conferenceDisconnectMsg": "Kontroller venligst din netværksforbindelse. Forbinder igen om {{seconds}} sekunder...",
"conferenceDisconnectTitle": "Din forbindelse er blevet afbrudt.",
"conferenceReloadMsg": "Forsøger at genoprette forbindelsen. Forbinder igen om {{seconds}} sekunder...",
"conferenceReloadTitle": "Der er desværre gået noget galt.",
"confirm": "Bekræft",
"confirmNo": "Nej",
"confirmYes": "Ja",
"connectError": "Det var ikke muligt at forbinde til mødet.",
"connectErrorWithMsg": "Det var ikke muligt at forbinde til mødet: {{msg}}",
"connecting": "Forbinder",
"contactSupport": "Kontakt support",
"copy": "Kopier invitation",
"dismiss": "Afbryd",
"displayNameRequired": "Navn/alias er påkrævet",
"done": "Gem",
"enterDisplayName": "Indtast venligst dit navn/alias",
"error": "Fejl",
"externalInstallationMsg": "Du skal installerer vores skærmdelings plugin.",
"externalInstallationTitle": "Plugin skal bruges",
"goToStore": "Gå til webstore",
"gracefulShutdown": "Vores service er pt. under vedligeholdese. Forsøg venligst igen senere.",
"IamHost": "Jeg er vært",
"incorrectRoomLockPassword": "",
"incorrectPassword": "Forkert brugernavn eller adgangskode",
"inlineInstallationMsg": "Du skal installerer vores skærmdelings plugin.",
"inlineInstallExtension": "Installer nu",
"internalError": "Der er opstået en fejl: {{error}}",
"internalErrorTitle": "Intern fejl",
"kickMessage": "Du er blevet afbrudt fra mødet!",
"kickParticipantButton": "Afbryd",
"kickParticipantDialog": "Er du sikker på at du vil afbryde den deltager?",
"kickParticipantTitle": "Afbryd denne deltager?",
"kickTitle": "Afbrudt fra møde",
"liveStreaming": "Live Streaming",
"liveStreamingDisabledForGuestTooltip": "Gæster kan ikke starte en live stream.",
"liveStreamingDisabledTooltip": "Live streaming er slået fra.",
"lockMessage": "Kunne ikke sikre mødet.",
"lockRoom": "Tilføj adgangskode",
"lockTitle": "Sikring fejlet",
"logoutQuestion": "Er du sikker på at du vil logge ud og stoppe mødet?",
"logoutTitle": "Log ud",
"maxUsersLimitReached": "Grænsen for antal deltagere er nået. Mødet er fuldt. Kontakt ejeren af mødet eller prøv igen senere!",
"maxUsersLimitReachedTitle": "Maksimum antal deltagere nået",
"micConstraintFailedError": "Din mikrofon supporterer ikke de nødvendige specifikationer.",
"micNotFoundError": "Mikrofon ikke fundet.",
"micNotSendingData": "Vi kunne ikke tilgå din mikrofon. Vælg en anden mikrofon under indstillinger eller genindlæs applikationen.",
"micNotSendingDataTitle": "Kunne ikke tilgå din mikrofon",
"micPermissionDeniedError": "Du har ikke givet tilladelse til at bruge din mikrofon. Du kan stadig deltage i mødet men de andre deltagere kan ikke høre dig. Benyt kamera knappen i adressbaren for at give tilladelse.",
"micUnknownError": "Kan ikke tilgå mikrofon af ukendt årsag.",
"muteEveryoneElseDialog": "Er du sikker på at du vil slå lyden fra for denne deltager? Du kan ikke tænde igen, men de kan selv tænde til enhver tid.",
"muteEveryoneElseTitle": "Slå lyd fra for alle undtagen {{whom}}?",
"muteEveryoneDialog": "Er du sikker på at du vil slå lyden fra for denne deltager? Du kan ikke tænde igen, men de kan selv tænde til enhver tid.",
"muteEveryoneTitle": "Slå lyd fra for alle?",
"muteEveryoneSelf": "dig selv",
"muteEveryoneStartMuted": "Lyden er slpet fra for alle fra nu af",
"muteParticipantBody": "Du kan ikke tænde for deres mikrofon, men de kan selv tænde for deres mikrofon til enhver tid.",
"muteParticipantButton": "Slå lyd fra",
"muteParticipantDialog": "Er du sikker på at du vil slå lyden fra for denne deltager? Du kan ikke tænde igen, men de kan selv tænde til enhver tid.",
"muteParticipantTitle": "Slå lyd fra for denne deltager?",
"Ok": "Ok",
"passwordLabel": "Adgangskode",
"passwordNotSupported": "Sætte en adgangskode for mødet er ikke understøttet.",
"passwordNotSupportedTitle": "Adgangskode er ikke understøttet",
"passwordRequired": "Adgangskode påkrævet",
"popupError": "Din browser blockerer for pop-upper fra denne hjemmeside. Slå venligst pop-upper til i din browsers indstillinger og forsøg igen.",
"popupErrorTitle": "Pop-up blokkeret",
"recording": "Optager",
"recordingDisabledForGuestTooltip": "Gæster kan ikke starte en optagelse.",
"recordingDisabledTooltip": "Start optagelse er slået fra.",
"rejoinNow": "Deltag igen",
"remoteControlAllowedMessage": "{{user}} accepterede din fjernstyring anmodning!",
"remoteControlDeniedMessage": "{{user}} afviste din fjernstyring anmodning!",
"remoteControlErrorMessage": "En fejl er opstået ved anmodning om fjernstyring for {{user}}!",
"remoteControlRequestMessage": "Vil du tillade at {{user}} fjerstyrer din computer?",
"remoteControlShareScreenWarning": "Bemærk at hvis du vælger \"Tillad\" så vil du tillade fjernstyring!",
"remoteControlStopMessage": "Fjernstyrings sessionen er afsluttet!",
"remoteControlTitle": "Fjerstyring",
"Remove": "Fjern",
"removePassword": "Fjern adgangskode",
"removeSharedVideoMsg": "Er du sikker på at du vil fjerne di delte video?",
"removeSharedVideoTitle": "Fjern delt video",
"reservationError": "Reservation - system fejl",
"reservationErrorMsg": "Fejlkode: {{code}}, fejl: {{msg}}",
"retry": "Forsøg igen",
"screenSharingFailedToInstall": "Skærmdelings-plugin kunne ikke installeres.",
"screenSharingFailedToInstallTitle": "Skærmdelings-plugin kunne ikke installeres.",
"screenSharingFirefoxPermissionDeniedError": "Noget gik galt under skærmdeling. Kontroller venligst at du har givet tilladelse til skærmdeling. ",
"screenSharingFirefoxPermissionDeniedTitle": "Skærmdeling kunne ikke startes!",
"screenSharingPermissionDeniedError": "Noget gik galt under skærmdeling. Kontroller venligst at du har givet tilladelse til skærmdeling. Genindlæs siden og forsøg igen.",
"sendPrivateMessage": "Du har modtage en privat besked. Ønsker du at svare private eller øsnker du at svare til gruppen?",
"sendPrivateMessageCancel": "Send til gruppen",
"sendPrivateMessageOk": "Send privat",
"sendPrivateMessageTitle": "Send privat?",
"serviceUnavailable": "Service er ikke tilgængelig",
"sessTerminated": "Møde afsluttet",
"Share": "Del",
"shareVideoLinkError": "Angiv venligst et validt Youtube link.",
"shareVideoTitle": "Del en video",
"shareYourScreen": "Del din skærm",
"shareYourScreenDisabled": "Skærmdeling er ikke slået til.",
"shareYourScreenDisabledForGuest": "Gæster kan ikke dele deres skærm.",
"startLiveStreaming": "Start live stream",
"startRecording": "Start optagelse",
"startRemoteControlErrorMessage": "Der er sket en fejl under opstart af fjern kontrol sessionen!",
"stopLiveStreaming": "Stop live stream",
"stopRecording": "Stop optagelse",
"stopRecordingWarning": "Er du sikker på at du ønsker at stoppe optagelesen?",
"stopStreamingWarning": "Er du sikker på at du ønsker at stoppe live streaming?",
"streamKey": "Live stream nøgle",
"Submit": "Gem",
"thankYou": "Tak for at du har benyttet {{appName}}!",
"token": "token",
"tokenAuthFailed": "Beklager, du kan ikke deltage i dette møde.",
"tokenAuthFailedTitle": "Log ind fejlede",
"transcribing": "Transcribering",
"unlockRoom": "Fjern møde adgangskode",
"userPassword": "bruger adgangskode",
"WaitForHostMsg": "Mødet <b>{{room}}</b> er ikke startet endnu. Hvis du er hosten log venligst ind, ellers vent på at hosten kommer.",
"WaitForHostMsgWOk": "Mødet <b>{{room}}</b> er ikke startet endnu. Hvis du er hosten tryk venligst på OK for at logge ind, ellers vent på at hosten kommer.",
"WaitingForHost": "Venter på host ...",
"Yes": "Ja",
"yourEntireScreen": "Hele din skærm"
},
"dialOut": {
"statusMessage": "er nu {{status}}"
},
"documentSharing": {
"title": "Delt dokument"
},
"feedback": {
"average": "Normal",
"bad": "Dårlig",
"detailsLabel": "Uddyb.",
"good": "God",
"rateExperience": "Vurder din oplevelse",
"veryBad": "Meget dårlig",
"veryGood": "Meget god"
},
"incomingCall": {
"answer": "Besvar",
"audioCallTitle": "Indkommende opkald",
"decline": "Afvis",
"productLabel": "fra Appinux skærmbesøg",
"videoCallTitle": "Indkommende videoopkald"
},
"info": {
"accessibilityLabel": "Vis info",
"addPassword": "Tilføj adgangskode",
"cancelPassword": "Annulé adgangskode",
"conferenceURL": "Link:",
"country": "Land",
"dialANumber": "For at deltage i mødet ring til et af følgende telefonnumre og indtast pinkode.",
"dialInConferenceID": "Pinkode:",
"dialInNotSupported": "Deltagelse vis telfonen er pt. ikke understøttet.",
"dialInNumber": "Ring ind:",
"dialInSummaryError": "Der er opstået en fejl under hentning af ring ind information. Forsøg venligst igen senere.",
"dialInTollFree": "Gratis",
"genericError": "Der er opstået en fejl",
"inviteLiveStream": "For at se en live stream i dette møde klik på dette link: {{url}}",
"invitePhone": "Ring-ind: {{number}},,{{conferenceID}}#",
"invitePhoneAlternatives": "",
"inviteURLFirstPartGeneral": "Der er blevet inviteret til at deltage i et møde.",
"inviteURLFirstPartPersonal": "{{name}} inviterer dig til at deltage i et møde.\n",
"inviteURLSecondPart": "\nDeltag i mødet:\n{{url}}\n",
"liveStreamURL": "Live stream:",
"moreNumbers": "Flere telefonnumre",
"noNumbers": "Ring-ind nummer findes ikke.",
"noPassword": "Ingen",
"noRoom": "Ring-ind møde information blev ikke angivet.",
"numbers": "Ring-ind numre",
"password": "Adgangskode:",
"title": "Del",
"tooltip": "Del link og rind-ind information for dette møde",
"label": "Møde information"
},
"inviteDialog": {
"alertText": "Kunne ikke invitere nogle af deltagerne.",
"header": "Invitér",
"searchCallOnlyPlaceholder": "Indtast telefonnummer",
"searchPeopleOnlyPlaceholder": "Søg efter deltagere",
"searchPlaceholder": "Deltager eller telefonnummer",
"send": "Send"
},
"inlineDialogFailure": {
"msg": "Der er opstået en fejl.",
"retry": "Forsøg igen",
"support": "Support",
"supportMsg": "Hvis denne fejl bliver ved, kontakt"
},
"keyboardShortcuts": {
"focusLocal": "Fokusér på din video",
"focusRemote": "Fokusér på en anden persons video",
"fullScreen": "Vis eller annullér fuld skærm",
"keyboardShortcuts": "Tastaturgenveje",
"localRecording": "Vis eller skjul optage kontrolknapper",
"mute": "Slå lyd fra eller til for din mikrofon",
"pushToTalk": "Tryk for at tale",
"raiseHand": "Lyft eller sænk din hånd",
"showSpeakerStats": "Vis højtaler statistik",
"toggleChat": "Åben eller luk chat",
"toggleFilmstrip": "Vis eller skjul video små billeder",
"toggleScreensharing": "Skift mellem video og skærmdeling",
"toggleShortcuts": "Vis eller skjul tastaturgenveje",
"videoMute": "Tænd eller sluk dit kamera",
"videoQuality": "Indstil opkaldskvalitet"
},
"liveStreaming": {
"busy": "Der arbejdes på at frigive streamingresourcer, forsøg venligst igen om et par minutter.",
"busyTitle": "Alle streamers er optaget",
"changeSignIn": "Skift konto.",
"choose": "Vælg en live stream",
"chooseCTA": "Vælg en stream mulighed. Du er pt. logget ind som {{email}}.",
"enterStreamKey": "Indtast din Youtube live stream her.",
"error": "Fejl under live streaming. Forsøg venligst igen.",
"errorAPI": "En fejl opstod ved forsøg på at tilgå din YouTube broadcast. Forsøg venligst at logge ind igen.",
"errorLiveStreamNotEnabled": "Live Streaming er ikke slpet til for {{email}}. Slå venligst live streaming til eller log ind på en konto der har live streaming slået til.",
"expandedOff": "Live stream er stoppet",
"expandedOn": "Mødet bliver pt. streamet til Youtube.",
"expandedPending": "Live streaming starter...",
"failedToStart": "Kunne ikke starte live streaming",
"getStreamKeyManually": "Vi kunne ikke hente nogle live streams. Forsøg at hente din live stream nøgle fra Youtube.",
"invalidStreamKey": "Live stream nøgle er muligvis forkert.",
"off": "Live Streaming er stoppet",
"offBy": "{{name}} stoppede live streaming",
"on": "Live Streaming",
"onBy": "{{name}} startede live streaming",
"pending": "Starter Live Stream...",
"serviceName": "Live Streaming service",
"signedInAs": "Du er pt. logget ind som:",
"signIn": "Log ind med Google",
"signInCTA": "Log ind eller indtast din live stream nøgle fra YouTube.",
"signOut": "Log ud",
"start": "Start en live stream",
"streamIdHelp": "Hvad er dette?",
"unavailableTitle": "Live Streaming er ikke tilgængelig"
},
"localRecording": {
"clientState": {
"off": "Slået fra",
"on": "Slået til",
"unknown": "Ukendt"
},
"dialogTitle": "Optage kontrolknapper",
"duration": "Varighed",
"durationNA": "Ikke tilgængelig",
"encoding": "Encoding",
"label": "Optager",
"labelToolTip": "Optager er slået til",
"localRecording": "Local Recording",
"me": "Mig",
"messages": {
"engaged": "Optager er slået til.",
"finished": "Optagelses session {{token}} afsluttet. Send venligst den optagede fil til moderator.",
"finishedModerator": "Optagelses session {{token}} afsluttet. Optagelsen er gemt. Bed deltageren om at sende deres optagelser.",
"notModerator": "Du er ikke moderator. Du kan ikke starte eller stoppe optagelser."
},
"moderator": "Moderator",
"no": "Nej",
"participant": "Deltager",
"participantStats": "Deltager statistik",
"sessionToken": "Sessionsnøgle",
"start": "Start optagelse",
"stop": "Stop optagelse",
"yes": "Ja"
},
"lockRoomPassword": "adgangskode",
"lockRoomPasswordUppercase": "Adgangskode",
"me": "mig",
"notify": {
"connectedOneMember": "{{name}} deltager nu i mødet",
"connectedThreePlusMembers": "{{name}} og {{count}} andre deltager nu i mødet",
"connectedTwoMembers": "{{first}} og {{second}} deltager nu i mødet",
"disconnected": "afbrudt",
"focus": "Konference fokus",
"focusFail": "{{component}} ikke tilgængelig - forsøg igen om {{ms}} sekunder",
"grantedTo": "Moderator rettigheder er givet til {{to}}!",
"invitedOneMember": "{{name}} er blevet inviteret",
"invitedThreePlusMembers": "{{name}} og {{count}} andre er blevet inviteret",
"invitedTwoMembers": "{{first}} og {{second}} er blevet inviteret",
"kickParticipant": "{{kicked}} blev afbrudt fra mødet af {{kicker}}",
"me": "Mig",
"moderator": "Moderator rettigheder givet!",
"muted": "Du har startet samtalen med lyden slået fra.",
"mutedTitle": "Din lyd er slået fra!",
"mutedRemotelyTitle": "Din lyd er slået fra af {{participantDisplayName}}!",
"mutedRemotelyDescription": "",
"passwordRemovedRemotely": "",
"passwordSetRemotely": "",
"raisedHand": "{{name}} ønsker at få ordet.",
"somebody": "Nogen",
"startSilentTitle": "",
"startSilentDescription": "",
"suboptimalExperienceDescription": "Hmmm... vi er bange for at din oplevelse med {{appName}} ikke vil være optimal. Vi arbejder på at forbedre dette, men indtil da så forsøg venligst at bruge en af følgende <a href='static/recommendedBrowsers.html' target='_blank'>fuldt understøttede internet browsere</a>.",
"suboptimalExperienceTitle": "Browser Advarsel",
"unmute": "",
"newDeviceCameraTitle": "Nyt kamerat fundet",
"newDeviceAudioTitle": "Ny lyd enhed fundet",
"newDeviceAction": "Benyt"
},
"passwordSetRemotely": "sat af et andet medlem",
"passwordDigitsOnly": "Op til {{number}} tal",
"poweredby": "powered by",
"presenceStatus": {
"busy": "Optaget",
"calling": "Ringer op...",
"connected": "Forbundet",
"connecting": "Forbinder...",
"connecting2": "Forbinder*...",
"disconnected": "Forbindelse afbrudt",
"expired": "Udløbet",
"ignored": "Ignoreret",
"initializingCall": "Starter opkald...",
"invited": "Inviteret",
"rejected": "Afvist",
"ringing": "Ringer..."
},
"profile": {
"setDisplayNameLabel": "Vælg navn/alias",
"setEmailInput": "Indtast email",
"setEmailLabel": "Indtast gravatar email",
"title": "Profil"
},
"raisedHand": "Ønsker at tale",
"recording": {
"authDropboxText": "Upload til Dropbox",
"availableSpace": "Tilgængelig plads: {{spaceLeft}} MB (plads til ca. {{duration}} minutters optagelse)",
"beta": "BETA",
"busy": "Der arbejdes på at frigive optagelsesresourcer. Prøv venligst igen om nogle få minutter.",
"busyTitle": "Alle optagere er pt optaget",
"error": "Fejl under optagelse, forsøg venligst igen om lidt.",
"expandedOff": "Optagelse er stoppet½",
"expandedOn": "Mødet bliver pt. optaget.",
"expandedPending": "Optagelse starter...",
"failedToStart": "Kunne ikke start optagelse",
"fileSharingdescription": "Del optagelse med deltagere",
"live": "LIVE",
"loggedIn": "Logget ind som {{userName}}",
"off": "Optagelse stoppet",
"offBy": "{{name}} stoppede optagelsen",
"on": "Optager",
"onBy": "{{name}} startede optagelsen",
"pending": "Gør klar til at optage mødet...",
"rec": "REC",
"serviceDescription": "Din optagelse bliver gemt af optager servicen",
"serviceName": "Optager service",
"signIn": "Log ind",
"signOut": "Log ud",
"unavailable": "Optager service {{serviceName}} er ikke tilgængelig. Der arbejdes på at løse problemet, forsøg igen senere.",
"unavailableTitle": "Optagelse ikke tilgængelig"
},
"sectionList": {
"pullToRefresh": "Træk ned for update"
},
"settings": {
"calendar": {
"about": "{{appName}}s kalenderintegration benyttes til at sikkert tilgå din kalender så den kan læse fremtidige aftaler.",
"disconnect": "Afbryd",
"microsoftSignIn": "Log ind med Microsoft",
"signedIn": "Henter kalenderaftaler for {{email}}. Tryk på Afbryd knappen for at afbryde forbindelsen.",
"title": "Kalender"
},
"devices": "Enheder",
"followMe": "Alle følger mig",
"language": "Sprog",
"loggedIn": "Logget ind som {{name}}",
"moderator": "Moderator",
"more": "Mere",
"name": "Navn",
"noDevice": "Ingen",
"selectAudioOutput": "Lyd udgang",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"startAudioMuted": "Alle starter med lyden slået fra",
"startVideoMuted": "Alle starter skjult",
"title": "Indstillinger"
},
"settingsView": {
"advanced": "Avanceret",
"alertOk": "OK",
"alertTitle": "Advarsel",
"alertURLText": "Den indtastede server url er ikke korrekt",
"buildInfoSection": "Build Information",
"conferenceSection": "Konference",
"disableCallIntegration": "Slå indbygget opkalds integration fra",
"disableP2P": "Slå Peer-To-Peer fra",
"displayName": "Navn/alias",
"email": "Email",
"header": "Indstillinger",
"profileSection": "Profil",
"serverURL": "Server URL",
"showAdvanced": "Show advanced settings",
"startWithAudioMuted": "Start med lyden slået fra",
"startWithVideoMuted": "Start med video slået fra",
"version": "Version"
},
"share": {
"dialInfoText": "\n\n=====\n\nØnsker du at ringe ind fra din telefon?\n\n{{defaultDialInNumber}}Klik på dette link for at se telefonnummeret for dette møde\n{{dialInfoPageUrl}}",
"mainText": "Klik på det følgende link for at deltage i mødet:\n{{roomUrl}}"
},
"speaker": "Højtaler",
"speakerStats": {
"hours": "{{count}}t",
"minutes": "{{count}}m",
"name": "Navn",
"seconds": "{{count}}s",
"speakerStats": "Højtaler info",
"speakerTime": "Højtaler tid"
},
"startupoverlay": {
"policyText": " ",
"title": "{{app}} har brug for adgang til din mikrofon og kamera."
},
"suspendedoverlay": {
"rejoinKeyTitle": "Forbind igen",
"text": "Tryk på <i>Forbind igen </i> knappen for at deltage igen.",
"title": "Dit møde blev afbrudt da din computer gik i dvale."
},
"toolbar": {
"accessibilityLabel": {
"audioOnly": "Tænd/sluk lyd",
"audioRoute": "Vælg lydenhed",
"callQuality": "Indstil møde kvalitet",
"cc": "Slå undertekst fra/til",
"chat": "Slå chat fra/til",
"document": "Slå delte dokumenter fra/til",
"download": "Hent vores apps",
"feedback": "Giv tilbagemelding",
"fullScreen": "Slå fuld skærm fra/til",
"hangup": "Forlad mødet",
"help": "Hjælp",
"invite": "Inviter deltagere",
"kick": "Afbryd deltager",
"localRecording": "Slå optagekontroller fra/til",
"lockRoom": "Slå mødeadgangskode fra/til",
"moreActions": "Slå \"Flere indstillinger\" menu fra/til",
"moreActionsMenu": "Flere indtstillinger",
"moreOptions": "Show more options",
"mute": "Slå lyd til/fra",
"muteEveryone": "Mute everyone",
"pip": "Slå Billede-i-billede fra/til",
"privateMessage": "Send privat besked",
"profile": "Redigér profil",
"raiseHand": "Slå løft hånden fra/til",
"recording": "Slå optagelse til/fra",
"remoteMute": "Slå lyd fra for deltager",
"Settings": "Slå indstillinger fra/til",
"sharedvideo": "Slå Youtube video deling fra/til",
"shareRoom": "Invitér nogen",
"shareYourScreen": "Slå skærmdeling fra/til",
"shortcuts": "Slå genveje fra/til",
"show": "Vis",
"speakerStats": "Slå højtaler info fra/til",
"tileView": "Slå tileview fra/til",
"toggleCamera": "Slå kamera fra/til",
"videomute": "Slå video fra/til",
"videoblur": "Slå baggrundsløring fra/til"
},
"addPeople": "Tilføj deltager til mødet",
"audioOnlyOff": "Slå kun-lyd møder fra",
"audioOnlyOn": "Slå kun-lyd møder til",
"audioRoute": "Vælg lydenhed",
"authenticate": "Log ind",
"callQuality": "Indstil møde kvalitet",
"chat": "Åben / Luk chat",
"closeChat": "Luk chat",
"documentClose": "Luk delt dokument",
"documentOpen": "Åben delt dokument",
"download": "Hent vores apps",
"enterFullScreen": "Vis fuld skærm",
"enterTileView": "Tileview",
"exitFullScreen": "Luk fuld skærm",
"exitTileView": "Luk Tileview",
"feedback": "Giv tilbagemeldign",
"hangup": "Forlad",
"help": "Hjælp",
"invite": "Invitér deltagere",
"login": "Log ind",
"logout": "Log ud",
"lowerYourHand": "Ta hånden ned",
"moreActions": "Flere handlinger",
"moreOptions": "Flere indstillinger",
"mute": "Slå lyd fra / Slå lyd til",
"muteEveryone": "Slå lyd fra for alle",
"noAudioSignalTitle": "Der kommer ingen input fra din mikrofon!",
"noAudioSignalDesc": "Hvis du ikke med vilje har slået den fra under systemindstillinger eller hardware, kan du overveje at skifte enhed.",
"noAudioSignalDescSuggestion": "Hvis du ikke med vilje har slået den fra under systemindstillinger eller hardware, skal du overveje at skifte til den foreslåede enhed.",
"noAudioSignalDialInDesc": "Du kan også ringe op ved hjælp af:",
"noAudioSignalDialInLinkDesc": "Opkaldsnumre",
"noisyAudioInputTitle": "Det lyder som om din mikrofon laver støj!",
"noisyAudioInputDesc": "Det lyder som om din mikrofon laver støj. Overvej venligst at slå lyden fra eller skifte enhed.",
"openChat": "Åben chat",
"pip": "Benyt Billede-i-billede",
"privateMessage": "Send private message",
"profile": "Rediger profil",
"raiseHand": "Ræk hånden op / Tag hånden ned",
"raiseYourHand": "Ræk hånden op",
"Settings": "Indstillinger",
"sharedvideo": "Del en Youtube video",
"shareRoom": "Invitér deltagere",
"shortcuts": "Vis genveje",
"speakerStats": "Højtaler info",
"startScreenSharing": "Start skærmdeling",
"startSubtitles": "Vis undertekster",
"stopScreenSharing": "Stop skærmdeling",
"stopSubtitles": "Skjul undertekster",
"stopSharedVideo": "Stop YouTube video",
"talkWhileMutedPopup": "Forsøger du at sige noget? Din lyd er slået fra.",
"tileViewToggle": "Slå tileview fra/til",
"toggleCamera": "Slå kamera fra/til",
"videomute": "Start / Stop kamera",
"startvideoblur": "Slå baggrundssløring til",
"stopvideoblur": "Slå baggrundssløring fra"
},
"transcribing": {
"ccButtonTooltip": "Start / Stop undertekster",
"error": "Transkription mislykkedes. Prøv venligst igen.",
"expandLabel": "Transkription er i øjeblikket tændt",
"failedToStart": "Transkription kunne ikke starte",
"labelToolTip": "Mødet transkriberes",
"off": "Transkription stoppet",
"pending": "Forbereder sig til at transkribere mødet ...",
"start": "Begynd at vise undertekster",
"stop": "Stop med at få vist undertekster",
"tr": "TR"
},
"userMedia": {
"androidGrantPermissions": "Vælg <b><i> Tillad</i> </b>, når din browser beder om tilladelser.",
"chromeGrantPermissions": "Vælg <b><i> Tillad</i> </b>, når din browser beder om tilladelser.",
"edgeGrantPermissions": "Vælg <b><i>Ja</i> </b>, når din browser beder om tilladelser.",
"electronGrantPermissions": "Giv tilladelse til at bruge dit kamera og din mikrofon",
"firefoxGrantPermissions": "Vælg <b> <i> Del valgt enhed </i> </b>, når din browser beder om tilladelser.",
"iexplorerGrantPermissions": "Vælg <b><i>OK</i> </b>, når din browser beder om tilladelser.",
"nwjsGrantPermissions": "Giv tilladelse til at bruge dit kamera og din mikrofon",
"operaGrantPermissions": "Vælg <b><i> Tillad</i> </b>, når din browser beder om tilladelser.",
"react-nativeGrantPermissions": "Vælg <b><i> Tillad</i> </b>, når din browser beder om tilladelser.",
"safariGrantPermissions": "Vælg <b><i>OK</i> </b>, når din browser beder om tilladelser."
},
"videoSIPGW": {
"busy": "Vi arbejder på at frigøre ressourcer. Prøv igen om et par minutter.",
"busyTitle": "Mødeservice er i øjeblikket optaget",
"errorAlreadyInvited": "{{displayName}} allerede inviteret",
"errorInvite": "Mødet er endnu ikke etableret. Prøv igen senere.",
"errorInviteFailed": "Vi arbejder på at løse problemet. Prøv igen senere.",
"errorInviteFailedTitle": "Inviterer {{displayName}} mislykkedes",
"errorInviteTitle": "Fejl ved indbydelse til møde",
"pending": "{{displayName}} er blevet inviteret"
},
"videoStatus": {
"audioOnly": "AUD",
"audioOnlyExpanded": "Du er i kun-lyd tilstand. Denne tilstand sparrer båndbredde, men du kan ikke se andres video.",
"callQuality": "Opkaldskvalitet",
"hd": "HD",
"hdTooltip": "Viser HD video",
"highDefinition": "Høj opløsning",
"labelTooiltipNoVideo": "Ingen video",
"labelTooltipAudioOnly": "Tilstand kun-lyd er slået til",
"ld": "LD",
"ldTooltip": "Viser lav opløsnings video",
"lowDefinition": "Lav opløsning",
"onlyAudioAvailable": "Kun-lyd er tilgængelig",
"onlyAudioSupported": "Vi understøtter kun-lyd i denne browser.",
"p2pEnabled": "Peer to Peer slået til",
"p2pVideoQualityDescription": "I peer-to-peer tilstand kan den modtagne opkaldskvalitet kun skiftes mellem høj og kun-lyd. Andre indstillinger vil ikke virke, før peer to peer er afsluttet.",
"recHighDefinitionOnly": "Foretrækker høj opløsning.",
"sd": "SD",
"sdTooltip": "Vider normal opløsnings video",
"standardDefinition": "Standard opløsning"
},
"videothumbnail": {
"domute": "Slå lyd fra",
"domuteOthers": "Slå lyd fra for alle andre",
"flip": "Flip",
"kick": "Afbryd",
"moderator": "Moderator",
"mute": "Medlemmets lyd er slået fra",
"muted": "Lyd slået fra",
"remoteControl": "Fjernbetjening",
"show": "",
"videomute": "Deltageren har stoppet kameraet"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Tryk for at deltage",
"roomname": "Skriv møde navn"
},
"appDescription": "Chat med hele dit team eller inviter alle du kender. {{app}} er en fuldt krypteret, 100% open source videokonference løsning som du kan bruge hele dagen, hver dag, gratis - uden at du behøver en konto. ",
"audioVideoSwitch": {
"audio": "Lyd",
"video": "Video"
},
"calendar": "Kalender",
"connectCalendarButton": "Forbind til din kalender",
"connectCalendarText": "",
"enterRoomTitle": "Start et nyt møde",
"go": "Start",
"join": "Deltag",
"info": "Info",
"privacy": "Privatliv",
"recentList": "Seneste",
"recentListDelete": "Slet",
"recentListEmpty": "Din seneste liste er i øjeblikket tom. Chat med dit team, og du finder alle dine seneste møder her.",
"reducedUIText": "",
"roomname": "Indtast mødenavn",
"roomnameHint": "Indtast mødenavnet, du vil deltage i.",
"sendFeedback": "Giv tilbagemelding",
"betingelser": "Betingelser",
"title": "Skærmbesøg & videomøder"
}
}

View File

@@ -21,7 +21,8 @@
"bluetooth": "Bluetooth",
"headphones": "Kopfhörer",
"phone": "Telefon",
"speaker": "Sprecher"
"speaker": "Lautsprecher",
"none": "Keine Audiogeräte verfügbar"
},
"audioOnly": {
"audioOnly": "Nur Audio"
@@ -40,19 +41,28 @@
"noEvents": "Es sind keine bevorstehenden Veranstaltungen geplant.",
"ongoingMeeting": "Laufendes Meeting",
"permissionButton": "Einstellungen öffnen",
"permissionMessage": "Die App benötigt Zugriff auf den Kalender um die Termine und Konferenzen anzuzeigen.",
"permissionMessage": "Die App benötigt Zugriff auf den Kalender, um die Termine und Konferenzen anzuzeigen.",
"refresh": "Kalender aktualisieren",
"today": "Heute"
},
"\u0005calendarSync": {},
"chat": {
"error": "",
"error": "Fehler: Ihre Nachricht wurde nicht versendet. Grund: {{error}}",
"fieldPlaceHolder": "Geben Sie Ihre Nachricht hier ein",
"messagebox": "Nachricht eingeben",
"messageTo": "Private Nachricht an {{recipient}}",
"noMessagesMessage": "Es gibt noch keine Nachricht in dieser Konferenz. Starten Sie hier eine Unterhaltung!",
"nickname": {
"popover": "Name",
"title": "Geben Sie einen Alias zum Chatten ein"
},
"title": "Chatten"
"privateNotice": "Private Nachricht an {{recipient}}",
"title": "Chatten",
"you": "Sie"
},
"chromeExtensionBanner": {
"installExtensionText": "Installieren Sie die Erweiterung für die Integration von Google Calendar und Office 365",
"buttonText": "Chrome-Erweiterung installieren",
"dontShowAgain": "Hinweis nicht mehr anzeigen"
},
"connectingOverlay": {
"joiningRoom": "Eine Verbindung zu Ihrem Meeting wird hergestellt…"
@@ -67,7 +77,10 @@
"DISCONNECTED": "Getrennt",
"DISCONNECTING": "Verbindung wird getrennt",
"ERROR": "Fehler",
"RECONNECTING": "Es ist ein Netzwerkproblem aufgetreten. Verbinde..."
"FETCH_SESSION_ID": "Sitzungs-ID erhalten...",
"GET_SESSION_ID_ERROR": "Session-ID-Fehler erhalten: {{code}}",
"GOT_SESSION_ID": "Sitzungs-ID erhalten... Beendet",
"LOW_BANDWIDTH": "Video für {{displayName}} wurde ausgeschaltet um Bandbreite einzusparen"
},
"connectionindicator": {
"address": "Adresse:",
@@ -75,6 +88,7 @@
"bitrate": "Bitrate:",
"bridgeCount": "Serverzahl: ",
"connectedTo": "Verbunden mit:",
"e2e_rtt": "E2E RTT:",
"framerate": "Bildwiederholrate:",
"less": "Weniger anzeigen",
"localaddress": "Lokale Adresse:",
@@ -97,7 +111,7 @@
"resolution": "Auflösung:",
"status": "Verbindung:",
"transport": "Protokoll:",
"turn": " (TURN)"
"transport_plural": "Protokolle:"
},
"dateUtils": {
"earlier": "Früher",
@@ -105,9 +119,9 @@
"yesterday": "Gestern"
},
"deepLinking": {
"appNotInstalled": "Sie benötigen die {{app}} App um der Konferenz auf dem Smartphone beizutreten.",
"description": "Nichts passiert? Wir haben versucht die Konferenz in {{app}} zu öffnen. Versuchen Sie es erneut oder treten Sie der Konferenz in {{app}} im Web bei.",
"descriptionWithoutWeb": "",
"appNotInstalled": "Sie benötigen die {{app}}-App, um der Konferenz auf dem Smartphone beizutreten.",
"description": "Nichts passiert? Wir haben versucht, die Konferenz in {{app}} zu öffnen. Versuchen Sie es erneut oder treten Sie der Konferenz in {{app}} im Web bei.",
"descriptionWithoutWeb": "Ist nichts passiert? Wir haben versucht, Ihre Besprechung in der {{{app}}} Desktop-App zu starten.",
"downloadApp": "App herunterladen",
"launchWebButton": "Im Web öffnen",
"openApp": "In der App fortfahren",
@@ -115,6 +129,7 @@
"tryAgainButton": "Erneut mit der nativen Applikation versuchen"
},
"defaultLink": "Bsp.: {{url}}",
"defaultNickname": "Z.B. Jane Pink",
"deviceError": {
"cameraError": "Fehler beim Zugriff auf die Kamera",
"cameraPermission": "Fehler beim Bezug der Kamera-Zugriffsberechtigungen",
@@ -132,7 +147,7 @@
"liveStreaming": "Livestream:"
},
"allow": "Erlauben",
"alreadySharedVideoMsg": "",
"alreadySharedVideoMsg": "Ein anderer Teilnehmer gibt bereits ein Video weiter. Bei dieser Konferenz ist jeweils nur ein geteiltes Video möglich.",
"alreadySharedVideoTitle": "Nur ein geteiltes Video gleichzeitig",
"applicationWindow": "Anwendungsfenster",
"Back": "Zurück",
@@ -158,67 +173,73 @@
"contactSupport": "Support kontaktieren",
"copy": "Kopieren",
"dismiss": "OK",
"displayNameRequired": "",
"displayNameRequired": "Hallo! Wie ist Ihr Name?",
"done": "Fertig",
"enterDisplayName": "",
"enterDisplayName": "Bitte geben Sie hier Ihren Namen ein",
"error": "Fehler",
"externalInstallationMsg": "Die Bildschirmfreigabeerweiterung muss installiert werden.",
"externalInstallationTitle": "Erweiterung erforderlich",
"goToStore": "Zum Store",
"gracefulShutdown": "Der Dienst steht momentan wegen Wartungsarbeiten nicht zur Verfügung. Bitte versuchen Sie es später noch einmal.",
"IamHost": "Ich bin der Organisator",
"incorrectRoomLockPassword": "",
"incorrectRoomLockPassword": "Falsches Passwort",
"incorrectPassword": "Benutzername oder Passwort ungültig",
"inlineInstallationMsg": "Die Bildschirmfreigabeerweiterung muss installiert werden.",
"inlineInstallExtension": "Jetzt installieren",
"internalError": "Oh! Es hat etwas nicht funktioniert. Der folgende Fehler ist aufgetreten: {{error}}",
"internalErrorTitle": "Interner Fehler",
"kickMessage": "",
"kickMessage": "Sie können sich für weitere Einzelheiten an {{participantDisplayName}}} wenden.",
"kickParticipantButton": "Entfernen",
"kickParticipantDialog": "Wollen Sie diesen Teilnehmer wirklich entfernen?",
"kickParticipantTitle": "Teilnehmer stummschalten?",
"kickTitle": "",
"kickTitle": "Autsch! {{participantDisplayName}} hat Sie aus dem Meeting geworfen.",
"liveStreaming": "Live-Streaming",
"liveStreamingDisabledForGuestTooltip": "Gäste können kein Live-Streaming starten.",
"liveStreamingDisabledTooltip": "Starten des Live-Streams deaktiviert.",
"lockMessage": "Die Konferenz konnte nicht gesperrt werden.",
"lockRoom": "",
"lockRoom": "Meeting $t(lockRoomPasswordUppercase) hinzufügen",
"lockTitle": "Sperren fehlgeschlagen",
"logoutQuestion": "Sind Sie sicher, dass Sie sich abmelden und die Konferenz verlassen möchten?",
"logoutTitle": "Abmelden",
"maxUsersLimitReached": "",
"maxUsersLimitReachedTitle": "",
"maxUsersLimitReached": "Das Limit für die maximale Teilnehmerzahl ist erreicht. Die Konferenz ist voll. Bitte wenden Sie sich an den Besitzer des Meetings oder versuchen Sie es später noch einmal!",
"maxUsersLimitReachedTitle": "Maximales Teilnehmerlimit erreicht",
"micConstraintFailedError": "Ihr Mikrofon erfüllt die notwendigen Anforderungen nicht.",
"micNotFoundError": "Mikrofon nicht gefunden.",
"micNotSendingData": "",
"micNotSendingDataTitle": "",
"micNotSendingData": "Gehen Sie zu den Einstellungen Ihres Computers, um die Stummschaltung Ihres Mikrofons aufzuheben und seinen Pegel einzustellen.",
"micNotSendingDataTitle": "Ihr Mikrofon ist durch Ihre Systemeinstellungen stumm geschaltet.",
"micPermissionDeniedError": "Die Berechtigung zur Verwendung des Mikrofons wurde nicht erteilt. Sie können trotzdem an der Konferenz teilnehmen, aber die anderen Teilnehmer können Sie nicht hören. Verwenden Sie die Kamera-Schaltfläche in der Adressleiste um die Berechtigungen zu erteilen.",
"micUnknownError": "Das Mikrofon kann aus einem unbekannten Grund nicht verwendet werden.",
"muteEveryoneElseDialog": "Einmal stummgeschaltet, können Sie deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
"muteEveryoneElseTitle": "Alle ausser {{whom}} stummschaten?",
"muteEveryoneDialog": "Wollen Sie wirklich alle stummschalten? Sie können deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
"muteEveryoneTitle": "Alle stummschalten?",
"muteEveryoneSelf": "sich selbst",
"muteEveryoneStartMuted": "Alle beginnen von jetzt an stummgeschaltet",
"muteParticipantBody": "Sie können die Stummschaltung anderer Teilnehmer nicht aufheben, aber ein Teilnehmer kann seine eigene Stummschaltung jederzeit beenden.",
"muteParticipantButton": "Stummschalten",
"muteParticipantDialog": "Wollen Sie diesen Teilnehmer wirklich stummschalten? Sie können die Stummschaltung nicht wieder aufheben, der Teilnehmer kann dies aber jederzeit selbst tun.",
"muteParticipantTitle": "Teilnehmer stummschalten?",
"Ok": "OK",
"passwordLabel": "",
"passwordLabel": "$t(lockRoomPasswordUppercase)",
"passwordNotSupported": "Setzen eines Konferenz-Passworts ist nicht unterstützt",
"passwordNotSupportedTitle": "",
"passwordRequired": "",
"popupError": "Ihr Browser blockiert Popups von dieser Website. Bitte aktivieren Sie Popups in den Sicherheitseinstellungen des Browsers und versuchen Sie es erneut.",
"popupErrorTitle": "Popup blockiert",
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) nicht unterstützt",
"passwordRequired": "$t(lockRoomPasswordUppercase) erforderlich",
"popupError": "Ihr Browser blockiert Pop-ups von dieser Website. Bitte aktivieren Sie Popups in den Sicherheitseinstellungen des Browsers und versuchen Sie es erneut.",
"popupErrorTitle": "Pop-up blockiert",
"recording": "Aufnahme",
"recordingDisabledForGuestTooltip": "Gäste können kein Aufzeichnungen starten.",
"recordingDisabledForGuestTooltip": "Gäste können keine Aufzeichnungen starten.",
"recordingDisabledTooltip": "Start der Aufzeichnung deaktiviert.",
"rejoinNow": "Jetzt erneut beitreten",
"remoteControlAllowedMessage": "{{user}} hat die Anfrage zur Fernsteuerung angenommen.",
"remoteControlDeniedMessage": "{{user}} hat die Anfrage zur Fernsteuerung verweigert.",
"remoteControlErrorMessage": "Beim Anfordern der Fernsteuerungsberechtigung von {{user}} ist ein Fehler aufgetreten.",
"remoteControlRequestMessage": "Möchten Sie {{user}} erlauben den Computer fernzusteuern?",
"remoteControlShareScreenWarning": "Achtung, wenn Sie die Anfrage genehmigen starten Sie die Bildschirmfreigabe!",
"remoteControlShareScreenWarning": "Achtung, wenn Sie die Anfrage genehmigen, starten Sie die Bildschirmfreigabe!",
"remoteControlStopMessage": "Die Fernsteuerung wurde beendet.",
"remoteControlTitle": "Fernsteuerung",
"Remove": "Entfernen",
"removePassword": "",
"removeSharedVideoMsg": "Sind Sie sicher dass Sie das geteilte Video entfernen möchten?",
"removePassword": "$t(lockRoomPassword) entfernen",
"removeSharedVideoMsg": "Sind Sie sicher, dass Sie das geteilte Video entfernen möchten?",
"removeSharedVideoTitle": "Freigegebenes Video entfernen",
"reservationError": "Fehler im Reservationssystem",
"reservationErrorMsg": "Fehler, Nummer: {{code}}, Nachricht: {{msg}}",
@@ -228,6 +249,10 @@
"screenSharingFirefoxPermissionDeniedError": "Die Bildschirmfreigabe ist leider fehlgeschlagen. Bitte stellen Sie sicher, dass die Berechtigung für die Bildschirmfreigabe im Browser erteilt wurde.",
"screenSharingFirefoxPermissionDeniedTitle": "Die Bildschirmfreigabe konnte nicht gestartet werden.",
"screenSharingPermissionDeniedError": "Oh! Beim Anfordern der Bildschirmfreigabe-Berechtigungen hat etwas nicht funktioniert. Bitte aktualisieren und erneut versuchen.",
"sendPrivateMessage": "Sie haben kürzlich eine private Nachricht erhalten. Hatten Sie die Absicht, darauf privat zu antworten, oder wollen Sie Ihre Nachricht an die Gruppe senden?",
"sendPrivateMessageCancel": "An die Gruppe senden",
"sendPrivateMessageOk": "Privat antworten",
"sendPrivateMessageTitle": "Privat antworten?",
"serviceUnavailable": "Dienst nicht verfügbar",
"sessTerminated": "Konferenz beendet",
"Share": "Teilen",
@@ -241,8 +266,8 @@
"startRemoteControlErrorMessage": "Beim Versuch die Fernsteuerung zu starten ist ein Fehler aufgetreten.",
"stopLiveStreaming": "Live-Streaming stoppen",
"stopRecording": "Aufnahme stoppen",
"stopRecordingWarning": "Sind Sie sicher dass Sie die Aufnahme stoppen möchten?",
"stopStreamingWarning": "Sind Sie sicher dass Sie das Live-Streaming stoppen möchten?",
"stopRecordingWarning": "Sind Sie sicher, dass Sie die Aufnahme stoppen möchten?",
"stopStreamingWarning": "Sind Sie sicher, dass Sie das Live-Streaming stoppen möchten?",
"streamKey": "Name/Schlüssel für den Stream",
"Submit": "OK",
"thankYou": "Danke für die Verwendung von {{appName}}!",
@@ -250,7 +275,7 @@
"tokenAuthFailed": "Sie sind nicht berechtigt dieser Konferenz beizutreten.",
"tokenAuthFailedTitle": "Authentifizierung fehlgeschlagen",
"transcribing": "Wird transkribiert",
"unlockRoom": "",
"unlockRoom": "Meeting $t(lockRoomPassword) entfernen",
"userPassword": "Benutzerpasswort",
"WaitForHostMsg": "Die Konferenz <b>{{room}}</b> wurde noch nicht gestartet. Wenn Sie der Veranstalter sind, authentifizieren Sie sich. Warten Sie andernfalls, bis der Veranstalter erscheint.",
"WaitForHostMsgWOk": "Die Konferenz <b>{{room}}</b> wurde noch nicht gestartet. Wenn Sie der Veranstalter sind, drücken Sie zum Authentifizieren auf OK. Warten Sie andernfalls, bis der Veranstalter erscheint.",
@@ -258,14 +283,14 @@
"Yes": "Ja",
"yourEntireScreen": "Ganzer Bildschirm"
},
"\u0005dialog": {
"accessibilityLabel": {}
},
"dialOut": {
"statusMessage": "ist jetzt {{status}}"
},
"documentSharing": {
"title": "Freigegebenes Dokument"
},
"feedback": {
"average": "Durschnittlich",
"average": "Durchschnittlich",
"bad": "Schlecht",
"detailsLabel": "Sagen Sie uns mehr dazu.",
"good": "Gut",
@@ -282,11 +307,11 @@
},
"info": {
"accessibilityLabel": "Informationen anzeigen",
"addPassword": "",
"cancelPassword": "",
"addPassword": "$t(lockRoomPassword) hinzufügen",
"cancelPassword": "$t(lockRoomPassword) löschen",
"conferenceURL": "Link:",
"country": "Land",
"dialANumber": "Um am Metting teilzunehmen, müssen Sie eine dieser Nummern wählen und dann die PIN eingeben.",
"dialANumber": "Um am Meeting teilzunehmen, müssen Sie eine dieser Nummern wählen und dann die PIN eingeben.",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Entschuldigung, leider wird das Einwählen derzeit nicht unterstützt.",
"dialInNumber": "Einwählen:",
@@ -294,18 +319,18 @@
"dialInTollFree": "Gebührenfrei",
"genericError": "Es ist leider etwas schiefgegangen.",
"inviteLiveStream": "Klicken Sie auf {{url}} um den Livestream dieser Konferenz zu öffnen",
"invitePhone": "",
"invitePhoneAlternatives": "",
"invitePhone": "Wenn Sie stattdessen per Telefon beitreten möchten, tippen Sie hier: {{number}},,{{conferenceID}}#\n",
"invitePhoneAlternatives": "Suche nach einer anderen Einwahlnummer?\nMeetings-Einwahlnummern sehen: {{{url}}\n\n\n\nWenn Sie sich auch über ein Raumtelefon einwählen, nehmen Sie teil, ohne sich mit dem Ton zu verbinden: {{silentUrl}}",
"inviteURLFirstPartGeneral": "Sie wurden zur Teilnahme an einem Meeting eingeladen.",
"inviteURLFirstPartPersonal": "",
"inviteURLSecondPart": "",
"inviteURLFirstPartPersonal": "{{name}} lädt Sie zu einem Meeting ein.\n",
"inviteURLSecondPart": "\nAm Meeting teilnehmen:\n{{url}}\n",
"liveStreamURL": "Livestream:",
"moreNumbers": "Weitere Telefonnummern",
"noNumbers": "Keine Telefonnummern verfügbar.",
"noPassword": "Kein",
"noRoom": "Keine Konferenz für die Einwähl-Informationen angegeben.",
"numbers": "Einwählnummern",
"password": "",
"password": "$t(lockRoomPasswordUppercase):",
"title": "Teilen",
"tooltip": "Freigabe-Link und Einwählinformationen für dieses Meeting",
"label": "Meeting-Informationen"
@@ -331,16 +356,16 @@
"keyboardShortcuts": "Tastenkürzel",
"localRecording": "Lokale Aufzeichnungssteuerelemente ein- oder ausblenden",
"mute": "Stummschaltung aktivieren oder deaktivieren",
"pushToTalk": "Drücken um zu sprechen",
"pushToTalk": "Drücken, um zu sprechen",
"raiseHand": "Hand erheben",
"showSpeakerStats": "Statistiken für Sprecher anzeigen",
"toggleChat": "Chat öffnen oder schliessen",
"toggleChat": "Chat öffnen oder schließen",
"toggleFilmstrip": "Video-Miniaturansichten ein- oder ausblenden",
"toggleScreensharing": "Zwischen Kamera und Bildschirmfreigabe wechseln",
"toggleShortcuts": "Tastenkombinationen ein- oder ausblenden",
"videoMute": "Kamera starten oder stoppen"
"videoMute": "Kamera starten oder stoppen",
"videoQuality": "Anrufqualität verwalten"
},
"\u0005keyboardShortcuts": {},
"liveStreaming": {
"busy": "Es werden Resourcen zum Streamen bereitgestellt. Bitte in ein paar Minuten erneut versuchen.",
"busyTitle": "Alle Streaming-Instanzen sind in Gebrauch",
@@ -355,10 +380,12 @@
"expandedOn": "Das Meeting wird momentan an YouTube gestreamt.",
"expandedPending": "Live-Streaming wird gestartet...",
"failedToStart": "Live-Streaming konnte nicht gestartet werden",
"getStreamKeyManually": "",
"getStreamKeyManually": "Wir waren nicht in der Lage, Live-Streams abzurufen. Versuchen Sie, Ihren Live-Stream-Schlüssel von YouTube zu erhalten.",
"invalidStreamKey": "Der Live-Stream-Schlüssel ist u. U. falsch.",
"off": "Live-Streaming gestoppt",
"offBy": "{{name}} stoppte das Live-Streaming",
"on": "Live-Streaming",
"onBy": "{{name}} startete das Live-Streaming",
"pending": "Live-Stream wird gestartet...",
"serviceName": "Live Streaming-Dienst",
"signedInAs": "Sie sind derzeit angemeldet als:",
@@ -369,7 +396,6 @@
"streamIdHelp": "Was ist das?",
"unavailableTitle": "Live-Streaming nicht verfügbar"
},
"\u0005liveStreaming": {},
"localRecording": {
"clientState": {
"off": "Aus",
@@ -399,7 +425,6 @@
"stop": "Aufnahme stoppen",
"yes": "Ja"
},
"\u0005localRecording": {},
"lockRoomPassword": "Passwort",
"lockRoomPasswordUppercase": "Passwort",
"me": "ich",
@@ -412,30 +437,30 @@
"focusFail": "{{component}} ist im Moment nicht verfügbar - wiederholen in {{ms}} Sekunden",
"grantedTo": "Moderatorenrechte an {{to}} vergeben.",
"invitedOneMember": "{{displayName}} wurde eingeladen",
"invitedThreePlusMembers": "",
"invitedTwoMembers": "",
"kickParticipant": "",
"invitedThreePlusMembers": "{{name}} und {{count}} andere wurden eingeladen",
"invitedTwoMembers": "{{first}} und {{second}} wurden eingeladen",
"kickParticipant": "Sie können sich für weitere Einzelheiten an {{participantDisplayName}}} wenden.",
"me": "Ich",
"moderator": "Moderatorenrechte vergeben",
"muted": "Der Konferenz wurde stumm beigetreten.",
"mutedTitle": "Stummschaltung aktiv!",
"mutedRemotelyTitle": "",
"mutedRemotelyDescription": "",
"passwordRemovedRemotely": "",
"passwordSetRemotely": "",
"mutedRemotelyTitle": "Sie wurden von {{participantDisplayName}} stummgeschaltet!",
"mutedRemotelyDescription": "Sie können jederzeit die Stummschaltung aufheben, wenn Sie bereit sind zu sprechen. Wenn Sie fertig sind, können sich wieder stummschalten, um Geräusche vom Meeting fernzuhalten.",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) von einem anderen Teilnehmer entfernt",
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) von einem anderen Teilnehmer gesetzt",
"raisedHand": "{{name}} möchte sprechen.",
"somebody": "Jemand",
"startSilentTitle": "",
"startSilentDescription": "",
"startSilentTitle": "Sie sind ohne Audioausgabe beigetreten!",
"startSilentDescription": "Treten Sie dem Meeting noch einma bei, um Ihr Audio zu aktivieren",
"suboptimalExperienceDescription": "Tut uns leid, aber die Konferenz wird mit {{appName}} kein grossartiges Erlebnis. Wir versuchen immer die Situation zu verbessern, bis dahin empfehlen wir aber die Verwendung einer der <a href=\"static/recommendedBrowsers.html\" target=\"_blank\">vollständig unterstützen Browser</a>.",
"suboptimalExperienceTitle": "Browserwarnung",
"unmute": "",
"unmute": "Stummschaltung aufheben",
"newDeviceCameraTitle": "Neue Kamera erkannt",
"newDeviceAudioTitle": "Neues Audiogerät erkannt",
"newDeviceAction": "Verwenden"
},
"passwordSetRemotely": "von einem anderen Teilnehmer gesetzt",
"passwordDigitsOnly": "",
"passwordDigitsOnly": "Bis zu {{number}} Ziffern",
"poweredby": "Betrieben von",
"presenceStatus": {
"busy": "Beschäftigt",
@@ -451,13 +476,13 @@
"rejected": "Abgelehnt",
"ringing": "Es klingelt…"
},
"\u0005presenceStatus": {},
"profile": {
"setDisplayNameLabel": "Anzeigename festlegen",
"setEmailInput": "E-Mail eingeben",
"setEmailLabel": "E-Mail Adresse für Gravatar",
"title": "Profil"
},
"raisedHand": "Ich möchte sprechen",
"recording": {
"authDropboxText": "In Dropbox hochladen",
"availableSpace": "Verfügbarer Speicherplatz: {{spaceLeft}} MB (ca. {{duration}} Minuten Aufzeichnung)",
@@ -473,7 +498,9 @@
"live": "LIVE",
"loggedIn": "Als {{userName}} angemeldet",
"off": "Aufnahme gestoppt",
"offBy": "{{name}} stoppte die Aufnahme",
"on": "Aufnahme",
"onBy": "{{name}} startete die Aufnahme",
"pending": "Aufzeichnung des Meetings wird vorbereitet…",
"rec": "AUFZ",
"serviceDescription": "Ihre Aufzeichnung wird vom Aufzeichnungsdienst gespeichert",
@@ -509,27 +536,28 @@
"startVideoMuted": "Alle Teilnehmer treten ohne Video bei",
"title": "Einstellungen"
},
"\u0005settings": {
"calendar": {}
},
"settingsView": {
"advanced": "Erweitert",
"alertOk": "OK",
"alertTitle": "Warnung",
"alertURLText": "Die angegebene Server URL ist ungültig",
"buildInfoSection": "Build-Informationen",
"conferenceSection": "Konferenz",
"disableCallIntegration": "Native Anrufintegration deaktivieren",
"disableP2P": "Ende-zu-Ende-Modus deaktivieren",
"displayName": "Anzeigename",
"email": "E-Mail",
"header": "Einstellungen",
"profileSection": "Profil",
"serverURL": "Server URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startWithAudioMuted": "Stumm beitreten",
"startWithVideoMuted": "Ohne Video beitreten",
"version": "Version"
},
"share": {
"dialInfoText": "",
"mainText": ""
"dialInfoText": "\n\n=====\n\nWollen Sie sich nur auf Ihrem Telefon einwählen?\n\n{{{defaultDialInNumber}}}Klicken Sie auf diesen Link, um die eingewählten Telefonnummern für dieses Meeting zu sehen\n{{dialInfoPageUrl}}",
"mainText": "Klicken Sie auf den folgenden Link, um dem Meeting beizutreten:\n{{roomUrl}}"
},
"speaker": "Sprecher",
"speakerStats": {
@@ -547,7 +575,7 @@
"suspendedoverlay": {
"rejoinKeyTitle": "Erneut teilnehmen",
"text": "<i>Erneut teilnehmen</i> Schaltfläche betätigen um erneut zu verbinden.",
"title": "Die Konferenz wurde unterbrochen weil der Standbymodus aktiviert wurde."
"title": "Die Konferenz wurde unterbrochen, weil der Standbymodus aktiviert wurde."
},
"toolbar": {
"accessibilityLabel": {
@@ -557,17 +585,22 @@
"cc": "Untertitel ein-/ausschalten",
"chat": "Chatfenster ein-/ausblenden",
"document": "Geteiltes Dokument schliessen",
"feedback": "Feedback hinterlasen",
"download": "Unsere Apps herunterladen",
"feedback": "Feedback hinterlassen",
"fullScreen": "Vollbildschirm ein-/ausblenden",
"hangup": "Anruf beenden",
"help": "Hilfe",
"invite": "Teilnehmer einladen",
"kick": "Teilnehmer entfernen",
"localRecording": "Lokale Aufzeichnungssteuerelemente ein-/ausschalten",
"lockRoom": "Meeting-Passwort ein-/auschalten",
"moreActions": "Menü „Weitere Aktionen“ ein-/ausschalten",
"moreActionsMenu": "Menü „Weitere Aktionen“",
"moreOptions": "Menü „Weitere Optionen“",
"mute": "„Audio stummschalten“ ein-/ausschalten",
"muteEveryone": "Alle stummschalten",
"pip": "Bild-in-Bild-Modus ein-/ausschalten",
"privateMessage": "Private Nachricht senden",
"profile": "Profil bearbeiten",
"raiseHand": "„Melden“ ein-/ausschalten",
"recording": "Aufzeichnung ein-/ausschalten",
@@ -577,12 +610,12 @@
"shareRoom": "Person einladen",
"shareYourScreen": "Bildschirmfreigabe ein-/ausschalten",
"shortcuts": "Tastenkombinationen ein-/ausblenden",
"show": "",
"show": "Im Vordergrund anzeigen",
"speakerStats": "Sprecherstatistik ein-/ausblenden",
"tileView": "Kachelansicht ein-/ausschalten",
"toggleCamera": "Kamera ein-/ausschalten",
"toggleCamera": "Kamera wechseln",
"videomute": "„Video stummschalten“ ein-/ausschalten",
"videoblur": ""
"videoblur": "Video-Unschärfe ein-/ausschalten"
},
"addPeople": "Teilnehmer zur Konferenz hinzufügen",
"audioOnlyOff": "Modus „Nur Audio“ deaktivieren",
@@ -594,20 +627,32 @@
"closeChat": "Chat schließen",
"documentClose": "Geteiltes Dokument schliessen",
"documentOpen": "Geteiltes Dokument öffnen",
"download": "Unsere Apps herunterladen",
"enterFullScreen": "Vollbildmodus",
"enterTileView": "Kachelansicht einschalten",
"exitFullScreen": "Vollbildmodus verlassen",
"exitTileView": "Kachelansicht ausschalten",
"feedback": "Feedback hinterlasen",
"feedback": "Feedback hinterlassen",
"hangup": "Verlassen",
"help": "Hilfe",
"invite": "Teilnehmer einladen",
"login": "Anmelden",
"logout": "Abmelden",
"lowerYourHand": "Hand senken",
"moreActions": "Weitere Einstellungen",
"moreOptions": "Weitere Optionen",
"mute": "Stummschaltung aktivieren / deaktivieren",
"muteEveryone": "Alle stummschalten",
"noAudioSignalTitle": "Es kommt kein Input von Ihrem Mikrofon!",
"noAudioSignalDesc": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stumm geschaltet haben, sollten Sie einen Wechsel des Geräts in Erwägung ziehen.",
"noAudioSignalDescSuggestion": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stummgeschaltet haben, sollten Sie einen Wechsel auf das vorgeschlagene Gerät in Erwägung ziehen.",
"noAudioSignalDialInDesc": "Sie können sich auch über die Einwahlnummer einwählen:",
"noAudioSignalDialInLinkDesc" : "Einwahlnummern:",
"noisyAudioInputTitle": "Ihr Mikrofon scheint lärmintensiv zu sein!",
"noisyAudioInputDesc": "Es klingt, als ob Ihr Mikrofon Geräusche macht. Bitte überlegen Sie, ob Sie das Gerät stummschalten oder austauschen wollen.",
"openChat": "Chat öffnen",
"pip": "Bild-in-Bild-Modus einschalten",
"privateMessage": "Private Nachricht senden",
"profile": "Profil bearbeiten",
"raiseHand": "Hand erheben",
"raiseYourHand": "Melden",
@@ -620,16 +665,13 @@
"startSubtitles": "Untertitel einschalten",
"stopScreenSharing": "Bildschirmfreigabe stoppen",
"stopSubtitles": "Untertitel ausschalten",
"stopSharedVideo": "YouTube Video stoppen",
"stopSharedVideo": "YouTube-Video stoppen",
"talkWhileMutedPopup": "Versuchen sie zu sprechen? Ihr Mikrofon ist stummgeschaltet.",
"tileViewToggle": "Kachelansicht ein-/ausschalten",
"toggleCamera": "Kamera ein-/ausschalten",
"toggleCamera": "Kamera wechseln",
"videomute": "Kamera starten / stoppen",
"startvideoblur": "",
"stopvideoblur": ""
},
"\u0005toolbar": {
"accessibilityLabel": {}
"startvideoblur": "Hintergrundunschärfe aktivieren",
"stopvideoblur": "Hintergrundunschärfe deaktivieren"
},
"transcribing": {
"ccButtonTooltip": "Untertitel ein-/ausschalten",
@@ -643,18 +685,17 @@
"stop": "Anzeige der Untertitel stoppen",
"tr": "TR"
},
"\u0005transcribing": {},
"userMedia": {
"androidGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b> wenn der Browser um Berechtigungen bittet.",
"chromeGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b> wenn der Browser um Berechtigungen bittet.",
"edgeGrantPermissions": "Wählen Sie <b><i>Ja</i></b> wenn der Browser um Berechtigungen bittet.",
"androidGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b>, wenn der Browser um Berechtigungen bittet.",
"chromeGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b>, wenn der Browser um Berechtigungen bittet.",
"edgeGrantPermissions": "Wählen Sie <b><i>Ja</i></b>, wenn der Browser um Berechtigungen bittet.",
"electronGrantPermissions": "Bitte Berechtigungen zur Verwendung der Kamera und des Mikrofons erteilen",
"firefoxGrantPermissions": "Wählen Sie <b><i>Markiertes Gerät teilen</i></b> wenn der Browser um Berechtigungen bittet.",
"iexplorerGrantPermissions": "Wählen Sie <b><i>OK</i></b> wenn der Browser um Berechtigungen bittet.",
"firefoxGrantPermissions": "Wählen Sie <b><i>Markiertes Gerät teilen</i></b>, wenn der Browser um Berechtigungen bittet.",
"iexplorerGrantPermissions": "Wählen Sie <b><i>OK</i></b>, wenn der Browser um Berechtigungen bittet.",
"nwjsGrantPermissions": "Bitte Berechtigungen zur Verwendung der Kamera und des Mikrofons erteilen",
"operaGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b> wenn der Browser um Berechtigungen bittet.",
"react-nativeGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b> wenn der Browser um Berechtigungen bittet.",
"safariGrantPermissions": "Wählen Sie <b><i>OK</i></b> wenn der Browser um Berechtigungen bittet."
"operaGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b>, wenn der Browser um Berechtigungen bittet.",
"react-nativeGrantPermissions": "Wählen Sie <b><i>Erlauben</i></b>, wenn der Browser um Berechtigungen bittet.",
"safariGrantPermissions": "Wählen Sie <b><i>OK</i></b>, wenn der Browser um Berechtigungen bittet."
},
"videoSIPGW": {
"busy": "Es stehen keine freien Ressourcen zur Verfügung. Bitte versuchen Sie es später noch einmal.",
@@ -669,38 +710,42 @@
"videoStatus": {
"audioOnly": "AUD",
"audioOnlyExpanded": "Sie befinden sich im Modus „Nur Audio“. Dieser Modus benötigt weniger Bandbreite, Sie sehen jedoch nicht die Videos der anderen.",
"callQuality": "",
"callQuality": "Video-Qualität",
"hd": "HD",
"hdTooltip": "Video wird in hoher Auflösung angezeigt",
"highDefinition": "Hohe Auflösung",
"labelTooiltipNoVideo": "Kein Video",
"labelTooltipAudioOnly": "Nur-Audio Modus aktiv",
"ld": "LD",
"ldTooltip": "Video wird in niedriger Auflösung angezeigt",
"lowDefinition": "Niedrige Auflösung",
"onlyAudioAvailable": "Nur Ton",
"onlyAudioSupported": "In diesem Browser wird nur Audio unterstützt.",
"p2pEnabled": "Ende-zu-Ende aktiviert",
"p2pVideoQualityDescription": "",
"p2pVideoQualityDescription": "Im Ende-zu-Ende-Modus kann die empfangene Videoqualität nur zwischen hoch und Nur-Audio umgeschaltet werden. Andere Einstellungen werden erst beim Verlassen des Ende-zu-Ende-Modus berücksichtigt.",
"recHighDefinitionOnly": "Hohe Qualität wird bevorzugt.",
"sd": "SD",
"sdTooltip": "Video wird in Standardauflösung angezeigt",
"standardDefinition": "Standardauflösung"
},
"videothumbnail": {
"domute": "Stummschalten",
"domuteOthers": "Alle anderen stummschalten",
"flip": "Spiegeln",
"kick": "Hinauswerfen",
"moderator": "Moderator",
"mute": "Teilnehmer ist stumm geschaltet",
"muted": "Stummgeschaltet",
"remoteControl": "Fernsteuerung",
"show": "",
"videomute": ""
"show": "Im Vordergrund anzeigen",
"videomute": "Teilnehmer hat die Kamera angehalten"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Zum Teilnehmen tippen",
"roomname": "Konferenzname eingeben"
},
"appDescription": "Auf geht's! Beginne eine Videokonferenz mit dem ganzen Team. Oder eigentlich, lade alle ein die du kennst. {{app}} ist eine vollständig verschlüsselte, aus 100% Open-Source-Software bestehende Videokonferenzlösung die du den ganzen Tag kostenlos verwenden kannst — ohne Registrierung.",
"appDescription": "Auf geht's! Beginne eine Videokonferenz mit dem ganzen Team. Oder besser noch, lade alle ein, die du kennst. {{app}} ist eine vollständig verschlüsselte, aus 100% Open-Source-Software bestehende Videokonferenzlösung, die du den ganzen Tag kostenlos verwenden kannst — ohne Registrierung.",
"audioVideoSwitch": {
"audio": "Sprache",
"video": "Video"
@@ -709,18 +754,20 @@
"connectCalendarButton": "Kalender verbinden",
"connectCalendarText": "Verbinden Sie Ihren Kalender, um all Ihre Meetings in {{app}} anzuzeigen. Fügen Sie zudem {{provider}}-Meetings in Ihren Kalender ein und starten Sie sie mit nur einem Klick.",
"enterRoomTitle": "Neues Meeting starten",
"roomNameAllowedChars": "Der Meeting-Name sollte keines der folgenden Zeichen enthalten: ?, &, :, ', \", %, #.",
"go": "Los",
"goSmall": "Los",
"join": "Beitreten",
"info": "Informationen",
"privacy": "Privatsphäre",
"recentList": "Letzte\"",
"recentList": "Letzte",
"recentListDelete": "Löschen",
"recentListEmpty": "Die Liste „Letzte“ ist momentan leer. Chatten Sie mit Ihrem Team. Sie finden all Ihre letzten Meetings hier.",
"reducedUIText": "",
"reducedUIText": "Willkommen bei {{app}}!",
"roomname": "Konferenzname eingeben",
"roomnameHint": "Name oder URL der Konferenz der Sie beitreten möchten. Sie können einen Namen erfinden, er muss nur den anderen Teilnehmern übermittelt werden damit sie der gleichen Konferenz beitreten.",
"roomnameHint": "Name oder URL der Konferenz, der Sie beitreten möchten. Sie können einen Namen erfinden, er muss nur den anderen Teilnehmern übermittelt werden, damit sie der gleichen Konferenz beitreten.",
"sendFeedback": "Senden Sie uns Ihr Feedback",
"terms": "Bedingungen",
"title": "Sichere, mit umfassenden Funktionen ausgestattete und vollkommen kostenlose Videokonferenzen"
}
}
}

View File

@@ -728,7 +728,7 @@
"join": "Touchez pour rejoindre",
"roomname": "Saisissez un nom de salle"
},
"appDescription": "Allez-y, chat vidéo avec toute l'équipe. En fait, invitez tout le monde que vous connaissez. {{app}} est une solution de visioconférence entièrement cryptée et 100% open source que vous pouvez utiliser toute la journée, tous les jours, gratuitement— aucun compte requis.",
"appDescription": "Allez-y, chat vidéo avec toute l'équipe. En fait, invitez tout le monde que vous connaissez. {{app}} est une solution de visioconférence entièrement chiffrée et 100% open source que vous pouvez utiliser toute la journée, tous les jours, gratuitement— aucun compte requis.",
"audioVideoSwitch": {
"audio": "Voix",
"video": "Vidéo"
@@ -753,4 +753,4 @@
"terms": "Termes",
"title": "Vidéoconférence Sécurisée, entièrement en vedette et gratuite"
}
}
}

View File

@@ -2,7 +2,7 @@
"addPeople": {
"add": "Invita",
"countryNotSupported": "Non supportiamo ancora questa destinazione.",
"countryReminder": "Stai chiamando fuori dagli Stati Uniti? Assicurati di iniziare inserendo il codice paese!",
"countryReminder": "Stai chiamando fuori dagli Stati Uniti? Assicurati d'inserire il prefisso internazionale!",
"disabled": "Non puoi invitare persone.",
"failedToAdd": "",
"footerText": "La chiamata dall'esterno è disabilitata.",
@@ -21,7 +21,7 @@
"bluetooth": "Bluetooth",
"headphones": "Cuffie",
"phone": "Telefono",
"speaker": "Relatore"
"speaker": "Vivavoce"
},
"audioOnly": {
"audioOnly": "Solo audio"
@@ -131,7 +131,7 @@
"liveStreaming": "Diretta"
},
"allow": "Consenti",
"alreadySharedVideoMsg": "",
"alreadySharedVideoMsg": "Un altro utente sta condividendo un video. Questa conferenza permette di condividere un solo video alla volta.",
"alreadySharedVideoTitle": "È permesso un solo video alla volta",
"applicationWindow": "Finestra applicazione",
"Back": "Indietro",
@@ -157,9 +157,9 @@
"contactSupport": "Contatta il supporto",
"copy": "Copia",
"dismiss": "Scarta",
"displayNameRequired": "",
"displayNameRequired": "Tutti devono avere un nome",
"done": "Fatto",
"enterDisplayName": "",
"enterDisplayName": "Inserisci il nome da visualizzare",
"error": "Errore",
"externalInstallationMsg": "Devi installare la nostra estensione per la condivisione desktop.",
"externalInstallationTitle": "Richiesta estensione",
@@ -172,31 +172,31 @@
"inlineInstallExtension": "Installa adesso",
"internalError": "Ops! Qualcosa è andato storto. Questo è l'errore: {{error}}",
"internalErrorTitle": "Errore interno",
"kickMessage": "",
"kickMessage": "Acc! Sei stato espulso dal meeting!",
"kickParticipantButton": "Espelli",
"kickParticipantDialog": "Espellere questo partecipante?",
"kickParticipantTitle": "",
"kickTitle": "",
"kickParticipantDialog": "Sei sicuro di voler espellere questo partecipante?",
"kickParticipantTitle": "Espellere questi partecipante?",
"kickTitle": "Espulso dal meeting",
"liveStreaming": "Live Streaming",
"liveStreamingDisabledForGuestTooltip": "Gli ospiti non possono avviare una diretta.",
"liveStreamingDisabledTooltip": "Trasmissioni in diretta disabilitate.",
"lockMessage": "Impossibile bloccare la conferenza.",
"lockRoom": "",
"lockRoom": "Aggiungi una password al meeting",
"lockTitle": "Blocco fallito",
"logoutQuestion": "Vuoi disconnetterti e interrompere la conferenza ?",
"logoutTitle": "Logout",
"maxUsersLimitReached": "",
"maxUsersLimitReachedTitle": "",
"maxUsersLimitReached": "E' stato raggiunto il numero massimo di partecipanti. La conferenza è al completo. Contatta l'organizzatore, o riprova più tardi!",
"maxUsersLimitReachedTitle": "Raggiunto limite partecipanti",
"micConstraintFailedError": "Il tuo microfono non soddisfa alcuni dei requisiti richiesti.",
"micNotFoundError": "Microfono non trovato.",
"micNotSendingData": "",
"micNotSendingDataTitle": "",
"micNotSendingData": "Non riusciamo a ricevere suoni dal microfono scelto. Prova a selezionare nelle impostazioni un microfono diverso, o a riavvare l'applicazione.",
"micNotSendingDataTitle": "Impossibile accedere al microfono",
"micPermissionDeniedError": "Non hai concesso il permesso di usare il microfono. Puoi comunque partecipare alla conferenza ma gli altri non potranno sentirti. Usa il bottone a forma di telecamera nella barra degli indirizzi per cambiare impostazioni.",
"micUnknownError": "Impossibile usare il microfono per un motivo sconosciuto.",
"muteParticipantBody": "Tu non sarai in grado di riattivare il loro audio, ma loro potranno riattivarlo in qualsiasi momento.",
"muteParticipantButton": "Disattiva audio",
"muteParticipantDialog": "",
"muteParticipantTitle": "",
"muteParticipantButton": "Silenzia partecipante",
"muteParticipantDialog": "Sei sicuro di voler disattivare l'audio di questo partecipante? Saranno loro a doversi riattivare l'audio, per parlare.",
"muteParticipantTitle": "Silenzio questo partecipante?",
"Ok": "Ok",
"passwordLabel": "",
"passwordNotSupported": "Le password per le videoconferenze non sono supportate.",
@@ -216,7 +216,7 @@
"remoteControlStopMessage": "Sessione di controllo remoto terminata!",
"remoteControlTitle": "Connessione desktop remoto",
"Remove": "Rimuovi",
"removePassword": "",
"removePassword": "Togli la password",
"removeSharedVideoMsg": "Sei sicuro di voler rimuovere il tuo video condiviso?",
"removeSharedVideoTitle": "Rimuovi video condiviso",
"reservationError": "Errore di sistema in prenotazione",
@@ -249,10 +249,10 @@
"tokenAuthFailed": "Ci dispiace ma non sei autorizzato a partecipare a questa chiamata.",
"tokenAuthFailedTitle": "Autenticazione fallita",
"transcribing": "Trascrizione",
"unlockRoom": "",
"unlockRoom": "Togli la password al meeting",
"userPassword": "password utente",
"WaitForHostMsg": "",
"WaitForHostMsgWOk": "",
"WaitForHostMsg": "La conferenza <b>{{room}}</b> non è ancora cominciata. Se sei l'organizzatore, per favore autenticati. Altrimenti, aspetta l'arrivo dell'organizzatore.",
"WaitForHostMsgWOk": "La conferenza <b>{{room}}</b> non è ancora cominciata. Se sei l'organizzatore, allora premi OK per autenticarti. Altrimenti, aspetta l'arrivo dell'organizzatore.",
"WaitingForHost": "In attesa dell'organizzatore ...",
"Yes": "Sì",
"yourEntireScreen": "Schermo intero"
@@ -270,41 +270,41 @@
"veryGood": "Molto Buona"
},
"incomingCall": {
"answer": "Risposta",
"answer": "Rispondi",
"audioCallTitle": "Chiamata in arrivo",
"decline": "Scarta",
"productLabel": "da ANDI Conference",
"productLabel": "da Jitsi Meet",
"videoCallTitle": "Videochiamata in arrivo"
},
"info": {
"accessibilityLabel": "Mostra informazioni",
"addPassword": "",
"cancelPassword": "",
"addPassword": "Aggiungi password",
"cancelPassword": "Togli password",
"conferenceURL": "Collegamento:",
"country": "Paese",
"dialANumber": "",
"dialANumber": "Per collegarti telefonicamente al meeting, chiama uno di questi numeri e metti il pin.",
"dialInConferenceID": "PIN:",
"dialInNotSupported": "Spiacenti, la chiamata per partecipare attualmente non è supportata",
"dialInNotSupported": "Spiacenti, la partecipazionne solo telefonica non è supportata attualmente",
"dialInNumber": "Componi:",
"dialInSummaryError": "",
"dialInTollFree": "",
"dialInSummaryError": "Errore nella ricerca dei numeri telefonici. Riprova più tardi.",
"dialInTollFree": "Numero verde",
"genericError": "Ops, qualcosa è andato storto.",
"inviteLiveStream": "Per visualizzare la trasmissione in diretta di questo meeting, clicca su questo link: {{url}}",
"invitePhone": "",
"inviteLiveStream": "Per vedere la diretta di questo meeting, clicca su questo link: {{url}}",
"invitePhone": "Per seguire solo telefonicamente, clicca: {{number}},,{{conferenceID}}#",
"invitePhoneAlternatives": "",
"inviteURLFirstPartGeneral": "",
"inviteURLFirstPartPersonal": "",
"inviteURLSecondPart": "",
"inviteURLFirstPartGeneral": "Invito a connettersi ad una conferenza.",
"inviteURLFirstPartPersonal": "{{name}} ti sta invitando ad un meeting.\n",
"inviteURLSecondPart": "\nPartecipa al meeting:\n{{url}}\n",
"liveStreamURL": "Trasmissione in diretta:",
"moreNumbers": "Più numeri",
"noNumbers": "Nessun numero da chiamare.",
"noPassword": "Nessuno",
"noPassword": "Nessuna",
"noRoom": "Non è stata specificata nessuna stanza da chiamare.",
"numbers": "Numeri da chiamare",
"password": "",
"password": "Password",
"title": "Condividi",
"tooltip": "Condividi collegamento e informazioni di chiamata per questa conferenza",
"label": ""
"tooltip": "Invia il collegamento e i numeri telefonici di questa conferenza",
"label": "Informazioni meeting"
},
"inviteDialog": {
"alertText": "",
@@ -328,13 +328,13 @@
"localRecording": "Mostra o nascondi i controlli per la registrazione",
"mute": "Attiva o disattiva il microfono",
"pushToTalk": "Premi per parlare",
"raiseHand": "Mostra / Nascondi i video",
"showSpeakerStats": "Mostra statistiche conversanti",
"raiseHand": "Alza o abbassa la mano",
"showSpeakerStats": "Mostra statistiche",
"toggleChat": "Apri o chiudi la chat",
"toggleFilmstrip": "Mostra o nascondi anteprime video",
"toggleScreensharing": "Cambia modalità tra videocamera e condivisione schermo",
"toggleShortcuts": "Mostra o nascondi le scorciatoie",
"videoMute": "Attiva / disattiva videocamera"
"videoMute": "Accendo o spegni la videocamera"
},
"liveStreaming": {
"busy": "Stiamo cercando di liberare risorse per lo streaming. Riprova tra qualche minuto.",
@@ -349,11 +349,11 @@
"expandedOff": "La diretta &egrave; stata interrotta",
"expandedOn": "La conferenza &egrave; attualmente in diretta su YouTube.",
"expandedPending": "La diretta &egrave; in fase di avvio...",
"failedToStart": "Avvio live streaming fallito",
"getStreamKeyManually": "",
"invalidStreamKey": "",
"off": "Il live streaming si è interrotto",
"on": "Live Streaming",
"failedToStart": "Avvio trasmissione in diretta fallito",
"getStreamKeyManually": "Non siamo stati in grado di trovare nessuna trasmissione dal vivo. Prova ad ottenere una chiave stream da Youtube",
"invalidStreamKey": "La chiave stream potrebbe non essere corretta.",
"off": "La diretta si è interrotta",
"on": "Trasmissione in diretta",
"pending": "Avvio live stream...",
"serviceName": "Servizio live streaming",
"signedInAs": "Sei attualmente collegato come:",
@@ -397,38 +397,38 @@
"lockRoomPasswordUppercase": "Password",
"me": "io",
"notify": {
"connectedOneMember": "",
"connectedThreePlusMembers": "",
"connectedTwoMembers": "",
"connectedOneMember": "{{name}} si è connesso",
"connectedThreePlusMembers": "{{name}} e altri {{count}} si sono connessi",
"connectedTwoMembers": "{{first}} e {{second}} si sono connessi",
"disconnected": "disconnesso",
"focus": "Focus su conferenza",
"focusFail": "{{component}} non disponibile - riprova in {{ms}} sec",
"grantedTo": "Permessi di moderatore garantiti a {{to}}!",
"invitedOneMember": "{{displayName}} è stato invitato",
"invitedThreePlusMembers": "",
"invitedTwoMembers": "",
"kickParticipant": "",
"me": "io",
"invitedThreePlusMembers": "Hai invitato {{name}} e altri {{count}}",
"invitedTwoMembers": "Hai invitato {{first}} e {{second}}",
"kickParticipant": "{{kicked}} è stato espulso da {{kicker}}",
"me": "Io",
"moderator": "Impostati i permessi di moderatore!",
"muted": "Hai iniziato la conversazione con l'audio disattivato.",
"mutedTitle": "Hai l'audio disattivato!",
"mutedRemotelyTitle": "",
"mutedRemotelyTitle": "Ti è stato disattivato l'audio da {{participantDisplayName}}!",
"mutedRemotelyDescription": "",
"passwordRemovedRemotely": "",
"passwordSetRemotely": "",
"raisedHand": "",
"raisedHand": "{{name}} vorrebbe intervenire.",
"somebody": "Qualcuno",
"startSilentTitle": "",
"startSilentDescription": "",
"suboptimalExperienceDescription": "Ehm... temiamo che la tua esperienza con {{appName}} non sarà granché su questo browser. Stiamo cercando di migliorare la situazione ma, per il momento, prova ad utilizzare uno di questi <a href='static/recommendedBrowsers.html' target='_blank'>browser supportati</a>.",
"suboptimalExperienceTitle": "Problemi con il browser",
"unmute": "",
"newDeviceCameraTitle": "",
"newDeviceAudioTitle": "",
"newDeviceAction": ""
"newDeviceCameraTitle": "Trovata nuova videocamera",
"newDeviceAudioTitle": "Trovata nuova origine audio",
"newDeviceAction": "Usala"
},
"passwordSetRemotely": "",
"passwordDigitsOnly": "",
"passwordSetRemotely": "definita da altro utente",
"passwordDigitsOnly": "Fino a {{number}} cifre",
"poweredby": "powered by",
"presenceStatus": {
"busy": "Occupato",
@@ -498,26 +498,26 @@
"selectCamera": "Videocamera",
"selectMic": "Microfono",
"startAudioMuted": "Tutti cominciano con il microfono disattivato",
"startVideoMuted": "Tutti cominciano nascosti",
"startVideoMuted": "Tutti cominciano con il video video",
"title": "Impostazioni"
},
"settingsView": {
"alertOk": "OK",
"alertTitle": "Attenzione",
"alertURLText": "L'URL del server inserito non è valido",
"buildInfoSection": "",
"buildInfoSection": "Versione",
"conferenceSection": "Conferenza",
"displayName": "Nome visualizzato",
"email": "Email",
"header": "Impostazioni",
"profileSection": "Profilo",
"serverURL": "URL del server",
"startWithAudioMuted": "Inizia con l'audio mutato",
"startWithVideoMuted": "Avvia con video mutato",
"version": ""
"startWithAudioMuted": "Inizia con l'audio disattivato",
"startWithVideoMuted": "Avvia con il video disattivato",
"version": "Versione"
},
"share": {
"dialInfoText": "",
"dialInfoText": "\n\n=====\n\nVuoi solo ascoltare la conferenza da un telefono?\n\n{{defaultDialInNumber}}Clicca questo link per vedere i numeri telefonici di questo meeting\n{{dialInfoPageUrl}}",
"mainText": "Clicca sul link seguente per partecipare alla conferenza:\n{{roomUrl}}"
},
"speaker": "Relatore",
@@ -526,8 +526,8 @@
"minutes": "{{count}}m",
"name": "Nome",
"seconds": "{{count}}s",
"speakerStats": "Statistiche del parlante",
"speakerTime": "Tempo del conversante"
"speakerStats": "Statistiche del relatore",
"speakerTime": "Tempo del relatore"
},
"startupoverlay": {
"policyText": " ",
@@ -550,75 +550,75 @@
"fullScreen": "Attiva/disattiva schermo intero",
"hangup": "Lascia la conferenza",
"invite": "Invita persone",
"kick": "",
"kick": "Espelli partecipante",
"localRecording": "Abilita controlli di registrazione locale",
"lockRoom": "",
"moreActions": "Attiva/disattiva Menu avanzato",
"lockRoom": "Attiva o disattiva password",
"moreActions": "Attiva o disattiva menu avanzato",
"moreActionsMenu": "Menu avanzato",
"mute": "Attiva/disattiva audio muto",
"mute": "Attiva/disattiva audio",
"pip": "Attiva/disattiva immagine nellimmagine",
"profile": "Modifica profilo",
"raiseHand": "Attiva/disattiva alzata di mano",
"recording": "Attiva/disattiva registrazione",
"remoteMute": "",
"remoteMute": "Disattiva audio partecipante",
"Settings": "Attiva/disattiva impostazioni",
"sharedvideo": "Attiva/disattiva condivisione YouTube",
"shareRoom": "Invita partecipante",
"shareRoom": "Invita qualcuno",
"shareYourScreen": "Attiva/disattiva condivisione schermo",
"shortcuts": "Attiva/disattiva scorciatoie",
"show": "",
"speakerStats": "Attiva/disattiva statistiche relatore",
"tileView": "Attiva/disattiva visualizzazione griglia",
"toggleCamera": "Attiva/disattiva webcam",
"videomute": "Attiva/disattiva silenziamento video",
"videoblur": ""
"tileView": "Attiva/disattiva visualizzazione a tessere",
"toggleCamera": "Cambia videocamera",
"videomute": "Attiva/disattiva videocamera",
"videoblur": "Attiva/disattiva offuscamento video"
},
"addPeople": "Aggiungi persone alla chiamata",
"audioOnlyOff": "Disattiva modalità solo audio",
"audioOnlyOn": "Disattiva modalità solo audio",
"audioOnlyOn": "Attiva modalità solo audio",
"audioRoute": "Seleziona la periferica audio",
"authenticate": "Autenticazione",
"callQuality": "Gestisci qualità della chiamata",
"chat": "Apri / Chiudi chat",
"closeChat": "",
"closeChat": "Chiudi chat",
"documentClose": "Chiudi documento condiviso",
"documentOpen": "Apri documento condiviso",
"enterFullScreen": "Visualizza a schermo intero",
"enterTileView": "",
"enterTileView": "Vista a tessere",
"exitFullScreen": "Esci da schermo intero",
"exitTileView": "",
"exitTileView": "Vista utente singolo",
"feedback": "Lascia un feedback",
"hangup": "Esci",
"invite": "Invita persone",
"login": "Login",
"logout": "Logout",
"lowerYourHand": "",
"lowerYourHand": "Abbassa la mano",
"moreActions": "Più azioni",
"mute": "Microfono Attiva / Disattiva",
"openChat": "",
"openChat": "Apri una chat",
"pip": "Abilita visualizzazione immagine nellimmagine",
"profile": "Modifica profilo",
"raiseHand": "Alza / Abbassa la mano",
"raiseYourHand": "",
"raiseYourHand": "Alza la mano",
"Settings": "Impostazioni",
"sharedvideo": "Condividi un video Youtube",
"shareRoom": "Invita partecipante",
"shortcuts": "Visualizza scorciatoie",
"speakerStats": "Statistiche dell'interlocutore",
"startScreenSharing": "",
"startSubtitles": "",
"stopScreenSharing": "",
"stopSubtitles": "",
"startScreenSharing": "Inizia la condivisione dello schermo",
"startSubtitles": "Avvia sottotitoli",
"stopScreenSharing": "Ferma la condivisione dello schermo",
"stopSubtitles": "Ferma sottotitoli",
"stopSharedVideo": "Ferma video YouTube",
"talkWhileMutedPopup": "Stai provando a parlare? Il microfono è disattivato.",
"tileViewToggle": "Attiva/disattiva visualizzazione griglia",
"toggleCamera": "Attiva/disattiva webcam",
"toggleCamera": "Cambia videocamera",
"videomute": "Attiva / Disattiva videocamera",
"startvideoblur": "",
"stopvideoblur": ""
"startvideoblur": "Offusca il video",
"stopvideoblur": "Non offuscare il video"
},
"transcribing": {
"ccButtonTooltip": "",
"ccButtonTooltip": "Inizia / Ferma i sottotitoli",
"error": "Registrazione fallita. Prova di nuovo.",
"expandedLabel": "La trascrizione della conferenza è attiva",
"failedToStart": "Cè stato un errore nellavvio del servizio di trascrizione.",
@@ -654,7 +654,7 @@
"videoStatus": {
"audioOnly": "AUD",
"audioOnlyExpanded": "Modalita' solo audio attiva. Questa modalità permette di rispamiare banda ma non vedrai gli altri partecipanti.",
"callQuality": "",
"callQuality": "Qualità audio",
"hd": "HD",
"highDefinition": "Alta definizione",
"labelTooiltipNoVideo": "Nessun video",
@@ -678,14 +678,14 @@
"muted": "Audio disattivato",
"remoteControl": "Controllo remoto",
"show": "",
"videomute": ""
"videomute": "Silenzia il video"
},
"welcomepage": {
"accessibilityLabel": {
"join": "Tap per accedere",
"roomname": "Inserisci Nome Stanza"
},
"appDescription": "Via avanti, video chatta con l'intero team. In effetti, invita tutti quelli che conosci. {{app}} è una soluzione di video conference totalmente crittografata, 100% open cource, che puoi utilizzare tutto il giorno, ogni giorno, gratuitamente - senza bisogno di un account.",
"appDescription": "Via avanti, video chatta con l'intero team. In effetti, invita tutti quelli che conosci. {{app}} è una soluzione di video conference totalmente crittografata, 100% open source, che puoi utilizzare tutto il giorno, ogni giorno, gratuitamente - senza bisogno di un account.",
"audioVideoSwitch": {
"audio": "Voce",
"video": "Video"
@@ -696,7 +696,7 @@
"enterRoomTitle": "Avvia una nuova conferenza",
"go": "VAI",
"join": "UNISCITI",
"info": "",
"info": "Informazioni",
"privacy": "Privacy",
"recentList": "Recente",
"recentListDelete": "Cancella",
@@ -708,4 +708,4 @@
"terms": "Termini di utilizzo",
"title": "Il sistema di conferenza sicuro, funzionale e completamente gratuito."
}
}
}

View File

@@ -209,6 +209,12 @@
"micNotSendingDataTitle": "Your mic is muted by your system settings",
"micPermissionDeniedError": "You have not granted permission to use your microphone. You can still join the conference but others won't hear you. Use the camera button in the address bar to fix this.",
"micUnknownError": "Cannot use microphone for an unknown reason.",
"muteEveryoneElseDialog": "Once muted, you won't be able to unmute them, but they can unmute themselves at any time.",
"muteEveryoneElseTitle": "Mute everyone except {{whom}}?",
"muteEveryoneDialog": "Are you sure you want to mute everyone? You won't be able to unmute them, but they can unmute themselves at any time.",
"muteEveryoneTitle": "Mute everyone?",
"muteEveryoneSelf": "yourself",
"muteEveryoneStartMuted": "Everyone starts muted from now on",
"muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.",
"muteParticipantButton": "Mute",
"muteParticipantDialog": "Are you sure you want to mute this participant? You won't be able to unmute them, but they can unmute themselves at any time.",
@@ -590,7 +596,9 @@
"lockRoom": "Toggle meeting password",
"moreActions": "Toggle more actions menu",
"moreActionsMenu": "More actions menu",
"moreOptions": "Show more options",
"mute": "Toggle mute audio",
"muteEveryone": "Mute everyone",
"pip": "Toggle Picture-in-Picture mode",
"privateMessage": "Send private message",
"profile": "Edit your profile",
@@ -632,14 +640,16 @@
"logout": "Logout",
"lowerYourHand": "Lower your hand",
"moreActions": "More actions",
"moreOptions": "More options",
"mute": "Mute / Unmute",
"muteEveryone": "Mute everyone",
"noAudioSignalTitle": "There is no input coming from your mic!",
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
"noAudioSignalDialInDesc": "You can also dial-in using:",
"noAudioSignalDialInLinkDesc" : "Dial-in numbers",
"noisyAudioInputTitle": "Your microphone appears to be noisy!",
"noisyAudioInputDesc": "Jitsi has detected noise coming from your microphone, please consider muting or changing the device.",
"noisyAudioInputDesc": "It sounds like your microphone is making noise, please consider muting or changing the device.",
"openChat": "Open chat",
"pip": "Enter Picture-in-Picture mode",
"privateMessage": "Send private message",
@@ -720,6 +730,7 @@
},
"videothumbnail": {
"domute": "Mute",
"domuteOthers": "Mute everyone else",
"flip": "Flip",
"kick": "Kick out",
"moderator": "Moderator",
@@ -758,5 +769,9 @@
"sendFeedback": "Send feedback",
"terms": "Terms",
"title": "Secure, fully featured, and completely free video conferencing"
},
"lonelyMeetingExperience": {
"button": "Invite others",
"youAreAlone": "You are the only one in the meeting"
}
}

View File

@@ -15,7 +15,7 @@ import { invite } from '../../react/features/invite';
import { toggleTileView } from '../../react/features/video-layout';
import { getJitsiMeetTransport } from '../transport';
import { API_ID } from './constants';
import { API_ID, ENDPOINT_TEXT_MESSAGE_NAME } from './constants';
import {
processExternalDeviceRequest
} from '../../react/features/device-selection/functions';
@@ -155,6 +155,17 @@ function initCommands() {
'avatar-url': avatarUrl => {
sendAnalytics(createApiEvent('avatar.url.changed'));
APP.conference.changeLocalAvatarUrl(avatarUrl);
},
'send-endpoint-text-message': (to, text) => {
logger.debug('Send endpoint message command received');
try {
APP.conference.sendEndpointMessage(to, {
name: ENDPOINT_TEXT_MESSAGE_NAME,
text
});
} catch (err) {
logger.error('Failed sending endpoint text message', err);
}
}
};
transport.on('event', ({ data, name }) => {
@@ -437,6 +448,20 @@ class API {
});
}
/**
* Notify external application (if API is enabled) that user received
* a text message through datachannels.
*
* @param {Object} data - The event data.
* @returns {void}
*/
notifyEndpointTextMessageReceived(data: Object) {
this._sendEvent({
name: 'endpoint-text-message-received',
data
});
}
/**
* Notify external application (if API is enabled) that the device list has
* changed.

View File

@@ -9,5 +9,9 @@ import parseURLParams from '../../react/features/base/config/parseURLParams';
/**
* JitsiMeetExternalAPI id - unique for a webpage.
*/
export const API_ID
= parseURLParams(window.location).jitsi_meet_external_api_id;
export const API_ID = parseURLParams(window.location).jitsi_meet_external_api_id;
/**
* The payload name for the datachannel/endpoint text message event
*/
export const ENDPOINT_TEXT_MESSAGE_NAME = 'endpoint-text-message';

View File

@@ -32,6 +32,7 @@ const commands = {
email: 'email',
hangup: 'video-hangup',
password: 'password',
sendEndpointTextMessage: 'send-endpoint-text-message',
sendTones: 'send-tones',
subject: 'subject',
submitFeedback: 'submit-feedback',
@@ -55,6 +56,7 @@ const events = {
'device-list-changed': 'deviceListChanged',
'display-name-change': 'displayNameChange',
'email-change': 'emailChange',
'endpoint-text-message-received': 'endpointTextMessageReceived',
'feedback-submitted': 'feedbackSubmitted',
'feedback-prompt-displayed': 'feedbackPromptDisplayed',
'filmstrip-display-changed': 'filmstripDisplayChanged',
@@ -300,7 +302,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
const frameName = `jitsiConferenceFrame${id}`;
this._frame = document.createElement('iframe');
this._frame.allow = 'camera; microphone';
this._frame.allow = 'camera; microphone; display-capture';
this._frame.src = this._url;
this._frame.name = frameName;
this._frame.id = frameName;

View File

@@ -126,10 +126,6 @@ UI.initConference = function() {
const { getState } = APP.store;
const { id, name } = getLocalParticipant(getState);
// Update default button states before showing the toolbar
// if local role changes buttons state will be again updated.
UI.updateLocalRole(APP.conference.isModerator);
UI.showToolbar();
const displayName = config.displayJids ? id : name;
@@ -166,7 +162,7 @@ UI.start = function() {
// resizeVideoArea) because the animation is not visible anyway. Plus with
// the current dom layout, the quality label is part of the video layout and
// will be seen animating in.
VideoLayout.resizeVideoArea(true, false);
VideoLayout.resizeVideoArea();
sharedVideoManager = new SharedVideoManager(eventEmitter);
@@ -279,44 +275,6 @@ UI.addUser = function(user) {
UI.onPeerVideoTypeChanged
= (id, newVideoType) => VideoLayout.onVideoTypeChanged(id, newVideoType);
/**
* Update local user role and show notification if user is moderator.
* @param {boolean} isModerator if local user is moderator or not
*/
UI.updateLocalRole = isModerator => {
VideoLayout.showModeratorIndicator();
if (isModerator && !interfaceConfig.DISABLE_FOCUS_INDICATOR) {
messageHandler.participantNotification(
null, 'notify.me', 'connected', 'notify.moderator');
}
};
/**
* Check the role for the user and reflect it in the UI, moderator ui indication
* and notifies user who is the moderator
* @param user to check for moderator
*/
UI.updateUserRole = user => {
VideoLayout.showModeratorIndicator();
// We don't need to show moderator notifications when the focus (moderator)
// indicator is disabled.
if (!user.isModerator() || interfaceConfig.DISABLE_FOCUS_INDICATOR) {
return;
}
const displayName = user.getDisplayName();
messageHandler.participantNotification(
displayName,
'notify.somebody',
'connected',
'notify.grantedTo',
{ to: displayName
? UIUtil.escapeHtml(displayName) : '$t(notify.somebody)' });
};
/**
* Updates the user status.
*

View File

@@ -120,7 +120,7 @@ class Etherpad extends LargeContainer {
if (interfaceConfig.VERTICAL_FILMSTRIP) {
height = containerHeight - getToolboxHeight();
width = containerWidth - Filmstrip.getFilmstripWidth();
width = containerWidth - Filmstrip.getVerticalFilmstripWidth();
} else {
height = containerHeight - Filmstrip.getFilmstripHeight();
width = containerWidth;

View File

@@ -661,7 +661,7 @@ class SharedVideoContainer extends LargeContainer {
if (interfaceConfig.VERTICAL_FILMSTRIP) {
height = containerHeight - getToolboxHeight();
width = containerWidth - Filmstrip.getFilmstripWidth();
width = containerWidth - Filmstrip.getVerticalFilmstripWidth();
} else {
height = containerHeight - Filmstrip.getFilmstripHeight();
width = containerWidth;

View File

@@ -1,6 +1,6 @@
/* global $, APP, interfaceConfig */
import { isFilmstripVisible } from '../../../react/features/filmstrip';
import { getVerticalFilmstripVisibleAreaWidth, isFilmstripVisible } from '../../../react/features/filmstrip';
const Filmstrip = {
/**
@@ -19,17 +19,12 @@ const Filmstrip = {
},
/**
* Returns the width of filmstip
* @returns {number} width
* Returns the width of the vertical filmstip if the filmstrip is visible and 0 otherwise.
*
* @returns {number} - The width of the vertical filmstip if the filmstrip is visible and 0 otherwise.
*/
getFilmstripWidth() {
const filmstrip = $('#remoteVideos');
return isFilmstripVisible(APP.store)
? filmstrip.outerWidth()
- parseInt(filmstrip.css('paddingLeft'), 10)
- parseInt(filmstrip.css('paddingRight'), 10)
: 0;
getVerticalFilmstripWidth() {
return isFilmstripVisible(APP.store) ? getVerticalFilmstripVisibleAreaWidth() : 0;
},
/**

View File

@@ -126,9 +126,11 @@ export default class RemoteVideo extends SmallVideo {
addRemoteVideoContainer() {
this.container = createContainer(this.videoSpanId);
this.$container = $(this.container);
this.initializeAvatar();
this._setThumbnailSize();
this.initBrowserSpecificProperties();
this.updateRemoteVideoMenu();
this.updateStatusBar();
this.addAudioLevelIndicator();
this.addPresenceLabel();
@@ -187,7 +189,6 @@ export default class RemoteVideo extends SmallVideo {
// hide volume when in silent mode
const onVolumeChange
= APP.store.getState()['features/base/config'].startSilent ? undefined : this._setAudioVolume;
const { isModerator } = APP.conference;
const participantID = this.id;
const currentLayout = getCurrentLayout(APP.store.getState());
let remoteMenuPosition;
@@ -207,7 +208,6 @@ export default class RemoteVideo extends SmallVideo {
<RemoteVideoMenuTriggerButton
initialVolumeValue = { initialVolumeValue }
isAudioMuted = { this.isAudioMuted }
isModerator = { isModerator }
menuPosition = { remoteMenuPosition }
onMenuDisplay
= {this._onRemoteVideoMenuDisplay.bind(this)}

View File

@@ -18,11 +18,9 @@ import {
import { ConnectionIndicator } from '../../../react/features/connection-indicator';
import { DisplayName } from '../../../react/features/display-name';
import {
AudioMutedIndicator,
DominantSpeakerIndicator,
ModeratorIndicator,
RaisedHandIndicator,
VideoMutedIndicator
StatusIndicators
} from '../../../react/features/filmstrip';
import {
LAYOUTS,
@@ -84,9 +82,7 @@ export default class SmallVideo {
* Constructor.
*/
constructor(VideoLayout) {
this._isModerator = false;
this.isAudioMuted = false;
this.hasAvatar = false;
this.isVideoMuted = false;
this.videoStream = null;
this.audioStream = null;
@@ -286,45 +282,18 @@ export default class SmallVideo {
return;
}
const currentLayout = getCurrentLayout(APP.store.getState());
let tooltipPosition;
if (currentLayout === LAYOUTS.TILE_VIEW) {
tooltipPosition = 'right';
} else if (currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW) {
tooltipPosition = 'left';
} else {
tooltipPosition = 'top';
}
ReactDOM.render(
<I18nextProvider i18n = { i18next }>
<div>
{ this.isAudioMuted
? <AudioMutedIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this.isVideoMuted
? <VideoMutedIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this._isModerator && !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator
tooltipPosition = { tooltipPosition } />
: null }
</div>
</I18nextProvider>,
<Provider store = { APP.store }>
<I18nextProvider i18n = { i18next }>
<StatusIndicators
showAudioMutedIndicator = { this.isAudioMuted }
showVideoMutedIndicator = { this.isVideoMuted }
participantID = { this.id } />
</I18nextProvider>
</Provider>,
statusBarContainer);
}
/**
* Adds the element indicating the moderator(owner) of the conference.
*/
addModeratorIndicator() {
this._isModerator = true;
this.updateStatusBar();
}
/**
* Adds the element indicating the audio level of the participant.
*
@@ -380,14 +349,6 @@ export default class SmallVideo {
return this.container.querySelector('.audioindicator-container');
}
/**
* Removes the element indicating the moderator(owner) of the conference.
*/
removeModeratorIndicator() {
this._isModerator = false;
this.updateStatusBar();
}
/**
* This is an especially interesting function. A naive reader might think that
* it returns this SmallVideo's "video" element. But it is much more exciting.
@@ -556,20 +517,9 @@ export default class SmallVideo {
}
/**
* Hides or shows the user's avatar.
* This update assumes that large video had been updated and we will
* reflect it on this small video.
* Updates the css classes of the thumbnail based on the current state.
*/
updateView() {
if (this.id) {
// Init / refresh avatar
this.initializeAvatar();
} else {
logger.error('Unable to init avatar - no id', this);
return;
}
this.$container.removeClass((index, classNames) =>
classNames.split(' ').filter(name => name.startsWith('display-')));
@@ -619,8 +569,6 @@ export default class SmallVideo {
initializeAvatar() {
const thumbnail = this.$avatar().get(0);
this.hasAvatar = true;
if (thumbnail) {
// Maybe add a special case for local participant, as on init of
// LocalVideo.js the id is set to "local" but will get updated later.

View File

@@ -46,7 +46,7 @@ function computeDesktopVideoSize( // eslint-disable-line max-params
if (interfaceConfig.VERTICAL_FILMSTRIP) {
// eslint-disable-next-line no-param-reassign
videoSpaceWidth -= Filmstrip.getFilmstripWidth();
videoSpaceWidth -= Filmstrip.getVerticalFilmstripWidth();
} else {
// eslint-disable-next-line no-param-reassign
videoSpaceHeight -= Filmstrip.getFilmstripHeight();
@@ -206,6 +206,8 @@ export class VideoContainer extends LargeContainer {
*/
this._hideBackground = true;
this._isHidden = false;
/**
* Flag indicates whether or not the avatar is currently displayed.
* @type {boolean}
@@ -332,7 +334,7 @@ export class VideoContainer extends LargeContainer {
/* eslint-enable max-params */
if (this.stream && this.isScreenSharing()) {
if (interfaceConfig.VERTICAL_FILMSTRIP) {
containerWidthToUse -= Filmstrip.getFilmstripWidth();
containerWidthToUse -= Filmstrip.getVerticalFilmstripWidth();
}
return getCameraVideoPosition(width,
@@ -561,6 +563,8 @@ export class VideoContainer extends LargeContainer {
FADE_DURATION_MS,
1,
() => {
this._isHidden = false;
this._updateBackground();
resolve();
}
);
@@ -578,6 +582,8 @@ export class VideoContainer extends LargeContainer {
return new Promise(resolve => {
this.$wrapperParent.fadeTo(FADE_DURATION_MS, 0, () => {
this.$wrapperParent.css('visibility', 'hidden');
this._isHidden = true;
this._updateBackground();
resolve();
});
});
@@ -635,7 +641,7 @@ export class VideoContainer extends LargeContainer {
ReactDOM.render(
<LargeVideoBackground
hidden = { this._hideBackground }
hidden = { this._hideBackground || this._isHidden }
mirror = {
this.stream
&& this.stream.isLocal()

View File

@@ -174,9 +174,9 @@ const VideoLayout = {
// Make sure track's muted state is reflected
if (stream.getType() === 'audio') {
this.onAudioMute(stream.getParticipantId(), stream.isMuted());
this.onAudioMute(id, stream.isMuted());
} else {
this.onVideoMute(stream.getParticipantId(), stream.isMuted());
this.onVideoMute(id, stream.isMuted());
}
},
@@ -204,8 +204,7 @@ const VideoLayout = {
updateMutedForNoTracks(participantId, mediaType) {
const participant = APP.conference.getParticipantById(participantId);
if (participant
&& !participant.getTracksByMediaType(mediaType).length) {
if (participant && !participant.getTracksByMediaType(mediaType).length) {
if (mediaType === 'audio') {
APP.UI.setAudioMuted(participantId, true);
} else if (mediaType === 'video') {
@@ -328,35 +327,6 @@ const VideoLayout = {
this._updateLargeVideoIfDisplayed(resourceJid, true);
},
/**
* Shows a visual indicator for the moderator of the conference.
* On local or remote participants.
*/
showModeratorIndicator() {
const isModerator = APP.conference.isModerator;
if (isModerator) {
localVideoThumbnail.addModeratorIndicator();
} else {
localVideoThumbnail.removeModeratorIndicator();
}
APP.conference.listMembers().forEach(member => {
const id = member.getId();
const remoteVideo = remoteVideos[id];
if (!remoteVideo) {
return;
}
if (member.isModerator()) {
remoteVideo.addModeratorIndicator();
}
remoteVideo.updateRemoteVideoMenu();
});
},
/**
* On audio muted event.
*/
@@ -371,7 +341,7 @@ const VideoLayout = {
}
remoteVideo.showAudioIndicator(isMuted);
remoteVideo.updateRemoteVideoMenu(isMuted);
remoteVideo.updateRemoteVideoMenu();
}
},
@@ -542,15 +512,11 @@ const VideoLayout = {
/**
* Resizes the video area.
*
* TODO: Remove the "animate" param as it is no longer passed in as true.
*
* @param forceUpdate indicates that hidden thumbnails will be shown
*/
resizeVideoArea(animate = false) {
resizeVideoArea() {
if (largeVideo) {
largeVideo.updateContainerSize();
largeVideo.resize(animate);
largeVideo.resize(false);
}
},
@@ -785,7 +751,7 @@ const VideoLayout = {
APP.remoteControl.checkUserRemoteControlSupport(user)
.then(result => remoteVideo.setRemoteControlSupport(result))
.catch(error =>
logger.warn('could not get remote control properties', error));
logger.warn(`could not get remote control properties for: ${user.getJid()}`, error));
},
/**

529
package-lock.json generated
View File

@@ -1745,11 +1745,18 @@
"integrity": "sha512-x5HFsW+E/nQalGMw7hu+fvPqnBeBaIr0lWJ2SG0PPL2j+Pm9lYvCrsZJGIgauPIENx0v10INIyFjmSNUD/gSqQ=="
},
"@babel/plugin-external-helpers": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.7.4.tgz",
"integrity": "sha512-RVGNajLaFlknbZLutaP/uv7Q+xmVs2LMlEWFXbcjLnwtBdPqAVpV3nzYIAJqri/VjJCUrhG5nALijtg0aND+XA==",
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.8.3.tgz",
"integrity": "sha512-mx0WXDDiIl5DwzMtzWGRSPugXi9BxROS05GQrhLNbEamhBiicgn994ibwkyiBH+6png7bm/yA7AUsvHyCXi4Vw==",
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
"@babel/helper-plugin-utils": "^7.8.3"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ=="
}
}
},
"@babel/plugin-proposal-async-generator-functions": {
@@ -2450,9 +2457,9 @@
}
},
"@babel/register": {
"version": "7.7.7",
"resolved": "https://registry.npmjs.org/@babel/register/-/register-7.7.7.tgz",
"integrity": "sha512-S2mv9a5dc2pcpg/ConlKZx/6wXaEwHeqfo7x/QbXsdCAZm+WJC1ekVvL1TVxNsedTs5y/gG63MhJTEsmwmjtiA==",
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/register/-/register-7.8.3.tgz",
"integrity": "sha512-t7UqebaWwo9nXWClIPLPloa5pN33A2leVs8Hf0e9g9YwUP8/H9NeR7DJU+4CXo23QtjChQv5a3DjEtT83ih1rg==",
"requires": {
"find-cache-dir": "^2.0.0",
"lodash": "^4.17.13",
@@ -2627,9 +2634,9 @@
}
},
"@cnakazawa/watch": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz",
"integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
"integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
"requires": {
"exec-sh": "^0.3.2",
"minimist": "^1.2.0"
@@ -2702,9 +2709,9 @@
"integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA=="
},
"@hapi/hoek": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.0.tgz",
"integrity": "sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw=="
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
"integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow=="
},
"@hapi/joi": {
"version": "15.1.1",
@@ -2864,9 +2871,9 @@
}
},
"@react-native-community/cli-platform-android": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz",
"integrity": "sha512-rNO9DmRiVhB6aP2DVUjEJv7ecriTARDZND88ny3xNVUkrD1Y+zwF6aZu3eoT52VXOxLCSLiJzz19OiyGmfqxYg==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-3.1.4.tgz",
"integrity": "sha512-ClSdY20F0gzWVLTqCv7vHjnUqOcuq10jd9GgHX6lGSc2GI+Ql3/aQg3tmG4uY3KXNNwAv3U8QCoYgg1WGfwiHA==",
"requires": {
"@react-native-community/cli-tools": "^3.0.0",
"chalk": "^2.4.2",
@@ -2916,9 +2923,9 @@
}
},
"@react-native-community/cli-platform-ios": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz",
"integrity": "sha512-QoNVlDj8eMXRZk9uktPFsctHurQpv9jKmiu6mQii4NEtT2npE7g1hbWpRNojutBsfgmCdQGDHd9uB54eeCnYgg==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.2.0.tgz",
"integrity": "sha512-pzEnx68H6+mHBq5jsMrr3UmAmkrLSMlC9BZ4yoUdfUXCQq6/R70zNYvH4hjUw8h2Al7Kgq53UzHUsM0ph8TSWQ==",
"requires": {
"@react-native-community/cli-tools": "^3.0.0",
"chalk": "^2.4.2",
@@ -4013,6 +4020,11 @@
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-1.5.1.tgz",
"integrity": "sha512-DyuhifqflK+bdpBRLAj3RuWm1eTVe8yNX2+WH+W+wmhpjGg7Yagnar6/66JdS2h3WUFoiplCpZRAVMVw631E5g=="
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -4036,9 +4048,9 @@
"integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg=="
},
"@types/istanbul-lib-report": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz",
"integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
"integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
"requires": {
"@types/istanbul-lib-coverage": "*"
}
@@ -4102,17 +4114,17 @@
"integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw=="
},
"@types/yargs": {
"version": "13.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.4.tgz",
"integrity": "sha512-Ke1WmBbIkVM8bpvsNEcGgQM70XcEh/nbpxQhW7FhrsbCsXSY9BmLB1+LHtD7r9zrsOcFlLiF+a/UeJsdfw3C5A==",
"version": "13.0.8",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz",
"integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==",
"requires": {
"@types/yargs-parser": "*"
}
},
"@types/yargs-parser": {
"version": "13.1.0",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz",
"integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg=="
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
},
"@webassemblyjs/ast": {
"version": "1.7.11",
@@ -4819,9 +4831,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -5079,9 +5091,9 @@
"dev": true
},
"aws4": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
"dev": true
},
"babel-code-frame": {
@@ -6839,9 +6851,9 @@
"dev": true
},
"dayjs": {
"version": "1.8.19",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.19.tgz",
"integrity": "sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg=="
"version": "1.8.20",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.20.tgz",
"integrity": "sha512-mH0MCDxw6UCGJYxVN78h8ugWycZAO8thkj3bW6vApL5tS0hQplIDdAQcmbvl7n35H0AKdCJQaArTrIQw2xt4Qg=="
},
"debounce": {
"version": "1.2.0",
@@ -7032,6 +7044,11 @@
"integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
"dev": true
},
"didyoumean": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz",
"integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8="
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@@ -9271,13 +9288,13 @@
}
},
"globule": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
"integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
"dev": true,
"requires": {
"glob": "~7.1.1",
"lodash": "~4.17.10",
"lodash": "~4.17.12",
"minimatch": "~3.0.2"
}
},
@@ -9343,21 +9360,21 @@
},
"dependencies": {
"ajv": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
"dev": true
},
"json-schema-traverse": {
@@ -10183,13 +10200,10 @@
"dev": true
},
"is-finite": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
"integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
@@ -10639,8 +10653,8 @@
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
},
"js-utils": {
"version": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"from": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"version": "github:jitsi/js-utils#7a2be83d17dc4a3d0fac4a742ab999478f326f2e",
"from": "github:jitsi/js-utils#7a2be83d17dc4a3d0fac4a742ab999478f326f2e",
"requires": {
"bowser": "2.7.0",
"js-md5": "0.7.3",
@@ -10869,8 +10883,8 @@
}
},
"lib-jitsi-meet": {
"version": "github:jitsi/lib-jitsi-meet#463f741cb6c76bb41490c0bc50728e4767f648ba",
"from": "github:jitsi/lib-jitsi-meet#463f741cb6c76bb41490c0bc50728e4767f648ba",
"version": "github:jitsi/lib-jitsi-meet#5466c9d08a2c262ebb5889e3bb0cbbe6f08dc0c3",
"from": "github:jitsi/lib-jitsi-meet#5466c9d08a2c262ebb5889e3bb0cbbe6f08dc0c3",
"requires": {
"@jitsi/sdp-interop": "0.1.14",
"@jitsi/sdp-simulcast": "0.2.2",
@@ -10880,9 +10894,26 @@
"js-utils": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"lodash.isequal": "4.5.0",
"sdp-transform": "2.3.0",
"strophe.js": "1.2.16",
"strophe.js": "1.3.4",
"strophejs-plugin-disco": "0.0.2",
"strophejs-plugin-stream-management": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009",
"webrtc-adapter": "github:webrtc/adapter#1eec19782b4058d186341263e7d049cea3e3290a"
},
"dependencies": {
"js-md5": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ=="
},
"js-utils": {
"version": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"from": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"requires": {
"bowser": "2.7.0",
"js-md5": "0.7.3",
"postis": "2.2.0"
}
}
}
},
"libflacjs": {
@@ -11384,9 +11415,9 @@
"dev": true
},
"metro": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro/-/metro-0.56.3.tgz",
"integrity": "sha512-mxHpvBGWanZ46wAEZVLinNO5IYMcFbTdMZIRhC7r+rvoSK6r9iPj95AujBfzLXMAl36RI2O3D7yp5hOYif/gEQ==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro/-/metro-0.56.4.tgz",
"integrity": "sha512-Kt3OQJQtQdts0JrKnyGdLpKHDjqYBgIfzvYrvfhmFCkKuZ8aqRlVnvpfjQ4/OBm0Fmm9NyyxbNRD9VIbj7WjnA==",
"requires": {
"@babel/core": "^7.0.0",
"@babel/generator": "^7.0.0",
@@ -11415,17 +11446,17 @@
"json-stable-stringify": "^1.0.1",
"lodash.throttle": "^4.1.1",
"merge-stream": "^1.0.1",
"metro-babel-register": "0.56.3",
"metro-babel-transformer": "0.56.3",
"metro-cache": "0.56.3",
"metro-config": "0.56.3",
"metro-core": "0.56.3",
"metro-inspector-proxy": "0.56.3",
"metro-minify-uglify": "0.56.3",
"metro-react-native-babel-preset": "0.56.3",
"metro-resolver": "0.56.3",
"metro-source-map": "0.56.3",
"metro-symbolicate": "0.56.3",
"metro-babel-register": "^0.56.4",
"metro-babel-transformer": "^0.56.4",
"metro-cache": "^0.56.4",
"metro-config": "^0.56.4",
"metro-core": "^0.56.4",
"metro-inspector-proxy": "^0.56.4",
"metro-minify-uglify": "^0.56.4",
"metro-react-native-babel-preset": "^0.56.4",
"metro-resolver": "^0.56.4",
"metro-source-map": "^0.56.4",
"metro-symbolicate": "^0.56.4",
"mime-types": "2.1.11",
"mkdirp": "^0.5.1",
"node-fetch": "^2.2.0",
@@ -11443,12 +11474,17 @@
"yargs": "^9.0.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ=="
},
"@babel/plugin-syntax-flow": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.4.tgz",
"integrity": "sha512-2AMAWl5PsmM5KPkB22cvOkUyWk6MjUaqhHNU5nSPUl/ns3j5qLfw2SuYP5RbVZ0tfLvePr4zUScbICtDP2CUNw==",
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz",
"integrity": "sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg==",
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
"@babel/helper-plugin-utils": "^7.8.3"
}
},
"ansi-styles": {
@@ -11566,9 +11602,9 @@
}
},
"metro-react-native-babel-preset": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz",
"integrity": "sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.4.tgz",
"integrity": "sha512-CzbBDM9Rh6w8s1fq+ZqihAh7DDqUAcfo9pPww25+N/eJ7UK436Q7JdfxwdIPpBwLFn6o6MyYn+uwL9OEWBJarA==",
"requires": {
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -11679,9 +11715,9 @@
}
},
"metro-babel-register": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.56.3.tgz",
"integrity": "sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.56.4.tgz",
"integrity": "sha512-Phm6hMluOWYqfykftjJ1jsTpWvbgb49AC/1taxEctxUdRCZlFgZwBleJZAhQYxJD5J+ikFkEbHDzePEXb29KVA==",
"requires": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
@@ -11698,53 +11734,53 @@
}
},
"metro-babel-transformer": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz",
"integrity": "sha512-N5/ftb3rBkt6uKlgYAv+lwtzYc4dK0tBpfZ8pjec3kcypGuGTuf4LTHEh65EuzySreLngYI0bQzoFSn3G3DYsw==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.4.tgz",
"integrity": "sha512-IOi4ILgZvaX7GCGHBJp79paNVOq5QxhhbyqAdEJgDP8bHfl/OVHoVKSypfrsMSKSiBrqxhIjyc4XjkXsQtkx5g==",
"requires": {
"@babel/core": "^7.0.0",
"metro-source-map": "0.56.3"
"metro-source-map": "^0.56.4"
}
},
"metro-cache": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.56.3.tgz",
"integrity": "sha512-SsryVe/TVkt2IkEGnYhB3gQlg9iMlu8WJikQHcCEjMfPEnSIzmeymrX73fwQNPnTnN7F3E0HVjH6Wvq6fh0mcA==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.56.4.tgz",
"integrity": "sha512-d1hiUSKwtRsuMxUhHVJ3tjK2BbpUlJGvTyMWohK8Wxx+0GbnWRWWFcI4vlCzlZfoK0VtZK2MJEl5t7Du1mIniQ==",
"requires": {
"jest-serializer": "^24.4.0",
"metro-core": "0.56.3",
"metro-core": "^0.56.4",
"mkdirp": "^0.5.1",
"rimraf": "^2.5.4"
}
},
"metro-config": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.56.3.tgz",
"integrity": "sha512-C3ZLA5y5gW5auDSQN5dsCTduJg7LXEiX/tLAADOkgXWVImr5P74x9Wt8y1MMWrKx6p+4p5RMDyEwWDMXJt/DwA==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.56.4.tgz",
"integrity": "sha512-O85QDHwWdMn/8ERe13y4a6vbZL0AHyO8atTvL+9BCulLEO+FQBi1iJjr3+ViLa8cf0m5dRftDsa7P47m5euk4A==",
"requires": {
"cosmiconfig": "^5.0.5",
"jest-validate": "^24.7.0",
"metro": "0.56.3",
"metro-cache": "0.56.3",
"metro-core": "0.56.3",
"metro": "^0.56.4",
"metro-cache": "^0.56.4",
"metro-core": "^0.56.4",
"pretty-format": "^24.7.0"
}
},
"metro-core": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.56.3.tgz",
"integrity": "sha512-OAaHP3mBdlACMZRwDJzZzYC0o2S3qfb4BBK75L8H4Ds+y3QUSrjsDEpHACcpaMTOds8rBvjzn+jjB5tqNoHfBA==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.56.4.tgz",
"integrity": "sha512-hMzkBdgPt5Zm9nr/1KtIT+A6H7TNiLVCEGG5OiAXj8gTRsA2yy7wAdQpwy0xbE+zi88t/pLOzXpd3ClG/YxyWg==",
"requires": {
"jest-haste-map": "^24.7.1",
"lodash.throttle": "^4.1.1",
"metro-resolver": "0.56.3",
"metro-resolver": "^0.56.4",
"wordwrap": "^1.0.0"
}
},
"metro-inspector-proxy": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz",
"integrity": "sha512-7WtHinw+VJcunQ3q8El1MqqzYSRvXEjW5QE13VYwcLtnay3pvcqACeiQmGbWI0IqxB1+QH8tf3nkA7z7pQ7Vpw==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.56.4.tgz",
"integrity": "sha512-E1S3MO25mWKmcLn1UQuCDiS0hf9P2Fwq8sEAX5lBLoZbehepNH+4xJ3xXSY51JX4dozBrE8GGoKL4ll3II40LA==",
"requires": {
"connect": "^3.6.5",
"debug": "^2.2.0",
@@ -11844,9 +11880,9 @@
}
},
"metro-minify-uglify": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz",
"integrity": "sha512-b9ljyeUpkJWVlFy8M/i4aNbvEBI0zN9vJh1jfU7yx+k9dX7FulLnpGmAQxxQdEszcM//sJrsKNS1oLYBxr0NMQ==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.56.4.tgz",
"integrity": "sha512-BHgj7+BKEK2pHvWHUR730bIrsZwl8DPtr49x9L0j2grPZ5/UROWXzEr8VZgIss7fl64t845uu1HXNNyuSj2EhA==",
"requires": {
"uglify-es": "^3.1.9"
}
@@ -11906,29 +11942,34 @@
}
},
"metro-react-native-babel-transformer": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz",
"integrity": "sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.4.tgz",
"integrity": "sha512-ng74eutuy1nyGI9+TDzzVAVfEmNPDlapV4msTQMKPi4EFqo/fBn7Ct33ME9l5E51pQBBnxt/UwcpTvd13b29kQ==",
"requires": {
"@babel/core": "^7.0.0",
"babel-preset-fbjs": "^3.1.2",
"metro-babel-transformer": "0.56.3",
"metro-react-native-babel-preset": "0.56.3",
"metro-source-map": "0.56.3"
"metro-babel-transformer": "^0.56.4",
"metro-react-native-babel-preset": "^0.56.4",
"metro-source-map": "^0.56.4"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
"integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ=="
},
"@babel/plugin-syntax-flow": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.4.tgz",
"integrity": "sha512-2AMAWl5PsmM5KPkB22cvOkUyWk6MjUaqhHNU5nSPUl/ns3j5qLfw2SuYP5RbVZ0tfLvePr4zUScbICtDP2CUNw==",
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz",
"integrity": "sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg==",
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
"@babel/helper-plugin-utils": "^7.8.3"
}
},
"metro-react-native-babel-preset": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz",
"integrity": "sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.4.tgz",
"integrity": "sha512-CzbBDM9Rh6w8s1fq+ZqihAh7DDqUAcfo9pPww25+N/eJ7UK436Q7JdfxwdIPpBwLFn6o6MyYn+uwL9OEWBJarA==",
"requires": {
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -11970,23 +12011,23 @@
}
},
"metro-resolver": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.56.3.tgz",
"integrity": "sha512-VvMl4xUp0fy76WiP3YDtzMmrn6tN/jwxOBqlTy9MjN6R9sUXrGyO5thwn/uKQqp5vwBTuJev7nZL7OKzwludKA==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.56.4.tgz",
"integrity": "sha512-Ug4ulVfpkKZ1Wu7mdYj9XLGuOqZTuWCqEhyx3siKTc/2eBwKZQXmiNo5d/IxWNvmwL/87Abeb724I6CMzMfjiQ==",
"requires": {
"absolute-path": "^0.0.0"
}
},
"metro-source-map": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.3.tgz",
"integrity": "sha512-CheqWbJZSM0zjcNBqELUiocwH3XArrOk6alhVuzJ2gV/WTMBQFwP0TtQssSMwjnouMHNEzY8RxErXKXBk/zJmQ==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.4.tgz",
"integrity": "sha512-f1P9/rpFmG3Z0Jatiw2zvLItx1TwR7mXTSDj4qLDCWeVMB3kEXAr3R0ucumTW8c6HfpJljeRBWzYFXF33fd81g==",
"requires": {
"@babel/traverse": "^7.0.0",
"@babel/types": "^7.0.0",
"invariant": "^2.2.4",
"metro-symbolicate": "0.56.3",
"ob1": "0.56.3",
"metro-symbolicate": "^0.56.4",
"ob1": "^0.56.4",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
},
@@ -12002,12 +12043,12 @@
}
},
"metro-symbolicate": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz",
"integrity": "sha512-fSQtjjy4eiJDThSl9eloxMElhrs+5PQB+DKKzmTFXT8e2GDga+pa1xTBFRUACMO8BXGuWmxR7SnGDw0wo5Ngrw==",
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz",
"integrity": "sha512-8mCNNn6zV5FFKCIcRgI7736Xl+owgvYuy8qanPxZN36f7utiWRYeB+PirEBPcglBk4qQvoy2lT6oPULNXZQbbQ==",
"requires": {
"invariant": "^2.2.4",
"metro-source-map": "0.56.3",
"metro-source-map": "^0.56.4",
"source-map": "^0.5.6",
"through2": "^2.0.1",
"vlq": "^1.0.0"
@@ -12241,8 +12282,7 @@
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
"optional": true
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
"nanomatch": {
"version": "1.2.13",
@@ -12495,9 +12535,9 @@
}
},
"node-sass": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
"integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
"integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@@ -12507,7 +12547,7 @@
"get-stdin": "^4.0.1",
"glob": "^7.0.3",
"in-publish": "^2.0.0",
"lodash": "^4.17.11",
"lodash": "^4.17.15",
"meow": "^3.7.0",
"mkdirp": "^0.5.1",
"nan": "^2.13.2",
@@ -12529,10 +12569,10 @@
"which": "^1.2.9"
}
},
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
}
}
@@ -12634,9 +12674,9 @@
"dev": true
},
"ob1": {
"version": "0.56.3",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.56.3.tgz",
"integrity": "sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ=="
"version": "0.56.4",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.56.4.tgz",
"integrity": "sha512-URgFof9z2wotiYFsqlydXtQfGV81gvBI2ODy64xfd3vPo+AYom5PVDX4t4zn23t/O+S2IxqApSQM8uJAybmz7w=="
},
"object-assign": {
"version": "4.1.1",
@@ -14129,9 +14169,9 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"psl": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz",
"integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==",
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
"integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
"dev": true
},
"public-encrypt": {
@@ -14501,9 +14541,8 @@
}
},
"react-native": {
"version": "0.61.5",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.61.5.tgz",
"integrity": "sha512-MXqE3NoGO0T3dUKIKkIppijBhRRMpfN6ANbhMXHDuyfA+fSilRWgCwYgR/YNCC7ntECoJYikKaNTUBB0DeQy6Q==",
"version": "github:jitsi/react-native#efd2aff5661d75a230e36406b698cfe0ee545be2",
"from": "github:jitsi/react-native#efd2aff5661d75a230e36406b698cfe0ee545be2",
"requires": {
"@babel/runtime": "^7.0.0",
"@react-native-community/cli": "^3.0.0",
@@ -14536,10 +14575,62 @@
"whatwg-fetch": "^3.0.0"
},
"dependencies": {
"@jest/types": {
"version": "25.1.0",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz",
"integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==",
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^1.1.1",
"@types/yargs": "^15.0.0",
"chalk": "^3.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"@react-native-community/cli": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-3.0.4.tgz",
"integrity": "sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-3.2.0.tgz",
"integrity": "sha512-k8GmNQH/EbIIVd4VlVbFP99IRNhovWV6hhnJ3y2+FfZq18H/U6yV/t1bpI3A3QqPuAyWxk/1jBdXvP6BY/7kbw==",
"requires": {
"@hapi/joi": "^15.0.3",
"@react-native-community/cli-debugger-ui": "^3.0.0",
@@ -14552,6 +14643,7 @@
"connect": "^3.6.5",
"cosmiconfig": "^5.1.0",
"deepmerge": "^3.2.0",
"didyoumean": "^1.2.1",
"envinfo": "^7.1.0",
"errorhandler": "^1.5.0",
"execa": "^1.0.0",
@@ -14572,6 +14664,7 @@
"open": "^6.2.0",
"ora": "^3.4.0",
"plist": "^3.0.0",
"pretty-format": "^25.1.0",
"semver": "^6.3.0",
"serve-static": "^1.13.1",
"shell-quote": "1.6.1",
@@ -14579,12 +14672,50 @@
"sudo-prompt": "^9.0.0",
"wcwidth": "^1.0.1",
"ws": "^1.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"pretty-format": {
"version": "25.1.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz",
"integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==",
"requires": {
"@jest/types": "^25.1.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
}
}
}
},
"@types/yargs": {
"version": "15.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz",
"integrity": "sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ==",
"requires": {
"@types/yargs-parser": "*"
}
},
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
},
"ansi-styles": {
"version": "3.2.1",
@@ -14604,6 +14735,11 @@
"supports-color": "^5.3.0"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -14721,6 +14857,13 @@
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"requires": {
"ansi-regex": "^4.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
}
}
},
"supports-color": {
@@ -15336,9 +15479,9 @@
}
},
"request": {
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
@@ -15348,7 +15491,7 @@
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
@@ -15358,24 +15501,24 @@
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
},
"dependencies": {
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
"version": "1.43.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
"dev": true
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"version": "2.1.26",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
"integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
"dev": true,
"requires": {
"mime-db": "1.40.0"
"mime-db": "1.43.0"
}
},
"safe-buffer": {
@@ -15385,9 +15528,9 @@
"dev": true
},
"uuid": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"dev": true
}
}
@@ -16467,9 +16610,9 @@
"dev": true
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -16726,15 +16869,19 @@
"dev": true
},
"strophe.js": {
"version": "1.2.16",
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.2.16.tgz",
"integrity": "sha512-r/Uq7aqrusg25Y0qHwV48cFnMY6K/CuZdGt3EggRx3kY4sMv8lG+AFoMlrmTcYVMG1BaJvQfv9Cthw4Ll8z7fQ=="
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.3.4.tgz",
"integrity": "sha512-jSLDG8jolhAwGOSgiJ7DTMSYK3wVoEJHKtpVRyEacQZ6CWA6z2WRPJpcFMjsIweq5aP9/XIvKUQqHBu/ZhvESA=="
},
"strophejs-plugin-disco": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/strophejs-plugin-disco/-/strophejs-plugin-disco-0.0.2.tgz",
"integrity": "sha512-T9pJFzn1ZUqZ/we9+OvI5pFdrjeb4IBMbEjK+ZWEZV036wEl8l8GOtF8AJ3sIqOMtdIiFLdFu99JiGWd7yapAQ=="
},
"strophejs-plugin-stream-management": {
"version": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009",
"from": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009"
},
"style-loader": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz",
@@ -17318,13 +17465,21 @@
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
"psl": "^1.1.28",
"punycode": "^2.1.1"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
}
}
},
"trim-newlines": {
@@ -18992,9 +19147,9 @@
},
"dependencies": {
"uuid": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}
}
},

View File

@@ -53,10 +53,10 @@
"jquery-contextmenu": "2.4.5",
"jquery-i18next": "1.2.1",
"js-md5": "0.6.1",
"js-utils": "github:jitsi/js-utils#8567f86ec2774ae1d1c47b22e3435928cf5d9771",
"js-utils": "github:jitsi/js-utils#7a2be83d17dc4a3d0fac4a742ab999478f326f2e",
"jsrsasign": "8.0.12",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#463f741cb6c76bb41490c0bc50728e4767f648ba",
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#5466c9d08a2c262ebb5889e3bb0cbbe6f08dc0c3",
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
"lodash": "4.17.13",
"moment": "2.19.4",
@@ -67,7 +67,7 @@
"react-emoji-render": "1.0.0",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.61.5",
"react-native": "github:jitsi/react-native#efd2aff5661d75a230e36406b698cfe0ee545be2",
"react-native-background-timer": "2.1.1",
"react-native-calendar-events": "github:jitsi/react-native-calendar-events#902e6e92d6bae450a6052f76ba4d02f977ffd8f2",
"react-native-callstats": "3.61.0",
@@ -122,7 +122,7 @@
"imports-loader": "0.7.1",
"jetifier": "1.6.4",
"metro-react-native-babel-preset": "0.56.0",
"node-sass": "4.12.0",
"node-sass": "4.13.1",
"precommit-hook": "3.0.0",
"string-replace-loader": "2.1.1",
"style-loader": "0.19.0",

View File

@@ -184,6 +184,23 @@ export function createRecentClickedEvent(eventName, attributes = {}) {
};
}
/**
* Creates an event which indicate an action occured in the chrome extension banner.
*
* @param {boolean} installPressed - Whether the user pressed install or `x` - cancel.
* @param {Object} attributes - Attributes to attach to the event.
* @returns {Object} The event in a format suitable for sending via
* sendAnalytics.
*/
export function createChromeExtensionBannerEvent(installPressed, attributes = {}) {
return {
action: installPressed ? 'install' : 'cancel',
attributes,
source: 'chrome.extension.banner',
type: TYPE_UI
};
}
/**
* Creates an event which indicates that the recent list container is shown and
* selected.

View File

@@ -2,10 +2,14 @@
import JitsiMeetJS, {
analytics,
browser,
isAnalyticsEnabled
} from '../base/lib-jitsi-meet';
import { getJitsiMeetGlobalNS, loadScript } from '../base/util';
import {
checkChromeExtensionsInstalled,
isMobileBrowser
} from '../base/environment/utils';
import { AmplitudeHandler } from './handlers';
import logger from './logger';
@@ -154,6 +158,18 @@ export function initAnalytics({ getState }: { getState: Function }, handlers: Ar
// Set the handlers last, since this triggers emptying of the cache
analytics.setAnalyticsHandlers(handlers);
if (!isMobileBrowser() && browser.isChrome()) {
const bannerCfg = state['features/base/config'].chromeExtensionBanner;
checkChromeExtensionsInstalled(bannerCfg).then(extensionsInstalled => {
if (extensionsInstalled?.length) {
analytics.addPermanentProperties({
hasChromeExtension: extensionsInstalled.some(ext => ext)
});
}
});
}
}
/**

View File

@@ -18,7 +18,7 @@ export default class AbstractHandler {
this._blackListedEvents = [
...(options.blackListedEvents || []), // eslint-disable-line no-extra-parens
'e2e_rtt', 'rtp.stats', 'rtt.by.region', 'available.device', 'stream.switch.delay', 'ice.state.changed',
'ice.duration'
'ice.duration', 'peer.conn.status.duration'
];
}

View File

@@ -30,6 +30,8 @@ import {
import logger from './logger';
declare var APP: Object;
declare var interfaceConfig: Object;
/**
* Triggers an in-app navigation to a specific route. Allows navigation to be
@@ -171,7 +173,7 @@ export function redirectToStaticPage(pathname: string) {
// fine but pointless to include it because contextRoot is the current
// directory.
newPathname.startsWith('./')
&& (newPathname = newPathname.substring(2));
&& (newPathname = newPathname.substring(2));
newPathname = getLocationContextRoot(windowLocation) + newPathname;
}
@@ -215,7 +217,7 @@ export function reloadWithStoredParams() {
windowLocation.replace(locationURL.toString());
if (window.self !== window.top
&& locationURL.search === oldSearchString) {
&& locationURL.search === oldSearchString) {
// NOTE: Assuming that only the hash or search part of the URL will
// be changed!
// location.reload will not trigger redirect/reload for iframe when
@@ -254,8 +256,15 @@ export function maybeRedirectToWelcomePage(options: Object = {}) {
// to close page
window.sessionStorage.setItem('guest', isGuest);
dispatch(redirectToStaticPage(`static/${
options.feedbackSubmitted ? 'close.html' : 'close2.html'}`));
let path = 'close.html';
if (interfaceConfig.SHOW_PROMOTIONAL_CLOSE_PAGE) {
path = 'close3.html';
} else if (!options.feedbackSubmitted) {
path = 'close2.html';
}
dispatch(redirectToStaticPage(`static/${path}`));
return;
}
@@ -279,4 +288,3 @@ export function maybeRedirectToWelcomePage(options: Object = {}) {
}
};
}

View File

@@ -23,6 +23,10 @@ export default {
replyBorder: 'rgb(219, 197, 200)',
replyIcon: 'rgb(94, 109, 121)'
},
'Conference': {
inviteButtonBackground: 'rgb(0, 119, 225)',
onVideoText: 'white'
},
'Dialog': {
border: 'rgba(0, 3, 6, 0.6)',
buttonBackground: ColorPalette.blue,

View File

@@ -12,6 +12,7 @@ export default [
'_peerConnStatusRtcMuteTimeout',
'abTesting',
'analytics.disabled',
'audioLevelsInterval',
'autoRecord',
'autoRecordToken',
'avgRtpStatsN',
@@ -103,6 +104,7 @@ export default [
'enableTcc',
'etherpad_base',
'failICE',
'feedbackPercentage',
'fileRecordingsEnabled',
'firefox_fake_device',
'forceJVB121Ratio',
@@ -120,6 +122,7 @@ export default [
'nick',
'openBridgeChannel',
'p2p',
'pcStatsInterval',
'preferH264',
'requireDisplayName',
'resolution',

View File

@@ -4,6 +4,8 @@ import { parseURLParams } from '../config';
import JitsiMeetJS from '../lib-jitsi-meet';
import { updateSettings } from '../settings';
import logger from './logger';
declare var APP: Object;
/**
@@ -187,6 +189,9 @@ export function setAudioOutputDeviceId(
dispatch: Function,
userSelection: boolean = false,
newLabel: ?string): Promise<*> {
logger.debug(`setAudioOutputDevice: ${String(newLabel)}[${newId}]`);
return JitsiMeetJS.mediaDevices.setAudioOutputDevice(newId)
.then(() => {
const newSettings = {

View File

@@ -9,6 +9,8 @@ import { groupDevicesByKind } from './functions';
import { ReducerRegistry } from '../redux';
import logger from './logger';
const DEFAULT_STATE = {
availableDevices: {
audioInput: [],
@@ -18,6 +20,24 @@ const DEFAULT_STATE = {
pendingRequests: []
};
/**
* Logs the current device list.
*
* @param {Object} deviceList - Whatever is returned by {@link groupDevicesByKind}.
* @returns {string}
*/
function logDeviceList(deviceList) {
const devicesToStr = list => list.map(device => `\t\t${device.label}[${device.deviceId}]`).join('\n');
const audioInputs = devicesToStr(deviceList.audioInput);
const audioOutputs = devicesToStr(deviceList.audioOutput);
const videoInputs = devicesToStr(deviceList.videoInput);
logger.debug('Device list updated:\n'
+ `audioInput:\n${audioInputs}\n`
+ `audioOutput:\n${audioOutputs}\n`
+ `videoInput:\n${videoInputs}`);
}
/**
* Listen for actions which changes the state of known and used devices.
*
@@ -35,6 +55,8 @@ ReducerRegistry.register(
case UPDATE_DEVICE_LIST: {
const deviceList = groupDevicesByKind(action.devices);
logDeviceList(deviceList);
return {
...state,
availableDevices: deviceList
@@ -56,11 +78,17 @@ ReducerRegistry.register(
pendingRequests: [ ]
};
// TODO: Changing of current audio and video device id is currently
// handled outside of react/redux. Fall through to default logic for
// now.
case SET_AUDIO_INPUT_DEVICE:
case SET_VIDEO_INPUT_DEVICE:
// TODO: Changing of current audio and video device id is currently handled outside of react/redux.
case SET_AUDIO_INPUT_DEVICE: {
logger.debug(`set audio input device: ${action.deviceId}`);
return state;
}
case SET_VIDEO_INPUT_DEVICE: {
logger.debug(`set video input device: ${action.deviceId}`);
return state;
}
default:
return state;
}

View File

@@ -174,8 +174,8 @@ ColorSchemeRegistry.register('BottomSheet', {
expandIcon: {
color: schemeColor('icon'),
fontSize: 16,
opacity: 0.7
fontSize: 48,
opacity: 0.8
},
/**

View File

@@ -3,6 +3,17 @@
import { ColorSchemeRegistry } from '../color-scheme';
import { toState } from '../redux';
/**
* Checks if any {@code Dialog} is currently open.
*
* @param {Function|Object} stateful - The redux store, the redux
* {@code getState} function, or the redux state itself.
* @returns {boolean}
*/
export function isAnyDialogOpen(stateful: Function) {
return Boolean(toState(stateful)['features/base/dialog'].component);
}
/**
* Checks if a {@code Dialog} with a specific {@code component} is currently
* open.

View File

@@ -1,3 +1,5 @@
// @flow
import Platform from '../react/Platform';
/**
@@ -8,3 +10,29 @@ import Platform from '../react/Platform';
export function isMobileBrowser() {
return Platform.OS === 'android' || Platform.OS === 'ios';
}
/**
* Checks whether the chrome extensions defined in the config file are installed or not.
*
* @param {Object} config - Objects containing info about the configured extensions.
*
* @returns {Promise[]}
*/
export function checkChromeExtensionsInstalled(config: Object = {}) {
const isExtensionInstalled = info => new Promise(resolve => {
const img = new Image();
img.src = `chrome-extension://${info.id}/${info.path}`;
img.onload = function() {
resolve(true);
};
img.onerror = function() {
resolve(false);
};
});
const extensionInstalledFunction = info => isExtensionInstalled(info);
return Promise.all(
(config.chromeExtensionsInfo || []).map(info => extensionInstalledFunction(info))
);
}

View File

@@ -1 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><path id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path clip-path="url(#b)" d="M20 9H4v2h16V9zM4 15h16v-2H4v2z"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="24"
height="24"
viewBox="0 0 24 24">
<path
d="m 5.6875,10.59375 h 12.625 c 0.779062,0 1.40625,0.627187 1.40625,1.40625 0,0.779062 -0.627188,1.40625 -1.40625,1.40625 H 5.6875 c -0.7790625,0 -1.40625,-0.627188 -1.40625,-1.40625 0,-0.779063 0.6271875,-1.40625 1.40625,-1.40625 z"
id="rect3711" />
</svg>

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 474 B

View File

@@ -44,6 +44,8 @@ export { default as IconMessage } from './message.svg';
export { default as IconMicDisabled } from './mic-disabled.svg';
export { default as IconMicrophone } from './microphone.svg';
export { default as IconModerator } from './star.svg';
export { default as IconMuteEveryone } from './mute-everyone.svg';
export { default as IconMuteEveryoneElse } from './mute-everyone-else.svg';
export { default as IconNotificationJoin } from './navigate_next.svg';
export { default as IconOpenInNew } from './open_in_new.svg';
export { default as IconPhone } from './phone.svg';

View File

@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 13.078V15C6 16.3999 6.9589 17.5759 8.25572 17.907C8.25195 17.9374 8.25 17.9685 8.25 18V19.4378C6.12171 19.0807 4.5 17.2297 4.5 15C4.5 14.5858 4.16421 14.25 3.75 14.25C3.33579 14.25 3 14.5858 3 15C3 18.0597 5.29027 20.5845 8.25 20.9536V21.75C8.25 22.1642 8.58579 22.5 9 22.5C9.41421 22.5 9.75 22.1642 9.75 21.75V20.9536C10.8412 20.8175 11.8415 20.3884 12.6694 19.7475L15.1986 22.2766C15.4964 22.5744 15.9791 22.5745 16.2768 22.2768C16.5745 21.9791 16.5744 21.4964 16.2766 21.1986L13.7475 18.6694C13.7502 18.6659 13.753 18.6623 13.7557 18.6588L12.6831 17.5861C12.6805 17.5898 12.6779 17.5935 12.6753 17.5972L11.5911 16.513C11.5934 16.5091 11.5957 16.5051 11.598 16.5011L10.4566 15.3596C10.4554 15.3647 10.4541 15.3697 10.4528 15.3748L7.5 12.422V12.403L6 10.903V10.922L2.80143 7.72339C2.50364 7.4256 2.02091 7.42553 1.72322 7.72322C1.42553 8.02091 1.4256 8.50364 1.72339 8.80143L6 13.078ZM7.5 14.578V15C7.5 15.8284 8.17157 16.5 9 16.5C9.1294 16.5 9.25498 16.4836 9.37476 16.4528L7.5 14.578ZM10.513 17.5911C10.2756 17.73 10.0175 17.8372 9.74428 17.907C9.74805 17.9374 9.75 17.9685 9.75 18V19.4378C10.4295 19.3238 11.0573 19.0575 11.5972 18.6753L10.513 17.5911ZM12 14.747L10.5 13.247V10.5C10.5 9.67157 9.82843 9 9 9C8.25144 9 7.63095 9.54832 7.51827 10.2652L6.34845 9.09541C6.85223 8.14635 7.85064 7.5 9 7.5C10.6569 7.5 12 8.84315 12 10.5V14.747ZM13.3623 16.1092L14.5462 17.2932C14.8386 16.5867 15 15.8122 15 15C15 14.5858 14.6642 14.25 14.25 14.25C13.8358 14.25 13.5 14.5858 13.5 15C13.5 15.3828 13.4522 15.7544 13.3623 16.1092Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.71869V6C16 6.93329 16.6393 7.71727 17.5038 7.93797C17.5013 7.95829 17.5 7.97899 17.5 8V8.95852C16.0811 8.72048 15 7.4865 15 6C15 5.72386 14.7761 5.5 14.5 5.5C14.2239 5.5 14 5.72386 14 6C14 8.03981 15.5268 9.723 17.5 9.96905V10.5C17.5 10.7761 17.7239 11 18 11C18.2761 11 18.5 10.7761 18.5 10.5V9.96905C19.2275 9.87834 19.8943 9.59227 20.4463 9.16499L22.1324 10.8511C22.3309 11.0496 22.6527 11.0496 22.8512 10.8512C23.0496 10.6527 23.0496 10.3309 22.8511 10.1324L21.165 8.4463C21.1668 8.44393 21.1687 8.44155 21.1705 8.43918L20.4554 7.7241C20.4537 7.72656 20.4519 7.72903 20.4502 7.73149L19.7274 7.00869C19.7289 7.00603 19.7305 7.00338 19.732 7.00072L18.9711 6.23977C18.9702 6.24313 18.9694 6.24649 18.9685 6.24984L17 4.28131V4.26869L16 3.26869V3.28131L13.8676 1.14893C13.6691 0.950402 13.3473 0.950351 13.1488 1.14881C12.9504 1.34727 12.9504 1.6691 13.1489 1.86762L16 4.71869ZM17 5.71869V6C17 6.55228 17.4477 7 18 7C18.0863 7 18.17 6.98908 18.2498 6.96854L17 5.71869ZM19.0087 7.72738C18.8504 7.81999 18.6783 7.89148 18.4962 7.93797C18.4987 7.95829 18.5 7.97899 18.5 8V8.95852C18.953 8.88252 19.3715 8.70502 19.7315 8.45019L19.0087 7.72738ZM20 5.83131L19 4.83131V3C19 2.44772 18.5523 2 18 2C17.501 2 17.0873 2.36555 17.0122 2.84348L16.2323 2.06361C16.5682 1.4309 17.2338 1 18 1C19.1046 1 20 1.89543 20 3V5.83131ZM20.9082 6.73948L21.6975 7.52877C21.8924 7.05778 22 6.54145 22 6C22 5.72386 21.7761 5.5 21.5 5.5C21.2239 5.5 21 5.72386 21 6C21 6.25519 20.9681 6.50294 20.9082 6.73948Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 13.078V15C6 16.3999 6.9589 17.5759 8.25572 17.907C8.25195 17.9374 8.25 17.9685 8.25 18V19.4378C6.12171 19.0807 4.5 17.2297 4.5 15C4.5 14.5858 4.16421 14.25 3.75 14.25C3.33579 14.25 3 14.5858 3 15C3 18.0597 5.29027 20.5845 8.25 20.9536V21.75C8.25 22.1642 8.58579 22.5 9 22.5C9.41421 22.5 9.75 22.1642 9.75 21.75V20.9536C10.8412 20.8175 11.8415 20.3884 12.6694 19.7475L15.1986 22.2766C15.4964 22.5744 15.9791 22.5745 16.2768 22.2768C16.5745 21.9791 16.5744 21.4964 16.2766 21.1986L13.7475 18.6694C13.7502 18.6659 13.753 18.6623 13.7557 18.6588L12.6831 17.5861C12.6805 17.5898 12.6779 17.5935 12.6753 17.5972L11.5911 16.513C11.5934 16.5091 11.5957 16.5051 11.598 16.5011L10.4566 15.3596C10.4554 15.3647 10.4541 15.3697 10.4528 15.3748L7.5 12.422V12.403L6 10.903V10.922L2.80143 7.72339C2.50364 7.4256 2.02091 7.42553 1.72322 7.72322C1.42553 8.02091 1.4256 8.50364 1.72339 8.80143L6 13.078ZM7.5 14.578V15C7.5 15.8284 8.17157 16.5 9 16.5C9.1294 16.5 9.25498 16.4836 9.37476 16.4528L7.5 14.578ZM10.513 17.5911C10.2756 17.73 10.0175 17.8372 9.74428 17.907C9.74805 17.9374 9.75 17.9685 9.75 18V19.4378C10.4295 19.3238 11.0573 19.0575 11.5972 18.6753L10.513 17.5911ZM12 14.747L10.5 13.247V10.5C10.5 9.67157 9.82843 9 9 9C8.25144 9 7.63095 9.54832 7.51827 10.2652L6.34845 9.09541C6.85223 8.14635 7.85064 7.5 9 7.5C10.6569 7.5 12 8.84315 12 10.5V14.747ZM13.3623 16.1092L14.5462 17.2932C14.8386 16.5867 15 15.8122 15 15C15 14.5858 14.6642 14.25 14.25 14.25C13.8358 14.25 13.5 14.5858 13.5 15C13.5 15.3828 13.4522 15.7544 13.3623 16.1092Z" fill="#A4B8D1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.71869V6C16 6.93329 16.6393 7.71727 17.5038 7.93797C17.5013 7.95829 17.5 7.97899 17.5 8V8.95852C16.0811 8.72048 15 7.4865 15 6C15 5.72386 14.7761 5.5 14.5 5.5C14.2239 5.5 14 5.72386 14 6C14 8.03981 15.5268 9.723 17.5 9.96905V10.5C17.5 10.7761 17.7239 11 18 11C18.2761 11 18.5 10.7761 18.5 10.5V9.96905C19.2275 9.87834 19.8943 9.59227 20.4463 9.16499L22.1324 10.8511C22.3309 11.0496 22.6527 11.0496 22.8512 10.8512C23.0496 10.6527 23.0496 10.3309 22.8511 10.1324L21.165 8.4463C21.1668 8.44393 21.1687 8.44155 21.1705 8.43918L20.4554 7.7241C20.4537 7.72656 20.4519 7.72903 20.4502 7.73149L19.7274 7.00869C19.7289 7.00603 19.7305 7.00338 19.732 7.00072L18.9711 6.23977C18.9702 6.24313 18.9694 6.24649 18.9685 6.24984L17 4.28131V4.26869L16 3.26869V3.28131L13.8676 1.14893C13.6691 0.950402 13.3473 0.950351 13.1488 1.14881C12.9504 1.34727 12.9504 1.6691 13.1489 1.86762L16 4.71869ZM17 5.71869V6C17 6.55228 17.4477 7 18 7C18.0863 7 18.17 6.98908 18.2498 6.96854L17 5.71869ZM19.0087 7.72738C18.8504 7.81999 18.6783 7.89148 18.4962 7.93797C18.4987 7.95829 18.5 7.97899 18.5 8V8.95852C18.953 8.88252 19.3715 8.70502 19.7315 8.45019L19.0087 7.72738ZM20 5.83131L19 4.83131V3C19 2.44772 18.5523 2 18 2C17.501 2 17.0873 2.36555 17.0122 2.84348L16.2323 2.06361C16.5682 1.4309 17.2338 1 18 1C19.1046 1 20 1.89543 20 3V5.83131ZM20.9082 6.73948L21.6975 7.52877C21.8924 7.05778 22 6.54145 22 6C22 5.72386 21.7761 5.5 21.5 5.5C21.2239 5.5 21 5.72386 21 6C21 6.25519 20.9681 6.50294 20.9082 6.73948Z" fill="#A4B8D1"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -27,8 +27,8 @@ export async function createLocalPresenterTrack(options, desktopHeight) {
// compute the constraints of the camera track based on the resolution
// of the desktop screen that is being shared.
const cameraHeights = [ 120, 180, 240, 360, 480, 600, 720 ];
const proportion = 4;
const cameraHeights = [ 180, 270, 360, 540, 720 ];
const proportion = 5;
const result = cameraHeights.find(
height => (desktopHeight / proportion) < height);
const constraints = {

View File

@@ -1,13 +1,9 @@
// @flow
import { ReducerRegistry } from '../base/redux';
import { PersistenceRegistry } from '../base/storage';
import { BLUR_ENABLED, BLUR_DISABLED } from './actionTypes';
PersistenceRegistry.register('features/blur', true, {
blurEnabled: false
});
ReducerRegistry.register('features/blur', (state = {}, action) => {

View File

@@ -46,8 +46,7 @@ export function bootstrapCalendarIntegration(): Function {
return Promise.resolve()
.then(() => {
if (googleApiApplicationClientID) {
return dispatch(
loadGoogleAPI(googleApiApplicationClientID));
return dispatch(loadGoogleAPI());
}
})
.then(() => {

View File

@@ -43,12 +43,7 @@ export const googleCalendarApi = {
* @returns {function(Dispatch<any>, Function): Promise<void>}
*/
load() {
return (dispatch: Dispatch<any>, getState: Function) => {
const { googleApiApplicationClientID }
= getState()['features/base/config'];
return dispatch(loadGoogleAPI(googleApiApplicationClientID));
};
return (dispatch: Dispatch<any>) => dispatch(loadGoogleAPI());
},
/**

View File

@@ -5,11 +5,20 @@ import { Icon, IconClose } from '../../base/icons';
import { translate } from '../../base/i18n';
import { getCurrentConference } from '../../base/conference/functions';
import { browser } from '../../base/lib-jitsi-meet';
import { isMobileBrowser } from '../../base/environment/utils';
import {
checkChromeExtensionsInstalled,
isMobileBrowser
} from '../../base/environment/utils';
import logger from '../logger';
import {
createChromeExtensionBannerEvent,
sendAnalytics
} from '../../analytics';
declare var interfaceConfig: Object;
const emptyObject = {};
/**
* Local storage key name for flag telling if user checked 'Don't show again' checkbox on the banner
* If the user checks this before closing the banner, next time he will access a jitsi domain
@@ -22,21 +31,16 @@ const DONT_SHOW_AGAIN_CHECKED = 'hide_chrome_extension_banner';
*/
type Props = {
/**
* Contains info about installed/to be installed chrome extension(s).
*/
bannerCfg: Object,
/**
* Conference data, if any
*/
conference: Object,
/**
* The url of the chrome extension
*/
chromeExtensionUrl: string,
/**
* An array containing info for identifying a chrome extension
*/
chromeExtensionsInfo: Array<Object>,
/**
* Whether I am the current recorder.
*/
@@ -91,7 +95,6 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
this._onClosePressed = this._onClosePressed.bind(this);
this._onInstallExtensionClick = this._onInstallExtensionClick.bind(this);
this._checkExtensionsInstalled = this._checkExtensionsInstalled.bind(this);
this._shouldNotRender = this._shouldNotRender.bind(this);
this._onDontShowAgainChange = this._onDontShowAgainChange.bind(this);
}
@@ -102,12 +105,23 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
*
* @inheritdoc
*/
async componentDidUpdate() {
async componentDidUpdate(prevProps) {
if (!this._isSupportedEnvironment()) {
return;
}
const hasExtensions = await this._checkExtensionsInstalled();
const { bannerCfg } = this.props;
const prevBannerCfg = prevProps.bannerCfg;
if (bannerCfg.url && !prevBannerCfg.url) {
logger.info('Chrome extension URL found.');
}
if ((bannerCfg.chromeExtensionsInfo || []).length && !(prevBannerCfg.chromeExtensionsInfo || []).length) {
logger.info('Chrome extension(s) info found.');
}
const hasExtensions = await checkChromeExtensionsInstalled(this.props.bannerCfg);
if (
hasExtensions
@@ -139,6 +153,7 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
* @returns {void}
*/
_onClosePressed() {
sendAnalytics(createChromeExtensionBannerEvent(false));
this.setState({ closePressed: true });
}
@@ -150,40 +165,11 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
* @returns {void}
*/
_onInstallExtensionClick() {
window.open(this.props.chromeExtensionUrl);
sendAnalytics(createChromeExtensionBannerEvent(true));
window.open(this.props.bannerCfg.url);
this.setState({ closePressed: true });
}
_checkExtensionsInstalled: () => Promise<*>;
/**
* Checks whether the chrome extensions defined in the config file are installed or not.
*
* @returns {Promise[]}
*/
_checkExtensionsInstalled() {
const isExtensionInstalled = info => new Promise(resolve => {
const img = new Image();
img.src = `chrome-extension://${info.id}/${info.path}`;
img.onload = function() {
resolve(true);
};
img.onerror = function() {
resolve(false);
};
});
const extensionInstalledFunction = info => isExtensionInstalled(info);
if (!this.props.chromeExtensionsInfo.length) {
logger.warn('Further configuration needed, missing chrome extension(s) info');
}
return Promise.all(
this.props.chromeExtensionsInfo.map(info => extensionInstalledFunction(info))
);
}
_shouldNotRender: () => boolean;
/**
@@ -196,15 +182,10 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
return true;
}
if (!this.props.chromeExtensionUrl) {
logger.warn('Further configuration needed, missing chrome extension URL');
return true;
}
const dontShowAgain = localStorage.getItem(DONT_SHOW_AGAIN_CHECKED) === 'true';
return dontShowAgain
return !this.props.bannerCfg.url
|| dontShowAgain
|| this.state.closePressed
|| !this.state.shouldShow
|| this.props.iAmRecorder;
@@ -291,11 +272,9 @@ class ChromeExtensionBanner extends PureComponent<Props, State> {
* @returns {Object}
*/
const _mapStateToProps = state => {
const bannerCfg = state['features/base/config'].chromeExtensionBanner || {};
return {
chromeExtensionUrl: bannerCfg.url,
chromeExtensionsInfo: bannerCfg.chromeExtensionsInfo || [],
// Using emptyObject so that we don't change the reference every time when _mapStateToProps is called.
bannerCfg: state['features/base/config'].chromeExtensionBanner || emptyObject,
conference: getCurrentConference(state),
iAmRecorder: state['features/base/config'].iAmRecorder
};

View File

@@ -34,6 +34,7 @@ import {
abstractMapStateToProps
} from '../AbstractConference';
import Labels from './Labels';
import LonelyMeetingExperience from './LonelyMeetingExperience';
import NavigationBar from './NavigationBar';
import styles, { NAVBAR_GRADIENT_COLORS } from './styles';
@@ -305,6 +306,8 @@ class Conference extends AbstractConference<Props, *> {
{ _shouldDisplayTileView || <DisplayNameLabel participantId = { _largeVideoParticipantId } /> }
<LonelyMeetingExperience />
{/*
* The Toolbox is in a stacking layer below the Filmstrip.
*/}

View File

@@ -0,0 +1,126 @@
// @flow
import React, { PureComponent } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { ColorSchemeRegistry } from '../../../base/color-scheme';
import { connect } from '../../../base/redux';
import { StyleType } from '../../../base/styles';
import { translate } from '../../../base/i18n';
import { getParticipantCount } from '../../../base/participants';
import { doInvitePeople } from '../../../invite/actions.native';
import styles from './styles';
import { Icon, IconAddPeople } from '../../../base/icons';
/**
* Props type of the component.
*/
type Props = {
/**
* True if it's a lonely meeting (participant count excluding fakes is 1).
*/
_isLonelyMeeting: boolean,
/**
* Color schemed styles of the component.
*/
_styles: StyleType,
/**
* The Redux Dispatch function.
*/
dispatch: Function,
/**
* Function to be used to translate i18n labels.
*/
t: Function
};
/**
* Implements the UI elements to be displayed in the lonely meeting experience.
*/
class LonelyMeetingExperience extends PureComponent<Props> {
/**
* Instantiates a new component.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this._onPress = this._onPress.bind(this);
}
/**
* Implements {@code PureComponent#render}.
*
* @inheritdoc
*/
render() {
const { _isLonelyMeeting, _styles, t } = this.props;
if (!_isLonelyMeeting) {
return null;
}
return (
<View style = { styles.lonelyMeetingContainer }>
<Text
style = { [
styles.lonelyMessage,
_styles.lonelyMessage
] }>
{ t('lonelyMeetingExperience.youAreAlone') }
</Text>
<TouchableOpacity
onPress = { this._onPress }
style = { [
styles.lonelyButton,
_styles.lonelyButton
] }>
<Icon
size = { 24 }
src = { IconAddPeople }
style = { styles.lonelyButtonComponents } />
<Text
style = { [
styles.lonelyButtonComponents,
_styles.lonelyMessage
] }>
{ t('lonelyMeetingExperience.button') }
</Text>
</TouchableOpacity>
</View>
);
}
_onPress: () => void;
/**
* Callback for the onPress function of the button.
*
* @returns {void}
*/
_onPress() {
this.props.dispatch(doInvitePeople());
}
}
/**
* Maps parts of the Redux state to the props of this Component.
*
* @param {Object} state - The redux state.
* @private
* @returns {Props}
*/
function _mapStateToProps(state): $Shape<Props> {
return {
_isLonelyMeeting: getParticipantCount(state) === 1,
_styles: ColorSchemeRegistry.get(state, 'Conference')
};
}
export default connect(_mapStateToProps)(translate(LonelyMeetingExperience));

View File

@@ -1,5 +1,5 @@
import { BoxModel, ColorPalette, fixAndroidViewClipping } from '../../../base/styles';
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
import { FILMSTRIP_SIZE } from '../../../filmstrip';
export const NAVBAR_GRADIENT_COLORS = [ '#000000FF', '#00000000' ];
@@ -72,6 +72,29 @@ export default {
top: 0
},
lonelyButton: {
alignItems: 'center',
borderRadius: 24,
flexDirection: 'row',
height: 48,
justifyContent: 'space-around',
paddingHorizontal: 12
},
lonelyButtonComponents: {
marginHorizontal: 6
},
lonelyMeetingContainer: {
alignSelf: 'stretch',
alignItems: 'center',
padding: BoxModel.padding * 2
},
lonelyMessage: {
paddingVertical: 12
},
navBarButton: {
iconStyle: {
color: ColorPalette.white,
@@ -146,3 +169,13 @@ export default {
top: BoxModel.margin * 3
}
};
ColorSchemeRegistry.register('Conference', {
lonelyButton: {
backgroundColor: schemeColor('inviteButtonBackground')
},
lonelyMessage: {
color: schemeColor('onVideoText')
}
});

View File

@@ -54,6 +54,7 @@ export function maybeOpenFeedbackDialog(conference: Object) {
return (dispatch: Dispatch<any>, getState: Function): Promise<R> => {
const state = getState();
const { feedbackPercentage = 100 } = state['features/base/config'];
if (interfaceConfig.filmStripOnly || config.iAmRecorder) {
// Intentionally fall through the if chain to prevent further action
@@ -69,7 +70,7 @@ export function maybeOpenFeedbackDialog(conference: Object) {
feedbackSubmitted: true,
showThankYou: true
});
} else if (conference.isCallstatsEnabled()) {
} else if (conference.isCallstatsEnabled() && feedbackPercentage > Math.random() * 100) {
return new Promise(resolve => {
dispatch(openFeedbackDialog(conference, () => {
const { submitted } = getState()['features/feedback'];

View File

@@ -53,6 +53,16 @@ type Props = {
*/
_filmstripWidth: number,
/**
* Whether the filmstrip scrollbar should be hidden or not.
*/
_hideScrollbar: boolean,
/**
* Whether the filmstrip toolbar should be hidden or not.
*/
_hideToolbar: boolean,
/**
* Whether or not remote videos are currently being hovered over. Hover
* handling is currently being handled detected outside of react.
@@ -161,14 +171,15 @@ class Filmstrip extends Component <Props> {
// will get updated without replacing the DOM. If the known DOM gets
// modified, then the views will get blown away.
const remoteVideosStyle = { };
const filmstripStyle = { };
const filmstripRemoteVideosContainerStyle = {};
let remoteVideoContainerClassName = 'remote-videos-container';
switch (this.props._currentLayout) {
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW:
// Adding 8px for the 2px margins and 2px borders on the left and right. Also adding 7px for the scrollbar.
remoteVideosStyle.maxWidth = (interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120) + 15;
// Adding 18px for the 2px margins, 2px borders on the left and right and 5px padding on the left and right.
// Also adding 7px for the scrollbar.
filmstripStyle.maxWidth = (interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120) + 25;
break;
case LAYOUTS.TILE_VIEW: {
// The size of the side margins for each tile as set in CSS.
@@ -183,14 +194,26 @@ class Filmstrip extends Component <Props> {
}
}
let remoteVideosWrapperClassName = 'filmstrip__videos';
if (this.props._hideScrollbar) {
remoteVideosWrapperClassName += ' hide-scrollbar';
}
let toolbar = null;
if (!this.props._hideToolbar) {
toolbar = this.props._filmstripOnly ? <Toolbar /> : this._renderToggleButton();
}
return (
<div className = { `filmstrip ${this.props._className}` }>
{ this.props._filmstripOnly
? <Toolbar /> : this._renderToggleButton() }
<div
className = { `filmstrip ${this.props._className}` }
style = { filmstripStyle }>
{ toolbar }
<div
className = { this.props._videosClassName }
id = 'remoteVideos'
style = { remoteVideosStyle }>
id = 'remoteVideos'>
<div
className = 'filmstrip__videos'
id = 'filmstripLocalVideo'
@@ -199,7 +222,7 @@ class Filmstrip extends Component <Props> {
<div id = 'filmstripLocalVideoThumbnail' />
</div>
<div
className = 'filmstrip__videos'
className = { remoteVideosWrapperClassName }
id = 'filmstripRemoteVideos'>
{/*
* XXX This extra video container is needed for
@@ -333,15 +356,10 @@ class Filmstrip extends Component <Props> {
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _className: string,
* _filmstripOnly: boolean,
* _hovered: boolean,
* _videosClassName: string,
* _visible: boolean
* }}
* @returns {Props}
*/
function _mapStateToProps(state) {
const { iAmSipGateway } = state['features/base/config'];
const { hovered, visible } = state['features/filmstrip'];
const isFilmstripOnly = Boolean(interfaceConfig.filmStripOnly);
const reduceHeight
@@ -360,6 +378,8 @@ function _mapStateToProps(state) {
_currentLayout: getCurrentLayout(state),
_filmstripOnly: isFilmstripOnly,
_filmstripWidth: filmstripWidth,
_hideScrollbar: Boolean(iAmSipGateway),
_hideToolbar: Boolean(iAmSipGateway),
_hovered: hovered,
_rows: gridDimensions.rows,
_videosClassName: videosClassName,

View File

@@ -0,0 +1,112 @@
/* @flow */
import React, { Component } from 'react';
import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
import { connect } from '../../../base/redux';
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
import AudioMutedIndicator from './AudioMutedIndicator';
import ModeratorIndicator from './ModeratorIndicator';
import VideoMutedIndicator from './VideoMutedIndicator';
declare var interfaceConfig: Object;
/**
* The type of the React {@code Component} props of {@link StatusIndicators}.
*/
type Props = {
/**
* The current layout of the filmstrip.
*/
_currentLayout: string,
/**
* Indicates if the moderator indicator should be visible or not.
*/
_showModeratorIndicator: Boolean,
/**
* Indicates if the audio muted indicator should be visible or not.
*/
showAudioMutedIndicator: Boolean,
/**
* Indicates if the video muted indicator should be visible or not.
*/
showVideoMutedIndicator: Boolean,
/**
* The ID of the participant for which the status bar is rendered.
*/
participantID: String
};
/**
* React {@code Component} for showing the status bar in a thumbnail.
*
* @extends Component
*/
class StatusIndicators extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const {
_currentLayout,
_showModeratorIndicator,
showAudioMutedIndicator,
showVideoMutedIndicator
} = this.props;
let tooltipPosition;
switch (_currentLayout) {
case LAYOUTS.TILE_VIEW:
tooltipPosition = 'right';
break;
case LAYOUTS.VERTICAL_FILMSTRIP_VIEW:
tooltipPosition = 'left';
break;
default:
tooltipPosition = 'top';
}
return (
<div>
{ showAudioMutedIndicator ? <AudioMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
{ showVideoMutedIndicator ? <VideoMutedIndicator tooltipPosition = { tooltipPosition } /> : null }
{ _showModeratorIndicator ? <ModeratorIndicator tooltipPosition = { tooltipPosition } /> : null }
</div>
);
}
}
/**
* Maps (parts of) the Redux state to the associated {@code StatusIndicators}'s props.
*
* @param {Object} state - The Redux state.
* @param {Object} ownProps - The own props of the component.
* @private
* @returns {{
* _currentLayout: string,
* _showModeratorIndicator: boolean
* }}
*/
function _mapStateToProps(state, ownProps) {
const { participantID } = ownProps;
// Only the local participant won't have id for the time when the conference is not yet joined.
const participant = participantID ? getParticipantById(state, participantID) : getLocalParticipant(state);
return {
_currentLayout: getCurrentLayout(state),
_showModeratorIndicator:
!interfaceConfig.DISABLE_FOCUS_INDICATOR && participant && participant.role === PARTICIPANT_ROLE.MODERATOR
};
}
export default connect(_mapStateToProps)(StatusIndicators);

View File

@@ -2,7 +2,7 @@
import React, { Component } from 'react';
import { connect } from '../../../base/redux';
import { connect, equals } from '../../../base/redux';
import { SettingsButton } from '../../../settings';
import {
AudioMuteButton,
@@ -12,6 +12,10 @@ import {
declare var interfaceConfig: Object;
// XXX: We are not currently using state here, but in the future, when
// interfaceConfig is part of redux we will. This has to be retrieved from the store.
const visibleButtons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
/**
* The type of the React {@code Component} props of {@link Toolbar}.
*/
@@ -84,9 +88,13 @@ class Toolbar extends Component<Props> {
function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
// XXX: We are not currently using state here, but in the future, when
// interfaceConfig is part of redux we will.
//
// NB: We compute the buttons again here because if URL parameters were used to
// override them we'd miss it.
const buttons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
return {
_visibleButtons: new Set(interfaceConfig.TOOLBAR_BUTTONS)
_visibleButtons: equals(visibleButtons, buttons) ? visibleButtons : buttons
};
}

View File

@@ -1,9 +1,9 @@
// @flow
export { default as AudioMutedIndicator } from './AudioMutedIndicator';
export { default as DominantSpeakerIndicator }
from './DominantSpeakerIndicator';
export { default as DominantSpeakerIndicator } from './DominantSpeakerIndicator';
export { default as Filmstrip } from './Filmstrip';
export { default as ModeratorIndicator } from './ModeratorIndicator';
export { default as RaisedHandIndicator } from './RaisedHandIndicator';
export { default as StatusIndicators } from './StatusIndicators';
export { default as VideoMutedIndicator } from './VideoMutedIndicator';

View File

@@ -116,3 +116,20 @@ export function calculateThumbnailSizeForTileView({
width
};
}
/**
* Returns the width of the visible area (doesn't include the left margin/padding) of the the vertical filmstrip.
*
* @returns {number} - The width of the vertical filmstrip.
*/
export function getVerticalFilmstripVisibleAreaWidth() {
// Adding 11px for the 2px right margin, 2px borders on the left and right and 5px right padding.
// Also adding 7px for the scrollbar. Note that we are not counting the left margins and paddings because this
// function is used for calculating the available space and they are invisible.
// TODO: Check if we can remove the left margins and paddings from the CSS.
// FIXME: This function is used to calculate the size of the large video, etherpad or shared video. Once everything
// is reactified this calculation will need to move to the corresponding components.
const filmstripMaxWidth = (interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120) + 18;
return Math.min(filmstripMaxWidth, window.innerWidth);
}

View File

@@ -15,7 +15,7 @@ StateListenerRegistry.register(
const state = store.getState();
if (shouldDisplayTileView(state)) {
const gridDimensions = getTileViewGridDimensions(state['features/base/participants'].length);
const gridDimensions = getTileViewGridDimensions(state);
const oldGridDimensions = state['features/filmstrip'].tileViewDimensions.gridDimensions;
const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
@@ -41,7 +41,7 @@ StateListenerRegistry.register(
const { clientHeight, clientWidth } = state['features/base/responsive-ui'];
store.dispatch(setTileViewDimensions(
getTileViewGridDimensions(state['features/base/participants'].length), {
getTileViewGridDimensions(state), {
clientHeight,
clientWidth
}));

View File

@@ -29,16 +29,22 @@ export function getCalendarEntries(
/**
* Loads Google API.
*
* @param {string} clientId - The client ID to be used with the API library.
* @returns {Function}
*/
export function loadGoogleAPI(clientId: string) {
export function loadGoogleAPI() {
return (dispatch: Dispatch<any>, getState: Function) =>
googleApi.get()
.then(() => {
const {
liveStreamingEnabled,
enableCalendarIntegration,
googleApiApplicationClientID
} = getState()['features/base/config'];
if (getState()['features/google-api'].googleAPIState
=== GOOGLE_API_STATES.NEEDS_LOADING) {
return googleApi.initializeClient(clientId);
return googleApi.initializeClient(
googleApiApplicationClientID, liveStreamingEnabled, enableCalendarIntegration);
}
return Promise.resolve();

View File

@@ -61,11 +61,17 @@ const googleApi = {
* making Google API requests.
*
* @param {string} clientId - The client ID to be used with the API library.
* @param {boolean} enableYoutube - Whether youtube scope is enabled.
* @param {boolean} enableCalendar - Whether calendar scope is enabled.
* @returns {Promise}
*/
initializeClient(clientId) {
initializeClient(clientId, enableYoutube, enableCalendar) {
return this.get()
.then(api => new Promise((resolve, reject) => {
const scope
= `${enableYoutube ? GOOGLE_SCOPE_YOUTUBE : ''} ${enableCalendar ? GOOGLE_SCOPE_CALENDAR : ''}`
.trim();
// setTimeout is used as a workaround for api.client.init not
// resolving consistently when the Google API Client Library is
// loaded asynchronously. See:
@@ -74,10 +80,7 @@ const googleApi = {
api.client.init({
clientId,
discoveryDocs: DISCOVERY_DOCS,
scope: [
GOOGLE_SCOPE_CALENDAR,
GOOGLE_SCOPE_YOUTUBE
].join(' ')
scope
})
.then(resolve)
.catch(reject);

View File

@@ -0,0 +1,31 @@
// @flow
import type { Dispatch } from 'redux';
import { getFeatureFlag, INVITE_ENABLED } from '../base/flags';
import { beginShareRoom } from '../share-room';
import { setAddPeopleDialogVisible } from './actions.any';
import { isAddPeopleEnabled, isDialOutEnabled } from './functions';
export * from './actions.any';
/**
* Starts the process for inviting people. Dpending on the sysstem config it
* may use the system share sheet or the invite peoplee dialog.
*
* @returns {Function}
*/
export function doInvitePeople() {
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
const addPeopleEnabled = getFeatureFlag(state, INVITE_ENABLED, true)
&& (isAddPeopleEnabled(state) || isDialOutEnabled(state));
if (addPeopleEnabled) {
return dispatch(setAddPeopleDialogVisible(true));
}
return dispatch(beginShareRoom());
};
}

View File

@@ -0,0 +1 @@
export * from './actions.any';

View File

@@ -24,7 +24,7 @@ import {
} from '../../../../base/react';
import { connect } from '../../../../base/redux';
import { setAddPeopleDialogVisible } from '../../../actions';
import { setAddPeopleDialogVisible } from '../../../actions.native';
import AbstractAddPeopleDialog, {
type Props as AbstractProps,

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