mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-31 11:52:29 +00:00
Compare commits
171 Commits
8705
...
debug-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ff3219935 | ||
|
|
386bdbfc22 | ||
|
|
a45453e391 | ||
|
|
07554a156b | ||
|
|
70c3c8db13 | ||
|
|
9bb1c36508 | ||
|
|
a93ca9d7c4 | ||
|
|
d2f20c49af | ||
|
|
c5f82d4f20 | ||
|
|
36a3e700e1 | ||
|
|
77464ddcc4 | ||
|
|
36ce5a1661 | ||
|
|
23c831e9b0 | ||
|
|
e6fbeb9458 | ||
|
|
e15a59c994 | ||
|
|
f5e1a97d64 | ||
|
|
cd25652182 | ||
|
|
2bf0b1922f | ||
|
|
469406d7cd | ||
|
|
60679aa2d3 | ||
|
|
319e8d1e4b | ||
|
|
40b8d6168b | ||
|
|
753d0399c9 | ||
|
|
2475aff21a | ||
|
|
121aabeb25 | ||
|
|
086f01aa5b | ||
|
|
6b6920693b | ||
|
|
566b3ba2d5 | ||
|
|
7373123166 | ||
|
|
cc312877f4 | ||
|
|
eb8b6159ec | ||
|
|
f9d8feacd2 | ||
|
|
f5668b6e8b | ||
|
|
4219d9ad4d | ||
|
|
d68b9b1cad | ||
|
|
8f0b9575c4 | ||
|
|
f780207c22 | ||
|
|
ce19e6d40b | ||
|
|
b108db832f | ||
|
|
e4283e61dd | ||
|
|
50e2458124 | ||
|
|
329df31811 | ||
|
|
fce39be9d2 | ||
|
|
6c5a9ea199 | ||
|
|
196192c97f | ||
|
|
71f358c62a | ||
|
|
7aa7e76ccd | ||
|
|
cd77b6bbe4 | ||
|
|
e94df6799e | ||
|
|
2e92818b53 | ||
|
|
8a3129f7bf | ||
|
|
eb03642ea6 | ||
|
|
c436e48956 | ||
|
|
58db02bab8 | ||
|
|
abc1f3d33b | ||
|
|
b2166d9874 | ||
|
|
901a13a99a | ||
|
|
1e15d9421b | ||
|
|
9252bbb036 | ||
|
|
f1bae8bc10 | ||
|
|
5a54511d2c | ||
|
|
61764273b2 | ||
|
|
e39f38f75b | ||
|
|
2d25f48c72 | ||
|
|
2cb727fc58 | ||
|
|
c069c0d7c3 | ||
|
|
5de69d501d | ||
|
|
599c88a71d | ||
|
|
5476321df6 | ||
|
|
076b6a2a7e | ||
|
|
8b9df0cd37 | ||
|
|
44f5de3db4 | ||
|
|
fb69225d42 | ||
|
|
32df284277 | ||
|
|
253679cfb9 | ||
|
|
057c19f4dd | ||
|
|
6159a23c55 | ||
|
|
1685c39c5d | ||
|
|
2cecc61b97 | ||
|
|
df2262ae53 | ||
|
|
d61deab163 | ||
|
|
e7eab72c0c | ||
|
|
c1e803c6e3 | ||
|
|
dc1f20e059 | ||
|
|
61ee9af304 | ||
|
|
d75de3642e | ||
|
|
1ae1729545 | ||
|
|
8cea505417 | ||
|
|
b0a96b32d2 | ||
|
|
dac9b5e244 | ||
|
|
d15cfd845a | ||
|
|
91e4ac1665 | ||
|
|
fda42e5230 | ||
|
|
142d4441c1 | ||
|
|
5814c4dda7 | ||
|
|
8c1dc03363 | ||
|
|
ff6fc198f1 | ||
|
|
f1a0012fc1 | ||
|
|
85522aea25 | ||
|
|
000c370c64 | ||
|
|
a762d585b8 | ||
|
|
ded8f22363 | ||
|
|
c3e1c9d568 | ||
|
|
8901132af9 | ||
|
|
71f92f6e17 | ||
|
|
76166df81a | ||
|
|
eb2ba39289 | ||
|
|
048b089acd | ||
|
|
b774f18f80 | ||
|
|
dbe4e6a784 | ||
|
|
d2e52d2c2a | ||
|
|
b5ad984dab | ||
|
|
81ce664ad7 | ||
|
|
181ef92e1f | ||
|
|
79dbc2d1ee | ||
|
|
f56ce78b9d | ||
|
|
8269b88796 | ||
|
|
252ef4604a | ||
|
|
fc816aa149 | ||
|
|
6de18fe82d | ||
|
|
5b7e3bb2d7 | ||
|
|
bc08b38791 | ||
|
|
6613f630d7 | ||
|
|
719b6d68c8 | ||
|
|
6a62c5120f | ||
|
|
64270f3015 | ||
|
|
cb621f8e32 | ||
|
|
3c80cfddd7 | ||
|
|
557f6defb8 | ||
|
|
52fa36f930 | ||
|
|
b050e5f5e8 | ||
|
|
bf8d83953b | ||
|
|
f16bf466eb | ||
|
|
29ea811527 | ||
|
|
435d034fdb | ||
|
|
419baa7ab7 | ||
|
|
9eb7b7bb01 | ||
|
|
19ee989cda | ||
|
|
ab1dcc5375 | ||
|
|
3047b4c8c4 | ||
|
|
2afce3d151 | ||
|
|
1cea9b1786 | ||
|
|
2b7299ae05 | ||
|
|
4b50f13e96 | ||
|
|
c639acebcf | ||
|
|
1a34ed9a2d | ||
|
|
0939e207eb | ||
|
|
8c3ea05ae6 | ||
|
|
daf8a929b1 | ||
|
|
2f3df2c66f | ||
|
|
d8d1f8331e | ||
|
|
0e69336f94 | ||
|
|
ede8ae6cb9 | ||
|
|
7e57156d2a | ||
|
|
6742435487 | ||
|
|
99f34aaef4 | ||
|
|
69f9838c03 | ||
|
|
dbfd24261d | ||
|
|
2305ae85a0 | ||
|
|
31a30f1118 | ||
|
|
eacf7addb2 | ||
|
|
2cf788ebee | ||
|
|
6bd3ed5ae4 | ||
|
|
b511f4b8df | ||
|
|
ead019f71b | ||
|
|
7a97d15e89 | ||
|
|
1acb99d763 | ||
|
|
adbe990867 | ||
|
|
a4367567ab | ||
|
|
7f56cbc4ce | ||
|
|
d636d084c8 |
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@@ -103,7 +103,7 @@ jobs:
|
||||
android-sdk-build:
|
||||
name: Build mobile SDK (Android)
|
||||
runs-on: ubuntu-latest
|
||||
container: reactnativecommunity/react-native-android:v13.0
|
||||
container: reactnativecommunity/react-native-android:v18.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@@ -139,6 +139,12 @@ jobs:
|
||||
xcode-select -p
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
||||
xcodebuild -version
|
||||
- name: clean Xcode
|
||||
run: |
|
||||
rm -rf ios/sdk/out
|
||||
xcodebuild clean \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK
|
||||
- name: setup-cocoapods
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
@@ -149,15 +155,13 @@ jobs:
|
||||
working-directory: ./ios
|
||||
run: bundle exec pod install --repo-update --deployment
|
||||
- run: |
|
||||
xcodebuild clean \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK
|
||||
xcodebuild -downloadPlatform iOS -buildVersion 18.2
|
||||
xcodebuild archive \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK \
|
||||
-configuration Release \
|
||||
-sdk iphoneos \
|
||||
-destination='generic/platform=iOS' \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-archivePath ios/sdk/out/ios-device \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
|
||||
267
CLAUDE.md
Normal file
267
CLAUDE.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Building and Development
|
||||
- `npm run lint-fix` - Automatically fix linting issues
|
||||
- `npm run tsc:ci` - Run TypeScript checks for both web and native platforms
|
||||
- `npm run tsc:web` - TypeScript check for web platform only
|
||||
- `npm run tsc:native` - TypeScript check for native platform only
|
||||
- `npm run lint:ci` - Run ESLint without type checking
|
||||
- `make dev` - Start development server with webpack-dev-server
|
||||
- `make compile` - Build production bundles
|
||||
- `make clean` - Clean build directory
|
||||
- `make all` - Full build (compile + deploy)
|
||||
|
||||
### Testing
|
||||
- `npm test` - Run full test suite using WebDriverIO
|
||||
- `npm run test-single -- <spec-file>` - Run single test file
|
||||
- `npm run test-dev` - Run tests against development environment
|
||||
- `npm run test-dev-single -- <spec-file>` - Run single test in dev mode
|
||||
|
||||
|
||||
### Language Tools
|
||||
- `npm run lang-sort` - Sort language files
|
||||
- `npm run lint:lang` - Validate JSON language files
|
||||
|
||||
### Platform-Specific TypeScript
|
||||
TypeScript configuration is split between web and native platforms with separate tsconfig files.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Multi-Platform Structure
|
||||
Jitsi Meet supports both web and React Native platforms with platform-specific file extensions and directories:
|
||||
- `.web.ts/.web.tsx` - Web-specific implementations
|
||||
- `.native.ts/.native.tsx` - React Native-specific implementations
|
||||
- `.any.ts/.any.tsx` - Shared cross-platform code
|
||||
- `.android.ts/.android.tsx` - Android-specific code
|
||||
- `.ios.ts/.ios.tsx` - iOS-specific code
|
||||
- `web/` directories - Web-specific components and modules
|
||||
- `native/` directories - React Native-specific components and modules
|
||||
- `react/features/mobile/` - Native-only features
|
||||
|
||||
### Core Directories
|
||||
- `react/features/` - Main application features organized by domain (83+ feature modules)
|
||||
- `modules/` - Legacy JavaScript modules and APIs
|
||||
- `css/` - SCSS stylesheets compiled to CSS
|
||||
- `libs/` - Compiled output directory for JavaScript bundles
|
||||
- `static/` - Static assets and HTML files
|
||||
- `tests/` - WebDriverIO end-to-end tests
|
||||
|
||||
### Feature-Driven Architecture
|
||||
The application is organized under `react/features/` with each feature containing:
|
||||
|
||||
- **`actionTypes.ts`** - Redux action type constants
|
||||
- **`actions.ts`** - Redux action creators (platform-specific variants with `.any.ts`, `.web.ts`, `.native.ts`)
|
||||
- **`reducer.ts`** - Redux reducer functions
|
||||
- **`middleware.ts`** - Redux middleware for side effects
|
||||
- **`functions.ts`** - Utility functions and selectors
|
||||
- **`constants.ts`** - Feature-specific constants
|
||||
- **`logger.ts`** - Feature-specific logger instance
|
||||
- **`types.ts`** - TypeScript type definitions
|
||||
|
||||
### Key Application Files
|
||||
- `app.js` - Main web application entry point
|
||||
- `webpack.config.js` - Multi-bundle Webpack configuration
|
||||
- `Makefile` - Build system for development and production
|
||||
- `package.json` - Dependencies and scripts with version requirements
|
||||
|
||||
### Bundle Architecture
|
||||
The application builds multiple bundles:
|
||||
- `app.bundle.js` / `app.bundle.min.js` - Main application bundle (entry: `./app.js`)
|
||||
- `external_api.js` / `external_api.min.js` - External API for embedders (entry: `./modules/API/external/index.js`)
|
||||
- `alwaysontop.js` / `alwaysontop.min.js` - Always-on-top window functionality (entry: `./react/features/always-on-top/index.tsx`)
|
||||
- `close3.js` / `close3.min.js` - Close3 functionality (entry: `./static/close3.js`)
|
||||
- `face-landmarks-worker.js` / `face-landmarks-worker.min.js` - Face landmarks detection worker (entry: `./react/features/face-landmarks/faceLandmarksWorker.ts`)
|
||||
- `noise-suppressor-worklet.js` / `noise-suppressor-worklet.min.js` - Audio noise suppression worklet (entry: `./react/features/stream-effects/noise-suppression/NoiseSuppressorWorklet.ts`)
|
||||
- `screenshot-capture-worker.js` / `screenshot-capture-worker.min.js` - Screenshot capture worker (entry: `./react/features/screenshot-capture/worker.ts`)
|
||||
|
||||
### Redux Architecture
|
||||
Features follow a Redux-based architecture with:
|
||||
- Actions, reducers, and middleware in each feature directory
|
||||
- Cross-platform state management
|
||||
- Modular feature organization with clear boundaries
|
||||
|
||||
The codebase uses a registry-based Redux architecture:
|
||||
- **ReducerRegistry** - Features register their reducers independently
|
||||
- **MiddlewareRegistry** - Features register middleware without cross-dependencies
|
||||
- **IReduxState** - Global state is strongly typed with 80+ feature states
|
||||
|
||||
### Dependencies
|
||||
- Uses `lib-jitsi-meet` as the core WebRTC library
|
||||
- React with TypeScript support
|
||||
- React Native for mobile applications
|
||||
- Webpack for bundling with development server
|
||||
|
||||
### TypeScript Configuration
|
||||
- `tsconfig.web.json` - Web platform TypeScript config (excludes native files)
|
||||
- `tsconfig.native.json` - React Native TypeScript config (excludes web files)
|
||||
- Strict TypeScript settings with ES2024 target
|
||||
- Platform-specific module suffixes (`.web`, `.native`)
|
||||
|
||||
### Key Base Features
|
||||
- **`base/app/`** - Application lifecycle management
|
||||
- **`base/conference/`** - Core conference logic
|
||||
- **`base/tracks/`** - Media track management
|
||||
- **`base/participants/`** - Participant management
|
||||
- **`base/config/`** - Configuration management
|
||||
- **`base/redux/`** - Redux infrastructure
|
||||
|
||||
### Component Patterns
|
||||
- **Abstract Components** - Base classes for cross-platform components
|
||||
- **Platform-Specific Components** - Separate implementations in `web/` and `native/` directories
|
||||
- **Hook-based patterns** - Modern React patterns for component logic
|
||||
### Testing Framework
|
||||
- WebDriverIO for end-to-end testing
|
||||
- Test files are located in `tests/specs/` and use page objects in `tests/pageobjects/`.
|
||||
- Environment configuration via `.env` files
|
||||
- Support for Chrome, Firefox, and grid testing
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Adding New Features
|
||||
1. Create feature directory under `react/features/[feature-name]/`
|
||||
2. Follow the standard file structure (actionTypes, actions, reducer, etc.)
|
||||
3. Register reducers and middleware using the registry pattern
|
||||
4. Define TypeScript interfaces for state and props
|
||||
5. Use platform-specific files for web/native differences
|
||||
6. Add feature-specific logger for debugging
|
||||
|
||||
### Working with Existing Features
|
||||
1. Check for existing `.any.ts`, `.web.ts`, `.native.ts` variants
|
||||
2. Follow established action-reducer-middleware patterns
|
||||
3. Use existing base utilities rather than creating new ones
|
||||
4. Leverage abstract components for cross-platform logic
|
||||
5. Maintain type safety across the entire state tree
|
||||
|
||||
### Testing
|
||||
The project uses WebDriver (WebdriverIO) for end-to-end testing. Test files are located in `tests/specs/` and use page objects in `tests/pageobjects/`.
|
||||
|
||||
### Build System
|
||||
- **Webpack** - Main build system for web bundles
|
||||
- **Makefile** - Coordinates build process and asset deployment
|
||||
- **Metro** - React Native bundler (configured in `metro.config.js`)
|
||||
|
||||
### Platform-Specific Notes
|
||||
- Web builds exclude files matching `**/native/*`, `**/*.native.ts`, etc.
|
||||
- Native builds exclude files matching `**/web/*`, `**/*.web.ts`, etc.
|
||||
- Use `moduleSuffixes` in TypeScript config to handle platform-specific imports
|
||||
- Check `tsconfig.web.json` and `tsconfig.native.json` for platform-specific exclusions
|
||||
|
||||
## Environment and Setup Requirements
|
||||
|
||||
### System Requirements
|
||||
- **Node.js and npm** are required
|
||||
- Development server runs at https://localhost:8080/
|
||||
- Certificate errors in development are expected (self-signed certificates)
|
||||
|
||||
### Development Workflow
|
||||
- Development server proxies to configurable target (default: https://alpha.jitsi.net)
|
||||
- Hot module replacement enabled for development
|
||||
- Bundle analysis available via `ANALYZE_BUNDLE=true` environment variable
|
||||
- Circular dependency detection via `DETECT_CIRCULAR_DEPS=true`
|
||||
|
||||
## Code Quality Requirements
|
||||
- All code must pass `npm run lint:ci` and `npm run tsc:ci` with 0 warnings before committing
|
||||
- TypeScript strict mode enabled - avoid `any` type
|
||||
- ESLint config extends `@jitsi/eslint-config`
|
||||
- Prefer TypeScript for new features, convert existing JavaScript when possible
|
||||
|
||||
## Code Style and Standards
|
||||
|
||||
### Conventional Commits Format
|
||||
Follow [Conventional Commits](https://www.conventionalcommits.org) with **mandatory scopes**:
|
||||
```
|
||||
feat(feature-name): description
|
||||
fix(feature-name): description
|
||||
docs(section): description
|
||||
```
|
||||
Available types: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test
|
||||
|
||||
### Feature Layout Structure
|
||||
When adding new features:
|
||||
```
|
||||
react/features/sample/
|
||||
├── actionTypes.ts
|
||||
├── actions.ts
|
||||
├── components/
|
||||
│ ├── AnotherComponent.tsx
|
||||
│ └── OneComponent.tsx
|
||||
├── middleware.ts
|
||||
└── reducer.ts
|
||||
```
|
||||
|
||||
### TypeScript Requirements
|
||||
- All new features must be written in TypeScript
|
||||
- Convert JavaScript to TypeScript when modifying existing code
|
||||
- Import middleware in `react/features/app/middlewares.{any,native,web}.js`
|
||||
- Import reducers in appropriate registry files
|
||||
- Avoid `index` files
|
||||
|
||||
### Bundle Size Management
|
||||
- Bundle size limits are enforced to prevent bloat
|
||||
- For increases, analyze first: `npx webpack -p --analyze-bundle`
|
||||
- Open analyzer: `npx webpack-bundle-analyzer build/app-stats.json`
|
||||
- Justify any dependency additions that increase bundle size
|
||||
|
||||
## Testing and Quality Assurance
|
||||
|
||||
### Tests
|
||||
- End-to-end tests are defined in the tests/
|
||||
- Tests run automatically for project member PRs via Jenkins
|
||||
- Tests cover peer-to-peer, invites, iOS, Android, and web platforms
|
||||
- Beta testing available at https://beta.meet.jit.si/
|
||||
|
||||
### Manual Testing Checklist
|
||||
- Test with 2 participants (P2P mode)
|
||||
- Test with 3+ participants (JVB mode)
|
||||
- Verify audio/video in both modes
|
||||
- Test mobile apps if changes affect mobile
|
||||
- Check that TLS certificate chain is complete for mobile app compatibility
|
||||
|
||||
## Common Issues and Debugging
|
||||
|
||||
### P2P vs JVB Problems
|
||||
- **Works with 2 participants, fails with 3+**: JVB/firewall issue, check UDP 10000
|
||||
- **Works on web, fails on mobile apps**: TLS certificate chain issue, need fullchain.pem
|
||||
- Use the tests from tests/ directory to verify functionality across platforms
|
||||
|
||||
### Development Server Issues
|
||||
- Certificate warnings are normal for development (self-signed)
|
||||
- Use different backend with WEBPACK_DEV_SERVER_PROXY_TARGET environment variable
|
||||
- Check firewall settings if local development fails
|
||||
|
||||
### Configuration and Customization
|
||||
- Extensive configuration options documented in handbook
|
||||
- See `config.js` for client-side options
|
||||
- Options marked 🚫 are not overwritable through `configOverwrite`
|
||||
- Reference [Configuration Guide](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration) for details
|
||||
|
||||
## Architecture Deep Dive
|
||||
|
||||
### Core Application Files
|
||||
- **`./conference.js`** - Foundation for user-conference interactions (connection, joining, muting)
|
||||
- **`./modules/external-api`** - External API for iframe integration and events
|
||||
- **`./lang/`** - Translations in `main-[language].json` files
|
||||
- **`./css/`** - SCSS files organized by features, matching React feature structure
|
||||
|
||||
### State Management Flow
|
||||
1. Actions dispatched from components
|
||||
2. Middleware processes side effects
|
||||
3. Reducers update state
|
||||
4. Components re-render based on state changes
|
||||
5. Registry pattern keeps features decoupled
|
||||
|
||||
### Cross-Platform Strategy
|
||||
- Abstract components handle shared logic
|
||||
- Platform files (.web.ts, .native.ts) handle platform differences
|
||||
- Build system excludes irrelevant platform files
|
||||
- TypeScript configs ensure proper platform targeting
|
||||
|
||||
## External Resources
|
||||
- [Jitsi Handbook](https://jitsi.github.io/handbook/) - Comprehensive documentation
|
||||
- [Community Forum](https://community.jitsi.org/) - Ask questions and get support
|
||||
- [Architecture Guide](https://jitsi.github.io/handbook/docs/architecture) - System overview
|
||||
- [Contributing Guidelines](https://jitsi.github.io/handbook/docs/dev-guide/contributing) - Detailed contribution process
|
||||
@@ -1,4 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
// Crashlytics integration is done as part of Firebase now, so it gets
|
||||
// automagically activated with google-services.json
|
||||
@@ -27,6 +28,14 @@ android {
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DANDROID_STL=c++_shared"
|
||||
cppFlags "-std=c++17"
|
||||
cFlags "-DANDROID_PLATFORM=android-26"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -45,8 +54,8 @@ android {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
release {
|
||||
// Uncomment the following line for singing a test release build.
|
||||
//signingConfig signingConfigs.debug
|
||||
// Uncomment the following line for signing a test release build.
|
||||
// signingConfig signingConfigs.debug
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.pro'
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}"
|
||||
@@ -66,9 +75,18 @@ android {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility rootProject.ext.javaVersion
|
||||
targetCompatibility rootProject.ext.javaVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = rootProject.ext.jvmTargetVersion
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(rootProject.ext.jvmToolchainVersion)
|
||||
}
|
||||
|
||||
namespace 'org.jitsi.meet'
|
||||
}
|
||||
|
||||
@@ -92,8 +110,6 @@ dependencies {
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
// Dropbox integration
|
||||
//
|
||||
|
||||
def dropboxAppKey
|
||||
if (project.file('dropbox.key').exists()) {
|
||||
dropboxAppKey = project.file('dropbox.key').text.trim() - 'db-'
|
||||
@@ -164,7 +180,6 @@ gradle.projectsEvaluated {
|
||||
|
||||
packageTask.dependsOn(currentRunPackagerTask)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (googleServicesEnabled) {
|
||||
|
||||
@@ -4,3 +4,7 @@
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep public class * extends java.lang.Exception
|
||||
|
||||
# R8 missing classes - suppress warnings
|
||||
-dontwarn com.facebook.memory.config.MemorySpikeConfig
|
||||
-dontwarn kotlinx.parcelize.Parcelize
|
||||
|
||||
5
android/app/proguard-rules.pro
vendored
5
android/app/proguard-rules.pro
vendored
@@ -96,8 +96,3 @@
|
||||
|
||||
# Rule to avoid build errors related to SVGs.
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
|
||||
# https://github.com/facebook/fresco/issues/2638
|
||||
-keep public class com.facebook.imageutils.** {
|
||||
public *;
|
||||
}
|
||||
|
||||
@@ -5,46 +5,52 @@ import org.gradle.util.VersionNumber
|
||||
// sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
kotlinVersion = "2.0.21"
|
||||
gradlePluginVersion = "8.6.0"
|
||||
buildToolsVersion = "35.0.0"
|
||||
compileSdkVersion = 35
|
||||
minSdkVersion = 26
|
||||
targetSdkVersion = 35
|
||||
supportLibVersion = "28.0.0"
|
||||
ndkVersion = "27.1.12297006"
|
||||
|
||||
// The Maven artifact groupId of the third-party react-native modules which
|
||||
// Jitsi Meet SDK for Android depends on and which are not available in
|
||||
// third-party Maven repositories so we have to deploy to a Maven repository
|
||||
// of ours.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
|
||||
//React Native and Hermes Version
|
||||
rnVersion = "0.77.2"
|
||||
|
||||
// Java dependencies
|
||||
javaVersion = JavaVersion.VERSION_17
|
||||
jvmToolchainVersion = 17
|
||||
jvmTargetVersion = '17'
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$rootProject.ext.kotlinVersion"
|
||||
classpath "com.android.tools.build:gradle:$rootProject.ext.gradlePluginVersion"
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
kotlinVersion = "1.9.24"
|
||||
buildToolsVersion = "34.0.0"
|
||||
compileSdkVersion = 34
|
||||
minSdkVersion = 26
|
||||
targetSdkVersion = 34
|
||||
supportLibVersion = "28.0.0"
|
||||
ndkVersion = "26.1.10909125"
|
||||
|
||||
// The Maven artifact groupId of the third-party react-native modules which
|
||||
// Jitsi Meet SDK for Android depends on and which are not available in
|
||||
// third-party Maven repositories so we have to deploy to a Maven repository
|
||||
// of ours.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
|
||||
//React Native and Hermes Version
|
||||
rnVersion = "0.75.5"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -69,26 +75,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// Due to a dependency conflict between React Native and the Fresco library used by GiphySDK,
|
||||
// GIFs appear as static images instead of animating
|
||||
// https://github.com/Giphy/giphy-react-native-sdk/commit/7fe466ed6fddfaec95f9cbc959d33bd75ad8f900
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy {
|
||||
forcedModules = [
|
||||
'com.facebook.fresco:fresco:3.2.0',
|
||||
'com.facebook.fresco:animated-gif:3.2.0',
|
||||
'com.facebook.fresco:animated-base:3.2.0',
|
||||
'com.facebook.fresco:animated-drawable:3.2.0',
|
||||
'com.facebook.fresco:animated-webp:3.2.0',
|
||||
'com.facebook.fresco:webpsupport:3.2.0',
|
||||
'com.facebook.fresco:imagepipeline-okhttp3:3.2.0',
|
||||
'com.facebook.fresco:middleware:3.2.0',
|
||||
'com.facebook.fresco:nativeimagetranscoder:3.2.0'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Third-party react-native modules which Jitsi Meet SDK for Android depends
|
||||
// on and which are not available in third-party Maven repositories need to
|
||||
// be deployed in a Maven repository of ours.
|
||||
@@ -134,7 +120,7 @@ allprojects {
|
||||
project.version = "${json.version}-jitsi-${versionQualifierNumber}"
|
||||
|
||||
task jitsiAndroidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
archiveClassifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
}
|
||||
|
||||
@@ -185,16 +171,46 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// Force the version of the Android build tools we have chosen on all
|
||||
// subprojects. The forcing was introduced for react-native and the third-party
|
||||
// modules that we utilize such as react-native-background-timer.
|
||||
// Force the version of the Android build tools we have chosen on all subprojects.
|
||||
subprojects { subproject ->
|
||||
afterEvaluate{
|
||||
if ((subproject.plugins.hasPlugin('android')
|
||||
|| subproject.plugins.hasPlugin('android-library'))
|
||||
&& rootProject.ext.has('buildToolsVersion')) {
|
||||
|
||||
android {
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
}
|
||||
|
||||
// Set JVM target across all subprojects
|
||||
compileOptions {
|
||||
sourceCompatibility rootProject.ext.javaVersion
|
||||
targetCompatibility rootProject.ext.javaVersion
|
||||
}
|
||||
|
||||
// Disable lint errors for problematic third-party modules
|
||||
// react-native-background-timer
|
||||
// react-native-calendar-events
|
||||
lint {
|
||||
abortOnError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add Kotlin configuration for subprojects that use Kotlin
|
||||
if (subproject.plugins.hasPlugin('kotlin-android')) {
|
||||
subproject.kotlin {
|
||||
jvmToolchain(rootProject.ext.jvmToolchainVersion)
|
||||
}
|
||||
|
||||
// Set Kotlin JVM target
|
||||
subproject.android {
|
||||
kotlinOptions {
|
||||
jvmTarget = rootProject.ext.jvmTargetVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,20 +11,26 @@
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx4048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# This one fixes a weird WebRTC runtime problem on some devices.
|
||||
# https://github.com/jitsi/jitsi-meet/issues/7911#issuecomment-714323255
|
||||
android.enableDexingArtifactTransform.desugaring=false
|
||||
|
||||
android.useAndroidX=true
|
||||
|
||||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
# Use this property to enable support to the new architecture.
|
||||
# This will allow you to use TurboModules and the Fabric render in
|
||||
# your application. You should enable this flag either if you want
|
||||
# to write custom TurboModules/Fabric components OR use libraries that
|
||||
# are providing them.
|
||||
newArchEnabled=false
|
||||
|
||||
# Use this property to enable or disable the Hermes JS engine.
|
||||
hermesEnabled=true
|
||||
|
||||
appVersion=99.0.0
|
||||
sdkVersion=0.0.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
113
android/scripts/check_elf_alignment.sh
Executable file
113
android/scripts/check_elf_alignment.sh
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
progname="${0##*/}"
|
||||
progname="${progname%.sh}"
|
||||
|
||||
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
|
||||
|
||||
cleanup_trap() {
|
||||
if [ -n "${tmp}" -a -d "${tmp}" ]; then
|
||||
rm -rf ${tmp}
|
||||
fi
|
||||
exit $1
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Host side script to check the ELF alignment of shared libraries."
|
||||
echo "Shared libraries are reported ALIGNED when their ELF regions are"
|
||||
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
|
||||
echo
|
||||
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
|
||||
}
|
||||
|
||||
if [ ${#} -ne 1 ]; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
case ${1} in
|
||||
--help | -h | -\?)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
|
||||
*)
|
||||
dir="${1}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! [ -f "${dir}" -o -d "${dir}" ]; then
|
||||
echo "Invalid file: ${dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apk ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
|
||||
echo "=== APK zip-alignment ==="
|
||||
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
|
||||
echo "========================="
|
||||
else
|
||||
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
|
||||
echo " You can install the latest build-tools by running the below command"
|
||||
echo " and updating your \$PATH:"
|
||||
echo
|
||||
echo " sdkmanager \"build-tools;35.0.0-rc3\""
|
||||
fi
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
|
||||
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apex ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
|
||||
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
RED="\e[31m"
|
||||
GREEN="\e[32m"
|
||||
ENDCOLOR="\e[0m"
|
||||
|
||||
unaligned_libs=()
|
||||
|
||||
echo
|
||||
echo "=== ELF alignment ==="
|
||||
|
||||
matches="$(find "${dir}" -type f)"
|
||||
IFS=$'\n'
|
||||
for match in $matches; do
|
||||
# We could recursively call this script or rewrite it to though.
|
||||
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
|
||||
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
|
||||
|
||||
[[ $(file "${match}") == *"ELF"* ]] || continue
|
||||
|
||||
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
|
||||
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
|
||||
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
|
||||
unaligned_libs+=("${match}")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#unaligned_libs[@]} -gt 0 ]; then
|
||||
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
|
||||
elif [ -n "${dir_filename}" ]; then
|
||||
echo -e "ELF Verification Successful"
|
||||
fi
|
||||
echo "====================="
|
||||
@@ -44,12 +44,11 @@ dependencies {
|
||||
api "com.facebook.react:react-android:$rootProject.ext.rnVersion"
|
||||
api "com.facebook.react:hermes-android:$rootProject.ext.rnVersion"
|
||||
|
||||
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
|
||||
implementation 'com.jakewharton.timber:timber:5.0.1'
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation 'androidx.startup:startup-runtime:1.1.0'
|
||||
implementation 'com.google.j2objc:j2objc-annotations:3.0.0'
|
||||
|
||||
// Only add these packages if we are NOT doing a LIBRE_BUILD
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
@@ -83,10 +82,11 @@ dependencies {
|
||||
implementation project(':react-native-screens')
|
||||
implementation project(':react-native-slider')
|
||||
implementation project(':react-native-sound')
|
||||
implementation project(':react-native-splash-screen')
|
||||
implementation project(':react-native-splash-view')
|
||||
implementation project(':react-native-svg')
|
||||
implementation project(':react-native-video')
|
||||
implementation project(':react-native-webview')
|
||||
implementation project(':react-native-worklets-core')
|
||||
|
||||
// Use `api` here so consumers can use WebRTCModuleOptions.
|
||||
api project(':react-native-webrtc')
|
||||
@@ -137,8 +137,16 @@ android.libraryVariants.all { def variant ->
|
||||
def devEnabled = !targetName.toLowerCase().contains("release")
|
||||
|
||||
// Run the bundler
|
||||
// Use full path to node to avoid PATH issues in Gradle
|
||||
def nodePath = System.getenv('NVM_BIN') ? "${System.getenv('NVM_BIN')}/node" : "node"
|
||||
|
||||
// Debug: Print the node path and environment
|
||||
println "Using node path: ${nodePath}"
|
||||
println "NVM_BIN: ${System.getenv('NVM_BIN')}"
|
||||
println "Working directory: ${reactRoot}"
|
||||
|
||||
commandLine(
|
||||
"node",
|
||||
nodePath,
|
||||
"node_modules/react-native/scripts/bundle.js",
|
||||
"--platform", "android",
|
||||
"--dev", "${devEnabled}",
|
||||
@@ -151,6 +159,70 @@ android.libraryVariants.all { def variant ->
|
||||
enabled !devEnabled
|
||||
}
|
||||
|
||||
// GRADLE REQUIREMENTS (Gradle 8.7+ / AGP 8.5.0+):
|
||||
|
||||
// This task requires explicit dependencies on resource tasks from all React Native modules
|
||||
// due to Gradle's strict validation of task dependencies.
|
||||
|
||||
// Without these dependencies,
|
||||
// builds will fail with errors like:
|
||||
// "Task ':sdk:bundleReleaseJsAndAssets' uses the output of task ':react-native-amplitude:packageReleaseResources'
|
||||
// without declaring a dependency on it."
|
||||
|
||||
// The automatic dependency resolution below ensures all required resource tasks are properly
|
||||
// declared as dependencies before this task executes.
|
||||
|
||||
if (variant.name.toLowerCase().contains("release")) {
|
||||
rootProject.subprojects.each { subproject ->
|
||||
if (
|
||||
subproject.name.startsWith("react-native-") ||
|
||||
subproject.name.startsWith("@react-native-") ||
|
||||
subproject.name.startsWith("@giphy/")
|
||||
) {
|
||||
[
|
||||
"packageReleaseResources",
|
||||
"generateReleaseResValues",
|
||||
"generateReleaseResources",
|
||||
"generateReleaseBuildConfig",
|
||||
"processReleaseManifest",
|
||||
"writeReleaseAarMetadata",
|
||||
"generateReleaseRFile",
|
||||
"compileReleaseLibraryResources",
|
||||
"compileReleaseJavaWithJavac",
|
||||
"javaPreCompileRelease",
|
||||
"bundleLibCompileToJarRelease",
|
||||
"exportReleaseConsumerProguardFiles",
|
||||
"mergeReleaseGeneratedProguardFiles",
|
||||
"mergeReleaseJniLibFolders",
|
||||
"mergeReleaseShaders",
|
||||
"packageReleaseAssets",
|
||||
"processReleaseJavaRes",
|
||||
"prepareReleaseArtProfile",
|
||||
"copyReleaseJniLibsProjectOnly",
|
||||
"extractDeepLinksRelease",
|
||||
"createFullJarRelease",
|
||||
"generateReleaseLintModel",
|
||||
"writeReleaseLintModelMetadata",
|
||||
"generateReleaseLintVitalModel",
|
||||
"lintVitalAnalyzeRelease",
|
||||
"lintReportRelease",
|
||||
"lintAnalyzeRelease",
|
||||
"lintReportDebug",
|
||||
"lintAnalyzeDebug"
|
||||
].each { taskName ->
|
||||
if (subproject.tasks.findByName(taskName)) {
|
||||
currentBundleTask.dependsOn(subproject.tasks.named(taskName))
|
||||
}
|
||||
}
|
||||
|
||||
// Also depend on the main build task to ensure all sub-tasks are completed
|
||||
if (subproject.tasks.findByName("build")) {
|
||||
currentBundleTask.dependsOn(subproject.tasks.named("build"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
|
||||
currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)
|
||||
variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.squareup.duktape.Duktape;
|
||||
|
||||
@ReactModule(name = JavaScriptSandboxModule.NAME)
|
||||
class JavaScriptSandboxModule extends ReactContextBaseJavaModule {
|
||||
public static final String NAME = "JavaScriptSandbox";
|
||||
|
||||
public JavaScriptSandboxModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given code in a Duktape VM.
|
||||
* @param code - The code that needs to evaluated.
|
||||
* @param promise - Resolved with the output in case of success or rejected with an exception
|
||||
* in case of failure.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void evaluate(String code, Promise promise) {
|
||||
Duktape vm = Duktape.create();
|
||||
try {
|
||||
Object res = vm.evaluate(code);
|
||||
promise.resolve(res.toString());
|
||||
} catch (Throwable tr) {
|
||||
promise.reject(tr);
|
||||
} finally {
|
||||
vm.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.startup.Initializer;
|
||||
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
|
||||
import org.wonday.orientation.OrientationActivityLifecycle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -35,7 +37,11 @@ public class JitsiInitializer implements Initializer<Boolean> {
|
||||
public Boolean create(@NonNull Context context) {
|
||||
Log.d(this.getClass().getCanonicalName(), "create");
|
||||
|
||||
SoLoader.init(context, /* native exopackage */ false);
|
||||
try {
|
||||
SoLoader.init(context, OpenSourceMergedSoMapping.INSTANCE);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// Register our uncaught exception handler.
|
||||
JitsiMeetUncaughtExceptionHandler.register();
|
||||
@@ -43,6 +49,10 @@ public class JitsiInitializer implements Initializer<Boolean> {
|
||||
// Register activity lifecycle handler for the orientation locker module.
|
||||
((Application) context).registerActivityLifecycleCallbacks(OrientationActivityLifecycle.getInstance());
|
||||
|
||||
// Initialize ReactInstanceManager during application startup
|
||||
// This ensures it's ready before any Activity onCreate is called
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Application) context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreen;
|
||||
import com.splashview.SplashView;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
public class JitsiMeet {
|
||||
@@ -92,7 +92,7 @@ public class JitsiMeet {
|
||||
*/
|
||||
public static void showSplashScreen(Activity activity) {
|
||||
try {
|
||||
SplashScreen.show(activity);
|
||||
SplashView.INSTANCE.showSplashView(activity);
|
||||
} catch (Exception e) {
|
||||
JitsiMeetLogger.e(e, "Failed to show splash screen");
|
||||
}
|
||||
|
||||
@@ -24,10 +24,17 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
@@ -87,6 +94,30 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
launch(context, options);
|
||||
}
|
||||
|
||||
public static void addTopBottomInsets(@NonNull Window w, @NonNull View v) {
|
||||
|
||||
// Only apply if edge-to-edge is supported (API 30+) or enforced (API 35+)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return;
|
||||
|
||||
View decorView = w.getDecorView();
|
||||
|
||||
decorView.post(() -> {
|
||||
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(decorView);
|
||||
if (insets != null) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
|
||||
params.topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
|
||||
params.bottomMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
|
||||
v.setLayoutParams(params);
|
||||
|
||||
decorView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
|
||||
view.setBackgroundColor(JitsiMeetView.BACKGROUND_COLOR);
|
||||
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Overrides
|
||||
//
|
||||
|
||||
@@ -102,7 +133,12 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// ReactInstanceManager is now initialized by JitsiInitializer during application startup
|
||||
// Just call onHostResume since the manager is already ready
|
||||
JitsiMeetActivityDelegate.onHostResume(this);
|
||||
|
||||
setContentView(R.layout.activity_jitsi_meet);
|
||||
addTopBottomInsets(getWindow(),findViewById(android.R.id.content));
|
||||
this.jitsiView = findViewById(R.id.jitsiView);
|
||||
|
||||
registerForBroadcastMessages();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -35,7 +36,7 @@ public class JitsiMeetView extends FrameLayout {
|
||||
/**
|
||||
* Background color. Should match the background color set in JS.
|
||||
*/
|
||||
private static final int BACKGROUND_COLOR = 0xFF040404;
|
||||
public static final int BACKGROUND_COLOR = 0xFF040404;
|
||||
|
||||
/**
|
||||
* React Native root view.
|
||||
@@ -196,8 +197,6 @@ public class JitsiMeetView extends FrameLayout {
|
||||
}
|
||||
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Activity) context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.facebook.react.uimanager.ViewManager;
|
||||
import com.oney.WebRTCModule.EglUtils;
|
||||
import com.oney.WebRTCModule.WebRTCModuleOptions;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreenModule;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.webrtc.EglBase;
|
||||
|
||||
@@ -65,10 +64,8 @@ class ReactInstanceManagerHolder {
|
||||
new AudioModeModule(reactContext),
|
||||
new DropboxModule(reactContext),
|
||||
new ExternalAPIModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new SplashScreenModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
new ProximityModule(reactContext),
|
||||
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)));
|
||||
@@ -90,7 +87,7 @@ class ReactInstanceManagerHolder {
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.calendarevents.RNCalendarEventsPackage(),
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.sayem.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.reactnativecommunity.clipboard.ClipboardPackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
@@ -110,6 +107,8 @@ class ReactInstanceManagerHolder {
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new org.wonday.orientation.OrientationPackage(),
|
||||
new com.splashview.SplashViewPackage(),
|
||||
new com.worklets.WorkletsCorePackage(),
|
||||
new ReactPackageAdapter() {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
@@ -133,7 +132,7 @@ class ReactInstanceManagerHolder {
|
||||
|
||||
// GiphyReactNativeSdkPackage
|
||||
try {
|
||||
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.GiphyReactNativeSdkPackage");
|
||||
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.RTNGiphySdkPackage");
|
||||
Constructor<?> constructor = giphyPackageClass.getConstructor();
|
||||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
@@ -208,9 +207,9 @@ class ReactInstanceManagerHolder {
|
||||
* time. All {@code ReactRootView} instances will be tied to the one and
|
||||
* only {@code ReactInstanceManager}.
|
||||
*
|
||||
* @param activity {@code Activity} current running Activity.
|
||||
* @param app {@code Application}
|
||||
*/
|
||||
static void initReactInstanceManager(Activity activity) {
|
||||
static void initReactInstanceManager(Application app) {
|
||||
if (reactInstanceManager != null) {
|
||||
return;
|
||||
}
|
||||
@@ -232,14 +231,14 @@ class ReactInstanceManagerHolder {
|
||||
|
||||
reactInstanceManager
|
||||
= ReactInstanceManager.builder()
|
||||
.setApplication(activity.getApplication())
|
||||
.setCurrentActivity(activity)
|
||||
.setApplication(app)
|
||||
.setCurrentActivity(null)
|
||||
.setBundleAssetName("index.android.bundle")
|
||||
.setJSMainModulePath("index.android")
|
||||
.setJavaScriptExecutorFactory(new HermesExecutorFactory())
|
||||
.addPackages(getReactNativePackages())
|
||||
.setUseDeveloperSupport(BuildConfig.DEBUG)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
rootProject.name = 'jitsi-meet'
|
||||
|
||||
include ':app', ':sdk'
|
||||
|
||||
include ':react-native-amplitude'
|
||||
@@ -29,7 +27,7 @@ project(':react-native-google-signin').projectDir = new File(rootProject.project
|
||||
include ':react-native-immersive-mode'
|
||||
project(':react-native-immersive-mode').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive-mode/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/@sayem314/react-native-keep-awake/android')
|
||||
include ':react-native-orientation-locker'
|
||||
project(':react-native-orientation-locker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation-locker/android')
|
||||
include ':react-native-pager-view'
|
||||
@@ -44,8 +42,8 @@ include ':react-native-slider'
|
||||
project(':react-native-slider').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/slider/android')
|
||||
include ':react-native-sound'
|
||||
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
|
||||
include ':react-native-splash-screen'
|
||||
project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
|
||||
include ':react-native-splash-view'
|
||||
project(':react-native-splash-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-view/android')
|
||||
include ':react-native-svg'
|
||||
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
|
||||
include ':react-native-video'
|
||||
@@ -54,3 +52,5 @@ include ':react-native-webrtc'
|
||||
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
|
||||
include ':react-native-webview'
|
||||
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
||||
include ':react-native-worklets-core'
|
||||
project(':react-native-worklets-core').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-worklets-core/android')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [ 'module:metro-react-native-babel-preset' ],
|
||||
presets: [ 'module:@react-native/babel-preset' ],
|
||||
env: {
|
||||
production: {
|
||||
plugins: [ 'react-native-paper/babel' ]
|
||||
@@ -8,9 +8,13 @@ module.exports = {
|
||||
|
||||
// This happens because react native has conflict with @babel/plugin-transform-private-methods plugin
|
||||
// https://github.com/ethers-io/ethers.js/discussions/4309#discussioncomment-6694524
|
||||
plugins: [ 'optional-require',
|
||||
[ '@babel/plugin-transform-private-methods', {
|
||||
'loose': true
|
||||
} ]
|
||||
plugins: [
|
||||
'optional-require',
|
||||
[
|
||||
'@babel/plugin-transform-private-methods', {
|
||||
'loose': true
|
||||
}
|
||||
],
|
||||
'react-native-worklets-core/plugin'
|
||||
]
|
||||
};
|
||||
|
||||
@@ -18,8 +18,6 @@ import {
|
||||
maybeRedirectToWelcomePage,
|
||||
reloadWithStoredParams
|
||||
} from './react/features/app/actions';
|
||||
import { showModeratedNotification } from './react/features/av-moderation/actions';
|
||||
import { shouldShowModeratedNotification } from './react/features/av-moderation/functions';
|
||||
import {
|
||||
_conferenceWillJoin,
|
||||
authStatusChanged,
|
||||
@@ -52,7 +50,8 @@ import {
|
||||
commonUserJoinedHandling,
|
||||
commonUserLeftHandling,
|
||||
getConferenceOptions,
|
||||
sendLocalParticipant
|
||||
sendLocalParticipant,
|
||||
updateTrackMuteState
|
||||
} from './react/features/base/conference/functions';
|
||||
import { getReplaceParticipant, getSsrcRewritingFeatureFlag } from './react/features/base/config/functions';
|
||||
import { connect } from './react/features/base/connection/actions.web';
|
||||
@@ -135,6 +134,7 @@ import {
|
||||
isLocalTrackMuted,
|
||||
isUserInteractionRequiredForUnmute
|
||||
} from './react/features/base/tracks/functions';
|
||||
import { getLocalJitsiAudioTrackSettings } from './react/features/base/tracks/functions.web';
|
||||
import { downloadJSON } from './react/features/base/util/downloadJSON';
|
||||
import { getJitsiMeetGlobalNSConnectionTimes } from './react/features/base/util/helpers';
|
||||
import { openLeaveReasonDialog } from './react/features/conference/actions.web';
|
||||
@@ -153,20 +153,20 @@ import {
|
||||
DATA_CHANNEL_CLOSED_NOTIFICATION_ID,
|
||||
NOTIFICATION_TIMEOUT_TYPE
|
||||
} from './react/features/notifications/constants';
|
||||
import { isModerationNotificationDisplayed } from './react/features/notifications/functions';
|
||||
import { suspendDetected } from './react/features/power-monitor/actions';
|
||||
import { initPrejoin, isPrejoinPageVisible } from './react/features/prejoin/functions';
|
||||
import { disableReceiver, stopReceiver } from './react/features/remote-control/actions';
|
||||
import { setScreenAudioShareState } from './react/features/screen-share/actions.web';
|
||||
import { isScreenAudioShared } from './react/features/screen-share/functions';
|
||||
import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture/actions';
|
||||
import { setAudioSettings } from './react/features/settings/actions.web';
|
||||
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
|
||||
import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise';
|
||||
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
|
||||
import { transcriberJoined, transcriberLeft } from './react/features/transcribing/actions';
|
||||
import { muteLocal } from './react/features/video-menu/actions.any';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('app:conference-web');
|
||||
let room;
|
||||
|
||||
/*
|
||||
@@ -568,7 +568,15 @@ export default {
|
||||
if (browser.isWebKitBased()) {
|
||||
this.muteAudio(true, true);
|
||||
} else {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
localTracks = localTracks.filter(track => {
|
||||
if (track.getType() === MEDIA_TYPE.AUDIO) {
|
||||
track.stopStream();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,15 +712,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for A/V Moderation when trying to unmute
|
||||
if (!mute && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, state)) {
|
||||
if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, state)) {
|
||||
APP.store.dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await APP.store.dispatch(setAudioMuted(mute, true));
|
||||
},
|
||||
|
||||
@@ -746,12 +745,6 @@ export default {
|
||||
* dialogs in case of media permissions error.
|
||||
*/
|
||||
muteVideo(mute) {
|
||||
if (this.videoSwitchInProgress) {
|
||||
logger.warn('muteVideo - unable to perform operations while video switch is in progress');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const state = APP.store.getState();
|
||||
|
||||
if (!mute
|
||||
@@ -761,11 +754,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for A/V Moderation when trying to unmute and return early
|
||||
if (!mute && shouldShowModeratedNotification(MEDIA_TYPE.VIDEO, state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
APP.store.dispatch(setVideoMuted(mute, VIDEO_MUTISM_AUTHORITY.USER, true));
|
||||
},
|
||||
|
||||
@@ -1019,7 +1007,6 @@ export default {
|
||||
|
||||
// Restore initial state.
|
||||
this._localTracksInitialized = false;
|
||||
this.isSharingScreen = false;
|
||||
this.roomName = roomName;
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
|
||||
@@ -1198,8 +1185,6 @@ export default {
|
||||
return Boolean(APP.store.getState()['features/base/audio-only'].enabled);
|
||||
},
|
||||
|
||||
videoSwitchInProgress: false,
|
||||
|
||||
/**
|
||||
* This fields stores a handler which will create a Promise which turns off
|
||||
* the screen sharing and restores the previous video state (was there
|
||||
@@ -1228,7 +1213,6 @@ export default {
|
||||
*/
|
||||
async _turnScreenSharingOff(didHaveVideo, ignoreDidHaveVideo) {
|
||||
this._untoggleScreenSharing = null;
|
||||
this.videoSwitchInProgress = true;
|
||||
|
||||
APP.store.dispatch(stopReceiver());
|
||||
|
||||
@@ -1280,13 +1264,11 @@ export default {
|
||||
|
||||
return promise.then(
|
||||
() => {
|
||||
this.videoSwitchInProgress = false;
|
||||
sendAnalytics(createScreenSharingEvent('stopped',
|
||||
duration === 0 ? null : duration));
|
||||
logger.info('Screen sharing stopped.');
|
||||
},
|
||||
error => {
|
||||
this.videoSwitchInProgress = false;
|
||||
logger.error(`_turnScreenSharingOff failed: ${error}`);
|
||||
|
||||
throw error;
|
||||
@@ -1316,14 +1298,13 @@ export default {
|
||||
this._untoggleScreenSharing
|
||||
= this._turnScreenSharingOff.bind(this, didHaveVideo);
|
||||
|
||||
const desktopVideoStream = desktopStreams.find(stream => stream.getType() === MEDIA_TYPE.VIDEO);
|
||||
const desktopAudioStream = desktopStreams.find(stream => stream.getType() === MEDIA_TYPE.AUDIO);
|
||||
|
||||
if (desktopAudioStream) {
|
||||
desktopAudioStream.on(
|
||||
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
|
||||
() => {
|
||||
logger.debug(`Local screensharing audio track stopped. ${this.isSharingScreen}`);
|
||||
logger.debug('Local screensharing audio track stopped.');
|
||||
|
||||
// Handle case where screen share was stopped from the browsers 'screen share in progress'
|
||||
// window. If audio screen sharing is stopped via the normal UX flow this point shouldn't
|
||||
@@ -1335,21 +1316,6 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
if (desktopVideoStream) {
|
||||
desktopVideoStream.on(
|
||||
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
|
||||
() => {
|
||||
logger.debug(`Local screensharing track stopped. ${this.isSharingScreen}`);
|
||||
|
||||
// If the stream was stopped during screen sharing
|
||||
// session then we should switch back to video.
|
||||
this.isSharingScreen
|
||||
&& this._untoggleScreenSharing
|
||||
&& this._untoggleScreenSharing();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return desktopStreams;
|
||||
}, error => {
|
||||
throw error;
|
||||
@@ -1497,10 +1463,6 @@ export default {
|
||||
room.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, (track, participantThatMutedUs) => {
|
||||
if (participantThatMutedUs) {
|
||||
APP.store.dispatch(participantMutedUs(participantThatMutedUs, track));
|
||||
if (this.isSharingScreen && track.isVideoTrack()) {
|
||||
logger.debug('TRACK_MUTE_CHANGED while screen sharing');
|
||||
this._turnScreenSharingOff(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1712,8 +1674,12 @@ export default {
|
||||
room.on(
|
||||
JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,
|
||||
({ audio, video }) => {
|
||||
APP.store.dispatch(
|
||||
onStartMutedPolicyChanged(audio, video));
|
||||
APP.store.dispatch(onStartMutedPolicyChanged(audio, video));
|
||||
|
||||
const state = APP.store.getState();
|
||||
|
||||
updateTrackMuteState(state, APP.store.dispatch, true);
|
||||
updateTrackMuteState(state, APP.store.dispatch, false);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1807,7 +1773,11 @@ export default {
|
||||
return this.useAudioStream(stream);
|
||||
})
|
||||
.then(() => {
|
||||
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
|
||||
const state = APP.store.getState();
|
||||
const localAudio = getLocalJitsiAudioTrack(state);
|
||||
const settings = getLocalJitsiAudioTrackSettings(state);
|
||||
|
||||
APP.store.dispatch(setAudioSettings(settings));
|
||||
|
||||
if (localAudio && isDefaultMicSelected) {
|
||||
// workaround for the default device to be shown as selected in the
|
||||
|
||||
14
config.js
14
config.js
@@ -363,6 +363,7 @@ var config = {
|
||||
// Desktop sharing
|
||||
|
||||
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
|
||||
// Setting higher min/max values will affect the resolution, it makes it worse.
|
||||
// desktopSharingFrameRate: {
|
||||
// min: 5,
|
||||
// max: 5,
|
||||
@@ -722,6 +723,8 @@ var config = {
|
||||
// autoKnock: false,
|
||||
// // Enables the lobby chat. Replaces `enableLobbyChat`.
|
||||
// enableChat: true,
|
||||
// // Shows the hangup button in the lobby screen.
|
||||
// showHangUp: true,
|
||||
// },
|
||||
|
||||
// Configs for the security related UI elements.
|
||||
@@ -761,7 +764,7 @@ var config = {
|
||||
// hideDominantSpeakerBadge: false,
|
||||
|
||||
// Default language for the user interface. Cannot be overwritten.
|
||||
// DEPRECATED! Use the `lang` iframe option directly instead.
|
||||
// For iframe integrations, use the `lang` option directly instead.
|
||||
// defaultLanguage: 'en',
|
||||
|
||||
// Disables profile and the edit of all fields from the profile settings (display name and email)
|
||||
@@ -791,7 +794,6 @@ var config = {
|
||||
// Configs for prejoin page.
|
||||
// prejoinConfig: {
|
||||
// // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
|
||||
// // This replaces `prejoinPageEnabled`. Defaults to true.
|
||||
// enabled: true,
|
||||
// // Hides the participant name editing field in the prejoin screen.
|
||||
// // If requireDisplayName is also set as true, a name should still be provided through
|
||||
@@ -1131,10 +1133,6 @@ var config = {
|
||||
// The Amplitude APP Key:
|
||||
// amplitudeAPPKey: '<APP_KEY>',
|
||||
|
||||
// Enables Amplitude UTM tracking:
|
||||
// Default value is false.
|
||||
// amplitudeIncludeUTM: false,
|
||||
|
||||
// Obfuscates room name sent to analytics (amplitude, rtcstats)
|
||||
// Default value is false.
|
||||
// obfuscateRoomName: false,
|
||||
@@ -1367,7 +1365,9 @@ var config = {
|
||||
// disableGrantModerator: true,
|
||||
// // If set to 'all' the 'Private chat' button will be disabled for all participants.
|
||||
// // If set to 'allow-moderator-chat' the 'Private chat' button will be available for chats with moderators.
|
||||
// disablePrivateChat: 'all' | 'allow-moderator-chat',
|
||||
// // If set to 'disable-visitor-chat' the 'Private chat' button will be disabled for visitor-main participant
|
||||
// // conversations.
|
||||
// disablePrivateChat: 'all' | 'allow-moderator-chat' | 'disable-visitor-chat',
|
||||
// },
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ $welcomePageHeaderContainerMargin: $welcomePageHeaderContainerMarginTop auto 0;
|
||||
$welcomePageHeaderTextTitleMarginBottom: 0;
|
||||
$welcomePageHeaderTextTitleFontSize: 2.625rem;
|
||||
$welcomePageHeaderTextTitleFontWeight: normal;
|
||||
$welcomePageHeaderTextTitleLineHeight: 50px;
|
||||
$welcomePageHeaderTextTitleLineHeight: 3.125rem;
|
||||
$welcomePageHeaderTextTitleOpacity: 1;
|
||||
|
||||
$welcomePageEnterRoomDisplay: flex;
|
||||
|
||||
10
debian/jitsi-meet-prosody.postinst
vendored
10
debian/jitsi-meet-prosody.postinst
vendored
@@ -154,6 +154,16 @@ case "$1" in
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# Start using the polls component
|
||||
if ! grep -q "Component \"polls.$JVB_HOSTNAME\"" $PROSODY_HOST_CONFIG ;then
|
||||
echo -e "\nComponent \"polls.$JVB_HOSTNAME\" \"polls_component\"" >> $PROSODY_HOST_CONFIG
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
if ! grep -q -- '--"polls";' $PROSODY_HOST_CONFIG ;then
|
||||
sed -i "s/\"polls\";/--\"polls\";/g" $PROSODY_HOST_CONFIG
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# Old versions of jitsi-meet-prosody come with the extra plugin path commented out (https://github.com/jitsi/jitsi-meet/commit/e11d4d3101e5228bf956a69a9e8da73d0aee7949)
|
||||
# Make sure it is uncommented, as it contains required modules.
|
||||
if grep -q -- '--plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }' $PROSODY_HOST_CONFIG ;then
|
||||
|
||||
@@ -83,7 +83,6 @@ Component "conference.jitmeet.example.com" "muc"
|
||||
"muc_hide_all";
|
||||
"muc_meeting_id";
|
||||
"muc_domain_mapper";
|
||||
"polls";
|
||||
--"token_verification";
|
||||
"muc_rate_limit";
|
||||
"muc_password_whitelist";
|
||||
@@ -159,9 +158,10 @@ Component "lobby.jitmeet.example.com" "muc"
|
||||
modules_enabled = {
|
||||
"muc_hide_all";
|
||||
"muc_rate_limit";
|
||||
"polls";
|
||||
}
|
||||
|
||||
Component "metadata.jitmeet.example.com" "room_metadata_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
breakout_rooms_component = "breakout.jitmeet.example.com"
|
||||
|
||||
Component "polls.jitmeet.example.com" "polls_component"
|
||||
|
||||
16
giphy-analytics-stub.js
Normal file
16
giphy-analytics-stub.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// Stub replacement for @giphy/js-analytics to prevent beforeunload handlers
|
||||
// This completely disables all Giphy analytics functionality
|
||||
|
||||
export const pingback = () => {
|
||||
// Completely disabled - do nothing
|
||||
|
||||
};
|
||||
|
||||
export const mergeAttributes = (attributes, newAttributes) => {
|
||||
// Return merged attributes without any analytics calls
|
||||
return { ...attributes,
|
||||
...newAttributes };
|
||||
};
|
||||
|
||||
// Ensure no beforeunload handlers are ever registered
|
||||
export default pingback;
|
||||
@@ -33,6 +33,7 @@ target 'JitsiMeetSDK' do
|
||||
:path => config[:reactNativePath],
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
:new_arch_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -66,6 +67,7 @@ target 'JitsiMeetSDKLite' do
|
||||
:path => config[:reactNativePath],
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
:new_arch_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -77,10 +79,12 @@ target 'JitsiMeetSDKLite' do
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
||||
react_native_post_install(
|
||||
installer,
|
||||
use_native_modules![:reactNativePath],
|
||||
:mac_catalyst_enabled => false
|
||||
:mac_catalyst_enabled => false,
|
||||
# :ccache_enabled => true
|
||||
)
|
||||
installer.pods_project.targets.each do |target|
|
||||
# https://github.com/CocoaPods/CocoaPods/issues/11402
|
||||
@@ -99,4 +103,5 @@ post_install do |installer|
|
||||
|
||||
# Patch SocketRocket to support TLS 1.3
|
||||
%x(patch Pods/SocketRocket/SocketRocket/SRSecurityPolicy.m -N < patches/ws-tls13.diff)
|
||||
|
||||
end
|
||||
|
||||
1277
ios/Podfile.lock
1277
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,14 @@
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>85F4.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */; };
|
||||
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */; };
|
||||
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */; };
|
||||
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */; };
|
||||
@@ -132,7 +132,7 @@
|
||||
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* jitsi-meet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = src/Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -250,7 +250,6 @@
|
||||
DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */,
|
||||
);
|
||||
path = src;
|
||||
@@ -475,7 +474,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.storyboard in Resources */,
|
||||
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -687,12 +686,12 @@
|
||||
name = Interface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
@@ -37,7 +37,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
let vc = ViewController()
|
||||
self.window?.rootViewController = vc
|
||||
jitsiMeet.showSplashScreen(vc.view)
|
||||
jitsiMeet.showSplashScreen()
|
||||
|
||||
self.window?.makeKeyAndVisible()
|
||||
|
||||
|
||||
42
ios/app/src/Base.lproj/LaunchScreen.storyboard
Normal file
42
ios/app/src/Base.lproj/LaunchScreen.storyboard
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" userInteractionEnabled="NO" contentMode="center" image="LaunchScreen" translatesAutoresizingMaskIntoConstraints="NO" id="4B8-Xf-NDE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.090196078431372548" green="0.62745098039215685" blue="0.85882352941176465" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="4B8-Xf-NDE" secondAttribute="bottom" id="aFF-BR-glX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="glR-YN-1GF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4B8-Xf-NDE" secondAttribute="trailing" id="tva-gl-jRX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="yaV-1V-oEh"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="LaunchScreen" width="480" height="480"/>
|
||||
</resources>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" userInteractionEnabled="NO" contentMode="center" image="LaunchScreen" translatesAutoresizingMaskIntoConstraints="NO" id="4B8-Xf-NDE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.090196078431372548" green="0.62745098039215685" blue="0.85882352941176465" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="4B8-Xf-NDE" secondAttribute="bottom" id="aFF-BR-glX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="glR-YN-1GF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4B8-Xf-NDE" secondAttribute="trailing" id="tva-gl-jRX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="yaV-1V-oEh"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="LaunchScreen" width="480" height="480"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -90,7 +90,7 @@
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UIStatusBarStyle</key>
|
||||
<string>UIStatusBarStyleLightContent</string>
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */; };
|
||||
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */; };
|
||||
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
|
||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
|
||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
|
||||
DE762DB422AFDE76000DEBD6 /* JitsiMeetUserInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -98,7 +97,6 @@
|
||||
DE9A015C289A9A9A00E41CBB /* JitsiMeetLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2D32316AC4D00AE1940 /* JitsiMeetLogger.m */; };
|
||||
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */; };
|
||||
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535321FB1BF800011A3A /* JitsiMeet.m */; };
|
||||
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
|
||||
DE9A0162289A9A9A00E41CBB /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD781F5EC6D7001C08DB /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
DE9A0163289A9A9A00E41CBB /* CallKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD761F5EC6CE001C08DB /* CallKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
DE9A0166289A9A9A00E41CBB /* CallKitIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */; };
|
||||
@@ -161,7 +159,6 @@
|
||||
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
|
||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
|
||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
|
||||
DE438CD82350934700DD541D /* JavaScriptSandbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JavaScriptSandbox.m; sourceTree = "<group>"; };
|
||||
DE65AAC92317FFCD00290BEC /* LogUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogUtils.h; sourceTree = "<group>"; };
|
||||
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetBaseLogHandler+Private.h"; sourceTree = "<group>"; };
|
||||
DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetUserInfo.h; sourceTree = "<group>"; };
|
||||
@@ -250,7 +247,6 @@
|
||||
C69EFA02209A0EFD0027712B /* callkit */,
|
||||
A4A934E7212F3AB8001E9388 /* dropbox */,
|
||||
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
||||
DE438CD82350934700DD541D /* JavaScriptSandbox.m */,
|
||||
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
||||
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */,
|
||||
DEA9F283258A5D9900D4CD74 /* JitsiMeetSDK.h */,
|
||||
@@ -681,7 +677,6 @@
|
||||
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
|
||||
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
||||
DEFE535421FB1BF800011A3A /* JitsiMeet.m in Sources */,
|
||||
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -714,7 +709,6 @@
|
||||
4E0EF63328CA2FB3005D1B03 /* JMCallKitEmitter.m in Sources */,
|
||||
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */,
|
||||
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */,
|
||||
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@import JavaScriptCore;
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
|
||||
@interface JavaScriptSandbox : NSObject<RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation JavaScriptSandbox
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Exported methods
|
||||
|
||||
RCT_EXPORT_METHOD(evaluate:(NSString *)code
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject) {
|
||||
__block BOOL hasError = NO;
|
||||
JSContext *ctx = [[JSContext alloc] init];
|
||||
ctx.exceptionHandler = ^(JSContext *context, JSValue *exception) {
|
||||
hasError = YES;
|
||||
reject(@"evaluate", [exception toString], nil);
|
||||
};
|
||||
JSValue *ret = [ctx evaluateScript:code];
|
||||
if (!hasError) {
|
||||
NSString *result = [ret toString];
|
||||
if (result == nil) {
|
||||
reject(@"evaluate", @"Error in string coercion", nil);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -100,6 +100,9 @@ typedef NS_ENUM(NSInteger, WebRTCLoggingSeverity) {
|
||||
|
||||
- (BOOL)isCrashReportingDisabled;
|
||||
|
||||
- (void)showSplashScreen:(UIView * _Nonnull) rootView;
|
||||
/**
|
||||
* Shows the splash screen.
|
||||
*/
|
||||
- (void)showSplashScreen;
|
||||
|
||||
@end
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#import "JitsiMeetView+Private.h"
|
||||
#import "RCTBridgeWrapper.h"
|
||||
#import "ReactUtils.h"
|
||||
#import "RNSplashScreen.h"
|
||||
#import "ScheenshareEventEmiter.h"
|
||||
|
||||
#import <react-native-webrtc/WebRTCModuleOptions.h>
|
||||
@@ -221,8 +220,17 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)showSplashScreen:(UIView*)rootView {
|
||||
[RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];
|
||||
- (void)showSplashScreen {
|
||||
Class splashClass = NSClassFromString(@"SplashView");
|
||||
if (splashClass && [splashClass respondsToSelector:@selector(sharedInstance)]) {
|
||||
id splashInstance = [splashClass performSelector:@selector(sharedInstance)];
|
||||
if (splashInstance && [splashInstance respondsToSelector:@selector(showSplash)]) {
|
||||
[splashInstance performSelector:@selector(showSplash)];
|
||||
NSLog(@"✅ Splash Screen Shown Successfully");
|
||||
}
|
||||
} else {
|
||||
NSLog(@"⚠️ SplashView module not found");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Property getter / setters
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
"en": "English",
|
||||
"eo": "Esperanto",
|
||||
"es": "Español",
|
||||
"esUS": "Español (Latinoamérica)",
|
||||
"es-US": "Español (Latinoamérica)",
|
||||
"et": "Eesti",
|
||||
"eu": "Euskara",
|
||||
"fa": "فارسی",
|
||||
"fi": "Suomi",
|
||||
"fr": "Français",
|
||||
"frCA": "Français (Canada)",
|
||||
"fr-CA": "Français (Canada)",
|
||||
"gl": "Galego",
|
||||
"he": "עברית",
|
||||
"hi": "हिन्दी",
|
||||
@@ -43,7 +43,7 @@
|
||||
"oc": "Occitan",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"pt-BR": "Português (Brasil)",
|
||||
"ro": "Română",
|
||||
"ru": "Русский",
|
||||
"sc": "Sardu",
|
||||
@@ -56,6 +56,6 @@
|
||||
"tr": "Türkçe",
|
||||
"uk": "Українська",
|
||||
"vi": "Tiếng Việt",
|
||||
"zhCN": "中文(简体)",
|
||||
"zhTW": "中文(繁體)"
|
||||
"zh-CN": "中文(简体)",
|
||||
"zh-TW": "中文(繁體)"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,24 +11,17 @@
|
||||
"copyStream": "Copier le lien de diffusion en direct",
|
||||
"countryNotSupported": "Nous ne prenons pas encore cette destination en charge.",
|
||||
"countryReminder": "Vous appelez en dehors des É.-U.? Veuillez vous assurer de commencer par le code de pays!",
|
||||
"defaultEmail": "Votre email par défaut",
|
||||
"disabled": "Vous ne pouvez pas inviter d'autres personnes.",
|
||||
"failedToAdd": "L'ajout de membres a échoué",
|
||||
"footerText": "Les appels sont désactivés.",
|
||||
"googleEmail": "Gmail",
|
||||
"inviteMoreHeader": "Vous êtes seul(e) dans la réunion",
|
||||
"inviteMoreMailSubject": "Rejoindre une réunion {{appName}}",
|
||||
"inviteMorePrompt": "Inviter d'autres personnes",
|
||||
"linkCopied": "Lien copié dans le presse-papiers",
|
||||
"loading": "Rechercher des personnes et des numéros de téléphone",
|
||||
"loadingNumber": "Validation du numéro de téléphone",
|
||||
"loadingPeople": "Rechercher des personnes à inviter",
|
||||
"noResults": "Aucun résultat de recherche correspondant",
|
||||
"noValidNumbers": "Veuillez entrer un numéro de téléphone",
|
||||
"outlookEmail": "Outlook",
|
||||
"phoneNumbers": "Numéros de téléphone",
|
||||
"searchNumbers": "Ajouter des numéros de téléphone",
|
||||
"searchPeople": "Rechercher des personnes",
|
||||
"searchPeopleAndNumbers": "Rechercher des personnes ou ajouter des numéros de téléphone",
|
||||
"searching": "Recherche…",
|
||||
"shareInvite": "Partager l'invitation à la réunion",
|
||||
"shareLink": "Partager le lien de la réunion pour inviter d'autres personnes",
|
||||
@@ -116,9 +109,12 @@
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"disabled": "L'envoi de messages de chat est désactivé.",
|
||||
"enter": "Entrez dans le salon",
|
||||
"error": "Erreur : votre message n'a pas été envoyé. Raison : {{error}}",
|
||||
"everyone": "Tout le monde",
|
||||
"fieldPlaceHolder": "Tapez votre message ici",
|
||||
"guestsChatIndicator": "(invité)",
|
||||
"lobbyChatMessageTo": "Message de salle d'attente à {{recipient}}",
|
||||
"message": "Message",
|
||||
"messageAccessibleTitle": "{{user}} dit: ",
|
||||
@@ -129,12 +125,26 @@
|
||||
"nickname": {
|
||||
"popover": "Choisissez un nom d'affichage",
|
||||
"title": "Entrer un nom d'affichage pour utiliser le clavardage",
|
||||
"titleWithPolls": "Entrer un nom d'affichage pour utiliser le clavardage"
|
||||
"titleWithCC": "Entrez un pseudonyme pour utiliser le chat et les sous-titres",
|
||||
"titleWithPolls": "Entrer un nom d'affichage pour utiliser le clavardage",
|
||||
"titleWithPollsAndCC": "Entrez un pseudonyme pour utiliser le chat, les sondages et les sous-titres",
|
||||
"titleWithPollsAndCCAndFileSharing": "Entrez un pseudonyme pour utiliser le chat, les sondages, les sous-titres et les fichiers"
|
||||
},
|
||||
"noMessagesMessage": "Il n'y a pas encore de messages dans cette réunion. Démarrez une conversation ici !",
|
||||
"noMessagesMessage": "Il n'y a pas encore de messages dans cette réunion. Démarrez une conversation ici!",
|
||||
"privateNotice": "Message privé à {{recipient}}",
|
||||
"sendButton": "Envoyer",
|
||||
"smileysPanel": "Panneaux des Émojis",
|
||||
"systemDisplayName": "Système",
|
||||
"tabs": {
|
||||
"chat": "Chat",
|
||||
"closedCaptions": "ST",
|
||||
"fileSharing": "Fichiers",
|
||||
"polls": "Sondages"
|
||||
},
|
||||
"title": "Clavardage",
|
||||
"titleWithCC": "ST",
|
||||
"titleWithFeatures": "Chat et",
|
||||
"titleWithFileSharing": "Fichiers",
|
||||
"titleWithPolls": "Clavardage",
|
||||
"you": "vous"
|
||||
},
|
||||
@@ -145,6 +155,10 @@
|
||||
"dontShowAgain": "Ne plus m'afficher ceci",
|
||||
"installExtensionText": "Installer l'extension pour l'intégration de Google Calendar et Office 365"
|
||||
},
|
||||
"closedCaptionsTab": {
|
||||
"emptyState": "Le contenu des sous-titres sera disponible quand un modérateur les aura démarrés",
|
||||
"startClosedCaptionsButton": "Démarrer les sous-titres"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": "Connexion à la réunion en cours…"
|
||||
},
|
||||
@@ -161,8 +175,7 @@
|
||||
"FETCH_SESSION_ID": "Obtention d'un identifiant de session…",
|
||||
"GET_SESSION_ID_ERROR": "Obtenir une erreur d'identifiant de session: {{code}}",
|
||||
"GOT_SESSION_ID": "Obtention d'un identifiant de session… Terminée",
|
||||
"LOW_BANDWIDTH": "La vidéo de {{displayName}} a été coupée pour économiser de la bande passante",
|
||||
"RECONNECTING": "Un problème de réseau est survenu. Reconnexion en cours…"
|
||||
"LOW_BANDWIDTH": "La vidéo de {{displayName}} a été coupée pour économiser de la bande passante"
|
||||
},
|
||||
"connectionindicator": {
|
||||
"address": "Adresse :",
|
||||
@@ -183,6 +196,7 @@
|
||||
"more": "Afficher plus",
|
||||
"no": "non",
|
||||
"packetloss": "Perte de paquet :",
|
||||
"participant_id": "ID du participant:",
|
||||
"quality": {
|
||||
"good": "Bonne",
|
||||
"inactive": "Inactive",
|
||||
@@ -221,8 +235,9 @@
|
||||
"joinInBrowser": "Rejoindre depuis le navigateur",
|
||||
"launchMeetingLabel": "Comment voulez-vous rejoindre la réunion ?",
|
||||
"launchWebButton": "Démarrer dans l'application Web",
|
||||
"noDesktopApp": "Vous n'avez pas l'application ?",
|
||||
"noMobileApp": "Vous n'avez pas l'application ?",
|
||||
"openApp": "Continuer vers l'application",
|
||||
"or": "OU",
|
||||
"termsAndConditions": "En continuant, vous acceptez nos <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>conditions générales d’utilisation.</a>",
|
||||
"title": "Démarrage de votre réunion dans {{app}} en cours…",
|
||||
"titleNew": "Démarrage de votre réunion…",
|
||||
@@ -263,8 +278,9 @@
|
||||
"Remove": "Supprimer",
|
||||
"Share": "Partager",
|
||||
"Submit": "Envoyer",
|
||||
"WaitForHostMsg": "La conférence n'a pas encore démarré. Si vous êtes l'hôte, veuillez vous authentifier. Sinon, veuillez attendre que l'hôte arrive.",
|
||||
"WaitingForHost": "En attente de l'hôte…",
|
||||
"Understand": "Je comprends, gardez-moi en sourdine pour l'instant",
|
||||
"UnderstandAndUnmute": "Je comprends, veuillez me réactiver s'il vous plaît",
|
||||
"WaitForHostNoAuthMsg": "La réunion n'a pas encore commencé car aucun modérateur n'est encore arrivé. Veuillez patienter.",
|
||||
"WaitingForHostButton": "Attendre l'hôte",
|
||||
"WaitingForHostTitle": "En attente de l'hôte…",
|
||||
"Yes": "Oui",
|
||||
@@ -276,19 +292,27 @@
|
||||
"sharingTabs": "Options de partage"
|
||||
},
|
||||
"add": "Ajouter",
|
||||
"addMeetingNote": "Ajouter une note à cette conférence",
|
||||
"addMeetingNote": "Ajouter une note à cette réunion",
|
||||
"addOptionalNote": "Ajouter une note (optionnel):",
|
||||
"allow": "Autoriser",
|
||||
"allowToggleCameraDialog": "Autorisez-vous {{initiatorName}} à changer votre mode de caméra?",
|
||||
"allowToggleCameraTitle": "Autoriser-vous le changement de mode de caméra?",
|
||||
"alreadySharedVideoMsg": "Un autre membre partage déjà une vidéo. Cette conférence permet le partage d'une seule vidéo à la fois.",
|
||||
"alreadySharedVideoMsg": "Un autre membre partage déjà une vidéo. Cette réunion permet le partage d'une seule vidéo à la fois.",
|
||||
"alreadySharedVideoTitle": "Seulement une vidéo à la fois peut être partagée",
|
||||
"applicationWindow": "Fenêtre d'application",
|
||||
"authenticationRequired": "Authentification requise",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Prendre et envoyer une photo en utilisant votre caméra mobile",
|
||||
"ok": "Ouvrir la caméra",
|
||||
"reject": "Pas maintenant",
|
||||
"title": "Prendre une photo"
|
||||
},
|
||||
"cameraConstraintFailedError": "Votre caméra ne répond pas à certaines exigences.",
|
||||
"cameraNotFoundError": "Impossible de trouver la caméra.",
|
||||
"cameraNotSendingData": "Il est impossible d'accéder à la caméra. Veuillez vérifier si une autre application utilise actuellement ce dispositif, sélectionner un autre dispositif à partir du menu des paramètres ou essayer de recharger l'application.",
|
||||
"cameraNotSendingDataTitle": "Impossible d'accéder à la caméra",
|
||||
"cameraPermissionDeniedError": "Vous n'avez pas reçu l'autorisation d'utiliser votre caméra. Vous pouvez toujours rejoindre la conférence, mais les autres membres ne pourront pas vous voir. Utilisez le bouton de caméra dans la barre d'adresse pour corriger cela.",
|
||||
"cameraPermissionDeniedError": "Vous n'avez pas reçu l'autorisation d'utiliser votre caméra. Vous pouvez toujours rejoindre la réunion, mais les autres membres ne pourront pas vous voir. Utilisez le bouton de caméra dans la barre d'adresse pour corriger cela.",
|
||||
"cameraTimeoutError": "Impossible de démarrer la source vidéo. Délai dépassé!",
|
||||
"cameraUnknownError": "Impossible d'utiliser la caméra pour une raison inconnue.",
|
||||
"cameraUnsupportedResolutionError": "Votre caméra ne prend pas en charge la résolution vidéo nécessaire.",
|
||||
"close": "Fermer",
|
||||
@@ -297,28 +321,29 @@
|
||||
"conferenceReloadMsg": "Nous tentons de résoudre le problème. Reconnexion dans {{seconds}} sec…",
|
||||
"conferenceReloadTitle": "Malheureusement, une erreur s'est produite.",
|
||||
"confirm": "Confirmer",
|
||||
"confirmBack": "Retour",
|
||||
"confirmNo": "Non",
|
||||
"confirmYes": "Oui",
|
||||
"connectError": "Oups! Une erreur s'est produite. La connexion à la conférence a échouée.",
|
||||
"connectErrorWithMsg": "Oups! Une erreur s'est produite. La connexion à la conférence a échoué : {{msg}}",
|
||||
"connectError": "Oups! Une erreur s'est produite. La connexion à la réunion a échouée.",
|
||||
"connectErrorWithMsg": "Oups! Une erreur s'est produite. La connexion à la réunion a échoué : {{msg}}",
|
||||
"connecting": "Connexion en cours",
|
||||
"contactSupport": "Communiquez avec le service de soutien",
|
||||
"copied": "Copié",
|
||||
"copy": "Copier",
|
||||
"demoteParticipantDialog": "Êtes-vous sûr de vouloir déplacer ce participant en visiteur ?",
|
||||
"demoteParticipantTitle": "Déplacer en visiteur",
|
||||
"dismiss": "Rejeter",
|
||||
"displayNameRequired": "Un nom d'affichage est requis",
|
||||
"done": "Terminé",
|
||||
"e2eeDescription": "Le chiffrement de bout en bout est actuellement expérimental. Veuillez garder en tête que l'activation du chiffrement de bout en bout désactivera les services fournis côté serveur tels que : l'enregistrement, la diffusion en direct et la participation par téléphone. Gardez également en tête que la réunion ne fonctionnera que pour les personnes qui se connectent à partir de navigateurs prenant en charge les flux insérables.",
|
||||
"e2eeDisabledDueToMaxModeDescription": "Impossible d'activer le chiffrement de bout en bout en raison du trop grand nombre de participants à la conférence.",
|
||||
"e2eeDisabledDueToMaxModeDescription": "Impossible d'activer le chiffrement de bout en bout en raison du trop grand nombre de participants à la réunion.",
|
||||
"e2eeLabel": "Activer le chiffrement de Bout-en-Bout",
|
||||
"e2eeWarning": "ATTENTION : Tous les participants de cette réunion ne semblent pas prendre en charge le chiffrement de bout en bout. Si vous activez le chiffrement, ils ne pourront ni vous voir, ni vous entendre.",
|
||||
"e2eeWillDisableDueToMaxModeDescription": "ATTENTION: le chiffrement de bout en bout sera automatiquement arrêté si plus de participants joignent la conférence.",
|
||||
"e2eeWillDisableDueToMaxModeDescription": "ATTENTION: le chiffrement de bout en bout sera automatiquement arrêté si plus de participants joignent la réunion.",
|
||||
"embedMeeting": "Intégrer la réunion",
|
||||
"enterDisplayName": "Veuillez saisir votre nom d'affichage",
|
||||
"error": "Erreur",
|
||||
"externalInstallationMsg": "Vous devez installer notre extension de partage de bureau.",
|
||||
"externalInstallationTitle": "Extension requise",
|
||||
"goToStore": "Rendez-vous sur notre boutique en ligne",
|
||||
"errorRoomCreationRestriction": "Vous avez essayé de rejoindre trop rapidement, veuillez revenir dans un moment.",
|
||||
"gracefulShutdown": "Notre service est actuellement hors service pour l'entretien. Veuillez réessayer plus tard.",
|
||||
"grantModeratorDialog": "Êtes-vous sûr de vouloir rendre ce participant modérateur ?",
|
||||
"grantModeratorTitle": "Nommer modérateur",
|
||||
@@ -326,57 +351,65 @@
|
||||
"hideShareAudioHelper": "Ne plus afficher ce dialogue",
|
||||
"incorrectPassword": "Nom d'utilisateur ou mot de passe incorrect",
|
||||
"incorrectRoomLockPassword": "Mot de passe incorrect",
|
||||
"inlineInstallExtension": "Installer maintenant",
|
||||
"inlineInstallationMsg": "Vous devez installer notre extension de partage de bureau.",
|
||||
"internalError": "Oups! Une erreur s'est produite. L'erreur suivante est survenue : {{error}}",
|
||||
"internalErrorTitle": "Erreur interne.",
|
||||
"kickMessage": "Aïe! Vous avez été expulsé de la réunion!",
|
||||
"kickParticipantButton": "Expulser",
|
||||
"kickParticipantDialog": "Êtes-vous certain de vouloir expulser ce participant?",
|
||||
"kickParticipantTitle": "Expulser ce membre?",
|
||||
"kickSystemTitle": "Oups ! Vous avez été expulsé de la réunion",
|
||||
"kickTitle": "Expulsé de la réunion",
|
||||
"linkMeeting": "Relier la conférence",
|
||||
"linkMeetingTitle": "Relier la conférence à Salesforce",
|
||||
"learnMore": "en savoir plus",
|
||||
"linkMeeting": "Relier la réunion",
|
||||
"linkMeetingTitle": "Relier la réunion à Salesforce",
|
||||
"liveStreaming": "Diffusion en direct",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Impossible durant l'enregistrement",
|
||||
"liveStreamingDisabledForGuestTooltip": "Les invités ne peuvent pas démarrer la diffusion en direct.",
|
||||
"liveStreamingDisabledTooltip": "Démarrage de la diffusion en direct désactivé.",
|
||||
"localUserControls": "Contrôles de l'utilisateur local",
|
||||
"lockMessage": "Échec du verrouillage de la conférence.",
|
||||
"lockMessage": "Échec du verrouillage de la réunion.",
|
||||
"lockRoom": "Ajouter un mot de passe à la réunion",
|
||||
"lockTitle": "Échec du verrouillage",
|
||||
"login": "Connexion",
|
||||
"loginQuestion": "Voulez-vous vraiment vous connecter et quitter la conférence?",
|
||||
"logoutQuestion": "Êtes-vous certain de vouloir vous déconnecter et arrêter la conférence?",
|
||||
"loginQuestion": "Voulez-vous vraiment vous connecter et quitter la réunion?",
|
||||
"logoutQuestion": "Êtes-vous certain de vouloir vous déconnecter et arrêter la réunion?",
|
||||
"logoutTitle": "Déconnexion",
|
||||
"maxUsersLimitReached": "La limite du nombre maximum de membres a été atteinte. La conférence est pleine. Veuillez communiquer avec l'hôte de la réunion ou réessayer plus tard.",
|
||||
"maxUsersLimitReached": "La limite du nombre maximum de membres a été atteinte. La réunion est pleine. Veuillez communiquer avec l'hôte de la réunion ou réessayer plus tard.",
|
||||
"maxUsersLimitReachedTitle": "Limite du nombre de membres maximum atteinte",
|
||||
"micConstraintFailedError": "Votre micro ne répond pas à certaines exigences",
|
||||
"micNotFoundError": "Impossible de trouver le micro.",
|
||||
"micNotSendingData": "Impossible d'accéder à votre micro. Veuillez sélectionner un autre dispositif à partir du menu des paramètres ou essayer de recharger l'application.",
|
||||
"micNotSendingDataTitle": "Impossible d'accéder à votre micro",
|
||||
"micPermissionDeniedError": "Vous n'avez pas accordé l'autorisation d'utilisation de votre micro. Vous pouvez toujours rejoindre la conférence, mais les autres membres ne pourront pas vous entendre. Utilisez le bouton de caméra dans la barre d'adresse pour remédier à cela.",
|
||||
"micPermissionDeniedError": "Vous n'avez pas accordé l'autorisation d'utilisation de votre micro. Vous pouvez toujours rejoindre la réunion, mais les autres membres ne pourront pas vous entendre. Utilisez le bouton de caméra dans la barre d'adresse pour remédier à cela.",
|
||||
"micTimeoutError": "Impossible de démarrer la source audio. Délai dépassé!",
|
||||
"micUnknownError": "Impossible d'utiliser le micro pour une raison inconnue.",
|
||||
"moderationAudioLabel": "Autoriser les participants à réactiver leur micro",
|
||||
"moderationDesktopLabel": "Autoriser les non-modérateurs à partager leur écran",
|
||||
"moderationVideoLabel": "Autoriser les participants à démarrer leur vidéo",
|
||||
"muteEveryoneDialog": "Êtes-vous sûr de vouloir couper les micros de tout le monde? Vous ne pourrez plus réactiver leur micro, mais ils pourront l'activer par eux-mêmes à tout moment.",
|
||||
"muteEveryoneDialogModerationOn": "Les participants peuvent demander à parler n'importe quand",
|
||||
"muteEveryoneElseDialog": "Une fois leur micro coupé, vous ne pourrez plus le réactiver, mais ils pourront l'activer par eux-mêmes à tout moment.",
|
||||
"muteEveryoneElseTitle": "Couper le micro de tout le monde sauf de {{whom}}?",
|
||||
"muteEveryoneElsesDesktopDialog": "Une fois le partage arrêté, vous ne pourrez pas le redémarrer, mais ils peuvent le faire à tout moment.",
|
||||
"muteEveryoneElsesDesktopTitle": "Arrêter le partage d'écran de tout le monde sauf {{whom}} ?",
|
||||
"muteEveryoneElsesVideoDialog": "Une fois la caméra coupée, vous ne pourrez plus la rallumer, mais ils peuvent la rallumer à tout moment.",
|
||||
"muteEveryoneElsesVideoTitle": "Couper la vidéo de tout le monde sauf {{whom}}?",
|
||||
"muteEveryoneSelf": "vous",
|
||||
"muteEveryoneStartMuted": "Tout le monde démarre avec le micro coupé",
|
||||
"muteEveryoneTitle": "Couper le micro de tout le monde ?",
|
||||
"muteEveryonesDesktopDialog": "Les participants peuvent partager leur écran à tout moment.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "Les participants peuvent envoyer une demande pour partager leur écran à tout moment.",
|
||||
"muteEveryonesDesktopTitle": "Arrêter le partage d'écran de tout le monde ?",
|
||||
"muteEveryonesVideoDialog": "Êtes-vous sûr de vouloir couper la caméra de tout le monde? Vous ne pourrez pas la réactiver, mais ils peuvent la remettre à tout moment.",
|
||||
"muteEveryonesVideoDialogModerationOn": "Les participants peuvent demander à activer leur caméra n'importe quand.",
|
||||
"muteEveryonesVideoDialogOk": "Désactiver",
|
||||
"muteEveryonesVideoTitle": "Couper la caméra de tout le monde?",
|
||||
"muteParticipantBody": "Vous ne pourrez pas réactiver leur micro, mais ils peuvent le réactiver eux-mêmes à tout moment.",
|
||||
"muteParticipantButton": "Discrétion",
|
||||
"muteParticipantDialog": "Êtes-vous certain de vouloir désactiver le micro de ce participant? Vous ne pourrez pas le réactiver, mais il peut le réactiver lui-même à tout moment.",
|
||||
"muteParticipantTitle": "Désactiver le micro de ce membre?",
|
||||
"muteParticipantsDesktopBody": "Vous ne pourrez pas démarrer leur partage d'écran, mais ils peuvent le faire à tout moment.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "Vous ne pourrez pas démarrer leur partage d'écran et eux non plus.",
|
||||
"muteParticipantsDesktopButton": "Arrêter le partage d'écran",
|
||||
"muteParticipantsDesktopDialog": "Êtes-vous sûr de vouloir désactiver le partage d'écran de ce participant ? Vous ne pourrez pas le redémarrer, mais ils peuvent le faire à tout moment.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Êtes-vous sûr de vouloir désactiver le partage d'écran de ce participant ? Vous ne pourrez pas réactiver l'écran et eux non plus.",
|
||||
"muteParticipantsDesktopTitle": "Désactiver le partage d'écran de ce participant ?",
|
||||
"muteParticipantsVideoBody": "Vous ne pourrez pas rallumer la caméra, mais ils peuvent la rallumer à tout moment.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Ni vous ni le participant ne pourront rallumer la caméra.",
|
||||
"muteParticipantsVideoButton": "Couper la caméra",
|
||||
@@ -392,14 +425,14 @@
|
||||
"permissionCameraRequiredError": "L'autorisation caméra est nécessaire pour participer aux réunions avec vidéo. Merci de l'accorder dans les paramètres",
|
||||
"permissionErrorTitle": "Permission nécessaire",
|
||||
"permissionMicRequiredError": "L'autorisation microphone est nécessaire pour participer aux réunions avec son. Merci de l'accorder dans les paramètres",
|
||||
"popupError": "Votre navigateur bloque les fenêtres surgissantes provenant de ce site. Veuillez activer les fenêtres surgissantes dans les paramètres de sécurité de votre navigateur et réessayer.",
|
||||
"popupErrorTitle": "Fenêtre surgissante bloquée",
|
||||
"readMore": "plus",
|
||||
"recentlyUsedObjects": "Vos objets récemment utilisés",
|
||||
"recording": "Enregistrement",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossible durant le direct",
|
||||
"recordingDisabledForGuestTooltip": "Les invités ne peuvent pas démarrer l'enregistrement.",
|
||||
"recordingDisabledTooltip": "Démarrage de l'enregistrement désactivé.",
|
||||
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA{{learnMore}}. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
|
||||
"recordingInProgressDescriptionFirstHalf": "Cette réunion est en cours d'enregistrement et d'analyse par IA",
|
||||
"recordingInProgressDescriptionSecondHalf": ". Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
|
||||
"recordingInProgressTitle": "Enregistrement en cours",
|
||||
"rejoinNow": "Rejoindre maintenant",
|
||||
"remoteControlAllowedMessage": "{{user}} a accepté votre demande de contrôle à distance!",
|
||||
"remoteControlDeniedMessage": "{{user}} a refusé votre demande de contrôle à distance!",
|
||||
@@ -408,6 +441,7 @@
|
||||
"remoteControlShareScreenWarning": "Notez que si vous appuyez sur « Permettre », vous partagerez votre écran!",
|
||||
"remoteControlStopMessage": "La séance de contrôle à distance est terminée!",
|
||||
"remoteControlTitle": "Contrôle du bureau à distance",
|
||||
"remoteUserControls": "Contrôles de l'utilisateur distant {{username}}",
|
||||
"removePassword": "Supprimer un mot de passe",
|
||||
"removeSharedVideoMsg": "Êtes-vous certain de vouloir supprimer votre vidéo partagée?",
|
||||
"removeSharedVideoTitle": "Supprimer la vidéo partagée",
|
||||
@@ -419,10 +453,6 @@
|
||||
"screenSharingAudio": "Partager l'audio",
|
||||
"screenSharingFailed": "Oups! Quelque chose s'est mal passé, nous n'avons pas pu démarrer le partage d'écran!",
|
||||
"screenSharingFailedTitle": "Echec du partage d'écran!",
|
||||
"screenSharingFailedToInstall": "Oups! L'installation de votre extension de partage d'écran a échouée.",
|
||||
"screenSharingFailedToInstallTitle": "L'installation de l'extension de partage d'écran a échouée",
|
||||
"screenSharingFirefoxPermissionDeniedError": "Une erreur s'est produite lors de la tentative de partage d'écran. Veuillez vous assurer d'avoir donné votre autorisation.",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "Oups! Il est impossible de démarrer le partage d'écran!",
|
||||
"screenSharingPermissionDeniedError": "Oups! Une erreur s'est produite avec les autorisations de l'extension de partage d'écran. Veuillez recharger et réessayer.",
|
||||
"searchInSalesforce": "Rechercher dans Salesforce",
|
||||
"searchResults": "Résultats de recherche ({{count}})",
|
||||
@@ -450,11 +480,13 @@
|
||||
"shareScreenWarningD2": "vous devez arrêter le partage d'audio, démarrer le partage d'écran et cocher l'option \"Partager l'audio\".",
|
||||
"shareScreenWarningH1": "Si vous voulez partager uniquement votre écran:",
|
||||
"shareScreenWarningTitle": "Vous devez cesser de partager votre audio avant de partager votre écran",
|
||||
"shareVideoConfirmPlay": "Vous êtes sur le point d'ouvrir un site web externe. Voulez-vous continuer ?",
|
||||
"shareVideoConfirmPlayTitle": "{{name}} a partagé une vidéo avec vous.",
|
||||
"shareVideoLinkError": "Veuillez fournir un lien correct.",
|
||||
"shareVideoLinkStopped": "La vidéo de {{name}} a été arrêtée.",
|
||||
"shareVideoTitle": "Partager une vidéo",
|
||||
"shareYourScreen": "Partager votre écran",
|
||||
"shareYourScreenDisabled": "Le partage d'écran est désactivé.",
|
||||
"shareYourScreenDisabledForGuest": "Les invités ne peuvent pas partager leur écran.",
|
||||
"sharedVideoDialogError": "Erreur: URL invalide",
|
||||
"sharedVideoLinkPlaceholder": "lien YouTube ou lien vidéo direct",
|
||||
"show": "Afficher",
|
||||
@@ -512,7 +544,7 @@
|
||||
"title": "Document partagé"
|
||||
},
|
||||
"e2ee": {
|
||||
"labelToolTip": "Le son et la vidéo de cette conférence sont chiffrés de bout en bout"
|
||||
"labelToolTip": "Le son et la vidéo de cette réunion sont chiffrés de bout en bout"
|
||||
},
|
||||
"embedMeeting": {
|
||||
"title": "Intégrer cette réunion"
|
||||
@@ -525,10 +557,28 @@
|
||||
"bad": "Mauvaise",
|
||||
"detailsLabel": "Dites-nous en plus.",
|
||||
"good": "Bonne",
|
||||
"rateExperience": "Évaluez votre expérience de cette conférence",
|
||||
"rateExperience": "Évaluez votre expérience de cette réunion",
|
||||
"star": "Étoile",
|
||||
"veryBad": "Très mauvaise",
|
||||
"veryGood": "Très bonne"
|
||||
},
|
||||
"fileSharing": {
|
||||
"downloadFailedDescription": "Veuillez réessayer.",
|
||||
"downloadFailedTitle": "Échec du téléchargement",
|
||||
"downloadFile": "Télécharger",
|
||||
"downloadStarted": "Téléchargement de fichier démarré",
|
||||
"dragAndDrop": "Glisser-déposer des fichiers ici ou n'importe où à l'écran",
|
||||
"fileAlreadyUploaded": "Ce fichier a déjà été téléversé dans cette réunion.",
|
||||
"fileTooLargeDescription": "Veuillez vous assurer que le fichier ne dépasse pas {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "Le fichier choisi est trop volumineux",
|
||||
"fileUploadProgress": "Progression du téléchargement de fichier",
|
||||
"fileUploadedSuccessfully": "Fichier téléversé avec succès",
|
||||
"removeFile": "Supprimer",
|
||||
"removeFileSuccess": "Fichier supprimé avec succès",
|
||||
"uploadFailedDescription": "Veuillez réessayer.",
|
||||
"uploadFailedTitle": "Échec du téléchargement",
|
||||
"uploadFile": "Partager un fichier"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Vignettes vidéos"
|
||||
@@ -576,6 +626,7 @@
|
||||
"noNumbers": "Aucun numéro d'appel trouvé",
|
||||
"noPassword": "Aucun",
|
||||
"noRoom": "Vous n'avez pas précisé de salle pour l'appel interne.",
|
||||
"noWhiteboard": "Impossible de charger le tableau blanc.",
|
||||
"numbers": "Numéros d'appel",
|
||||
"password": "Mot de passe:",
|
||||
"reachedLimit": "Vous avez atteint la limite de votre abonnement.",
|
||||
@@ -583,7 +634,8 @@
|
||||
"sipAudioOnly": "Adresse SIP en audio uniquement",
|
||||
"title": "Partager",
|
||||
"tooltip": "Lien de partage et informations d'appel interne pour cette réunion",
|
||||
"upgradeOptions": "Veuillez vérifier les options de mise à niveau"
|
||||
"upgradeOptions": "Veuillez vérifier les options de mise à niveau",
|
||||
"whiteboardError": "Erreur de chargement du tableau blanc. Veuillez réessayer plus tard."
|
||||
},
|
||||
"inlineDialogFailure": {
|
||||
"msg": "Nous avons rencontré un obstacle.",
|
||||
@@ -613,10 +665,10 @@
|
||||
"showSpeakerStats": "Afficher les statistiques d'intervenant",
|
||||
"toggleChat": "Ouvrir ou fermer le clavardage",
|
||||
"toggleFilmstrip": "Afficher ou masquer les icônes vidéos",
|
||||
"toggleParticipantsPane": "Afficher ou masquer le volet des participants",
|
||||
"toggleScreensharing": "Basculer entre la caméra et le partage d'écran",
|
||||
"toggleShortcuts": "Afficher ou masquer les raccourcis clavier",
|
||||
"videoMute": "Démarrer ou arrêter votre caméra",
|
||||
"videoQuality": "Gérer la qualité d'appel"
|
||||
"videoMute": "Démarrer ou arrêter votre caméra"
|
||||
},
|
||||
"largeVideo": {
|
||||
"screenIsShared": "Vous êtes en train de partager votre écran",
|
||||
@@ -647,6 +699,7 @@
|
||||
"on": "Diffusion en direct",
|
||||
"onBy": "{{name}} démarré la diffusion en continu",
|
||||
"pending": "Démarrage de la diffusion en direct…",
|
||||
"policyError": "Vous avez essayé de démarrer une diffusion en direct trop rapidement. Veuillez réessayer plus tard !",
|
||||
"serviceName": "Service de diffusion en direct",
|
||||
"sessionAlreadyActive": "Cette session est déjà en cours d'enregistrement ou de diffusion.",
|
||||
"signIn": "Se connecter avec Google",
|
||||
@@ -694,7 +747,8 @@
|
||||
"notificationTitle": "Salle d'attente",
|
||||
"passwordJoinButton": "Rejoindre",
|
||||
"title": "Salle d'attente",
|
||||
"toggleLabel": "Activer la salle d'attente"
|
||||
"toggleLabel": "Activer la salle d'attente",
|
||||
"waitForModerator": "La réunion n'a pas encore commencé car aucun modérateur n'est encore arrivé. Si vous souhaitez devenir modérateur, veuillez vous connecter. Sinon, veuillez attendre."
|
||||
},
|
||||
"localRecording": {
|
||||
"clientState": {
|
||||
@@ -737,27 +791,37 @@
|
||||
"me": "moi",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Faille de sécurité !",
|
||||
"allowAction": "Permettre",
|
||||
"allowAll": "Tout autoriser",
|
||||
"allowAudio": "Autoriser l'audio",
|
||||
"allowDesktop": "Autoriser le partage d'écran",
|
||||
"allowVideo": "Autoriser la vidéo",
|
||||
"allowedUnmute": "Vous pouvez réactiver votre écran, votre caméra ou partager votre écran.",
|
||||
"audioUnmuteBlockedDescription": "Le rétablissement du son a été bloqué temporairement en raison de limites système.",
|
||||
"audioUnmuteBlockedTitle": "Rétablissement du son bloqué!",
|
||||
"chatMessages": "Messages de chat",
|
||||
"connectedOneMember": "{{name}} a rejoint la réunion",
|
||||
"connectedThreePlusMembers": "{{name}} et {{count}} autres ont rejoint la réunion",
|
||||
"connectedTwoMembers": "{{first}} et {{second}} ont rejoint la réunion",
|
||||
"connectedOneMember": "{{name}} a rerejoint la réunion",
|
||||
"connectedThreePlusMembers": "{{name}} et {{count}} autres ont rerejoint la réunion",
|
||||
"connectedTwoMembers": "{{first}} et {{second}} ont rerejoint la réunion",
|
||||
"connectionFailed": "Connexion échouée. Veuillez réessayer plus tard !",
|
||||
"dataChannelClosed": "Qualité vidéo dégradée",
|
||||
"dataChannelClosedDescription": "Le canal de communication avec le Bridge a été interrompu, la qualité vidéo se trouve limitée à sa valeur la plus faible.",
|
||||
"dataChannelClosedDescriptionWithAudio": "Le canal de pont est fermé, ce qui peut entraîner des perturbations de l'audio et de la vidéo.",
|
||||
"dataChannelClosedWithAudio": "La qualité de l'audio et de la vidéo peut être altérée",
|
||||
"desktopMutedRemotelyTitle": "Votre partage d'écran a été arrêté par {{participantDisplayName}}",
|
||||
"disabledIframe": "L'intégration Iframe est uniquement destinée à des démos, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondary": "L'intégration Iframe de {{domaine}} est uniquement destinée à des démos, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryNative": "L'intégration de {{domain}} est uniquement destinée aux fins de démonstration, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryWeb": "L'intégration de {{domain}} est uniquement destinée aux fins de démonstration, cet appel se terminera dans {{timeout}} minutes. Veuillez utiliser <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> pour l'intégration en production !",
|
||||
"disconnected": "déconnecté",
|
||||
"displayNotifications": "Afficher les notifications pour",
|
||||
"dontRemindMe": "Ne pas me le rappeler",
|
||||
"focus": "Sujet de la conférence",
|
||||
"focus": "Sujet de la réunion",
|
||||
"focusFail": "{{component}} non disponible; réessayez dans {{ms}} sec",
|
||||
"gifsMenu": "GIPHY",
|
||||
"grantedTo": "Droits de modérateur accordés à {{to}}!",
|
||||
"groupTitle": "Notifications",
|
||||
"hostAskedUnmute": "Le modérateur souhaite vous donner la parole",
|
||||
"invalidTenant": "Tenant invalide",
|
||||
"invalidTenantHyphenDescription": "Le tenant que vous utilisez est invalide (commence ou se termine par '-').",
|
||||
"invalidTenantLengthDescription": "Le tenant que vous utilisez est trop long.",
|
||||
"invitedOneMember": "{{displayName}} a été invité",
|
||||
"invitedThreePlusMembers": "{{name}} et {{count}} autres ont été invités",
|
||||
"invitedTwoMembers": "{{first}} et {{second}} ont été invités",
|
||||
@@ -767,11 +831,11 @@
|
||||
"leftThreePlusMembers": "{{name}} et beaucoup d'autres ont quitté la réunion",
|
||||
"leftTwoMembers": "{{first}} et {{second}} ont quitté la réunion",
|
||||
"linkToSalesforce": "Lien à Salesforce",
|
||||
"linkToSalesforceDescription": "Vous pouvez lier le résumé de la conférence à un objet Salesforce.",
|
||||
"linkToSalesforceError": "Impossible de relier la conférence à Salesforce",
|
||||
"linkToSalesforceKey": "Relier cette conférence",
|
||||
"linkToSalesforceProgress": "Liaison de la conférence à Salesforce…",
|
||||
"linkToSalesforceSuccess": "La conférence a été reliée à Salesforce",
|
||||
"linkToSalesforceDescription": "Vous pouvez lier le résumé de la réunion à un objet Salesforce.",
|
||||
"linkToSalesforceError": "Impossible de relier la réunion à Salesforce",
|
||||
"linkToSalesforceKey": "Relier cette réunion",
|
||||
"linkToSalesforceProgress": "Liaison de la réunion à Salesforce…",
|
||||
"linkToSalesforceSuccess": "La réunion a été reliée à Salesforce",
|
||||
"localRecordingStarted": "{{name}} a commencé un enregistrement local.",
|
||||
"localRecordingStopped": "{{name}} a arrêté un enregistrement local.",
|
||||
"me": "Moi",
|
||||
@@ -794,18 +858,21 @@
|
||||
"newDeviceAction": "Utiliser",
|
||||
"newDeviceAudioTitle": "Nouveau dispositif audio détecté",
|
||||
"newDeviceCameraTitle": "Nouvelle caméra détectée",
|
||||
"nextToSpeak": "Vous êtes le prochain à prendre la parole",
|
||||
"noiseSuppressionDesktopAudioDescription": "La suppression de bruit ne peut pas être activée en même temps que la partage audio du système, veuillez le désactiver et réessayer.",
|
||||
"noiseSuppressionFailedTitle": "Échec du démarrage de la suppression de bruit",
|
||||
"noiseSuppressionStereoDescription": "La suppression de bruit d'une source stéréo n'est pas encore supportée.",
|
||||
"oldElectronClientDescription1": "Vous semblez utiliser une ancienne version du client Jitsi Meet qui présente des failles de sécurité connues. Veuillez vous assurer de mettre à jour vers notre ",
|
||||
"oldElectronClientDescription2": "dernière build",
|
||||
"oldElectronClientDescription3": " rapidement !",
|
||||
"openChat": "Ouvrir le chat",
|
||||
"participantWantsToJoin": "souhaite rejoindre la réunion",
|
||||
"participantsWantToJoin": "souhaitent rejoindre la réunion",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) supprimé par un autre participant",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) défini par un autre participant",
|
||||
"raiseHandAction": "Lever la main",
|
||||
"raisedHand": "{{name}} voudrait parler.",
|
||||
"raisedHands": "{{participantName}} et {{raisedHands}} autres personnes",
|
||||
"reactionSounds": "Bloquer les réactions sonores",
|
||||
"reactionSoundsForAll": "Bloquer les réactions sonores pour tous",
|
||||
"screenShareNoAudio": " La case Partager l'audio n'a pas été cochée dans l'écran de sélection de la fenêtre.",
|
||||
@@ -818,13 +885,22 @@
|
||||
"startSilentTitle": "Vous avez rejoint sans sortie audio!",
|
||||
"suboptimalBrowserWarning": "Nous craignons que votre expérience de réunion en ligne ne soit bonne ici. Nous cherchons des moyens d'améliorer cela, mais d'ici-là, essayez d'utiliser l'un des <a href='{{recommendedBrowserPageLink}}' target='_blank'>navigateurs supportés</a>.",
|
||||
"suboptimalExperienceTitle": "Avertissement de navigateur",
|
||||
"suggestRecordingAction": "Démarrer",
|
||||
"suggestRecordingDescription": "Souhaitez-vous démarrer un enregistrement ?",
|
||||
"suggestRecordingTitle": "Enregistrer cette réunion",
|
||||
"unmute": "Rétablir le son",
|
||||
"unmuteScreen": "Démarrer le partage d'écran",
|
||||
"unmuteVideo": "Réactiver la vidéo",
|
||||
"videoMutedRemotelyDescription": "Vous pouvez toujours la réactiver.",
|
||||
"videoMutedRemotelyTitle": "Votre caméra a été coupée par {{participantDisplayName}}!",
|
||||
"videoUnmuteBlockedDescription": "Le rétablissement de la vidéo a été bloqué temporairement en raison de limites système.",
|
||||
"videoUnmuteBlockedTitle": "Rétablissement de la caméra bloqué !",
|
||||
"viewLobby": "Voir la salle d'attente",
|
||||
"viewParticipants": "Voir les participants",
|
||||
"viewVisitors": "Voir les visiteurs",
|
||||
"waitingParticipants": "{{waitingParticipants}} personnes",
|
||||
"waitingVisitors": "Visiteurs en attente dans la file : {{waitingVisitors}}",
|
||||
"waitingVisitorsTitle": "La réunion n'est pas encore en direct !",
|
||||
"whiteboardLimitDescription": "Veuillez sauvegarder votre progression, car la limite d'utilisation du tableau blanc sera bientôt atteinte et celui-ci sera fermé.",
|
||||
"whiteboardLimitTitle": "Utiilisation du tableau blanc"
|
||||
},
|
||||
@@ -833,12 +909,18 @@
|
||||
"admit": "Accepter",
|
||||
"admitAll": "Tout accepter",
|
||||
"allow": "Autoriser les participants à:",
|
||||
"allowDesktop": "Autoriser le partage d'écran",
|
||||
"allowVideo": "permettre la vidéo",
|
||||
"askDesktop": "Demander de partager l'écran",
|
||||
"askUnmute": "Demander de réactiver le micro",
|
||||
"audioModeration": "Rouvrir leur micro",
|
||||
"blockEveryoneMicCamera": "Bloquer tous les micros et caméras",
|
||||
"breakoutRooms": "Salles annexes",
|
||||
"desktopModeration": "Démarrer le partage d'écran",
|
||||
"goLive": "Passer en direct",
|
||||
"invite": "Inviter quelqu'un",
|
||||
"lowerAllHands": "Abaisser toutes les mains",
|
||||
"lowerHand": "Abaisser la main",
|
||||
"moreModerationActions": "Options de modération supplémentaires",
|
||||
"moreModerationControls": "Options de modération supplémentaires",
|
||||
"moreParticipantOptions": "Options supplémentaires pour les participants",
|
||||
@@ -846,6 +928,8 @@
|
||||
"muteAll": "Couper le micro de tout le monde",
|
||||
"muteEveryoneElse": "Couper le micro de tous les autres",
|
||||
"reject": "Refuser",
|
||||
"stopDesktop": "Arrêter le partage d'écran",
|
||||
"stopEveryonesDesktop": "Arrêter le partage d'écran de tout le monde",
|
||||
"stopEveryonesVideo": "Couper toutes les caméras",
|
||||
"stopVideo": "Couper la vidéo",
|
||||
"unblockEveryoneMicCamera": "Débloquer tous les micros et caméras",
|
||||
@@ -855,11 +939,15 @@
|
||||
"headings": {
|
||||
"lobby": "Salle d'attente ({{count}})",
|
||||
"participantsList": "Participants de la réunion ({{count}})",
|
||||
"viewerRequests": "Demandes des spectateurs {{count}}",
|
||||
"visitorInQueue": " (en attente {{count}})",
|
||||
"visitorRequests": "(Demande {{count}} )",
|
||||
"visitors": "Visiteurs {{count}}",
|
||||
"visitorsList": "Spectateurs ({{count}})",
|
||||
"waitingLobby": "Dans la salle d'attente ({{count}})"
|
||||
},
|
||||
"search": "Rechercher des participants",
|
||||
"searchDescription": "Commencez à taper pour filtrer les participants",
|
||||
"title": "Participants"
|
||||
},
|
||||
"passwordDigitsOnly": "Jusqu'à {{number}} chiffres",
|
||||
@@ -868,10 +956,13 @@
|
||||
"pinnedParticipant": "Participant toujours affiché",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"edit": "Modifier",
|
||||
"send": "Envoyer",
|
||||
"skip": "Passer",
|
||||
"submit": "Envoyer"
|
||||
},
|
||||
"by": "Par {{ name }}",
|
||||
"closeButton": "Fermer le sondage",
|
||||
"create": {
|
||||
"addOption": "Ajouter une option",
|
||||
"answerPlaceholder": "Option {{index}}",
|
||||
@@ -881,6 +972,7 @@
|
||||
"pollQuestion": "Question du sondage",
|
||||
"questionPlaceholder": "Poser une question",
|
||||
"removeOption": "Supprimer l'option",
|
||||
"save": "Enregistrer",
|
||||
"send": "Envoyer"
|
||||
},
|
||||
"errors": {
|
||||
@@ -910,9 +1002,11 @@
|
||||
"configuringDevices": "Configuration des appareils…",
|
||||
"connectedWithAudioQ": "Êtes-vous connecté avec le microphone ?",
|
||||
"connection": {
|
||||
"failed": "Le test de connexion a échoué !",
|
||||
"good": "Votre connexion Internet est bonne !",
|
||||
"nonOptimal": "Votre connexion n'est pas optimale",
|
||||
"poor": "Vous avez une mauvaise connexion"
|
||||
"poor": "Vous avez une mauvaise connexion",
|
||||
"running": "Exécution du test de connexion…"
|
||||
},
|
||||
"connectionDetails": {
|
||||
"audioClipping": "Attendez vous à ce que votre son soit coupé.",
|
||||
@@ -921,6 +1015,7 @@
|
||||
"goodQuality": "Impressionnant ! La qualité de vos médias sera excellente",
|
||||
"noMediaConnectivity": "Nous n'avons pas pu trouver un moyen d'établir une connectivité multimédia pour ce test. Cela est généralement causé par un pare-feu ou un NAT.",
|
||||
"noVideo": "Attendez vous à ce que votre qualité vidéo soit très mauvaise.",
|
||||
"testFailed": "Le test de connexion a rencontré des problèmes inattendus, mais cela pourrait ne pas affecter votre expérience.",
|
||||
"undetectable": "Si vous ne parvenez toujours pas à passer des appels dans le navigateur, nous vous recommandons de vous assurer que vos haut-parleurs, microphone et caméra sont correctement configurés, que vous avez accordé à votre navigateur les droits d'utiliser votre microphone et votre caméra et que la version de votre navigateur est à jour. Si vous rencontrez toujours des difficultés pour appeler, vous devez contacter le développeur de l'application Web.",
|
||||
"veryPoorConnection": "Attendez vous à ce que la qualité de votre appel soit très mauvaise",
|
||||
"videoFreezing": "Attendez vous à ce que votre vidéo saute, soit noire, et pixelisée.",
|
||||
@@ -937,7 +1032,7 @@
|
||||
"errorDialOutDisconnected": "Impossible de composer le numéro. Déconnecté",
|
||||
"errorDialOutFailed": "Impossible de composer le numéro. L'appel a échoué",
|
||||
"errorDialOutStatus": "Erreur lors de l'obtention de l'état d'appel sortant",
|
||||
"errorMissingName": "Veuillez entrer votre nom pour entrer en conférence",
|
||||
"errorMissingName": "Veuillez entrer votre nom pour entrer en réunion",
|
||||
"errorNoPermissions": "Vous devez permettre l'accès microphone et caméra",
|
||||
"errorStatusCode": "Erreur de numérotation, code d'état: {{status}}",
|
||||
"errorValidation": "La validation du numéro a échoué",
|
||||
@@ -953,6 +1048,7 @@
|
||||
"or": "ou",
|
||||
"premeeting": "Pré-séance",
|
||||
"proceedAnyway": "Continuer quand même",
|
||||
"recordingWarning": "D'autres participants peuvent enregistrer cet appel",
|
||||
"screenSharingError": "Erreur de partage d'écran:",
|
||||
"startWithPhone": "Commencez avec l'audio du téléphone",
|
||||
"unsafeRoomConsent": "Je comprends les risques et je veux quand même rejoindre cette réunion",
|
||||
@@ -1018,7 +1114,6 @@
|
||||
"limitNotificationDescriptionNative": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <3> {{app}} </3>.",
|
||||
"limitNotificationDescriptionWeb": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
|
||||
"linkGenerated": "Nous avons généré un lien à votre enregistrement.",
|
||||
"live": "EN DIRECT",
|
||||
"localRecordingNoNotificationWarning": "Le démarrage de l’enregistrement ne sera pas annoncé aux autres participants. Vous devrez les informer par vous-même que la réunion sera enregistrée.",
|
||||
"localRecordingNoVideo": "La vidéo n'est pas en cours d’enregistrement",
|
||||
"localRecordingStartWarning": "Assurez-vous d’arrêter l’enregistrement vidéo avant de quitter la réunion afin de pouvoir le sauvegarder.",
|
||||
@@ -1035,13 +1130,13 @@
|
||||
"onBy": "{{name}} a démarré l'enregistrement",
|
||||
"onlyRecordSelf": "Enregistrer seulement mon audio et ma vidéo.",
|
||||
"pending": "Enregistrement de la réunion en préparation…",
|
||||
"rec": "REC",
|
||||
"policyError": "Vous avez essayé de démarrer un enregistrement trop rapidement. Veuillez réessayer plus tard !",
|
||||
"recordAudioAndVideo": "Enregistrer l'audio et la vidéo",
|
||||
"recordTranscription": "Enregistrer la transcription",
|
||||
"saveLocalRecording": "Sauvegarder l’enregistrement local (Beta)",
|
||||
"serviceDescription": "Votre enregistrement sera sauvegardé par le service d'enregistrement",
|
||||
"serviceDescriptionCloud": "Enregistrement Cloud",
|
||||
"serviceDescriptionCloudInfo": "Les conférences enregistrées sont automatiquement supprimées 24h après leur heure d'enregistrement.",
|
||||
"serviceDescriptionCloudInfo": "Les réunions enregistrées sont automatiquement supprimées 24h après leur heure d'enregistrement.",
|
||||
"serviceName": "Service d'enregistrement",
|
||||
"sessionAlreadyActive": "Cette session est déjà en cours d'enregistrement ou de diffusion.",
|
||||
"showAdvancedOptions": "Afficher les options avancées",
|
||||
@@ -1057,6 +1152,18 @@
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Tirer pour rafraîchir"
|
||||
},
|
||||
"security": {
|
||||
"about": "Vous pouvez ajouter un mot de passe à votre réunion. Les participants devront fournir le mot de passe avant de pouvoir rejoindre la réunion.",
|
||||
"aboutReadOnly": "Les modérateurs peuvent ajouter un mot de passe à la réunion. Les participants devront fournir le mot de passe avant de pouvoir rejoindre la réunion.",
|
||||
"insecureRoomNameWarningNative": "Le nom de la réunion n’est pas sûr. Des participants non voulus pourraient rejoindre cette réunion. {{recommendAction}} En apprendre plus sur la sécurisation des réunions.",
|
||||
"insecureRoomNameWarningWeb": "Le nom de la réunion n’est pas sûr. Des participants non voulus pourraient rejoindre cette réunion. {{recommendAction}} En apprendre plus sur la sécurisation des réunions <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
|
||||
"title": "Options de sécurité",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Envisagez de sécuriser votre réunion en utilisant le bouton options de sécurité.",
|
||||
"prejoin": "Envisagez d'utiliser un nom plus unique",
|
||||
"welcome": "Envisagez d'utiliser un nom plus unique ou choisissez en un parmi ceux suggérés"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Audio",
|
||||
"buttonLabel": "Paramètres",
|
||||
@@ -1067,11 +1174,13 @@
|
||||
"signedIn": "Accès aux événements de votre agenda en cours pour {{email}}. Cliquez sur le bouton de déconnexion ci-dessous pour terminer l'accès aux événements d'agenda.",
|
||||
"title": "Calendrier"
|
||||
},
|
||||
"chatWithPermissions": "Le chat nécessite une autorisation",
|
||||
"desktopShareFramerate": "Images par seconde pour le Partage d'écran",
|
||||
"desktopShareHighFpsWarning": "Augmenter le nombre d'images par seconde pour le partage d'écran peut impacter votre bande passante. Vous devez repartager l'écran pour que ces paramètres soient utilisés.",
|
||||
"desktopShareWarning": "Vous devez repartager l'écran pour que ces paramètres soient utilisés.",
|
||||
"devices": "Dispositifs",
|
||||
"followMe": "Tous les participants me suivent",
|
||||
"followMeRecorder": "L'enregistreur me suit",
|
||||
"framesPerSecond": "images par seconde",
|
||||
"incomingMessage": "un message arrive",
|
||||
"language": "Langue",
|
||||
@@ -1095,6 +1204,7 @@
|
||||
"selectMic": "Micro",
|
||||
"selfView": "Affichage de votre propre vidéo",
|
||||
"shortcuts": "Raccourcis",
|
||||
"showSubtitlesOnStage": "Afficher les sous-titres sur scène",
|
||||
"speakers": "Haut-parleurs",
|
||||
"startAudioMuted": "Tous les participants débutent en sourdine",
|
||||
"startReactionsMuted": "Tout le monde commence avec les réactions sonores bloquées",
|
||||
@@ -1111,7 +1221,7 @@
|
||||
"alertURLText": "L'URL de serveur saisi n'est pas valide",
|
||||
"apply": "Appliquer",
|
||||
"buildInfoSection": "Information de version",
|
||||
"conferenceSection": "Conférence",
|
||||
"conferenceSection": "Réunion",
|
||||
"disableCallIntegration": "Désactiver l'intégration d'appels native",
|
||||
"disableCrashReporting": "Désactiver les rapports de plantage",
|
||||
"disableCrashReportingWarning": "Etes-vous certain de vouloir désactiver les rapports de plantage ? Le paramètre sera effectif après le redémarrage de l'application.",
|
||||
@@ -1148,11 +1258,13 @@
|
||||
"fearful": "Effrayé",
|
||||
"happy": "Content",
|
||||
"hours": "{{count}} h",
|
||||
"labelTooltip": "Nombre de participants : {{count}}",
|
||||
"minutes": "{{count}} min",
|
||||
"name": "Nom",
|
||||
"neutral": "Neutre",
|
||||
"sad": "Triste",
|
||||
"search": "Recherche",
|
||||
"searchDescription": "Commencez à taper pour filtrer les participants",
|
||||
"searchHint": "Recherche des participants",
|
||||
"seconds": "{{count}} s",
|
||||
"speakerStats": "Statistiques d'intervenant",
|
||||
@@ -1160,7 +1272,7 @@
|
||||
"surprised": "Surpris"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"genericTitle": "La conférence a besoin d'utiliser votre microphone et votre caméra.",
|
||||
"genericTitle": "La réunion a besoin d'utiliser votre microphone et votre caméra.",
|
||||
"policyText": " ",
|
||||
"title": "{{app}} doit utiliser votre micro et votre caméra."
|
||||
},
|
||||
@@ -1189,6 +1301,7 @@
|
||||
"closeChat": "Fermer la discussion instantanée",
|
||||
"closeMoreActions": "Fermer le menu plus d'actions",
|
||||
"closeParticipantsPane": "Fermer le panneau des participants",
|
||||
"closedCaptions": "Sous-titres",
|
||||
"collapse": "Plier",
|
||||
"document": "Basculement du document partagé",
|
||||
"documentClose": "Fermer le document partagé",
|
||||
@@ -1218,6 +1331,7 @@
|
||||
"lobbyButton": "Activer / Désactiver le mode salle d'attente",
|
||||
"localRecording": "Basculement des commandes d'enregistrement local",
|
||||
"lockRoom": "Basculement du mot de passe de la réunion",
|
||||
"love": "Cœur",
|
||||
"lowerHand": "Baisser la main",
|
||||
"moreActions": "Basculement du menu d'actions supplémentaires",
|
||||
"moreActionsMenu": "Menu d'actions supplémentaires",
|
||||
@@ -1235,6 +1349,7 @@
|
||||
"privateMessage": "",
|
||||
"profile": "Modifier votre profil",
|
||||
"raiseHand": "Basculement de la main levée",
|
||||
"react": "Réactions aux messages",
|
||||
"reactions": "Réactions",
|
||||
"reactionsMenu": "Ouvrir / fermer le menu réactions",
|
||||
"recording": "Basculement de l'enregistrement",
|
||||
@@ -1265,6 +1380,20 @@
|
||||
"videounmute": "Démarrer la vidéo"
|
||||
},
|
||||
"addPeople": "Ajouter des personnes à votre appel",
|
||||
"advancedAudioSettings": {
|
||||
"aec": {
|
||||
"label": "Suppression d'écho acoustique"
|
||||
},
|
||||
"agc": {
|
||||
"label": "Contrôle automatique du gain"
|
||||
},
|
||||
"ns": {
|
||||
"label": "Suppression de bruit"
|
||||
},
|
||||
"stereo": {
|
||||
"label": "Stéréo"
|
||||
}
|
||||
},
|
||||
"audioOnlyOff": "Désactiver le mode bande passante faible",
|
||||
"audioOnlyOn": "Activer le mode bande passante faible",
|
||||
"audioRoute": "Sélectionner le dispositif audio",
|
||||
@@ -1277,6 +1406,7 @@
|
||||
"closeChat": "Fermer le clavardage",
|
||||
"closeParticipantsPane": "Fermer le panneau des participants",
|
||||
"closeReactionsMenu": "Fermer le menu réactions",
|
||||
"closedCaptions": "Sous-titres",
|
||||
"disableNoiseSuppression": "Arrêter la suppression du bruit",
|
||||
"disableReactionSounds": "Vous pouvez interdire les réactions sonores à cette réunion",
|
||||
"documentClose": "Fermer le document partagé",
|
||||
@@ -1294,6 +1424,7 @@
|
||||
"giphy": "Activer/désactiver le menu GIPHY",
|
||||
"hangup": "Quitter",
|
||||
"help": "Aide",
|
||||
"hideWhiteboard": "Masquer le tableau blanc",
|
||||
"invite": "Inviter des personnes",
|
||||
"joinBreakoutRoom": "Rejoindre salle annexe",
|
||||
"laugh": "Rire",
|
||||
@@ -1305,6 +1436,7 @@
|
||||
"lobbyButtonEnable": "Activer le mode salle d'attente / contrôle des participant(e)s",
|
||||
"login": "Connexion",
|
||||
"logout": "Déconnexion",
|
||||
"love": "Cœur",
|
||||
"lowerYourHand": "Abaisser votre main",
|
||||
"moreActions": "Plus d'actions",
|
||||
"moreOptions": "Plus d'options",
|
||||
@@ -1330,14 +1462,17 @@
|
||||
"raiseYourHand": "Lever votre main",
|
||||
"reactionBoo": "Envoyer réaction huer",
|
||||
"reactionClap": "Envoyer réaction applaudir",
|
||||
"reactionHeart": "Envoyer une réaction en forme de cœur",
|
||||
"reactionLaugh": "Envoyer réaction rire",
|
||||
"reactionLike": "Envoyer réaction approuver",
|
||||
"reactionLove": "Envoyer une réaction d'amour",
|
||||
"reactionSilence": "Envoyer réaction silence",
|
||||
"reactionSurprised": "Envoyer réaction surprise",
|
||||
"reactions": "Reactions",
|
||||
"security": "Options de sécurité",
|
||||
"selectBackground": "Sélectionner un arrière-plan",
|
||||
"shareRoom": "Inviter quelqu'un",
|
||||
"shareaudio": "Partager l'audio",
|
||||
"sharedvideo": "Partager une vidéo",
|
||||
"shortcuts": "Voir les raccourcis",
|
||||
"showWhiteboard": "Afficher le tableau blanc",
|
||||
@@ -1345,12 +1480,10 @@
|
||||
"speakerStats": "Statistiques d'intervenant",
|
||||
"startScreenSharing": "Démarrer le partage d'écran",
|
||||
"startSubtitles": "Activer les sous-titres",
|
||||
"startvideoblur": "Brouiller mon arrière plan",
|
||||
"stopAudioSharing": "Arrêter le partage son",
|
||||
"stopScreenSharing": "Arrêter le partage d'écran",
|
||||
"stopSharedVideo": "Arrêter la vidéo",
|
||||
"stopSubtitles": "Désactiver les sous-titres",
|
||||
"stopvideoblur": "Désactiver le brouillage d'arrière-plan",
|
||||
"surprised": "Surpris",
|
||||
"talkWhileMutedPopup": "Vous essayez de parler? Vous êtes en sourdine.",
|
||||
"tileViewToggle": "Basculement de l'affichage mosaïque",
|
||||
@@ -1363,20 +1496,20 @@
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Activer / Désactiver les sous-titres",
|
||||
"error": "Échec de la transcription. Veuillez réessayer.",
|
||||
"expandedLabel": "La transcription est actuellement activée",
|
||||
"failedToStart": "Échec du démarrage de la transcription",
|
||||
"labelToolTip": "La réunion est transcrite",
|
||||
"off": "La transcription est arrêtée",
|
||||
"on": "La transcription est activée",
|
||||
"pending": "Préparation de la transcription de la réunion en cours…",
|
||||
"failed": "La transcription a échoué",
|
||||
"labelTooltip": "La transcription de la réunion est en cours",
|
||||
"labelTooltipExtra": "De plus, une transcription sera disponible plus tard.",
|
||||
"openClosedCaptions": "Ouvrir les sous-titres",
|
||||
"original": "Original",
|
||||
"sourceLanguageDesc": "Actuellement, la langue de la réunion est sélectionnée à <b>{{sourceLanguage}}</b>. <br/> Vous pouvez la changer à partir de ",
|
||||
"sourceLanguageHere": "ici",
|
||||
"start": "Activer l'affichage des sous-titres",
|
||||
"stop": "Désactiver l'affichage des sous-titres",
|
||||
"subtitles": "sous-titres",
|
||||
"subtitlesOff": "off",
|
||||
"tr": "PI"
|
||||
"tr": "PI",
|
||||
"translateTo": "Traduire vers"
|
||||
},
|
||||
"unpinParticipant": "Désépingler - {{participantName}}",
|
||||
"userMedia": {
|
||||
@@ -1386,7 +1519,7 @@
|
||||
"busy": "Libération des ressources en cours. Veuillez réessayer dans quelques minutes.",
|
||||
"busyTitle": "Le service de Salle est actuellement occupé.",
|
||||
"errorAlreadyInvited": "{{displayName}} a déjà été invité",
|
||||
"errorInvite": "La conférence n'est pas encore configurée. Veuillez réessayer plus tard.",
|
||||
"errorInvite": "La réunion n'est pas encore configurée. Veuillez réessayer plus tard.",
|
||||
"errorInviteFailed": "Nous nous efforçons de régler ce problème. Veuillez réessayer plus tard.",
|
||||
"errorInviteFailedTitle": "L'invitation de {{displayName}} a échoué",
|
||||
"errorInviteTitle": "Erreur lors de l'invitation de la salle",
|
||||
@@ -1407,8 +1540,6 @@
|
||||
"ld": "LD",
|
||||
"ldTooltip": "Visionnement de vidéo en basse définition",
|
||||
"lowDefinition": "Basse définition",
|
||||
"onlyAudioAvailable": "Seulement l'audio est disponible",
|
||||
"onlyAudioSupported": "Ce navigateur prend seulement l'audio en charge.",
|
||||
"performanceSettings": "Paramètres de performance",
|
||||
"recording": "Enregistrement en cours",
|
||||
"sd": "SD",
|
||||
@@ -1418,7 +1549,10 @@
|
||||
},
|
||||
"videothumbnail": {
|
||||
"connectionInfo": "Informations de la connexion",
|
||||
"demote": "Déplacer en visiteur",
|
||||
"domute": "Discrétion",
|
||||
"domuteDesktop": "Arrêter le partage d'écran",
|
||||
"domuteDesktopOfOthers": "Arrêter le partage d'écran de tous les autres",
|
||||
"domuteOthers": "Couper le micro de tous les autres",
|
||||
"domuteVideo": "Couper la caméra",
|
||||
"domuteVideoOfOthers": "Couper la caméra des autres",
|
||||
@@ -1470,11 +1604,24 @@
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(visiteur)",
|
||||
"joinMeeting": {
|
||||
"description": "Vous êtes actuellement un observateur dans cette réunion.",
|
||||
"raiseHand": "Levez la main",
|
||||
"title": "Rejoindre la réunion",
|
||||
"wishToSpeak": "Si vous souhaitez prendre la parole, veuillez lever la main ci-dessous et attendre l'approbation du modérateur."
|
||||
},
|
||||
"labelTooltip": "Nombre de Visiteurs",
|
||||
"notification": {
|
||||
"description": "Pour participer lever la main.",
|
||||
"demoteDescription": "Envoyé ici par {{actor}}, levez la main pour participer",
|
||||
"noMainParticipantsDescription": "Un participant doit démarrer la réunion. Veuillez réessayer dans un moment.",
|
||||
"noMainParticipantsTitle": "Cette réunion n'a pas encore commencé.",
|
||||
"noVisitorLobby": "Vous ne pouvez pas rejoindre tant qu'une salle d'attente est activée pour la réunion.",
|
||||
"notAllowedPromotion": "Un participant doit d'abord autoriser votre demande.",
|
||||
"requestToJoin": "Main levée",
|
||||
"requestToJoinDescription": "Votre demande a été envoyée aux modérateurs. Patientez !",
|
||||
"title": "Vous êtes visiteur dans cette réunion"
|
||||
}
|
||||
},
|
||||
"waitingMessage": "Vous rejoindrez la réunion dès qu'elle sera en direct !"
|
||||
},
|
||||
"volumeSlider": "Curseur de volume",
|
||||
"welcomepage": {
|
||||
@@ -1483,7 +1630,7 @@
|
||||
"roomname": "Entrer le nom de la salle"
|
||||
},
|
||||
"addMeetingName": "Ajouter un nom de réunion",
|
||||
"appDescription": "Profitez de la conversation vidéo avec toute votre équipe. Allez-y, invitez tous ceux que vous connaissez. {{app}} est une solution 100 % libre de conférence vidéo entièrement chiffrée que vous pouvez utiliser en tout temps et gratuitement, sans avoir besoin de compte.",
|
||||
"appDescription": "Profitez de la conversation vidéo avec toute votre équipe. Allez-y, invitez tous ceux que vous connaissez. {{app}} est une solution 100 % libre de réunion vidéo entièrement chiffrée que vous pouvez utiliser en tout temps et gratuitement, sans avoir besoin de compte.",
|
||||
"audioVideoSwitch": {
|
||||
"audio": "Voix",
|
||||
"video": "Vidéo"
|
||||
@@ -1492,12 +1639,13 @@
|
||||
"connectCalendarButton": "Connecter votre agenda",
|
||||
"connectCalendarText": "Connectez-vous à votre calendrier pour afficher toutes les réunions {{app}}. Ajoutez également les réunions de {{provider}} à votre calendrier et démarrez-les d'un simple clic.",
|
||||
"enterRoomTitle": "Démarrer une nouvelle réunion",
|
||||
"getHelp": "Obtenir de l'aide",
|
||||
"go": "Aller",
|
||||
"goSmall": "Aller",
|
||||
"headerSubtitle": "Conférences sécurisées et de haute qualité",
|
||||
"headerSubtitle": "Réunions sécurisées et de haute qualité",
|
||||
"headerTitle": "Jitsi Meet",
|
||||
"info": "Ret. arr.",
|
||||
"jitsiOnMobile": "Jitsi sur mobile – télécharger notre application et démarrez des conférences de n'import où",
|
||||
"jitsiOnMobile": "Jitsi sur mobile – télécharger notre application et démarrez des réunions de n'import où",
|
||||
"join": "CRÉER / REJOINDRE",
|
||||
"logo": {
|
||||
"calendar": "Logo Calendar",
|
||||
@@ -1523,14 +1671,15 @@
|
||||
"roomnameHint": "Entrez le nom ou l'URL de la salle que vous voulez rejoindre. Vous pouvez inventer un nom, mais assurez-vous de le partager avec les participants de la réunion pour qu'ils utilisent le même nom.",
|
||||
"sendFeedback": "Envoyer un commentaire",
|
||||
"settings": "Paramètres",
|
||||
"startMeeting": "Démarrer la conférence",
|
||||
"startMeeting": "Démarrer la réunion",
|
||||
"terms": "Termes",
|
||||
"title": "Conférence vidéo sécurisée, riche en fonctionnalités et entièrement gratuite",
|
||||
"title": "Réunion vidéo sécurisée, riche en fonctionnalités et entièrement gratuite",
|
||||
"upcomingMeetings": "Vos réunions à venir"
|
||||
},
|
||||
"whiteboard": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Tableau blanc"
|
||||
}
|
||||
},
|
||||
"screenTitle": "Tableau blanc"
|
||||
}
|
||||
}
|
||||
@@ -109,9 +109,12 @@
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"disabled": "L'envoi de messages de chat est désactivé.",
|
||||
"enter": "Entrez dans le salon",
|
||||
"error": "Erreur : votre message n'a pas été envoyé. Raison : {{error}}",
|
||||
"everyone": "Tout le monde",
|
||||
"fieldPlaceHolder": "Tapez votre message ici",
|
||||
"guestsChatIndicator": "(invité)",
|
||||
"lobbyChatMessageTo": "Message de salle d'attente à {{recipient}}",
|
||||
"message": "Message",
|
||||
"messageAccessibleTitle": "{{user}} dit: ",
|
||||
@@ -122,7 +125,10 @@
|
||||
"nickname": {
|
||||
"popover": "Choisissez un pseudonyme",
|
||||
"title": "Entrez un pseudonyme pour utiliser le chat",
|
||||
"titleWithPolls": "Entrez un pseudonyme pour utiliser le chat et les sondages"
|
||||
"titleWithCC": "Entrez un pseudonyme pour utiliser le chat et les sous-titres",
|
||||
"titleWithPolls": "Entrez un pseudonyme pour utiliser le chat et les sondages",
|
||||
"titleWithPollsAndCC": "Entrez un pseudonyme pour utiliser le chat, les sondages et les sous-titres",
|
||||
"titleWithPollsAndCCAndFileSharing": "Entrez un pseudonyme pour utiliser le chat, les sondages, les sous-titres et les fichiers"
|
||||
},
|
||||
"noMessagesMessage": "Il n'y a pas encore de messages dans cette réunion. Démarrez une conversation ici !",
|
||||
"privateNotice": "Message privé à {{recipient}}",
|
||||
@@ -131,9 +137,14 @@
|
||||
"systemDisplayName": "Système",
|
||||
"tabs": {
|
||||
"chat": "Chat",
|
||||
"closedCaptions": "ST",
|
||||
"fileSharing": "Fichiers",
|
||||
"polls": "Sondages"
|
||||
},
|
||||
"title": "Chat",
|
||||
"titleWithCC": "ST",
|
||||
"titleWithFeatures": "Chat et",
|
||||
"titleWithFileSharing": "Fichiers",
|
||||
"titleWithPolls": "Chat et Sondages",
|
||||
"you": "vous"
|
||||
},
|
||||
@@ -144,6 +155,10 @@
|
||||
"dontShowAgain": "Ne plus m'afficher ceci",
|
||||
"installExtensionText": "Installer l'extension pour l'intégration de Google Calendar et Office 365"
|
||||
},
|
||||
"closedCaptionsTab": {
|
||||
"emptyState": "Le contenu des sous-titres sera disponible une fois qu'un modérateur l'aura démarré",
|
||||
"startClosedCaptionsButton": "Démarrer les sous-titres"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": "Connexion à la réunion…"
|
||||
},
|
||||
@@ -263,7 +278,8 @@
|
||||
"Remove": "Supprimer",
|
||||
"Share": "Partager",
|
||||
"Submit": "Soumettre",
|
||||
"WaitForHostMsg": "La conférence n'a pas encore commencé. Si vous en êtes l'hôte, veuillez vous authentifier. Sinon, veuillez attendre son arrivée.",
|
||||
"Understand": "Je comprends, gardez-moi en sourdine pour l'instant",
|
||||
"UnderstandAndUnmute": "Je comprends, veuillez me réactiver s'il vous plaît",
|
||||
"WaitForHostNoAuthMsg": "La conférence n'a pas encore commencé car aucun modérateur n'est encore arrivé. Veuillez patienter.",
|
||||
"WaitingForHostButton": "Attendre l'hôte",
|
||||
"WaitingForHostTitle": "En attente de l'hôte…",
|
||||
@@ -285,6 +301,12 @@
|
||||
"alreadySharedVideoTitle": "Une seule vidéo partagée est autorisée à la fois",
|
||||
"applicationWindow": "Fenêtre d'application",
|
||||
"authenticationRequired": "Authentification requise",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Prendre et envoyer une photo en utilisant votre caméra mobile",
|
||||
"ok": "Ouvrir la caméra",
|
||||
"reject": "Pas maintenant",
|
||||
"title": "Prendre une photo"
|
||||
},
|
||||
"cameraConstraintFailedError": "Votre caméra ne satisfait pas certaines des contraintes nécessaires.",
|
||||
"cameraNotFoundError": "La caméra n'a pas été trouvée.",
|
||||
"cameraNotSendingData": "Impossible d'accéder à votre caméra. Veuillez sélectionner un autre périphérique dans les paramètres ou rafraîchir la page.",
|
||||
@@ -299,6 +321,7 @@
|
||||
"conferenceReloadMsg": "On essaie d'arranger ça. Reconnexion dans {{seconds}} secondes…",
|
||||
"conferenceReloadTitle": "Malheureusement, un problème est survenu",
|
||||
"confirm": "Confirmer",
|
||||
"confirmBack": "Retour",
|
||||
"confirmNo": "Non",
|
||||
"confirmYes": "Oui",
|
||||
"connectError": "Oups ! Un problème est survenu et la connexion à la conférence est impossible.",
|
||||
@@ -336,6 +359,7 @@
|
||||
"kickParticipantTitle": "Expulser ce participant ?",
|
||||
"kickSystemTitle": "Oups ! Vous avez été expulsé de la réunion",
|
||||
"kickTitle": "Oups ! vous avez été expulsé(e) par {{participantDisplayName}}",
|
||||
"learnMore": "en savoir plus",
|
||||
"linkMeeting": "Relier la conférence",
|
||||
"linkMeetingTitle": "Relier la conférence à Salesforce",
|
||||
"liveStreaming": "Direct",
|
||||
@@ -358,22 +382,34 @@
|
||||
"micTimeoutError": "Impossible de démarrer la source audio. Délai dépassé!",
|
||||
"micUnknownError": "Vous ne pouvez pas utiliser le microphone pour une raison inconnue.",
|
||||
"moderationAudioLabel": "Autoriser les participants à réactiver leur micro",
|
||||
"moderationDesktopLabel": "Autoriser les non-modérateurs à partager leur écran",
|
||||
"moderationVideoLabel": "Autoriser les participants à démarrer leur vidéo",
|
||||
"muteEveryoneDialog": "Êtes-vous sûr de vouloir couper les micros de tout le monde ? Vous ne pourrez plus réactiver leur micro, mais ils pourront l'activer par eux-mêmes à tout moment.",
|
||||
"muteEveryoneDialogModerationOn": "Les participants peuvent demander à parler n'importe quand",
|
||||
"muteEveryoneElseDialog": "Une fois leur micro coupé, vous ne pourrez plus le réactiver, mais ils pourront l'activer par eux-mêmes à tout moment.",
|
||||
"muteEveryoneElseTitle": "Couper le micro de tout le monde sauf de {{whom}} ?",
|
||||
"muteEveryoneElsesDesktopDialog": "Une fois le partage arrêté, vous ne pourrez pas le redémarrer, mais ils peuvent le faire à tout moment.",
|
||||
"muteEveryoneElsesDesktopTitle": "Arrêter le partage d'écran de tout le monde sauf {{whom}} ?",
|
||||
"muteEveryoneElsesVideoDialog": "Une fois la caméra coupée, vous ne pourrez plus la rallumer, mais ils peuvent la rallumer à tout moment.",
|
||||
"muteEveryoneElsesVideoTitle": "Couper la vidéo de tout le monde sauf {{whom}}?",
|
||||
"muteEveryoneSelf": "vous",
|
||||
"muteEveryoneStartMuted": "Tout le monde démarre avec le micro coupé",
|
||||
"muteEveryoneTitle": "Couper le micro de tout le monde ?",
|
||||
"muteEveryonesDesktopDialog": "Les participants peuvent partager leur écran à tout moment.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "Les participants peuvent envoyer une demande pour partager leur écran à tout moment.",
|
||||
"muteEveryonesDesktopTitle": "Arrêter le partage d'écran de tout le monde ?",
|
||||
"muteEveryonesVideoDialog": "Êtes-vous sûr de vouloir couper la caméra de tout le monde? Vous ne pourrez pas la réactiver, mais ils peuvent la remettre à tout moment.",
|
||||
"muteEveryonesVideoDialogModerationOn": "Les participants peuvent demander à activer leur caméra n'importe quand.",
|
||||
"muteEveryonesVideoDialogOk": "Désactiver",
|
||||
"muteEveryonesVideoTitle": "Couper la caméra de tout le monde?",
|
||||
"muteParticipantBody": "Vous ne pourrez plus réactiver son micro, mais il pourra l'activer par lui-même à tout moment.",
|
||||
"muteParticipantButton": "Couper le micro",
|
||||
"muteParticipantsDesktopBody": "Vous ne pourrez pas démarrer leur partage d'écran, mais ils peuvent le faire à tout moment.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "Vous ne pourrez pas démarrer leur partage d'écran et eux non plus.",
|
||||
"muteParticipantsDesktopButton": "Arrêter le partage d'écran",
|
||||
"muteParticipantsDesktopDialog": "Êtes-vous sûr de vouloir désactiver le partage d'écran de ce participant ? Vous ne pourrez pas le redémarrer, mais ils peuvent le faire à tout moment.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Êtes-vous sûr de vouloir désactiver le partage d'écran de ce participant ? Vous ne pourrez pas réactiver l'écran et eux non plus.",
|
||||
"muteParticipantsDesktopTitle": "Désactiver le partage d'écran de ce participant ?",
|
||||
"muteParticipantsVideoBody": "Vous ne pourrez pas rallumer la caméra, mais ils peuvent la rallumer à tout moment.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Ni vous ni le participant ne pourront rallumer la caméra.",
|
||||
"muteParticipantsVideoButton": "Couper la caméra",
|
||||
@@ -393,6 +429,10 @@
|
||||
"recentlyUsedObjects": "Vos objets récemment utilisés",
|
||||
"recording": "Enregistrement",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossible durant le direct",
|
||||
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA{{learnMore}}. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
|
||||
"recordingInProgressDescriptionFirstHalf": "Cette réunion est en cours d'enregistrement et d'analyse par IA",
|
||||
"recordingInProgressDescriptionSecondHalf": ". Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
|
||||
"recordingInProgressTitle": "Enregistrement en cours",
|
||||
"rejoinNow": "Rejoindre maintenant",
|
||||
"remoteControlAllowedMessage": "{{user}} a accepté votre demande de prise en main à distance !",
|
||||
"remoteControlDeniedMessage": "{{user}} a refusé votre demande de prise en main à distance !",
|
||||
@@ -522,6 +562,23 @@
|
||||
"veryBad": "Très mauvais",
|
||||
"veryGood": "Très bon"
|
||||
},
|
||||
"fileSharing": {
|
||||
"downloadFailedDescription": "Veuillez réessayer.",
|
||||
"downloadFailedTitle": "Échec du téléchargement",
|
||||
"downloadFile": "Télécharger",
|
||||
"downloadStarted": "Téléchargement de fichier démarré",
|
||||
"dragAndDrop": "Glissez et déposez des fichiers ici ou n'importe où sur l'écran",
|
||||
"fileAlreadyUploaded": "Le fichier a déjà été téléchargé vers cette réunion.",
|
||||
"fileTooLargeDescription": "Veuillez vous assurer que le fichier ne dépasse pas {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "Le fichier sélectionné est trop volumineux",
|
||||
"fileUploadProgress": "Progression du téléchargement de fichier",
|
||||
"fileUploadedSuccessfully": "Fichier téléchargé avec succès",
|
||||
"removeFile": "Supprimer",
|
||||
"removeFileSuccess": "Fichier supprimé avec succès",
|
||||
"uploadFailedDescription": "Veuillez réessayer.",
|
||||
"uploadFailedTitle": "Échec du téléchargement",
|
||||
"uploadFile": "Partager un fichier"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Vignettes vidéos"
|
||||
@@ -690,7 +747,8 @@
|
||||
"notificationTitle": "Salle d'attente",
|
||||
"passwordJoinButton": "Rejoindre",
|
||||
"title": "Salle d'attente",
|
||||
"toggleLabel": "Activer la salle d'attente"
|
||||
"toggleLabel": "Activer la salle d'attente",
|
||||
"waitForModerator": "La conférence n'a pas encore commencé car aucun modérateur n'est encore arrivé. Si vous souhaitez devenir modérateur, veuillez vous connecter. Sinon, veuillez attendre."
|
||||
},
|
||||
"localRecording": {
|
||||
"clientState": {
|
||||
@@ -733,7 +791,10 @@
|
||||
"me": "moi",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Faille de sécurité !",
|
||||
"allowAction": "Permettre",
|
||||
"allowAll": "Tout autoriser",
|
||||
"allowAudio": "Autoriser l'audio",
|
||||
"allowDesktop": "Autoriser le partage d'écran",
|
||||
"allowVideo": "Autoriser la vidéo",
|
||||
"allowedUnmute": "Vous pouvez réactiver votre écran, votre caméra ou partager votre écran.",
|
||||
"audioUnmuteBlockedDescription": "Le rétablissement du son a été bloqué temporairement en raison de limites système.",
|
||||
"audioUnmuteBlockedTitle": "Rétablissement du son bloqué !",
|
||||
@@ -746,8 +807,10 @@
|
||||
"dataChannelClosedDescription": "Le canal de communication avec le Bridge a été interrompu, la qualité vidéo se trouve limitée à sa valeur la plus faible.",
|
||||
"dataChannelClosedDescriptionWithAudio": "Le canal de pont est fermé, ce qui peut entraîner des perturbations de l'audio et de la vidéo.",
|
||||
"dataChannelClosedWithAudio": "La qualité de l'audio et de la vidéo peut être altérée",
|
||||
"desktopMutedRemotelyTitle": "Votre partage d'écran a été arrêté par {{participantDisplayName}}",
|
||||
"disabledIframe": "L'intégration Iframe est uniquement destinée à des démos, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondary": "L'intégration Iframe de {{domaine}} est uniquement destinée à des démos, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryNative": "L'intégration de {{domain}} est uniquement destinée aux fins de démonstration, cet appel se terminera dans {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryWeb": "L'intégration de {{domain}} est uniquement destinée aux fins de démonstration, cet appel se terminera dans {{timeout}} minutes. Veuillez utiliser <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> pour l'intégration en production !",
|
||||
"disconnected": "déconnecté",
|
||||
"displayNotifications": "Afficher les notifications pour",
|
||||
"dontRemindMe": "Ne pas me le rappeler",
|
||||
@@ -802,6 +865,7 @@
|
||||
"oldElectronClientDescription1": "Vous semblez utiliser une ancienne version du client Jitsi Meet qui présente des failles de sécurité connues. Veuillez vous assurer de mettre à jour vers notre ",
|
||||
"oldElectronClientDescription2": "dernière build",
|
||||
"oldElectronClientDescription3": " rapidement !",
|
||||
"openChat": "Ouvrir le chat",
|
||||
"participantWantsToJoin": "souhaite rejoindre la réunion",
|
||||
"participantsWantToJoin": "souhaitent rejoindre la réunion",
|
||||
"passwordRemovedRemotely": "Le $t(lockRoomPassword) a été supprimé par un autre participant",
|
||||
@@ -825,6 +889,8 @@
|
||||
"suggestRecordingDescription": "Souhaitez-vous démarrer un enregistrement ?",
|
||||
"suggestRecordingTitle": "Enregistrer cette réunion",
|
||||
"unmute": "Rétablir le son",
|
||||
"unmuteScreen": "Démarrer le partage d'écran",
|
||||
"unmuteVideo": "Réactiver la vidéo",
|
||||
"videoMutedRemotelyDescription": "Vous pouvez toujours la réactiver.",
|
||||
"videoMutedRemotelyTitle": "Votre caméra a été coupée par {{participantDisplayName}}!",
|
||||
"videoUnmuteBlockedDescription": "Le rétablissement de la vidéo a été bloqué temporairement en raison de limites système.",
|
||||
@@ -843,11 +909,14 @@
|
||||
"admit": "Accepter",
|
||||
"admitAll": "Tout accepter",
|
||||
"allow": "Autoriser les participants à:",
|
||||
"allowDesktop": "Autoriser le partage d'écran",
|
||||
"allowVideo": "permettre la vidéo",
|
||||
"askDesktop": "Demander de partager l'écran",
|
||||
"askUnmute": "Demander de réactiver le micro",
|
||||
"audioModeration": "Rouvrir leur micro",
|
||||
"blockEveryoneMicCamera": "Bloquer tous les micros et caméras",
|
||||
"breakoutRooms": "Salles annexes",
|
||||
"desktopModeration": "Démarrer le partage d'écran",
|
||||
"goLive": "Passer en direct",
|
||||
"invite": "Inviter quelqu'un",
|
||||
"lowerAllHands": "Abaisser toutes les mains",
|
||||
@@ -859,6 +928,8 @@
|
||||
"muteAll": "Couper le micro de tout le monde",
|
||||
"muteEveryoneElse": "Couper le micro de tous les autres",
|
||||
"reject": "Refuser",
|
||||
"stopDesktop": "Arrêter le partage d'écran",
|
||||
"stopEveryonesDesktop": "Arrêter le partage d'écran de tout le monde",
|
||||
"stopEveryonesVideo": "Couper toutes les caméras",
|
||||
"stopVideo": "Couper la vidéo",
|
||||
"unblockEveryoneMicCamera": "Débloquer tous les micros et caméras",
|
||||
@@ -868,12 +939,15 @@
|
||||
"headings": {
|
||||
"lobby": "Salle d'attente ({{count}})",
|
||||
"participantsList": "Participants de la réunion ({{count}})",
|
||||
"viewerRequests": "Demandes des spectateurs {{count}}",
|
||||
"visitorInQueue": " (en attente {{count}})",
|
||||
"visitorRequests": "(Demande {{count}} )",
|
||||
"visitors": "Visiteurs {{count}}",
|
||||
"visitorsList": "Spectateurs ({{count}})",
|
||||
"waitingLobby": "Dans la salle d'attente ({{count}})"
|
||||
},
|
||||
"search": "Rechercher des participants",
|
||||
"searchDescription": "Commencez à taper pour filtrer les participants",
|
||||
"title": "Participants"
|
||||
},
|
||||
"passwordDigitsOnly": "Jusqu'à {{number}} chiffres",
|
||||
@@ -1100,6 +1174,7 @@
|
||||
"signedIn": "Accès aux événements du calendrier {{email}}. Cliquez sur le bouton se déconnecter ci-dessous pour arrêter l'accès aux événements du calendrier.",
|
||||
"title": "Calendrier"
|
||||
},
|
||||
"chatWithPermissions": "Le chat nécessite une autorisation",
|
||||
"desktopShareFramerate": "Images par seconde pour le Partage d'écran",
|
||||
"desktopShareHighFpsWarning": "Augmenter le nombre d'images par seconde pour le partage d'écran peut impacter votre bande passante. Vous devez repartager l'écran pour que ces paramètres soient utilisés.",
|
||||
"desktopShareWarning": "Vous devez repartager l'écran pour que ces paramètres soient utilisés.",
|
||||
@@ -1129,6 +1204,7 @@
|
||||
"selectMic": "Microphone",
|
||||
"selfView": "Affichage de votre propre vidéo",
|
||||
"shortcuts": "Raccourcis",
|
||||
"showSubtitlesOnStage": "Afficher les sous-titres sur l'écran",
|
||||
"speakers": "Haut-parleurs",
|
||||
"startAudioMuted": "Tout le monde commence en muet",
|
||||
"startReactionsMuted": "Tout le monde commence avec les réactions sonores bloquées",
|
||||
@@ -1182,11 +1258,13 @@
|
||||
"fearful": "Effrayé",
|
||||
"happy": "Content",
|
||||
"hours": "{{count}}h",
|
||||
"labelTooltip": "Nombre de participants : {{count}}",
|
||||
"minutes": "{{count}}m",
|
||||
"name": "Nom",
|
||||
"neutral": "Indifférent",
|
||||
"sad": "Triste",
|
||||
"search": "Recherche",
|
||||
"searchDescription": "Commencez à taper pour filtrer les participants",
|
||||
"searchHint": "Recherche des participants",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerStats": "Statistiques de l'interlocuteur",
|
||||
@@ -1223,6 +1301,7 @@
|
||||
"closeChat": "Fermer la discussion instantanée",
|
||||
"closeMoreActions": "Fermer le menu plus d'actions",
|
||||
"closeParticipantsPane": "Fermer le panneau des participants",
|
||||
"closedCaptions": "Sous-titres",
|
||||
"collapse": "Plier",
|
||||
"document": "Activer / Désactiver le document partagé",
|
||||
"documentClose": "Fermer le document partagé",
|
||||
@@ -1301,6 +1380,20 @@
|
||||
"videounmute": "Activer votre vidéo"
|
||||
},
|
||||
"addPeople": "Ajouter des personnes à votre appel",
|
||||
"advancedAudioSettings": {
|
||||
"aec": {
|
||||
"label": "Suppression d'écho acoustique"
|
||||
},
|
||||
"agc": {
|
||||
"label": "Contrôle automatique du gain"
|
||||
},
|
||||
"ns": {
|
||||
"label": "Suppression de bruit"
|
||||
},
|
||||
"stereo": {
|
||||
"label": "Stéréo"
|
||||
}
|
||||
},
|
||||
"audioOnlyOff": "Désactiver le mode bande passante réduite",
|
||||
"audioOnlyOn": "Activer le mode bande passante réduite",
|
||||
"audioRoute": "Sélectionner la source audio",
|
||||
@@ -1313,6 +1406,7 @@
|
||||
"closeChat": "Fermer le chat",
|
||||
"closeParticipantsPane": "Fermer le panneau des participants",
|
||||
"closeReactionsMenu": "Fermer le menu réactions",
|
||||
"closedCaptions": "Sous-titres",
|
||||
"disableNoiseSuppression": "Arrêter la suppression du bruit",
|
||||
"disableReactionSounds": "Vous pouvez interdire les réactions sonores à cette réunion",
|
||||
"documentClose": "Fermer le document partagé",
|
||||
@@ -1371,6 +1465,7 @@
|
||||
"reactionHeart": "Envoyer une réaction en forme de cœur",
|
||||
"reactionLaugh": "Envoyer réaction rire",
|
||||
"reactionLike": "Envoyer réaction approuver",
|
||||
"reactionLove": "Envoyer une réaction d'amour",
|
||||
"reactionSilence": "Envoyer réaction silence",
|
||||
"reactionSurprised": "Envoyer réaction surprise",
|
||||
"reactions": "Reactions",
|
||||
@@ -1403,14 +1498,18 @@
|
||||
"ccButtonTooltip": "Activer / Désactiver les sous-titres",
|
||||
"expandedLabel": "La transcription est actuellement activée",
|
||||
"failed": "La transcription a échoué",
|
||||
"labelToolTip": "La transcription de la réunion est en cours",
|
||||
"labelTooltip": "La transcription de la réunion est en cours",
|
||||
"labelTooltipExtra": "Une transcription sera disponible plus tard.",
|
||||
"openClosedCaptions": "Ouvrir les sous-titres",
|
||||
"original": "Original",
|
||||
"sourceLanguageDesc": "Actuellement, la langue de la réunion est sélectionnée à <b>{{sourceLanguage}}</b>. <br/> Vous pouvez la changer à partir de ",
|
||||
"sourceLanguageHere": "ici",
|
||||
"start": "Activer les sous-titres",
|
||||
"stop": "Désactiver les sous-titres",
|
||||
"subtitles": "sous-titres",
|
||||
"subtitlesOff": "off",
|
||||
"tr": "TR"
|
||||
"tr": "TR",
|
||||
"translateTo": "Traduire vers"
|
||||
},
|
||||
"unpinParticipant": "Désépingler - {{participantName}}",
|
||||
"userMedia": {
|
||||
@@ -1452,6 +1551,8 @@
|
||||
"connectionInfo": "Informations de la connexion",
|
||||
"demote": "Déplacer en visiteur",
|
||||
"domute": "Couper le micro",
|
||||
"domuteDesktop": "Arrêter le partage d'écran",
|
||||
"domuteDesktopOfOthers": "Arrêter le partage d'écran de tous les autres",
|
||||
"domuteOthers": "Couper le micro de tous les autres",
|
||||
"domuteVideo": "Couper la caméra",
|
||||
"domuteVideoOfOthers": "Couper la caméra des autres",
|
||||
@@ -1516,6 +1617,8 @@
|
||||
"noMainParticipantsTitle": "Cette réunion n'a pas encore commencé.",
|
||||
"noVisitorLobby": "Vous ne pouvez pas rejoindre tant qu'une salle d'attente est activée pour la réunion.",
|
||||
"notAllowedPromotion": "Un participant doit d'abord autoriser votre demande.",
|
||||
"requestToJoin": "Main levée",
|
||||
"requestToJoinDescription": "Votre demande a été envoyée aux modérateurs.",
|
||||
"title": "Vous êtes visiteur dans cette réunion"
|
||||
},
|
||||
"waitingMessage": "Vous rejoindrez la réunion dès qu'elle sera en direct !"
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
"disabled": "L'invio di messaggi in chat è disabilitato.",
|
||||
"enter": "Entra nella conversazione",
|
||||
"error": "Errore: il tuo messaggio non è stato inviato. Motivo: {{error}}",
|
||||
"everyone": "Tutti",
|
||||
"fieldPlaceHolder": "Scrivi qui il tuo messaggio",
|
||||
"guestsChatIndicator": "(ospite)",
|
||||
"lobbyChatMessageTo": "Messaggio a {{recipient}} in sala d'attesa",
|
||||
"message": "Messaggio",
|
||||
"messageAccessibleTitle": "{{user}} dice:",
|
||||
@@ -154,7 +156,7 @@
|
||||
"installExtensionText": "Installa un'estensione per integrare Google Calendar e Office 365"
|
||||
},
|
||||
"closedCaptionsTab": {
|
||||
"emptyState": "Il contenuto dei sottotitoli sarà disponibile una volta che l'organizzatore lo attiva",
|
||||
"emptyState": "Il contenuto dei sottotitoli sarà disponibile una volta che l'organizzatore lo attiverà",
|
||||
"startClosedCaptionsButton": "Attiva sottotitoli"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
@@ -300,6 +302,12 @@
|
||||
"alreadySharedVideoTitle": "È permessa una sola condivisione video alla volta",
|
||||
"applicationWindow": "Finestra dell'applicazione",
|
||||
"authenticationRequired": "Richiesta autenticazione",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Scatta ed invia una foto usando la fotocamera del telefono",
|
||||
"ok": "Apri la fotocamera",
|
||||
"reject": "Non adesso",
|
||||
"title": "Scatta una foto"
|
||||
},
|
||||
"cameraConstraintFailedError": "La tua videocamera non soddisfa alcuni dei requisiti.",
|
||||
"cameraNotFoundError": "Videocamera non trovata.",
|
||||
"cameraNotSendingData": "Impossibile accedere alla videocamera. Controlla che non sia in uso in un'altra applicazione, seleziona un altro dispositivo dalle impostazioni o prova a ricaricare l'applicazione.",
|
||||
@@ -323,7 +331,7 @@
|
||||
"contactSupport": "Contatta il supporto",
|
||||
"copied": "Copiato",
|
||||
"copy": "Copia",
|
||||
"demoteParticipantDialog": "Sei sicuro di voler far diventare questo partecipante uno spettatore?",
|
||||
"demoteParticipantDialog": "Vuoi far diventare questo partecipante uno spettatore?",
|
||||
"demoteParticipantTitle": "Fai diventare spettatore",
|
||||
"dismiss": "Scarta",
|
||||
"displayNameRequired": "Ciao, qual è il tuo nome?",
|
||||
@@ -338,8 +346,8 @@
|
||||
"error": "Errore",
|
||||
"errorRoomCreationRestriction": "Hai provato ad accedere alla riunione troppo presto, torna tra un po'.",
|
||||
"gracefulShutdown": "Il nostro servizio è al momento inattivo per manutenzione. Si prega di riprovare più tardi.",
|
||||
"grantModeratorDialog": "Sei sicuro di voler rendere organizzatore questo partecipante?",
|
||||
"grantModeratorTitle": "Fai diventare organizzatore",
|
||||
"grantModeratorDialog": "Vuoi rendere relatore questo partecipante?",
|
||||
"grantModeratorTitle": "Fai diventare relatore",
|
||||
"hide": "Nascondi",
|
||||
"hideShareAudioHelper": "Non mostrare più questa finestra",
|
||||
"incorrectPassword": "Nome utente o password errati",
|
||||
@@ -348,7 +356,7 @@
|
||||
"internalErrorTitle": "Errore interno",
|
||||
"kickMessage": "Puoi contattare {{participantDisplayName}} per maggiori dettagli.",
|
||||
"kickParticipantButton": "Espelli",
|
||||
"kickParticipantDialog": "Sei sicuro di voler espellere questo partecipante?",
|
||||
"kickParticipantDialog": "Vuoi espellere questo partecipante?",
|
||||
"kickParticipantTitle": "Espellere questo partecipante?",
|
||||
"kickSystemTitle": "Oh! Sei stato espulso dalla riunione",
|
||||
"kickTitle": "Oh! {{participantDisplayName}} ti ha espulso dalla riunione.",
|
||||
@@ -362,8 +370,8 @@
|
||||
"lockRoom": "Aggiungi una $t(lockRoomPassword) alla riunione",
|
||||
"lockTitle": "Blocco fallito",
|
||||
"login": "Accesso",
|
||||
"loginQuestion": "Sei sicuro di voler fare l'accesso e abbandonare la riunione?",
|
||||
"logoutQuestion": "Sei sicuro di volerti disconnettere e abbandonare la riunione?",
|
||||
"loginQuestion": "Vuoi fare l'accesso e abbandonare la riunione?",
|
||||
"logoutQuestion": "Vuoi disconnetterti e abbandonare la riunione?",
|
||||
"logoutTitle": "Disconnessione",
|
||||
"maxUsersLimitReached": "È stato raggiunto il numero massimo di partecipanti. La riunione è al completo. Contatta l'organizzatore o riprova più tardi!",
|
||||
"maxUsersLimitReachedTitle": "Raggiunto limite massimo partecipanti",
|
||||
@@ -375,27 +383,39 @@
|
||||
"micTimeoutError": "Impossibile avviare la sorgente audio. Tempo di attesa scaduto.",
|
||||
"micUnknownError": "Impossibile usare il microfono per un motivo sconosciuto.",
|
||||
"moderationAudioLabel": "Consenti ai partecipanti di attivare il microfono",
|
||||
"moderationDesktopLabel": "Consenti ai partecipanti di condividere lo schermo",
|
||||
"moderationVideoLabel": "Consenti ai partecipanti di attivare la videocamera",
|
||||
"muteEveryoneDialog": "I partecipanti possono attivare il microfono in qualsiasi momento.",
|
||||
"muteEveryoneDialogModerationOn": "I partecipanti possono chiedere di parlare in qualsiasi momento.",
|
||||
"muteEveryoneElseDialog": "Una volta spenti i microfoni non potrai riattivarli, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
|
||||
"muteEveryoneElseTitle": "Spegnere il microfono a tutti, tranne che a {{whom}}?",
|
||||
"muteEveryoneElsesDesktopDialog": "Una volta interrotta la condivisione dello schermo non potrai riattivarla, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
|
||||
"muteEveryoneElsesDesktopTitle": "Interrompere la condivisione dello schermo a tutti, tranne che a {{whom}}?",
|
||||
"muteEveryoneElsesVideoDialog": "Una volta spente le videocamere non potrai riaccenderle, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
|
||||
"muteEveryoneElsesVideoTitle": "Spegnere la videocamera a tutti, tranne che a {{whom}}?",
|
||||
"muteEveryoneSelf": "tu",
|
||||
"muteEveryoneStartMuted": "Tutti iniziano a microfono spento da adesso in avanti",
|
||||
"muteEveryoneTitle": "Spegnere il microfono a tutti?",
|
||||
"muteEveryonesDesktopDialog": "I partecipanti potranno condividere lo schermo in qualsiasi momento.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "I partecipanti possono inviare una richiesta per condividere lo schermo in ogni momento.",
|
||||
"muteEveryonesDesktopTitle": "Interrompere la condivisione dello schermo a tutti?",
|
||||
"muteEveryonesVideoDialog": "Ogni partecipante potrà riavviare il video da sé in qualsiasi momento.",
|
||||
"muteEveryonesVideoDialogModerationOn": "I partecipanti possono chiedere di attivare il video in qualsiasi momento.",
|
||||
"muteEveryonesVideoDialogOk": "Spegni",
|
||||
"muteEveryonesVideoTitle": "Spegnere la videocamera a tutti?",
|
||||
"muteParticipantBody": "Non potrai riattivare il loro microfono, ma loro potranno farlo in qualsiasi momento.",
|
||||
"muteParticipantButton": "Silenzia",
|
||||
"muteParticipantsDesktopBody": "Non potrai riavviare la loro condivisione dello schermo, ma loro potranno farlo in qualsiasi momento.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "Non potrai riavviare la loro condivisione dello schermo e nemmeno loro potranno.",
|
||||
"muteParticipantsDesktopButton": "Interrompi la condivisione dello schermo",
|
||||
"muteParticipantsDesktopDialog": "Vuoi interrompere la condivisione dello schermo di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Vuoi interrompere la condivisione dello schermo di questo partecipante? Non potrai riattivarla e nemmeno loro potranno.",
|
||||
"muteParticipantsDesktopTitle": "Disattivare la condivisione dello schermo di questo partecipante?",
|
||||
"muteParticipantsVideoBody": "Non potrai riattivare le videocamere, ma loro potranno farlo in qualsiasi momento.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Non potrai riattivare le videocamere e nemmeno loro potranno.",
|
||||
"muteParticipantsVideoButton": "Spegni videocamere",
|
||||
"muteParticipantsVideoDialog": "Sei sicuro di voler spegnere la videocamera di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
|
||||
"muteParticipantsVideoDialogModerationOn": "Sei sicuro di voler spegnere la videocamera di questo partecipante? Non potrai riattivarla e nemmeno lui potrà farlo.",
|
||||
"muteParticipantsVideoDialog": "Vuoi spegnere la videocamera di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
|
||||
"muteParticipantsVideoDialogModerationOn": "Vuoi spegnere la videocamera di questo partecipante? Non potrai riattivarla e nemmeno lui potrà farlo.",
|
||||
"muteParticipantsVideoTitle": "Spegnere la videocamera di questo partecipante?",
|
||||
"noDropboxToken": "Token Dropbox non valido",
|
||||
"password": "Password",
|
||||
@@ -424,7 +444,7 @@
|
||||
"remoteControlTitle": "Connessione desktop remoto",
|
||||
"remoteUserControls": "Controlli dell'utente remoto {{username}}",
|
||||
"removePassword": "Rimuovi la $t(lockRoomPassword)",
|
||||
"removeSharedVideoMsg": "Sei sicuro di voler rimuovere il tuo video condiviso?",
|
||||
"removeSharedVideoMsg": "Vuoi rimuovere il tuo video condiviso?",
|
||||
"removeSharedVideoTitle": "Rimuovi video condiviso",
|
||||
"renameBreakoutRoomLabel": "Nome della stanza",
|
||||
"renameBreakoutRoomTitle": "Rinomina stanza",
|
||||
@@ -477,8 +497,8 @@
|
||||
"startRemoteControlErrorMessage": "Si è verificato un errore nel tentativo di avviare la sessione di controllo remoto!",
|
||||
"stopLiveStreaming": "Ferma la diretta",
|
||||
"stopRecording": "Ferma registrazione",
|
||||
"stopRecordingWarning": "Sei sicuro di voler interrompere la registrazione?",
|
||||
"stopStreamingWarning": "Sei sicuro di voler interrompere la diretta?",
|
||||
"stopRecordingWarning": "Vuoi interrompere la registrazione?",
|
||||
"stopStreamingWarning": "Vuoi interrompere la diretta?",
|
||||
"streamKey": "Chiave della diretta",
|
||||
"thankYou": "Grazie per aver usato {{appName}}!",
|
||||
"token": "token",
|
||||
@@ -547,11 +567,15 @@
|
||||
"downloadFailedDescription": "Si prega di riprovare.",
|
||||
"downloadFailedTitle": "Download non riuscito",
|
||||
"downloadFile": "Download",
|
||||
"downloadStarted": "Download del file iniziato",
|
||||
"dragAndDrop": "Trascina e rilascia i file qui o da qualsiasi altra parte nella schermata",
|
||||
"fileAlreadyUploaded": "Questo file è già stato caricato nella riunione.",
|
||||
"fileTooLargeDescription": "Assicurati che il file non superi {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "Il file selezionato è troppo grande",
|
||||
"fileUploadProgress": "Caricamento del file in corso",
|
||||
"fileUploadedSuccessfully": "Il file è stato caricato con successo",
|
||||
"removeFile": "Rimuovi",
|
||||
"removeFileSuccess": "File rimosso con successo",
|
||||
"uploadFailedDescription": "Si prega di riprovare.",
|
||||
"uploadFailedTitle": "Caricamento non riuscito",
|
||||
"uploadFile": "Condividi file"
|
||||
@@ -683,7 +707,7 @@
|
||||
"signInCTA": "Accedi o inserisci la tua chiave della diretta su YouTube.",
|
||||
"signOut": "Disconnetti",
|
||||
"signedInAs": "Hai effettuato l'accesso come:",
|
||||
"start": "Inizia una diretta",
|
||||
"start": "Avvia una diretta",
|
||||
"streamIdHelp": "Cos'è questo?",
|
||||
"title": "Diretta",
|
||||
"unavailableTitle": "La diretta non è disponibile",
|
||||
@@ -744,9 +768,9 @@
|
||||
"engaged": "Registrazione avviata.",
|
||||
"finished": "La registrazione della sessione {{token}} è terminata. Invia il file della registrazione all'organizzatore.",
|
||||
"finishedModerator": "La registrazione della sessione {{token}} è terminata. La registrazione della traccia è stata salvata. Chiedi ai partecipanti di inviare le loro registrazioni.",
|
||||
"notModerator": "Non sei un organizzatore. Non puoi avviare o interrompere la registrazione."
|
||||
"notModerator": "Non sei un relatore. Non puoi avviare o interrompere la registrazione."
|
||||
},
|
||||
"moderator": "Organizzatore",
|
||||
"moderator": "Relatore",
|
||||
"no": "No",
|
||||
"participant": "Partecipante",
|
||||
"participantStats": "Statistiche partecipante",
|
||||
@@ -767,8 +791,9 @@
|
||||
"me": "io",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Falla di sicurezza!",
|
||||
"allowAll": "Consenti tutto",
|
||||
"allowAudio": "Consenti l'audio",
|
||||
"allowBoth": "Entrambi",
|
||||
"allowDesktop": "Consenti la condivisione dello schermo",
|
||||
"allowVideo": "Consenti il video",
|
||||
"allowedUnmute": "Puoi accendere il microfono, avviare la videocamera o condividere il tuo schermo.",
|
||||
"audioUnmuteBlockedDescription": "L'accensione dei microfoni è stata temporaneamente bloccata per i limiti del sistema.",
|
||||
@@ -782,6 +807,7 @@
|
||||
"dataChannelClosedDescription": "Il canale bridge è inattivo, quindi la qualità video potrebbe essere limitata all'impostazione più bassa.",
|
||||
"dataChannelClosedDescriptionWithAudio": "Il canale bridge è inattivo, quindi potrebbero esserci interruzioni di audio e video",
|
||||
"dataChannelClosedWithAudio": "La qualità audio e video potrebbe essere scarsa",
|
||||
"desktopMutedRemotelyTitle": "La tua condivisione dello schermo è stata interrotta da {{participantDisplayName}}",
|
||||
"disabledIframe": "L'incorporamento serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti.",
|
||||
"disabledIframeSecondaryNative": "L'incorporamento {{domain}} serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti.",
|
||||
"disabledIframeSecondaryWeb": "L'incorporamento {{domain}} serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti. Si prega di usare <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> per la produzione di riunioni incorporate!",
|
||||
@@ -792,7 +818,7 @@
|
||||
"focusFail": "{{component}} non disponibile - nuovo tentativo tra {{ms}} sec",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notifiche",
|
||||
"hostAskedUnmute": "L'organizzatore ti chiede di intervenire.",
|
||||
"hostAskedUnmute": "Il relatore ti chiede di intervenire.",
|
||||
"invalidTenant": "Nome non valido",
|
||||
"invalidTenantHyphenDescription": "Il nome che hai scelto non è valido (inizia o finisce con '-').",
|
||||
"invalidTenantLengthDescription": "Il nome che hai scelto è troppo lungo.",
|
||||
@@ -814,17 +840,17 @@
|
||||
"localRecordingStopped": "{{name}} ha smesso di registrare.",
|
||||
"me": "Io",
|
||||
"moderationInEffectCSDescription": "Alza la mano, se vuoi condividere lo schermo.",
|
||||
"moderationInEffectCSTitle": "La condivisione schermo è stata bloccata dall'organizzatore",
|
||||
"moderationInEffectCSTitle": "La condivisione schermo è stata bloccata dal relatore",
|
||||
"moderationInEffectDescription": "Alza la mano, se vuoi prendere la parola.",
|
||||
"moderationInEffectTitle": "Il tuo microfono è stato spento dall'organizzatore",
|
||||
"moderationInEffectTitle": "Il tuo microfono è stato spento dal relatore",
|
||||
"moderationInEffectVideoDescription": "Alza la mano, se vuoi avviare la tua videocamera.",
|
||||
"moderationInEffectVideoTitle": "La tua videocamera è stata spenta dall'organizzatore",
|
||||
"moderationRequestFromModerator": "L'organizzatore vorrebbe che tu accendessi il microfono",
|
||||
"moderationInEffectVideoTitle": "La tua videocamera è stata spenta dal relatore",
|
||||
"moderationRequestFromModerator": "Il relatore vorrebbe che tu accendessi il microfono",
|
||||
"moderationRequestFromParticipant": "Vuole parlare",
|
||||
"moderationStartedTitle": "Moderazione in corso",
|
||||
"moderationStoppedTitle": "Moderazione interrotta",
|
||||
"moderationToggleDescription": "da {{participantDisplayName}}",
|
||||
"moderator": "Ora sei un organizzatore!",
|
||||
"moderator": "Ora sei un relatore!",
|
||||
"muted": "Hai iniziato la conversazione con il microfono disattivato.",
|
||||
"mutedRemotelyDescription": "Puoi sempre attivare il microfono quando vuoi parlare. Spegni il microfono quando hai finito, per evitare rumori di fondo nella riunione.",
|
||||
"mutedRemotelyTitle": "{{participantDisplayName}} ti ha spento il microfono",
|
||||
@@ -839,6 +865,7 @@
|
||||
"oldElectronClientDescription1": "Sembra che tu stia usando una versione obsoleta del client Jitsi Meet, che ha vulnerabilità note. Assicurati di aggiornarlo alla nostra ",
|
||||
"oldElectronClientDescription2": "ultima versione",
|
||||
"oldElectronClientDescription3": " ora!",
|
||||
"openChat": "Apri chat",
|
||||
"participantWantsToJoin": "Vuole unirsi alla riunione",
|
||||
"participantsWantToJoin": "Vogliono unirsi alla riunione",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) è stata rimossa da un altro partecipante",
|
||||
@@ -862,6 +889,7 @@
|
||||
"suggestRecordingDescription": "Vuoi avviare la registrazione?",
|
||||
"suggestRecordingTitle": "Registra questa riunione",
|
||||
"unmute": "Accendi il microfono",
|
||||
"unmuteScreen": "Iniziata la condivisione dello schermo",
|
||||
"unmuteVideo": "Accendi la videocamera",
|
||||
"videoMutedRemotelyDescription": "Puoi riaccenderla in qualsiasi momento.",
|
||||
"videoMutedRemotelyTitle": "{{participantDisplayName}} ti ha spento la videocamera",
|
||||
@@ -881,11 +909,14 @@
|
||||
"admit": "Ammetti",
|
||||
"admitAll": "Ammetti tutti",
|
||||
"allow": "Permetti ai partecipanti di:",
|
||||
"allowDesktop": "Consenti la condivisione dello schermo",
|
||||
"allowVideo": "Permetti videocamere",
|
||||
"askDesktop": "Chiedi di condividere lo schermo",
|
||||
"askUnmute": "Chiedi di accendere il microfono",
|
||||
"audioModeration": "Riattivare il microfono",
|
||||
"blockEveryoneMicCamera": "Blocca microfono e videocamera a tutti",
|
||||
"breakoutRooms": "Stanze",
|
||||
"desktopModeration": "Avvia la condivisione dello schermo",
|
||||
"goLive": "Vai alla diretta",
|
||||
"invite": "Invita partecipanti",
|
||||
"lowerAllHands": "Abbassa tutte le mani",
|
||||
@@ -897,6 +928,8 @@
|
||||
"muteAll": "Silenzia tutti",
|
||||
"muteEveryoneElse": "Silenzia tutti gli altri",
|
||||
"reject": "Respingi",
|
||||
"stopDesktop": "Interrompi la condivisione dello schermo",
|
||||
"stopEveryonesDesktop": "Interrompi la condivisione dello schermo agli altri",
|
||||
"stopEveryonesVideo": "Ferma il video di tutti",
|
||||
"stopVideo": "Ferma il video",
|
||||
"unblockEveryoneMicCamera": "Sblocca microfono e videocamera a tutti",
|
||||
@@ -906,6 +939,7 @@
|
||||
"headings": {
|
||||
"lobby": "Sala d'attesa ({{count}})",
|
||||
"participantsList": "Partecipanti alla riunione ({{count}})",
|
||||
"viewerRequests": "Richieste spettatori ({{count}})",
|
||||
"visitorInQueue": " ({{count}} in attesa)",
|
||||
"visitorRequests": " ({{count}} richiesta/e)",
|
||||
"visitors": "Spettatori {{count}}",
|
||||
@@ -1073,7 +1107,7 @@
|
||||
"fileSharingdescription": "Condividi la registrazione con i partecipanti alla riunione",
|
||||
"highlight": "Evidenzia",
|
||||
"highlightMoment": "Evidenzia momento",
|
||||
"highlightMomentDisabled": "Puoi evidenziare dei momenti quando inizia la registrazione",
|
||||
"highlightMomentDisabled": "Puoi evidenziare i momenti in cui inizia la registrazione",
|
||||
"highlightMomentSuccess": "Momento evidenziato",
|
||||
"highlightMomentSucessDescription": "Il tuo momento evidenziato sarà aggiunto al riepilogo della riunione.",
|
||||
"inProgress": "Registrazione o diretta in corso",
|
||||
@@ -1084,7 +1118,7 @@
|
||||
"localRecordingNoVideo": "Il video non sta venendo registrato",
|
||||
"localRecordingStartWarning": "Assicurati di interrompere la registrazione prima di uscire dalla riunione, altrimenti la registrazione non verrà salvata.",
|
||||
"localRecordingStartWarningTitle": "Interrompi la registrazione per salvarla",
|
||||
"localRecordingVideoStop": "Interrompere il video fermerà anche la registrazione. Sei sicuro di voler continuare?",
|
||||
"localRecordingVideoStop": "Interrompere il video fermerà anche la registrazione. Vuoi continuare?",
|
||||
"localRecordingVideoWarning": "Per registrare il video, deve essere già avviato prima dell'inizio della registrazione",
|
||||
"localRecordingWarning": "Assicurati di aver selezionato la scheda corrente, per registrare gli audio e video corretti.",
|
||||
"loggedIn": "Accesso effettuato come {{userName}}",
|
||||
@@ -1153,8 +1187,8 @@
|
||||
"loggedIn": "Connesso come {{name}}",
|
||||
"maxStageParticipants": "Numero massimo di partecipanti che possono essere messi in evidenza nella schermata principale",
|
||||
"microphones": "Microfoni",
|
||||
"moderator": "Organizzatore",
|
||||
"moderatorOptions": "Opzioni organizzatore",
|
||||
"moderator": "Relatore",
|
||||
"moderatorOptions": "Opzioni relatore",
|
||||
"more": "Generali",
|
||||
"name": "Nome",
|
||||
"noDevice": "Nessuno",
|
||||
@@ -1190,7 +1224,7 @@
|
||||
"conferenceSection": "Riunione",
|
||||
"disableCallIntegration": "Disattiva l'integrazione nativa delle chiamate",
|
||||
"disableCrashReporting": "Disattiva la diagnostica dei crash",
|
||||
"disableCrashReportingWarning": "Sei sicuro di voler disattivare la diagnostica dei crash? Quest'impostazione verrà applicata al prossimo avvio dell'app.",
|
||||
"disableCrashReportingWarning": "Vuoi disattivare la diagnostica dei crash? Quest'impostazione verrà applicata al prossimo avvio dell'app.",
|
||||
"disableP2P": "Disattiva la modalità Peer-to-Peer",
|
||||
"displayName": "Nome visualizzato",
|
||||
"displayNamePlaceholderText": "Es: Mario Rossi",
|
||||
@@ -1207,8 +1241,8 @@
|
||||
"serverURL": "URL del server",
|
||||
"showAdvanced": "Mostra impostazioni avanzate",
|
||||
"startCarModeInLowBandwidthMode": "Avvia modalità auto in modalità larghezza di banda limitata",
|
||||
"startWithAudioMuted": "Inizia con audio disattivato",
|
||||
"startWithVideoMuted": "Inizia con video disattivato",
|
||||
"startWithAudioMuted": "Avvia con audio disattivato",
|
||||
"startWithVideoMuted": "Avvia con video disattivato",
|
||||
"terms": "Termini",
|
||||
"version": "Versione"
|
||||
},
|
||||
@@ -1283,7 +1317,7 @@
|
||||
"feedback": "Lascia un feedback",
|
||||
"fullScreen": "Attiva modalità a schermo intero",
|
||||
"giphy": "Mostra menu GIPHY",
|
||||
"grantModerator": "Concedi permessi di organizzatore",
|
||||
"grantModerator": "Concedi permessi da relatore",
|
||||
"hangup": "Lascia la riunione",
|
||||
"heading": "Barra degli strumenti",
|
||||
"help": "Aiuto",
|
||||
@@ -1346,6 +1380,20 @@
|
||||
"videounmute": "Accendi videocamera"
|
||||
},
|
||||
"addPeople": "Aggiungi partecipanti alla chiamata",
|
||||
"advancedAudioSettings": {
|
||||
"aec": {
|
||||
"label": "Cancellazione dell'eco"
|
||||
},
|
||||
"agc": {
|
||||
"label": "Controllo del guadagno automatico"
|
||||
},
|
||||
"ns": {
|
||||
"label": "Cancellazione del rumore"
|
||||
},
|
||||
"stereo": {
|
||||
"label": "Stereo"
|
||||
}
|
||||
},
|
||||
"audioOnlyOff": "Disabilita modalità larghezza di banda limitata",
|
||||
"audioOnlyOn": "Abilita modalità larghezza di banda limitata",
|
||||
"audioRoute": "Scegli il dispositivo audio",
|
||||
@@ -1412,11 +1460,12 @@
|
||||
"profile": "Modifica profilo",
|
||||
"raiseHand": "Alza la mano",
|
||||
"raiseYourHand": "Alza la mano",
|
||||
"reactionBoo": "Invia buu",
|
||||
"reactionClap": "Invia applauso",
|
||||
"reactionHeart": "Invia cuore",
|
||||
"reactionLaugh": "Invia risata",
|
||||
"reactionLike": "Invia mi piace",
|
||||
"reactionBoo": "Invia Buu",
|
||||
"reactionClap": "Invia Applauso",
|
||||
"reactionHeart": "Invia Cuore",
|
||||
"reactionLaugh": "Invia Risata",
|
||||
"reactionLike": "Invia Mi piace",
|
||||
"reactionLove": "Invia Love",
|
||||
"reactionSilence": "Invia senza parole",
|
||||
"reactionSurprised": "Invia a bocca aperta",
|
||||
"reactions": "Reazioni",
|
||||
@@ -1502,15 +1551,17 @@
|
||||
"connectionInfo": "Informazioni connessione",
|
||||
"demote": "Fai diventare spettatore",
|
||||
"domute": "Disattiva microfono",
|
||||
"domuteDesktop": "Interrompi la condivisione dello schermo",
|
||||
"domuteDesktopOfOthers": "Interrompi la condivisione dello schermo agli altri",
|
||||
"domuteOthers": "Disattiva microfono a tutti gli altri",
|
||||
"domuteVideo": "Disattiva videocamera",
|
||||
"domuteVideoOfOthers": "Disattiva videocamera a tutti gli altri",
|
||||
"flip": "Specchia",
|
||||
"grantModerator": "Concedi permessi da organizzatore",
|
||||
"grantModerator": "Concedi permessi da relatore",
|
||||
"hideSelfView": "Nascondi la tua immagine",
|
||||
"kick": "Espelli",
|
||||
"mirrorVideo": "Specchia il tuo video",
|
||||
"moderator": "Organizzatore",
|
||||
"moderator": "Relatore",
|
||||
"mute": "Il partecipante ha il microfono spento",
|
||||
"muted": "Microfono spento",
|
||||
"pinToStage": "Metti in primo piano",
|
||||
@@ -1557,7 +1608,7 @@
|
||||
"description": "Adesso sei uno spettatore in questa riunione.",
|
||||
"raiseHand": "Alza la mano",
|
||||
"title": "Ingresso nella riunione in corso",
|
||||
"wishToSpeak": "Se vuoi parlare, si prega di alzare la mano sotto e aspettare l'autorizzazione dell'organizzatore."
|
||||
"wishToSpeak": "Se vuoi parlare, si prega di alzare la mano sotto e aspettare l'autorizzazione del relatore."
|
||||
},
|
||||
"labelTooltip": "Numero di spettatori: {{count}}",
|
||||
"notification": {
|
||||
@@ -1618,7 +1669,7 @@
|
||||
"roomnameHint": "Inserisci il nome o l'URL della riunione a cui vuoi accedere. Puoi anche inventarti un nome, assicurati solo che le persone con cui vuoi collegarti lo conoscano, così che possano inserire lo stesso nome.",
|
||||
"sendFeedback": "Invia feedback",
|
||||
"settings": "Impostazioni",
|
||||
"startMeeting": "Inizia riunione",
|
||||
"startMeeting": "Avvia riunione",
|
||||
"terms": "Termini di utilizzo",
|
||||
"title": "Il sistema di videoconferenza sicuro, funzionale e completamente gratuito.",
|
||||
"upcomingMeetings": "Prossime riunioni"
|
||||
|
||||
@@ -109,9 +109,12 @@
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"disabled": "Tērzēšanas ziņojumu sūtīšana ir atspējota.",
|
||||
"enter": "Ienākt istabā",
|
||||
"error": "Kļūda: Jūsu ziņa netika nosūtīta. Cēlonis: {{error}}",
|
||||
"everyone": "Visi",
|
||||
"fieldPlaceHolder": "Rakstiet ziņu šeit",
|
||||
"guestsChatIndicator": "(viesis)",
|
||||
"lobbyChatMessageTo": "Vestibila tērzēšanas ziņa adresātam {{recipient}}",
|
||||
"message": "Ziņa",
|
||||
"messageAccessibleTitle": "{{user}} saka:",
|
||||
@@ -124,7 +127,8 @@
|
||||
"title": "Ierakstiet vārdu, lai izmantotu tērzēšanā",
|
||||
"titleWithCC": "Ievadiet segvārdu, lai izmantotu tērzēšanā un slēptos subtitros",
|
||||
"titleWithPolls": "Ierakstiet segvārdu, lai izmantotu tērzēšanā un aptaujās",
|
||||
"titleWithPollsAndCC": "Ievadiet segvārdu, lai izmantotu tērzēšanā, aptaujās un slēptos subtitros"
|
||||
"titleWithPollsAndCC": "Ievadiet segvārdu, lai izmantotu tērzēšanā, aptaujās un slēptos subtitros",
|
||||
"titleWithPollsAndCCAndFileSharing": "Ievadiet segvārdu, lai izmantotu tērzēšanā, aptaujās, slēptos subtitros un failos"
|
||||
},
|
||||
"noMessagesMessage": "Sapulcē pagaidām nav nevienas ziņas. Uzsāciet saraksti!",
|
||||
"privateNotice": "Privāta ziņa adresātam {{recipient}}",
|
||||
@@ -134,12 +138,14 @@
|
||||
"tabs": {
|
||||
"chat": "Tērzēšana",
|
||||
"closedCaptions": "Slēptie subtitri",
|
||||
"fileSharing": "Faili",
|
||||
"polls": "Aptaujas"
|
||||
},
|
||||
"title": "Tērzēšana",
|
||||
"titleWithCC": "Tērzēšana un slēptie subtitri",
|
||||
"titleWithCC": "Tērzēšana un Slēptie subtitri",
|
||||
"titleWithFeatures": "Tērzēšana un",
|
||||
"titleWithFileSharing": "Faili",
|
||||
"titleWithPolls": "Tērzēšana un Aptaujas",
|
||||
"titleWithPollsAndCC": "Tērzēšana, Aptaujas un Slēptie subtitri",
|
||||
"you": "jūs"
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
@@ -296,6 +302,12 @@
|
||||
"alreadySharedVideoTitle": "Atļauts tikai viens kopīgots videoklips",
|
||||
"applicationWindow": "Lietotnes logs",
|
||||
"authenticationRequired": "Nepieciešama autentifikācija",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Uzņemt un nosūtīt attēlu, izmantojot mobilā tālruņa kameru",
|
||||
"ok": "Atvērt kameru",
|
||||
"reject": "Ne tagad",
|
||||
"title": "Uzņemt attēlu"
|
||||
},
|
||||
"cameraConstraintFailedError": "Kamera neatbilst noteiktajām prasībām.",
|
||||
"cameraNotFoundError": "Kamera nav atrasta.",
|
||||
"cameraNotSendingData": "Nevar piekļūt jūsu kamerai. Lūdzu, pārbaudiet, vai šo ierīci neizmanto cita programma, iestatījumu izvēlnē atlasiet citu ierīci vai mēģiniet atkārtoti ielādēt programmu.",
|
||||
@@ -371,22 +383,34 @@
|
||||
"micTimeoutError": "Nevarēja palaist audio avotu. Iestājās noildze!",
|
||||
"micUnknownError": "Nevar izmantot mikrofonu nezināma iemesla dēļ.",
|
||||
"moderationAudioLabel": "Atļaut dalībniekiem ieslēgt savu mikrofonu",
|
||||
"moderationDesktopLabel": "Atļaut lietotājiem, kas nav moderatori, kopīgot savu ekrānu",
|
||||
"moderationVideoLabel": "Atļaut dalībniekiem ieslēgt savu kameru",
|
||||
"muteEveryoneDialog": "Dalībnieki paši var ieslēgt savu mikrofonu.",
|
||||
"muteEveryoneDialogModerationOn": "Dalībnieki var nosūtīt pieprasījumu ieslēgt savu mikrofonu.",
|
||||
"muteEveryoneElseDialog": "Kad skaņa būs izslēgta, jūs nevarēsiet to ieslēgt atpakaļ, taču dalībnieki to varēs izdarīt paši.",
|
||||
"muteEveryoneElseTitle": "Vai izslēgt skaņu visiem, izņemot {{whom}}?",
|
||||
"muteEveryoneElsesDesktopDialog": "Kad kopīgošana būs apturēta, jūs vairs nevarēsiet to ieslēgt atpakaļ, bet viņi to varēs izdarīt jebkurā laikā.",
|
||||
"muteEveryoneElsesDesktopTitle": "Apturēt ekrāna kopīgošanu visiem, izņemot {{kam}}?",
|
||||
"muteEveryoneElsesVideoDialog": "Kad video būs izslēgts, jūs nevarēsiet to ieslēgt atpakaļ, taču dalībnieki to varēs izdarīt paši.",
|
||||
"muteEveryoneElsesVideoTitle": "Vai izslēgt video visiem, izņemot {{whom}}?",
|
||||
"muteEveryoneSelf": "jūs",
|
||||
"muteEveryoneStartMuted": "No šī brīža visi jauni dalībnieki pieslēdzas ar izslēgt skaņu",
|
||||
"muteEveryoneTitle": "Vai izslēgt skaņu visiem?",
|
||||
"muteEveryonesDesktopDialog": "Dalībnieki var kopīgot savu ekrānu jebkurā laikā.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "Dalībnieki jebkurā laikā var nosūtīt pieprasījumu kopīgot savu ekrānu.",
|
||||
"muteEveryonesDesktopTitle": "Vai pārtraukt ekrāna kopīgošanu visiem?",
|
||||
"muteEveryonesVideoDialog": "Dalībnieki var ieslēgt savu video.",
|
||||
"muteEveryonesVideoDialogModerationOn": "Dalībnieki var nosūtīt pieprasījumu ieslēgt viņu video.",
|
||||
"muteEveryonesVideoDialogOk": "Atspējot",
|
||||
"muteEveryonesVideoTitle": "Vai apturēt ikviena video?",
|
||||
"muteParticipantBody": "Jūs nevariet viņiem ieslēgt skaņu, bet viņi paši to var izdarīt jebkurā laikā.",
|
||||
"muteParticipantButton": "Izslēgt skaņu",
|
||||
"muteParticipantsDesktopBody": "Jūs nevarēsiet sākt viņu ekrāna kopīgošanu, bet viņi to varēs izdarīt jebkurā laikā.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "Jūs nevarēsiet sākt viņu ekrāna kopīgošanu, un arī viņi to nevarēs izdarīt.",
|
||||
"muteParticipantsDesktopButton": "Pārtraukt ekrāna kopīgošanu",
|
||||
"muteParticipantsDesktopDialog": "Vai tiešām vēlaties izslēgt šī dalībnieka ekrāna kopīgošanu? Jūs vairs nevarēsiet ieslēgt to atpakaļ, bet viņš to varēs izdarīt jebkurā laikā.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Vai tiešām vēlaties izslēgt šī dalībnieka ekrāna kopīgošanu? Jūs vairs nevarēsiet ieslēgt to atpakaļ, un arī viņš to nevarēs izdarīt.",
|
||||
"muteParticipantsDesktopTitle": "Atspējot ekrāna kopīgošanu šim dalībniekam?",
|
||||
"muteParticipantsVideoBody": "Jūs nevarēsiet kameru ieslēgt atpakaļ, taču viņi paši to varēs izdarīt jebkurā laikā.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Ne Jūs, ne dalībnieki nevarēsiet ieslēgt kameru atpakaļ.",
|
||||
"muteParticipantsVideoButton": "Pārtraukt video",
|
||||
@@ -539,6 +563,23 @@
|
||||
"veryBad": "Ļoti Slikta",
|
||||
"veryGood": "Ļoti Laba"
|
||||
},
|
||||
"fileSharing": {
|
||||
"downloadFailedDescription": "Lūdzu, mēģiniet vēlreiz.",
|
||||
"downloadFailedTitle": "Lejuplādes kļūda",
|
||||
"downloadFile": "Lejuplādēt",
|
||||
"downloadStarted": "Sākta faila lejuplāde",
|
||||
"dragAndDrop": "Velciet un palaidiet failus šeit, vai jebkurā ekrāna vietā",
|
||||
"fileAlreadyUploaded": "Fails jau ir augšuplādēts šajā sanāksmē.",
|
||||
"fileTooLargeDescription": "Lūdzu, pārliecinieties, vai faila lielums nepārsniedz {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "Izvēlētais fails ir pārāk liels",
|
||||
"fileUploadProgress": "Faila augšuplādes gaita",
|
||||
"fileUploadedSuccessfully": "Fails veiksmīgi augšuplādēts",
|
||||
"removeFile": "Noņemt",
|
||||
"removeFileSuccess": "Fails veiksmīgi noņemts",
|
||||
"uploadFailedDescription": "Lūdzu, mēģiniet vēlreiz.",
|
||||
"uploadFailedTitle": "Augšuplādes kļūda",
|
||||
"uploadFile": "Kopīgot failu"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Video sīktēli"
|
||||
@@ -750,8 +791,9 @@
|
||||
"me": "es",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Drošības ievainojamība!",
|
||||
"allowAll": "Atļaut visu",
|
||||
"allowAudio": "Atļaut audio",
|
||||
"allowBoth": "Abus",
|
||||
"allowDesktop": "Atļaut ekrāna kopīgošanu",
|
||||
"allowVideo": "Atļaut video",
|
||||
"allowedUnmute": "Varat ieslēgt mikrofona skaņu, ieslēgt kameru vai kopīgot ekrānu.",
|
||||
"audioUnmuteBlockedDescription": "Mikrofona ieslēgšanas darbība ir īslaicīgi bloķēta sistēmas ierobežojumu dēļ.",
|
||||
@@ -765,6 +807,7 @@
|
||||
"dataChannelClosedDescription": "Savienojuma kanāls nedarbojas, tāpēc video kvalitāte var būt ierobežota līdz zemākajam iestatījumam.",
|
||||
"dataChannelClosedDescriptionWithAudio": "Savienojuma kanāls nedarbojas, tāpēc var rasties audio un video traucējumi.",
|
||||
"dataChannelClosedWithAudio": "Audio un video kvalitāte var būt traucēta",
|
||||
"desktopMutedRemotelyTitle": "",
|
||||
"disabledIframe": "Iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks atvienots pēc {{timeout}} minūtēm.",
|
||||
"disabledIframeSecondaryNative": "Domēna {{domain}} iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks pārtraukts pēc {{timeout}} minūtēm.",
|
||||
"disabledIframeSecondaryWeb": "Domēna {{domain}} iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks pārtraukts pēc {{timeout}} minūtēm. Lūdzu, produkcijas videi izmantojiet <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a>!",
|
||||
@@ -845,6 +888,7 @@
|
||||
"suggestRecordingDescription": "Vai vēlaties sākt ierakstīšanu?",
|
||||
"suggestRecordingTitle": "Ierakstīt sanāksmi",
|
||||
"unmute": "Ieslēgt mikrofonu",
|
||||
"unmuteScreen": "",
|
||||
"unmuteVideo": "Ieslēgt video",
|
||||
"videoMutedRemotelyDescription": "Jūs vienmēr varat to atkal ieslēgt.",
|
||||
"videoMutedRemotelyTitle": "{{participantDisplayName}} izslēdza jūsu video",
|
||||
@@ -864,11 +908,14 @@
|
||||
"admit": "Apstiprināt",
|
||||
"admitAll": "Apstiprināt visus",
|
||||
"allow": "Atļaut dalībniekiem:",
|
||||
"allowDesktop": "Atļaut ekrāna kopīgošanu",
|
||||
"allowVideo": "Atļaut video",
|
||||
"askDesktop": "Lūgt kopīgot ekrānu",
|
||||
"askUnmute": "Lūgt ieslēgt skaņu",
|
||||
"audioModeration": "Ieslēgt savu skaņu",
|
||||
"blockEveryoneMicCamera": "Bloķēt visiem mikrofonu un kameru",
|
||||
"breakoutRooms": "Grupu istabas",
|
||||
"desktopModeration": "Sākt ekrāna kopīgošanu",
|
||||
"goLive": "Sākt",
|
||||
"invite": "Uzaicināt",
|
||||
"lowerAllHands": "Nolaist visas paceltās rokas",
|
||||
@@ -880,6 +927,8 @@
|
||||
"muteAll": "Apklusināt visus",
|
||||
"muteEveryoneElse": "Apklusināt pārējos",
|
||||
"reject": "Noraidīt",
|
||||
"stopDesktop": "Pārtraukt ekrāna kopīgošanu",
|
||||
"stopEveryonesDesktop": "Pārtraukt visiem ekrāna kopīgošanu",
|
||||
"stopEveryonesVideo": "Izslēgt visiem video",
|
||||
"stopVideo": "Izslēgt video",
|
||||
"unblockEveryoneMicCamera": "Atbloķēt visiem mikrofonu un kameru",
|
||||
@@ -889,9 +938,11 @@
|
||||
"headings": {
|
||||
"lobby": "Vestibils ({{count}})",
|
||||
"participantsList": "Sapulces dalībnieki ({{count}})",
|
||||
"viewerRequests": "Apmeklētāju pieprasījumi {{count}}",
|
||||
"visitorInQueue": " (gaida {{count}})",
|
||||
"visitorRequests": " (pieprasījumi {{count}})",
|
||||
"visitors": "Apmeklētāji ({{count}})",
|
||||
"visitors": "Apmeklētāji {{count}}",
|
||||
"visitorsList": "Apmeklētāji ({{count}})",
|
||||
"waitingLobby": "Gaida vestibilā ({{count}})"
|
||||
},
|
||||
"search": "Meklēt dalībniekus",
|
||||
@@ -1484,6 +1535,8 @@
|
||||
"connectionInfo": "Informācija par savienojumu",
|
||||
"demote": "Pārveidot par apmeklētāju",
|
||||
"domute": "Izlsēgt skaņu",
|
||||
"domuteDesktop": "Pārtraukt ekrāna kopīgošanu",
|
||||
"domuteDesktopOfOthers": "Pārtraukt ekrāna kopīgošanu visiem pārējiem",
|
||||
"domuteOthers": "Izslēgt skaņu visiem pārējiem",
|
||||
"domuteVideo": "Izslēgt kameru",
|
||||
"domuteVideoOfOthers": "Izslēgt video visiem pārējiem",
|
||||
|
||||
@@ -109,8 +109,10 @@
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"disabled": "O envio de mensagens de chat está desativado.",
|
||||
"enter": "Entrar na sala",
|
||||
"error": "Erro: a sua mensagem não foi enviada. Motivo: {{error}}",
|
||||
"everyone": "Todos",
|
||||
"fieldPlaceHolder": "Aa",
|
||||
"lobbyChatMessageTo": "Mensagem de chat na sala de espera para {{recipient}}",
|
||||
"message": "Mensagem",
|
||||
@@ -122,7 +124,10 @@
|
||||
"nickname": {
|
||||
"popover": "Escolha um apelido",
|
||||
"title": "Introduza um apelido para usar o chat",
|
||||
"titleWithPolls": "Introduza um apelido para usar o chat e as sondagens"
|
||||
"titleWithCC": "Insira um apelido para usar o chat e as legendas ocultas",
|
||||
"titleWithPolls": "Digite um apelido para usar o chat e as sondagens",
|
||||
"titleWithPollsAndCC": "Insira um apelido para utilizar o chat, as sondagens e as legendas ocultas",
|
||||
"titleWithPollsAndCCAndFileSharing": "Insira um apelido para utilizar o chat, as sondagens, as legendas e os ficheiros"
|
||||
},
|
||||
"noMessagesMessage": "Ainda não há mensagens na reunião. Comece aqui uma conversa!",
|
||||
"privateNotice": "Mensagem privada para {{recipient}}",
|
||||
@@ -131,10 +136,15 @@
|
||||
"systemDisplayName": "Sistema",
|
||||
"tabs": {
|
||||
"chat": "Chat",
|
||||
"closedCaptions": "LO",
|
||||
"fileSharing": "Ficheiros",
|
||||
"polls": "Sondagens"
|
||||
},
|
||||
"title": "Chat",
|
||||
"titleWithPolls": "Chat e Sondagens",
|
||||
"titleWithCC": "LO",
|
||||
"titleWithFeatures": "Chat e",
|
||||
"titleWithFileSharing": "Ficheiros",
|
||||
"titleWithPolls": "Sondagens",
|
||||
"you": "você"
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
@@ -144,6 +154,10 @@
|
||||
"dontShowAgain": "Não me mostre isto outra vez",
|
||||
"installExtensionText": "Instalar a extensão para a integração Google Calendar e Office 365"
|
||||
},
|
||||
"closedCaptionsTab": {
|
||||
"emptyState": "O conteúdo das legendas ocultas estará disponível assim que um moderador iniciar a sessão.",
|
||||
"startClosedCaptionsButton": "Iniciar legendas ocultas"
|
||||
},
|
||||
"connectingOverlay": {
|
||||
"joiningRoom": "A ligá-lo à reunião…"
|
||||
},
|
||||
@@ -263,6 +277,8 @@
|
||||
"Remove": "Remover",
|
||||
"Share": "Partilhar",
|
||||
"Submit": "Submeter",
|
||||
"Understand": "Entendo, mantenha-me em silêncio por enquanto.",
|
||||
"UnderstandAndUnmute": "Entendo, por favor, desative o silêncio.",
|
||||
"WaitForHostMsg": "A conferência ainda não começou porque ainda não chegaram moderadores. Se quiser ser um moderador, inicie a sessão. Caso contrário, aguarde.",
|
||||
"WaitForHostNoAuthMsg": "A conferência ainda não começou porque ainda não chegaram os moderadores. Por favor, aguarde.",
|
||||
"WaitingForHostButton": "Esperar pelo moderador",
|
||||
@@ -285,6 +301,12 @@
|
||||
"alreadySharedVideoTitle": "Só é permitido um vídeo partilhado de cada vez",
|
||||
"applicationWindow": "Janela de aplicação",
|
||||
"authenticationRequired": "Autenticação necessária",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Tire e envie uma foto usando a câmara do seu telemóvel",
|
||||
"ok": "Ligar a câmara",
|
||||
"reject": "Agora não",
|
||||
"title": "Tire uma foto"
|
||||
},
|
||||
"cameraConstraintFailedError": "A sua câmara não satisfaz algumas das restrições exigidas.",
|
||||
"cameraNotFoundError": "A câmara não foi encontrada.",
|
||||
"cameraNotSendingData": "Não podemos aceder à sua câmara. Verifique se outra aplicação está a utilizar este dispositivo, seleccione outro dispositivo do menu de definições ou tente recarregar a aplicação.",
|
||||
@@ -299,6 +321,7 @@
|
||||
"conferenceReloadMsg": "Estamos a tentar resolver isto. Reconexão em {{seconds}} seg…",
|
||||
"conferenceReloadTitle": "Infelizmente, algo correu mal.",
|
||||
"confirm": "Confirme",
|
||||
"confirmBack": "Voltar",
|
||||
"confirmNo": "Não",
|
||||
"confirmYes": "Sim",
|
||||
"connectError": "Oops! Algo correu mal e não conseguimos estabelecer uma ligação com a conferência.",
|
||||
@@ -307,8 +330,8 @@
|
||||
"contactSupport": "Contacte o suporte",
|
||||
"copied": "Copiado",
|
||||
"copy": "Cópia",
|
||||
"demoteParticipantDialog": "Tem a certeza de que pretende passar este participante para visitante?",
|
||||
"demoteParticipantTitle": "Passar a visitante",
|
||||
"demoteParticipantDialog": "Tem a certeza de que deseja mover este participante para espectador?",
|
||||
"demoteParticipantTitle": "Mover para espectador",
|
||||
"dismiss": "Dispensar",
|
||||
"displayNameRequired": "Olá! Qual é o seu nome?",
|
||||
"done": "Feito",
|
||||
@@ -334,7 +357,9 @@
|
||||
"kickParticipantButton": "Expulsar",
|
||||
"kickParticipantDialog": "Tem a certeza que quer expulsar este participante?",
|
||||
"kickParticipantTitle": "Expulsar este participante?",
|
||||
"kickSystemTitle": "Ai! Foste expulso da reunião.",
|
||||
"kickTitle": "Ai! {{participantDisplayName}} expulsou-o da reunião",
|
||||
"learnMore": "saiba mais",
|
||||
"linkMeeting": "Link da reunião",
|
||||
"linkMeetingTitle": "Link da reunião à Força de Vendas",
|
||||
"liveStreaming": "Transmissão em direto",
|
||||
@@ -356,23 +381,35 @@
|
||||
"micPermissionDeniedError": "Não concedeu autorização para utilizar o seu microfone. Ainda pode participar na conferência, mas outros não o ouvirão. Use o botão da câmara na barra de endereço para corrigir isto.",
|
||||
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite expirado!",
|
||||
"micUnknownError": "Não pode usar microfone por uma razão desconhecida.",
|
||||
"moderationAudioLabel": "Permitir aos participantes ligar o som",
|
||||
"moderationVideoLabel": "Permitir aos participantes ligar a câmara",
|
||||
"moderationAudioLabel": "Permitir aos não moderadores ligar o som",
|
||||
"moderationDesktopLabel": "Permitir que não moderadores partilhem o seu ecrã",
|
||||
"moderationVideoLabel": "Permitir que não moderadores iniciem os seus vídeos",
|
||||
"muteEveryoneDialog": "Os participantes podem ligar o som a qualquer momento.",
|
||||
"muteEveryoneDialogModerationOn": "Os participantes podem enviar um pedido para falar a qualquer momento.",
|
||||
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem ligar o microfone a qualquer momento.",
|
||||
"muteEveryoneElseTitle": "Silenciar todos excepto {{whom}}?",
|
||||
"muteEveryoneElsesDesktopDialog": "Depois que o compartilhamento for interrompido, não será possível reiniciá-lo, mas eles poderão fazê-lo a qualquer momento.",
|
||||
"muteEveryoneElsesDesktopTitle": "SInterromper a partilha de ecrã de todos, exceto {{whom}}?",
|
||||
"muteEveryoneElsesVideoDialog": "Quando a câmara for desligada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
|
||||
"muteEveryoneElsesVideoTitle": "Parar o vídeo de todos excepto {{whom}}?",
|
||||
"muteEveryoneSelf": "você mesmo",
|
||||
"muteEveryoneStartMuted": "A partir de agora, toda a gente começa a ficar calada",
|
||||
"muteEveryoneTitle": "Silenciar toda a gente?",
|
||||
"muteEveryonesDesktopDialog": "Os participantes podem partilhar o seu ecrã a qualquer momento.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "Os participantes podem enviar um pedido para partilhar o seu ecrã a qualquer momento.",
|
||||
"muteEveryonesDesktopTitle": "Interromper a partilha de ecrã de todos?",
|
||||
"muteEveryonesVideoDialog": "Os participantes podem ligar a sua câmara a qualquer momento.",
|
||||
"muteEveryonesVideoDialogModerationOn": "Os participantes podem enviar um pedido para ligar a sua câmara a qualquer momento.",
|
||||
"muteEveryonesVideoDialogOk": "Desativar",
|
||||
"muteEveryonesVideoTitle": "Desligar a câmara de todos?",
|
||||
"muteParticipantBody": "Não poderá reativá-los, mas eles podem reativar-se a qualquer momento.",
|
||||
"muteParticipantButton": "Silenciar",
|
||||
"muteParticipantsDesktopBody": "Não poderá iniciar a partilha de ecrã deles, mas eles podem fazê-lo a qualquer momento.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "Não será possível iniciar a partilha de ecrã nem para si nem para eles.",
|
||||
"muteParticipantsDesktopButton": "Parar a partilha de ecrã",
|
||||
"muteParticipantsDesktopDialog": "Tem a certeza de que deseja desativar a partilha de ecrã deste participante? Não será possível reiniciá-la, mas ele poderá fazê-lo a qualquer momento.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Tem a certeza de que deseja desativar a partilha de ecrã deste participante? Não será possível reativar o ecrã, nem para si nem para ele.",
|
||||
"muteParticipantsDesktopTitle": "Desativar a partilha de ecrã deste participante?",
|
||||
"muteParticipantsVideoBody": "Não poderá voltar a ligar a câmara, mas eles podem voltar a ligá-la a qualquer momento.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Não será capaz de voltar a ligar a câmara e eles também não.",
|
||||
"muteParticipantsVideoButton": "Parar vídeo",
|
||||
@@ -392,6 +429,10 @@
|
||||
"recentlyUsedObjects": "Os seus objetos recentemente utilizados",
|
||||
"recording": "A gravar",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Não possível enquanto a transmissão em direto estiver activa",
|
||||
"recordingInProgressDescription": "Esta reunião está a ser gravada e analisada pela IA{{learnMore}}. O seu áudio e vídeo foram silenciados. Se optar por ativar o som, concorda em ser gravado.",
|
||||
"recordingInProgressDescriptionFirstHalf": "Esta reunião está a ser gravada e analisada por IA.",
|
||||
"recordingInProgressDescriptionSecondHalf": ". Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
|
||||
"recordingInProgressTitle": "Gravação em andamento",
|
||||
"rejoinNow": "Reingressar agora",
|
||||
"remoteControlAllowedMessage": "{{user}} aceitou o seu pedido de controlo remoto!",
|
||||
"remoteControlDeniedMessage": "{{user}} rejeitou o seu pedido de controlo remoto!",
|
||||
@@ -439,7 +480,10 @@
|
||||
"shareScreenWarningD2": "é necessário parar a partilha de áudio, iniciar a partilha de ecrã e verificar a opção \"partilhar áudio\".",
|
||||
"shareScreenWarningH1": "Se quiser partilhar apenas o seu ecrã:",
|
||||
"shareScreenWarningTitle": "Tem de parar a partilha de áudio antes de partilhar o seu ecrã",
|
||||
"shareVideoLinkError": "Por favor, forneça um link correcto do vídeo.",
|
||||
"shareVideoConfirmPlay": "Está prestes a abrir um site externo. Deseja continuar?",
|
||||
"shareVideoConfirmPlayTitle": "{{name}} partilhou um vídeo consigo.",
|
||||
"shareVideoLinkError": "Oops, este vídeo não pode ser reproduzido.",
|
||||
"shareVideoLinkStopped": "O vídeo de {{name}} foi interrompido.",
|
||||
"shareVideoTitle": "Partilhar vídeo",
|
||||
"shareYourScreen": "Partilhe o seu ecrã",
|
||||
"shareYourScreenDisabled": "Partilha de ecrã desactivada.",
|
||||
@@ -518,6 +562,21 @@
|
||||
"veryBad": "Muito má",
|
||||
"veryGood": "Muito boa"
|
||||
},
|
||||
"fileSharing": {
|
||||
"downloadFailedDescription": "Por favor, tente novamente.",
|
||||
"downloadFailedTitle": "Falha no descarregar",
|
||||
"downloadFile": "Descarregar",
|
||||
"dragAndDrop": "Arraste e solte os ficheiros aqui ou em qualquer lugar do ecrã",
|
||||
"fileAlreadyUploaded": "O ficheiro já foi carregado para esta reunião.",
|
||||
"fileTooLargeDescription": "Certifique-se de que o ficheiro não exceda {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "O ficheiro selecionado é muito grande",
|
||||
"fileUploadProgress": "Progresso do envio do ficheiro",
|
||||
"fileUploadedSuccessfully": "Ficheiro carregado com sucesso",
|
||||
"removeFile": "Remover",
|
||||
"uploadFailedDescription": "Por favor, tente novamente.",
|
||||
"uploadFailedTitle": "Falha ao carregar",
|
||||
"uploadFile": "Partilhar ficheiro"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Miniaturas de vídeo"
|
||||
@@ -638,6 +697,7 @@
|
||||
"on": "Iniciada a transmissão em direto",
|
||||
"onBy": "{{name}} iniciou a transmissão em direto",
|
||||
"pending": "Início da transmissão em direto…",
|
||||
"policyError": "Tentou iniciar uma transmissão ao vivo muito rapidamente. Por favor, tente novamente mais tarde!",
|
||||
"serviceName": "Serviço de Transmissão em Direto",
|
||||
"sessionAlreadyActive": "Esta sessão já está a ser gravada ou transmitida em direto.",
|
||||
"signIn": "Iniciar sessão com o Google",
|
||||
@@ -728,7 +788,10 @@
|
||||
"me": "eu",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Vulnerabilidade de segurança!",
|
||||
"allowAction": "Permitir",
|
||||
"allowAll": "Permitir tudo",
|
||||
"allowAudio": "Permitir áudio",
|
||||
"allowDesktop": "Permitir partilha de ecrã",
|
||||
"allowVideo": "Permitir vídeo",
|
||||
"allowedUnmute": "Pode ligar o seu microfone, ligar a sua câmara ou partilhar o seu ecrã.",
|
||||
"audioUnmuteBlockedDescription": "A operação de ligar o microfone foi temporariamente bloqueada devido aos limites do sistema.",
|
||||
"audioUnmuteBlockedTitle": "Ligar microfone bloqueado!",
|
||||
@@ -736,12 +799,15 @@
|
||||
"connectedOneMember": "{{name}} entrou na reunião",
|
||||
"connectedThreePlusMembers": "{{name}} e muitos outros entraram na reunião",
|
||||
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
|
||||
"connectionFailed": "Falha na ligação. Por favor, tente novamente mais tarde!",
|
||||
"dataChannelClosed": "A qualidade do vídeo pode ser afetada",
|
||||
"dataChannelClosedDescription": "O canal de ponte está em baixo e, por isso, a qualidade de vídeo pode estar limitada à sua definição mais baixa.",
|
||||
"dataChannelClosedDescriptionWithAudio": "O canal de ponte está em baixo, pelo que podem ocorrer interrupções no áudio e no vídeo.",
|
||||
"dataChannelClosedWithAudio": "A qualidade do áudio e do vídeo pode ser afetada",
|
||||
"desktopMutedRemotelyTitle": "A partilha do seu ecrã foi interrompida por {{participantDisplayName}}",
|
||||
"disabledIframe": "A incorporação destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
|
||||
"disabledIframeSecondary": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos. Por favor, use <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> para incorporação em produção!",
|
||||
"disabledIframeSecondaryNative": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
|
||||
"disabledIframeSecondaryWeb": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos. Utilize <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> para incorporação em produção!",
|
||||
"disconnected": "desconectado",
|
||||
"displayNotifications": "Mostrar notificações para",
|
||||
"dontRemindMe": "Não me lembre",
|
||||
@@ -749,7 +815,10 @@
|
||||
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notificações",
|
||||
"hostAskedUnmute": "O moderador gostaria que você falasse",
|
||||
"hostAskedUnmute": "O moderador gostaria que participasse.",
|
||||
"invalidTenant": "Tenant inválido",
|
||||
"invalidTenantHyphenDescription": "O tenant que está a utilizar é inválido (começa ou termina com '-').",
|
||||
"invalidTenantLengthDescription": "O tenant que está a utilizar é demasiado longo.",
|
||||
"invitedOneMember": "{{displayName}} foi convidado",
|
||||
"invitedThreePlusMembers": "{{name}} e {{count}} outros foram convidados",
|
||||
"invitedTwoMembers": "{{first}} e {{second}} foram convidados",
|
||||
@@ -787,9 +856,9 @@
|
||||
"newDeviceAudioTitle": "Novo dispositivo de áudio detetado",
|
||||
"newDeviceCameraTitle": "Nova câmara detetada",
|
||||
"nextToSpeak": "É o próximo na fila para falar",
|
||||
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído não pode ser ativada enquanto se partilha o áudio do ambiente de trabalho, por favor desative-o e tente novamente.",
|
||||
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído",
|
||||
"noiseSuppressionStereoDescription": "A supressão do ruído de áudio estéreo não é atualmente suportada.",
|
||||
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído extra não pode ser ativada enquanto estiver a partilhar o áudio do ambiente de trabalho. Desative-a e tente novamente.",
|
||||
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído extra",
|
||||
"noiseSuppressionStereoDescription": "Atualmente, a supressão extra de ruído não é suportada com áudio estéreo.",
|
||||
"oldElectronClientDescription1": "Parece estar a utilizar uma versão antiga do cliente Jitsi Meet que tem vulnerabilidades de segurança conhecidas. Por favor, certifique-se de que actualiza a nossa ",
|
||||
"oldElectronClientDescription2": "compilação mais recente",
|
||||
"oldElectronClientDescription3": " agora!",
|
||||
@@ -798,7 +867,7 @@
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removido por outro participante",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) definido por outro participante",
|
||||
"raiseHandAction": "Levantar a mão",
|
||||
"raisedHand": "Gostaria de falar.",
|
||||
"raisedHand": "Gostaria de participar.",
|
||||
"raisedHands": "{{participantName}} e mais {{raisedHands}} pessoas",
|
||||
"reactionSounds": "Desactivar sons",
|
||||
"reactionSoundsForAll": "Desativar sons para todos",
|
||||
@@ -816,15 +885,17 @@
|
||||
"suggestRecordingDescription": "Gostaria de iniciar uma gravação?",
|
||||
"suggestRecordingTitle": "Gravar esta reunião",
|
||||
"unmute": "Ligar microfone",
|
||||
"unmuteScreen": "Iniciar partilha de ecrã",
|
||||
"unmuteVideo": "Ligar câmara",
|
||||
"videoMutedRemotelyDescription": "Pode sempre ligá-la novamente.",
|
||||
"videoMutedRemotelyTitle": "A sua câmara foi desligada pelo {{participantDisplayName}}.",
|
||||
"videoUnmuteBlockedDescription": "A operação de ligar a câmara e partilhar o ambiente de trabalho foi temporariamente bloqueada devido aos limites do sistema.",
|
||||
"videoUnmuteBlockedTitle": "Está bloqueado ligar a câmara e partilhar o ambiente de trabalho!",
|
||||
"viewLobby": "Ver sala de espera",
|
||||
"viewParticipants": "Ver participantes",
|
||||
"viewVisitors": "Ver visitantes",
|
||||
"viewVisitors": "Visualizar espectadores",
|
||||
"waitingParticipants": "{{waitingParticipants}} pessoas",
|
||||
"waitingVisitors": "Visitantes em fila de espera: {{waitingVisitors}}",
|
||||
"waitingVisitors": "Espectadores em fila de espera: {{waitingVisitors}}",
|
||||
"waitingVisitorsTitle": "A reunião ainda não está em direto!",
|
||||
"whiteboardLimitDescription": "Guarde o seu progresso, pois o limite de utilizadores será atingido em breve e o quadro branco será encerrado.",
|
||||
"whiteboardLimitTitle": "Utilização do quadro branco"
|
||||
@@ -833,14 +904,17 @@
|
||||
"actions": {
|
||||
"admit": "Aceitar",
|
||||
"admitAll": "Aceitar todos",
|
||||
"allow": "Permitir aos participantes:",
|
||||
"allow": "Permitir que os não moderadores:",
|
||||
"allowDesktop": "Permitir partilha de ecrã",
|
||||
"allowVideo": "Permitir vídeo",
|
||||
"askDesktop": "Pedir para partilhar o ecrã",
|
||||
"askUnmute": "Pedir para ligar o som",
|
||||
"audioModeration": "Ligar o microfone deles",
|
||||
"blockEveryoneMicCamera": "Bloquear o microfone e a câmara de todos",
|
||||
"breakoutRooms": "Salas simultâneas",
|
||||
"desktopModeration": "Iniciar partilha de ecrã",
|
||||
"goLive": "Aceder ao vivo",
|
||||
"invite": "Convidar alguém",
|
||||
"invite": "Convide alguém",
|
||||
"lowerAllHands": "Baixar todas as mãos",
|
||||
"lowerHand": "Baixar a mão",
|
||||
"moreModerationActions": "Mais opções de moderação",
|
||||
@@ -850,6 +924,8 @@
|
||||
"muteAll": "Silenciar todos",
|
||||
"muteEveryoneElse": "Silenciar todos os outros",
|
||||
"reject": "Rejeitar",
|
||||
"stopDesktop": "Parar a partilha de ecrã",
|
||||
"stopEveryonesDesktop": "Interromper a partilha de ecrã de todos",
|
||||
"stopEveryonesVideo": "Desligar a câmara de todos",
|
||||
"stopVideo": "Desligar a câmara",
|
||||
"unblockEveryoneMicCamera": "Desbloquear o microfone e a câmara de todos",
|
||||
@@ -859,12 +935,15 @@
|
||||
"headings": {
|
||||
"lobby": "Sala de espera ({{count}})",
|
||||
"participantsList": "Participantes da reunião ({{count}})",
|
||||
"viewerRequests": "Pedidos dos espectadores {{count}}",
|
||||
"visitorInQueue": " (à espera {{count}})",
|
||||
"visitorRequests": " (pedidos {{count}})",
|
||||
"visitors": "Visitantes ({{count}})",
|
||||
"visitors": "Espectadores ({{count}})",
|
||||
"visitorsList": "Espectadores ({{count}})",
|
||||
"waitingLobby": "Aguardam na sala de espera ({{count}})"
|
||||
},
|
||||
"search": "Pesquisar participantes",
|
||||
"searchDescription": "Comece a digitar para filtrar os participantes",
|
||||
"title": "Participantes"
|
||||
},
|
||||
"passwordDigitsOnly": "Até {{number}} dígitos",
|
||||
@@ -901,7 +980,7 @@
|
||||
},
|
||||
"results": {
|
||||
"changeVote": "Mudar o voto",
|
||||
"empty": "Ainda não há sondagens na reunião. Comece aqui uma sondagem!",
|
||||
"empty": "Ainda não há sondagens na reunião.",
|
||||
"hideDetailedResults": "Ocultar detalhes",
|
||||
"showDetailedResults": "Mostrar detalhes",
|
||||
"vote": "Voto"
|
||||
@@ -919,9 +998,11 @@
|
||||
"configuringDevices": "A configurar os dispositivos…",
|
||||
"connectedWithAudioQ": "Está ligado com áudio?",
|
||||
"connection": {
|
||||
"failed": "Falha no teste de ligação!",
|
||||
"good": "A sua ligação à Internet parece boa!",
|
||||
"nonOptimal": "A sua ligação à Internet não é óptima",
|
||||
"poor": "Tem uma má ligação à Internet"
|
||||
"poor": "Tem uma ligação à Internet fraca",
|
||||
"running": "A realizar teste de ligação..."
|
||||
},
|
||||
"connectionDetails": {
|
||||
"audioClipping": "Prevemos que o seu áudio tenha cortes.",
|
||||
@@ -930,6 +1011,7 @@
|
||||
"goodQuality": "Fantástico! A qualidade dos seus meios de comunicação vai ser óptima.",
|
||||
"noMediaConnectivity": "Não foi possível encontrar uma forma de estabelecer a conectividade dos meios de comunicação para este teste. Isto é tipicamente causado por uma firewall ou NAT.",
|
||||
"noVideo": "Prevemos que o seu vídeo seja terrível.",
|
||||
"testFailed": "O teste de ligação encontrou problemas inesperados, mas isso pode não afetar a sua experiência.",
|
||||
"undetectable": "Se mesmo assim não conseguir fazer chamadas no browser, recomendamos que se certifique de que os seus altifalantes, microfone e câmara estão devidamente configurados, que concedeu ao seu browser direitos de utilização do seu microfone e câmara, e que a versão do seu browser está actualizada. Se mesmo assim tiver problemas em telefonar, deverá contactar o criador da aplicação web.",
|
||||
"veryPoorConnection": "Prevemos que a qualidade da sua chamada seja realmente terrível.",
|
||||
"videoFreezing": "Prevemos que o seu vídeo congele, fique preto, e seja pixelizado.",
|
||||
@@ -958,7 +1040,7 @@
|
||||
"joinWithoutAudio": "Entrar sem áudio",
|
||||
"keyboardShortcuts": "Ativar os atalhos de teclado",
|
||||
"linkCopied": "Link copiado para a área de transferência",
|
||||
"lookGood": "Tudo está a funcionar corretamente",
|
||||
"lookGood": "Os seus dispositivos estão a funcionar corretamente",
|
||||
"or": "ou",
|
||||
"premeeting": "Pré-reunião",
|
||||
"proceedAnyway": "Continuar na mesma",
|
||||
@@ -1044,6 +1126,7 @@
|
||||
"onBy": "{{name}} iniciou a gravação",
|
||||
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
|
||||
"pending": "Preparando para gravar a reunião…",
|
||||
"policyError": "Tentou iniciar uma gravação muito rapidamente. Por favor, tente novamente mais tarde!",
|
||||
"recordAudioAndVideo": "Gravar áudio e vídeo",
|
||||
"recordTranscription": "Gravar transcrições",
|
||||
"saveLocalRecording": "Guardar ficheiro de gravação localmente (Beta)",
|
||||
@@ -1087,11 +1170,13 @@
|
||||
"signedIn": "Atualmente a aceder a eventos de calendário por {{email}}. Clique no botão Desconectar abaixo para parar de aceder a eventos de calendário.",
|
||||
"title": "Calendário"
|
||||
},
|
||||
"chatWithPermissions": "O chat requer permissão",
|
||||
"desktopShareFramerate": "Taxa de fotogramas para partilha do ambiente de trabalho",
|
||||
"desktopShareHighFpsWarning": "Uma taxa de fotogramas mais elevada para a partilha do ambiente de trabalho pode afectar a sua largura de banda. É necessário reiniciar a partilha de ecrã para que as novas definições entrem em vigor.",
|
||||
"desktopShareWarning": "É necessário reiniciar a partilha do ecrã para que as novas definições entrem em vigor.",
|
||||
"devices": "Dispositivos",
|
||||
"followMe": "Todos me seguem",
|
||||
"followMeRecorder": "O gravador segue-me",
|
||||
"framesPerSecond": "fotogramas-por-segundo",
|
||||
"incomingMessage": "Receber uma mensagem",
|
||||
"language": "Idioma",
|
||||
@@ -1115,6 +1200,7 @@
|
||||
"selectMic": "Microfone",
|
||||
"selfView": "Autovisualização",
|
||||
"shortcuts": "Atalhos",
|
||||
"showSubtitlesOnStage": "Mostrar legendas",
|
||||
"speakers": "Altifalantes",
|
||||
"startAudioMuted": "Todos começam com microfone desligado",
|
||||
"startReactionsMuted": "Todos começam com os sons de reação desativados",
|
||||
@@ -1168,11 +1254,13 @@
|
||||
"fearful": "Temeroso",
|
||||
"happy": "Feliz",
|
||||
"hours": "{{count}}h",
|
||||
"labelTooltip": "Número de participantes: {{count}}",
|
||||
"minutes": "{{count}}m",
|
||||
"name": "Nome",
|
||||
"neutral": "Neutro",
|
||||
"sad": "Triste",
|
||||
"search": "Pesquisar",
|
||||
"searchDescription": "Comece a digitar para filtrar os participantes",
|
||||
"searchHint": "Pesquisar participantes",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerStats": "Estatísticas dos Participantes",
|
||||
@@ -1209,6 +1297,7 @@
|
||||
"closeChat": "Fechar chat",
|
||||
"closeMoreActions": "Fechar menu de mais ações",
|
||||
"closeParticipantsPane": "Fechar painel de participantes",
|
||||
"closedCaptions": "Legendas ocultas",
|
||||
"collapse": "Colapsar",
|
||||
"document": "Mudar para documento partilhado",
|
||||
"documentClose": "Fechar documento partilhado",
|
||||
@@ -1238,6 +1327,7 @@
|
||||
"lobbyButton": "Ativar/desativar sala de espera",
|
||||
"localRecording": "Mudar os controlos locais de gravação",
|
||||
"lockRoom": "Mudar palavra-chave de reunião",
|
||||
"love": "Coração",
|
||||
"lowerHand": "Baixar a mão",
|
||||
"moreActions": "Mais ações",
|
||||
"moreActionsMenu": "Menu de mais ações",
|
||||
@@ -1248,13 +1338,14 @@
|
||||
"muteEveryoneElsesVideo": "Parar o vídeo de todos os outros",
|
||||
"muteEveryonesVideo": "Parar o vídeo de todos",
|
||||
"muteGUMPending": "A ligar o seu microfone",
|
||||
"noiseSuppression": "Supressão de ruído",
|
||||
"noiseSuppression": "Supressão extra de ruído (BETA)",
|
||||
"openChat": "Abrir chat",
|
||||
"participants": "Abrir painel de participantes",
|
||||
"participants": "Abrir painel de participantes. {{participantsCount}} participantes",
|
||||
"pip": "Mudar para o modo Picture-in-Picture",
|
||||
"privateMessage": "Enviar mensagem privada",
|
||||
"profile": "Editar o seu perfil",
|
||||
"raiseHand": "Levantar a mão",
|
||||
"react": "Reações às mensagens",
|
||||
"reactions": "Reações",
|
||||
"reactionsMenu": "Menu de reações",
|
||||
"recording": "Mudar gravação",
|
||||
@@ -1297,14 +1388,15 @@
|
||||
"closeChat": "Fechar chat",
|
||||
"closeParticipantsPane": "Fechar painel de participantes",
|
||||
"closeReactionsMenu": "Fechar menu de reações",
|
||||
"disableNoiseSuppression": "Desativar a supressão de ruído",
|
||||
"closedCaptions": "Legendas ocultas",
|
||||
"disableNoiseSuppression": "Desativar supressão de ruído extra (BETA)",
|
||||
"disableReactionSounds": "Pode desactivar os sons de reacção para esta reunião",
|
||||
"documentClose": "Fechar documento partilhado",
|
||||
"documentOpen": "Abrir documento partilhado",
|
||||
"download": "Descarregar as nossas aplicações",
|
||||
"e2ee": "Criptografia ponta a ponta",
|
||||
"embedMeeting": "Incorporar reunião",
|
||||
"enableNoiseSuppression": "Ativar a supressão de ruído",
|
||||
"enableNoiseSuppression": "Ativar supressão extra de ruído (BETA)",
|
||||
"endConference": "Terminar reunião para todos",
|
||||
"enterFullScreen": "Ver em ecrã completo",
|
||||
"enterTileView": "Ver em quadrícula",
|
||||
@@ -1326,6 +1418,7 @@
|
||||
"lobbyButtonEnable": "Ativar sala de espera",
|
||||
"login": "Iniciar sessão",
|
||||
"logout": "Terminar sessão",
|
||||
"love": "Coração",
|
||||
"lowerYourHand": "Baixar a mão",
|
||||
"moreActions": "Mais ações",
|
||||
"moreOptions": "Mais opções",
|
||||
@@ -1338,7 +1431,7 @@
|
||||
"noAudioSignalDialInDesc": "Também pode marcar usando:",
|
||||
"noAudioSignalDialInLinkDesc": "Números de marcação",
|
||||
"noAudioSignalTitle": "Não há nenhuma entrada vinda do seu microfone!",
|
||||
"noiseSuppression": "Supressão de ruído",
|
||||
"noiseSuppression": "Supressão extra de ruído (BETA)",
|
||||
"noisyAudioInputDesc": "Parece que o seu microfone está a fazer barulho, por favor considere silenciar ou mudar de dispositivo.",
|
||||
"noisyAudioInputTitle": "Seu microfone parece estar barulhento!",
|
||||
"openChat": "Abrir chat",
|
||||
@@ -1351,6 +1444,7 @@
|
||||
"raiseYourHand": "Levantar a mão",
|
||||
"reactionBoo": "Enviar reação de vaia",
|
||||
"reactionClap": "Enviar reação de aplausos",
|
||||
"reactionHeart": "Enviar reação com coração",
|
||||
"reactionLaugh": "Enviar reação de risos",
|
||||
"reactionLike": "Enviar reação de aprovado",
|
||||
"reactionSilence": "Enviar reação de silêncio",
|
||||
@@ -1384,15 +1478,19 @@
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Iniciar/parar legendas",
|
||||
"expandedLabel": "Transcrição ativada",
|
||||
"failedToStart": "Transcrição falhou ao iniciar",
|
||||
"labelToolTip": "A reunião esta sendo transcrita",
|
||||
"failed": "Falha na transcrição",
|
||||
"labelTooltip": "Esta reunião está a ser transcrita.",
|
||||
"labelTooltipExtra": "Além disso, uma transcrição estará disponível posteriormente.",
|
||||
"openClosedCaptions": "Abrir legendas ocultas",
|
||||
"original": "Original",
|
||||
"sourceLanguageDesc": "Atualmente a língua da reunião está definida para <b>{{sourceLanguage}}</b>. <br/> Pode alterá-la a partir ",
|
||||
"sourceLanguageHere": "daqui",
|
||||
"start": "Exibir legendas",
|
||||
"stop": "Não exibir legendas",
|
||||
"subtitles": "Legendas",
|
||||
"subtitlesOff": "Desligado",
|
||||
"tr": "TR"
|
||||
"tr": "TR",
|
||||
"translateTo": "Traduzir para"
|
||||
},
|
||||
"unpinParticipant": "{{participantName}} - Desafixar",
|
||||
"userMedia": {
|
||||
@@ -1424,7 +1522,7 @@
|
||||
"ldTooltip": "Ver vídeo em baixa definição",
|
||||
"lowDefinition": "Baixa definição (LD)",
|
||||
"performanceSettings": "Definições de desempenho",
|
||||
"recording": "Gravação em curso",
|
||||
"recording": "Esta reunião está a ser gravada.",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Ver vídeo em definição padrão",
|
||||
"standardDefinition": "Definição padrão",
|
||||
@@ -1432,8 +1530,10 @@
|
||||
},
|
||||
"videothumbnail": {
|
||||
"connectionInfo": "Informações sobre a ligação",
|
||||
"demote": "Passar a visitante",
|
||||
"demote": "Passar a espectador",
|
||||
"domute": "Sem som",
|
||||
"domuteDesktop": "Parar a partilha de ecrã",
|
||||
"domuteDesktopOfOthers": "Interromper a partilha de ecrã para todos os outros",
|
||||
"domuteOthers": "Silenciar todos os outros",
|
||||
"domuteVideo": "Desativar a câmara",
|
||||
"domuteVideoOfOthers": "Desactivar a câmara de todos os outros",
|
||||
@@ -1484,21 +1584,21 @@
|
||||
"webAssemblyWarningDescription": "WebAssembly desactivado ou não suportado por este navegador"
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(visitante)",
|
||||
"chatIndicator": "(espectador)",
|
||||
"joinMeeting": {
|
||||
"description": "Atualmente, é um observador nesta conferência.",
|
||||
"description": "Atualmente, é um espectador nesta conferência.",
|
||||
"raiseHand": "Levantar a mão",
|
||||
"title": "Participar na reunião",
|
||||
"wishToSpeak": "Se deseja intervir, levante a mão e aguarde a aprovação do moderador."
|
||||
},
|
||||
"labelTooltip": "Número de visitantes: {{count}}",
|
||||
"labelTooltip": "Número de espectadores: {{count}}",
|
||||
"notification": {
|
||||
"demoteDescription": "Enviado aqui pelo {{actor}}, levante a mão para participar",
|
||||
"noMainParticipantsDescription": "Um participante precisa de iniciar a reunião. Tente novamente daqui a pouco.",
|
||||
"noMainParticipantsTitle": "Esta reunião ainda não começou.",
|
||||
"noVisitorLobby": "Não é possível aderir enquanto houver uma sala de espera activada para a reunião.",
|
||||
"notAllowedPromotion": "É necessário que um participante autorize primeiro o seu pedido.",
|
||||
"title": "É um visitante na reunião"
|
||||
"title": "É um espectador na reunião"
|
||||
},
|
||||
"waitingMessage": "Participará na reunião assim que esta estiver em direto!"
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -331,11 +331,11 @@
|
||||
"internalError": "Ett fel uppstod. Fel: {{error}}",
|
||||
"internalErrorTitle": "Internt fel",
|
||||
"kickMessage": "Du kan kontakta {{participantDisplayName}} för mer information.",
|
||||
"kickParticipantButton": "Sparka ut",
|
||||
"kickParticipantDialog": "Vill du sparka ut den här deltagaren?",
|
||||
"kickParticipantButton": "Ta bort från mötet",
|
||||
"kickParticipantDialog": "Vill du ta bort denna deltagaren från mötet?",
|
||||
"kickParticipantTitle": "Tysta deltagaren?",
|
||||
"kickSystemTitle": "Aj! du blev utsparkad ur mötet",
|
||||
"kickTitle": "Aj! {{participantDisplayName}} sparkade ut dig ur mötet",
|
||||
"kickSystemTitle": "Du har blivit borttagen från mötet",
|
||||
"kickTitle": "{{participantDisplayName}} tog bort dig från mötet",
|
||||
"linkMeeting": "Länka möte",
|
||||
"linkMeetingTitle": "Länka möte till Salesforce",
|
||||
"liveStreaming": "Streama",
|
||||
@@ -763,7 +763,7 @@
|
||||
"invitedThreePlusMembers": "{{name}} och {{count}} andra har bjudits in",
|
||||
"invitedTwoMembers": "{{first}} och {{second}} har bjudits in",
|
||||
"joinMeeting": "Delta",
|
||||
"kickParticipant": "{{kicked}} sparkades ut av {{kicker}}",
|
||||
"kickParticipant": "{{kicked}} togs bort av {{kicker}}",
|
||||
"leftOneMember": "{{name}} lämnade mötet",
|
||||
"leftThreePlusMembers": "{{name}} och många andra lämnade mötet",
|
||||
"leftTwoMembers": "{{first}} och {{second}} lämnade mötet",
|
||||
@@ -1245,7 +1245,7 @@
|
||||
"help": "Hjälp",
|
||||
"hideWhiteboard": "Dölj whiteboard",
|
||||
"invite": "Bjud in personer",
|
||||
"kick": "Sparka ut deltagare",
|
||||
"kick": "Ta bort deltagare",
|
||||
"laugh": "Skratta",
|
||||
"leaveConference": "Lämna mötet",
|
||||
"like": "Tummen upp",
|
||||
@@ -1459,7 +1459,7 @@
|
||||
"flip": "Vänd",
|
||||
"grantModerator": "Godkänn moderator",
|
||||
"hideSelfView": "Dölj självvyn",
|
||||
"kick": "Sparka ut",
|
||||
"kick": "Ta bort",
|
||||
"mirrorVideo": "Spegelvänd video",
|
||||
"moderator": "Moderator",
|
||||
"mute": "Deltagaren har avstängd mikrofon",
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
"disabled": "Sending chat messages is disabled.",
|
||||
"enter": "Enter room",
|
||||
"error": "Error: your message was not sent. Reason: {{error}}",
|
||||
"everyone": "Everyone",
|
||||
"fieldPlaceHolder": "Aa",
|
||||
"guestsChatIndicator": "(guest)",
|
||||
"lobbyChatMessageTo": "Lobby chat message to {{recipient}}",
|
||||
"message": "Message",
|
||||
"messageAccessibleTitle": "{{user}} says:",
|
||||
@@ -278,7 +280,6 @@
|
||||
"Submit": "Submit",
|
||||
"Understand": "I understand, keep me muted for now",
|
||||
"UnderstandAndUnmute": "I understand, please unmute me",
|
||||
"WaitForHostMsg": "The conference has not yet started because no moderators have yet arrived. If you'd like to become a moderator please log-in. Otherwise, please wait.",
|
||||
"WaitForHostNoAuthMsg": "The conference has not yet started because no moderators have yet arrived. Please wait.",
|
||||
"WaitingForHostButton": "Wait for moderator",
|
||||
"WaitingForHostTitle": "Waiting for a moderator…",
|
||||
@@ -300,6 +301,12 @@
|
||||
"alreadySharedVideoTitle": "Only one shared video is allowed at a time",
|
||||
"applicationWindow": "Application window",
|
||||
"authenticationRequired": "Authentication required",
|
||||
"cameraCaptureDialog": {
|
||||
"description": "Take and send a picture using your mobile camera",
|
||||
"ok": "Open camera",
|
||||
"reject": "Not now",
|
||||
"title": "Take a picture"
|
||||
},
|
||||
"cameraConstraintFailedError": "Your camera does not satisfy some of the required constraints.",
|
||||
"cameraNotFoundError": "Camera was not found.",
|
||||
"cameraNotSendingData": "We are unable to access your camera. Please check if another application is using this device, select another device from the settings menu or try to reload the application.",
|
||||
@@ -374,23 +381,35 @@
|
||||
"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.",
|
||||
"micTimeoutError": "Could not start audio source. Timeout occurred!",
|
||||
"micUnknownError": "Cannot use microphone for an unknown reason.",
|
||||
"moderationAudioLabel": "Allow attendees to unmute themselves",
|
||||
"moderationAudioLabel": "Allow non-moderators to unmute themselves",
|
||||
"moderationDesktopLabel": "Allow non-moderators to share their screen",
|
||||
"moderationVideoLabel": "Allow non-moderators to start their video",
|
||||
"muteEveryoneDialog": "The participants can unmute themselves at any time.",
|
||||
"muteEveryoneDialogModerationOn": "The participants can send a request to speak at any time.",
|
||||
"muteEveryoneElseDialog": "Once muted, you won't be able to unmute them, but they can unmute themselves at any time.",
|
||||
"muteEveryoneElseTitle": "Mute everyone except {{whom}}?",
|
||||
"muteEveryoneElsesDesktopDialog": "Once the share is stopped, you won't be able to restart it, but they can do so at any time.",
|
||||
"muteEveryoneElsesDesktopTitle": "Stop everyone's screen-share except {{whom}}?",
|
||||
"muteEveryoneElsesVideoDialog": "Once the camera is disabled, you won't be able to turn it back on, but they can turn it back on at any time.",
|
||||
"muteEveryoneElsesVideoTitle": "Stop everyone's video except {{whom}}?",
|
||||
"muteEveryoneSelf": "yourself",
|
||||
"muteEveryoneStartMuted": "Everyone starts muted from now on",
|
||||
"muteEveryoneTitle": "Mute everyone?",
|
||||
"muteEveryonesDesktopDialog": "The participants can share their screen at any time.",
|
||||
"muteEveryonesDesktopDialogModerationOn": "The participants can send a request to share their screen at any time.",
|
||||
"muteEveryonesDesktopTitle": "Stop everyone's screen share?",
|
||||
"muteEveryonesVideoDialog": "The participants can turn on their video at any time.",
|
||||
"muteEveryonesVideoDialogModerationOn": "The participants can send a request to turn on their video at any time.",
|
||||
"muteEveryonesVideoDialogOk": "Disable",
|
||||
"muteEveryonesVideoTitle": "Stop everyone's video?",
|
||||
"muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.",
|
||||
"muteParticipantButton": "Mute",
|
||||
"muteParticipantsDesktopBody": "You won't be able to start their screen-share, but they can do so at any time.",
|
||||
"muteParticipantsDesktopBodyModerationOn": "You won't be able to start their screen-share and neither will they.",
|
||||
"muteParticipantsDesktopButton": "Stop screen sharing",
|
||||
"muteParticipantsDesktopDialog": "Are you sure you want to turn off this participant's screen-share? You won't be able to restart it, but they can do so at any time.",
|
||||
"muteParticipantsDesktopDialogModerationOn": "Are you sure you want to turn off this participant's screen-share? You won't be able to turn the screen back on and neither will they.",
|
||||
"muteParticipantsDesktopTitle": "Disable screen-share of this participant?",
|
||||
"muteParticipantsVideoBody": "You won't be able to turn the camera back on, but they can turn it back on at any time.",
|
||||
"muteParticipantsVideoBodyModerationOn": "You won't be able to turn the camera back on and neither will they.",
|
||||
"muteParticipantsVideoButton": "Stop video",
|
||||
@@ -503,6 +522,7 @@
|
||||
"tokenAuthFailedWithReasons": "Sorry, you're not allowed to join this call. Possible reasons: {{reason}}",
|
||||
"tokenAuthUnsupported": "Token URL is not supported.",
|
||||
"transcribing": "Transcribing",
|
||||
"unauthenticatedAccessDisabled": "This call requires authentication. Please login in order to proceed.",
|
||||
"unlockRoom": "Remove meeting $t(lockRoomPassword)",
|
||||
"user": "User",
|
||||
"userIdentifier": "User identifier",
|
||||
@@ -547,11 +567,15 @@
|
||||
"downloadFailedDescription": "Please try again.",
|
||||
"downloadFailedTitle": "Download failed",
|
||||
"downloadFile": "Download",
|
||||
"downloadStarted": "File download started",
|
||||
"dragAndDrop": "Drag and drop files here or anywhere on screen",
|
||||
"fileAlreadyUploaded": "File has already been uploaded to this meeting.",
|
||||
"fileTooLargeDescription": "Please make sure the file does not exceed {{ maxFileSize }}.",
|
||||
"fileTooLargeTitle": "The selected file is too large",
|
||||
"fileUploadProgress": "File upload progress",
|
||||
"fileUploadedSuccessfully": "File uploaded successfully",
|
||||
"removeFile": "Remove",
|
||||
"removeFileSuccess": "File removed successfully",
|
||||
"uploadFailedDescription": "Please try again.",
|
||||
"uploadFailedTitle": "Upload failed",
|
||||
"uploadFile": "Share file"
|
||||
@@ -724,7 +748,8 @@
|
||||
"notificationTitle": "Lobby",
|
||||
"passwordJoinButton": "Join",
|
||||
"title": "Lobby",
|
||||
"toggleLabel": "Enable lobby"
|
||||
"toggleLabel": "Enable lobby",
|
||||
"waitForModerator": "The conference has not yet started because no moderators have yet arrived. If you'd like to become a moderator please log-in. Otherwise, please wait."
|
||||
},
|
||||
"localRecording": {
|
||||
"clientState": {
|
||||
@@ -767,8 +792,9 @@
|
||||
"me": "me",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Security vulnerability!",
|
||||
"allowAll": "Allow All",
|
||||
"allowAudio": "Allow Audio",
|
||||
"allowBoth": "Both",
|
||||
"allowDesktop": "Allow screen sharing",
|
||||
"allowVideo": "Allow Video",
|
||||
"allowedUnmute": "You can unmute your microphone, start your camera or share your screen.",
|
||||
"audioUnmuteBlockedDescription": "Mic unmute operation has been temporarily blocked because of system limits.",
|
||||
@@ -782,6 +808,7 @@
|
||||
"dataChannelClosedDescription": "The bridge channel is down and thus video quality may be limited to its lowest setting.",
|
||||
"dataChannelClosedDescriptionWithAudio": "The bridge channel is down and thus disruptions to audio and video may occur.",
|
||||
"dataChannelClosedWithAudio": "Audio and video quality may be impaired",
|
||||
"desktopMutedRemotelyTitle": "Your screen sharing has been stopped by {{participantDisplayName}}",
|
||||
"disabledIframe": "Embedding is only meant for demo purposes, so this call will disconnect in {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryNative": "Embedding {{domain}} is only meant for demo purposes, so this call will disconnect in {{timeout}} minutes.",
|
||||
"disabledIframeSecondaryWeb": "Embedding {{domain}} is only meant for demo purposes, so this call will disconnect in {{timeout}} minutes. Please use <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> for production embedding!",
|
||||
@@ -839,6 +866,7 @@
|
||||
"oldElectronClientDescription1": "You appear to be using an old version of the Jitsi Meet client which has known security vulnerabilities. Please make sure you update to our ",
|
||||
"oldElectronClientDescription2": "latest build",
|
||||
"oldElectronClientDescription3": " now!",
|
||||
"openChat": "Open chat",
|
||||
"participantWantsToJoin": "Wants to join the meeting",
|
||||
"participantsWantToJoin": "Want to join the meeting",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removed by another participant",
|
||||
@@ -862,6 +890,7 @@
|
||||
"suggestRecordingDescription": "Would you like to start a recording?",
|
||||
"suggestRecordingTitle": "Record this meeting",
|
||||
"unmute": "Unmute Audio",
|
||||
"unmuteScreen": "Start screen sharing",
|
||||
"unmuteVideo": "Unmute Video",
|
||||
"videoMutedRemotelyDescription": "You can always turn it on again.",
|
||||
"videoMutedRemotelyTitle": "Your video has been turned off by {{participantDisplayName}}",
|
||||
@@ -881,11 +910,14 @@
|
||||
"admit": "Admit",
|
||||
"admitAll": "Admit all",
|
||||
"allow": "Allow non-moderators to:",
|
||||
"allowDesktop": "Allow screen sharing",
|
||||
"allowVideo": "Allow video",
|
||||
"askDesktop": "Ask to share screen",
|
||||
"askUnmute": "Ask to unmute",
|
||||
"audioModeration": "Unmute themselves",
|
||||
"blockEveryoneMicCamera": "Block everyone's mic and camera",
|
||||
"breakoutRooms": "Breakout rooms",
|
||||
"desktopModeration": "Start screen sharing",
|
||||
"goLive": "Go live",
|
||||
"invite": "Invite someone",
|
||||
"lowerAllHands": "Lower all hands",
|
||||
@@ -897,6 +929,8 @@
|
||||
"muteAll": "Mute all",
|
||||
"muteEveryoneElse": "Mute everyone else",
|
||||
"reject": "Reject",
|
||||
"stopDesktop": "Stop screen sharing",
|
||||
"stopEveryonesDesktop": "Stop everyone's screen-share",
|
||||
"stopEveryonesVideo": "Stop everyone's video",
|
||||
"stopVideo": "Stop video",
|
||||
"unblockEveryoneMicCamera": "Unblock everyone's mic and camera",
|
||||
@@ -931,6 +965,9 @@
|
||||
"by": "By {{ name }}",
|
||||
"closeButton": "Close poll",
|
||||
"create": {
|
||||
"accessibilityLabel": {
|
||||
"send": "Send poll"
|
||||
},
|
||||
"addOption": "Add option",
|
||||
"answerPlaceholder": "Option {{index}}",
|
||||
"cancel": "Cancel",
|
||||
@@ -939,8 +976,7 @@
|
||||
"pollQuestion": "Poll Question",
|
||||
"questionPlaceholder": "Ask a question",
|
||||
"removeOption": "Remove option",
|
||||
"save": "Save",
|
||||
"send": "Send"
|
||||
"save": "Save"
|
||||
},
|
||||
"errors": {
|
||||
"notUniqueOption": "Options must be unique"
|
||||
@@ -1347,6 +1383,20 @@
|
||||
"videounmute": "Start camera"
|
||||
},
|
||||
"addPeople": "Add people to your call",
|
||||
"advancedAudioSettings": {
|
||||
"aec": {
|
||||
"label": "Acoustic echo cancellation"
|
||||
},
|
||||
"agc": {
|
||||
"label": "Automatic gain control"
|
||||
},
|
||||
"ns": {
|
||||
"label": "Noise suppression"
|
||||
},
|
||||
"stereo": {
|
||||
"label": "Stereo"
|
||||
}
|
||||
},
|
||||
"audioOnlyOff": "Disable low bandwidth mode",
|
||||
"audioOnlyOn": "Enable low bandwidth mode",
|
||||
"audioRoute": "Select the sound device",
|
||||
@@ -1387,8 +1437,8 @@
|
||||
"linkToSalesforce": "Link to Salesforce",
|
||||
"lobbyButtonDisable": "Disable lobby mode",
|
||||
"lobbyButtonEnable": "Enable lobby mode",
|
||||
"login": "Log-in",
|
||||
"logout": "Log-out",
|
||||
"login": "Log In",
|
||||
"logout": "Log Out",
|
||||
"love": "Heart",
|
||||
"lowerYourHand": "Lower your hand",
|
||||
"moreActions": "More actions",
|
||||
@@ -1418,6 +1468,7 @@
|
||||
"reactionHeart": "Send heart reaction",
|
||||
"reactionLaugh": "Send laugh reaction",
|
||||
"reactionLike": "Send thumbs up reaction",
|
||||
"reactionLove": "Send love reaction",
|
||||
"reactionSilence": "Send silence reaction",
|
||||
"reactionSurprised": "Send surprised reaction",
|
||||
"reactions": "Reactions",
|
||||
@@ -1503,6 +1554,8 @@
|
||||
"connectionInfo": "Connection Info",
|
||||
"demote": "Move to viewer",
|
||||
"domute": "Mute",
|
||||
"domuteDesktop": "Stop screen-sharing",
|
||||
"domuteDesktopOfOthers": "Stop screen-sharing for everyone else",
|
||||
"domuteOthers": "Mute everyone else",
|
||||
"domuteVideo": "Disable camera",
|
||||
"domuteVideoOfOthers": "Disable camera of everyone else",
|
||||
@@ -1567,6 +1620,8 @@
|
||||
"noMainParticipantsTitle": "This meeting hasn't started yet.",
|
||||
"noVisitorLobby": "You cannot join while there is a lobby enabled for the meeting.",
|
||||
"notAllowedPromotion": "A participant needs to allow your request first.",
|
||||
"requestToJoin": "Hand Raised",
|
||||
"requestToJoinDescription": "Your request was sent to the moderators. Hang tight!",
|
||||
"title": "You are a viewer in the meeting"
|
||||
},
|
||||
"waitingMessage": "You'll join the meeting as soon as it is live!"
|
||||
|
||||
@@ -13,14 +13,12 @@ import {
|
||||
requestEnableAudioModeration,
|
||||
requestEnableVideoModeration
|
||||
} from '../../react/features/av-moderation/actions';
|
||||
import { isEnabledFromState } from '../../react/features/av-moderation/functions';
|
||||
import { isEnabledFromState, isForceMuted } from '../../react/features/av-moderation/functions';
|
||||
import { setAudioOnly } from '../../react/features/base/audio-only/actions';
|
||||
import {
|
||||
endConference,
|
||||
sendTones,
|
||||
setAssumedBandwidthBps,
|
||||
setFollowMe,
|
||||
setFollowMeRecorder,
|
||||
setLocalSubject,
|
||||
setPassword,
|
||||
setSubject
|
||||
@@ -30,6 +28,7 @@ import { overwriteConfig } from '../../react/features/base/config/actions';
|
||||
import { getWhitelistedJSON } from '../../react/features/base/config/functions.any';
|
||||
import { toggleDialog } from '../../react/features/base/dialog/actions';
|
||||
import { isSupportedBrowser } from '../../react/features/base/environment/environment';
|
||||
import { isMobileBrowser } from '../../react/features/base/environment/utils';
|
||||
import { parseJWTFromURLParams } from '../../react/features/base/jwt/functions';
|
||||
import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../../react/features/base/media/constants';
|
||||
@@ -90,6 +89,7 @@ import {
|
||||
togglePinStageParticipant
|
||||
} from '../../react/features/filmstrip/actions.web';
|
||||
import { getPinnedActiveParticipants, isStageFilmstripAvailable } from '../../react/features/filmstrip/functions.web';
|
||||
import { setFollowMe, setFollowMeRecorder } from '../../react/features/follow-me/actions';
|
||||
import { invite } from '../../react/features/invite/actions.any';
|
||||
import {
|
||||
selectParticipantInLargeVideo
|
||||
@@ -106,14 +106,17 @@ import {
|
||||
close as closeParticipantsPane,
|
||||
open as openParticipantsPane
|
||||
} from '../../react/features/participants-pane/actions';
|
||||
import { getParticipantsPaneOpen, isForceMuted } from '../../react/features/participants-pane/functions';
|
||||
import { getParticipantsPaneOpen } from '../../react/features/participants-pane/functions';
|
||||
import { startLocalVideoRecording, stopLocalVideoRecording } from '../../react/features/recording/actions.any';
|
||||
import { grantRecordingConsent, grantRecordingConsentAndUnmute } from '../../react/features/recording/actions.web';
|
||||
import { RECORDING_METADATA_ID, RECORDING_TYPES } from '../../react/features/recording/constants';
|
||||
import { getActiveSession, supportsLocalRecording } from '../../react/features/recording/functions';
|
||||
import { startAudioScreenShareFlow, startScreenShareFlow } from '../../react/features/screen-share/actions';
|
||||
import { isScreenAudioSupported } from '../../react/features/screen-share/functions';
|
||||
import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-capture/actions';
|
||||
import {
|
||||
openCameraCaptureDialog,
|
||||
toggleScreenshotCaptureSummary
|
||||
} from '../../react/features/screenshot-capture/actions';
|
||||
import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions';
|
||||
import SettingsDialog from '../../react/features/settings/components/web/SettingsDialog';
|
||||
import { SETTINGS_TABS } from '../../react/features/settings/constants';
|
||||
@@ -134,7 +137,7 @@ import {
|
||||
ENDPOINT_TEXT_MESSAGE_NAME
|
||||
} from './constants';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('api:core');
|
||||
|
||||
/**
|
||||
* List of the available commands.
|
||||
@@ -940,6 +943,20 @@ function initCommands() {
|
||||
});
|
||||
});
|
||||
break;
|
||||
case 'capture-camera-picture' : {
|
||||
const { cameraFacingMode, descriptionText, titleText } = request;
|
||||
|
||||
if (!isMobileBrowser()) {
|
||||
logger.error('This feature is only supported on mobile');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
APP.store.dispatch(openCameraCaptureDialog(callback, { cameraFacingMode,
|
||||
descriptionText,
|
||||
titleText }));
|
||||
break;
|
||||
}
|
||||
case 'deployment-info':
|
||||
callback(APP.store.getState()['features/base/config'].deploymentInfo);
|
||||
break;
|
||||
|
||||
21
modules/API/external/external_api.js
vendored
21
modules/API/external/external_api.js
vendored
@@ -820,6 +820,27 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures a picture through OS camera.
|
||||
*
|
||||
* @param {string} cameraFacingMode - The OS camera facing mode (environment/user).
|
||||
* @param {string} descriptionText - The OS camera facing mode (environment/user).
|
||||
* @param {string} titleText - The OS camera facing mode (environment/user).
|
||||
* @returns {Promise<string>} - Resolves with a base64 encoded image data of the screenshot.
|
||||
*/
|
||||
captureCameraPicture(
|
||||
cameraFacingMode,
|
||||
descriptionText,
|
||||
titleText
|
||||
) {
|
||||
return this._transport.sendRequest({
|
||||
name: 'capture-camera-picture',
|
||||
cameraFacingMode,
|
||||
descriptionText,
|
||||
titleText
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listeners and removes the Jitsi Meet frame.
|
||||
*
|
||||
|
||||
2
modules/API/external/functions.js
vendored
2
modules/API/external/functions.js
vendored
@@ -1,6 +1,6 @@
|
||||
import Logger from '@jitsi/logger';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('api:external');
|
||||
|
||||
/**
|
||||
* Returns Promise that resolves with result an list of available devices.
|
||||
|
||||
@@ -28,7 +28,7 @@ import EtherpadManager from './etherpad/Etherpad';
|
||||
import UIUtil from './util/UIUtil';
|
||||
import VideoLayout from './videolayout/VideoLayout';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('ui:core');
|
||||
|
||||
let etherpadManager;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import AudioLevels from '../audio_levels/AudioLevels';
|
||||
|
||||
import { VIDEO_CONTAINER_TYPE, VideoContainer } from './VideoContainer';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('ui:videolayout');
|
||||
|
||||
const DESKTOP_CONTAINER_TYPE = 'desktop';
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export const VIDEO_CONTAINER_TYPE = 'camera';
|
||||
// Corresponds to animation duration from the animatedFadeIn and animatedFadeOut CSS classes.
|
||||
const FADE_DURATION_MS = 300;
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('ui:VideoContainer');
|
||||
|
||||
/**
|
||||
* List of container events that we are going to process for the large video.
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import LargeVideoManager from './LargeVideoManager';
|
||||
import { VIDEO_CONTAINER_TYPE } from './VideoContainer';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('ui:VideoLayout');
|
||||
let largeVideo;
|
||||
|
||||
const VideoLayout = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const logger = require('@jitsi/logger').getLogger(__filename);
|
||||
const logger = require('@jitsi/logger').getLogger('app:utils');
|
||||
|
||||
/**
|
||||
* Manages a queue of functions where the current function in progress will
|
||||
|
||||
6973
package-lock.json
generated
6973
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
62
package.json
62
package.json
@@ -23,10 +23,10 @@
|
||||
"@emotion/styled": "11.10.6",
|
||||
"@giphy/js-fetch-api": "4.9.3",
|
||||
"@giphy/react-components": "6.9.4",
|
||||
"@giphy/react-native-sdk": "2.3.0",
|
||||
"@giphy/react-native-sdk": "4.1.0",
|
||||
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.19/jitsi-excalidraw-0.0.19.tgz",
|
||||
"@jitsi/js-utils": "2.2.1",
|
||||
"@jitsi/logger": "2.0.2",
|
||||
"@jitsi/logger": "2.1.1",
|
||||
"@jitsi/rnnoise-wasm": "0.2.1",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@microsoft/microsoft-graph-client": "3.0.1",
|
||||
@@ -34,13 +34,14 @@
|
||||
"@react-native-async-storage/async-storage": "1.23.1",
|
||||
"@react-native-clipboard/clipboard": "1.14.3",
|
||||
"@react-native-community/netinfo": "11.1.0",
|
||||
"@react-native-community/slider": "4.4.3",
|
||||
"@react-native-community/slider": "4.5.6",
|
||||
"@react-native-google-signin/google-signin": "10.1.0",
|
||||
"@react-navigation/bottom-tabs": "6.6.0",
|
||||
"@react-navigation/elements": "1.3.30",
|
||||
"@react-navigation/material-top-tabs": "6.6.13",
|
||||
"@react-navigation/native": "6.1.17",
|
||||
"@react-navigation/stack": "6.4.0",
|
||||
"@sayem314/react-native-keep-awake": "1.3.1",
|
||||
"@stomp/stompjs": "7.0.0",
|
||||
"@svgr/webpack": "6.3.1",
|
||||
"@tensorflow/tfjs-backend-wasm": "3.13.0",
|
||||
@@ -56,8 +57,10 @@
|
||||
"clipboard-copy": "4.0.1",
|
||||
"clsx": "1.1.1",
|
||||
"dayjs": "1.11.13",
|
||||
"dompurify": "3.2.6",
|
||||
"dropbox": "10.7.0",
|
||||
"focus-visible": "5.1.0",
|
||||
"glob": "11.0.3",
|
||||
"grapheme-splitter": "1.0.4",
|
||||
"i18n-iso-countries": "6.8.0",
|
||||
"i18next": "17.0.6",
|
||||
@@ -69,7 +72,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/v2025.0.0+49eb29a8/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2099.0.0+89536686/lib-jitsi-meet.tgz",
|
||||
"lodash-es": "4.17.21",
|
||||
"null-loader": "4.0.1",
|
||||
"optional-require": "1.0.3",
|
||||
@@ -82,36 +85,36 @@
|
||||
"react-focus-on": "3.8.1",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.75.5",
|
||||
"react-native-background-timer": "2.4.1",
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-device-info": "10.9.0",
|
||||
"react-native": "0.77.2",
|
||||
"react-native-background-timer": "https://github.com/jitsi/react-native-background-timer.git#d180dfaa4486ae3ee17d01242db92cb3195f4718",
|
||||
"react-native-calendar-events": "https://github.com/jitsi/react-native-calendar-events.git#47f068dedfed7c0f72042e093f688eb11624eb7b",
|
||||
"react-native-default-preference": "https://github.com/jitsi/react-native-default-preference.git#c9bf63bdc058e3fa2aa0b87b1ee1af240f44ed02",
|
||||
"react-native-device-info": "12.1.0",
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-gesture-handler": "2.18.1",
|
||||
"react-native-get-random-values": "1.9.0",
|
||||
"react-native-immersive-mode": "2.0.2",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "1.6.0",
|
||||
"react-native-pager-view": "6.4.1",
|
||||
"react-native-gesture-handler": "2.24.0",
|
||||
"react-native-get-random-values": "1.11.0",
|
||||
"react-native-immersive-mode": "https://github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c",
|
||||
"react-native-orientation-locker": "https://github.com/jitsi/react-native-orientation-locker.git#fe095651d819cf134624f786b61fc8667862178a",
|
||||
"react-native-pager-view": "6.8.1",
|
||||
"react-native-paper": "5.10.3",
|
||||
"react-native-performance": "5.0.0",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "3.35.0",
|
||||
"react-native-sound": "0.11.2",
|
||||
"react-native-splash-screen": "3.3.0",
|
||||
"react-native-svg": "13.13.0",
|
||||
"react-native-performance": "5.1.2",
|
||||
"react-native-safe-area-context": "5.5.2",
|
||||
"react-native-screens": "4.11.1",
|
||||
"react-native-sound": "https://github.com/jitsi/react-native-sound.git#ea13c97b5c2a4ff5e0d9bacbd9ff5e4457fe2c3c",
|
||||
"react-native-splash-view": "0.0.18",
|
||||
"react-native-svg": "15.11.2",
|
||||
"react-native-svg-transformer": "1.2.0",
|
||||
"react-native-tab-view": "3.5.2",
|
||||
"react-native-url-polyfill": "2.0.0",
|
||||
"react-native-video": "6.0.0-alpha.11",
|
||||
"react-native-video": "6.13.0",
|
||||
"react-native-watch-connectivity": "1.1.0",
|
||||
"react-native-webrtc": "124.0.4",
|
||||
"react-native-webview": "13.8.7",
|
||||
"react-native-webview": "13.13.5",
|
||||
"react-native-worklets-core": "https://github.com/jitsi/react-native-worklets-core.git#8c5dfab2a5907305da8971696a781b60f0f9cb18",
|
||||
"react-native-youtube-iframe": "2.3.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-textarea-autosize": "8.3.0",
|
||||
"react-virtualized-auto-sizer": "^1.0.26",
|
||||
"react-virtualized-auto-sizer": "1.0.26",
|
||||
"react-window": "1.8.6",
|
||||
"react-youtube": "10.1.0",
|
||||
"redux": "4.0.4",
|
||||
@@ -129,11 +132,17 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.25.9",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.21.0",
|
||||
"@babel/plugin-transform-private-methods": "7.25.9",
|
||||
"@babel/preset-env": "7.25.9",
|
||||
"@babel/preset-react": "7.25.9",
|
||||
"@jitsi/eslint-config": "6.0.4",
|
||||
"@react-native/metro-config": "0.75.5",
|
||||
"@react-native-community/cli": "15.0.1",
|
||||
"@react-native-community/cli-platform-android": "15.0.1",
|
||||
"@react-native-community/cli-platform-ios": "15.0.1",
|
||||
"@react-native/babel-preset": "0.77.2",
|
||||
"@react-native/metro-config": "0.77.2",
|
||||
"@types/amplitude-js": "8.16.5",
|
||||
"@types/audioworklet": "0.0.29",
|
||||
"@types/dom-screen-wake-lock": "1.0.1",
|
||||
@@ -177,7 +186,6 @@
|
||||
"eslint-plugin-typescript-sort-keys": "3.3.0",
|
||||
"jetifier": "1.6.4",
|
||||
"jsonwebtoken": "9.0.2",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"patch-package": "6.4.7",
|
||||
"pretty": "2.0.0",
|
||||
"process": "0.11.10",
|
||||
@@ -209,8 +217,6 @@
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
|
||||
"postinstall": "patch-package --error-on-fail && jetify",
|
||||
"validate": "npm ls",
|
||||
"tsc-test:web": "tsc --project tsconfig.web.json --listFilesOnly | grep -v node_modules | grep native",
|
||||
"tsc-test:native": "tsc --project tsconfig.native.json --listFilesOnly | grep -v node_modules | grep web",
|
||||
"start": "make dev",
|
||||
"test": "DOTENV_CONFIG_PATH=tests/.env wdio run tests/wdio.conf.ts",
|
||||
"test-single": "DOTENV_CONFIG_PATH=tests/.env wdio run tests/wdio.conf.ts --spec",
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
diff --git a/node_modules/@giphy/js-analytics/dist/send-pingback.js b/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
index 989f0ff..52471cb 100644
|
||||
--- a/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
+++ b/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
@@ -10,6 +10,9 @@ var global_1 = __importDefault(require("./global"));
|
||||
var environment = (global_1.default === null || global_1.default === void 0 ? void 0 : global_1.default.GIPHY_PINGBACK_URL) || 'https://pingback.giphy.com';
|
||||
var pingBackUrl = "".concat(environment, "/v2/pingback?apikey=l0HlIwPWyBBUDAUgM");
|
||||
var sendPingback = function (events) {
|
||||
+ // Disabled.
|
||||
+ return Promise.resolve();
|
||||
+
|
||||
var headers = (0, js_util_1.getGiphySDKRequestHeaders)();
|
||||
/* istanbul ignore next */
|
||||
headers === null || headers === void 0 ? void 0 : headers.set('Content-Type', 'application/json');
|
||||
@@ -1,11 +0,0 @@
|
||||
diff --git a/node_modules/@giphy/react-native-sdk/giphy-react-native-sdk.podspec b/node_modules/@giphy/react-native-sdk/giphy-react-native-sdk.podspec
|
||||
index ddd41ac..a7b143e 100644
|
||||
--- a/node_modules/@giphy/react-native-sdk/giphy-react-native-sdk.podspec
|
||||
+++ b/node_modules/@giphy/react-native-sdk/giphy-react-native-sdk.podspec
|
||||
@@ -16,5 +16,5 @@ Pod::Spec.new do |s|
|
||||
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
||||
|
||||
s.dependency "React-Core"
|
||||
- s.dependency "Giphy", "2.2.4"
|
||||
+ s.dependency "Giphy", "2.2.12"
|
||||
end
|
||||
@@ -70,6 +70,7 @@ cd ios && pod install && cd ..
|
||||
## Android
|
||||
|
||||
- In your build.gradle have at least `minSdkVersion = 26`
|
||||
- In your build.gradle have `gradlePluginVersion = "8.4.2"` or higher
|
||||
- In `android/app/src/debug/AndroidManifest.xml` and `android/app/src/main/AndroidManifest.xml`, under the `</application>` tag, include
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath "com.android.tools.build:gradle:$rootProject.ext.gradlePluginVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ def getExtOrIntegerDefault(name) {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'org.jitsi.meet.sdk'
|
||||
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
||||
|
||||
defaultConfig {
|
||||
@@ -46,8 +47,8 @@ android {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,12 +124,11 @@ repositories {
|
||||
|
||||
|
||||
dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
// noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+"
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
// From node_modules
|
||||
// From node_modules
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
JitsiMeetReactNative_kotlinVersion=1.7.0
|
||||
JitsiMeetReactNative_minSdkVersion=21
|
||||
JitsiMeetReactNative_targetSdkVersion=31
|
||||
JitsiMeetReactNative_compileSdkVersion=31
|
||||
JitsiMeetReactNative_ndkversion=21.4.7075529
|
||||
JitsiMeetReactNative_kotlinVersion=2.0.21
|
||||
JitsiMeetReactNative_minSdkVersion=26
|
||||
JitsiMeetReactNative_targetSdkVersion=34
|
||||
JitsiMeetReactNative_compileSdkVersion=34
|
||||
JitsiMeetReactNative_ndkversion=27.1.12297006
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.jitsi.meet.sdk">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -22,7 +22,6 @@ public class JitsiMeetReactNativePackage implements ReactPackage {
|
||||
new AppInfoModule(reactContext),
|
||||
new AudioModeModule(reactContext),
|
||||
new JMOngoingConferenceModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
|
||||
@@ -64,7 +64,8 @@
|
||||
"@react-native-community/netinfo": "0.0.0",
|
||||
"@react-native-community/slider": "0.0.0",
|
||||
"@react-native-google-signin/google-signin": "0.0.0",
|
||||
"react-native": "*",
|
||||
"@sayem314/react-native-keep-awake": "0.0.0",
|
||||
"react-native": "0.0.0",
|
||||
"react": "*",
|
||||
"react-native-background-timer": "0.0.0",
|
||||
"react-native-calendar-events": "0.0.0",
|
||||
@@ -73,19 +74,23 @@
|
||||
"react-native-get-random-values": "0.0.0",
|
||||
"react-native-gesture-handler": "0.0.0",
|
||||
"react-native-immersive-mode": "0.0.0",
|
||||
"react-native-keep-awake": "0.0.0",
|
||||
"react-native-pager-view": "0.0.0",
|
||||
"react-native-performance": "0.0.0",
|
||||
"react-native-orientation-locker": "0.0.0",
|
||||
"react-native-safe-area-context": "0.0.0",
|
||||
"react-native-screens": "0.0.0",
|
||||
"react-native-sound": "0.0.0",
|
||||
"react-native-splash-screen": "0.0.0",
|
||||
"react-native-splash-view": "0.0.0",
|
||||
"react-native-svg": "0.0.0",
|
||||
"react-native-video": "0.0.0",
|
||||
"react-native-watch-connectivity": "0.0.0",
|
||||
"react-native-webrtc": "0.0.0",
|
||||
"react-native-webview": "0.0.0"
|
||||
"react-native-webview": "0.0.0",
|
||||
"react-native-worklets-core": "0.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "0.0.0",
|
||||
"@babel/plugin-proposal-optional-chaining": "0.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node sdk_instructions.js",
|
||||
|
||||
8
react-native-sdk/prepare_sdk.js
vendored
8
react-native-sdk/prepare_sdk.js
vendored
@@ -100,10 +100,6 @@ fs.copyFileSync(
|
||||
`${iosSrcPath}/InfoPlistUtil.h`,
|
||||
`${iosDestPath}/InfoPlistUtil.h`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JavaScriptSandbox.m`,
|
||||
`${iosDestPath}/JavaScriptSandbox.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JitsiAudioSession.m`,
|
||||
`${iosDestPath}/JitsiAudioSession.m`
|
||||
@@ -184,10 +180,6 @@ fs.copyFileSync(
|
||||
`${androidSourcePath}/ConnectionService.java`,
|
||||
`${androidTargetPath}/ConnectionService.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/JavaScriptSandboxModule.java`,
|
||||
`${androidTargetPath}/JavaScriptSandboxModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/LocaleDetector.java`,
|
||||
`${androidTargetPath}/LocaleDetector.java`
|
||||
|
||||
18
react-native-sdk/update_dependencies.js
vendored
18
react-native-sdk/update_dependencies.js
vendored
@@ -60,12 +60,12 @@ This is now set on your end.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
packageJSON.devDependencies = packageJSON.devDependencies || {};
|
||||
|
||||
packageJSON.overrides = packageJSON.overrides || {};
|
||||
|
||||
for (const key in RNSDKpackageJSON.overrides) {
|
||||
if (!packageJSON.overrides.hasOwnProperty(key)) {
|
||||
packageJSON.overrides[key] = RNSDKpackageJSON.overrides[key];
|
||||
for (const key in RNSDKpackageJSON.devDependencies) {
|
||||
if (!packageJSON.devDependencies.hasOwnProperty(key)) {
|
||||
packageJSON.devDependencies[key] = RNSDKpackageJSON.devDependencies[key];
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,14 @@ This is now set on your end.`
|
||||
|
||||
return item;
|
||||
}, {});
|
||||
|
||||
packageJSON.devDependencies = Object.keys(packageJSON.devDependencies)
|
||||
.sort()
|
||||
.reduce((item, itemKey) => {
|
||||
item[itemKey] = packageJSON.devDependencies[itemKey];
|
||||
|
||||
return item;
|
||||
}, {});
|
||||
|
||||
fs.writeFileSync(pathToPackageJSON, JSON.stringify(packageJSON, null, 2));
|
||||
|
||||
|
||||
7
react-native-sdk/update_sdk_dependencies.js
vendored
7
react-native-sdk/update_sdk_dependencies.js
vendored
@@ -26,6 +26,13 @@ function mergeDependencyVersions() {
|
||||
SDKPackageJSON.peerDependencies[key] = packageJSON.dependencies[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Updates SDK dev dependencies(used by react-native-worklets-core lib. babel plugin)
|
||||
for (const key in packageJSON.devDependencies) {
|
||||
if (SDKPackageJSON.devDependencies.hasOwnProperty(key)) {
|
||||
SDKPackageJSON.devDependencies[key] = packageJSON.devDependencies[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Set RN peer dependency.
|
||||
const rnVersion = semver.parse(packageJSON.dependencies['react-native']);
|
||||
|
||||
@@ -63,6 +63,11 @@ export const ACTION_SHORTCUT_TRIGGERED = 'triggered';
|
||||
*/
|
||||
export const AUDIO_MUTE = 'audio.mute';
|
||||
|
||||
/**
|
||||
* The name of the keyboard shortcut or toolbar button for muting desktop sharing.
|
||||
*/
|
||||
export const DESKTOP_MUTE = 'desktop.mute';
|
||||
|
||||
/**
|
||||
* The name of the keyboard shortcut or toolbar button for muting video.
|
||||
*/
|
||||
|
||||
@@ -84,7 +84,6 @@ export async function createHandlers({ getState }: IStore) {
|
||||
} = config;
|
||||
const {
|
||||
amplitudeAPPKey,
|
||||
amplitudeIncludeUTM,
|
||||
blackListedEvents,
|
||||
scriptURLs,
|
||||
matomoEndpoint,
|
||||
@@ -94,7 +93,6 @@ export async function createHandlers({ getState }: IStore) {
|
||||
const { group, user } = state['features/base/jwt'];
|
||||
const handlerConstructorOptions = {
|
||||
amplitudeAPPKey,
|
||||
amplitudeIncludeUTM,
|
||||
blackListedEvents,
|
||||
envType: deploymentInfo?.envType || 'dev',
|
||||
matomoEndpoint,
|
||||
|
||||
@@ -11,7 +11,6 @@ export interface IEvent {
|
||||
|
||||
interface IOptions {
|
||||
amplitudeAPPKey?: string;
|
||||
amplitudeIncludeUTM?: boolean;
|
||||
blackListedEvents?: string[];
|
||||
envType?: string;
|
||||
group?: string;
|
||||
|
||||
@@ -4,7 +4,7 @@ import logger from '../logger';
|
||||
|
||||
import AbstractHandler, { IEvent } from './AbstractHandler';
|
||||
import { fixDeviceID } from './amplitude/fixDeviceID';
|
||||
import amplitude from './amplitude/lib';
|
||||
import amplitude, { initAmplitude } from './amplitude/lib';
|
||||
|
||||
/**
|
||||
* Analytics handler for Amplitude.
|
||||
@@ -15,8 +15,7 @@ export default class AmplitudeHandler extends AbstractHandler {
|
||||
* Creates new instance of the Amplitude analytics handler.
|
||||
*
|
||||
* @param {Object} options - The amplitude options.
|
||||
* @param {string} options.amplitudeAPPKey - The Amplitude app key required by the Amplitude API.
|
||||
* @param {boolean} options.amplitudeIncludeUTM - Whether to include UTM parameters
|
||||
* @param {string} options.amplitudeAPPKey - The Amplitude app key required by the Amplitude API
|
||||
* in the Amplitude events.
|
||||
*/
|
||||
constructor(options: any) {
|
||||
@@ -24,47 +23,26 @@ export default class AmplitudeHandler extends AbstractHandler {
|
||||
|
||||
const {
|
||||
amplitudeAPPKey,
|
||||
amplitudeIncludeUTM: includeUtm = true,
|
||||
user
|
||||
} = options;
|
||||
|
||||
this._enabled = true;
|
||||
|
||||
const onError = (e: Error) => {
|
||||
logger.error('Error initializing Amplitude', e);
|
||||
this._enabled = false;
|
||||
};
|
||||
|
||||
// Forces sending all events on exit (flushing) via sendBeacon
|
||||
const onExitPage = () => {
|
||||
amplitude.flush();
|
||||
};
|
||||
|
||||
if (navigator.product === 'ReactNative') {
|
||||
amplitude.init(amplitudeAPPKey);
|
||||
fixDeviceID(amplitude);
|
||||
} else {
|
||||
const amplitudeOptions: any = {
|
||||
includeReferrer: true,
|
||||
includeUtm,
|
||||
saveParamsReferrerOncePerSession: false,
|
||||
onError,
|
||||
onExitPage
|
||||
};
|
||||
|
||||
amplitude.init(amplitudeAPPKey, undefined, amplitudeOptions);
|
||||
fixDeviceID(amplitude);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
amplitude.setUserId(user);
|
||||
}
|
||||
initAmplitude(amplitudeAPPKey, user)
|
||||
.then(() => {
|
||||
logger.info('Amplitude initialized');
|
||||
fixDeviceID(amplitude);
|
||||
})
|
||||
.catch(e => {
|
||||
logger.error('Error initializing Amplitude', e);
|
||||
this._enabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Amplitude user properties.
|
||||
*
|
||||
* @param {Object} userProps - The user portperties.
|
||||
* @param {Object} userProps - The user properties.
|
||||
* @returns {void}
|
||||
*/
|
||||
setUserProperties(userProps: any) {
|
||||
@@ -95,7 +73,7 @@ export default class AmplitudeHandler extends AbstractHandler {
|
||||
|
||||
const eventName = this._extractName(event) ?? '';
|
||||
|
||||
amplitude.logEvent(eventName, event);
|
||||
amplitude.track(eventName, event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,3 +35,12 @@ export function fixDeviceID(amplitude: Types.BrowserClient) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amplitude shared deviceId.
|
||||
*
|
||||
* @returns {string} - The amplitude deviceId.
|
||||
*/
|
||||
export function getDeviceID() {
|
||||
return jitsiLocalStorage.getItem(DEVICE_ID_KEY);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
import { createInstance } from '@amplitude/analytics-react-native';
|
||||
import amplitude from '@amplitude/analytics-react-native';
|
||||
|
||||
export default createInstance();
|
||||
export default amplitude;
|
||||
|
||||
/**
|
||||
* Initializes the Amplitude instance.
|
||||
*
|
||||
* @param {string} amplitudeAPPKey - The Amplitude app key.
|
||||
* @param {string | undefined} user - The user ID.
|
||||
* @returns {Promise} The initialized Amplitude instance.
|
||||
*/
|
||||
export function initAmplitude(
|
||||
amplitudeAPPKey: string, user: string | undefined): Promise<unknown> {
|
||||
return amplitude.init(amplitudeAPPKey, user, {}).promise;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
import { createInstance } from '@amplitude/analytics-browser';
|
||||
|
||||
export default createInstance();
|
||||
const amplitude = createInstance();
|
||||
|
||||
export default amplitude;
|
||||
|
||||
/**
|
||||
* Initializes the Amplitude instance.
|
||||
*
|
||||
* @param {string} amplitudeAPPKey - The Amplitude app key.
|
||||
* @param {string | undefined} user - The user ID.
|
||||
* @returns {Promise} The initialized Amplitude instance.
|
||||
*/
|
||||
export function initAmplitude(
|
||||
amplitudeAPPKey: string, user: string | undefined): Promise<unknown> {
|
||||
|
||||
// Forces sending all events on exit (flushing) via sendBeacon.
|
||||
window.addEventListener('pagehide', () => {
|
||||
// Set https transport to use sendBeacon API.
|
||||
amplitude.setTransport('beacon');
|
||||
// Send all pending events to server.
|
||||
amplitude.flush();
|
||||
});
|
||||
|
||||
const options = {
|
||||
autocapture: {
|
||||
attribution: true,
|
||||
pageViews: true,
|
||||
sessions: false,
|
||||
fileDownloads: false,
|
||||
formInteractions: false,
|
||||
elementInteractions: false
|
||||
},
|
||||
defaultTracking: false
|
||||
};
|
||||
|
||||
return amplitude.init(amplitudeAPPKey, user, options).promise;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/analytics');
|
||||
export default getLogger('app:analytics');
|
||||
|
||||
@@ -2,7 +2,8 @@ import React, { ComponentType } from 'react';
|
||||
import { NativeModules, Platform, StyleSheet, View } from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import SplashScreen from 'react-native-splash-screen';
|
||||
// @ts-ignore
|
||||
import { hideSplash } from 'react-native-splash-view';
|
||||
|
||||
import BottomSheetContainer from '../../base/dialog/components/native/BottomSheetContainer';
|
||||
import DialogContainer from '../../base/dialog/components/native/DialogContainer';
|
||||
@@ -84,7 +85,7 @@ export class App extends AbstractApp<IProps> {
|
||||
override async componentDidMount() {
|
||||
await super.componentDidMount();
|
||||
|
||||
SplashScreen.hide();
|
||||
hideSplash();
|
||||
|
||||
const liteTxt = AppInfo.isLiteSDK ? ' (lite)' : '';
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { IStateful } from '../base/app/types';
|
||||
import { toState } from '../base/redux/functions';
|
||||
import { getServerURL } from '../base/settings/functions.web';
|
||||
import { getJitsiMeetGlobalNS } from '../base/util/helpers';
|
||||
|
||||
export * from './functions.any';
|
||||
import logger from './logger';
|
||||
|
||||
/**
|
||||
* Retrieves the default URL for the app. This can either come from a prop to
|
||||
@@ -31,3 +33,27 @@ export function getDefaultURL(stateful: IStateful) {
|
||||
export function getName() {
|
||||
return interfaceConfig.APP_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a handler function after the window load event has been received.
|
||||
* If the app has already loaded, the handler is executed immediately.
|
||||
* Otherwise, the handler is registered as a 'load' event listener.
|
||||
*
|
||||
* @param {Function} handler - The callback function to execute.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function executeAfterLoad(handler: () => void) {
|
||||
const safeHandler = () => {
|
||||
try {
|
||||
handler();
|
||||
} catch (error) {
|
||||
logger.error('Error executing handler after load:', error);
|
||||
}
|
||||
};
|
||||
|
||||
if (getJitsiMeetGlobalNS()?.hasLoaded) {
|
||||
safeHandler();
|
||||
} else {
|
||||
window.addEventListener('load', safeHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/app');
|
||||
export default getLogger('app:core');
|
||||
|
||||
@@ -24,7 +24,6 @@ import '../calendar-sync/middleware';
|
||||
import '../chat/middleware';
|
||||
import '../conference/middleware';
|
||||
import '../connection-indicator/middleware';
|
||||
import '../deep-linking/middleware';
|
||||
import '../device-selection/middleware';
|
||||
import '../display-name/middleware';
|
||||
import '../dynamic-branding/middleware';
|
||||
|
||||
@@ -2,6 +2,7 @@ import '../base/app/middleware';
|
||||
import '../base/connection/middleware';
|
||||
import '../base/devices/middleware';
|
||||
import '../base/media/middleware';
|
||||
import '../deep-linking/middleware.web';
|
||||
import '../dynamic-branding/middleware';
|
||||
import '../e2ee/middleware';
|
||||
import '../external-api/middleware';
|
||||
|
||||
@@ -46,6 +46,15 @@ export const SET_TOKEN_AUTH_URL_SUCCESS = 'SET_TOKEN_AUTH_URL_SUCCESS';
|
||||
*/
|
||||
export const STOP_WAIT_FOR_OWNER = 'STOP_WAIT_FOR_OWNER';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which disables moderator login.
|
||||
*
|
||||
* {
|
||||
* type: DISABLE_MODERATOR_LOGIN
|
||||
* }
|
||||
*/
|
||||
export const DISABLE_MODERATOR_LOGIN = 'DISABLE_MODERATOR_LOGIN';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which informs that the authentication and role
|
||||
* upgrade process has finished either with success or with a specific error.
|
||||
@@ -74,6 +83,15 @@ export const UPGRADE_ROLE_FINISHED = 'UPGRADE_ROLE_FINISHED';
|
||||
*/
|
||||
export const UPGRADE_ROLE_STARTED = 'UPGRADE_ROLE_STARTED';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which enables moderator login.
|
||||
*
|
||||
* {
|
||||
* type: ENABLE_MODERATOR_LOGIN
|
||||
* }
|
||||
*/
|
||||
export const ENABLE_MODERATOR_LOGIN = 'ENABLE_MODERATOR_LOGIN';
|
||||
|
||||
/**
|
||||
* The type of (redux) action that sets delayed handler which will check if
|
||||
* the conference has been created and it's now possible to join from anonymous
|
||||
|
||||
@@ -4,12 +4,15 @@ import { IJitsiConference } from '../base/conference/reducer';
|
||||
import { hideDialog, openDialog } from '../base/dialog/actions';
|
||||
|
||||
import {
|
||||
DISABLE_MODERATOR_LOGIN,
|
||||
ENABLE_MODERATOR_LOGIN,
|
||||
LOGIN,
|
||||
LOGOUT,
|
||||
SET_TOKEN_AUTH_URL_SUCCESS,
|
||||
STOP_WAIT_FOR_OWNER,
|
||||
UPGRADE_ROLE_FINISHED,
|
||||
UPGRADE_ROLE_STARTED, WAIT_FOR_OWNER
|
||||
UPGRADE_ROLE_STARTED,
|
||||
WAIT_FOR_OWNER
|
||||
} from './actionTypes';
|
||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||
import logger from './logger';
|
||||
@@ -165,6 +168,30 @@ export function logout() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables moderator login.
|
||||
*
|
||||
* @returns {{
|
||||
* type: DISABLE_MODERATOR_LOGIN
|
||||
* }}
|
||||
*/
|
||||
export function disableModeratorLogin() {
|
||||
return {
|
||||
type: DISABLE_MODERATOR_LOGIN
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables moderator login.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function enableModeratorLogin() {
|
||||
return {
|
||||
type: ENABLE_MODERATOR_LOGIN
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens {@link WaitForOnwerDialog}.
|
||||
*
|
||||
@@ -175,6 +202,7 @@ export function openWaitForOwnerDialog() {
|
||||
return openDialog(WaitForOwnerDialog);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stops waiting for the conference owner.
|
||||
*
|
||||
|
||||
@@ -67,7 +67,7 @@ class WaitForOwnerDialog extends Component<IProps> {
|
||||
<ConfirmDialog
|
||||
cancelLabel = { this.props._alternativeCancelText ? 'dialog.WaitingForHostButton' : 'dialog.Cancel' }
|
||||
confirmLabel = 'dialog.IamHost'
|
||||
descriptionKey = 'dialog.WaitForHostMsg'
|
||||
descriptionKey = 'lobby.waitForModerator'
|
||||
isConfirmHidden = { _isConfirmHidden }
|
||||
onCancel = { this._onCancel }
|
||||
onSubmit = { this._onLogin } />
|
||||
|
||||
@@ -91,7 +91,7 @@ class WaitForOwnerDialog extends PureComponent<IProps> {
|
||||
onSubmit = { this._onIAmHost }
|
||||
titleKey = { t('dialog.WaitingForHostTitle') }>
|
||||
<span>
|
||||
{ this.props._hideLoginButton ? t('dialog.WaitForHostNoAuthMsg') : t('dialog.WaitForHostMsg') }
|
||||
{ this.props._hideLoginButton ? t('dialog.WaitForHostNoAuthMsg') : t('lobby.waitForModerator') }
|
||||
</span>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/authentication');
|
||||
export default getLogger('app:authentication');
|
||||
|
||||
@@ -28,6 +28,8 @@ import {
|
||||
WAIT_FOR_OWNER
|
||||
} from './actionTypes';
|
||||
import {
|
||||
disableModeratorLogin,
|
||||
enableModeratorLogin,
|
||||
hideLoginDialog,
|
||||
openLoginDialog,
|
||||
openTokenAuthUrl,
|
||||
@@ -44,7 +46,7 @@ import logger from './logger';
|
||||
|
||||
/**
|
||||
* Middleware that captures connection or conference failed errors and controls
|
||||
* {@link WaitForOwnerDialog} and {@link LoginDialog}.
|
||||
* moderator login availability and {@link LoginDialog}.
|
||||
*
|
||||
* FIXME Some of the complexity was introduced by the lack of dialog stacking.
|
||||
*
|
||||
@@ -105,11 +107,21 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
}
|
||||
recoverable = error.recoverable;
|
||||
}
|
||||
if (recoverable) {
|
||||
store.dispatch(waitForOwner());
|
||||
} else {
|
||||
store.dispatch(stopWaitForOwner());
|
||||
|
||||
if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR && lobbyWaitingForHost) {
|
||||
if (recoverable) {
|
||||
store.dispatch(enableModeratorLogin());
|
||||
} else {
|
||||
store.dispatch(disableModeratorLogin());
|
||||
}
|
||||
} else if (error.name === JitsiConferenceErrors.AUTHENTICATION_REQUIRED) {
|
||||
if (recoverable) {
|
||||
store.dispatch(waitForOwner());
|
||||
} else {
|
||||
store.dispatch(stopWaitForOwner());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -126,6 +138,9 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
dispatch(setTokenAuthUrlSuccess(true));
|
||||
}
|
||||
|
||||
if (_isWaitingForModerator(store)) {
|
||||
store.dispatch(disableModeratorLogin());
|
||||
}
|
||||
if (_isWaitingForOwner(store)) {
|
||||
store.dispatch(stopWaitForOwner());
|
||||
}
|
||||
@@ -134,6 +149,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
}
|
||||
|
||||
case CONFERENCE_LEFT:
|
||||
store.dispatch(disableModeratorLogin());
|
||||
store.dispatch(stopWaitForOwner());
|
||||
break;
|
||||
|
||||
@@ -236,7 +252,6 @@ function _clearExistingWaitForOwnerTimeout({ getState }: IStore) {
|
||||
waitForOwnerTimeoutID && clearTimeout(waitForOwnerTimeoutID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the cyclic "wait for conference owner" task is currently scheduled.
|
||||
*
|
||||
@@ -247,6 +262,16 @@ function _isWaitingForOwner({ getState }: IStore) {
|
||||
return Boolean(getState()['features/authentication'].waitForOwnerTimeoutID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the cyclic "wait for moderator" task is currently scheduled.
|
||||
*
|
||||
* @param {Object} store - The redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function _isWaitingForModerator({ getState }: IStore) {
|
||||
return getState()['features/authentication'].showModeratorLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles login challenge. Opens login dialog or redirects to token auth URL.
|
||||
*
|
||||
|
||||
@@ -4,6 +4,8 @@ import { assign } from '../base/redux/functions';
|
||||
|
||||
import {
|
||||
CANCEL_LOGIN,
|
||||
DISABLE_MODERATOR_LOGIN,
|
||||
ENABLE_MODERATOR_LOGIN,
|
||||
SET_TOKEN_AUTH_URL_SUCCESS,
|
||||
STOP_WAIT_FOR_OWNER,
|
||||
UPGRADE_ROLE_FINISHED,
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
export interface IAuthenticationState {
|
||||
error?: Object | undefined;
|
||||
progress?: number | undefined;
|
||||
showModeratorLogin?: boolean;
|
||||
thenableWithCancel?: {
|
||||
cancel: Function;
|
||||
};
|
||||
@@ -45,6 +48,11 @@ ReducerRegistry.register<IAuthenticationState>('features/authentication',
|
||||
progress: undefined,
|
||||
thenableWithCancel: undefined
|
||||
});
|
||||
case ENABLE_MODERATOR_LOGIN:
|
||||
return assign(state, {
|
||||
showModeratorLogin: true
|
||||
});
|
||||
|
||||
case SET_TOKEN_AUTH_URL_SUCCESS:
|
||||
return assign(state, {
|
||||
tokenAuthUrlSuccessful: action.value
|
||||
@@ -56,6 +64,12 @@ ReducerRegistry.register<IAuthenticationState>('features/authentication',
|
||||
waitForOwnerTimeoutID: undefined
|
||||
});
|
||||
|
||||
case DISABLE_MODERATOR_LOGIN:
|
||||
return assign(state, {
|
||||
error: undefined,
|
||||
showModeratorLogin: false
|
||||
});
|
||||
|
||||
case UPGRADE_ROLE_FINISHED: {
|
||||
let { thenableWithCancel } = action;
|
||||
|
||||
|
||||
@@ -37,6 +37,15 @@ export const ENABLE_MODERATION = 'ENABLE_MODERATION';
|
||||
*/
|
||||
export const REQUEST_DISABLE_AUDIO_MODERATION = 'REQUEST_DISABLE_AUDIO_MODERATION';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that Desktop Moderation disable has been requested.
|
||||
*
|
||||
* {
|
||||
* type: REQUEST_DISABLE_DESKTOP_MODERATION
|
||||
* }
|
||||
*/
|
||||
export const REQUEST_DISABLE_DESKTOP_MODERATION = 'REQUEST_DISABLE_DESKTOP_MODERATION';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that Video Moderation disable has been requested.
|
||||
*
|
||||
@@ -55,6 +64,15 @@ export const REQUEST_DISABLE_VIDEO_MODERATION = 'REQUEST_DISABLE_VIDEO_MODERATIO
|
||||
*/
|
||||
export const REQUEST_ENABLE_AUDIO_MODERATION = 'REQUEST_ENABLE_AUDIO_MODERATION';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that Desktop Moderation enable has been requested.
|
||||
*
|
||||
* {
|
||||
* type: REQUEST_ENABLE_DESKTOP_MODERATION
|
||||
* }
|
||||
*/
|
||||
export const REQUEST_ENABLE_DESKTOP_MODERATION = 'REQUEST_ENABLE_DESKTOP_MODERATION';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that Video Moderation enable has been requested.
|
||||
*
|
||||
@@ -117,7 +135,7 @@ export const PARTICIPANT_REJECTED = 'PARTICIPANT_REJECTED';
|
||||
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that a participant asked to have its audio umuted.
|
||||
* The type of (redux) action which signals that a participant asked to have its audio unmuted.
|
||||
*
|
||||
* {
|
||||
* type: PARTICIPANT_PENDING_AUDIO
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { batch } from 'react-redux';
|
||||
|
||||
import { IStore } from '../app/types';
|
||||
import { getConferenceState } from '../base/conference/functions';
|
||||
import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
|
||||
import { getParticipantById, isParticipantModerator } from '../base/participants/functions';
|
||||
import { IParticipant } from '../base/participants/types';
|
||||
import { isForceMuted } from '../participants-pane/functions';
|
||||
|
||||
import {
|
||||
DISABLE_MODERATION,
|
||||
@@ -16,11 +16,14 @@ import {
|
||||
PARTICIPANT_PENDING_AUDIO,
|
||||
PARTICIPANT_REJECTED,
|
||||
REQUEST_DISABLE_AUDIO_MODERATION,
|
||||
REQUEST_DISABLE_DESKTOP_MODERATION,
|
||||
REQUEST_DISABLE_VIDEO_MODERATION,
|
||||
REQUEST_ENABLE_AUDIO_MODERATION,
|
||||
REQUEST_ENABLE_DESKTOP_MODERATION,
|
||||
REQUEST_ENABLE_VIDEO_MODERATION
|
||||
} from './actionTypes';
|
||||
import { isEnabledFromState } from './functions';
|
||||
import { MEDIA_TYPE, type MediaType } from './constants';
|
||||
import { isEnabledFromState, isForceMuted } from './functions';
|
||||
|
||||
/**
|
||||
* Action used by moderator to approve audio for a participant.
|
||||
@@ -42,6 +45,25 @@ export const approveParticipantAudio = (id: string) => (dispatch: IStore['dispat
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Action used by moderator to approve desktop for a participant.
|
||||
*
|
||||
* @param {staring} id - The id of the participant to be approved.
|
||||
* @returns {void}
|
||||
*/
|
||||
export const approveParticipantDesktop = (id: string) => (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState();
|
||||
const { conference } = getConferenceState(state);
|
||||
const participant = getParticipantById(state, id);
|
||||
|
||||
const isDesktopForceMuted = isForceMuted(participant, MEDIA_TYPE.DESKTOP, state);
|
||||
const isDesktopModerationOn = isEnabledFromState(MEDIA_TYPE.DESKTOP, state);
|
||||
|
||||
if (isDesktopModerationOn && isDesktopForceMuted) {
|
||||
conference?.avModerationApprove(MEDIA_TYPE.DESKTOP, id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Action used by moderator to approve video for a participant.
|
||||
*
|
||||
@@ -68,8 +90,11 @@ export const approveParticipantVideo = (id: string) => (dispatch: IStore['dispat
|
||||
* @returns {void}
|
||||
*/
|
||||
export const approveParticipant = (id: string) => (dispatch: IStore['dispatch']) => {
|
||||
dispatch(approveParticipantAudio(id));
|
||||
dispatch(approveParticipantVideo(id));
|
||||
batch(() => {
|
||||
dispatch(approveParticipantAudio(id));
|
||||
dispatch(approveParticipantDesktop(id));
|
||||
dispatch(approveParticipantVideo(id));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -92,6 +117,26 @@ export const rejectParticipantAudio = (id: string) => (dispatch: IStore['dispatc
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Action used by moderator to reject desktop for a participant.
|
||||
*
|
||||
* @param {staring} id - The id of the participant to be rejected.
|
||||
* @returns {void}
|
||||
*/
|
||||
export const rejectParticipantDesktop = (id: string) => (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState();
|
||||
const { conference } = getConferenceState(state);
|
||||
const desktopModeration = isEnabledFromState(MEDIA_TYPE.DESKTOP, state);
|
||||
|
||||
const participant = getParticipantById(state, id);
|
||||
const isDesktopForceMuted = isForceMuted(participant, MEDIA_TYPE.DESKTOP, state);
|
||||
const isModerator = isParticipantModerator(participant);
|
||||
|
||||
if (desktopModeration && !isDesktopForceMuted && !isModerator) {
|
||||
conference?.avModerationReject(MEDIA_TYPE.DESKTOP, id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Action used by moderator to reject video for a participant.
|
||||
*
|
||||
@@ -185,6 +230,19 @@ export const requestDisableAudioModeration = () => {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests disable of video moderation.
|
||||
*
|
||||
* @returns {{
|
||||
* type: REQUEST_DISABLE_DESKTOP_MODERATION
|
||||
* }}
|
||||
*/
|
||||
export const requestDisableDesktopModeration = () => {
|
||||
return {
|
||||
type: REQUEST_DISABLE_DESKTOP_MODERATION
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests disable of video moderation.
|
||||
*
|
||||
@@ -211,6 +269,19 @@ export const requestEnableAudioModeration = () => {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests enable of video moderation.
|
||||
*
|
||||
* @returns {{
|
||||
* type: REQUEST_ENABLE_DESKTOP_MODERATION
|
||||
* }}
|
||||
*/
|
||||
export const requestEnableDesktopModeration = () => {
|
||||
return {
|
||||
type: REQUEST_ENABLE_DESKTOP_MODERATION
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests enable of video moderation.
|
||||
*
|
||||
@@ -313,4 +384,3 @@ export function participantRejected(id: string, mediaType: MediaType) {
|
||||
mediaType
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
import { MEDIA_TYPE } from '../base/media/constants';
|
||||
export type MediaType = 'audio' | 'video' | 'desktop';
|
||||
|
||||
/**
|
||||
* Mapping between a media type and the witelist reducer key.
|
||||
* The set of media types for AV moderation.
|
||||
*
|
||||
* @enum {string}
|
||||
*/
|
||||
export const MEDIA_TYPE: {
|
||||
AUDIO: MediaType;
|
||||
DESKTOP: MediaType;
|
||||
VIDEO: MediaType;
|
||||
} = {
|
||||
AUDIO: 'audio',
|
||||
DESKTOP: 'desktop',
|
||||
VIDEO: 'video'
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping between a media type and the whitelist reducer key.
|
||||
*/
|
||||
export const MEDIA_TYPE_TO_WHITELIST_STORE_KEY: { [key: string]: string; } = {
|
||||
[MEDIA_TYPE.AUDIO]: 'audioWhitelist',
|
||||
[MEDIA_TYPE.DESKTOP]: 'desktopWhitelist',
|
||||
[MEDIA_TYPE.VIDEO]: 'videoWhitelist'
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping between a media type and the pending reducer key.
|
||||
*/
|
||||
export const MEDIA_TYPE_TO_PENDING_STORE_KEY: { [key: string]: 'pendingAudio' | 'pendingVideo'; } = {
|
||||
export const MEDIA_TYPE_TO_PENDING_STORE_KEY: { [key: string]: 'pendingAudio' | 'pendingDesktop' | 'pendingVideo'; } = {
|
||||
[MEDIA_TYPE.AUDIO]: 'pendingAudio',
|
||||
[MEDIA_TYPE.DESKTOP]: 'pendingDesktop',
|
||||
[MEDIA_TYPE.VIDEO]: 'pendingVideo'
|
||||
};
|
||||
|
||||
@@ -20,11 +37,15 @@ export const ASKED_TO_UNMUTE_NOTIFICATION_ID = 'asked-to-unmute';
|
||||
export const ASKED_TO_UNMUTE_SOUND_ID = 'ASKED_TO_UNMUTE_SOUND';
|
||||
|
||||
export const AUDIO_MODERATION_NOTIFICATION_ID = 'audio-moderation';
|
||||
export const DESKTOP_MODERATION_NOTIFICATION_ID = 'desktop-moderation';
|
||||
export const VIDEO_MODERATION_NOTIFICATION_ID = 'video-moderation';
|
||||
export const CS_MODERATION_NOTIFICATION_ID = 'screensharing-moderation';
|
||||
|
||||
export const AUDIO_RAISED_HAND_NOTIFICATION_ID = 'raise-hand-audio';
|
||||
export const DESKTOP_RAISED_HAND_NOTIFICATION_ID = 'raise-hand-desktop';
|
||||
export const VIDEO_RAISED_HAND_NOTIFICATION_ID = 'raise-hand-video';
|
||||
|
||||
export const MODERATION_NOTIFICATIONS = {
|
||||
[MEDIA_TYPE.AUDIO]: AUDIO_MODERATION_NOTIFICATION_ID,
|
||||
[MEDIA_TYPE.SCREENSHARE]: CS_MODERATION_NOTIFICATION_ID,
|
||||
[MEDIA_TYPE.DESKTOP]: DESKTOP_MODERATION_NOTIFICATION_ID,
|
||||
[MEDIA_TYPE.VIDEO]: VIDEO_MODERATION_NOTIFICATION_ID
|
||||
};
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { IReduxState } from '../app/types';
|
||||
import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
|
||||
import { isLocalParticipantModerator } from '../base/participants/functions';
|
||||
import { isLocalParticipantModerator, isParticipantModerator } from '../base/participants/functions';
|
||||
import { IParticipant } from '../base/participants/types';
|
||||
import { isInBreakoutRoom } from '../breakout-rooms/functions';
|
||||
|
||||
import { MEDIA_TYPE_TO_PENDING_STORE_KEY, MEDIA_TYPE_TO_WHITELIST_STORE_KEY } from './constants';
|
||||
import {
|
||||
MEDIA_TYPE,
|
||||
MEDIA_TYPE_TO_PENDING_STORE_KEY,
|
||||
MEDIA_TYPE_TO_WHITELIST_STORE_KEY,
|
||||
MediaType
|
||||
} from './constants';
|
||||
|
||||
/**
|
||||
* Returns this feature's root state.
|
||||
@@ -29,10 +33,18 @@ const EMPTY_ARRAY: any[] = [];
|
||||
* @param {IReduxState} state - Global state.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isEnabledFromState = (mediaType: MediaType, state: IReduxState) =>
|
||||
(mediaType === MEDIA_TYPE.AUDIO
|
||||
? getState(state)?.audioModerationEnabled
|
||||
: getState(state)?.videoModerationEnabled) === true;
|
||||
export const isEnabledFromState = (mediaType: MediaType, state: IReduxState) => {
|
||||
switch (mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
return getState(state)?.audioModerationEnabled === true;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
return getState(state)?.desktopModerationEnabled === true;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
return getState(state)?.videoModerationEnabled === true;
|
||||
default:
|
||||
throw new Error(`Unknown media type: ${mediaType}`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether moderation is enabled per media type.
|
||||
@@ -61,11 +73,20 @@ export const isSupported = () => (state: IReduxState) => {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isLocalParticipantApprovedFromState = (mediaType: MediaType, state: IReduxState) => {
|
||||
const approved = (mediaType === MEDIA_TYPE.AUDIO
|
||||
? getState(state).audioUnmuteApproved
|
||||
: getState(state).videoUnmuteApproved) === true;
|
||||
if (isLocalParticipantModerator(state)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return approved || isLocalParticipantModerator(state);
|
||||
switch (mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
return getState(state).audioUnmuteApproved === true;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
return getState(state).desktopUnmuteApproved === true;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
return getState(state).videoUnmuteApproved === true;
|
||||
default:
|
||||
throw new Error(`Unknown media type: ${mediaType}`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -134,3 +155,28 @@ export const getParticipantsAskingToAudioUnmute = (state: IReduxState) => {
|
||||
export const shouldShowModeratedNotification = (mediaType: MediaType, state: IReduxState) =>
|
||||
isEnabledFromState(mediaType, state)
|
||||
&& !isLocalParticipantApprovedFromState(mediaType, state);
|
||||
|
||||
/**
|
||||
* Checks if a participant is force muted.
|
||||
*
|
||||
* @param {IParticipant|undefined} participant - The participant.
|
||||
* @param {MediaType} mediaType - The media type.
|
||||
* @param {IReduxState} state - The redux state.
|
||||
* @returns {MediaState}
|
||||
*/
|
||||
export function isForceMuted(participant: IParticipant | undefined, mediaType: MediaType, state: IReduxState) {
|
||||
if (isEnabledFromState(mediaType, state)) {
|
||||
if (participant?.local) {
|
||||
return !isLocalParticipantApprovedFromState(mediaType, state);
|
||||
}
|
||||
|
||||
// moderators cannot be force muted
|
||||
if (isParticipantModerator(participant)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !isParticipantApproved(participant?.id ?? '', mediaType)(state);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@ import { batch } from 'react-redux';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
|
||||
import { getConferenceState } from '../base/conference/functions';
|
||||
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, MediaType } from '../base/media/constants';
|
||||
import { isAudioMuted, isVideoMuted } from '../base/media/functions';
|
||||
import { MEDIA_TYPE as TRACK_MEDIA_TYPE } from '../base/media/constants';
|
||||
import {
|
||||
isAudioMuted,
|
||||
isScreenshareMuted,
|
||||
isVideoMuted
|
||||
} from '../base/media/functions';
|
||||
import { PARTICIPANT_UPDATED } from '../base/participants/actionTypes';
|
||||
import { raiseHand } from '../base/participants/actions';
|
||||
import {
|
||||
@@ -30,8 +34,10 @@ import {
|
||||
PARTICIPANT_APPROVED,
|
||||
PARTICIPANT_REJECTED,
|
||||
REQUEST_DISABLE_AUDIO_MODERATION,
|
||||
REQUEST_DISABLE_DESKTOP_MODERATION,
|
||||
REQUEST_DISABLE_VIDEO_MODERATION,
|
||||
REQUEST_ENABLE_AUDIO_MODERATION,
|
||||
REQUEST_ENABLE_DESKTOP_MODERATION,
|
||||
REQUEST_ENABLE_VIDEO_MODERATION
|
||||
} from './actionTypes';
|
||||
import {
|
||||
@@ -49,8 +55,10 @@ import {
|
||||
ASKED_TO_UNMUTE_NOTIFICATION_ID,
|
||||
ASKED_TO_UNMUTE_SOUND_ID,
|
||||
AUDIO_MODERATION_NOTIFICATION_ID,
|
||||
CS_MODERATION_NOTIFICATION_ID,
|
||||
VIDEO_MODERATION_NOTIFICATION_ID
|
||||
DESKTOP_MODERATION_NOTIFICATION_ID,
|
||||
MEDIA_TYPE,
|
||||
MediaType,
|
||||
VIDEO_MODERATION_NOTIFICATION_ID,
|
||||
} from './constants';
|
||||
import {
|
||||
isEnabledFromState,
|
||||
@@ -90,9 +98,9 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
uid = VIDEO_MODERATION_NOTIFICATION_ID;
|
||||
break;
|
||||
}
|
||||
case MEDIA_TYPE.SCREENSHARE: {
|
||||
case MEDIA_TYPE.DESKTOP: {
|
||||
titleKey = 'notify.moderationInEffectCSTitle';
|
||||
uid = CS_MODERATION_NOTIFICATION_ID;
|
||||
uid = DESKTOP_MODERATION_NOTIFICATION_ID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -115,6 +123,10 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
conference?.disableAVModeration(MEDIA_TYPE.AUDIO);
|
||||
break;
|
||||
}
|
||||
case REQUEST_DISABLE_DESKTOP_MODERATION: {
|
||||
conference?.disableAVModeration(MEDIA_TYPE.DESKTOP);
|
||||
break;
|
||||
}
|
||||
case REQUEST_DISABLE_VIDEO_MODERATION: {
|
||||
conference?.disableAVModeration(MEDIA_TYPE.VIDEO);
|
||||
break;
|
||||
@@ -123,6 +135,10 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
conference?.enableAVModeration(MEDIA_TYPE.AUDIO);
|
||||
break;
|
||||
}
|
||||
case REQUEST_ENABLE_DESKTOP_MODERATION: {
|
||||
conference?.enableAVModeration(MEDIA_TYPE.DESKTOP);
|
||||
break;
|
||||
}
|
||||
case REQUEST_ENABLE_VIDEO_MODERATION: {
|
||||
conference?.enableAVModeration(MEDIA_TYPE.VIDEO);
|
||||
break;
|
||||
@@ -219,24 +235,37 @@ StateListenerRegistry.register(
|
||||
const customActionHandler = [];
|
||||
|
||||
if ((mediaType === MEDIA_TYPE.AUDIO || getState()['features/av-moderation'].audioUnmuteApproved)
|
||||
&& isAudioMuted(getState())) {
|
||||
&& isAudioMuted(getState())) {
|
||||
customActionNameKey.push('notify.unmute');
|
||||
customActionHandler.push(() => {
|
||||
dispatch(muteLocal(false, MEDIA_TYPE.AUDIO));
|
||||
dispatch(muteLocal(false, TRACK_MEDIA_TYPE.AUDIO));
|
||||
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));
|
||||
});
|
||||
}
|
||||
|
||||
if ((mediaType === MEDIA_TYPE.VIDEO || getState()['features/av-moderation'].videoUnmuteApproved)
|
||||
&& isVideoMuted(getState())) {
|
||||
customActionNameKey.push('notify.unmuteVideo');
|
||||
if ((mediaType === MEDIA_TYPE.DESKTOP || getState()['features/av-moderation'].desktopUnmuteApproved)
|
||||
&& isScreenshareMuted(getState())) {
|
||||
customActionNameKey.push('notify.unmuteScreen');
|
||||
customActionHandler.push(() => {
|
||||
dispatch(muteLocal(false, MEDIA_TYPE.VIDEO));
|
||||
dispatch(muteLocal(false, TRACK_MEDIA_TYPE.SCREENSHARE));
|
||||
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));
|
||||
|
||||
// lower hand as there will be no audio and change in dominant speaker to clear it
|
||||
// Since permission is requested by raising the hand, lower it not to rely on dominant speaker detection
|
||||
// to clear the hand.
|
||||
dispatch(raiseHand(false));
|
||||
});
|
||||
}
|
||||
|
||||
if ((mediaType === MEDIA_TYPE.VIDEO || getState()['features/av-moderation'].videoUnmuteApproved)
|
||||
&& isVideoMuted(getState())) {
|
||||
customActionNameKey.push('notify.unmuteVideo');
|
||||
customActionHandler.push(() => {
|
||||
dispatch(muteLocal(false, TRACK_MEDIA_TYPE.VIDEO));
|
||||
dispatch(hideNotification(ASKED_TO_UNMUTE_NOTIFICATION_ID));
|
||||
|
||||
// Since permission is requested by raising the hand, lower it not to rely on dominant speaker detection
|
||||
// to clear the hand.
|
||||
dispatch(raiseHand(false));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { MEDIA_TYPE, type MediaType } from '../base/media/constants';
|
||||
import {
|
||||
PARTICIPANT_LEFT,
|
||||
PARTICIPANT_UPDATED
|
||||
@@ -16,14 +15,21 @@ import {
|
||||
PARTICIPANT_PENDING_AUDIO,
|
||||
PARTICIPANT_REJECTED
|
||||
} from './actionTypes';
|
||||
import { MEDIA_TYPE_TO_PENDING_STORE_KEY } from './constants';
|
||||
import {
|
||||
MEDIA_TYPE,
|
||||
MEDIA_TYPE_TO_PENDING_STORE_KEY,
|
||||
type MediaType
|
||||
} from './constants';
|
||||
|
||||
const initialState = {
|
||||
audioModerationEnabled: false,
|
||||
desktopModerationEnabled: false,
|
||||
videoModerationEnabled: false,
|
||||
audioWhitelist: {},
|
||||
desktopWhitelist: {},
|
||||
videoWhitelist: {},
|
||||
pendingAudio: [],
|
||||
pendingDesktop: [],
|
||||
pendingVideo: []
|
||||
};
|
||||
|
||||
@@ -31,7 +37,11 @@ export interface IAVModerationState {
|
||||
audioModerationEnabled: boolean;
|
||||
audioUnmuteApproved?: boolean | undefined;
|
||||
audioWhitelist: { [id: string]: boolean; };
|
||||
desktopModerationEnabled: boolean;
|
||||
desktopUnmuteApproved?: boolean | undefined;
|
||||
desktopWhitelist: { [id: string]: boolean; };
|
||||
pendingAudio: Array<{ id: string; }>;
|
||||
pendingDesktop: Array<{ id: string; }>;
|
||||
pendingVideo: Array<{ id: string; }>;
|
||||
videoModerationEnabled: boolean;
|
||||
videoUnmuteApproved?: boolean | undefined;
|
||||
@@ -77,28 +87,61 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
(state = initialState, action): IAVModerationState => {
|
||||
switch (action.type) {
|
||||
case DISABLE_MODERATION: {
|
||||
const newState = action.mediaType === MEDIA_TYPE.AUDIO
|
||||
? {
|
||||
let newState = {};
|
||||
|
||||
switch (action.mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
newState = {
|
||||
audioModerationEnabled: false,
|
||||
audioUnmuteApproved: undefined
|
||||
} : {
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
newState = {
|
||||
desktopModerationEnabled: false,
|
||||
desktopUnmuteApproved: undefined
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
newState = {
|
||||
videoModerationEnabled: false,
|
||||
videoUnmuteApproved: undefined
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
...newState,
|
||||
audioWhitelist: {},
|
||||
desktopWhitelist: {},
|
||||
videoWhitelist: {},
|
||||
pendingAudio: [],
|
||||
pendingDesktop: [],
|
||||
pendingVideo: []
|
||||
};
|
||||
}
|
||||
|
||||
case ENABLE_MODERATION: {
|
||||
const newState = action.mediaType === MEDIA_TYPE.AUDIO
|
||||
? { audioModerationEnabled: true } : { videoModerationEnabled: true };
|
||||
let newState = {};
|
||||
|
||||
switch (action.mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
newState = {
|
||||
audioModerationEnabled: true,
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
newState = {
|
||||
desktopModerationEnabled: true,
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
newState = {
|
||||
videoModerationEnabled: true,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
@@ -107,8 +150,25 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
}
|
||||
|
||||
case LOCAL_PARTICIPANT_APPROVED: {
|
||||
const newState = action.mediaType === MEDIA_TYPE.AUDIO
|
||||
? { audioUnmuteApproved: true } : { videoUnmuteApproved: true };
|
||||
let newState = {};
|
||||
|
||||
switch (action.mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
newState = {
|
||||
audioUnmuteApproved: true
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
newState = {
|
||||
desktopUnmuteApproved: true
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
newState = {
|
||||
videoUnmuteApproved: true
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
@@ -117,8 +177,25 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
}
|
||||
|
||||
case LOCAL_PARTICIPANT_REJECTED: {
|
||||
const newState = action.mediaType === MEDIA_TYPE.AUDIO
|
||||
? { audioUnmuteApproved: false } : { videoUnmuteApproved: false };
|
||||
let newState = {};
|
||||
|
||||
switch (action.mediaType) {
|
||||
case MEDIA_TYPE.AUDIO:
|
||||
newState = {
|
||||
audioUnmuteApproved: false
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.DESKTOP:
|
||||
newState = {
|
||||
desktopUnmuteApproved: false
|
||||
};
|
||||
break;
|
||||
case MEDIA_TYPE.VIDEO:
|
||||
newState = {
|
||||
videoUnmuteApproved: false
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
@@ -146,7 +223,7 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
|
||||
case PARTICIPANT_UPDATED: {
|
||||
const participant = action.participant;
|
||||
const { audioModerationEnabled, videoModerationEnabled } = state;
|
||||
const { audioModerationEnabled, desktopModerationEnabled, videoModerationEnabled } = state;
|
||||
let hasStateChanged = false;
|
||||
|
||||
// skips changing the reference of pendingAudio or pendingVideo,
|
||||
@@ -155,6 +232,10 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
hasStateChanged = _updatePendingParticipant(MEDIA_TYPE.AUDIO, participant, state);
|
||||
}
|
||||
|
||||
if (desktopModerationEnabled) {
|
||||
hasStateChanged = hasStateChanged || _updatePendingParticipant(MEDIA_TYPE.DESKTOP, participant, state);
|
||||
}
|
||||
|
||||
if (videoModerationEnabled) {
|
||||
hasStateChanged = hasStateChanged || _updatePendingParticipant(MEDIA_TYPE.VIDEO, participant, state);
|
||||
}
|
||||
@@ -168,9 +249,10 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
case PARTICIPANT_LEFT: {
|
||||
const participant = action.participant;
|
||||
const { audioModerationEnabled, videoModerationEnabled } = state;
|
||||
const { audioModerationEnabled, desktopModerationEnabled, videoModerationEnabled } = state;
|
||||
let hasStateChanged = false;
|
||||
|
||||
// skips changing the reference of pendingAudio or pendingVideo,
|
||||
@@ -184,6 +266,15 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
}
|
||||
}
|
||||
|
||||
if (desktopModerationEnabled) {
|
||||
const newPendingDesktop = state.pendingDesktop.filter(pending => pending.id !== participant.id);
|
||||
|
||||
if (state.pendingDesktop.length !== newPendingDesktop.length) {
|
||||
state.pendingDesktop = newPendingDesktop;
|
||||
hasStateChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (videoModerationEnabled) {
|
||||
const newPendingVideo = state.pendingVideo.filter(pending => pending.id !== participant.id);
|
||||
|
||||
@@ -213,6 +304,13 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.DESKTOP) {
|
||||
return {
|
||||
...state,
|
||||
pendingDesktop: state.pendingDesktop.filter(pending => pending.id !== id)
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.VIDEO) {
|
||||
return {
|
||||
...state,
|
||||
@@ -236,6 +334,16 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.DESKTOP) {
|
||||
return {
|
||||
...state,
|
||||
desktopWhitelist: {
|
||||
...state.desktopWhitelist,
|
||||
[id]: true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.VIDEO) {
|
||||
return {
|
||||
...state,
|
||||
@@ -262,6 +370,16 @@ ReducerRegistry.register<IAVModerationState>('features/av-moderation',
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.DESKTOP) {
|
||||
return {
|
||||
...state,
|
||||
desktopWhitelist: {
|
||||
...state.desktopWhitelist,
|
||||
[id]: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (mediaType === MEDIA_TYPE.VIDEO) {
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/app');
|
||||
export default getLogger('app:base-app');
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/audio-only');
|
||||
export default getLogger('app:audio-only');
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { withPixelLineHeight } from '../../../styles/functions.web';
|
||||
import { pixelsToRem } from '../../../ui/functions.any';
|
||||
import { isIcon } from '../../functions';
|
||||
import { IAvatarProps } from '../../types';
|
||||
import { PRESENCE_AVAILABLE_COLOR, PRESENCE_AWAY_COLOR, PRESENCE_BUSY_COLOR, PRESENCE_IDLE_COLOR } from '../styles';
|
||||
@@ -50,9 +50,8 @@ const useStyles = makeStyles()(theme => {
|
||||
avatar: {
|
||||
backgroundColor: '#AAA',
|
||||
borderRadius: '50%',
|
||||
fontWeight: '600',
|
||||
color: theme.palette?.text01 || '#fff',
|
||||
...withPixelLineHeight(theme.typography?.heading1 ?? {}),
|
||||
...(theme.typography?.heading1 ?? {}),
|
||||
fontSize: 'inherit',
|
||||
objectFit: 'cover',
|
||||
textAlign: 'center',
|
||||
@@ -137,7 +136,7 @@ const StatelessAvatar = ({
|
||||
const _getAvatarStyle = (backgroundColor?: string) => {
|
||||
return {
|
||||
background: backgroundColor || undefined,
|
||||
fontSize: size ? size * 0.4 : '180%',
|
||||
fontSize: size ? pixelsToRem(size * 0.4) : '180%',
|
||||
height: size || '100%',
|
||||
width: size || '100%'
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user