Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56b5f2845d | ||
|
|
afee9eaa26 | ||
|
|
d53ad9a8f3 | ||
|
|
d8634eed3d | ||
|
|
be4b70c1e1 | ||
|
|
e79cded57f | ||
|
|
486430d1f0 | ||
|
|
e6ddf40b1b | ||
|
|
9f521a79f7 | ||
|
|
83784a717a | ||
|
|
0729deee79 | ||
|
|
77c3114cf8 | ||
|
|
82a56c8204 | ||
|
|
b39896d8c6 | ||
|
|
79b3fdb645 | ||
|
|
0f877cd021 | ||
|
|
db2acc75b2 | ||
|
|
a5dbfbf2c1 | ||
|
|
34c7d02de2 | ||
|
|
ca45067158 | ||
|
|
5a6eb7c573 | ||
|
|
5ad2a27a92 | ||
|
|
68daaa45f9 | ||
|
|
c40ea35937 | ||
|
|
d27f433175 | ||
|
|
8a6101cd14 | ||
|
|
4db7c2bc68 | ||
|
|
18740fc686 | ||
|
|
0c39398493 | ||
|
|
949145f04b | ||
|
|
8578dcadf2 | ||
|
|
959db44eca | ||
|
|
a031c0e128 | ||
|
|
591833505f | ||
|
|
f7ad5074d8 | ||
|
|
e0aef74bf5 | ||
|
|
b2378bf899 | ||
|
|
255f6b1814 | ||
|
|
4c491b5363 | ||
|
|
61c808d4cf | ||
|
|
13ef3183e2 | ||
|
|
afd4fdcea2 | ||
|
|
982181ccd4 | ||
|
|
30629ebba2 | ||
|
|
7f6a32d21a | ||
|
|
320ade0a50 | ||
|
|
8c6fee3150 | ||
|
|
5c6acaf915 | ||
|
|
c46549b2b6 | ||
|
|
97a58f6db7 | ||
|
|
b6288579c9 | ||
|
|
44bf987cdc | ||
|
|
a7d55824bb | ||
|
|
8fa038c61f | ||
|
|
869d9b43cb |
12
.github/workflows/docker.yaml
vendored
12
.github/workflows/docker.yaml
vendored
@@ -23,10 +23,10 @@ jobs:
|
||||
packages: write
|
||||
steps:
|
||||
- name: Check it out
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ inputs.artifact_run_id }}
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
path: dist
|
||||
|
||||
- name: Log in to container registry
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
@@ -42,16 +42,16 @@ jobs:
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@f7b4ed12385588c3f9bc252f0a2b520d83b52d48
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: ${{ inputs.docker_tags}}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@5138f76647652447004da686b2411557eaf65f33
|
||||
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@f6010ea70151369b06f0194be1051fbbdff851b2
|
||||
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6.3.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
2
.github/workflows/e2e.yml
vendored
2
.github/workflows/e2e.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out test private repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
with:
|
||||
repository: element-hq/static-call-participant
|
||||
ref: refs/heads/main
|
||||
|
||||
6
.github/workflows/element-call.yaml
vendored
6
.github/workflows/element-call.yaml
vendored
@@ -21,9 +21,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
- name: Install dependencies
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
VITE_APP_VERSION: ${{ inputs.vite_app_version }}
|
||||
NODE_OPTIONS: "--max-old-space-size=4096"
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4
|
||||
with:
|
||||
name: build-output
|
||||
path: dist
|
||||
|
||||
4
.github/workflows/lint.yaml
vendored
4
.github/workflows/lint.yaml
vendored
@@ -7,9 +7,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
- name: Install dependencies
|
||||
|
||||
8
.github/workflows/netlify.yaml
vendored
8
.github/workflows/netlify.yaml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
environment: Netlify
|
||||
steps:
|
||||
- name: 📝 Create Deployment
|
||||
uses: bobheadxi/deployments@v1
|
||||
uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1
|
||||
id: deployment
|
||||
with:
|
||||
step: start
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
Exercise caution. Use test accounts.
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4
|
||||
with:
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
run-id: ${{ inputs.artifact_run_id }}
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
|
||||
- name: ☁️ Deploy to Netlify
|
||||
id: netlify
|
||||
uses: nwtgck/actions-netlify@v3.0
|
||||
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0
|
||||
with:
|
||||
publish-dir: webapp
|
||||
deploy-message: "Deploy from GitHub Actions"
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
timeout-minutes: 1
|
||||
|
||||
- name: 🚦 Update deployment status
|
||||
uses: bobheadxi/deployments@v1
|
||||
uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1
|
||||
if: always()
|
||||
with:
|
||||
step: finish
|
||||
|
||||
2
.github/workflows/pr-deploy.yaml
vendored
2
.github/workflows/pr-deploy.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
pr_data_json: ${{ steps.prdetails.outputs.data }}
|
||||
steps:
|
||||
- id: prdetails
|
||||
uses: matrix-org/pr-details-action@v1.3
|
||||
uses: matrix-org/pr-details-action@15bde5285d7850ba276cc3bd8a03733e3f24622a # v1.3
|
||||
continue-on-error: true
|
||||
with:
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
|
||||
4
.github/workflows/publish.yaml
vendored
4
.github/workflows/publish.yaml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
id: current-time
|
||||
run: echo "unix_time=$(date +'%s')" >> $GITHUB_OUTPUT
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id || github.run_id }}
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
run: |
|
||||
tar --numeric-owner --transform "s/dist/element-call-${TARBALL_VERSION}/" -cvzf element-call-${TARBALL_VERSION}.tar.gz dist
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@552bf3722c16e81001aea7db72d8cedf64eb5f68
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
|
||||
6
.github/workflows/test.yaml
vendored
6
.github/workflows/test.yaml
vendored
@@ -9,9 +9,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
- name: Install dependencies
|
||||
@@ -19,6 +19,6 @@ jobs:
|
||||
- name: Vitest
|
||||
run: "yarn run test"
|
||||
- name: Upload to codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4
|
||||
with:
|
||||
flags: unittests
|
||||
|
||||
8
.github/workflows/translations-download.yaml
vendored
8
.github/workflows/translations-download.yaml
vendored
@@ -13,9 +13,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
run: "rm -R public/locales"
|
||||
|
||||
- name: Download translation files
|
||||
uses: localazy/download@v1.1.0
|
||||
uses: localazy/download@0a79880fb66150601e3b43606fab69c88123c087 # v1.1.0
|
||||
with:
|
||||
groups: "-p includeSourceLang:true"
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v6.0.5
|
||||
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/localazy-download
|
||||
|
||||
4
.github/workflows/translations-upload.yaml
vendored
4
.github/workflows/translations-upload.yaml
vendored
@@ -14,9 +14,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout the code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
||||
|
||||
- name: Upload
|
||||
uses: localazy/upload@v1
|
||||
uses: localazy/upload@27e6b5c0fddf4551596b42226b1c24124335d24a # v1
|
||||
with:
|
||||
write_key: ${{ secrets.LOCALAZY_WRITE_KEY }}
|
||||
|
||||
@@ -131,7 +131,7 @@ advertises one in the client well-known, this will not be used.)
|
||||
|
||||
```json
|
||||
"livekit": {
|
||||
"livekit_service_url": "http://localhost:8881"
|
||||
"livekit_service_url": "http://localhost:7881"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
"server_name": "call.ems.host"
|
||||
}
|
||||
},
|
||||
"livekit": {
|
||||
"livekit_service_url": "http://localhost:7881"
|
||||
},
|
||||
"eula": "https://static.element.io/legal/online-EULA.pdf"
|
||||
}
|
||||
|
||||
28
package.json
28
package.json
@@ -26,9 +26,9 @@
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"@opentelemetry/context-zone": "^1.9.1",
|
||||
"@opentelemetry/exporter-jaeger": "^1.9.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.48.0",
|
||||
"@opentelemetry/instrumentation-document-load": "^0.38.0",
|
||||
"@opentelemetry/instrumentation-user-interaction": "^0.38.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.0",
|
||||
"@opentelemetry/instrumentation-document-load": "^0.39.0",
|
||||
"@opentelemetry/instrumentation-user-interaction": "^0.39.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.9.1",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-slider": "^1.1.2",
|
||||
@@ -47,7 +47,7 @@
|
||||
"@react-stately/select": "^3.1.3",
|
||||
"@react-stately/tooltip": "^3.0.5",
|
||||
"@react-stately/tree": "^3.2.0",
|
||||
"@sentry/react": "^7.0.0",
|
||||
"@sentry/react": "^8.0.0",
|
||||
"@sentry/tracing": "^7.0.0",
|
||||
"@types/lodash": "^4.14.199",
|
||||
"@use-gesture/react": "^10.2.11",
|
||||
@@ -59,7 +59,7 @@
|
||||
"classnames": "^2.3.1",
|
||||
"events": "^3.3.0",
|
||||
"i18next": "^23.0.0",
|
||||
"i18next-browser-languagedetector": "^7.0.0",
|
||||
"i18next-browser-languagedetector": "^8.0.0",
|
||||
"i18next-http-backend": "^2.0.0",
|
||||
"livekit-client": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -71,15 +71,15 @@
|
||||
"posthog-js": "^1.29.0",
|
||||
"react": "18",
|
||||
"react-dom": "18",
|
||||
"react-i18next": "^14.0.0",
|
||||
"react-i18next": "^15.0.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-use-clipboard": "^1.0.7",
|
||||
"react-use-measure": "^2.1.1",
|
||||
"rxjs": "^7.8.1",
|
||||
"sdp-transform": "^2.14.1",
|
||||
"tinyqueue": "^2.0.3",
|
||||
"tinyqueue": "^3.0.0",
|
||||
"unique-names-generator": "^4.6.0",
|
||||
"uuid": "9",
|
||||
"uuid": "10",
|
||||
"vaul": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -90,17 +90,19 @@
|
||||
"@react-spring/rafz": "^9.7.3",
|
||||
"@react-types/dialog": "^3.5.5",
|
||||
"@sentry/vite-plugin": "^2.0.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/dom": "^10.1.0",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/user-event": "^14.5.1",
|
||||
"@types/content-type": "^1.1.5",
|
||||
"@types/dom-screen-wake-lock": "^1.0.1",
|
||||
"@types/dompurify": "^3.0.2",
|
||||
"@types/grecaptcha": "^3.0.4",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/request": "^2.48.8",
|
||||
"@types/sdp-transform": "^2.4.5",
|
||||
"@types/uuid": "9",
|
||||
"@types/uuid": "10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"babel-loader": "^9.0.0",
|
||||
@@ -114,8 +116,8 @@
|
||||
"eslint-plugin-matrix-org": "^1.2.1",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.5.0",
|
||||
"eslint-plugin-unicorn": "^51.0.0",
|
||||
"i18next-parser": "^8.0.0",
|
||||
"eslint-plugin-unicorn": "^54.0.0",
|
||||
"i18next-parser": "^9.0.0",
|
||||
"jsdom": "^24.0.0",
|
||||
"prettier": "^3.0.0",
|
||||
"sass": "^1.42.1",
|
||||
@@ -124,6 +126,6 @@
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-html-template": "^1.1.0",
|
||||
"vite-plugin-svgr": "^4.0.0",
|
||||
"vitest": "^1.2.2"
|
||||
"vitest": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,42 @@
|
||||
"extends": ["config:base"],
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Disable renoavte for packages we want to monitor ourselves",
|
||||
"matchPackagePatterns": ["matrix-js-sdk"],
|
||||
"extends": ["group:allNonMajor", "schedule:weekly"]
|
||||
},
|
||||
{
|
||||
"groupName": "GitHub Actions",
|
||||
"matchDepTypes": ["action"],
|
||||
"pinDigests": true,
|
||||
"extends": ["schedule:monthly"]
|
||||
},
|
||||
{
|
||||
"description": "Disable Renovate for packages we want to monitor ourselves",
|
||||
"groupName": "manually updated packages",
|
||||
"matchDepNames": ["matrix-js-sdk"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"groupName": "matrix-widget-api",
|
||||
"matchDepNames": ["matrix-widget-api"]
|
||||
},
|
||||
{
|
||||
"groupName": "Compound",
|
||||
"matchPackagePrefixes": ["@vector-im/compound-"],
|
||||
"schedule": "before 5am on Tuesday and Friday"
|
||||
},
|
||||
{
|
||||
"groupName": "LiveKit client",
|
||||
"matchDepNames": ["livekit-client"]
|
||||
},
|
||||
{
|
||||
"groupName": "LiveKit components",
|
||||
"matchPackagePrefixes": ["@livekit/components-"]
|
||||
},
|
||||
{
|
||||
"groupName": "Vaul",
|
||||
"matchDepNames": ["vaul"],
|
||||
"extends": ["schedule:monthly"],
|
||||
"prHeader": "Please review modals on mobile for visual regressions."
|
||||
}
|
||||
],
|
||||
"semanticCommits": "disabled",
|
||||
|
||||
6
src/@types/global.d.ts
vendored
6
src/@types/global.d.ts
vendored
@@ -28,12 +28,6 @@ declare global {
|
||||
OLM_OPTIONS: Record<string, string>;
|
||||
}
|
||||
|
||||
// TypeScript doesn't know about the experimental setSinkId method, so we
|
||||
// declare it ourselves
|
||||
interface MediaElement extends HTMLVideoElement {
|
||||
setSinkId: (id: string) => void;
|
||||
}
|
||||
|
||||
interface HTMLElement {
|
||||
// Safari only supports this prefixed, so tell the type system about it
|
||||
webkitRequestFullscreen: () => void;
|
||||
|
||||
@@ -65,11 +65,21 @@ export interface ConfigOptions {
|
||||
};
|
||||
|
||||
/**
|
||||
* Allow to join a group calls without audio and video.
|
||||
* TEMPORARY: Is a feature that's not proved and experimental
|
||||
* TEMPORARY experimental features.
|
||||
*/
|
||||
features?: {
|
||||
feature_group_calls_without_video_and_audio: boolean;
|
||||
/**
|
||||
* Allow to join group calls without audio and video.
|
||||
*/
|
||||
feature_group_calls_without_video_and_audio?: boolean;
|
||||
/**
|
||||
* Send device-specific call session membership state events instead of
|
||||
* legacy user-specific call membership state events.
|
||||
* This setting has no effect when the user joins an active call with
|
||||
* legacy state events. For compatibility, Element Call will always join
|
||||
* active legacy calls with legacy state events.
|
||||
*/
|
||||
feature_use_device_session_member_events?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { BrowserTracing } from "@sentry/browser";
|
||||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
@@ -160,10 +159,7 @@ export class Initializer {
|
||||
dsn: Config.get().sentry?.DSN,
|
||||
environment: Config.get().sentry?.environment,
|
||||
integrations: [
|
||||
new BrowserTracing({
|
||||
routingInstrumentation:
|
||||
Sentry.reactRouterV5Instrumentation(history),
|
||||
}),
|
||||
Sentry.reactRouterV5BrowserTracingIntegration({ history }),
|
||||
],
|
||||
tracesSampleRate: 1.0,
|
||||
});
|
||||
|
||||
@@ -40,7 +40,6 @@ import {
|
||||
SummaryStatsReport,
|
||||
CallFeedReport,
|
||||
} from "matrix-js-sdk/src/webrtc/stats/statsReport";
|
||||
import { setSpan } from "@opentelemetry/api/build/esm/trace/context-utils";
|
||||
|
||||
import { ElementCallOpenTelemetry } from "./otel";
|
||||
import { ObjectFlattener } from "./ObjectFlattener";
|
||||
@@ -446,7 +445,7 @@ export class OTelGroupCallMembership {
|
||||
const type = OTelStatsReportType.SummaryReport;
|
||||
const data = ObjectFlattener.flattenSummaryStatsReportObject(statsReport);
|
||||
if (this.statsReportSpan.span === undefined && this.callMembershipSpan) {
|
||||
const ctx = setSpan(
|
||||
const ctx = opentelemetry.trace.setSpan(
|
||||
opentelemetry.context.active(),
|
||||
this.callMembershipSpan,
|
||||
);
|
||||
|
||||
@@ -118,7 +118,7 @@ export function useProfile(client: MatrixClient | undefined): UseProfile {
|
||||
displayName,
|
||||
avatarUrl: removeAvatar
|
||||
? undefined
|
||||
: mxcAvatarUrl ?? prev.avatarUrl,
|
||||
: (mxcAvatarUrl ?? prev.avatarUrl),
|
||||
loading: false,
|
||||
success: true,
|
||||
}));
|
||||
|
||||
@@ -80,17 +80,12 @@ export const GroupCallView: FC<Props> = ({
|
||||
const memberships = useMatrixRTCSessionMemberships(rtcSession);
|
||||
const isJoined = useMatrixRTCSessionJoinState(rtcSession);
|
||||
|
||||
// The mute state reactively gets updated once the participant count reaches the threshold.
|
||||
// The user then still is able to unmute again.
|
||||
// The more common case is that the user is muted from the start (participant count is already over the threshold).
|
||||
const autoMuteHappened = useRef(false);
|
||||
// This should use `useEffectEvent` (only available in experimental versions)
|
||||
useEffect(() => {
|
||||
if (autoMuteHappened.current) return;
|
||||
if (memberships.length >= MUTE_PARTICIPANT_COUNT) {
|
||||
if (memberships.length >= MUTE_PARTICIPANT_COUNT)
|
||||
muteStates.audio.setEnabled?.(false);
|
||||
autoMuteHappened.current = true;
|
||||
}
|
||||
}, [autoMuteHappened, memberships, muteStates.audio]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.rtcSession = rtcSession;
|
||||
|
||||
@@ -254,7 +254,7 @@ export const InCallView: FC<InCallViewProps> = subscribe(
|
||||
() =>
|
||||
fullscreenItem ??
|
||||
(noControls
|
||||
? items.find((item) => item.isSpeaker) ?? items.at(0) ?? null
|
||||
? (items.find((item) => item.isSpeaker) ?? items.at(0) ?? null)
|
||||
: null),
|
||||
[fullscreenItem, noControls, items],
|
||||
);
|
||||
|
||||
@@ -53,7 +53,7 @@ function useMuteState(
|
||||
): MuteState {
|
||||
const [enabled, setEnabled] = useReactiveState<boolean | undefined>(
|
||||
(prev) =>
|
||||
device.available.length > 0 ? prev ?? enabledByDefault() : undefined,
|
||||
device.available.length > 0 ? (prev ?? enabledByDefault()) : undefined,
|
||||
[device],
|
||||
);
|
||||
return useMemo(
|
||||
|
||||
@@ -65,7 +65,7 @@ export function useFullscreen<T>(items: TileDescriptor<T>[]): {
|
||||
(prevItem) =>
|
||||
prevItem == null
|
||||
? null
|
||||
: items.find((i) => i.id === prevItem.id) ?? null,
|
||||
: (items.find((i) => i.id === prevItem.id) ?? null),
|
||||
[items],
|
||||
);
|
||||
|
||||
@@ -79,7 +79,7 @@ export function useFullscreen<T>(items: TileDescriptor<T>[]): {
|
||||
(itemId: string) => {
|
||||
setFullscreenItem(
|
||||
latestFullscreenItem.current === null
|
||||
? latestItems.current.find((i) => i.id === itemId) ?? null
|
||||
? (latestItems.current.find((i) => i.id === itemId) ?? null)
|
||||
: null,
|
||||
);
|
||||
},
|
||||
|
||||
@@ -225,16 +225,38 @@ export const useLoadGroupCall = (
|
||||
});
|
||||
} else {
|
||||
// If the room does not exist we first search for it with viaServers
|
||||
const roomSummary = await client.getRoomSummary(roomId, viaServers);
|
||||
if (roomSummary.join_rule === JoinRule.Public) {
|
||||
room = await client.joinRoom(roomSummary.room_id, {
|
||||
let roomSummary: RoomSummary | undefined = undefined;
|
||||
try {
|
||||
roomSummary = await client.getRoomSummary(roomId, viaServers);
|
||||
} catch (error) {
|
||||
// If the room summary endpoint is not supported we let it be undefined and treat this case like
|
||||
// `JoinRule.Public`.
|
||||
// This is how the logic was done before: "we expect any room id passed to EC
|
||||
// to be for a public call" Which is definitely not ideal but worth a try if fetching
|
||||
// the summary crashes.
|
||||
logger.warn(
|
||||
`Could not load room summary to decide whether we want to join or knock.
|
||||
EC will fallback to join as if this would be a public room.
|
||||
Reach out to your homeserver admin to ask them about supporting the \`/summary\` endpoint (im.nheko.summary):`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
if (
|
||||
roomSummary === undefined ||
|
||||
roomSummary.join_rule === JoinRule.Public
|
||||
) {
|
||||
room = await client.joinRoom(roomId, {
|
||||
viaServers,
|
||||
});
|
||||
} else if (roomSummary.join_rule === JoinRule.Knock) {
|
||||
// bind room summary in this scope so we have it stored in a binding of type `RoomSummary`
|
||||
// instead of `RoomSummary | undefined`. Because we use it in a promise the linter does not accept
|
||||
// the type check from the if condition above.
|
||||
const _roomSummary = roomSummary;
|
||||
let knock: () => void = () => {};
|
||||
const userPressedAskToJoinPromise: Promise<void> = new Promise(
|
||||
(resolve) => {
|
||||
if (roomSummary.membership !== KnownMembership.Knock) {
|
||||
if (_roomSummary.membership !== KnownMembership.Knock) {
|
||||
knock = resolve;
|
||||
} else {
|
||||
// resolve immediately if the user already knocked
|
||||
@@ -242,12 +264,13 @@ export const useLoadGroupCall = (
|
||||
}
|
||||
},
|
||||
);
|
||||
setState({ kind: "canKnock", roomSummary, knock });
|
||||
setState({ kind: "canKnock", roomSummary: _roomSummary, knock });
|
||||
await userPressedAskToJoinPromise;
|
||||
room = await getRoomByKnocking(
|
||||
roomSummary.room_id,
|
||||
viaServers,
|
||||
() => setState({ kind: "waitForInvite", roomSummary }),
|
||||
() =>
|
||||
setState({ kind: "waitForInvite", roomSummary: _roomSummary }),
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
|
||||
@@ -108,10 +108,17 @@ export async function enterRTCSession(
|
||||
|
||||
// right now we assume everything is a room-scoped call
|
||||
const livekitAlias = rtcSession.room.roomId;
|
||||
const useDeviceSessionMemberEvents =
|
||||
Config.get().features?.feature_use_device_session_member_events;
|
||||
rtcSession.joinRoomSession(
|
||||
await makePreferredLivekitFoci(rtcSession, livekitAlias),
|
||||
makeActiveFocus(),
|
||||
{ manageMediaKeys: encryptMedia },
|
||||
{
|
||||
manageMediaKeys: encryptMedia,
|
||||
...(useDeviceSessionMemberEvents !== undefined && {
|
||||
useLegacyMemberEvents: !useDeviceSessionMemberEvents,
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ export const ProfileSettingsTab: FC<Props> = ({ client }) => {
|
||||
const avatar = data.get("avatar");
|
||||
|
||||
const avatarSize =
|
||||
typeof avatar == "string" ? avatar.length : avatar?.size ?? 0;
|
||||
typeof avatar == "string" ? avatar.length : (avatar?.size ?? 0);
|
||||
const displayName =
|
||||
typeof displayNameDataEntry == "string"
|
||||
? displayNameDataEntry
|
||||
: displayNameDataEntry?.name ?? null;
|
||||
: (displayNameDataEntry?.name ?? null);
|
||||
|
||||
if (!displayName) {
|
||||
return;
|
||||
|
||||
@@ -118,13 +118,17 @@ export const widget = ((): WidgetHelpers | null => {
|
||||
"org.matrix.rageshake_request",
|
||||
EventType.CallEncryptionKeysPrefix,
|
||||
];
|
||||
|
||||
const sendState = [
|
||||
{
|
||||
userId, // legacy call membership events
|
||||
`_${userId}_${deviceId}`, // session membership events
|
||||
`${userId}_${deviceId}`, // MSC3779 session membership events
|
||||
].map((stateKey) => ({
|
||||
eventType: EventType.GroupCallMemberPrefix,
|
||||
stateKey: userId, // TODO: based on if we use the new format we want the key to be: `_${userId}_${deviceId}`
|
||||
},
|
||||
];
|
||||
stateKey,
|
||||
}));
|
||||
const receiveState = [
|
||||
{ eventType: EventType.RoomCreate },
|
||||
{ eventType: EventType.RoomMember },
|
||||
{ eventType: EventType.RoomEncryption },
|
||||
{ eventType: EventType.GroupCallMemberPrefix },
|
||||
|
||||
Reference in New Issue
Block a user