diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index eac5b86e..7d1be2a9 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v4 - name: Log in to container registry - uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb + uses: docker/login-action@83a00bc1ab5ded6580f31df1c49e6aaa932d840d with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -54,7 +54,7 @@ jobs: tar --numeric-owner --transform "s/dist/element-call-${TARBALL_VERSION}/" -cvzf element-call-${TARBALL_VERSION}.tar.gz dist - name: Upload - uses: actions/upload-artifact@4c0ff1c489dca52fedb26375d7d8fe7bd9233f19 + uses: actions/upload-artifact@ef09cdac3e2d3e60d8ccadda691f4f1cec5035cb env: GITHUB_TOKEN: ${{ github.token }} with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d37aa75c..85385cb5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,11 +1,11 @@ -name: Run jest tests +name: Run unit tests on: pull_request: {} push: branches: [livekit, full-mesh] jobs: - jest: - name: Run jest tests + vitest: + name: Run vitest tests runs-on: ubuntu-latest steps: - name: Checkout code @@ -16,7 +16,7 @@ jobs: cache: "yarn" - name: Install dependencies run: "yarn install" - - name: Jest + - name: Vitest run: "yarn run test" - name: Upload to codecov uses: codecov/codecov-action@v4 diff --git a/package.json b/package.json index 11ed3ff1..372dc61e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "lint:types": "tsc", "i18n": "node_modules/i18next-parser/bin/cli.js", "i18n:check": "node_modules/i18next-parser/bin/cli.js --fail-on-warnings --fail-on-update", - "test": "jest", + "test": "vitest", + "test:coverage": "vitest run --coverage", "backend": "docker-compose -f backend-docker-compose.yml up" }, "dependencies": { @@ -88,21 +89,19 @@ "@react-spring/rafz": "^9.7.3", "@react-types/dialog": "^3.5.5", "@sentry/vite-plugin": "^2.0.0", - "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.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/jest": "^29.5.5", "@types/node": "^20.0.0", "@types/react-router-dom": "^5.3.3", "@types/request": "^2.48.8", "@types/sdp-transform": "^2.4.5", "@types/uuid": "9", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", "babel-loader": "^9.0.0", "babel-plugin-transform-vite-meta-env": "^1.0.3", "eslint": "^8.14.0", @@ -116,37 +115,14 @@ "eslint-plugin-react-hooks": "^4.5.0", "eslint-plugin-unicorn": "^51.0.0", "i18next-parser": "^8.0.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^29.2.2", - "jest-environment-jsdom": "^29.3.1", - "jest-mock": "^29.5.0", + "jsdom": "^24.0.0", "prettier": "^3.0.0", "sass": "^1.42.1", "typescript": "^5.1.6", "typescript-eslint-language-service": "^5.0.5", "vite": "^5.0.0", "vite-plugin-html-template": "^1.1.0", - "vite-plugin-svgr": "^4.0.0" - }, - "jest": { - "testEnvironment": "./test/environment.ts", - "testMatch": [ - "/test/**/*-test.[jt]s?(x)" - ], - "transformIgnorePatterns": [ - "/node_modules/(?!d3)+$", - "/node_modules/(?!internmap)+$" - ], - "moduleNameMapper": { - "\\.css$": "identity-obj-proxy", - "\\.svg\\?react$": "/test/mocks/svgr.ts", - "^\\./IndexedDBWorker\\?worker$": "/test/mocks/workerMock.ts", - "^\\./olm$": "/test/mocks/olmMock.ts" - }, - "collectCoverage": true, - "coverageReporters": [ - "text", - "cobertura" - ] + "vite-plugin-svgr": "^4.0.0", + "vitest": "^1.2.2" } } diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index 9dca0a19..0acb3006 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -143,6 +143,7 @@ "unmute_microphone_button_label": "Unmute microphone", "version": "Version: {{version}}", "video_tile": { + "change_fit_contain": "Crop to fit", "exit_full_screen": "Exit full screen", "full_screen": "Full screen", "mute_for_me": "Mute for me", diff --git a/src/matrix-utils.ts b/src/matrix-utils.ts index 08af1750..48c51d15 100644 --- a/src/matrix-utils.ts +++ b/src/matrix-utils.ts @@ -188,16 +188,8 @@ export async function initClient( await client.store.startup(); } - if (client.initCrypto) { - await client.initCrypto(); - } - - await client.startClient({ - // dirty hack to reduce chance of gappy syncs - // should be fixed by spotting gaps and backpaginating - initialSyncLimit: 50, - }); - + await client.initCrypto(); + await client.startClient(); await waitForSync(client); return client; diff --git a/src/room/RoomAuthView.tsx b/src/room/RoomAuthView.tsx index 2b17e54a..272b82e4 100644 --- a/src/room/RoomAuthView.tsx +++ b/src/room/RoomAuthView.tsx @@ -41,6 +41,8 @@ export const RoomAuthView: FC = () => { // @ts-ignore (e) => { e.preventDefault(); + setLoading(true); + const data = new FormData(e.target); const dataForDisplayName = data.get("displayName"); const displayName = diff --git a/src/state/TileViewModel.ts b/src/state/TileViewModel.ts index 1343fb38..59c48bdc 100644 --- a/src/state/TileViewModel.ts +++ b/src/state/TileViewModel.ts @@ -167,6 +167,12 @@ export class UserMediaTileViewModel extends BaseTileViewModel { */ public readonly videoEnabled: StateObservable; + private readonly _cropVideo = new BehaviorSubject(true); + /** + * Whether the tile video should be contained inside the tile or be cropped to fit. + */ + public readonly cropVideo = state(this._cropVideo); + public constructor( id: string, member: RoomMember | undefined, @@ -205,6 +211,10 @@ export class UserMediaTileViewModel extends BaseTileViewModel { this._locallyMuted.next(!this._locallyMuted.value); } + public toggleFitContain(): void { + this._cropVideo.next(!this._cropVideo.value); + } + public setLocalVolume(value: number): void { this._localVolume.next(value); } diff --git a/src/video-grid/VideoTile.module.css b/src/video-grid/VideoTile.module.css index 9e30c6e1..b4da6e5e 100644 --- a/src/video-grid/VideoTile.module.css +++ b/src/video-grid/VideoTile.module.css @@ -73,7 +73,7 @@ borders don't support gradients */ .videoTile video { inline-size: 100%; block-size: 100%; - object-fit: cover; + object-fit: contain; background-color: var(--cpd-color-bg-subtle-primary); /* This transform is a no-op, but it forces Firefox to use a different rendering path, one that actually clips the corners of