mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-30 08:17:45 +00:00
Compare commits
18 Commits
6065
...
saghul-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
624b650138 | ||
|
|
8bf42e79a0 | ||
|
|
930852cd88 | ||
|
|
fcc8e98aad | ||
|
|
c633929c58 | ||
|
|
6085220bfc | ||
|
|
ed6759c6cf | ||
|
|
0259d1c260 | ||
|
|
537d3ae53a | ||
|
|
bf463e37ca | ||
|
|
c246174555 | ||
|
|
0cf1b7e3d9 | ||
|
|
41d8b9fbeb | ||
|
|
cc5f65f58f | ||
|
|
3097ac8cc4 | ||
|
|
d78b591e68 | ||
|
|
7c523f3250 | ||
|
|
23b91c0336 |
@@ -16,4 +16,4 @@ react/features/face-landmarks/resources/*
|
||||
!.eslintrc.js
|
||||
|
||||
# Not worth it.
|
||||
actionTypes.js
|
||||
actionTypes.ts
|
||||
|
||||
@@ -3,8 +3,8 @@ We would love to have your help. Before you start working however, please read
|
||||
and follow this short guide.
|
||||
|
||||
# Reporting Issues
|
||||
Provide as much information as possible. Mention the version of Jitsi Meet,
|
||||
Jicofo and JVB you are using, and explain (as detailed as you can) how the
|
||||
Provide as much information as possible. Mention the version of Jitsi Meet,
|
||||
Jicofo and JVB you are using, and explain (as detailed as you can) how the
|
||||
problem can be reproduced.
|
||||
|
||||
# Code contributions
|
||||
@@ -130,7 +130,7 @@ When adding a new feature, this would be the usual layout.
|
||||
|
||||
```
|
||||
react/features/sample/
|
||||
├── actionTypes.js
|
||||
├── actionTypes.ts
|
||||
├── actions.js
|
||||
├── components
|
||||
│ ├── AnotherComponent.js
|
||||
|
||||
@@ -51,11 +51,20 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
intent.setAction(Action.START.getName());
|
||||
|
||||
ComponentName componentName;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
componentName = context.startForegroundService(intent);
|
||||
} else {
|
||||
componentName = context.startService(intent);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
componentName = context.startForegroundService(intent);
|
||||
} else {
|
||||
componentName = context.startService(intent);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
// Avoid crashing due to ForegroundServiceStartNotAllowedException (API level 31).
|
||||
// See: https://developer.android.com/guide/components/foreground-services#background-start-restrictions
|
||||
JitsiMeetLogger.w(TAG + " Ongoing conference service not started", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (componentName == null) {
|
||||
JitsiMeetLogger.w(TAG + " Ongoing conference service not started");
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ import {
|
||||
} from './react/features/base/devices';
|
||||
import {
|
||||
browser,
|
||||
isFatalJitsiConnectionError,
|
||||
JitsiConferenceErrors,
|
||||
JitsiConferenceEvents,
|
||||
JitsiConnectionErrors,
|
||||
@@ -77,6 +76,7 @@ import {
|
||||
JitsiTrackErrors,
|
||||
JitsiTrackEvents
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import {
|
||||
getStartWithAudioMuted,
|
||||
getStartWithVideoMuted,
|
||||
|
||||
@@ -13,10 +13,10 @@ import {
|
||||
import { openDialog } from './react/features/base/dialog/actions';
|
||||
import { setJWT } from './react/features/base/jwt';
|
||||
import {
|
||||
isFatalJitsiConnectionError,
|
||||
JitsiConnectionErrors,
|
||||
JitsiConnectionEvents
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import { getCustomerDetails } from './react/features/jaas/actions.any';
|
||||
import { isVpaasMeeting, getJaasJWT } from './react/features/jaas/functions';
|
||||
import { setPrejoinDisplayNameRequired } from './react/features/prejoin/actions';
|
||||
|
||||
@@ -421,7 +421,7 @@ PODS:
|
||||
- React-Core
|
||||
- RNCMaskedView (0.2.6):
|
||||
- React-Core
|
||||
- RNDefaultPreference (1.4.3):
|
||||
- RNDefaultPreference (1.4.4):
|
||||
- React-Core
|
||||
- RNDeviceInfo (8.4.8):
|
||||
- React-Core
|
||||
@@ -723,7 +723,7 @@ SPEC CHECKSUMS:
|
||||
RNCAsyncStorage: ea6b5c280997b2b32a587793163b1f10e580c4f7
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
|
||||
RNDefaultPreference: 326860d42a681bfd7338c8f6d061cf58745bd860
|
||||
RNDefaultPreference: 08bdb06cfa9188d5da97d4642dac745218d7fb31
|
||||
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
|
||||
RNGestureHandler: e5c7cab5f214503dcefd6b2b0cefb050e1f51c4a
|
||||
RNGoogleSignin: c4381751eefd73c552b923ba347a9bfc6f18771c
|
||||
|
||||
@@ -35,9 +35,10 @@ typedef enum {
|
||||
static NSString * const kDevicesChanged = @"org.jitsi.meet:features/audio-mode#devices-update";
|
||||
|
||||
// Device types (must match JS and Java)
|
||||
static NSString * const kDeviceTypeHeadphones = @"HEADPHONES";
|
||||
static NSString * const kDeviceTypeBluetooth = @"BLUETOOTH";
|
||||
static NSString * const kDeviceTypeCar = @"CAR";
|
||||
static NSString * const kDeviceTypeEarpiece = @"EARPIECE";
|
||||
static NSString * const kDeviceTypeHeadphones = @"HEADPHONES";
|
||||
static NSString * const kDeviceTypeSpeaker = @"SPEAKER";
|
||||
static NSString * const kDeviceTypeUnknown = @"UNKNOWN";
|
||||
|
||||
@@ -190,7 +191,7 @@ RCT_EXPORT_METHOD(setAudioDevice:(NSString *)device
|
||||
|
||||
// The speaker is special, so test for it first.
|
||||
if ([device isEqualToString:kDeviceTypeSpeaker]) {
|
||||
forceSpeaker = NO;
|
||||
forceSpeaker = YES;
|
||||
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
|
||||
} else {
|
||||
// Here we use AVAudioSession because RTCAudioSession doesn't expose availableInputs.
|
||||
@@ -258,10 +259,16 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
self->forceSpeaker = NO;
|
||||
self->forceEarpiece = NO;
|
||||
break;
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange:
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange: {
|
||||
// The category has changed. Check if it's the one we want and adjust as
|
||||
// needed.
|
||||
RTCAudioSessionConfiguration *currentConfig = [self configForMode:self->activeMode];
|
||||
if ([session.category isEqualToString:currentConfig.category]) {
|
||||
// We are in the desired category, nothing to do here.
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -274,7 +281,6 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
RTCAudioSessionConfiguration *config = [self configForMode:self->activeMode];
|
||||
[self setConfig:config error:nil];
|
||||
if (self->forceSpeaker && !self->isSpeakerOn) {
|
||||
RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
|
||||
[session lockForConfiguration];
|
||||
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
|
||||
[session unlockForConfiguration];
|
||||
@@ -320,6 +326,8 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
|| [portType isEqualToString:AVAudioSessionPortBluetoothLE]
|
||||
|| [portType isEqualToString:AVAudioSessionPortBluetoothA2DP]) {
|
||||
return kDeviceTypeBluetooth;
|
||||
} else if ([portType isEqualToString:AVAudioSessionPortCarAudio]) {
|
||||
return kDeviceTypeCar;
|
||||
} else {
|
||||
return kDeviceTypeUnknown;
|
||||
}
|
||||
@@ -355,7 +363,7 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (AVAudioSessionPortDescription *portDesc in session.availableInputs) {
|
||||
// Skip "Phone" if headphones are present.
|
||||
if (headphonesAvailable && [portDesc.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Auto",
|
||||
"headphones": "Kopfhörer",
|
||||
"none": "Keine Audiogeräte verfügbar",
|
||||
"phone": "Hörer",
|
||||
@@ -216,6 +217,8 @@
|
||||
"liveStreaming": "Livestream"
|
||||
},
|
||||
"add": "Hinzufügen",
|
||||
"addMeetingNote": "Notiz zu dieser Konferenz hinzufügen",
|
||||
"addOptionalNote": "Notiz hinzufügen (optional):",
|
||||
"allow": "Erlauben",
|
||||
"alreadySharedVideoMsg": "Eine andere Person gibt bereits ein Video weiter. Bei dieser Konferenz ist jeweils nur ein geteiltes Video möglich.",
|
||||
"alreadySharedVideoTitle": "Nur ein geteiltes Video gleichzeitig",
|
||||
@@ -267,6 +270,8 @@
|
||||
"kickParticipantDialog": "Wollen Sie diese Person wirklich entfernen?",
|
||||
"kickParticipantTitle": "Person entfernen?",
|
||||
"kickTitle": "Autsch! {{participantDisplayName}} hat Sie aus dem Meeting geworfen",
|
||||
"linkMeeting": "Konferenz verlinken",
|
||||
"linkMeetingTitle": "Konferenz mit Salesforce verlinken",
|
||||
"liveStreaming": "Livestreaming",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Während einer Aufnahme nicht möglich",
|
||||
"liveStreamingDisabledTooltip": "Starten des Livestreams deaktiviert.",
|
||||
@@ -303,11 +308,11 @@
|
||||
"muteEveryonesVideoTitle": "Die Kamera von allen anderen ausschalten?",
|
||||
"muteParticipantBody": "Sie können die Stummschaltung anderer Personen nicht aufheben, aber eine Person kann ihre eigene Stummschaltung jederzeit beenden.",
|
||||
"muteParticipantButton": "Stummschalten",
|
||||
"muteParticipantDialog": "Wollen Sie diese Person wirklich stummschalten? Sie können die Stummschaltung nicht wieder aufheben, die Person kann dies aber jederzeit selbst tun.",
|
||||
"muteParticipantTitle": "Person stummschalten?",
|
||||
"muteParticipantsVideoBody": "Sie können die Kamera nicht wieder aktivieren, die Teilnehmer können dies aber jederzeit wieder ändern.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Sie können die Kamera nicht wieder aktivieren und die Person selbst auch nicht.",
|
||||
"muteParticipantsVideoButton": "Kamera ausschalten",
|
||||
"muteParticipantsVideoDialog": "Wollen Sie die Kamera dieser Person wirklich deaktivieren? Sie können die Kamera nicht wieder aktivieren, die Person kann dies aber jederzeit selbst tun.",
|
||||
"muteParticipantsVideoDialogModerationOn": "Wollen Sie die Kamera dieser Person wirklich deaktivieren? Sie können die Kamea nicht wieder aktivieren und die Person selbst auch nicht.",
|
||||
"muteParticipantsVideoTitle": "Die Kamera von dieser Person ausschalten?",
|
||||
"noDropboxToken": "Kein gültiges Dropbox-Token",
|
||||
"password": "Passwort",
|
||||
@@ -321,6 +326,7 @@
|
||||
"popupError": "Ihr Browser blockiert Pop-ups von dieser Website. Bitte aktivieren Sie Pop-ups in den Sicherheitseinstellungen des Browsers und versuchen Sie es erneut.",
|
||||
"popupErrorTitle": "Pop-up blockiert",
|
||||
"readMore": "mehr",
|
||||
"recentlyUsedObjects": "Ihre zuletzt verwendeten Objekte",
|
||||
"recording": "Aufnahme",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Während eines Livestreams nicht möglich",
|
||||
"recordingDisabledTooltip": "Start der Aufzeichnung deaktiviert.",
|
||||
@@ -343,6 +349,12 @@
|
||||
"screenSharingFailed": "Ups! Beim Teilen des Bildschirms ist etwas schiefgegangen!",
|
||||
"screenSharingFailedTitle": "Bildschirmfreigabe fehlgeschlagen!",
|
||||
"screenSharingPermissionDeniedError": "Ups! Etwas stimmt nicht mit Ihren Berechtigungen zur Bildschirmfreigabe. Bitte neu laden und erneut versuchen.",
|
||||
"searchInSalesforce": "In Salesforce suchen",
|
||||
"searchResults": "Suchergebnisse({{count}})",
|
||||
"searchResultsDetailsError": "Beim Abrufen der Daten des Besitzers ist ein Fehler aufgetreten.",
|
||||
"searchResultsError": "Beim Abrufen der Daten ist ein Fehler aufgetreten.",
|
||||
"searchResultsNotFound": "Keine Suchergebnisse.",
|
||||
"searchResultsTryAgain": "Versuchen Sie es mit anderen Stichwörtern.",
|
||||
"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",
|
||||
@@ -410,6 +422,10 @@
|
||||
"veryBad": "Sehr schlecht",
|
||||
"veryGood": "Sehr gut"
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "Keine Ergebnisse :(",
|
||||
"search": "GIPHY durchsuchen"
|
||||
},
|
||||
"helpView": {
|
||||
"header": "Hilfecenter"
|
||||
},
|
||||
@@ -476,6 +492,7 @@
|
||||
"focusLocal": "Lokales Video fokussieren",
|
||||
"focusRemote": "Auf das Video einer anderen Person fokussieren",
|
||||
"fullScreen": "Vollbildmodus aktivieren oder deaktivieren",
|
||||
"giphyMenu": "GIPHY ein- oder ausblenden",
|
||||
"keyboardShortcuts": "Tastenkürzel",
|
||||
"localRecording": "Lokale Aufzeichnungssteuerelemente ein- oder ausblenden",
|
||||
"mute": "Stummschaltung aktivieren oder deaktivieren",
|
||||
@@ -543,6 +560,7 @@
|
||||
"errorMissingPassword": "Bitte das Konferenzpasswort eingeben",
|
||||
"invalidPassword": "Ungültiges Passwort",
|
||||
"joinRejectedMessage": "Ihre Beitrittsanfrage wurde von der Moderation abgelehnt.",
|
||||
"joinRejectedTitle": "Beitrittsanfrage abgelehnt.",
|
||||
"joinTitle": "Konferenz beitreten",
|
||||
"joinWithPasswordMessage": "Beitrittsversuch mit Passwort, bitte warten …",
|
||||
"joiningMessage": "Sie treten der Konferenz bei, sobald jemand Ihre Anfrage annimmt.",
|
||||
@@ -615,6 +633,7 @@
|
||||
"displayNotifications": "Benachrichtigungen anzeigen für",
|
||||
"focus": "Konferenzleitung",
|
||||
"focusFail": "{{component}} ist im Moment nicht verfügbar – wiederholen in {{ms}} Sekunden",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Benachrichtigungen",
|
||||
"hostAskedUnmute": "Die Moderation bittet Sie, das Mikrofon zu aktivieren",
|
||||
"invitedOneMember": "{{name}} wurde eingeladen",
|
||||
@@ -624,6 +643,12 @@
|
||||
"leftOneMember": "{{name}} hat die Konferenz verlassen",
|
||||
"leftThreePlusMembers": "{{name}} und Weitere haben die Konferenz verlassen",
|
||||
"leftTwoMembers": "{{first}} und {{second}} haben die Konferenz verlassen",
|
||||
"linkToSalesforce": "Mit Salesforce verlinken",
|
||||
"linkToSalesforceDescription": "Sie können die Zusammenfassung der Konferenz mit einem Objekt bei Salesforce verlinken.",
|
||||
"linkToSalesforceError": "Konferenz konnte nicht mit Salesforce verlinkt werden",
|
||||
"linkToSalesforceKey": "Konferenz verlinken",
|
||||
"linkToSalesforceProgress": "Konferenz wird mit Salesforce verlinkt...",
|
||||
"linkToSalesforceSuccess": "Die Konferenz wurde mit Salesforce verlinkt",
|
||||
"me": "Ich",
|
||||
"moderationInEffectCSDescription": "Bitte melden um ein Video zu teilen",
|
||||
"moderationInEffectCSTitle": "Die Videofreigabe ist von der Moderation gesperrt",
|
||||
@@ -702,6 +727,7 @@
|
||||
},
|
||||
"passwordDigitsOnly": "Bis zu {{number}} Ziffern",
|
||||
"passwordSetRemotely": "von einer anderen Person gesetzt",
|
||||
"pinnedParticipant": "Die Person ist angeheftet",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Überspringen",
|
||||
@@ -817,6 +843,18 @@
|
||||
},
|
||||
"raisedHand": "Ich möchte sprechen",
|
||||
"raisedHandsLabel": "Anzahl gehobener Hände",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "Diese Konferenz ist bereits mit einem Objekt bei Salesforce verlinkt."
|
||||
},
|
||||
"type": {
|
||||
"account": "Account",
|
||||
"contact": "Contact",
|
||||
"lead": "Lead",
|
||||
"opportunity": "Opportunity",
|
||||
"owner": "Owner"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "In Dropbox hochladen",
|
||||
"availableSpace": "Verfügbarer Speicherplatz: {{spaceLeft}} MB (ca. {{duration}} Minuten Aufzeichnung)",
|
||||
@@ -831,6 +869,11 @@
|
||||
"expandedPending": "Aufzeichnung wird gestartet…",
|
||||
"failedToStart": "Die Aufnahme konnte nicht gestartet werden",
|
||||
"fileSharingdescription": "Aufzeichnung mit den Personen der Konferenz teilen",
|
||||
"highlight": "Highlight",
|
||||
"highlightMoment": "Moment als Highlight festhalten",
|
||||
"highlightMomentDisabled": "Sie können Momente als Highlights festhalten, sobald die Aufnahme startet",
|
||||
"highlightMomentSuccess": "Highlight festgehalten",
|
||||
"highlightMomentSucessDescription": "Ihr festgehaltener Moment wird zur Zusammenfassung des Meeting hinzugefügt.",
|
||||
"inProgress": "Aufzeichnung gestartet",
|
||||
"limitNotificationDescriptionNative": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <3>{{app}}</3>.",
|
||||
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
@@ -845,6 +888,7 @@
|
||||
"rec": "AUFZ",
|
||||
"serviceDescription": "Ihre Aufzeichnung wird vom Aufzeichnungsdienst gespeichert",
|
||||
"serviceDescriptionCloud": "Cloud-Aufzeichnung",
|
||||
"serviceDescriptionCloudInfo": "Aufzeichnungen werden 24 Stunden nach Aufzeichnungsende automatisch gelöscht.",
|
||||
"serviceName": "Aufnahmedienst",
|
||||
"sessionAlreadyActive": "Diese Konferenz wird bereits aufgezeichnet.",
|
||||
"signIn": "Anmelden",
|
||||
@@ -879,6 +923,7 @@
|
||||
"incomingMessage": "Eingehende Nachricht",
|
||||
"language": "Sprache",
|
||||
"loggedIn": "Als {{name}} angemeldet",
|
||||
"maxStageParticipants": "Maximale Anzahl an Personen, die zur Hauptansicht angeheftet werden können",
|
||||
"microphones": "Mikrofon",
|
||||
"moderator": "Moderation",
|
||||
"more": "Mehr",
|
||||
@@ -977,6 +1022,7 @@
|
||||
"expand": "Ausklappen",
|
||||
"feedback": "Feedback hinterlassen",
|
||||
"fullScreen": "Vollbildmodus ein-/ausschalten",
|
||||
"giphy": "GIPHY ein-/ausschalten",
|
||||
"grantModerator": "Moderationsrechte vergeben",
|
||||
"hangup": "Konferenz verlassen",
|
||||
"help": "Hilfe",
|
||||
@@ -984,6 +1030,7 @@
|
||||
"kick": "Person entfernen",
|
||||
"laugh": "Lachen",
|
||||
"like": "Daumen nach oben",
|
||||
"linkToSalesforce": "Mit Salesforce verlinken",
|
||||
"lobbyButton": "Lobbymodus ein-/ausschalten",
|
||||
"localRecording": "Lokale Aufzeichnungssteuerelemente ein-/ausschalten",
|
||||
"lockRoom": "Konferenzpasswort ein-/ausschalten",
|
||||
@@ -993,8 +1040,8 @@
|
||||
"mute": "Mikrofon aktivieren / deaktivieren",
|
||||
"muteEveryone": "Alle stummschalten",
|
||||
"muteEveryoneElse": "Alle anderen stummschalten",
|
||||
"muteEveryoneElsesVideo": "Alle anderen Kameras ausschalten",
|
||||
"muteEveryonesVideo": "Alle Kameras ausschalten",
|
||||
"muteEveryoneElsesVideoStream": "Alle anderen Kameras ausschalten",
|
||||
"muteEveryonesVideoStream": "Alle Kameras ausschalten",
|
||||
"participants": "Anwesende",
|
||||
"pip": "Bild-in-Bild-Modus ein-/ausschalten",
|
||||
"privateMessage": "Private Nachricht senden",
|
||||
@@ -1045,6 +1092,7 @@
|
||||
"exitFullScreen": "Vollbildmodus verlassen",
|
||||
"exitTileView": "Kachelansicht ausschalten",
|
||||
"feedback": "Feedback hinterlassen",
|
||||
"giphy": "GIPHY ein-/ausschalten",
|
||||
"hangup": "Konferenz verlassen",
|
||||
"help": "Hilfe",
|
||||
"invite": "Personen einladen",
|
||||
@@ -1052,6 +1100,7 @@
|
||||
"laugh": "Lachen",
|
||||
"leaveBreakoutRoom": "Breakout-Raum verlassen",
|
||||
"like": "Daumen hoch",
|
||||
"linkToSalesforce": "Mit Salesforce verknüpfen",
|
||||
"lobbyButtonDisable": "Lobbymodus deaktivieren",
|
||||
"lobbyButtonEnable": "Lobbymodus aktivieren",
|
||||
"login": "Anmelden",
|
||||
@@ -1171,10 +1220,12 @@
|
||||
"moderator": "Moderation",
|
||||
"mute": "Person ist stumm geschaltet",
|
||||
"muted": "Stummgeschaltet",
|
||||
"pinToStage": "Anheften",
|
||||
"remoteControl": "Fernsteuerung",
|
||||
"screenSharing": "Person teilt den Bildschirm",
|
||||
"show": "Im Vordergrund anzeigen",
|
||||
"showSelfView": "Eigene Ansicht anzeigen",
|
||||
"unpinFromStage": "Lösen",
|
||||
"videoMuted": "Kamera ausgeschaltet",
|
||||
"videomute": "Person hat die Kamera angehalten"
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Car Audio",
|
||||
"headphones": "Headphones",
|
||||
"none": "No audio devices available",
|
||||
"phone": "Phone",
|
||||
|
||||
216
package-lock.json
generated
216
package-lock.json
generated
@@ -72,10 +72,10 @@
|
||||
"jquery-i18next": "1.2.1",
|
||||
"js-md5": "0.6.1",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1412.0.0+832d7d35/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1415.0.0+fa916d41/lib-jitsi-meet.tgz",
|
||||
"libflacjs": "https://git@github.com/mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
"moment": "2.29.2",
|
||||
"moment-duration-format": "2.2.2",
|
||||
"optional-require": "1.0.3",
|
||||
"promise.allsettled": "1.0.4",
|
||||
@@ -91,7 +91,7 @@
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-callstats": "3.73.7",
|
||||
"react-native-collapsible": "1.6.0",
|
||||
"react-native-default-preference": "https://git@github.com/kevinresol/react-native-default-preference#11bff5eb05cb04fd8d35b5e761eeee80525e8c6c",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-dialog": "9.2.1",
|
||||
"react-native-gesture-handler": "2.1.0",
|
||||
@@ -161,6 +161,7 @@
|
||||
"string-replace-loader": "3.0.3",
|
||||
"style-loader": "0.19.0",
|
||||
"traverse": "0.6.6",
|
||||
"ts-loader": "9.2.6",
|
||||
"typescript": "4.3.5",
|
||||
"unorm": "1.6.0",
|
||||
"webpack": "5.57.1",
|
||||
@@ -11795,8 +11796,8 @@
|
||||
},
|
||||
"node_modules/lib-jitsi-meet": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1412.0.0+832d7d35/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-QffTLTXyI7RAauRUULOtNlMWDU4XursMcREj6gFQTsYJ4A64rgNaJfd/G8sya7mRLrrj9jJ4yeLVfMQL/q11xg==",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1415.0.0+fa916d41/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-xCDIkUykAYPLocmnOItFC1PYNYVMTp57XwJ1PXvOwHV4lZO9RBG36ln5QBUonD2P0X6di2UGiRzOi9l4FaHoLQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
@@ -12780,9 +12781,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
|
||||
"version": "2.29.2",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
@@ -15068,10 +15069,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-default-preference": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "git+https://git@github.com/kevinresol/react-native-default-preference.git#11bff5eb05cb04fd8d35b5e761eeee80525e8c6c",
|
||||
"integrity": "sha512-vmUyt63mLc+xebOOWrZxTF7o7AdWQqzy6lUn7pgjnyUd93//AOpQ6iXGijL9KpNiOv8mDKWAPZKhLY1XVuzZwA==",
|
||||
"license": "MIT",
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-default-preference/-/react-native-default-preference-1.4.4.tgz",
|
||||
"integrity": "sha512-h0vtgiSKws3UmMRJykXAVM4ne1SgfoocUcoBD19ewRpQd6wqurE0HJRQGrSxcHK5LdKE7QPSIB1VX3YGIVS8Jg==",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
}
|
||||
@@ -18332,6 +18332,110 @@
|
||||
"resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz",
|
||||
"integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ=="
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"enhanced-resolve": "^5.0.0",
|
||||
"micromatch": "^4.0.0",
|
||||
"semver": "^7.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*",
|
||||
"webpack": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/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==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/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==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||
@@ -28795,8 +28899,8 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1412.0.0+832d7d35/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-QffTLTXyI7RAauRUULOtNlMWDU4XursMcREj6gFQTsYJ4A64rgNaJfd/G8sya7mRLrrj9jJ4yeLVfMQL/q11xg==",
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1415.0.0+fa916d41/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-xCDIkUykAYPLocmnOItFC1PYNYVMTp57XwJ1PXvOwHV4lZO9RBG36ln5QBUonD2P0X6di2UGiRzOi9l4FaHoLQ==",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
@@ -29623,9 +29727,9 @@
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
"version": "2.29.2",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
|
||||
"integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg=="
|
||||
},
|
||||
"moment-duration-format": {
|
||||
"version": "2.2.2",
|
||||
@@ -31400,9 +31504,9 @@
|
||||
"integrity": "sha512-beZjdgbT9Y/Pg591Xy5XkKG20HffJiVad4n9bfcUF/f783A+tvOVXnqvbS58Lkaym93mi4jcDPMuW9Vc1t6rqg=="
|
||||
},
|
||||
"react-native-default-preference": {
|
||||
"version": "git+https://git@github.com/kevinresol/react-native-default-preference.git#11bff5eb05cb04fd8d35b5e761eeee80525e8c6c",
|
||||
"integrity": "sha512-vmUyt63mLc+xebOOWrZxTF7o7AdWQqzy6lUn7pgjnyUd93//AOpQ6iXGijL9KpNiOv8mDKWAPZKhLY1XVuzZwA==",
|
||||
"from": "react-native-default-preference@https://git@github.com/kevinresol/react-native-default-preference#11bff5eb05cb04fd8d35b5e761eeee80525e8c6c"
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-default-preference/-/react-native-default-preference-1.4.4.tgz",
|
||||
"integrity": "sha512-h0vtgiSKws3UmMRJykXAVM4ne1SgfoocUcoBD19ewRpQd6wqurE0HJRQGrSxcHK5LdKE7QPSIB1VX3YGIVS8Jg=="
|
||||
},
|
||||
"react-native-device-info": {
|
||||
"version": "8.4.8",
|
||||
@@ -33840,6 +33944,78 @@
|
||||
"resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz",
|
||||
"integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ=="
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.6.tgz",
|
||||
"integrity": "sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"enhanced-resolve": "^5.0.0",
|
||||
"micromatch": "^4.0.0",
|
||||
"semver": "^7.3.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"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==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tsconfig-paths": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||
|
||||
@@ -77,10 +77,10 @@
|
||||
"jquery-i18next": "1.2.1",
|
||||
"js-md5": "0.6.1",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1412.0.0+832d7d35/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1415.0.0+fa916d41/lib-jitsi-meet.tgz",
|
||||
"libflacjs": "https://git@github.com/mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.1",
|
||||
"moment": "2.29.2",
|
||||
"moment-duration-format": "2.2.2",
|
||||
"optional-require": "1.0.3",
|
||||
"promise.allsettled": "1.0.4",
|
||||
@@ -96,7 +96,7 @@
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-callstats": "3.73.7",
|
||||
"react-native-collapsible": "1.6.0",
|
||||
"react-native-default-preference": "https://git@github.com/kevinresol/react-native-default-preference#11bff5eb05cb04fd8d35b5e761eeee80525e8c6c",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-dialog": "9.2.1",
|
||||
"react-native-gesture-handler": "2.1.0",
|
||||
@@ -166,6 +166,7 @@
|
||||
"string-replace-loader": "3.0.3",
|
||||
"style-loader": "0.19.0",
|
||||
"traverse": "0.6.6",
|
||||
"ts-loader": "9.2.6",
|
||||
"typescript": "4.3.5",
|
||||
"unorm": "1.6.0",
|
||||
"webpack": "5.57.1",
|
||||
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
} from '../base/environment/utils';
|
||||
import JitsiMeetJS, {
|
||||
analytics,
|
||||
browser,
|
||||
isAnalyticsEnabled
|
||||
browser
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import { isAnalyticsEnabled } from '../base/lib-jitsi-meet/functions';
|
||||
import { getJitsiMeetGlobalNS, loadScript, parseURIString } from '../base/util';
|
||||
|
||||
import { AmplitudeHandler, MatomoHandler } from './handlers';
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
storeConfig
|
||||
} from '../base/config';
|
||||
import { setLocationURL } from '../base/connection';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
|
||||
import {
|
||||
getBackendSafeRoomName,
|
||||
parseURIString
|
||||
|
||||
@@ -56,6 +56,11 @@ export type Props = {
|
||||
*/
|
||||
onKeyPress?: Function,
|
||||
|
||||
/**
|
||||
* TestId of the element, if any.
|
||||
*/
|
||||
testId?: string,
|
||||
|
||||
/**
|
||||
* Action text.
|
||||
*/
|
||||
@@ -112,6 +117,7 @@ const ContextMenuItem = ({
|
||||
onClick,
|
||||
onKeyDown,
|
||||
onKeyPress,
|
||||
testId,
|
||||
text,
|
||||
textClassName }: Props) => {
|
||||
const styles = useStyles();
|
||||
@@ -126,6 +132,7 @@ const ContextMenuItem = ({
|
||||
disabled && styles.contextMenuItemDisabled,
|
||||
className
|
||||
) }
|
||||
data-testid = { testId }
|
||||
id = { id }
|
||||
key = { text }
|
||||
onClick = { disabled ? undefined : onClick }
|
||||
|
||||
3
react/features/base/icons/svg/car.svg
Normal file
3
react/features/base/icons/svg/car.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.44701 5H15.553C16.427 5 17.1997 5.56747 17.4613 6.40136L18.2765 9H18H6H5.7235L6.5387 6.40136C6.8003 5.56747 7.57305 5 8.44701 5ZM3.29779 10.0507L4.6304 5.80272C5.15358 4.13493 6.69908 3 8.44701 3H15.553C17.3009 3 18.8464 4.13494 19.3696 5.80272L20.7022 10.0507C21.4999 10.782 22 11.8326 22 13V17V18V21H20V18H4V21H2V18V17V13C2 11.8326 2.50012 10.782 3.29779 10.0507ZM6 11C4.89543 11 4 11.8954 4 13V16H20V13C20 11.8954 19.1046 11 18 11H6ZM9 13.5C9 14.3284 8.32843 15 7.5 15C6.67157 15 6 14.3284 6 13.5C6 12.6716 6.67157 12 7.5 12C8.32843 12 9 12.6716 9 13.5ZM16.5 15C17.3284 15 18 14.3284 18 13.5C18 12.6716 17.3284 12 16.5 12C15.6716 12 15 12.6716 15 13.5C15 14.3284 15.6716 15 16.5 15Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 844 B |
@@ -22,6 +22,7 @@ export { default as IconCameraEmpty } from './camera-empty.svg';
|
||||
export { default as IconCameraEmptyDisabled } from './camera-empty-disabled.svg';
|
||||
export { default as IconCameraRefresh } from './camera-refresh.svg';
|
||||
export { default as IconCancelSelection } from './cancel.svg';
|
||||
export { default as IconCar } from './car.svg';
|
||||
export { default as IconChat } from './chat.svg';
|
||||
export { default as IconChatSend } from './send.svg';
|
||||
export { default as IconChatUnread } from './chat-unread.svg';
|
||||
|
||||
@@ -24,7 +24,3 @@ export const JitsiRecordingConstants = JitsiMeetJS.constants.recording;
|
||||
export const JitsiSIPVideoGWStatus = JitsiMeetJS.constants.sipVideoGW;
|
||||
export const JitsiTrackErrors = JitsiMeetJS.errors.track;
|
||||
export const JitsiTrackEvents = JitsiMeetJS.events.track;
|
||||
|
||||
export * from './actions';
|
||||
export * from './actionTypes';
|
||||
export * from './functions';
|
||||
|
||||
@@ -5,9 +5,9 @@ import Logger from '@jitsi/logger';
|
||||
import { APP_WILL_MOUNT } from '../app';
|
||||
import { CONFERENCE_JOINED, getCurrentConference } from '../conference';
|
||||
import JitsiMeetJS, {
|
||||
LIB_WILL_INIT,
|
||||
JitsiConferenceEvents
|
||||
} from '../lib-jitsi-meet';
|
||||
import { LIB_WILL_INIT } from '../lib-jitsi-meet/actionTypes';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import { isTestModeEnabled } from '../testing';
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
import { NOTIFICATION_TIMEOUT_TYPE, showErrorNotification, showNotification } from '../../notifications';
|
||||
import { getCurrentConference } from '../conference';
|
||||
import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../config';
|
||||
import { JitsiTrackErrors, JitsiTrackEvents, createLocalTrack } from '../lib-jitsi-meet';
|
||||
import { JitsiTrackErrors, JitsiTrackEvents } from '../lib-jitsi-meet';
|
||||
import { createLocalTrack } from '../lib-jitsi-meet/functions';
|
||||
import {
|
||||
CAMERA_FACING_MODE,
|
||||
MEDIA_TYPE,
|
||||
|
||||
@@ -78,6 +78,10 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
store.dispatch(getAvailableDevices());
|
||||
}
|
||||
|
||||
// Call next before the creation of a fake screenshare participant to ensure a video track is available when
|
||||
// the participant is auto pinned.
|
||||
const result = next(action);
|
||||
|
||||
// The TRACK_ADDED action is dispatched when a presenter starts a screenshare. Do not create a local fake
|
||||
// screenshare participant when multiple stream is not enabled.
|
||||
const skipCreateFakeScreenShareParticipant = local && !getMultipleVideoSupportFeatureFlag(state);
|
||||
@@ -90,7 +94,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
createFakeScreenShareParticipant(store, action);
|
||||
}
|
||||
|
||||
break;
|
||||
return result;
|
||||
}
|
||||
case TRACK_NO_DATA_FROM_SOURCE: {
|
||||
const result = next(action);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import * as React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import {
|
||||
getParticipantById,
|
||||
getParticipantDisplayName
|
||||
} from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
} from '../../../base/participants/functions';
|
||||
import { connect } from '../../../base/redux/functions';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
@@ -16,28 +14,28 @@ type Props = {
|
||||
/**
|
||||
* The name of the participant to render.
|
||||
*/
|
||||
_participantName: string,
|
||||
_participantName: string;
|
||||
|
||||
/**
|
||||
* True of the label needs to be rendered. False otherwise.
|
||||
*/
|
||||
_render: boolean,
|
||||
_render: boolean;
|
||||
|
||||
/**
|
||||
* Whether ot not the name is in a container.
|
||||
*/
|
||||
contained?: boolean,
|
||||
contained?: boolean;
|
||||
|
||||
/**
|
||||
* The ID of the participant to render the label for.
|
||||
*/
|
||||
participantId: string
|
||||
participantId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a label with the display name of the on-stage participant.
|
||||
*/
|
||||
class DisplayNameLabel extends Component<Props> {
|
||||
class DisplayNameLabel extends React.Component<Props> {
|
||||
/**
|
||||
* Implements {@code Component#render}.
|
||||
*
|
||||
@@ -63,18 +61,16 @@ class DisplayNameLabel extends Component<Props> {
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @param {any} state - The Redux state.
|
||||
* @param {Props} ownProps - The own props of the component.
|
||||
* @returns {{
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state: Object, ownProps: Props) {
|
||||
const { participantId, contained } = ownProps;
|
||||
const participant = getParticipantById(state, participantId);
|
||||
function _mapStateToProps(state: any, ownProps) {
|
||||
const participant = getParticipantById(state, ownProps.participantId);
|
||||
|
||||
return {
|
||||
_participantName: getParticipantDisplayName(state, participantId),
|
||||
_render: participant && (!participant?.local || contained) && !participant?.isFakeParticipant
|
||||
_participantName: getParticipantDisplayName(state, ownProps.participantId),
|
||||
_render: participant && (!participant?.local || ownProps.contained) && !participant?.isFakeParticipant
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
// @flow
|
||||
|
||||
export { default as DisplayNameLabel } from './DisplayNameLabel';
|
||||
export { default as DisplayNamePrompt } from './DisplayNamePrompt';
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
// @flow
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The name to be displayed within the badge.
|
||||
*/
|
||||
name: string
|
||||
interface Theme {
|
||||
palette: any;
|
||||
text01: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
const useStyles = makeStyles((theme: Theme) => {
|
||||
const { text01 } = theme.palette;
|
||||
|
||||
return {
|
||||
badge: {
|
||||
background: 'rgba(0, 0, 0, 0.6)',
|
||||
borderRadius: '3px',
|
||||
color: theme.palette.text01,
|
||||
color: text01,
|
||||
maxWidth: '50%',
|
||||
overflow: 'hidden',
|
||||
padding: '2px 16px',
|
||||
@@ -32,12 +29,12 @@ const useStyles = makeStyles(theme => {
|
||||
* @param {Props} props - The props of the component.
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
const DisplayNameBadge = ({ name }: Props) => {
|
||||
const DisplayNameBadge: React.FC<{ name: string }> = ({ name }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<div className = { classes.badge }>
|
||||
{name}
|
||||
{ name }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* Appends a suffix to the display name.
|
||||
@@ -7,7 +6,7 @@
|
||||
* @param {string} suffix - Suffix that will be appended.
|
||||
* @returns {string} The formatted display name.
|
||||
*/
|
||||
export function appendSuffix(displayName: string, suffix: string = '') {
|
||||
export function appendSuffix(displayName: string, suffix = ''): string {
|
||||
return `${displayName || suffix}${
|
||||
displayName && suffix && displayName !== suffix ? ` (${suffix})` : ''}`;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import { loadConfig } from '../base/lib-jitsi-meet';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet/functions';
|
||||
|
||||
/**
|
||||
* Extracts the fqn part from a path, where fqn represents
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* Redux action type dispatched in order to add a face expression.
|
||||
*
|
||||
@@ -19,7 +17,7 @@ export const ADD_FACE_EXPRESSION = 'ADD_FACE_EXPRESSION';
|
||||
* faceExpression: string
|
||||
* }
|
||||
*/
|
||||
export const ADD_TO_FACE_EXPRESSIONS_BUFFER = 'ADD_TO_FACE_EXPRESSIONS_BUFFER ';
|
||||
export const ADD_TO_FACE_EXPRESSIONS_BUFFER = 'ADD_TO_FACE_EXPRESSIONS_BUFFER';
|
||||
|
||||
/**
|
||||
* Redux action type dispatched in order to clear the face expressions buffer in the state.
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import {
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
|
||||
@@ -170,3 +170,13 @@ export const SET_STAGE_PARTICIPANTS = 'SET_STAGE_PARTICIPANTS';
|
||||
* }
|
||||
*/
|
||||
export const SET_MAX_STAGE_PARTICIPANTS = 'SET_MAX_STAGE_PARTICIPANTS';
|
||||
|
||||
|
||||
/**
|
||||
* The type of Redux action which toggles the pin state of stage participants.
|
||||
* {
|
||||
* type: TOGGLE_PIN_STAGE_PARTICIPANT,
|
||||
* participantId: String
|
||||
* }
|
||||
*/
|
||||
export const TOGGLE_PIN_STAGE_PARTICIPANT = 'TOGGLE_PIN_STAGE_PARTICIPANT';
|
||||
@@ -23,7 +23,8 @@ import {
|
||||
SET_USER_IS_RESIZING,
|
||||
SET_VERTICAL_VIEW_DIMENSIONS,
|
||||
SET_VOLUME,
|
||||
SET_MAX_STAGE_PARTICIPANTS
|
||||
SET_MAX_STAGE_PARTICIPANTS,
|
||||
TOGGLE_PIN_STAGE_PARTICIPANT
|
||||
} from './actionTypes';
|
||||
import {
|
||||
HORIZONTAL_FILMSTRIP_MARGIN,
|
||||
@@ -449,3 +450,16 @@ export function setMaxStageParticipants(maxParticipants) {
|
||||
maxParticipants
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the pin state of the given participant.
|
||||
*
|
||||
* @param {string} participantId - The id of the participant to be toggled.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function togglePinStageParticipant(participantId) {
|
||||
return {
|
||||
type: TOGGLE_PIN_STAGE_PARTICIPANT,
|
||||
participantId
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getSourceNameSignalingFeatureFlag } from '../../../base/config';
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
import { MEDIA_TYPE, VideoTrack } from '../../../base/media';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantByIdOrUndefined,
|
||||
hasRaisedHand,
|
||||
pinParticipant
|
||||
@@ -30,7 +31,7 @@ import { hideGif, showGif } from '../../../gifs/actions';
|
||||
import { getGifDisplayMode, getGifForParticipant } from '../../../gifs/functions';
|
||||
import { PresenceLabel } from '../../../presence-status';
|
||||
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||
import { addStageParticipant } from '../../actions.web';
|
||||
import { togglePinStageParticipant } from '../../actions';
|
||||
import {
|
||||
DISPLAY_MODE_TO_CLASS_NAME,
|
||||
DISPLAY_VIDEO,
|
||||
@@ -42,9 +43,10 @@ import {
|
||||
getActiveParticipantsIds,
|
||||
getDisplayModeInput,
|
||||
isVideoPlayable,
|
||||
showGridInVerticalView
|
||||
showGridInVerticalView,
|
||||
isStageFilmstripEnabled,
|
||||
shouldDisplayStageFilmstrip
|
||||
} from '../../functions';
|
||||
import { isStageFilmstripEnabled } from '../../functions.web';
|
||||
|
||||
import FakeScreenShareParticipant from './FakeScreenShareParticipant';
|
||||
import ThumbnailAudioIndicator from './ThumbnailAudioIndicator';
|
||||
@@ -191,6 +193,13 @@ export type Props = {|
|
||||
*/
|
||||
_stageFilmstripDisabled: boolean,
|
||||
|
||||
/**
|
||||
* Whether or not the participants are displayed on stage.
|
||||
* (and not screensharing or shared video; used to determine
|
||||
* whether or not the display the participant video in the vertical filmstrip).
|
||||
*/
|
||||
_stageParticipantsVisible: boolean,
|
||||
|
||||
/**
|
||||
* The video object position for the participant.
|
||||
*/
|
||||
@@ -633,7 +642,7 @@ class Thumbnail extends Component<Props, State> {
|
||||
if (_stageFilmstripDisabled) {
|
||||
dispatch(pinParticipant(pinned ? null : id));
|
||||
} else {
|
||||
dispatch(addStageParticipant(id, true));
|
||||
dispatch(togglePinStageParticipant(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1173,6 +1182,7 @@ function _mapStateToProps(state, ownProps): Object {
|
||||
|
||||
const { gifUrl: gifSrc } = getGifForParticipant(state, id);
|
||||
const mode = getGifDisplayMode(state);
|
||||
const participantId = isLocal ? getLocalParticipant(state).id : participantID;
|
||||
|
||||
return {
|
||||
_audioTrack,
|
||||
@@ -1180,7 +1190,7 @@ function _mapStateToProps(state, ownProps): Object {
|
||||
_defaultLocalDisplayName: defaultLocalDisplayName,
|
||||
_disableLocalVideoFlip: Boolean(disableLocalVideoFlip),
|
||||
_disableTileEnlargement: Boolean(disableTileEnlargement),
|
||||
_isActiveParticipant: activeParticipants.find(pId => pId === participantID),
|
||||
_isActiveParticipant: activeParticipants.find(pId => pId === participantId),
|
||||
_isHidden: isLocal && iAmRecorder && !iAmSipGateway,
|
||||
_isAudioOnly: Boolean(state['features/base/audio-only'].enabled),
|
||||
_isCurrentlyOnLargeVideo: state['features/large-video']?.participantId === id,
|
||||
@@ -1195,6 +1205,7 @@ function _mapStateToProps(state, ownProps): Object {
|
||||
_participant: participant,
|
||||
_raisedHand: hasRaisedHand(participant),
|
||||
_stageFilmstripDisabled: !isStageFilmstripEnabled(state),
|
||||
_stageParticipantsVisible: shouldDisplayStageFilmstrip(state, 1),
|
||||
_videoObjectPosition: getVideoObjectPosition(state, participant?.id),
|
||||
_videoTrack,
|
||||
...size,
|
||||
|
||||
@@ -148,7 +148,8 @@ function _mapStateToProps(state, ownProps) {
|
||||
const sourceNameSignalingEnabled = getSourceNameSignalingFeatureFlag(state);
|
||||
const _verticalViewGrid = showGridInVerticalView(state);
|
||||
const stageFilmstrip = ownProps.data?.stageFilmstrip;
|
||||
const remoteParticipants = stageFilmstrip ? activeParticipants : remote;
|
||||
const sortedActiveParticipants = activeParticipants.sort();
|
||||
const remoteParticipants = stageFilmstrip ? sortedActiveParticipants : remote;
|
||||
const remoteParticipantsLength = remoteParticipants.length;
|
||||
const localId = getLocalParticipant(state).id;
|
||||
|
||||
|
||||
@@ -498,6 +498,7 @@ export function computeDisplayModeFromInput(input: Object) {
|
||||
isScreenSharing,
|
||||
canPlayEventReceived,
|
||||
isRemoteParticipant,
|
||||
stageParticipantsVisible,
|
||||
tileViewActive
|
||||
} = input;
|
||||
const adjustedIsVideoPlayable = input.isVideoPlayable && (!isRemoteParticipant || canPlayEventReceived);
|
||||
@@ -506,7 +507,8 @@ export function computeDisplayModeFromInput(input: Object) {
|
||||
return DISPLAY_VIDEO;
|
||||
}
|
||||
|
||||
if (!tileViewActive && ((isScreenSharing && isRemoteParticipant) || isActiveParticipant)) {
|
||||
if (!tileViewActive && ((isScreenSharing && isRemoteParticipant)
|
||||
|| (stageParticipantsVisible && isActiveParticipant))) {
|
||||
return DISPLAY_AVATAR;
|
||||
} else if (isCurrentlyOnLargeVideo && !tileViewActive) {
|
||||
// Display name is always and only displayed when user is on the stage
|
||||
@@ -537,6 +539,7 @@ export function getDisplayModeInput(props: Object, state: Object) {
|
||||
_isScreenSharing,
|
||||
_isVideoPlayable,
|
||||
_participant,
|
||||
_stageParticipantsVisible,
|
||||
_videoTrack
|
||||
} = props;
|
||||
const tileViewActive = _currentLayout === LAYOUTS.TILE_VIEW;
|
||||
@@ -554,6 +557,7 @@ export function getDisplayModeInput(props: Object, state: Object) {
|
||||
isRemoteParticipant: !_participant?.isFakeParticipant && !_participant?.local,
|
||||
isScreenSharing: _isScreenSharing,
|
||||
isFakeScreenShareParticipant: _isFakeScreenShareParticipant,
|
||||
stageParticipantsVisible: _stageParticipantsVisible,
|
||||
videoStreamMuted: _videoTrack ? _videoTrack.muted : 'no stream'
|
||||
};
|
||||
}
|
||||
@@ -674,7 +678,7 @@ export function getActiveParticipantsIds(state) {
|
||||
* Gets the ids of the active participants.
|
||||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @returns {Array<string>}
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
export function getPinnedActiveParticipants(state) {
|
||||
const { activeParticipants } = state['features/filmstrip'];
|
||||
@@ -686,16 +690,18 @@ export function getPinnedActiveParticipants(state) {
|
||||
* Get whether or not the stage filmstrip should be displayed.
|
||||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @param {number} minParticipantCount - The min number of participants for the stage filmstrip
|
||||
* to be displayed.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function shouldDisplayStageFilmstrip(state) {
|
||||
export function shouldDisplayStageFilmstrip(state, minParticipantCount = 2) {
|
||||
const { activeParticipants } = state['features/filmstrip'];
|
||||
const { remoteScreenShares } = state['features/video-layout'];
|
||||
const currentLayout = getCurrentLayout(state);
|
||||
const sharedVideo = isSharingStatus(state['features/shared-video']?.status);
|
||||
|
||||
return isStageFilmstripEnabled(state) && remoteScreenShares.length === 0 && !sharedVideo
|
||||
&& activeParticipants.length > 1 && currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW;
|
||||
&& activeParticipants.length >= minParticipantCount && currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,8 @@ import {
|
||||
ADD_STAGE_PARTICIPANT,
|
||||
REMOVE_STAGE_PARTICIPANT,
|
||||
SET_MAX_STAGE_PARTICIPANTS,
|
||||
SET_USER_FILMSTRIP_WIDTH
|
||||
SET_USER_FILMSTRIP_WIDTH,
|
||||
TOGGLE_PIN_STAGE_PARTICIPANT
|
||||
} from './actionTypes';
|
||||
import {
|
||||
addStageParticipant,
|
||||
@@ -141,6 +142,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
const tid = timers.get(participantId);
|
||||
|
||||
clearTimeout(tid);
|
||||
timers.delete(participantId);
|
||||
} else if (activeParticipants.length < maxStageParticipants) {
|
||||
queue = [ ...activeParticipants, {
|
||||
participantId,
|
||||
@@ -216,11 +218,17 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
break;
|
||||
}
|
||||
case PARTICIPANT_LEFT: {
|
||||
const state = store.getState();
|
||||
const { id } = action.participant;
|
||||
const activeParticipantsIds = getActiveParticipantsIds(store.getState());
|
||||
const activeParticipantsIds = getActiveParticipantsIds(state);
|
||||
|
||||
if (activeParticipantsIds.find(pId => pId === id)) {
|
||||
store.dispatch(removeStageParticipant(id));
|
||||
const tid = timers.get(id);
|
||||
const { activeParticipants } = state['features/filmstrip'];
|
||||
|
||||
clearTimeout(tid);
|
||||
timers.delete(id);
|
||||
store.dispatch(setStageParticipants(activeParticipants.filter(p => p.participantId !== id)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -240,6 +248,36 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TOGGLE_PIN_STAGE_PARTICIPANT: {
|
||||
const { dispatch, getState } = store;
|
||||
const state = getState();
|
||||
const { participantId } = action;
|
||||
const pinnedParticipants = getPinnedActiveParticipants(state);
|
||||
const dominant = getDominantSpeakerParticipant(state);
|
||||
|
||||
if (pinnedParticipants.find(p => p.participantId === participantId)) {
|
||||
if (dominant?.id === participantId) {
|
||||
const { activeParticipants } = state['features/filmstrip'];
|
||||
const queue = activeParticipants.map(p => {
|
||||
if (p.participantId === participantId) {
|
||||
return {
|
||||
participantId,
|
||||
pinned: false
|
||||
};
|
||||
}
|
||||
|
||||
return p;
|
||||
});
|
||||
|
||||
dispatch(setStageParticipants(queue));
|
||||
} else {
|
||||
dispatch(removeStageParticipant(participantId));
|
||||
}
|
||||
} else {
|
||||
dispatch(addStageParticipant(participantId, true));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result ?? next(action);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { hideDialog, BottomSheet } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import {
|
||||
Icon,
|
||||
IconCar,
|
||||
IconDeviceBluetooth,
|
||||
IconDeviceEarpiece,
|
||||
IconDeviceHeadphone,
|
||||
@@ -125,6 +126,11 @@ const deviceInfoMap = {
|
||||
text: 'audioDevices.bluetooth',
|
||||
type: 'BLUETOOTH'
|
||||
},
|
||||
CAR: {
|
||||
icon: IconCar,
|
||||
text: 'audioDevices.car',
|
||||
type: 'CAR'
|
||||
},
|
||||
EARPIECE: {
|
||||
icon: IconDeviceEarpiece,
|
||||
text: 'audioDevices.phone',
|
||||
@@ -166,7 +172,7 @@ class AudioRoutePickerDialog extends Component<Props, State> {
|
||||
* @inheritdoc
|
||||
*/
|
||||
static getDerivedStateFromProps(props: Props) {
|
||||
const { _devices: devices } = props;
|
||||
const { _devices: devices, t } = props;
|
||||
|
||||
if (!devices) {
|
||||
return null;
|
||||
@@ -183,13 +189,18 @@ class AudioRoutePickerDialog extends Component<Props, State> {
|
||||
continue;
|
||||
}
|
||||
|
||||
const text = device.type === 'BLUETOOTH' && device.name ? device.name : infoMap.text;
|
||||
let text = t(infoMap.text);
|
||||
|
||||
// iOS provides descriptive names for these, use it.
|
||||
if ((device.type === 'BLUETOOTH' || device.type === 'CAR') && device.name) {
|
||||
text = device.name;
|
||||
}
|
||||
|
||||
if (infoMap) {
|
||||
const info = {
|
||||
...infoMap,
|
||||
selected: Boolean(device.selected),
|
||||
text: props.t(text),
|
||||
text,
|
||||
uid: device.uid
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class Notification extends AbstractNotification<Props> {
|
||||
description = { this._renderDescription() }
|
||||
icon = { this._mapAppearanceToIcon() }
|
||||
id = { uid }
|
||||
testId = { titleKey }
|
||||
testId = { titleKey || this._getDescriptionKey() }
|
||||
title = { title || t(titleKey, titleArguments) } />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { reloadNow } from '../../app/actions';
|
||||
import {
|
||||
isFatalJitsiConferenceError,
|
||||
isFatalJitsiConnectionError
|
||||
} from '../../base/lib-jitsi-meet';
|
||||
} from '../../base/lib-jitsi-meet/functions';
|
||||
import logger from '../logger';
|
||||
|
||||
import ReloadButton from './web/ReloadButton';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// @flow
|
||||
|
||||
import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
|
||||
import {
|
||||
JitsiConferenceErrors,
|
||||
isFatalJitsiConferenceError,
|
||||
isFatalJitsiConnectionError
|
||||
} from '../base/lib-jitsi-meet';
|
||||
} from '../base/lib-jitsi-meet/functions';
|
||||
import { StateListenerRegistry } from '../base/redux';
|
||||
|
||||
import { setFatalError } from './actions';
|
||||
|
||||
@@ -31,7 +31,7 @@ type Props = {
|
||||
function LobbyParticipantItems({ openDrawerForParticipant, overflowDrawer, participants }: Props) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div id = 'lobby-list'>
|
||||
{participants.map(p => (
|
||||
<LobbyParticipantItem
|
||||
key = { p.id }
|
||||
|
||||
@@ -6,7 +6,8 @@ declare var APP: Object;
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { getDialOutStatusUrl, getDialOutUrl, updateConfig } from '../base/config';
|
||||
import { browser, createLocalTrack } from '../base/lib-jitsi-meet';
|
||||
import { browser } from '../base/lib-jitsi-meet';
|
||||
import { createLocalTrack } from '../base/lib-jitsi-meet/functions';
|
||||
import { isVideoMutedByUser, MEDIA_TYPE } from '../base/media';
|
||||
import {
|
||||
createLocalTracksF,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user