Merge branch 'voip-team/rebased-multiSFU' into valere/multi-sfu/connection_states
This commit is contained in:
2
.github/workflows/blocked.yaml
vendored
2
.github/workflows/blocked.yaml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
pull-requests: read
|
pull-requests: read
|
||||||
steps:
|
steps:
|
||||||
- name: Add notice
|
- name: Add notice
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
|
||||||
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
|
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
|
|||||||
10
.github/workflows/build-and-publish-docker.yaml
vendored
10
.github/workflows/build-and-publish-docker.yaml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
- name: Check it out
|
- name: Check it out
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
|
|
||||||
- name: 📥 Download artifact
|
- name: 📥 Download artifact
|
||||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
path: dist
|
path: dist
|
||||||
|
|
||||||
- name: Log in to container registry
|
- name: Log in to container registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Extract metadata (tags, labels) for Docker
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
tags: ${{ inputs.docker_tags}}
|
tags: ${{ inputs.docker_tags}}
|
||||||
@@ -50,10 +50,10 @@ jobs:
|
|||||||
org.opencontainers.image.licenses=AGPL-3.0-only OR LicenseRef-Element-Commercial
|
org.opencontainers.image.licenses=AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
2
.github/workflows/build-element-call.yaml
vendored
2
.github/workflows/build-element-call.yaml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable
|
||||||
- name: Yarn cache
|
- name: Yarn cache
|
||||||
|
|||||||
2
.github/workflows/lint.yaml
vendored
2
.github/workflows/lint.yaml
vendored
@@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable
|
||||||
- name: Yarn cache
|
- name: Yarn cache
|
||||||
|
|||||||
12
.github/workflows/publish-embedded-packages.yaml
vendored
12
.github/workflows/publish-embedded-packages.yaml
vendored
@@ -85,7 +85,7 @@ jobs:
|
|||||||
run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256
|
run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256
|
||||||
- name: Upload
|
- name: Upload
|
||||||
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
|
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
|
||||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
|
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
${{ env.FILENAME_PREFIX }}.tar.gz
|
${{ env.FILENAME_PREFIX }}.tar.gz
|
||||||
@@ -103,7 +103,7 @@ jobs:
|
|||||||
id-token: write # required for the provenance flag on npm publish
|
id-token: write # required for the provenance flag on npm publish
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
|
|
||||||
- name: 📥 Download built element-call artifact
|
- name: 📥 Download built element-call artifact
|
||||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||||
@@ -144,7 +144,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
|
|
||||||
- name: 📥 Download built element-call artifact
|
- name: 📥 Download built element-call artifact
|
||||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||||
@@ -199,7 +199,7 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
with:
|
with:
|
||||||
path: element-call
|
path: element-call
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ jobs:
|
|||||||
path: element-call/embedded/ios/Sources/dist
|
path: element-call/embedded/ios/Sources/dist
|
||||||
|
|
||||||
- name: Checkout element-call-swift
|
- name: Checkout element-call-swift
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
with:
|
with:
|
||||||
repository: element-hq/element-call-swift
|
repository: element-hq/element-call-swift
|
||||||
path: element-call-swift
|
path: element-call-swift
|
||||||
@@ -264,7 +264,7 @@ jobs:
|
|||||||
echo "iOS: ${{ needs.publish_ios.outputs.ARTIFACT_VERSION }}"
|
echo "iOS: ${{ needs.publish_ios.outputs.ARTIFACT_VERSION }}"
|
||||||
- name: Add release notes
|
- name: Add release notes
|
||||||
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
|
if: ${{ needs.versioning.outputs.DRY_RUN == 'false' }}
|
||||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
|
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2
|
||||||
with:
|
with:
|
||||||
append_body: true
|
append_body: true
|
||||||
body: |
|
body: |
|
||||||
|
|||||||
4
.github/workflows/publish.yaml
vendored
4
.github/workflows/publish.yaml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- name: Create Checksum
|
- name: Create Checksum
|
||||||
run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256
|
run: find ${{ env.FILENAME_PREFIX }} -type f -print0 | sort -z | xargs -0 sha256sum | tee ${{ env.FILENAME_PREFIX }}.sha256
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
|
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
${{ env.FILENAME_PREFIX }}.tar.gz
|
${{ env.FILENAME_PREFIX }}.tar.gz
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Add release note
|
- name: Add release note
|
||||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2
|
uses: softprops/action-gh-release@aec2ec56f94eb8180ceec724245f64ef008b89f5 # v2
|
||||||
with:
|
with:
|
||||||
append_body: true
|
append_body: true
|
||||||
body: |
|
body: |
|
||||||
|
|||||||
6
.github/workflows/test.yaml
vendored
6
.github/workflows/test.yaml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable
|
||||||
- name: Yarn cache
|
- name: Yarn cache
|
||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Vitest
|
- name: Vitest
|
||||||
run: "yarn run test:coverage"
|
run: "yarn run test:coverage"
|
||||||
- name: Upload to codecov
|
- name: Upload to codecov
|
||||||
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5
|
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
with:
|
with:
|
||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable
|
||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||||
|
|||||||
2
.github/workflows/translations-download.yaml
vendored
2
.github/workflows/translations-download.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the code
|
- name: Checkout the code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
|
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable
|
||||||
|
|||||||
2
.github/workflows/translations-upload.yaml
vendored
2
.github/workflows/translations-upload.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the code
|
- name: Checkout the code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4
|
||||||
|
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: localazy/upload@27e6b5c0fddf4551596b42226b1c24124335d24a # v1
|
uses: localazy/upload@27e6b5c0fddf4551596b42226b1c24124335d24a # v1
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
"livekit-client": "^2.13.0",
|
"livekit-client": "^2.13.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"loglevel": "^1.9.1",
|
"loglevel": "^1.9.1",
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#head=voip-team/multi-SFU",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#head=toger5/use-relation-based-CallMembership-create-ts",
|
||||||
"matrix-widget-api": "^1.13.0",
|
"matrix-widget-api": "^1.13.0",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"observable-hooks": "^4.2.3",
|
"observable-hooks": "^4.2.3",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
MatrixRTCSessionManagerEvents,
|
MatrixRTCSessionManagerEvents,
|
||||||
type MatrixRTCSession,
|
type MatrixRTCSession,
|
||||||
} from "matrix-js-sdk/lib/matrixrtc";
|
} from "matrix-js-sdk/lib/matrixrtc";
|
||||||
|
import { logger } from "matrix-js-sdk/lib/logger";
|
||||||
|
|
||||||
import { getKeyForRoom } from "../e2ee/sharedKeyManagement";
|
import { getKeyForRoom } from "../e2ee/sharedKeyManagement";
|
||||||
|
|
||||||
@@ -139,22 +140,24 @@ export function useGroupCallRooms(client: MatrixClient): GroupCallRoom[] {
|
|||||||
.filter(roomHasCallMembershipEvents)
|
.filter(roomHasCallMembershipEvents)
|
||||||
.filter(roomIsJoinable);
|
.filter(roomIsJoinable);
|
||||||
const sortedRooms = sortRooms(client, rooms);
|
const sortedRooms = sortRooms(client, rooms);
|
||||||
const items = sortedRooms.map((room) => {
|
Promise.all(
|
||||||
const session = client.matrixRTC.getRoomSession(room);
|
sortedRooms.map(async (room) => {
|
||||||
return {
|
const session = await client.matrixRTC.getRoomSession(room);
|
||||||
roomAlias: room.getCanonicalAlias() ?? undefined,
|
return {
|
||||||
roomName: room.name,
|
roomAlias: room.getCanonicalAlias() ?? undefined,
|
||||||
avatarUrl: room.getMxcAvatarUrl()!,
|
roomName: room.name,
|
||||||
room,
|
avatarUrl: room.getMxcAvatarUrl()!,
|
||||||
session,
|
room,
|
||||||
participants: session.memberships
|
session,
|
||||||
.filter((m) => m.sender)
|
participants: session.memberships
|
||||||
.map((m) => room.getMember(m.sender!))
|
.filter((m) => m.sender)
|
||||||
.filter((m) => m) as RoomMember[],
|
.map((m) => room.getMember(m.sender!))
|
||||||
};
|
.filter((m) => m) as RoomMember[],
|
||||||
});
|
};
|
||||||
|
}),
|
||||||
setRooms(items);
|
)
|
||||||
|
.then((items) => setRooms(items))
|
||||||
|
.catch(logger.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRooms();
|
updateRooms();
|
||||||
|
|||||||
@@ -436,7 +436,10 @@ export const GroupCallView: FC<Props> = ({
|
|||||||
client={client}
|
client={client}
|
||||||
matrixInfo={matrixInfo}
|
matrixInfo={matrixInfo}
|
||||||
muteStates={muteStates}
|
muteStates={muteStates}
|
||||||
onEnter={() => setJoined(true)}
|
onEnter={async () => {
|
||||||
|
setJoined(true);
|
||||||
|
return Promise.resolve();
|
||||||
|
}}
|
||||||
confineToRoom={confineToRoom}
|
confineToRoom={confineToRoom}
|
||||||
hideHeader={header === HeaderStyle.None}
|
hideHeader={header === HeaderStyle.None}
|
||||||
participantCount={participantCount}
|
participantCount={participantCount}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ interface Props {
|
|||||||
client: MatrixClient;
|
client: MatrixClient;
|
||||||
matrixInfo: MatrixInfo;
|
matrixInfo: MatrixInfo;
|
||||||
muteStates: MuteStates;
|
muteStates: MuteStates;
|
||||||
onEnter: () => void;
|
onEnter: () => Promise<void>;
|
||||||
enterLabel?: JSX.Element | string;
|
enterLabel?: JSX.Element | string;
|
||||||
confineToRoom: boolean;
|
confineToRoom: boolean;
|
||||||
hideHeader: boolean;
|
hideHeader: boolean;
|
||||||
@@ -183,6 +183,14 @@ export const LobbyView: FC<Props> = ({
|
|||||||
|
|
||||||
useTrackProcessorSync(videoTrack);
|
useTrackProcessorSync(videoTrack);
|
||||||
|
|
||||||
|
const [waitingToEnter, setWaitingToEnter] = useState(false);
|
||||||
|
const onEnterCall = useCallback(() => {
|
||||||
|
setWaitingToEnter(true);
|
||||||
|
void onEnter().finally(() => setWaitingToEnter(false));
|
||||||
|
}, [onEnter]);
|
||||||
|
|
||||||
|
const waiting = waitingForInvite || waitingToEnter;
|
||||||
|
|
||||||
// TODO: Unify this component with InCallView, so we can get slick joining
|
// TODO: Unify this component with InCallView, so we can get slick joining
|
||||||
// animations and don't have to feel bad about reusing its CSS
|
// animations and don't have to feel bad about reusing its CSS
|
||||||
return (
|
return (
|
||||||
@@ -212,11 +220,12 @@ export const LobbyView: FC<Props> = ({
|
|||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
className={classNames(styles.join, {
|
className={classNames(styles.join, {
|
||||||
[styles.wait]: waitingForInvite,
|
[styles.wait]: waiting,
|
||||||
})}
|
})}
|
||||||
size={waitingForInvite ? "sm" : "lg"}
|
size={waiting ? "sm" : "lg"}
|
||||||
|
disabled={waiting}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!waitingForInvite) onEnter();
|
if (!waiting) onEnterCall();
|
||||||
}}
|
}}
|
||||||
data-testid="lobby_joinCall"
|
data-testid="lobby_joinCall"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -150,35 +150,34 @@ export const RoomPage: FC = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
muteStates && (
|
muteStates && <LobbyView
|
||||||
<LobbyView
|
client={client!}
|
||||||
client={client!}
|
matrixInfo={{
|
||||||
matrixInfo={{
|
userId: client!.getUserId() ?? "",
|
||||||
userId: client!.getUserId() ?? "",
|
displayName: userDisplayName ?? "",
|
||||||
displayName: userDisplayName ?? "",
|
avatarUrl: avatarUrl ?? "",
|
||||||
avatarUrl: avatarUrl ?? "",
|
roomAlias: null,
|
||||||
roomAlias: null,
|
roomId: groupCallState.roomSummary.room_id,
|
||||||
roomId: groupCallState.roomSummary.room_id,
|
roomName: groupCallState.roomSummary.name ?? "",
|
||||||
roomName: groupCallState.roomSummary.name ?? "",
|
roomAvatar: groupCallState.roomSummary.avatar_url ?? null,
|
||||||
roomAvatar: groupCallState.roomSummary.avatar_url ?? null,
|
e2eeSystem: {
|
||||||
e2eeSystem: {
|
kind: groupCallState.roomSummary["im.nheko.summary.encryption"]
|
||||||
kind: groupCallState.roomSummary[
|
? E2eeType.PER_PARTICIPANT
|
||||||
"im.nheko.summary.encryption"
|
: E2eeType.NONE,
|
||||||
]
|
},
|
||||||
? E2eeType.PER_PARTICIPANT
|
}}
|
||||||
: E2eeType.NONE,
|
onEnter={async (): Promise<void> => {
|
||||||
},
|
knock?.();
|
||||||
}}
|
return Promise.resolve();
|
||||||
onEnter={(): void => knock?.()}
|
}}
|
||||||
enterLabel={label}
|
enterLabel={label}
|
||||||
waitingForInvite={groupCallState.kind === "waitForInvite"}
|
waitingForInvite={groupCallState.kind === "waitForInvite"}
|
||||||
confineToRoom={confineToRoom}
|
confineToRoom={confineToRoom}
|
||||||
hideHeader={header !== "standard"}
|
hideHeader={header !== "standard"}
|
||||||
participantCount={null}
|
participantCount={null}
|
||||||
muteStates={muteStates}
|
muteStates={muteStates}
|
||||||
onShareClick={null}
|
onShareClick={null}
|
||||||
/>
|
/>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case "loading":
|
case "loading":
|
||||||
|
|||||||
@@ -528,10 +528,12 @@ export class CallViewModel extends ViewModel {
|
|||||||
multiSfu.value$,
|
multiSfu.value$,
|
||||||
],
|
],
|
||||||
(preferred, memberships, multiSfu) => {
|
(preferred, memberships, multiSfu) => {
|
||||||
|
const oldestMembership =
|
||||||
|
this.matrixRTCSession.getOldestMembership();
|
||||||
const remote = memberships.flatMap((m) => {
|
const remote = memberships.flatMap((m) => {
|
||||||
if (m.sender === this.userId && m.deviceId === this.deviceId)
|
if (m.sender === this.userId && m.deviceId === this.deviceId)
|
||||||
return [];
|
return [];
|
||||||
const t = this.matrixRTCSession.resolveActiveFocus(m);
|
const t = m.getTransport(oldestMembership ?? m);
|
||||||
return t && isLivekitTransport(t)
|
return t && isLivekitTransport(t)
|
||||||
? [{ membership: m, transport: t }]
|
? [{ membership: m, transport: t }]
|
||||||
: [];
|
: [];
|
||||||
@@ -633,10 +635,11 @@ export class CallViewModel extends ViewModel {
|
|||||||
// Until the local transport becomes ready we have no idea which
|
// Until the local transport becomes ready we have no idea which
|
||||||
// transports will actually need a dedicated remote connection
|
// transports will actually need a dedicated remote connection
|
||||||
if (transports?.local.state === "ready") {
|
if (transports?.local.state === "ready") {
|
||||||
|
const oldestMembership = this.matrixRTCSession.getOldestMembership();
|
||||||
const localServiceUrl = transports.local.value.livekit_service_url;
|
const localServiceUrl = transports.local.value.livekit_service_url;
|
||||||
const remoteServiceUrls = new Set(
|
const remoteServiceUrls = new Set(
|
||||||
transports.remote.flatMap(({ membership, transport }) => {
|
transports.remote.flatMap(({ membership, transport }) => {
|
||||||
const t = this.matrixRTCSession.resolveActiveFocus(membership);
|
const t = membership.getTransport(oldestMembership ?? membership);
|
||||||
return t &&
|
return t &&
|
||||||
isLivekitTransport(t) &&
|
isLivekitTransport(t) &&
|
||||||
t.livekit_service_url !== localServiceUrl
|
t.livekit_service_url !== localServiceUrl
|
||||||
|
|||||||
@@ -99,7 +99,19 @@ export class ObservableScope {
|
|||||||
.subscribe(callback);
|
.subscribe(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO-MULTI-SFU Dear Future Robin, please document this. Love, Past Robin.
|
/**
|
||||||
|
* For the duration of the scope, sync some external state with the value of
|
||||||
|
* the provided Behavior by way of an async function which attempts to update
|
||||||
|
* (reconcile) the external state. The reconciliation function may return a
|
||||||
|
* clean-up callback which will be called and awaited before the next change
|
||||||
|
* in value (or the end of the scope).
|
||||||
|
*
|
||||||
|
* All calls to the function and its clean-up callbacks are serialized. If the
|
||||||
|
* value changes faster than the handlers can keep up with, intermediate
|
||||||
|
* values may be skipped.
|
||||||
|
*
|
||||||
|
* Basically, this is like React's useEffect but async and for Behaviors.
|
||||||
|
*/
|
||||||
public reconcile<T>(
|
public reconcile<T>(
|
||||||
value$: Behavior<T>,
|
value$: Behavior<T>,
|
||||||
callback: (value: T) => Promise<(() => Promise<void>) | undefined>,
|
callback: (value: T) => Promise<(() => Promise<void>) | undefined>,
|
||||||
@@ -107,27 +119,27 @@ export class ObservableScope {
|
|||||||
let latestValue: T | typeof nothing = nothing;
|
let latestValue: T | typeof nothing = nothing;
|
||||||
let reconciledValue: T | typeof nothing = nothing;
|
let reconciledValue: T | typeof nothing = nothing;
|
||||||
let cleanUp: (() => Promise<void>) | undefined = undefined;
|
let cleanUp: (() => Promise<void>) | undefined = undefined;
|
||||||
let callbackPromise: Promise<(() => Promise<void>) | undefined>;
|
|
||||||
value$
|
value$
|
||||||
.pipe(
|
.pipe(
|
||||||
catchError(() => EMPTY),
|
catchError(() => EMPTY), // Ignore errors
|
||||||
this.bind(),
|
this.bind(), // Limit to the duration of the scope
|
||||||
endWith(nothing),
|
endWith(nothing), // Clean up when the scope ends
|
||||||
)
|
)
|
||||||
.subscribe((value) => {
|
.subscribe((value) => {
|
||||||
void (async (): Promise<void> => {
|
void (async (): Promise<void> => {
|
||||||
if (latestValue === nothing) {
|
if (latestValue === nothing) {
|
||||||
latestValue = value;
|
latestValue = value;
|
||||||
while (latestValue !== reconciledValue) {
|
while (latestValue !== reconciledValue) {
|
||||||
await cleanUp?.();
|
await cleanUp?.(); // Call the previous value's clean-up handler
|
||||||
reconciledValue = latestValue;
|
reconciledValue = latestValue;
|
||||||
if (latestValue !== nothing) {
|
if (latestValue !== nothing)
|
||||||
callbackPromise = callback(latestValue);
|
cleanUp = await callback(latestValue); // Sync current value
|
||||||
cleanUp = await callbackPromise;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Reset to signal that reconciliation is done for now
|
||||||
latestValue = nothing;
|
latestValue = nothing;
|
||||||
} else {
|
} else {
|
||||||
|
// There's already an instance of the above 'while' loop running
|
||||||
|
// concurrently. Just update the latest value and let it be handled.
|
||||||
latestValue = value;
|
latestValue = value;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@@ -7545,7 +7545,7 @@ __metadata:
|
|||||||
livekit-client: "npm:^2.13.0"
|
livekit-client: "npm:^2.13.0"
|
||||||
lodash-es: "npm:^4.17.21"
|
lodash-es: "npm:^4.17.21"
|
||||||
loglevel: "npm:^1.9.1"
|
loglevel: "npm:^1.9.1"
|
||||||
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#head=voip-team/multi-SFU"
|
matrix-js-sdk: "github:matrix-org/matrix-js-sdk#head=toger5/use-relation-based-CallMembership-create-ts"
|
||||||
matrix-widget-api: "npm:^1.13.0"
|
matrix-widget-api: "npm:^1.13.0"
|
||||||
normalize.css: "npm:^8.0.1"
|
normalize.css: "npm:^8.0.1"
|
||||||
observable-hooks: "npm:^4.2.3"
|
observable-hooks: "npm:^4.2.3"
|
||||||
@@ -10335,9 +10335,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=voip-team/multi-SFU":
|
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=toger5/use-relation-based-CallMembership-create-ts":
|
||||||
version: 38.3.0
|
version: 38.4.0
|
||||||
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=4643844597f8bd0196714ecc1c7fafd3f3f6669d"
|
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=4608506288c6beaa252982d224e996e23e51f681"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": "npm:^7.12.5"
|
"@babel/runtime": "npm:^7.12.5"
|
||||||
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^15.3.0"
|
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^15.3.0"
|
||||||
@@ -10353,7 +10353,7 @@ __metadata:
|
|||||||
sdp-transform: "npm:^2.14.1"
|
sdp-transform: "npm:^2.14.1"
|
||||||
unhomoglyph: "npm:^1.0.6"
|
unhomoglyph: "npm:^1.0.6"
|
||||||
uuid: "npm:13"
|
uuid: "npm:13"
|
||||||
checksum: 10c0/90d6feb7c5214b2fce7b8d6394c88d39a538224dac464e2a5315fb63388126999da28284bc9b7443e035ad0f24c21c1c7d9e1ad4245ee854595e73a390f48c2a
|
checksum: 10c0/2e896d6a92cb3bbb47c120a39dd1a0030b4bf02289cb914f6c848b564208f421ada605e8efb68f6d9d55a0d2e3f86698b6076cb029e9bab2bac0f70f7250dd17
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user