Merge branch 'master' into conference-request-http

This commit is contained in:
Boris Grozev 2023-01-03 15:30:38 -06:00
commit b1284989df
20 changed files with 141 additions and 188 deletions

View File

@ -7,7 +7,7 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
@ -20,12 +20,11 @@ jobs:
- name: Check if the git repository is clean
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
- run: npm run lint:ci
- run: for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done
linux-build:
name: Build Frontend (Linux)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
@ -36,7 +35,7 @@ jobs:
name: Build Frontend (macOS)
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16

View File

@ -126,6 +126,12 @@ form {
background-size: contain;
}
.leftwatermarknomargin {
background-position: center left;
background-repeat: no-repeat;
background-size: contain;
}
.rightwatermark {
right: 32px;
top: 32px;

View File

@ -170,8 +170,9 @@ $welcomePageHeaderPaddingBottom: 0px;
$welcomePageHeaderTitleMaxWidth: initial;
$welcomePageHeaderTextAlign: center;
$welcomePageHeaderContainerMarginTop: 104px;
$welcomePageHeaderContainerDisplay: flex;
$welcomePageHeaderContainerMargin: 104px 32px 0 32px;
$welcomePageHeaderContainerMargin: $welcomePageHeaderContainerMarginTop auto 0;
$welcomePageHeaderTextTitleMarginBottom: 0;
$welcomePageHeaderTextTitleFontSize: 42px;

View File

@ -29,6 +29,16 @@ body.welcome-page {
flex-direction: column;
margin: $welcomePageHeaderContainerMargin;
z-index: $zindex2;
align-items: center;
position: relative;
max-width: 688px;
}
.header-watermark-container {
position: absolute;
width: 100%;
height: 100%;
margin-top: calc(20px - #{$welcomePageHeaderContainerMarginTop});
}
.header-text-title {
@ -123,16 +133,11 @@ body.welcome-page {
max-width: calc(100% - 40px);
padding: 16px 0 39px 0;
width: $welcomePageEnterRoomWidth;
text-align: center;
p {
color: $welcomePageDescriptionColor;
float: left;
text-align: $welcomePageHeaderTextAlign;
a {
color: inherit;
font-weight: 600;
}
a {
color: inherit;
font-weight: 600;
}
}
}
@ -200,8 +205,8 @@ body.welcome-page {
color: $welcomePageDescriptionColor;
padding: 4px;
position: absolute;
top: 32px;
right: 32px;
top: calc(35px - #{$welcomePageHeaderContainerMarginTop});
right: 0;
z-index: $zindex2;
* {
@ -224,6 +229,11 @@ body.welcome-page {
width: $welcomePageWatermarkWidth;
height: $welcomePageWatermarkHeight;
}
.watermark.leftwatermarknomargin {
width: $welcomePageWatermarkWidth;
height: $welcomePageWatermarkHeight;
}
}
&.without-content {
@ -242,10 +252,17 @@ body.welcome-page {
padding-top: 40px;
}
.welcome-card-row {
.welcome-card-column {
display: flex;
justify-content: center;
padding: 0 32px;
flex-direction: column;
align-items: center;
max-width: 688px;
margin: auto;
> div {
margin-bottom: 16px;
}
}
.welcome-card-text {
@ -253,7 +270,7 @@ body.welcome-page {
}
.welcome-card {
width: 49%;
width: 100%;
border-radius: 8px;
&--dark {
@ -268,10 +285,6 @@ body.welcome-page {
&--grey {
background: #F2F3F4;
}
&--shadow {
box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.15);
}
}
.welcome-footer {

View File

@ -147,6 +147,7 @@
"bridgeCount": "Serverzahl: ",
"codecs": "Codecs (A/V): ",
"connectedTo": "Verbunden mit:",
"e2eeVerified": "E2EE verifiziert:",
"framerate": "Bildwiederholrate:",
"less": "Weniger anzeigen",
"localaddress": "Lokale Adresse:",
@ -408,6 +409,10 @@
"user": "Anmeldename",
"userIdentifier": "Benutzername",
"userPassword": "Passwort",
"verifyParticipantConfirm": "Sie stimmen überein",
"verifyParticipantDismiss": "Sie stimmen nicht überein",
"verifyParticipantQuestion": "EXPERIMENTELL: Frage Person {{participantName}} ob sie den selben Inhalt in der selben Reihenfolge sieht.",
"verifyParticipantTitle": "Personsverifikation",
"videoLink": "Video-Link",
"viewUpgradeOptions": "Upgradeoptionen anzeigen",
"viewUpgradeOptionsContent": "Sie müssen Ihren Tarif erweitern, um Premium-Features wie Aufnahme, Transkription, RTMP-Streaming und mehr zu nutzen.",
@ -437,9 +442,6 @@
"noResults": "Keine Ergebnisse :(",
"search": "GIPHY durchsuchen"
},
"helpView": {
"title": "Hilfecenter"
},
"incomingCall": {
"answer": "Antworten",
"audioCallTitle": "Eingehender Anruf",
@ -563,7 +565,6 @@
"lobby": {
"admit": "Zulassen",
"admitAll": "Alle zulassen",
"allow": "Annehmen",
"backToKnockModeButton": "Kein Passwort, stattdessen Beitritt anfragen",
"chat": "Chat",
"dialogTitle": "Lobbymodus",
@ -649,6 +650,8 @@
"connectedOneMember": "{{name}} nimmt am Meeting teil",
"connectedThreePlusMembers": "{{name}} und {{count}} andere Personen nehmen am Meeting teil",
"connectedTwoMembers": "{{first}} und {{second}} nehmen am Meeting teil",
"dataChannelClosed": "Schlechte Videoqualität",
"dataChannelClosedDescription": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher ist die Videoqulität auf die schlechteste Stufe limitiert.",
"disconnected": "getrennt",
"displayNotifications": "Benachrichtigungen anzeigen für",
"focus": "Konferenzleitung",
@ -709,6 +712,8 @@
"reactionSoundsForAll": "Interaktionstöne für alle deaktivieren",
"screenShareNoAudio": "Die Option \"Audio freigeben\" wurde bei der Auswahl des Fensters nicht ausgewählt.",
"screenShareNoAudioTitle": "Share audio was not checked",
"screenSharingAudioOnlyDescription": "Durch die Bildschirmfreigabe wird der Modus \"Beste Leistung\" beeinflusst und daher mehr Datenrate benötigt.",
"screenSharingAudioOnlyTitle": "Modus \"Beste Leistung\"",
"selfViewTitle": "Sie können die eigene Ansicht immer in den Einstellungen reaktivieren",
"somebody": "Jemand",
"startSilentDescription": "Treten Sie dem Meeting noch einmal bei, um Ihr Audio zu aktivieren",
@ -858,9 +863,6 @@
"rejected": "Abgelehnt",
"ringing": "Es klingelt …"
},
"privacyView": {
"title": "Datenschutz"
},
"profile": {
"avatar": "Benutzerbild",
"setDisplayNameLabel": "Anzeigename festlegen",
@ -1003,6 +1005,7 @@
"displayName": "Anzeigename",
"displayNamePlaceholderText": "z.B. Erika Musterfrau",
"email": "E-Mail",
"emailPlaceholderText": "email@beispiel.de",
"goTo": "Gehe zu",
"header": "Einstellungen",
"help": "Hilfe",
@ -1011,6 +1014,7 @@
"profileSection": "Profil",
"serverURL": "Server-URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startCarModeInLowBandwidthMode": "Automodus mit Datensparmodus starten",
"startWithAudioMuted": "Stumm beitreten",
"startWithVideoMuted": "Ohne Video beitreten",
"terms": "Nutzungsbedingungen",
@ -1290,6 +1294,7 @@
"show": "Im Vordergrund anzeigen",
"showSelfView": "Eigene Ansicht anzeigen",
"unpinFromStage": "Lösen",
"verify": "Person verifizieren",
"videoMuted": "Kamera ausgeschaltet",
"videomute": "Person hat die Kamera angehalten"
},
@ -1357,6 +1362,7 @@
"recentList": "Verlauf",
"recentListDelete": "Eintrag löschen",
"recentListEmpty": "Ihr Konferenzverlauf ist derzeit leer. Reden Sie mit Ihrem Team und Ihre vergangenen Konferenzen landen hier.",
"recentMeetings": "Ihre letzten Konferenzen",
"reducedUIText": "Willkommen bei {{app}}!",
"roomNameAllowedChars": "Der Konferenzname sollte keines der folgenden Zeichen enthalten: ?, &, :, ', \", %, #.",
"roomname": "Konferenzname eingeben",
@ -1365,6 +1371,7 @@
"settings": "Einstellungen",
"startMeeting": "Meeting starten",
"terms": "AGB",
"title": "Sichere, voll funktionale und komplett kostenlose Videokonferenzen"
"title": "Sichere, voll funktionale und komplett kostenlose Videokonferenzen",
"upcomingMeetings": "Ihre zukünftigen Konferenzen"
}
}

View File

@ -1362,6 +1362,7 @@
"recentList": "Recent",
"recentListDelete": "Delete entry",
"recentListEmpty": "Your recent list is currently empty. Chat with your team and you will find all your recent meetings here.",
"recentMeetings": "Your recent meetings",
"reducedUIText": "Welcome to {{app}}!",
"roomNameAllowedChars": "Meeting name should not contain any of these characters: ?, &, :, ', \", %, #.",
"roomname": "Enter room name",
@ -1370,6 +1371,7 @@
"settings": "Settings",
"startMeeting": "Start meeting",
"terms": "Terms",
"title": "Secure, fully featured, and completely free video conferencing"
"title": "Secure, fully featured, and completely free video conferencing",
"upcomingMeetings": "Your upcoming meetings"
}
}

46
package-lock.json generated
View File

@ -74,7 +74,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1560.0.0+92a5738b/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1561.0.0+2d4cd935/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@ -13497,8 +13497,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1560.0.0+92a5738b/lib-jitsi-meet.tgz",
"integrity": "sha512-H8y04Nug8prhCYbtJuqNNpAqEE7ctOKor2RoCIxjVrmdtTbyRI8tmj4OPVDUOZZyAxF4l/V3aHmDz2JvWJU7Pw==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1561.0.0+2d4cd935/lib-jitsi-meet.tgz",
"integrity": "sha512-ec3XE3LheQQEkIBZ8mrfGdRDE/9yKM/CQpw7E2eF1zMQJGGREZRZ+Xqbhgv7o1eYPgI5GsAECns8ZjmWtre8bg==",
"license": "Apache-2.0",
"dependencies": {
"@jitsi/js-utils": "2.0.0",
@ -13571,9 +13571,9 @@
}
},
"node_modules/loader-utils": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.1.tgz",
"integrity": "sha512-1Qo97Y2oKaU+Ro2xnDMR26g1BwMT29jNbem1EvcujW2jqt+j5COXyscjM7bLQkM9HaxI7pkWeW7gnI072yMI9Q==",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
"integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
@ -14711,9 +14711,9 @@
}
},
"node_modules/null-loader/node_modules/loader-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
"integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
@ -18177,9 +18177,9 @@
}
},
"node_modules/string-replace-loader/node_modules/loader-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
"integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
@ -30496,8 +30496,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1560.0.0+92a5738b/lib-jitsi-meet.tgz",
"integrity": "sha512-H8y04Nug8prhCYbtJuqNNpAqEE7ctOKor2RoCIxjVrmdtTbyRI8tmj4OPVDUOZZyAxF4l/V3aHmDz2JvWJU7Pw==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1561.0.0+2d4cd935/lib-jitsi-meet.tgz",
"integrity": "sha512-ec3XE3LheQQEkIBZ8mrfGdRDE/9yKM/CQpw7E2eF1zMQJGGREZRZ+Xqbhgv7o1eYPgI5GsAECns8ZjmWtre8bg==",
"requires": {
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
@ -30565,9 +30565,9 @@
"dev": true
},
"loader-utils": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.1.tgz",
"integrity": "sha512-1Qo97Y2oKaU+Ro2xnDMR26g1BwMT29jNbem1EvcujW2jqt+j5COXyscjM7bLQkM9HaxI7pkWeW7gnI072yMI9Q==",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
"integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
@ -31474,9 +31474,9 @@
},
"dependencies": {
"loader-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
"integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
@ -34086,9 +34086,9 @@
},
"dependencies": {
"loader-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
"integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",

View File

@ -79,7 +79,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1560.0.0+92a5738b/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1561.0.0+2d4cd935/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@ -199,7 +199,8 @@
"tsc:web": "tsc --noEmit --project tsconfig.web.json",
"tsc:native": "tsc --noEmit --project tsconfig.native.json",
"tsc:ci": "npm run tsc:web && npm run tsc:native",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && npm run tsc:ci",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && npm run tsc:ci && npm run lint:lang",
"lint:lang": "for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done",
"lang-sort": "./resources/lang-sort.sh",
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
"postinstall": "patch-package --error-on-fail && jetify",

View File

@ -5,7 +5,6 @@ import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
import {
SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
SET_CAR_MODE,
SET_TILE_VIEW,
VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED
@ -102,7 +101,6 @@ MiddlewareRegistry.register(store => next => action => {
case PARTICIPANT_JOINED:
case PARTICIPANT_KICKED:
case PARTICIPANT_LEFT:
case SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED:
case SELECT_LARGE_VIDEO_PARTICIPANT:
case SET_AUDIO_ONLY:
case SET_CAR_MODE:

View File

@ -351,11 +351,11 @@ export function isWhiteboardParticipant(participant?: IParticipant): boolean {
* features/base/participants.
* @returns {number}
*/
export function getRemoteParticipantCount(stateful: IStateful) {
export function getRemoteParticipantCountWithFake(stateful: IStateful) {
const state = toState(stateful);
const participantsState = state['features/base/participants'];
return participantsState.remote.size - participantsState.sortedRemoteVirtualScreenshareParticipants.size;
return participantsState.remote.size;
}
/**

View File

@ -1,6 +1,3 @@
import {
SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED
} from '../../video-layout/actionTypes';
import ReducerRegistry from '../redux/ReducerRegistry';
import { set } from '../redux/functions';
@ -74,7 +71,6 @@ const DEFAULT_STATE = {
remote: new Map(),
sortedRemoteVirtualScreenshareParticipants: new Map(),
sortedRemoteParticipants: new Map(),
sortedRemoteScreenshares: new Map(),
speakersList: new Map()
};
@ -89,7 +85,6 @@ export interface IParticipantsState {
raisedHandsQueue: Array<{ id: string; raisedHandTimestamp: number; }>;
remote: Map<string, IParticipant>;
sortedRemoteParticipants: Map<string, string>;
sortedRemoteScreenshares: Map<string, string>;
sortedRemoteVirtualScreenshareParticipants: Map<string, string>;
speakersList: Map<string, string>;
}
@ -385,29 +380,6 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
raisedHandsQueue: action.queue
};
}
case SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED: {
const { participantIds } = action;
const sortedSharesList = [];
for (const participant of participantIds) {
const remoteParticipant = state.remote.get(participant);
if (remoteParticipant) {
const displayName
= _getDisplayName(state, remoteParticipant.name);
sortedSharesList.push([ participant, displayName ]);
}
}
// Keep the remote screen share list sorted alphabetically.
sortedSharesList.length && sortedSharesList.sort((a, b) => a[1].localeCompare(b[1]));
// @ts-ignore
state.sortedRemoteScreenshares = new Map(sortedSharesList);
return { ...state };
}
case OVERWRITE_PARTICIPANT_NAME: {
const { id, name } = action;

View File

@ -38,6 +38,11 @@ type Props = {
*/
_showJitsiWatermark: boolean,
/**
* Whether the watermark should have a `top` and `left` value.
*/
noMargins: boolean;
/**
* The default value for the Jitsi logo URL.
*/
@ -160,7 +165,9 @@ class Watermarks extends Component<Props, State> {
_logoUrl,
_showJitsiWatermark
} = this.props;
const { t } = this.props;
const { noMargins, t } = this.props;
const className = `watermark ${noMargins ? 'leftwatermarknomargin' : 'leftwatermark'}`;
let reactElement = null;
if (_showJitsiWatermark) {
@ -172,14 +179,14 @@ class Watermarks extends Component<Props, State> {
};
reactElement = (<div
className = 'watermark leftwatermark'
className = { className }
style = { style } />);
if (_logoLink) {
reactElement = (
<a
aria-label = { t('jitsiHome', { logo: interfaceConfig.APP_NAME }) }
className = 'watermark leftwatermark'
className = { className }
href = { _logoLink }
target = '_new'>
{ reactElement }

View File

@ -2,7 +2,8 @@ import { IReduxState, IStore } from '../../app/types';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { setPictureInPictureEnabled } from '../../mobile/picture-in-picture/functions';
import { setAudioOnly } from '../audio-only/actions';
import { showNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import JitsiMeetJS from '../lib-jitsi-meet';
import {
setScreenshareMuted,
@ -75,7 +76,11 @@ async function _startScreenSharing(dispatch: Function, state: IReduxState) {
const { enabled: audioOnly } = state['features/base/audio-only'];
if (audioOnly) {
dispatch(setAudioOnly(false));
dispatch(showNotification({
titleKey: 'notify.screenSharingAudioOnlyTitle',
descriptionKey: 'notify.screenSharingAudioOnlyDescription',
maxLines: 3
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
}
} catch (error: any) {
console.log('ERROR creating ScreeSharing stream ', error);

View File

@ -3,7 +3,7 @@ import { pinParticipant } from '../base/participants/actions';
import {
getLocalParticipant,
getParticipantById,
getRemoteParticipantCount
getRemoteParticipantCountWithFake
} from '../base/participants/functions';
import { shouldHideSelfView } from '../base/settings/functions.web';
import { getMaxColumnCount } from '../video-layout/functions.web';
@ -149,7 +149,7 @@ export function setVerticalViewDimensions() {
const disableSelfView = shouldHideSelfView(state);
const resizableFilmstrip = isFilmstripResizable(state);
const _verticalViewGrid = showGridInVerticalView(state);
const numberOfRemoteParticipants = getRemoteParticipantCount(state);
const numberOfRemoteParticipants = getRemoteParticipantCountWithFake(state);
const { localScreenShare } = state['features/base/participants'];
let gridView = {};
@ -261,7 +261,7 @@ export function setHorizontalViewDimensions() {
= clientWidth - (disableSelfView ? 0 : thumbnails?.local?.width) - HORIZONTAL_FILMSTRIP_MARGIN;
const remoteVideosContainerHeight
= thumbnails?.local?.height + TILE_VERTICAL_MARGIN + STAGE_VIEW_THUMBNAIL_VERTICAL_BORDER + SCROLL_SIZE;
const numberOfRemoteParticipants = getRemoteParticipantCount(state);
const numberOfRemoteParticipants = getRemoteParticipantCountWithFake(state);
const hasScroll
= remoteVideosContainerHeight
< (thumbnails?.remote.width + TILE_HORIZONTAL_MARGIN) * numberOfRemoteParticipants;

View File

@ -1,15 +1,3 @@
/**
* The type of the action which sets the list of known remote participant IDs which
* have an active screen share.
*
* @returns {{
* type: SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
* participantIds: Array<string>
* }}
*/
export const SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED
= 'SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED';
/**
* The type of the action which tells whether we are in carmode.
*

View File

@ -1,30 +1,11 @@
import { IStore } from '../app/types';
import {
SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
SET_TILE_VIEW,
VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED
} from './actionTypes';
import { shouldDisplayTileView } from './functions';
/**
* Creates a (redux) action which signals that the list of known remote participants
* with screen shares has changed.
*
* @param {string} participantIds - The remote participants which currently have active
* screen share streams.
* @returns {{
* type: SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
* participantId: string
* }}
*/
export function setRemoteParticipantsWithScreenShare(participantIds: Array<string>) {
return {
type: SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
participantIds
};
}
/**
* Creates a (redux) action which signals that the list of known remote virtual screen share participant ids has
* changed.

View File

@ -1,18 +1,16 @@
import { IStore } from '../app/types';
import { getCurrentConference } from '../base/conference/functions';
import { VIDEO_TYPE } from '../base/media/constants';
import { PARTICIPANT_LEFT, PIN_PARTICIPANT } from '../base/participants/actionTypes';
import { pinParticipant } from '../base/participants/actions';
import { getParticipantById, getPinnedParticipant } from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { TRACK_REMOVED } from '../base/tracks/actionTypes';
import { SET_DOCUMENT_EDITING_STATUS } from '../etherpad/actionTypes';
import { isStageFilmstripEnabled } from '../filmstrip/functions';
import { isFollowMeActive } from '../follow-me/functions';
import { SET_TILE_VIEW } from './actionTypes';
import { setRemoteParticipantsWithScreenShare, setTileView } from './actions';
import { setTileView } from './actions';
import { getAutoPinSetting, updateAutoPinnedParticipant } from './functions';
import './subscriber';
@ -74,31 +72,6 @@ MiddlewareRegistry.register(store => next => action => {
}
break;
}
// Update the remoteScreenShares.
// Because of the debounce in the subscriber which updates the remoteScreenShares we need to handle
// removal of screen shares separately here. Otherwise it is possible to have screen sharing
// participant that has already left in the remoteScreenShares array. This can lead to rendering
// a thumbnails for already left participants since the remoteScreenShares array is used for
// building the ordered list of remote participants.
case TRACK_REMOVED: {
const { jitsiTrack } = action.track;
if (jitsiTrack?.isVideoTrack() && jitsiTrack?.getVideoType() === VIDEO_TYPE.DESKTOP) {
const participantId = jitsiTrack.getParticipantId();
const oldScreenShares = store.getState()['features/video-layout'].remoteScreenShares || [];
const newScreenShares = oldScreenShares.filter(id => id !== participantId);
if (oldScreenShares.length !== newScreenShares.length) { // the participant was removed
store.dispatch(setRemoteParticipantsWithScreenShare(newScreenShares));
updateAutoPinnedParticipant(oldScreenShares, store);
}
}
break;
}
}
if (shouldUpdateAutoPin) {

View File

@ -1,7 +1,6 @@
import ReducerRegistry from '../base/redux/ReducerRegistry';
import {
SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
SET_CAR_MODE,
SET_TILE_VIEW,
VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED
@ -41,7 +40,6 @@ const STORE_NAME = 'features/video-layout';
ReducerRegistry.register<IVideoLayoutState>(STORE_NAME, (state = DEFAULT_STATE, action): IVideoLayoutState => {
switch (action.type) {
case SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED:
case VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED:
return {
...state,

View File

@ -274,7 +274,7 @@ export class AbstractWelcomePage<P: Props> extends Component<P, *> {
export function _mapStateToProps(state: Object) {
return {
_calendarEnabled: isCalendarEnabled(state),
_deeplinkingCfg: state['features/base/config'].deeplinking,
_deeplinkingCfg: state['features/base/config'].deeplinking || {},
_enableInsecureRoomNameWarning: state['features/base/config'].enableInsecureRoomNameWarning || false,
_moderatedRoomServiceUrl: state['features/base/config'].moderatedRoomServiceUrl,
_recentListEnabled: isRecentListEnabled(),

View File

@ -184,24 +184,27 @@ class WelcomePage extends AbstractWelcomePage {
<div
className = { `welcome ${contentClassName} ${footerClassName}` }
id = 'welcome_page'>
<div className = 'welcome-watermark'>
<Watermarks defaultJitsiLogoURL = { DEFAULT_WELCOME_PAGE_LOGO_URL } />
</div>
<div className = 'header'>
<div className = 'welcome-page-settings'>
<SettingsButton
defaultTab = { SETTINGS_TABS.CALENDAR }
isDisplayedOnWelcomePage = { true } />
{ showAdditionalToolbarContent
? <div
className = 'settings-toolbar-content'
ref = { this._setAdditionalToolbarContentRef } />
: null
}
</div>
<div className = 'header-image' />
<div className = 'header-container'>
<div className = 'header-watermark-container'>
<div className = 'welcome-watermark'>
<Watermarks
defaultJitsiLogoURL = { DEFAULT_WELCOME_PAGE_LOGO_URL }
noMargins = { true } />
</div>
</div>
<div className = 'welcome-page-settings'>
<SettingsButton
defaultTab = { SETTINGS_TABS.CALENDAR }
isDisplayedOnWelcomePage = { true } />
{ showAdditionalToolbarContent
? <div
className = 'settings-toolbar-content'
ref = { this._setAdditionalToolbarContentRef } />
: null
}
</div>
<h1 className = 'header-text-title'>
{ t('welcomepage.headerTitle') }
</h1>
@ -246,18 +249,16 @@ class WelcomePage extends AbstractWelcomePage {
{ _moderatedRoomServiceUrl && (
<div id = 'moderated-meetings'>
<p>
{
translateToHTML(
t, 'welcomepage.moderatedMessage', { url: _moderatedRoomServiceUrl })
}
</p>
{
translateToHTML(
t, 'welcomepage.moderatedMessage', { url: _moderatedRoomServiceUrl })
}
</div>)}
</div>
</div>
<div className = 'welcome-cards-container'>
<div className = 'welcome-card-row'>
<div className = 'welcome-card-column'>
<div className = 'welcome-tabs welcome-card welcome-card--blue'>
{ this._renderTabs() }
</div>
@ -346,14 +347,15 @@ class WelcomePage extends AbstractWelcomePage {
const {
t,
_deeplinkingCfg: {
ios: { downloadLink: iosDownloadLink },
android: {
fDroidUrl,
downloadLink: androidDownloadLink
}
ios = {},
android = {}
}
} = this.props;
const { downloadLink: iosDownloadLink } = ios;
const { fDroidUrl, downloadLink: androidDownloadLink } = android;
return (<footer className = 'welcome-footer'>
<div className = 'welcome-footer-centered'>
<div className = 'welcome-footer-padded'>
@ -403,14 +405,14 @@ class WelcomePage extends AbstractWelcomePage {
if (_calendarEnabled) {
tabs.push({
label: t('welcomepage.calendar'),
label: t('welcomepage.upcomingMeetings'),
content: <CalendarList />
});
}
if (_recentListEnabled) {
tabs.push({
label: t('welcomepage.recentList'),
label: t('welcomepage.recentMeetings'),
content: <RecentList />
});
}