Merge branch 'release-v1.11.3'

This commit is contained in:
RiotRobot 2022-08-16 16:14:34 +01:00
commit 40a114a80a
22 changed files with 1282 additions and 1575 deletions

View file

@ -23,6 +23,8 @@ module.exports = {
"plugin:matrix-org/typescript", "plugin:matrix-org/typescript",
"plugin:matrix-org/react", "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: { rules: {
// Things we do that break the ideal style // Things we do that break the ideal style
"prefer-promise-reject-errors": "off", "prefer-promise-reject-errors": "off",

6
.github/renovate.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"github>matrix-org/renovate-config-element-web"
]
}

View file

@ -6,6 +6,9 @@ on:
branches: [ develop ] branches: [ develop ]
repository_dispatch: repository_dispatch:
types: [ element-web-notify ] types: [ element-web-notify ]
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: true
jobs: jobs:
build: build:
name: "Build & Upload source maps to Sentry" name: "Build & Upload source maps to Sentry"
@ -29,26 +32,19 @@ jobs:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_URL: ${{ secrets.SENTRY_URL }} SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_ORG: sentry SENTRY_ORG: element
SENTRY_PROJECT: riot-web SENTRY_PROJECT: riot-web
- run: mv dist/element-*.tar.gz webapp.tar.gz - run: mv dist/element-*.tar.gz webapp.tar.gz
- name: Wait for static analysis to succeed - name: Wait for other steps to succeed
uses: lewagon/wait-on-check-action@v1.0.0 uses: lewagon/wait-on-check-action@v1.0.0
with: with:
ref: ${{ github.ref }} ref: ${{ github.ref }}
running-workflow-name: 'Static Analysis' running-workflow-name: 'Build & Upload source maps to Sentry'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
- name: Wait for tests to succeed
uses: lewagon/wait-on-check-action@v1.0.0
with:
ref: ${{ github.ref }}
running-workflow-name: 'Tests'
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10 wait-interval: 10
check-regexp: ^((?!SonarQube|issues|board).)*$
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:

View file

@ -63,3 +63,19 @@ jobs:
- name: Run Linter - name: Run Linter
run: "yarn run lint:style" run: "yarn run lint:style"
analyse_dead_code:
name: "Analyse Dead Code"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
cache: 'yarn'
- name: Install Deps
run: "scripts/layered.sh"
- name: Dead Code Analysis
run: "yarn run analyse:unused-exports"

View file

@ -93,6 +93,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: > if: >
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience') || contains(github.event.issue.labels.*.name, 'A-New-Search-Experience') ||
(contains(github.event.issue.labels.*.name, 'A-Threads') &&
(contains(github.event.issue.labels.*.name, 'S-Major') ||
contains(github.event.issue.labels.*.name, 'S-Critical'))) ||
contains(github.event.issue.labels.*.name, 'Team: Delight') || contains(github.event.issue.labels.*.name, 'Team: Delight') ||
contains(github.event.issue.labels.*.name, 'Z-NewUserJourney') contains(github.event.issue.labels.*.name, 'Z-NewUserJourney')
steps: steps:

View file

@ -1,3 +1,34 @@
Changes in [1.11.3](https://github.com/vector-im/element-web/releases/tag/v1.11.3) (2022-08-16)
===============================================================================================
## ✨ Features
* Improve auth aria attributes and semantics ([\#22948](https://github.com/vector-im/element-web/pull/22948)).
* Device manager - New device tile info design ([\#9122](https://github.com/matrix-org/matrix-react-sdk/pull/9122)). Contributed by @kerryarchibald.
* Device manager generic settings subsection component ([\#9147](https://github.com/matrix-org/matrix-react-sdk/pull/9147)). Contributed by @kerryarchibald.
* Migrate the hidden read receipts flag to new "send read receipts" option ([\#9141](https://github.com/matrix-org/matrix-react-sdk/pull/9141)).
* Live location sharing - share location at most every 5 seconds ([\#9148](https://github.com/matrix-org/matrix-react-sdk/pull/9148)). Contributed by @kerryarchibald.
* Increase max length of voice messages to 15m ([\#9133](https://github.com/matrix-org/matrix-react-sdk/pull/9133)). Fixes #18620.
* Move pin drop out of labs ([\#9135](https://github.com/matrix-org/matrix-react-sdk/pull/9135)).
* Start DM on first message ([\#8612](https://github.com/matrix-org/matrix-react-sdk/pull/8612)). Fixes #14736.
* Remove "Add Space" button from RoomListHeader when user cannot create spaces ([\#9129](https://github.com/matrix-org/matrix-react-sdk/pull/9129)).
* The Welcome Home Screen: Dedicated Download Apps Dialog ([\#9120](https://github.com/matrix-org/matrix-react-sdk/pull/9120)). Fixes #22921. Contributed by @justjanne.
* The Welcome Home Screen: "Submit Feedback" pane ([\#9090](https://github.com/matrix-org/matrix-react-sdk/pull/9090)). Fixes #22918. Contributed by @justjanne.
* New User Onboarding Task List ([\#9083](https://github.com/matrix-org/matrix-react-sdk/pull/9083)). Fixes #22919. Contributed by @justjanne.
* Add support for disabling spell checking ([\#8604](https://github.com/matrix-org/matrix-react-sdk/pull/8604)). Fixes #21901.
* Live location share - leave maximised map open when beacons expire ([\#9098](https://github.com/matrix-org/matrix-react-sdk/pull/9098)). Contributed by @kerryarchibald.
## 🐛 Bug Fixes
* Some slash-commands (`/myroomnick`) have temporarily been disabled before the first message in a DM is sent. ([\#9193](https://github.com/matrix-org/matrix-react-sdk/pull/9193)).
* Use stable reference for active tab in tabbedView ([\#9145](https://github.com/matrix-org/matrix-react-sdk/pull/9145)). Contributed by @kerryarchibald.
* Fix pillification sometimes doubling up ([\#9152](https://github.com/matrix-org/matrix-react-sdk/pull/9152)). Fixes #23036.
* Fix highlights not being applied to plaintext messages ([\#9126](https://github.com/matrix-org/matrix-react-sdk/pull/9126)). Fixes #22787.
* Fix dismissing edit composer when change was undone ([\#9109](https://github.com/matrix-org/matrix-react-sdk/pull/9109)). Fixes #22932.
* 1-to-1 DM rooms with bots now act like DM rooms instead of multi-user-rooms before ([\#9124](https://github.com/matrix-org/matrix-react-sdk/pull/9124)). Fixes #22894.
* Apply inline start padding to selected lines on modern layout only ([\#9006](https://github.com/matrix-org/matrix-react-sdk/pull/9006)). Fixes #22768. Contributed by @luixxiul.
* Peek into world-readable rooms from spotlight ([\#9115](https://github.com/matrix-org/matrix-react-sdk/pull/9115)). Fixes #22862.
* Use default styling on nested numbered lists due to MD being sensitive ([\#9110](https://github.com/matrix-org/matrix-react-sdk/pull/9110)). Fixes #22935.
* Fix replying using chat effect commands ([\#9101](https://github.com/matrix-org/matrix-react-sdk/pull/9101)). Fixes #22824.
Changes in [1.11.2](https://github.com/vector-im/element-web/releases/tag/v1.11.2) (2022-08-03) Changes in [1.11.2](https://github.com/vector-im/element-web/releases/tag/v1.11.2) (2022-08-03)
=============================================================================================== ===============================================================================================

View file

@ -27,9 +27,6 @@ FROM nginx:alpine
COPY --from=builder /src/webapp /app COPY --from=builder /src/webapp /app
# Insert wasm type into Nginx mime.types file so they load correctly.
RUN sed -i '3i\ \ \ \ application/wasm wasm\;' /etc/nginx/mime.types
# Override default nginx config # Override default nginx config
COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

View file

@ -108,10 +108,6 @@ To enable message previews for reactions in DMs only, enable `feature_roomlist_p
Allows users to receive encrypted messages by creating a device that is stored Allows users to receive encrypted messages by creating a device that is stored
encrypted on the server, as described in [MSC2697](https://github.com/matrix-org/matrix-doc/pull/2697). encrypted on the server, as described in [MSC2697](https://github.com/matrix-org/matrix-doc/pull/2697).
## Hidden read receipts (`feature_hidden_read_receipts`)
Enables sending hidden read receipts as per [MSC2285](https://github.com/matrix-org/matrix-doc/pull/2285)
## Breadcrumbs v2 (`feature_breadcrumbs_v2`) ## Breadcrumbs v2 (`feature_breadcrumbs_v2`)
Instead of showing the horizontal list of breadcrumbs under the filter field, the new UX is an interactive context menu Instead of showing the horizontal list of breadcrumbs under the filter field, the new UX is an interactive context menu
@ -146,14 +142,6 @@ If no right panel state is known for the room or it was closed on the last room
visit, it will default to the room member list. Otherwise, the saved card last visit, it will default to the room member list. Otherwise, the saved card last
used in that room is shown. used in that room is shown.
## Show current profile of users on historical messages (`feature_use_only_current_profiles`)
An experimental flag to determine how the app would behave if a user's current display
name and avatar (profile) were shown on historical messages instead of the profile details
at the time when the message was sent.
When enabled, historical messages will use the current profile for the sender.
## Pin drop location sharing (`feature_location_share_pin_drop`) [In Development] ## Pin drop location sharing (`feature_location_share_pin_drop`) [In Development]
Enables sharing a pin drop location to the timeline. Enables sharing a pin drop location to the timeline.

View file

@ -1,191 +0,0 @@
#!/usr/bin/env python
#
# download and unpack a element-web tarball.
#
# Allows `bundles` to be extracted to a common directory, and a link to
# config.json to be added.
from __future__ import print_function
import argparse
import os
import os.path
import subprocess
import sys
import tarfile
import shutil
import glob
try:
# python3
from urllib.request import urlretrieve
except ImportError:
# python2
from urllib import urlretrieve
class DeployException(Exception):
pass
def create_relative_symlink(linkname, target):
relpath = os.path.relpath(target, os.path.dirname(linkname))
print ("Symlink %s -> %s" % (linkname, relpath))
os.symlink(relpath, linkname)
def move_bundles(source, dest):
"""Move the contents of the 'bundles' directory to a common dir
We check that we will not be overwriting anything before we proceed.
Args:
source (str): path to 'bundles' within the extracted tarball
dest (str): target common directory
"""
if not os.path.isdir(dest):
os.mkdir(dest)
# build a map from source to destination, checking for non-existence as we go.
renames = {}
for f in os.listdir(source):
dst = os.path.join(dest, f)
if os.path.exists(dst):
print (
"Skipping bundle. The bundle includes '%s' which we have previously deployed."
% f
)
else:
renames[os.path.join(source, f)] = dst
for (src, dst) in renames.iteritems():
print ("Move %s -> %s" % (src, dst))
os.rename(src, dst)
class Deployer:
def __init__(self):
self.packages_path = "."
self.bundles_path = None
self.should_clean = False
# filename -> symlink path e.g 'config.localhost.json' => '../localhost/config.json'
self.symlink_paths = {}
self.verify_signature = True
def deploy(self, tarball, extract_path):
"""Download a tarball if necessary, and unpack it
Returns:
(str) the path to the unpacked deployment
"""
print("Deploying %s to %s" % (tarball, extract_path))
name_str = os.path.basename(tarball).replace(".tar.gz", "")
extracted_dir = os.path.join(extract_path, name_str)
if os.path.exists(extracted_dir):
raise DeployException('Cannot unpack %s: %s already exists' % (
tarball, extracted_dir))
downloaded = False
if tarball.startswith("http://") or tarball.startswith("https://"):
tarball = self.download_and_verify(tarball)
print("Downloaded file: %s" % tarball)
downloaded = True
try:
with tarfile.open(tarball) as tar:
tar.extractall(extract_path)
finally:
if self.should_clean and downloaded:
os.remove(tarball)
print ("Extracted into: %s" % extracted_dir)
if self.symlink_paths:
for link_path, file_path in self.symlink_paths.iteritems():
create_relative_symlink(
target=file_path,
linkname=os.path.join(extracted_dir, link_path)
)
if self.bundles_path:
extracted_bundles = os.path.join(extracted_dir, 'bundles')
move_bundles(source=extracted_bundles, dest=self.bundles_path)
# replace the extracted_bundles dir (which may not be empty if some
# bundles were skipped) with a symlink to the common dir.
shutil.rmtree(extracted_bundles)
create_relative_symlink(
target=self.bundles_path,
linkname=extracted_bundles,
)
return extracted_dir
def download_and_verify(self, url):
tarball = self.download_file(url)
if self.verify_signature:
sigfile = self.download_file(url + ".asc")
subprocess.check_call(["gpg", "--verify", sigfile, tarball])
return tarball
def download_file(self, url):
if not os.path.isdir(self.packages_path):
os.mkdir(self.packages_path)
local_filename = os.path.join(self.packages_path,
url.split('/')[-1])
sys.stdout.write("Downloading %s -> %s..." % (url, local_filename))
sys.stdout.flush()
urlretrieve(url, local_filename)
print ("Done")
return local_filename
if __name__ == "__main__":
parser = argparse.ArgumentParser("Deploy a Riot build on a web server.")
parser.add_argument(
"-p", "--packages-dir", default="./packages", help=(
"The directory to download the tarball into. (Default: '%(default)s')"
)
)
parser.add_argument(
"-e", "--extract-path", default="./deploys", help=(
"The location to extract .tar.gz files to. (Default: '%(default)s')"
)
)
parser.add_argument(
"-b", "--bundles-dir", nargs='?', default="./bundles", help=(
"A directory to move the contents of the 'bundles' directory to. A \
symlink to the bundles directory will also be written inside the \
extracted tarball. Example: './bundles'. \
(Default: '%(default)s')"
)
)
parser.add_argument(
"-c", "--clean", action="store_true", default=False, help=(
"Remove .tar.gz files after they have been downloaded and extracted. \
(Default: %(default)s)"
)
)
parser.add_argument(
"--include", nargs='*', default=['./config*.json'], help=(
"Symlink these files into the root of the deployed tarball. \
Useful for config files and home pages. Supports glob syntax. \
(Default: '%(default)s')"
)
)
parser.add_argument(
"tarball", help=(
"filename of tarball, or URL to download."
),
)
args = parser.parse_args()
deployer = Deployer()
deployer.packages_path = args.packages_dir
deployer.bundles_path = args.bundles_dir
deployer.should_clean = args.clean
for include in args.include:
deployer.symlink_paths.update({ os.path.basename(pth): pth for pth in glob.iglob(include) })
deployer.deploy(args.tarball, args.extract_path)

View file

@ -1,6 +1,6 @@
{ {
"name": "element-web", "name": "element-web",
"version": "1.11.2", "version": "1.11.3",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.", "author": "New Vector Ltd.",
"repository": { "repository": {
@ -61,8 +61,8 @@
"gfm.css": "^1.1.2", "gfm.css": "^1.1.2",
"jsrsasign": "^10.5.25", "jsrsasign": "^10.5.25",
"katex": "^0.12.0", "katex": "^0.12.0",
"matrix-js-sdk": "19.2.0", "matrix-js-sdk": "19.3.0",
"matrix-react-sdk": "3.51.0", "matrix-react-sdk": "3.52.0",
"matrix-widget-api": "^0.1.0-beta.18", "matrix-widget-api": "^0.1.0-beta.18",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "17.0.2", "react": "17.0.2",
@ -91,7 +91,7 @@
"@sentry/webpack-plugin": "^1.18.1", "@sentry/webpack-plugin": "^1.18.1",
"@svgr/webpack": "^5.5.0", "@svgr/webpack": "^5.5.0",
"@types/flux": "^3.1.9", "@types/flux": "^3.1.9",
"@types/jest": "^27.0.2", "@types/jest": "^28.0.0",
"@types/modernizr": "^3.5.3", "@types/modernizr": "^3.5.3",
"@types/node": "^14.14.22", "@types/node": "^14.14.22",
"@types/react": "17.0.14", "@types/react": "17.0.14",
@ -102,7 +102,7 @@
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.6.0",
"allchange": "^1.0.6", "allchange": "^1.0.6",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"babel-jest": "^26.6.3", "babel-jest": "^28.0.0",
"babel-loader": "^8.2.2", "babel-loader": "^8.2.2",
"chokidar": "^3.5.1", "chokidar": "^3.5.1",
"concurrently": "^5.3.0", "concurrently": "^5.3.0",
@ -111,8 +111,9 @@
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"eslint": "8.9.0", "eslint": "8.9.0",
"eslint-config-google": "^0.14.0", "eslint-config-google": "^0.14.0",
"eslint-plugin-deprecate": "^0.7.0",
"eslint-plugin-import": "^2.25.4", "eslint-plugin-import": "^2.25.4",
"eslint-plugin-matrix-org": "^0.4.0", "eslint-plugin-matrix-org": "^0.6.1",
"eslint-plugin-react": "^7.28.0", "eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0", "eslint-plugin-react-hooks": "^4.3.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0", "extract-text-webpack-plugin": "^4.0.0-beta.0",
@ -120,8 +121,8 @@
"file-loader": "^5.1.0", "file-loader": "^5.1.0",
"fs-extra": "^0.30.0", "fs-extra": "^0.30.0",
"html-webpack-plugin": "^4.5.2", "html-webpack-plugin": "^4.5.2",
"jest": "^26.6.3", "jest": "^28.0.0",
"jest-environment-jsdom-sixteen": "^1.0.3", "jest-environment-jsdom": "^28.1.3",
"jest-raw-loader": "^1.0.1", "jest-raw-loader": "^1.0.1",
"jest-sonar-reporter": "^2.0.0", "jest-sonar-reporter": "^2.0.0",
"json-loader": "^0.5.7", "json-loader": "^0.5.7",
@ -144,7 +145,6 @@
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"postcss-scss": "^2.1.1", "postcss-scss": "^2.1.1",
"postcss-simple-vars": "^5.0.2", "postcss-simple-vars": "^5.0.2",
"postcss-strip-inline-comments": "^0.1.5",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"semver": "^7.3.7", "semver": "^7.3.7",
@ -169,7 +169,10 @@
"@types/react": "17.0.14" "@types/react": "17.0.14"
}, },
"jest": { "jest": {
"testEnvironment": "jest-environment-jsdom-sixteen", "testEnvironment": "jsdom",
"testEnvironmentOptions": {
"url": "http://localhost/"
},
"testMatch": [ "testMatch": [
"<rootDir>/test/**/*-test.[tj]s?(x)" "<rootDir>/test/**/*-test.[tj]s?(x)"
], ],

View file

@ -1,13 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# download and unpack a element-web tarball. # download and unpack a element-web tarball.
# #
# Allows `bundles` to be extracted to a common directory, and a link to # Allows `bundles` to be extracted to a common directory, and a link to
# config.json to be added. # config.json to be added.
from __future__ import print_function
import argparse import argparse
import errno
import os import os
import os.path import os.path
import subprocess import subprocess
@ -15,21 +14,26 @@ import sys
import tarfile import tarfile
import shutil import shutil
import glob import glob
from urllib.request import urlretrieve
try:
# python3
from urllib.request import urlretrieve
except ImportError:
# python2
from urllib import urlretrieve
class DeployException(Exception): class DeployException(Exception):
pass pass
def create_relative_symlink(linkname, target): def create_relative_symlink(linkname, target):
relpath = os.path.relpath(target, os.path.dirname(linkname)) relpath = os.path.relpath(target, os.path.dirname(linkname))
print ("Symlink %s -> %s" % (linkname, relpath)) print("Symlink %s -> %s" % (linkname, relpath))
try:
os.symlink(relpath, linkname) os.symlink(relpath, linkname)
except OSError as e:
if e.errno == errno.EEXIST:
# atomic modification
os.symlink(relpath, linkname + ".tmp")
os.rename(linkname + ".tmp", linkname)
else:
raise e
def move_bundles(source, dest): def move_bundles(source, dest):
@ -50,33 +54,35 @@ def move_bundles(source, dest):
for f in os.listdir(source): for f in os.listdir(source):
dst = os.path.join(dest, f) dst = os.path.join(dest, f)
if os.path.exists(dst): if os.path.exists(dst):
print ( print(
"Skipping bundle. The bundle includes '%s' which we have previously deployed." "Skipping bundle. The bundle includes '%s' which we have previously deployed."
% f % f
) )
else: else:
renames[os.path.join(source, f)] = dst renames[os.path.join(source, f)] = dst
for (src, dst) in renames.iteritems(): for (src, dst) in renames.items():
print ("Move %s -> %s" % (src, dst)) print("Move %s -> %s" % (src, dst))
os.rename(src, dst) os.rename(src, dst)
class Deployer: class Deployer:
def __init__(self): def __init__(self):
self.packages_path = "." self.packages_path = "."
self.bundles_path = None self.bundles_path = None
self.should_clean = False self.should_clean = False
self.symlink_latest = None
# filename -> symlink path e.g 'config.localhost.json' => '../localhost/config.json' # filename -> symlink path e.g 'config.localhost.json' => '../localhost/config.json'
self.symlink_paths = {} self.symlink_paths = {}
self.verify_signature = True self.verify_signature = True
def deploy(self, tarball, extract_path): def fetch(self, tarball, extract_path):
"""Download a tarball if necessary, and unpack it """Download a tarball, verifies it if needed, and unpacks it
Returns: Returns:
(str) the path to the unpacked deployment (str) the path to the unpacked directory
""" """
print("Deploying %s to %s" % (tarball, extract_path)) print("Fetching %s to %s" % (tarball, extract_path))
name_str = os.path.basename(tarball).replace(".tar.gz", "") name_str = os.path.basename(tarball).replace(".tar.gz", "")
extracted_dir = os.path.join(extract_path, name_str) extracted_dir = os.path.join(extract_path, name_str)
@ -97,10 +103,15 @@ class Deployer:
if self.should_clean and downloaded: if self.should_clean and downloaded:
os.remove(tarball) os.remove(tarball)
print ("Extracted into: %s" % extracted_dir) print("Extracted into: %s" % extracted_dir)
return extracted_dir
def deploy(self, extracted_dir):
"""Applies symlinks and handles the bundles directory on an extracted tarball"""
print("Deploying %s" % extracted_dir)
if self.symlink_paths: if self.symlink_paths:
for link_path, file_path in self.symlink_paths.iteritems(): for link_path, file_path in self.symlink_paths.items():
create_relative_symlink( create_relative_symlink(
target=file_path, target=file_path,
linkname=os.path.join(extracted_dir, link_path) linkname=os.path.join(extracted_dir, link_path)
@ -117,7 +128,12 @@ class Deployer:
target=self.bundles_path, target=self.bundles_path,
linkname=extracted_bundles, linkname=extracted_bundles,
) )
return extracted_dir
if self.symlink_latest:
create_relative_symlink(
target=extracted_dir,
linkname=self.symlink_latest,
)
def download_and_verify(self, url): def download_and_verify(self, url):
tarball = self.download_file(url) tarball = self.download_file(url)
@ -139,6 +155,7 @@ class Deployer:
print ("Done") print ("Done")
return local_filename return local_filename
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser("Deploy a Riot build on a web server.") parser = argparse.ArgumentParser("Deploy a Riot build on a web server.")
parser.add_argument( parser.add_argument(
@ -173,8 +190,15 @@ if __name__ == "__main__":
) )
) )
parser.add_argument( parser.add_argument(
"tarball", help=( "-s", "--symlink", dest="symlink", default="./latest", help=(
"filename of tarball, or URL to download." "Write a symlink to this location pointing to the extracted tarball. \
New builds will keep overwriting this symlink. The symlink will point \
to the webapp directory INSIDE the tarball."
)
)
parser.add_argument(
"target", help=(
"filename of extracted directory, tarball, or URL to download."
), ),
) )
@ -184,8 +208,18 @@ if __name__ == "__main__":
deployer.packages_path = args.packages_dir deployer.packages_path = args.packages_dir
deployer.bundles_path = args.bundles_dir deployer.bundles_path = args.bundles_dir
deployer.should_clean = args.clean deployer.should_clean = args.clean
deployer.symlink_latest = args.symlink
for include in args.include: for include in args.include:
deployer.symlink_paths.update({ os.path.basename(pth): pth for pth in glob.iglob(include) }) deployer.symlink_paths.update({ os.path.basename(pth): pth for pth in glob.iglob(include) })
deployer.deploy(args.tarball, args.extract_path) if os.path.isdir(args.target):
# If the given directory contains a single directory then use that instead, the ci package wraps in an extra dir
files = os.listdir(args.target)
if len(files) == 1 and os.path.isdir(os.path.join(args.target, files[0])):
extracted_dir = os.path.join(args.target, files[0])
else:
extracted_dir = args.target
else:
extracted_dir = deployer.fetch(args.target, args.extract_path)
deployer.deploy(extracted_dir)

View file

@ -5,7 +5,7 @@ set -ex
# Automatically link to develop if we're building develop, but only if the caller # Automatically link to develop if we're building develop, but only if the caller
# hasn't asked us to build something else # hasn't asked us to build something else
BRANCH=$(git rev-parse --abbrev-ref HEAD) BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ $USE_CUSTOM_SDKS == false ] && [ $BRANCH == 'develop' ] if [[ $USE_CUSTOM_SDKS == false ]] && [[ $BRANCH == 'develop' ]]
then then
echo "using develop dependencies for react-sdk and js-sdk" echo "using develop dependencies for react-sdk and js-sdk"
USE_CUSTOM_SDKS=true USE_CUSTOM_SDKS=true
@ -13,21 +13,21 @@ then
REACT_SDK_BRANCH='develop' REACT_SDK_BRANCH='develop'
fi fi
if [ $USE_CUSTOM_SDKS == false ] if [[ $USE_CUSTOM_SDKS == false ]]
then then
echo "skipping react-sdk and js-sdk installs: USE_CUSTOM_SDKS is false" echo "skipping react-sdk and js-sdk installs: USE_CUSTOM_SDKS is false"
exit 0 exit 0
fi fi
echo "Linking js-sdk" echo "Linking js-sdk"
git clone --depth 1 --branch $JS_SDK_BRANCH $JS_SDK_REPO js-sdk git clone --depth 1 --branch $JS_SDK_BRANCH "$JS_SDK_REPO" js-sdk
cd js-sdk cd js-sdk
yarn link yarn link
yarn --network-timeout=100000 install yarn --network-timeout=100000 install
cd ../ cd ../
echo "Linking react-sdk" echo "Linking react-sdk"
git clone --depth 1 --branch $REACT_SDK_BRANCH $REACT_SDK_REPO react-sdk git clone --depth 1 --branch $REACT_SDK_BRANCH "$REACT_SDK_REPO" react-sdk
cd react-sdk cd react-sdk
yarn link yarn link
yarn link matrix-js-sdk yarn link matrix-js-sdk

View file

@ -1,21 +1,18 @@
#!/bin/sh #!/bin/bash
set -ex set -ex
TAG=$(git describe --tags)
BRANCH=$(git rev-parse --abbrev-ref HEAD) BRANCH=$(git rev-parse --abbrev-ref HEAD)
DIST_VERSION=$TAG DIST_VERSION=$(git describe --abbrev=0 --tags)
# If the branch comes out as HEAD then we're probably checked out to a tag, so if the thing is *not* DIR=$(dirname "$0")
# coming out as HEAD then we're on a branch. When we're on a branch, we want to resolve ourselves to
# a few SHAs rather than a version. # If we're not using custom SDKs and on a branch other than master, generate a version akin go develop.element.io
# Docker Hub doesn't always check out the tag and sometimes checks out the branch, so we should look if [[ $USE_CUSTOM_SDKS == false ]] && [[ $BRANCH != 'master' ]]
# for an appropriately tagged branch as well (heads/v1.2.3).
if [[ $BRANCH != HEAD && ! $BRANCH =~ heads/v.+ ]]
then then
DIST_VERSION=`$(dirname $0)/get-version-from-git.sh` DIST_VERSION=$("$DIR"/get-version-from-git.sh)
fi fi
DIST_VERSION=`$(dirname $0)/normalize-version.sh ${DIST_VERSION}` DIST_VERSION=$("$DIR"/normalize-version.sh "$DIST_VERSION")
VERSION=$DIST_VERSION yarn build VERSION=$DIST_VERSION yarn build
echo $DIST_VERSION > /src/webapp/version echo "$DIST_VERSION" > /src/webapp/version

View file

@ -12,10 +12,9 @@
# - flask # - flask
# #
from __future__ import print_function from __future__ import print_function
import json, requests, tarfile, argparse, os, errno import requests, argparse, os, errno
import time import time
import traceback import traceback
from urlparse import urljoin
import glob import glob
import re import re
import shutil import shutil
@ -30,22 +29,11 @@ app = Flask(__name__)
deployer = None deployer = None
arg_extract_path = None arg_extract_path = None
arg_symlink = None
arg_webhook_token = None arg_webhook_token = None
arg_api_token = None arg_api_token = None
workQueue = Queue() workQueue = Queue()
def create_symlink(source, linkname):
try:
os.symlink(source, linkname)
except OSError, e:
if e.errno == errno.EEXIST:
# atomic modification
os.symlink(source, linkname + ".tmp")
os.rename(linkname + ".tmp", linkname)
else:
raise e
def req_headers(): def req_headers():
return { return {
@ -173,7 +161,6 @@ def deploy_buildkite_artifact(artifact, pipeline_name, build_num):
traceback.print_exc() traceback.print_exc()
abort(400, e.message) abort(400, e.message)
create_symlink(source=extracted_dir, linkname=arg_symlink)
def deploy_tarball(artifact, build_dir): def deploy_tarball(artifact, build_dir):
"""Download a tarball from jenkins and unpack it """Download a tarball from jenkins and unpack it
@ -274,7 +261,6 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
arg_extract_path = args.extract arg_extract_path = args.extract
arg_symlink = args.symlink
arg_webbook_token = args.webhook_token arg_webbook_token = args.webhook_token
arg_api_token = args.api_token arg_api_token = args.api_token
arg_buildkite_org = args.buildkite_org arg_buildkite_org = args.buildkite_org
@ -285,6 +271,7 @@ if __name__ == "__main__":
deployer = Deployer() deployer = Deployer()
deployer.bundles_path = args.bundles_dir deployer.bundles_path = args.bundles_dir
deployer.should_clean = args.clean deployer.should_clean = args.clean
deployer.symlink_latest = args.symlink
for include in args.include: for include in args.include:
deployer.symlink_paths.update({ os.path.basename(pth): pth for pth in glob.iglob(include) }) deployer.symlink_paths.update({ os.path.basename(pth): pth for pth in glob.iglob(include) })
@ -298,7 +285,7 @@ if __name__ == "__main__":
(args.port, (args.port,
arg_extract_path, arg_extract_path,
" (clean after)" if deployer.should_clean else "", " (clean after)" if deployer.should_clean else "",
arg_symlink, args.symlink,
deployer.symlink_paths, deployer.symlink_paths,
) )
) )

View file

@ -37,10 +37,10 @@ const VectorAuthFooter = () => {
} }
return ( return (
<div className="mx_AuthFooter"> <footer className="mx_AuthFooter" role="contentinfo">
{ authFooterLinks } { authFooterLinks }
<a href="https://matrix.org" target="_blank" rel="noreferrer noopener">{ _t('Powered by Matrix') }</a> <a href="https://matrix.org" target="_blank" rel="noreferrer noopener">{ _t('Powered by Matrix') }</a>
</div> </footer>
); );
}; };

View file

@ -24,9 +24,9 @@ export default class VectorAuthHeaderLogo extends React.PureComponent {
const logoUrl = brandingConfig?.get("auth_header_logo_url") ?? "themes/element/img/logos/element-logo.svg"; const logoUrl = brandingConfig?.get("auth_header_logo_url") ?? "themes/element/img/logos/element-logo.svg";
return ( return (
<div className="mx_AuthHeaderLogo"> <aside className="mx_AuthHeaderLogo">
<img src={logoUrl} alt="Element" /> <img src={logoUrl} alt="Element" />
</div> </aside>
); );
} }
} }

View file

@ -16,7 +16,7 @@
"%(appName)s (%(browserName)s, %(osName)s)": "%(appName)s (%(browserName)s, %(osName)s)", "%(appName)s (%(browserName)s, %(osName)s)": "%(appName)s (%(browserName)s, %(osName)s)",
"Unsupported browser": "Неподдерживаемый браузер", "Unsupported browser": "Неподдерживаемый браузер",
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Пожалуйста поставьте <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, или <safariLink>Safari</safariLink> для лучшей совместимости.", "Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Пожалуйста поставьте <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, или <safariLink>Safari</safariLink> для лучшей совместимости.",
"You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.": "Вы можете продолжать пользоваться этим браузером но некоторые возможности будут недоступны и интерфейс может быть отрисован неправильно.", "You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.": "Вы можете продолжать пользоваться этим браузером, но некоторые возможности будут недоступны и интерфейс может быть отрисован неправильно.",
"I understand the risks and wish to continue": "Я понимаю риск и хочу продолжить", "I understand the risks and wish to continue": "Я понимаю риск и хочу продолжить",
"Go to element.io": "К element.io", "Go to element.io": "К element.io",
"Failed to start": "Старт не удался", "Failed to start": "Старт не удался",

View file

@ -1,4 +1,12 @@
{ {
"Dismiss": "రద్దుచేసే", "Dismiss": "రద్దుచేయి",
"Unknown device": "తెలుయని పరికరం" "Unknown device": "తెలియని పరికరము",
"Go to element.io": "element.io కు వెళ్ళు",
"I understand the risks and wish to continue": "నాకు పర్యవసానాలు తెలిసే ముందుకు కొనసాగుతా",
"Explore rooms": "గదులను అన్వేెషించు",
"Welcome to Element": "ఎలిమెంట్ కు స్వాగతం",
"Failed to start": "ప్రారంభించుటలో విఫలం",
"Create Account": "ఖాతా తెరువు",
"Open": "తెరువు",
"Download Completed": "దిగుమతి పూర్తయినది"
} }

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// TODO: Match the user's theme: https://github.com/vector-im/element-web/issues/12794 /* TODO: Match the user's theme: https://github.com/vector-im/element-web/issues/12794 */
@font-face { @font-face {
font-family: 'Nunito'; font-family: 'Nunito';
@ -57,8 +57,8 @@ body, html {
height: 100%; height: 100%;
width: 100%; width: 100%;
// Hidden by default to avoid flashing the prejoin screen at the user when /* Hidden by default to avoid flashing the prejoin screen at the user when */
// we're supposed to skip it anyways /* we're supposed to skip it anyways */
visibility: hidden; visibility: hidden;
} }
@ -75,7 +75,7 @@ body, html {
} }
#joinButton { #joinButton {
// A mix of AccessibleButton styles /* A mix of AccessibleButton styles */
cursor: pointer; cursor: pointer;
padding: 7px 18px; padding: 7px 18px;
text-align: center; text-align: center;
@ -89,7 +89,7 @@ body, html {
.icon { .icon {
$icon-size: 42px; $icon-size: 42px;
margin-top: -$icon-size; // to visually center the form margin-top: -$icon-size; /* to visually center the form */
&::before { &::before {
content: ''; content: '';
@ -102,7 +102,7 @@ body, html {
display: block; display: block;
width: $icon-size; width: $icon-size;
height: $icon-size; height: $icon-size;
margin: 0 auto; // center margin: 0 auto; /* center */
} }
} }

View file

@ -175,9 +175,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
* Return true if platform supports multi-language * Return true if platform supports multi-language
* spell-checking, otherwise false. * spell-checking, otherwise false.
*/ */
public supportsMultiLanguageSpellCheck(): boolean { public supportsSpellCheckSettings(): boolean {
// Electron uses OS spell checking on macOS, so no need for in-app options
if (isMac) return false;
return true; return true;
} }
@ -305,7 +303,18 @@ export default class ElectronPlatform extends VectorBasePlatform {
return this.ipc.call('setLanguage', preferredLangs); return this.ipc.call('setLanguage', preferredLangs);
} }
public setSpellCheckLanguages(preferredLangs: string[]) { public setSpellCheckEnabled(enabled: boolean): void {
this.ipc.call('setSpellCheckEnabled', enabled).catch(error => {
logger.log("Failed to send setSpellCheckEnabled IPC to Electron");
logger.error(error);
});
}
public async getSpellCheckEnabled(): Promise<boolean> {
return this.ipc.call('getSpellCheckEnabled');
}
public setSpellCheckLanguages(preferredLangs: string[]): void {
this.ipc.call('setSpellCheckLanguages', preferredLangs).catch(error => { this.ipc.call('setSpellCheckLanguages', preferredLangs).catch(error => {
logger.log("Failed to send setSpellCheckLanguages IPC to Electron"); logger.log("Failed to send setSpellCheckLanguages IPC to Electron");
logger.error(error); logger.error(error);

View file

@ -187,8 +187,9 @@ module.exports = (env, argv) => {
"react": path.resolve(__dirname, 'node_modules/react'), "react": path.resolve(__dirname, 'node_modules/react'),
"react-dom": path.resolve(__dirname, 'node_modules/react-dom'), "react-dom": path.resolve(__dirname, 'node_modules/react-dom'),
// same goes for js-sdk - we don't need two copies. // Same goes for js/react-sdk - we don't need two copies.
"matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'), "matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'),
"matrix-react-sdk": path.resolve(__dirname, 'node_modules/matrix-react-sdk'),
// and prop-types and sanitize-html // and prop-types and sanitize-html
"prop-types": path.resolve(__dirname, 'node_modules/prop-types'), "prop-types": path.resolve(__dirname, 'node_modules/prop-types'),
"sanitize-html": path.resolve(__dirname, 'node_modules/sanitize-html'), "sanitize-html": path.resolve(__dirname, 'node_modules/sanitize-html'),
@ -286,7 +287,6 @@ module.exports = (env, argv) => {
// plain CSS together for the bundler. // plain CSS together for the bundler.
require("postcss-simple-vars")(), require("postcss-simple-vars")(),
require("postcss-strip-inline-comments")(),
require("postcss-hexrgba")(), require("postcss-hexrgba")(),
// It's important that this plugin is last otherwise we end // It's important that this plugin is last otherwise we end
@ -355,7 +355,6 @@ module.exports = (env, argv) => {
require("postcss-simple-vars")(), require("postcss-simple-vars")(),
require("postcss-nested")(), require("postcss-nested")(),
require("postcss-easings")(), require("postcss-easings")(),
require("postcss-strip-inline-comments")(),
require("postcss-hexrgba")(), require("postcss-hexrgba")(),
// It's important that this plugin is last otherwise we end // It's important that this plugin is last otherwise we end
@ -632,6 +631,10 @@ module.exports = (env, argv) => {
new SentryCliPlugin({ new SentryCliPlugin({
release: process.env.VERSION, release: process.env.VERSION,
include: "./webapp/bundles", include: "./webapp/bundles",
errorHandler: (err, invokeErr, compilation) => {
compilation.warnings.push('Sentry CLI Plugin: ' + err.message);
console.log(`::warning title=Sentry error::${err.message}`);
},
}), }),
new webpack.EnvironmentPlugin(['VERSION']), new webpack.EnvironmentPlugin(['VERSION']),
].filter(Boolean), ].filter(Boolean),

2358
yarn.lock

File diff suppressed because it is too large Load diff