Merge branch 'develop' into mention-text-and-pills-ux
|
@ -1,60 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["./.eslintrc.js"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: ["matrix-js-sdk/lib", "matrix-js-sdk/lib/", "matrix-js-sdk/lib/**"],
|
||||
message: "Please use matrix-js-sdk/src/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
57
.eslintrc.js
|
@ -266,6 +266,63 @@ module.exports = {
|
|||
parserOptions: {
|
||||
project: ["./playwright/tsconfig.json"],
|
||||
},
|
||||
rules: {
|
||||
"react-hooks/rules-of-hooks": ["off"],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: ["matrix-js-sdk/lib", "matrix-js-sdk/lib/", "matrix-js-sdk/lib/**"],
|
||||
message: "Please use matrix-js-sdk/src/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
|
|
|
@ -21,13 +21,13 @@ jobs:
|
|||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3
|
||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3
|
||||
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
report:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled'
|
||||
name: Report results
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
statuses: write
|
||||
|
|
|
@ -36,7 +36,7 @@ env:
|
|||
jobs:
|
||||
build:
|
||||
name: "Build Element-Web"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
if: inputs.skip != true
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
@ -69,7 +69,6 @@ jobs:
|
|||
VERSION: "${{ steps.layered_build.outputs.VERSION }}"
|
||||
run: |
|
||||
yarn build
|
||||
echo $VERSION > webapp/version
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -144,7 +143,7 @@ jobs:
|
|||
name: end-to-end-tests
|
||||
needs: playwright
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
if: inputs.skip != true
|
||||
|
|
|
@ -9,7 +9,7 @@ on:
|
|||
jobs:
|
||||
deploy:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled' && github.event.workflow_run.event == 'pull_request'
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Netlify
|
||||
steps:
|
||||
- name: 📝 Create Deployment
|
||||
|
|
|
@ -5,7 +5,7 @@ on:
|
|||
- cron: "0 6 * * *" # Every day at 6am UTC
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ on:
|
|||
jobs:
|
||||
check_base_branch:
|
||||
name: Check PR base branch
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
|
|
|
@ -49,7 +49,7 @@ jobs:
|
|||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "Docker Buildx (vanilla)"
|
||||
check-name: "Docker Buildx"
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for debian package
|
||||
|
|
|
@ -20,6 +20,9 @@ on:
|
|||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
# The order is specified bottom-up to avoid any races for allchange
|
||||
REPOS: matrix-js-sdk element-web element-desktop
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@v4
|
||||
|
|
|
@ -34,27 +34,6 @@ jobs:
|
|||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
- name: Switch js-sdk to release mode
|
||||
working-directory: node_modules/matrix-js-sdk
|
||||
run: |
|
||||
scripts/switch_package_to_release.cjs
|
||||
yarn install
|
||||
yarn run build:compile
|
||||
yarn run build:types
|
||||
|
||||
- name: Typecheck (release mode)
|
||||
run: "yarn run lint:types"
|
||||
|
||||
# Temporary while we directly import matrix-js-sdk/src/* which means we need
|
||||
# certain @types/* packages to make sense of matrix-js-sdk types.
|
||||
#- name: Typecheck (release mode; no yarn link)
|
||||
# if: github.event_name != 'pull_request' && github.ref_name != 'master'
|
||||
# run: |
|
||||
# yarn unlink matrix-js-sdk
|
||||
# yarn add github:matrix-org/matrix-js-sdk#develop
|
||||
# yarn install --force
|
||||
# yarn run lint:types
|
||||
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/i18n_check.yml@main
|
||||
|
@ -71,7 +50,7 @@ jobs:
|
|||
|
||||
rethemendex_lint:
|
||||
name: "Rethemendex Check"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
@ -144,6 +123,12 @@ jobs:
|
|||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run linter
|
||||
run: "yarn run lint:knip"
|
||||
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ env:
|
|||
jobs:
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -93,7 +93,7 @@ jobs:
|
|||
name: jest-tests
|
||||
needs: jest
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- if: needs.jest.result != 'skipped' && needs.jest.result != 'success'
|
||||
run: exit 1
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
"*": "prettier --write",
|
||||
"src/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"scripts/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"module_system/**/*.(ts|tsx)": ["eslint --fix --config .eslintrc-module_system.js module_system"],
|
||||
"module_system/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"*.pcss": ["stylelint --fix"]
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
20
|
||||
22
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
extends: ["stylelint-config-standard"],
|
||||
customSyntax: require("postcss-scss"),
|
||||
customSyntax: "postcss-scss",
|
||||
plugins: ["stylelint-scss"],
|
||||
rules: {
|
||||
"comment-empty-line-before": null,
|
||||
|
|
73
CHANGELOG.md
|
@ -1,3 +1,76 @@
|
|||
Changes in [1.11.85](https://github.com/element-hq/element-web/releases/tag/v1.11.85) (2024-11-12)
|
||||
==================================================================================================
|
||||
# Security
|
||||
- Fixes for [CVE-2024-51750](https://www.cve.org/CVERecord?id=CVE-2024-51750) / [GHSA-w36j-v56h-q9pc](https://github.com/element-hq/element-web/security/advisories/GHSA-w36j-v56h-q9pc)
|
||||
- Fixes for [CVE-2024-51749](https://www.cve.org/CVERecord?id=CVE-2024-51749) / [GHSA-5486-384g-mcx2](https://github.com/element-hq/element-web/security/advisories/GHSA-5486-384g-mcx2)
|
||||
- Update JS SDK with the fixes for [CVE-2024-50336](https://www.cve.org/CVERecord?id=CVE-2024-50336) / [GHSA-xvg8-m4x3-w6xr](https://github.com/matrix-org/matrix-js-sdk/security/advisories/GHSA-xvg8-m4x3-w6xr)
|
||||
|
||||
|
||||
Changes in [1.11.84](https://github.com/element-hq/element-web/releases/tag/v1.11.84) (2024-11-05)
|
||||
==================================================================================================
|
||||
## ✨ Features
|
||||
|
||||
* Remove abandoned MSC3886, MSC3903, MSC3906 implementations ([#28274](https://github.com/element-hq/element-web/pull/28274)). Contributed by @t3chguy.
|
||||
* Update to React 18 ([#24763](https://github.com/element-hq/element-web/pull/24763)). Contributed by @t3chguy.
|
||||
* Deduplicate icons using Compound ([#28239](https://github.com/element-hq/element-web/pull/28239)). Contributed by @t3chguy.
|
||||
* Replace legacy Tooltips with Compound tooltips ([#28231](https://github.com/element-hq/element-web/pull/28231)). Contributed by @t3chguy.
|
||||
* Deduplicate icons using Compound Design Tokens ([#28219](https://github.com/element-hq/element-web/pull/28219)). Contributed by @t3chguy.
|
||||
* Add reactions to html export ([#28210](https://github.com/element-hq/element-web/pull/28210)). Contributed by @langleyd.
|
||||
* Remove feature\_dehydration ([#28173](https://github.com/element-hq/element-web/pull/28173)). Contributed by @florianduros.
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
* Remove upgrade encryption in `DeviceListener` and `SetupEncryptionToast` ([#28299](https://github.com/element-hq/element-web/pull/28299)). Contributed by @florianduros.
|
||||
* Fix 'remove alias' button in room settings ([#28269](https://github.com/element-hq/element-web/pull/28269)). Contributed by @Dev-Gurjar.
|
||||
* Add back unencrypted path in `StopGapWidgetDriver.sendToDevice` ([#28295](https://github.com/element-hq/element-web/pull/28295)). Contributed by @florianduros.
|
||||
* Fix other devices not being decorated as such ([#28279](https://github.com/element-hq/element-web/pull/28279)). Contributed by @t3chguy.
|
||||
* Fix pill contrast in invitation dialog ([#28250](https://github.com/element-hq/element-web/pull/28250)). Contributed by @florianduros.
|
||||
* Close right panel chat when minimising maximised voip widget ([#28241](https://github.com/element-hq/element-web/pull/28241)). Contributed by @t3chguy.
|
||||
* Fix develop changelog parsing ([#28232](https://github.com/element-hq/element-web/pull/28232)). Contributed by @t3chguy.
|
||||
* Fix Ctrl+F shortcut not working with minimised room summary card ([#28223](https://github.com/element-hq/element-web/pull/28223)). Contributed by @t3chguy.
|
||||
* Fix network dropdown missing checkbox \& aria-checked ([#28220](https://github.com/element-hq/element-web/pull/28220)). Contributed by @t3chguy.
|
||||
|
||||
|
||||
Changes in [1.11.83](https://github.com/element-hq/element-web/releases/tag/v1.11.83) (2024-10-29)
|
||||
==================================================================================================
|
||||
## ✨ Features
|
||||
|
||||
* Enable Element Call by default on release instances ([#28314](https://github.com/element-hq/element-web/pull/28314)). Contributed by @t3chguy.
|
||||
|
||||
|
||||
|
||||
Changes in [1.11.82](https://github.com/element-hq/element-web/releases/tag/v1.11.82) (2024-10-22)
|
||||
==================================================================================================
|
||||
## ✨ Features
|
||||
|
||||
* Deduplicate more icons using Compound Design Tokens ([#132](https://github.com/element-hq/matrix-react-sdk/pull/132)). Contributed by @t3chguy.
|
||||
* Always show link new device flow even if unsupported ([#147](https://github.com/element-hq/matrix-react-sdk/pull/147)). Contributed by @t3chguy.
|
||||
* Update design of files list in right panel ([#144](https://github.com/element-hq/matrix-react-sdk/pull/144)). Contributed by @t3chguy.
|
||||
* Remove feature\_dehydration ([#138](https://github.com/element-hq/matrix-react-sdk/pull/138)). Contributed by @florianduros.
|
||||
* Upgrade emojibase-bindings and remove local handling of emoticon variations ([#127](https://github.com/element-hq/matrix-react-sdk/pull/127)). Contributed by @langleyd.
|
||||
* Add support for rendering media captions ([#43](https://github.com/element-hq/matrix-react-sdk/pull/43)). Contributed by @tulir.
|
||||
* Replace composer icons with Compound variants ([#123](https://github.com/element-hq/matrix-react-sdk/pull/123)). Contributed by @t3chguy.
|
||||
* Tweak default right panel size to be 320px except for maximised widgets at 420px ([#110](https://github.com/element-hq/matrix-react-sdk/pull/110)). Contributed by @t3chguy.
|
||||
* Add a pinned message badge under a pinned message ([#118](https://github.com/element-hq/matrix-react-sdk/pull/118)). Contributed by @florianduros.
|
||||
* Ditch right panel tabs and re-add close button ([#99](https://github.com/element-hq/matrix-react-sdk/pull/99)). Contributed by @t3chguy.
|
||||
* Force verification even for refreshed clients ([#44](https://github.com/element-hq/matrix-react-sdk/pull/44)). Contributed by @dbkr.
|
||||
* Update emoji text, border and background colour in timeline ([#119](https://github.com/element-hq/matrix-react-sdk/pull/119)). Contributed by @florianduros.
|
||||
* Disable ICE fallback based on well-known configuration ([#111](https://github.com/element-hq/matrix-react-sdk/pull/111)). Contributed by @t3chguy.
|
||||
* Remove legacy room header and promote beta room header ([#105](https://github.com/element-hq/matrix-react-sdk/pull/105)). Contributed by @t3chguy.
|
||||
* Respect `io.element.jitsi` `useFor1To1Calls` in well-known ([#112](https://github.com/element-hq/matrix-react-sdk/pull/112)). Contributed by @t3chguy.
|
||||
* Use Compound close icon in favour of mishmash of x/close icons ([#108](https://github.com/element-hq/matrix-react-sdk/pull/108)). Contributed by @t3chguy.
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
* Correct typo in option documentation ([#28148](https://github.com/element-hq/element-web/pull/28148)). Contributed by @AndrewKvalheim.
|
||||
* Revert #124 and #135 ([#139](https://github.com/element-hq/matrix-react-sdk/pull/139)). Contributed by @dbkr.
|
||||
* Add aria-label to e2e icon ([#136](https://github.com/element-hq/matrix-react-sdk/pull/136)). Contributed by @florianduros.
|
||||
* Fix bell icons on room list hover being black squares ([#135](https://github.com/element-hq/matrix-react-sdk/pull/135)). Contributed by @dbkr.
|
||||
* Fix vertical overflow on the mobile register screen ([#137](https://github.com/element-hq/matrix-react-sdk/pull/137)). Contributed by @langleyd.
|
||||
* Allow to unpin redacted event ([#98](https://github.com/element-hq/matrix-react-sdk/pull/98)). Contributed by @florianduros.
|
||||
|
||||
|
||||
|
||||
Changes in [1.11.81](https://github.com/element-hq/element-web/releases/tag/v1.11.81) (2024-10-15)
|
||||
==================================================================================================
|
||||
This release fixes High severity vulnerability CVE-2024-47771 / GHSA-963w-49j9-gxj6
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:20-bullseye as builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye as builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
{
|
||||
"src/components/views/auth/AuthFooter.tsx": "src/components/views/auth/VectorAuthFooter.tsx",
|
||||
"src/components/views/auth/AuthHeaderLogo.tsx": "src/components/views/auth/VectorAuthHeaderLogo.tsx",
|
||||
"src/components/views/auth/AuthPage.tsx": "src/components/views/auth/VectorAuthPage.tsx"
|
||||
}
|
||||
{}
|
||||
|
|
|
@ -11,8 +11,8 @@ Customisations will be removed from the codebase in a future release.
|
|||
Element Web and the React SDK support "customisation points" that can be used to
|
||||
easily add custom logic specific to a particular deployment of Element Web.
|
||||
|
||||
An example of this is the [security customisations
|
||||
module](https://github.com/element-hq/element-web/blob/develop/src/customisations/Security.ts).
|
||||
An example of this is the [media customisations
|
||||
module](https://github.com/element-hq/element-web/blob/develop/src/customisations/Media.ts).
|
||||
This module in the React SDK only defines some empty functions and their types:
|
||||
it does not do anything by default.
|
||||
|
||||
|
@ -21,14 +21,14 @@ Web so that you can add your own code. Even though the default module is part of
|
|||
the React SDK, you can still override it from the Element Web layer:
|
||||
|
||||
1. Copy the default customisation module to
|
||||
`element-web/src/customisations/YourNameSecurity.ts`
|
||||
`element-web/src/customisations/YourNameMedia.ts`
|
||||
2. Edit customisations points and make sure export the ones you actually want to
|
||||
activate
|
||||
3. Create/add an entry to `customisations.json` next to the webpack config:
|
||||
|
||||
```json
|
||||
{
|
||||
"src/customisations/Security.ts": "src/customisations/YourNameSecurity.ts"
|
||||
"src/customisations/Media.ts": "src/customisations/YourNameMedia.ts"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -41,7 +41,15 @@ The Docker image can be used to serve element-web as a web server. The easiest w
|
|||
it is to use the prebuilt image:
|
||||
|
||||
```bash
|
||||
docker run -p 80:80 vectorim/element-web
|
||||
docker run --rm -p 127.0.0.1:80:80 vectorim/element-web
|
||||
```
|
||||
|
||||
A server can also be made available to clients outside the local host by omitting the
|
||||
explicit local address as described in
|
||||
[docker run documentation](https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose):
|
||||
|
||||
```bash
|
||||
docker run --rm -p 80:80 vectorim/element-web
|
||||
```
|
||||
|
||||
To supply your own custom `config.json`, map a volume to `/app/config.json`. For example,
|
||||
|
@ -49,7 +57,7 @@ if your custom config was located at `/etc/element-web/config.json` then your Do
|
|||
would be:
|
||||
|
||||
```bash
|
||||
docker run -p 80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
docker run --rm -p 127.0.0.1:80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
```
|
||||
|
||||
To build the image yourself:
|
||||
|
|
|
@ -29,7 +29,7 @@ default theme, you would use `default_theme: "custom-Electric Blue"`.
|
|||
|
||||
e.g. in config.json:
|
||||
|
||||
```
|
||||
```json5
|
||||
"setting_defaults": {
|
||||
"custom_themes": [
|
||||
{
|
||||
|
@ -59,6 +59,10 @@ e.g. in config.json:
|
|||
"timeline-text-color": "#2e2f32",
|
||||
"timeline-text-secondary-color": "#61708b",
|
||||
"timeline-highlights-color": "#f3f8fd",
|
||||
|
||||
// These should both be 8 values long
|
||||
"username-colors": ["#ff0000", /*...*/],
|
||||
"avatar-background-colors": ["#cc0000", /*...*/]
|
||||
},
|
||||
"compound": {
|
||||
"--cpd-color-icon-accent-tertiary": "var(--cpd-color-blue-800)",
|
||||
|
|
|
@ -46,5 +46,13 @@
|
|||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
|
||||
"setting_defaults": {
|
||||
"RustCrypto.staged_rollout_percent": 60
|
||||
},
|
||||
"features": {
|
||||
"feature_video_rooms": true,
|
||||
"feature_group_calls": true,
|
||||
"feature_element_call_video_rooms": true
|
||||
},
|
||||
"element_call": {
|
||||
"url": "https://call.element.io"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ const config: Config = {
|
|||
"recorderWorkletFactory": "<rootDir>/__mocks__/empty.js",
|
||||
"^fetch-mock$": "<rootDir>/node_modules/fetch-mock",
|
||||
},
|
||||
transformIgnorePatterns: ["/node_modules/(?!matrix-js-sdk).+$"],
|
||||
transformIgnorePatterns: ["/node_modules/(?!(mime|matrix-js-sdk)).+$"],
|
||||
collectCoverageFrom: [
|
||||
"<rootDir>/src/**/*.{js,ts,tsx}",
|
||||
// getSessionLock is piped into a different JS context via stringification, and the coverage functionality is
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { KnipConfig } from "knip";
|
||||
|
||||
export default {
|
||||
entry: [
|
||||
"src/vector/index.ts",
|
||||
"src/serviceworker/index.ts",
|
||||
"src/workers/*.worker.ts",
|
||||
"src/utils/exportUtils/exportJS.js",
|
||||
"scripts/**",
|
||||
"playwright/**",
|
||||
"test/**",
|
||||
"res/decoder-ring/**",
|
||||
],
|
||||
project: ["**/*.{js,ts,jsx,tsx}"],
|
||||
ignore: [
|
||||
"docs/**",
|
||||
"res/jitsi_external_api.min.js",
|
||||
// Used by jest
|
||||
"__mocks__/maplibre-gl.js",
|
||||
// Keep for now
|
||||
"src/hooks/useLocalStorageState.ts",
|
||||
"src/components/views/elements/InfoTooltip.tsx",
|
||||
"src/components/views/elements/StyledCheckbox.tsx",
|
||||
],
|
||||
ignoreDependencies: [
|
||||
// Required for `action-validator`
|
||||
"@action-validator/*",
|
||||
// Used for git pre-commit hooks
|
||||
"husky",
|
||||
// Used by jest
|
||||
"babel-jest",
|
||||
// Used by babel
|
||||
"@babel/runtime",
|
||||
"@babel/plugin-transform-class-properties",
|
||||
// Referenced in PCSS
|
||||
"github-markdown-css",
|
||||
// False positive
|
||||
"sw.js",
|
||||
// Used by webpack
|
||||
"buffer",
|
||||
"process",
|
||||
"util",
|
||||
// Used by workflows
|
||||
"ts-prune",
|
||||
// Required due to bug in bloom-filters https://github.com/Callidon/bloom-filters/issues/75
|
||||
"@types/seedrandom",
|
||||
],
|
||||
ignoreBinaries: [
|
||||
// Used in scripts & workflows
|
||||
"jq",
|
||||
],
|
||||
ignoreExportsUsedInFile: true,
|
||||
} satisfies KnipConfig;
|
57
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "element-web",
|
||||
"version": "1.11.81",
|
||||
"version": "1.11.85",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "New Vector Ltd.",
|
||||
"repository": {
|
||||
|
@ -35,7 +35,7 @@
|
|||
"i18n:lint": "matrix-i18n-lint && prettier --log-level=silent --write src/i18n/strings/ --ignore-path /dev/null",
|
||||
"i18n:diff": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && yarn i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
|
||||
"make-component": "node scripts/make-react-component.js",
|
||||
"rethemendex": "res/css/rethemendex.sh",
|
||||
"rethemendex": "./res/css/rethemendex.sh",
|
||||
"clean": "rimraf lib webapp",
|
||||
"build": "yarn clean && yarn build:genfiles && yarn build:bundle",
|
||||
"build-stats": "yarn clean && yarn build:genfiles && yarn build:bundle-stats",
|
||||
|
@ -45,23 +45,20 @@
|
|||
"build:bundle": "webpack --progress --mode production",
|
||||
"build:bundle-stats": "webpack --progress --mode production --json > webpack-stats.json",
|
||||
"build:module_system": "ts-node --project ./tsconfig.module_system.json module_system/scripts/install.ts",
|
||||
"dist": "scripts/package.sh",
|
||||
"dist": "./scripts/package.sh",
|
||||
"start": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n modules,res \"yarn build:module_system\" \"yarn build:res\" && concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n res,element-js \"yarn start:res\" \"yarn start:js\"",
|
||||
"start:https": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n res,element-js \"yarn start:res\" \"yarn start:js --server-type https\"",
|
||||
"start:res": "ts-node scripts/copy-res.ts -w",
|
||||
"start:js": "webpack serve --output-path webapp --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js --mode development",
|
||||
"lint": "yarn lint:types && yarn lint:js && yarn lint:style && yarn lint:workflows",
|
||||
"lint:js": "yarn lint:js:src && yarn lint:js:module_system",
|
||||
"lint:js:src": "eslint --max-warnings 0 src test playwright && prettier --check .",
|
||||
"lint:js:module_system": "eslint --max-warnings 0 --config .eslintrc-module_system.js module_system",
|
||||
"lint:js-fix": "yarn lint:js-fix:src && yarn lint:js-fix:module_system",
|
||||
"lint:js-fix:src": "prettier --log-level=warn --write . && eslint --fix src test playwright",
|
||||
"lint:js-fix:module_system": "eslint --fix --config .eslintrc-module_system.js module_system",
|
||||
"lint:js": "eslint --max-warnings 0 src test playwright module_system && prettier --check .",
|
||||
"lint:js-fix": "prettier --log-level=warn --write . && eslint --fix src test playwright module_system",
|
||||
"lint:types": "yarn lint:types:src && yarn lint:types:module_system",
|
||||
"lint:types:src": "tsc --noEmit --jsx react && tsc --noEmit --jsx react -p playwright",
|
||||
"lint:types:module_system": "tsc --noEmit --project ./tsconfig.module_system.json",
|
||||
"lint:style": "stylelint \"res/css/**/*.pcss\"",
|
||||
"lint:workflows": "find .github/workflows -type f \\( -iname '*.yaml' -o -iname '*.yml' \\) | xargs -I {} sh -c 'echo \"Linting {}\"; action-validator \"{}\"'",
|
||||
"lint:knip": "knip",
|
||||
"test": "jest",
|
||||
"test:playwright": "playwright test",
|
||||
"test:playwright:open": "yarn test:playwright --ui",
|
||||
|
@ -74,29 +71,28 @@
|
|||
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/seedrandom": "3.0.8",
|
||||
"oidc-client-ts": "3.1.0",
|
||||
"jwt-decode": "4.0.0",
|
||||
"caniuse-lite": "1.0.30001668",
|
||||
"caniuse-lite": "1.0.30001679",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
|
||||
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@formatjs/intl-segmenter": "^11.5.7",
|
||||
"@matrix-org/analytics-events": "^0.26.0",
|
||||
"@matrix-org/analytics-events": "^0.29.0",
|
||||
"@matrix-org/emojibase-bindings": "^1.3.3",
|
||||
"@vector-im/matrix-wysiwyg": "2.37.13",
|
||||
"@matrix-org/react-sdk-module-api": "^2.4.0",
|
||||
"@matrix-org/spec": "^1.7.0",
|
||||
"@sentry/browser": "^8.0.0",
|
||||
"@vector-im/compound-design-tokens": "^1.8.0",
|
||||
"@vector-im/compound-web": "^7.1.0",
|
||||
"@vector-im/compound-design-tokens": "^2.0.1",
|
||||
"@vector-im/compound-web": "^7.3.0",
|
||||
"@vector-im/matrix-wysiwyg": "2.37.13",
|
||||
"@zxcvbn-ts/core": "^3.0.4",
|
||||
"@zxcvbn-ts/language-common": "^3.0.4",
|
||||
"@zxcvbn-ts/language-en": "^3.0.2",
|
||||
"await-lock": "^2.1.0",
|
||||
"bloom-filters": "^3.0.1",
|
||||
"bloom-filters": "^3.0.3",
|
||||
"blurhash": "^2.0.3",
|
||||
"browserslist": "^4.23.2",
|
||||
"classnames": "^2.2.6",
|
||||
|
@ -114,8 +110,8 @@
|
|||
"highlight.js": "^11.3.1",
|
||||
"html-entities": "^2.0.0",
|
||||
"is-ip": "^3.1.0",
|
||||
"jsrsasign": "^11.0.0",
|
||||
"js-xxhash": "^4.0.0",
|
||||
"jsrsasign": "^11.0.0",
|
||||
"jszip": "^3.7.0",
|
||||
"katex": "^0.16.0",
|
||||
"linkify-element": "4.1.3",
|
||||
|
@ -123,19 +119,20 @@
|
|||
"linkify-string": "4.1.3",
|
||||
"linkifyjs": "4.1.3",
|
||||
"lodash": "^4.17.21",
|
||||
"maplibre-gl": "^2.0.0",
|
||||
"maplibre-gl": "^4.0.0",
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
"matrix-events-sdk": "0.0.1",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-widget-api": "^1.9.0",
|
||||
"matrix-widget-api": "^1.10.0",
|
||||
"memoize-one": "^6.0.0",
|
||||
"mime": "^4.0.4",
|
||||
"oidc-client-ts": "^3.0.1",
|
||||
"opus-recorder": "^8.0.3",
|
||||
"pako": "^2.0.3",
|
||||
"png-chunks-extract": "^1.0.0",
|
||||
"posthog-js": "1.157.2",
|
||||
"qrcode": "1.5.4",
|
||||
"re-resizable": "6.9.17",
|
||||
"re-resizable": "6.10.1",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-blurhash": "^0.3.0",
|
||||
|
@ -148,18 +145,16 @@
|
|||
"tar-js": "^0.3.0",
|
||||
"temporal-polyfill": "^0.2.5",
|
||||
"ua-parser-js": "^1.0.2",
|
||||
"uuid": "^10.0.0",
|
||||
"uuid": "^11.0.0",
|
||||
"what-input": "^5.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@action-validator/cli": "^0.6.0",
|
||||
"@action-validator/core": "^0.6.0",
|
||||
"@axe-core/playwright": "^4.8.1",
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/eslint-parser": "^7.12.10",
|
||||
"@babel/eslint-plugin": "^7.12.10",
|
||||
"@babel/parser": "^7.12.11",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.12.1",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-class-properties": "^7.12.1",
|
||||
|
@ -172,7 +167,6 @@
|
|||
"@babel/preset-env": "^7.12.11",
|
||||
"@babel/preset-react": "^7.12.10",
|
||||
"@babel/preset-typescript": "^7.12.7",
|
||||
"@babel/register": "^7.12.10",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@casualbot/jest-sonar-reporter": "2.2.7",
|
||||
"@peculiar/webcrypto": "^1.4.3",
|
||||
|
@ -186,7 +180,6 @@
|
|||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/commonmark": "^0.27.4",
|
||||
"@types/content-type": "^1.1.5",
|
||||
"@types/counterpart": "^0.18.1",
|
||||
"@types/css-tree": "^2.3.8",
|
||||
"@types/diff-match-patch": "^1.0.32",
|
||||
|
@ -208,18 +201,15 @@
|
|||
"@types/qrcode": "^1.3.5",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react-beautiful-dnd": "^13.0.0",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@types/react-dom": "18.3.1",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/sanitize-html": "2.13.0",
|
||||
"@types/sdp-transform": "^2.4.6",
|
||||
"@types/seedrandom": "3.0.8",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/tar-js": "^0.3.5",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"axe-core": "4.10.0",
|
||||
"babel-jest": "^29.0.0",
|
||||
"babel-loader": "^9.0.0",
|
||||
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
|
||||
|
@ -242,7 +232,7 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-matrix-org": "^2.0.2",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.0",
|
||||
"express": "^4.18.2",
|
||||
"fake-indexeddb": "^6.0.0",
|
||||
|
@ -259,14 +249,12 @@
|
|||
"jest-mock": "^29.6.2",
|
||||
"jest-raw-loader": "^1.0.1",
|
||||
"jsqr": "^1.4.0",
|
||||
"knip": "^5.36.2",
|
||||
"lint-staged": "^15.0.2",
|
||||
"mailhog": "^4.16.0",
|
||||
"matrix-mock-request": "^2.5.0",
|
||||
"matrix-web-i18n": "^3.2.1",
|
||||
"mini-css-extract-plugin": "2.9.0",
|
||||
"minimist": "^1.2.6",
|
||||
"mkdirp": "^3.0.0",
|
||||
"mocha-junit-reporter": "^2.2.0",
|
||||
"modernizr": "^3.12.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"playwright-core": "^1.45.1",
|
||||
|
@ -276,7 +264,7 @@
|
|||
"postcss-import": "16.1.0",
|
||||
"postcss-loader": "8.1.1",
|
||||
"postcss-mixins": "^11.0.0",
|
||||
"postcss-nested": "^6.0.0",
|
||||
"postcss-nested": "^7.0.0",
|
||||
"postcss-preset-env": "^10.0.0",
|
||||
"postcss-scss": "^4.0.4",
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
|
@ -298,6 +286,7 @@
|
|||
"webpack-bundle-analyzer": "^4.8.0",
|
||||
"webpack-cli": "^5.0.0",
|
||||
"webpack-dev-server": "^5.0.0",
|
||||
"webpack-version-file-plugin": "^0.5.0",
|
||||
"yaml": "^2.3.3"
|
||||
},
|
||||
"@casualbot/jest-sonar-reporter": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM mcr.microsoft.com/playwright:v1.48.0-jammy
|
||||
FROM mcr.microsoft.com/playwright:v1.48.2-jammy
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
|
|
|
@ -51,6 +51,6 @@ test.describe("Invisible cryptography", () => {
|
|||
/* should show an error for a message from a previously verified device */
|
||||
await bobSecondDevice.sendMessage(testRoomId, "test encrypted from user that was previously verified");
|
||||
const lastTile = page.locator(".mx_EventTile_last");
|
||||
await expect(lastTile).toContainText("Verified identity has changed");
|
||||
await expect(lastTile).toContainText("Sender's verified identity has changed");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -60,6 +60,11 @@ test.describe("User verification", () => {
|
|||
// Accept
|
||||
await toast.getByRole("button", { name: "Verify User" }).click();
|
||||
|
||||
// Wait for the QR code to be rendered. If we don't do this, then the QR code can be rendered just as
|
||||
// Playwright tries to click the "Verify by emoji" button, which seems to make it miss the button.
|
||||
// (richvdh: I thought Playwright was supposed to be resilient to such things, but empirically not.)
|
||||
await expect(page.getByAltText("QR Code")).toBeVisible();
|
||||
|
||||
// request verification by emoji
|
||||
await page.locator("#mx_RightPanel").getByRole("button", { name: "Verify by emoji" }).click();
|
||||
|
||||
|
@ -101,13 +106,20 @@ test.describe("User verification", () => {
|
|||
const toast = await toasts.getToast("Verification requested");
|
||||
await toast.getByRole("button", { name: "Verify User" }).click();
|
||||
|
||||
// Wait for the QR code to be rendered. If we don't do this, then the QR code can be rendered just as
|
||||
// Playwright tries to click the "Verify by emoji" button, which seems to make it miss the button.
|
||||
// (richvdh: I thought Playwright was supposed to be resilient to such things, but empirically not.)
|
||||
await expect(page.getByAltText("QR Code")).toBeVisible();
|
||||
|
||||
// request verification by emoji
|
||||
await page.locator("#mx_RightPanel").getByRole("button", { name: "Verify by emoji" }).click();
|
||||
|
||||
/* on the bot side, wait for the verifier to exist ... */
|
||||
const botVerifier = await awaitVerifier(bobVerificationRequest);
|
||||
// ... confirm ...
|
||||
botVerifier.evaluate((verifier) => verifier.verify()).catch(() => {});
|
||||
// ... and confirm. We expect the verification to fail; we catch the error on the DOM side
|
||||
// to stop playwright marking the evaluate as failing in the UI.
|
||||
const botVerification = botVerifier.evaluate((verifier) => verifier.verify().catch(() => {}));
|
||||
|
||||
// ... and abort the verification
|
||||
await page.getByRole("button", { name: "They don't match" }).click();
|
||||
|
||||
|
@ -115,6 +127,8 @@ test.describe("User verification", () => {
|
|||
await expect(dialog.getByText("Your messages are not secure")).toBeVisible();
|
||||
await dialog.getByRole("button", { name: "OK" }).click();
|
||||
await expect(dialog).not.toBeVisible();
|
||||
|
||||
await botVerification;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -196,14 +196,7 @@ export class Helpers {
|
|||
*/
|
||||
async assertEmptyPinnedMessagesList() {
|
||||
const rightPanel = this.getRightPanel();
|
||||
await expect(rightPanel).toMatchScreenshot(`pinned-messages-list-empty.png`, {
|
||||
css: `
|
||||
// hide the tooltip "Room information" to avoid flakiness
|
||||
[data-floating-ui-portal] {
|
||||
display: none !important;
|
||||
}
|
||||
`,
|
||||
});
|
||||
await expect(rightPanel).toMatchScreenshot(`pinned-messages-list-empty.png`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,8 +31,8 @@ test.describe("Pinned messages", () => {
|
|||
const tile = util.getEventTile("Msg1");
|
||||
await expect(tile).toMatchScreenshot("pinned-message-Msg1.png", {
|
||||
mask: [tile.locator(".mx_MessageTimestamp")],
|
||||
// Hide the jump to bottom button in the timeline to avoid flakiness
|
||||
css: `
|
||||
// Hide the jump to bottom button in the timeline to avoid flakiness
|
||||
.mx_JumpToBottomButton {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export class Helpers {
|
|||
*/
|
||||
async assertReleaseAnnouncementIsVisible(name: string) {
|
||||
await expect(this.getReleaseAnnouncement(name)).toBeVisible();
|
||||
await expect(this.page).toMatchScreenshot(`release-announcement-${name}.png`);
|
||||
await expect(this.page).toMatchScreenshot(`release-announcement-${name}.png`, { showTooltips: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -357,9 +357,9 @@ test.describe("Threads", () => {
|
|||
await bot.joinRoom(roomId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
// Exclude timestamp, read marker, and mapboxgl-map from snapshots
|
||||
// Exclude timestamp, read marker, and maplibregl-map from snapshots
|
||||
const css =
|
||||
".mx_MessageTimestamp, .mx_MessagePanel_myReadMarker, .mapboxgl-map { visibility: hidden !important; }";
|
||||
".mx_MessageTimestamp, .mx_MessagePanel_myReadMarker, .maplibregl-map { visibility: hidden !important; }";
|
||||
|
||||
let locator = page.locator(".mx_RoomView_body");
|
||||
// User sends message
|
||||
|
|
|
@ -6,32 +6,48 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
|||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import * as fs from "node:fs";
|
||||
|
||||
import type { Page } from "@playwright/test";
|
||||
import { test, expect } from "../../element-web-test";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import { Credentials } from "../../plugins/homeserver";
|
||||
|
||||
const STICKER_PICKER_WIDGET_ID = "fake-sticker-picker";
|
||||
const STICKER_PICKER_WIDGET_NAME = "Fake Stickers";
|
||||
const STICKER_NAME = "Test Sticker";
|
||||
const ROOM_NAME_1 = "Sticker Test";
|
||||
const ROOM_NAME_2 = "Sticker Test Two";
|
||||
const STICKER_MESSAGE = JSON.stringify({
|
||||
action: "m.sticker",
|
||||
api: "fromWidget",
|
||||
data: {
|
||||
name: "teststicker",
|
||||
description: STICKER_NAME,
|
||||
file: "test.png",
|
||||
content: {
|
||||
body: STICKER_NAME,
|
||||
msgtype: "m.sticker",
|
||||
url: "mxc://localhost/somewhere",
|
||||
const STICKER_IMAGE = fs.readFileSync("playwright/sample-files/riot.png");
|
||||
|
||||
function getStickerMessage(contentUri: string, mimetype: string): string {
|
||||
return JSON.stringify({
|
||||
action: "m.sticker",
|
||||
api: "fromWidget",
|
||||
data: {
|
||||
name: "teststicker",
|
||||
description: STICKER_NAME,
|
||||
file: "test.png",
|
||||
content: {
|
||||
body: STICKER_NAME,
|
||||
info: {
|
||||
h: 480,
|
||||
mimetype: mimetype,
|
||||
size: 13818,
|
||||
w: 480,
|
||||
},
|
||||
msgtype: "m.sticker",
|
||||
url: contentUri,
|
||||
},
|
||||
},
|
||||
},
|
||||
requestId: "1",
|
||||
widgetId: STICKER_PICKER_WIDGET_ID,
|
||||
});
|
||||
const WIDGET_HTML = `
|
||||
requestId: "1",
|
||||
widgetId: STICKER_PICKER_WIDGET_ID,
|
||||
});
|
||||
}
|
||||
|
||||
function getWidgetHtml(contentUri: string, mimetype: string) {
|
||||
const stickerMessage = getStickerMessage(contentUri, mimetype);
|
||||
return `
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Fake Sticker Picker</title>
|
||||
|
@ -51,13 +67,13 @@ const WIDGET_HTML = `
|
|||
<button name="Send" id="sendsticker">Press for sticker</button>
|
||||
<script>
|
||||
document.getElementById('sendsticker').onclick = () => {
|
||||
window.parent.postMessage(${STICKER_MESSAGE}, '*')
|
||||
window.parent.postMessage(${stickerMessage}, '*')
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
}
|
||||
async function openStickerPicker(app: ElementAppPage) {
|
||||
const options = await app.openMessageComposerOptions();
|
||||
await options.getByRole("menuitem", { name: "Sticker" }).click();
|
||||
|
@ -71,7 +87,8 @@ async function sendStickerFromPicker(page: Page) {
|
|||
await expect(page.locator(".mx_AppTileFullWidth#stickers")).not.toBeVisible();
|
||||
}
|
||||
|
||||
async function expectTimelineSticker(page: Page, roomId: string) {
|
||||
async function expectTimelineSticker(page: Page, roomId: string, contentUri: string) {
|
||||
const contentId = contentUri.split("/").slice(-1)[0];
|
||||
// Make sure it's in the right room
|
||||
await expect(page.locator(".mx_EventTile_sticker > a")).toHaveAttribute("href", new RegExp(`/${roomId}/`));
|
||||
|
||||
|
@ -80,13 +97,43 @@ async function expectTimelineSticker(page: Page, roomId: string) {
|
|||
// download URL.
|
||||
await expect(page.locator(`img[alt="${STICKER_NAME}"]`)).toHaveAttribute(
|
||||
"src",
|
||||
new RegExp("/download/localhost/somewhere"),
|
||||
new RegExp(`/localhost/${contentId}`),
|
||||
);
|
||||
}
|
||||
|
||||
async function expectFileTile(page: Page, roomId: string, contentUri: string) {
|
||||
await expect(page.locator(".mx_MFileBody_info_filename")).toContainText(STICKER_NAME);
|
||||
}
|
||||
|
||||
async function setWidgetAccountData(
|
||||
app: ElementAppPage,
|
||||
user: Credentials,
|
||||
stickerPickerUrl: string,
|
||||
provideCreatorUserId: boolean = true,
|
||||
) {
|
||||
await app.client.setAccountData("m.widgets", {
|
||||
[STICKER_PICKER_WIDGET_ID]: {
|
||||
content: {
|
||||
type: "m.stickerpicker",
|
||||
name: STICKER_PICKER_WIDGET_NAME,
|
||||
url: stickerPickerUrl,
|
||||
creatorUserId: provideCreatorUserId ? user.userId : undefined,
|
||||
},
|
||||
sender: user.userId,
|
||||
state_key: STICKER_PICKER_WIDGET_ID,
|
||||
type: "m.widget",
|
||||
id: STICKER_PICKER_WIDGET_ID,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
test.describe("Stickers", () => {
|
||||
test.use({
|
||||
displayName: "Sally",
|
||||
room: async ({ app }, use) => {
|
||||
const roomId = await app.client.createRoom({ name: ROOM_NAME_1 });
|
||||
await use({ roomId });
|
||||
},
|
||||
});
|
||||
|
||||
// We spin up a web server for the sticker picker so that we're not testing to see if
|
||||
|
@ -96,34 +143,19 @@ test.describe("Stickers", () => {
|
|||
//
|
||||
// See sendStickerFromPicker() for more detail on iframe comms.
|
||||
let stickerPickerUrl: string;
|
||||
test.beforeEach(async ({ webserver }) => {
|
||||
stickerPickerUrl = webserver.start(WIDGET_HTML);
|
||||
});
|
||||
|
||||
test("should send a sticker to multiple rooms", async ({ page, app, user }) => {
|
||||
const roomId1 = await app.client.createRoom({ name: ROOM_NAME_1 });
|
||||
test("should send a sticker to multiple rooms", async ({ webserver, page, app, user, room }) => {
|
||||
const roomId2 = await app.client.createRoom({ name: ROOM_NAME_2 });
|
||||
|
||||
await app.client.setAccountData("m.widgets", {
|
||||
[STICKER_PICKER_WIDGET_ID]: {
|
||||
content: {
|
||||
type: "m.stickerpicker",
|
||||
name: STICKER_PICKER_WIDGET_NAME,
|
||||
url: stickerPickerUrl,
|
||||
creatorUserId: user.userId,
|
||||
},
|
||||
sender: user.userId,
|
||||
state_key: STICKER_PICKER_WIDGET_ID,
|
||||
type: "m.widget",
|
||||
id: STICKER_PICKER_WIDGET_ID,
|
||||
},
|
||||
});
|
||||
const { content_uri: contentUri } = await app.client.uploadContent(STICKER_IMAGE, { type: "image/png" });
|
||||
const widgetHtml = getWidgetHtml(contentUri, "image/png");
|
||||
stickerPickerUrl = webserver.start(widgetHtml);
|
||||
setWidgetAccountData(app, user, stickerPickerUrl);
|
||||
|
||||
await app.viewRoomByName(ROOM_NAME_1);
|
||||
await expect(page).toHaveURL(`/#/room/${roomId1}`);
|
||||
await expect(page).toHaveURL(`/#/room/${room.roomId}`);
|
||||
await openStickerPicker(app);
|
||||
await sendStickerFromPicker(page);
|
||||
await expectTimelineSticker(page, roomId1);
|
||||
await expectTimelineSticker(page, room.roomId, contentUri);
|
||||
|
||||
// Ensure that when we switch to a different room that the sticker
|
||||
// goes to the right place
|
||||
|
@ -131,31 +163,40 @@ test.describe("Stickers", () => {
|
|||
await expect(page).toHaveURL(`/#/room/${roomId2}`);
|
||||
await openStickerPicker(app);
|
||||
await sendStickerFromPicker(page);
|
||||
await expectTimelineSticker(page, roomId2);
|
||||
await expectTimelineSticker(page, roomId2, contentUri);
|
||||
});
|
||||
|
||||
test("should handle a sticker picker widget missing creatorUserId", async ({ page, app, user }) => {
|
||||
const roomId1 = await app.client.createRoom({ name: ROOM_NAME_1 });
|
||||
|
||||
await app.client.setAccountData("m.widgets", {
|
||||
[STICKER_PICKER_WIDGET_ID]: {
|
||||
content: {
|
||||
type: "m.stickerpicker",
|
||||
name: STICKER_PICKER_WIDGET_NAME,
|
||||
url: stickerPickerUrl,
|
||||
// No creatorUserId
|
||||
},
|
||||
sender: user.userId,
|
||||
state_key: STICKER_PICKER_WIDGET_ID,
|
||||
type: "m.widget",
|
||||
id: STICKER_PICKER_WIDGET_ID,
|
||||
},
|
||||
});
|
||||
test("should handle a sticker picker widget missing creatorUserId", async ({
|
||||
webserver,
|
||||
page,
|
||||
app,
|
||||
user,
|
||||
room,
|
||||
}) => {
|
||||
const { content_uri: contentUri } = await app.client.uploadContent(STICKER_IMAGE, { type: "image/png" });
|
||||
const widgetHtml = getWidgetHtml(contentUri, "image/png");
|
||||
stickerPickerUrl = webserver.start(widgetHtml);
|
||||
setWidgetAccountData(app, user, stickerPickerUrl, false);
|
||||
|
||||
await app.viewRoomByName(ROOM_NAME_1);
|
||||
await expect(page).toHaveURL(`/#/room/${roomId1}`);
|
||||
await expect(page).toHaveURL(`/#/room/${room.roomId}`);
|
||||
await openStickerPicker(app);
|
||||
await sendStickerFromPicker(page);
|
||||
await expectTimelineSticker(page, roomId1);
|
||||
await expectTimelineSticker(page, room.roomId, contentUri);
|
||||
});
|
||||
|
||||
test("should render invalid mimetype as a file", async ({ webserver, page, app, user, room }) => {
|
||||
const { content_uri: contentUri } = await app.client.uploadContent(STICKER_IMAGE, {
|
||||
type: "application/octet-stream",
|
||||
});
|
||||
const widgetHtml = getWidgetHtml(contentUri, "application/octet-stream");
|
||||
stickerPickerUrl = webserver.start(widgetHtml);
|
||||
setWidgetAccountData(app, user, stickerPickerUrl);
|
||||
|
||||
await app.viewRoomByName(ROOM_NAME_1);
|
||||
await expect(page).toHaveURL(`/#/room/${room.roomId}`);
|
||||
await openStickerPicker(app);
|
||||
await sendStickerFromPicker(page);
|
||||
await expectFileTile(page, room.roomId, contentUri);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -345,6 +345,7 @@ export const expect = baseExpect.extend({
|
|||
|
||||
if (!options?.showTooltips) {
|
||||
css += `
|
||||
[data-floating-ui-portal],
|
||||
[role="tooltip"] {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import { randB64Bytes } from "../../utils/rand";
|
|||
// Docker tag to use for synapse docker image.
|
||||
// We target a specific digest as every now and then a Synapse update will break our CI.
|
||||
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
|
||||
const DOCKER_TAG = "develop@sha256:47c62aa9507a24820190eef547861c0d278cc83fe90329c46b9f4329eed88ef4";
|
||||
const DOCKER_TAG = "develop@sha256:b1b5693fa954ec0124e330dba8a28260ac1cc4d9948a778724a421be9f934284";
|
||||
|
||||
async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
|
||||
const templateDir = path.join(__dirname, "templates", opts.template);
|
||||
|
|
|
@ -102,3 +102,5 @@ experimental_features:
|
|||
# messages > non-joined historical messages.
|
||||
# Can be removed after Synapse enables it by default
|
||||
msc4115_membership_on_events: true
|
||||
|
||||
enable_authenticated_media: true
|
||||
|
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 563 KiB After Width: | Height: | Size: 503 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,4 +0,0 @@
|
|||
signing_id: releases@riot.im
|
||||
subprojects:
|
||||
matrix-js-sdk:
|
||||
includeByDefault: false
|
|
@ -186,7 +186,7 @@ input[type="search"].mx_textinput_icon {
|
|||
/* FIXME THEME - Tint by CSS rather than referencing a duplicate asset */
|
||||
input[type="text"].mx_textinput_icon.mx_textinput_search,
|
||||
input[type="search"].mx_textinput_icon.mx_textinput_search {
|
||||
background-image: url("$(res)/img/feather-customised/search-input.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/search.svg");
|
||||
}
|
||||
|
||||
/* dont search UI as not all browsers support it, */
|
||||
|
|
|
@ -282,11 +282,11 @@
|
|||
@import "./views/rooms/_EmojiButton.pcss";
|
||||
@import "./views/rooms/_EntityTile.pcss";
|
||||
@import "./views/rooms/_EventBubbleTile.pcss";
|
||||
@import "./views/rooms/_EventPreview.pcss";
|
||||
@import "./views/rooms/_EventTile.pcss";
|
||||
@import "./views/rooms/_HistoryTile.pcss";
|
||||
@import "./views/rooms/_IRCLayout.pcss";
|
||||
@import "./views/rooms/_JumpToBottomButton.pcss";
|
||||
@import "./views/rooms/_LegacyRoomHeader.pcss";
|
||||
@import "./views/rooms/_LinkPreviewGroup.pcss";
|
||||
@import "./views/rooms/_LinkPreviewWidget.pcss";
|
||||
@import "./views/rooms/_LiveContentSummary.pcss";
|
||||
|
|
|
@ -53,8 +53,6 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
.mx_MapError_icon {
|
||||
height: var(--mx-map-error-icon-size);
|
||||
|
||||
path {
|
||||
fill: var(--mx-map-error-icon-color);
|
||||
}
|
||||
width: var(--mx-map-error-icon-size);
|
||||
color: var(--mx-map-error-icon-color);
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_DeviceExpandDetailsButton_icon {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
|
||||
transition: all 0.3s;
|
||||
transform: var(--icon-transform);
|
||||
|
|
|
@ -25,7 +25,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
width: 18px;
|
||||
height: 18px;
|
||||
background: currentColor;
|
||||
mask-image: url("$(res)/img/feather-customised/chevron-down.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
mask-size: 100%;
|
||||
mask-repeat: no-repeat;
|
||||
float: right;
|
||||
|
|
|
@ -176,7 +176,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_LeftPanel_recentsButton::before {
|
||||
mask-image: url("$(res)/img/element-icons/clock.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/time.svg");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
padding-left: 34px; /* 28px from above, but +6px to account for the wider icon */
|
||||
|
||||
&::before {
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
&::before {
|
||||
background-color: $info-plinth-fg-color;
|
||||
mask: url("$(res)/img/feather-customised/search-input.svg");
|
||||
mask: url("@vector-im/compound-design-tokens/icons/search.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: 50px;
|
||||
|
@ -181,11 +181,6 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
}
|
||||
|
||||
/* Rooms with immersive content */
|
||||
.mx_RoomView_immersive .mx_LegacyRoomHeader_wrapper {
|
||||
border: unset;
|
||||
}
|
||||
|
||||
.mx_RoomView_inCall {
|
||||
.mx_RoomView_statusAreaBox_line {
|
||||
margin-top: 2px;
|
||||
|
|
|
@ -77,7 +77,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
height: 16px;
|
||||
width: 16px;
|
||||
left: 0;
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
background-color: $tertiary-content;
|
||||
mask-size: 16px;
|
||||
transform: rotate(270deg);
|
||||
mask-image: url("$(res)/img/feather-customised/chevron-down.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
}
|
||||
|
||||
&.mx_SpaceHierarchy_subspace_toggle_shown::before {
|
||||
|
|
|
@ -48,7 +48,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $background;
|
||||
mask-image: url("$(res)/img/feather-customised/chevron-down.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-size: 20px;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $tertiary-content;
|
||||
mask-image: url("$(res)/img/feather-customised/chevron-down.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
}
|
||||
|
||||
.mx_SpaceButton_icon {
|
||||
|
@ -207,7 +207,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
&.mx_SpaceButton_home .mx_SpaceButton_icon::before {
|
||||
mask-image: url("$(res)/img/element-icons/home.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_favourites .mx_SpaceButton_icon::before {
|
||||
|
@ -414,7 +414,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_SpacePanel_iconHome::before {
|
||||
mask-image: url("$(res)/img/element-icons/home.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconInvite::before {
|
||||
|
@ -422,7 +422,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_SpacePanel_iconSettings::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconLeave::before {
|
||||
|
|
|
@ -27,13 +27,14 @@ Please see LICENSE files in the repository root for full details.
|
|||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 27px;
|
||||
left: 20px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 22px;
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 24px;
|
||||
mask-size: 28px;
|
||||
background-color: $tertiary-content;
|
||||
}
|
||||
|
||||
|
@ -221,7 +222,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
width: 24px;
|
||||
background: $tertiary-content;
|
||||
mask-size: contain;
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_UserMenu_iconHome::before {
|
||||
mask-image: url("$(res)/img/element-icons/home.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconDnd::before {
|
||||
|
@ -185,11 +185,11 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_UserMenu_iconLock::before {
|
||||
mask-image: url("$(res)/img/element-icons/security.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconSettings::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconMessage::before {
|
||||
|
|
|
@ -43,7 +43,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $secondary-content;
|
||||
mask-image: url("$(res)/img/globe.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/public.svg");
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon_offline::before {
|
||||
|
|
|
@ -29,7 +29,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReport::before {
|
||||
mask-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconLink::before {
|
||||
|
@ -61,7 +61,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_MessageContextMenu_iconResend::before {
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconSource::before {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconFiles::before {
|
||||
mask-image: url("$(res)/img/element-icons/room/files.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/files.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconPins::before {
|
||||
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconSettings::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_RoomGeneralContextMenu_iconExport::before {
|
||||
|
|
|
@ -125,7 +125,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-image: url("$(res)/img/element-icons/retry.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/restart.svg");
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
left: 0;
|
||||
|
|
|
@ -36,9 +36,24 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_AnalyticsLearnMore_bullets li {
|
||||
background: url("$(res)/img/tick-circle.svg") no-repeat;
|
||||
list-style-type: none;
|
||||
padding: 2px 0px 20px 32px;
|
||||
padding: 2px 0 0 32px;
|
||||
margin-bottom: 20px;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #0dbd8b;
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/check-circle.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,14 +41,13 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
.mx_JoinRuleDropdown_invite::before {
|
||||
box-sizing: border-box;
|
||||
mask-image: url("$(res)/img/element-icons/lock.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg");
|
||||
mask-size: contain;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.mx_JoinRuleDropdown_public::before {
|
||||
mask-image: url("$(res)/img/globe.svg");
|
||||
mask-size: 12px;
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/public.svg");
|
||||
}
|
||||
|
||||
.mx_JoinRuleDropdown_restricted::before {
|
||||
|
|
|
@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
/* ========================================================== */
|
||||
|
||||
.mx_RoomSettingsDialog_settingsIcon::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSettingsDialog_voiceIcon::before {
|
||||
|
@ -17,7 +17,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_RoomSettingsDialog_securityIcon::before {
|
||||
mask-image: url("$(res)/img/element-icons/security.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/lock-solid.svg");
|
||||
}
|
||||
|
||||
.mx_RoomSettingsDialog_rolesIcon::before {
|
||||
|
@ -56,7 +56,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
/* show a different AvatarSetting placeholder for RoomProfileSettings which is basically a clone of ProfileSettings */
|
||||
.mx_RoomSettingsDialog .mx_AvatarSetting_avatar .mx_AvatarSetting_avatarPlaceholder::before {
|
||||
mask: url("$(res)/img/feather-customised/image.svg");
|
||||
mask: url("@vector-im/compound-design-tokens/icons/image.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 36px;
|
||||
mask-position: center;
|
||||
|
|
|
@ -74,7 +74,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
.mx_TabbedView_tabLabel {
|
||||
.mx_SpaceSettingsDialog_generalIcon::before {
|
||||
mask-image: url("$(res)/img/element-icons/settings.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/settings-solid.svg");
|
||||
}
|
||||
|
||||
.mx_SpaceSettingsDialog_visibilityIcon::before {
|
||||
|
|
|
@ -508,7 +508,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
mask-size: contain;
|
||||
|
||||
&.mx_SpotlightDialog_metaspaceResult_home-space {
|
||||
mask-image: url("$(res)/img/element-icons/home.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/home-solid.svg");
|
||||
}
|
||||
|
||||
&.mx_SpotlightDialog_metaspaceResult_favourites-space {
|
||||
|
|
|
@ -21,7 +21,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
&.mx_AccessSecretStorageDialog_resetBadge::before {
|
||||
/* The image isn't capable of masking, so we use a background instead. */
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: 24px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
width: 16px;
|
||||
left: 0;
|
||||
top: 2px; /* alignment */
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
background-image: url("@vector-im/compound-design-tokens/icons/error.svg");
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,13 @@ Please see LICENSE files in the repository root for full details.
|
|||
}
|
||||
|
||||
.mx_Dropdown_arrow {
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
padding-right: 9px;
|
||||
mask: url("$(res)/img/feather-customised/dropdown-arrow.svg");
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 4px;
|
||||
mask: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: 18px;
|
||||
background: $primary-content;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,9 @@ Please see LICENSE files in the repository root for full details.
|
|||
.mx_EditableItem_delete {
|
||||
@mixin customisedCancelButton;
|
||||
order: 3;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background-color: $alert;
|
||||
mask-size: 100%;
|
||||
}
|
||||
|
@ -42,7 +41,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
.mx_EditableItem_item {
|
||||
flex: auto 1 0;
|
||||
order: 1;
|
||||
width: calc(100% - 14px); /* leave space for the remove button */
|
||||
width: calc(100% - 28px); /* leave space for the remove button */
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
|
@ -51,12 +51,15 @@ Please see LICENSE files in the repository root for full details.
|
|||
.mx_Field_select::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
mask: url("$(res)/img/feather-customised/dropdown-arrow.svg");
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 4px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
mask: url("@vector-im/compound-design-tokens/icons/chevron-down.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
background-color: $primary-content;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
|
|
|
@ -125,7 +125,7 @@ $button-gap: 24px;
|
|||
}
|
||||
|
||||
.mx_ImageView_button_download::before {
|
||||
mask-image: url("$(res)/img/image-view/download.svg");
|
||||
mask-image: url("@vector-im/compound-design-tokens/icons/download.svg");
|
||||
}
|
||||
|
||||
.mx_ImageView_button_more::before {
|
||||
|
|