Merge remote-tracking branch 'upstream/develop' into compact-reply-rendering

This commit is contained in:
Tulir Asokan 2020-03-05 13:19:15 +02:00
commit a8c5574bc8
792 changed files with 44313 additions and 29058 deletions

View file

@ -1,21 +0,0 @@
{
"presets": [
"react",
"es2015",
"es2016"
],
"plugins": [
[
"transform-builtin-extend",
{
"globals": ["Error"]
}
],
"transform-class-properties",
"transform-object-rest-spread",
"transform-async-to-bluebird",
"transform-runtime",
"add-module-exports",
"syntax-dynamic-import"
]
}

View file

@ -1,106 +0,0 @@
steps:
- label: ":eslint: Lint"
command:
# TODO: Remove hacky chmod for BuildKite
- "echo '--- Setup'"
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "echo '--- Install js-sdk'"
- "./scripts/ci/install-deps.sh"
- "yarn lintwithexclusions"
- "yarn stylelint"
plugins:
- docker#v3.0.1:
image: "node:10"
- label: ":chains: End-to-End Tests"
agents:
# We use a medium sized instance instead of the normal small ones because
# e2e tests otherwise take +-8min
queue: "medium"
command:
# TODO: Remove hacky chmod for BuildKite
- "echo '--- Setup'"
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "echo '--- Install js-sdk'"
- "./scripts/ci/install-deps.sh"
- "./scripts/ci/end-to-end-tests.sh"
plugins:
- docker#v3.0.1:
image: "matrixdotorg/riotweb-ci-e2etests-env:latest"
propagate-environment: true
- label: ":karma: Tests"
agents:
# We use a medium sized instance instead of the normal small ones because
# webpack loves to gorge itself on resources.
queue: "medium"
command:
# Install chrome
- "echo '--- Installing Chrome'"
- "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -"
- "sh -c 'echo \"deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'"
- "apt-get update"
- "apt-get install -y google-chrome-stable"
# Run tests
# TODO: Remove hacky chmod for BuildKite
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "echo '--- Installing Dependencies'"
- "./scripts/ci/install-deps.sh"
- "echo '+++ Running Tests'"
- "./scripts/ci/unit-tests.sh"
env:
CHROME_BIN: "/usr/bin/google-chrome-stable"
plugins:
- docker#v3.0.1:
image: "node:10"
propagate-environment: true
- label: "🔧 Riot Tests"
agents:
# We use a medium sized instance instead of the normal small ones because
# webpack loves to gorge itself on resources.
queue: "medium"
command:
# Install chrome
- "echo '--- Installing Chrome'"
- "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -"
- "sh -c 'echo \"deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'"
- "apt-get update"
- "apt-get install -y google-chrome-stable"
# Run tests
# TODO: Remove hacky chmod for BuildKite
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "echo '--- Installing Dependencies'"
- "./scripts/ci/install-deps.sh"
- "echo '+++ Running Tests'"
- "./scripts/ci/riot-unit-tests.sh"
env:
CHROME_BIN: "/usr/bin/google-chrome-stable"
plugins:
- docker#v3.0.1:
image: "node:10"
propagate-environment: true
- label: "🌐 i18n"
command:
- "echo '--- Fetching Dependencies'"
- "yarn install"
- "echo '+++ Testing i18n output'"
- "yarn diff-i18n"
plugins:
- docker#v3.0.1:
image: "node:10"
- wait
- label: "🐴 Trigger riot-web"
trigger: "riot-web"
branches: "develop"
build:
branch: "develop"
message: "[react-sdk] ${BUILDKITE_MESSAGE}"
async: true

View file

@ -1 +1,4 @@
src/component-index.js
test/end-to-end-tests/node_modules/
test/end-to-end-tests/riot/
test/end-to-end-tests/synapse/

View file

@ -33,7 +33,6 @@ src/components/views/rooms/RoomList.js
src/components/views/rooms/RoomPreviewBar.js
src/components/views/rooms/SearchBar.js
src/components/views/rooms/SearchResultTile.js
src/components/views/rooms/SlateMessageComposer.js
src/components/views/settings/ChangeAvatar.js
src/components/views/settings/ChangePassword.js
src/components/views/settings/DevicesPanel.js
@ -58,8 +57,11 @@ src/utils/Receipt.js
src/Velociraptor.js
test/components/structures/MessagePanel-test.js
test/components/views/dialogs/InteractiveAuthDialog-test.js
test/components/views/rooms/MessageComposerInput-test.js
test/mock-clock.js
test/notifications/ContentRules-test.js
test/notifications/PushRuleVectorState-test.js
test/stores/RoomViewStore-test.js
src/component-index.js
test/end-to-end-tests/node_modules/
test/end-to-end-tests/riot/
test/end-to-end-tests/synapse/

View file

@ -5,13 +5,17 @@ const path = require('path');
// but only if they come from a module that starts with eslint-config-
// So we load the filename directly (and it could be in node_modules/
// or or ../node_modules/ etc)
const matrixJsSdkPath = path.dirname(require.resolve('matrix-js-sdk'));
//
// We add a `..` to the end because the js-sdk lives out of lib/, but the eslint
// config is at the project root.
const matrixJsSdkPath = path.join(path.dirname(require.resolve('matrix-js-sdk')), '..');
module.exports = {
parser: "babel-eslint",
extends: [matrixJsSdkPath + "/.eslintrc.js"],
plugins: [
"react",
"react-hooks",
"flowtype",
"babel"
],
@ -24,6 +28,7 @@ module.exports = {
parserOptions: {
ecmaFeatures: {
jsx: true,
legacyDecorators: true,
}
},
rules: {
@ -104,6 +109,9 @@ module.exports = {
// crashes currently: https://github.com/eslint/eslint/issues/6274
"generator-star-spacing": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
},
settings: {
flowtype: {

View file

@ -15,6 +15,7 @@ module.exports = {
"number-leading-zero": null,
"selector-list-comma-newline-after": null,
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"scss/at-rule-no-unknown": [true, {
// https://github.com/vector-im/riot-web/issues/10544
"ignoreAtRules": ["define-mixin"],

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@ matrix-react-sdk
This is a react-based SDK for inserting a Matrix chat/voip client into a web page.
This package provides the React components needed to build a Matrix web client
using React. It is not useable in isolation, and instead must must be used from
using React. It is not useable in isolation, and instead must be used from
a 'skin'. A skin provides:
* Customised implementations of presentation components.
* Custom CSS
@ -67,6 +67,7 @@ practices that anyone working with the SDK needs to be be aware of and uphold:
* After creating a new component you must run `yarn reskindex` to regenerate
the `component-index.js` for the SDK (used in future for skinning)
<!-- TODO: Remove this once this approach to skinning is replaced -->
* The view's CSS file MUST have the same name (e.g. view/rooms/MessageTile.css).
CSS for matrix-react-sdk currently resides in
@ -82,7 +83,7 @@ practices that anyone working with the SDK needs to be be aware of and uphold:
'Stealing' styling information from other components (including parents)
is not cool, as it breaks the independence of the components.
* CSS classes are named with an app-specific namespacing prefix to try to avoid
* CSS classes are named with an app-specific name-spacing prefix to try to avoid
CSS collisions. The base skin shipped by Matrix.org with the matrix-react-sdk
uses the naming prefix "mx_". A company called Yoyodyne Inc might use a
prefix like "yy_" for its app-specific classes.
@ -107,7 +108,7 @@ practices that anyone working with the SDK needs to be be aware of and uphold:
.mx_RoomTile {} in RoomList.css - only RoomTile.css is allowed to define its
own CSS. Instead, say .mx_RoomList .mx_RoomTile {} to scope the override
only to the context of RoomList views. N.B. overrides should be relatively
rare as in general CSS inheritence should be enough.
rare as in general CSS inheritance should be enough.
* Components should render only within the bounding box of their outermost DOM
element. Page-absolute positioning and negative CSS margins and similar are
@ -168,3 +169,8 @@ Ensure you've followed the above development instructions and then:
```bash
yarn test
```
## End-to-End tests
Make sure you've got your Riot development server running (by doing `yarn start` in riot-web), and then in this project, run `yarn run e2etests`.
See `test/end-to-end-tests/README.md` for more information.

View file

@ -0,0 +1,17 @@
const en = require("../src/i18n/strings/en_EN");
module.exports = jest.fn((opts, cb) => {
const url = opts.url || opts.uri;
if (url && url.endsWith("languages.json")) {
cb(undefined, {status: 200}, JSON.stringify({
"en": {
"fileName": "en_EN.json",
"label": "English",
},
}));
} else if (url && url.endsWith("en_EN.json")) {
cb(undefined, {status: 200}, JSON.stringify(en));
} else {
cb(true, {status: 404}, "");
}
});

1
__mocks__/imageMock.js Normal file
View file

@ -0,0 +1 @@
module.exports = "image-file-stub";

10
__mocks__/languages.json Normal file
View file

@ -0,0 +1,10 @@
{
"en": {
"fileName": "en_EN.json",
"label": "English"
},
"en-us": {
"fileName": "en_US.json",
"label": "English (US)"
}
}

23
babel.config.js Normal file
View file

@ -0,0 +1,23 @@
module.exports = {
"sourceMaps": "inline",
"presets": [
["@babel/preset-env", {
"targets": [
"last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions"
],
}],
"@babel/preset-typescript",
"@babel/preset-flow",
"@babel/preset-react"
],
"plugins": [
["@babel/plugin-proposal-decorators", {legacy: true}],
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-flow-comments",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-runtime"
]
};

View file

@ -22,7 +22,7 @@ number throgh from the original code to the final application.
General Style
-------------
- 4 spaces to indent, for consistency with Matrix Python.
- 120 columns per line, but try to keep JavaScript code around the 80 column mark.
- 120 columns per line, but try to keep JavaScript code around the 90 column mark.
Inline JSX in particular can be nicer with more columns per line.
- No trailing whitespace at end of lines.
- Don't indent empty lines.
@ -174,12 +174,6 @@ React
<Foo onClick={this.onFooClick}> // Best, if onFooClick would do anything other than directly calling doStuff
```
Not doing so is acceptable in a single case: in function-refs:
```jsx
<Foo ref={(self) => this.component = self}>
```
- Prefer classes that extend `React.Component` (or `React.PureComponent`) instead of `React.createClass`
- You can avoid the need to bind handler functions by using [property initializers](https://reactjs.org/docs/react-component.html#constructor):
@ -208,3 +202,5 @@ React
```
- Think about whether your component really needs state: are you duplicating
information in component state that could be derived from the model?
- Avoid things marked as Legacy or Deprecated in React 16 (e.g string refs and legacy contexts)

View file

@ -2,8 +2,7 @@
The CIDER editor is a custom editor written for Riot.
Most of the code can be found in the `/editor/` directory of the `matrix-react-sdk` project.
It is used to power the composer to edit messages,
and will soon be used as the main composer to send messages as well.
It is used to power the composer main composer (both to send and edit messages), and might be used for other usecases where autocomplete is desired (invite box, ...).
## High-level overview.

28
docs/scrolling.md Normal file
View file

@ -0,0 +1,28 @@
# ScrollPanel
## Updates
During an onscroll event, we check whether we're getting close to the top or bottom edge of the loaded content. If close enough, we fire a request to load more through the callback passed in the `onFillRequest` prop. This returns a promise is passed down from `TimelinePanel`, where it will call paginate on the `TimelineWindow` and once the events are received back, update its state with the new events. This update trickles down to the `MessagePanel`, which rerenders all tiles and passed that to `ScrollPanel`. ScrollPanels `componentDidUpdate` method gets called, and we do the scroll housekeeping there (read below). Once the rerender has completed, the `setState` callback is called and we resolve the promise returned by `onFillRequest`. Now we check the DOM to see if we need more fill requests.
## Prevent Shrinking
ScrollPanel supports a mode to prevent it shrinking. This is used to prevent a jump when at the bottom of the timeline and people start and stop typing. It gets cleared automatically when 200px above the bottom of the timeline.
## BACAT (Bottom-Aligned, Clipped-At-Top) scrolling
BACAT scrolling implements a different way of restoring the scroll position in the timeline while tiles out of view are changing height or tiles are being added or removed. It was added in https://github.com/matrix-org/matrix-react-sdk/pull/2842.
The motivation for the changes is having noticed that setting scrollTop while scrolling tends to not work well, with it interrupting ongoing scrolling and also querying scrollTop reporting outdated values and consecutive scroll adjustments cancelling each out previous ones. This seems to be worse on macOS than other platforms, presumably because of a higher resolution in scroll events there. Also see https://github.com/vector-im/riot-web/issues/528. The BACAT approach allows to only have to change the scroll offset when adding or removing tiles.
The approach taken instead is to vertically align the timeline tiles to the bottom of the scroll container (using flexbox) and give the timeline inside the scroll container an explicit height, initially set to a multiple of the PAGE_SIZE (400px at time of writing) as needed by the content. When scrolled up, we can compensate for anything that grew below the viewport by changing the height of the timeline to maintain what's currently visible in the viewport without adjusting the scrollTop and hence without jumping.
For anything above the viewport growing or shrinking, we don't need to do anything as the timeline is bottom-aligned. We do need to update the height manually to keep all content visible as more is loaded. To maintain scroll position after the portion above the viewport changes height, we need to set the scrollTop, as we cannot balance it out with more height changes. We do this 100ms after the user has stopped scrolling, so setting scrollTop has not nasty side-effects.
As of https://github.com/matrix-org/matrix-react-sdk/pull/4166, we are scrolling to compensate for height changes by calling `scrollBy(0, x)` rather than reading and than setting `scrollTop`, as reading `scrollTop` can (again, especially on macOS) easily return values that are out of sync with what is on the screen, probably because scrolling can be done [off the main thread](https://wiki.mozilla.org/Platform/GFX/APZ) in some circumstances. This seems to further prevent jumps.
### How does it work?
`componentDidUpdate` is called when a tile in the timeline is updated (as we rerender the whole timeline) or tiles are added or removed (see Updates section before). From here, `checkScroll` is called, which calls `_restoreSavedScrollState`. Now, we increase the timeline height if something below the viewport grew by adjusting `this._bottomGrowth`. `bottomGrowth` is the height added to the timeline (on top of the height from the number of pages calculated at the last `_updateHeight` run) to compensate for growth below the viewport. This is cleared during the next run of `_updateHeight`. Remember that the tiles in the timeline are aligned to the bottom.
From `_restoreSavedScrollState` we also call `_updateHeight` which waits until the user stops scrolling for 100ms and then recalculates the amount of pages of 400px the timeline should be sized to, to be able to show all of its (newly added) content. We have to adjust the scroll offset (which is why we wait until scrolling has stopped) now because the space above the viewport has likely changed.

71
docs/skinning.md Normal file
View file

@ -0,0 +1,71 @@
# Skinning
The react-sdk can be skinned to replace presentation components, CSS, or
other relevant parts of the SDK. Typically consumers will replace entire
components and get the ability for custom CSS as a result.
This doc isn't exhaustive on how skinning works, though it should cover
some of the more complicated parts such as component replacement.
## Loading a skin
1. Generate a `component-index.js` (preferably using the tools that the react-sdk
exposes). This can typically be done with a npm script like `"reskindex -h src/header"`.
2. In your app's entry point, add something like this code:
```javascript
import {loadSkin} from "matrix-react-sdk";
loadSkin(import("component-index").components);
// The rest of your imports go under this.
```
3. Import the remainder of the SDK and bootstrap your app.
It is extremely important that you **do not** import anything else from the
SDK prior to loading your skin as otherwise the skin might not work. Loading
the skin should be one of the first things your app does, if not the very
first thing.
Additionally, **do not** provide `loadSkin` with the react-sdk components
themselves otherwise the app might explode. The SDK is already aware of its
components and doesn't need to be told.
## Replacing components
Components that replace the react-sdk ones MUST have a `replaces` static
key on the component's class to describe which component it overrides. For
example, if your `VectorAuthPage` component is meant to replace the react-sdk
`AuthPage` component then you'd add `static replaces = 'views.auth.AuthPage';`
to the `VectorAuthPage` class.
Other than that, the skin just needs to be loaded normally as mentioned above.
Consumers of the SDK likely will not be interested in the rest of this section.
### SDK developer notes
Components in the react-sdk MUST be decorated with the `@replaceableComponent`
function. For components that can't use the decorator, they must use a
variation that provides similar functionality. The decorator gives consumers
an opportunity to load skinned components by abusing import ordering and
behaviour.
Decorators are executed at import time which is why we can abuse the import
ordering behaviour: importing `loadSkin` doesn't trigger any components to
be imported, allowing the consumer to specify a skin. When the consumer does
import a component (for example, `MatrixChat`), it starts to pull in all the
components via `import` statements. When the components get pulled in the
decorator checks with the skinned components to see if it should be replacing
the component being imported. The decorator then effectively replaces the
components when needed by specifying the skinned component as an override for
the SDK's component, which should in theory override critical functions like
`render()` and lifecycle event handlers.
The decorator also means that older usage of `getComponent()` is no longer
required because components should be replaced by the decorator. Eventually
the react-sdk should only have one usage of `getComponent()`: the decorator.
The decorator assumes that if `getComponent()` returns null that there is
no skinned version of the component and continues on using the SDK's component.
In previous versions of the SDK, the function would throw an error instead
because it also expected the skin to list the SDK's components as well, however
that is no longer possible due to the above.
In short, components should always be `import`ed.

27
docs/usercontent.md Normal file
View file

@ -0,0 +1,27 @@
# Usercontent
While decryption itself is safe to be done without a sandbox,
letting the browser and user interact with the resulting data may be dangerous,
previously `usercontent.riot.im` was used to act as a sandbox on a different origin to close the attack surface,
it is now possible to do by using a combination of a sandboxed iframe and some code written into the app which consumes this SDK.
Usercontent is an iframe sandbox target for allowing a user to safely download a decrypted attachment from a sandboxed origin where it cannot be used to XSS your riot session out from under you.
Its function is to create an Object URL for the user/browser to use but bound to an origin different to that of the riot instance to protect against XSS.
It exposes a function over a postMessage API, when sent an object with the matching fields to render a download link with the Object URL:
```json5
{
"imgSrc": "", // the src of the image to display in the download link
"imgStyle": "", // the style to apply to the image
"style": "", // the style to apply to the download link
"download": "", // download attribute to pass to the <a/> tag
"textContent": "", // the text to put inside the download link
"blob": "", // the data blob to wrap in an object url and allow the user to download
}
```
If only imgSrc, imgStyle and style are passed then just update the existing link without overwriting other things about it.
It is expected that this target be available at `usercontent/` relative to the root of the app, this can be seen in riot-web's webpack config.

View file

@ -1,39 +0,0 @@
#!/bin/bash
set -e
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm use 10
set -x
scripts/fetchdep.sh matrix-org matrix-js-sdk
pushd matrix-js-sdk
yarn link
yarn install
popd
yarn link matrix-js-sdk
# install the other dependencies
yarn install
# run the mocha tests
yarn test --no-colors
# run eslint
yarn lintall -f checkstyle -o eslint.xml || true
# re-run the linter, excluding any files known to have errors or warnings.
yarn lintwithexclusions
# lint styles
yarn stylelint
# delete the old tarball, if it exists
rm -f matrix-react-sdk-*.tgz
# build our tarball
yarn pack

View file

@ -1,228 +0,0 @@
// karma.conf.js - the config file for karma, which runs our tests.
var path = require('path');
var fs = require('fs');
/*
* We use webpack to build our tests. It's a pain to have to wait for webpack
* to build everything; however it's the easiest way to load our dependencies
* from node_modules.
*
* If you run karma in multi-run mode (with `yarn test-multi`), it will watch
* the tests for changes, and webpack will rebuild using a cache. This is much quicker
* than a clean rebuild.
*/
// the name of the test file. By default, a special file which runs all tests.
//
// TODO: this could be a pattern, and karma would run each file, with a
// separate webpack bundle for each file. But then we get a separate instance
// of the sdk, and each of the dependencies, for each test file, and everything
// gets very confused. Can we persuade webpack to put all of the dependencies
// in a 'common' bundle?
//
var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js';
process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
function fileExists(name) {
try {
fs.statSync(name);
return true;
} catch (e) {
return false;
}
}
// try find the gemini-scrollbar css in an version-agnostic way
var gsCss = 'node_modules/gemini-scrollbar/gemini-scrollbar.css';
if (!fileExists(gsCss)) {
gsCss = 'node_modules/react-gemini-scrollbar/'+gsCss;
}
module.exports = function (config) {
config.set({
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
testFile,
gsCss,
// some images to reduce noise from the tests
{pattern: 'test/img/*', watched: false, included: false,
served: true, nocache: false},
// translation files
{pattern: 'src/i18n/strings/*', watcheed: false, included: false, served: true},
{pattern: 'test/i18n/*', watched: false, included: false, served: true},
],
proxies: {
// redirect img links to the karma server
"/img/": "/base/test/img/",
// special languages.json file for the tests
"/i18n/languages.json": "/base/test/i18n/languages.json",
// and redirect i18n requests
"/i18n/": "/base/src/i18n/strings/",
},
// list of files to exclude
//
// This doesn't work. It turns out that it's webpack which does the
// watching of the /test directory (karma only watches `testFile`
// itself). Webpack watches the directory so that it can spot
// new tests, which is fair enough; unfortunately it triggers a rebuild
// every time a lockfile is created in that directory, and there
// doesn't seem to be any way to tell webpack to ignore particular
// files in a watched directory.
//
// exclude: [
// '**/.#*'
// ],
// preprocess matching files before serving them to the browser
// available preprocessors:
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/**/*.js': ['webpack', 'sourcemap']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['logcapture', 'spec', 'summary'],
specReporter: {
suppressErrorSummary: false, // do print error summary
suppressFailed: false, // do print information about failed tests
suppressPassed: false, // do print information about passed tests
showSpecTiming: true, // print the time elapsed for each spec
},
client: {
captureLogs: true,
},
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR ||
// config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
//
// This is strictly for logs that would be generated by the browser itself and we
// don't want to log about missing images, which are emitted on LOG_WARN.
logLevel: config.LOG_ERROR,
// enable / disable watching file and executing tests whenever any file
// changes
autoWatch: true,
// start these browsers
// available browser launchers:
// https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'Chrome',
//'PhantomJS',
//'ChromeHeadless',
],
customLaunchers: {
'VectorChromeHeadless': {
base: 'Chrome',
flags: [
'--no-sandbox',
// See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
'--headless',
'--disable-gpu',
// Without a remote debugging port, Google Chrome exits immediately.
'--remote-debugging-port=9222',
],
}
},
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
// singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
webpack: {
module: {
rules: [
{
test: /\.js$/, loader: "babel-loader",
include: [path.resolve('./src'),
path.resolve('./test'),
]
},
{
test: /\.(gif|png|svg|ttf|woff2)$/,
loader: 'file-loader',
},
],
noParse: [
// for cross platform compatibility use [\\\/] as the path separator
// this ensures that the regex trips on both Windows and *nix
// don't parse the languages within highlight.js. They
// cause stack overflows
// (https://github.com/webpack/webpack/issues/1721), and
// there is no need for webpack to parse them - they can
// just be included as-is.
/highlight\.js[\\\/]lib[\\\/]languages/,
// olm takes ages for webpack to process, and it's already heavily
// optimised, so there is little to gain by us uglifying it.
/olm[\\\/](javascript[\\\/])?olm\.js$/,
// also disable parsing for sinon, because it
// tries to do voodoo with 'require' which upsets
// webpack (https://github.com/webpack/webpack/issues/304)
/sinon[\\\/]pkg[\\\/]sinon\.js$/,
],
},
resolve: {
alias: {
// alias any requires to the react module to the one in our
// path, otherwise we tend to get the react source included
// twice when using `npm link` / `yarn link`.
react: path.resolve('./node_modules/react'),
'matrix-react-sdk': path.resolve('test/skinned-sdk.js'),
'sinon': 'sinon/pkg/sinon.js',
},
modules: [
path.resolve('./test'),
"node_modules"
],
},
devtool: 'inline-source-map',
externals: {
// Don't try to bundle electron: leave it as a commonjs dependency
// (the 'commonjs' here means it will output a 'require')
"electron": "commonjs electron",
},
// make sure we're flagged as development to avoid wasting time optimising
mode: 'development',
},
webpackMiddleware: {
stats: {
// don't fill the console up with a mahoosive list of modules
chunks: false,
},
},
browserNoActivityTimeout: 15000,
});
};

View file

@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
"version": "1.6.2",
"version": "2.2.1",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
@ -8,58 +8,53 @@
"url": "https://github.com/matrix-org/matrix-react-sdk"
},
"license": "Apache-2.0",
"main": "lib/index.js",
"files": [
".babelrc",
".eslintrc.js",
"lib",
"res",
"src",
"scripts",
"git-revision.txt",
"docs",
"header",
"CHANGELOG.md",
"CONTRIBUTING.rst",
"LICENSE",
"README.md",
"code_style.md",
"git-revision.txt",
"header",
"jenkins.sh",
"karma.conf.js",
"lib",
"package.json",
"release.sh",
"scripts",
"src",
"test",
"res"
"package.json"
],
"bin": {
"reskindex": "scripts/reskindex.js",
"matrix-gen-i18n": "scripts/gen-i18n.js",
"matrix-prune-i18n": "scripts/prune-i18n.js"
},
"main": "./lib/index.js",
"typings": "./lib/index.d.ts",
"matrix_src_main": "./src/index.js",
"scripts": {
"reskindex": "node scripts/reskindex.js -h header",
"reskindex:watch": "node scripts/reskindex.js -h header -w",
"rethemendex": "res/css/rethemendex.sh",
"prepare": "yarn build",
"i18n": "matrix-gen-i18n",
"prunei18n": "matrix-prune-i18n",
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && ./scripts/gen-i18n.js && node scripts/compare-file.js src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
"build": "yarn reskindex && yarn start:init",
"build:watch": "babel src -w --skip-initial-build -d lib --source-maps --copy-files",
"emoji-data-strip": "node scripts/emoji-data-strip.js",
"start": "yarn start:init && yarn start:all",
"start:all": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n build,reskindex \"yarn build:watch\" \"yarn reskindex:watch\"",
"start:init": "babel src -d lib --source-maps --copy-files",
"lint": "eslint src/",
"lintall": "eslint src/ test/",
"lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test",
"stylelint": "stylelint 'res/css/**/*.scss'",
"reskindex": "node scripts/reskindex.js -h header",
"reskindex:watch": "node scripts/reskindex.js -h header -w",
"rethemendex": "res/css/rethemendex.sh",
"clean": "rimraf lib",
"prepare": "yarn clean && yarn build && git rev-parse HEAD > git-revision.txt",
"test": "karma start --single-run=true --browsers VectorChromeHeadless",
"test-multi": "karma start"
"build": "yarn clean && git rev-parse HEAD > git-revision.txt && yarn build:compile && yarn build:types",
"build:compile": "yarn reskindex && babel -d lib --verbose --extensions \".ts,.js\" src",
"build:types": "tsc --emitDeclarationOnly",
"start": "echo THIS IS FOR LEGACY PURPOSES ONLY. && yarn start:all",
"start:all": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n build,reskindex \"yarn start:build\" \"yarn reskindex:watch\"",
"start:build": "babel src -w -s -d lib --verbose --extensions \".ts,.js\"",
"lint": "yarn lint:types && yarn lint:ts && yarn lint:js && yarn lint:style",
"lint:js": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test",
"lint:ts": "tslint --project ./tsconfig.json -t stylish",
"lint:types": "tsc --noEmit",
"lint:style": "stylelint 'res/css/**/*.scss'",
"test": "jest",
"test:e2e": "./test/end-to-end-tests/run.sh --riot-url http://localhost:8080"
},
"dependencies": {
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-runtime": "^6.26.0",
"bluebird": "^3.5.0",
"@babel/runtime": "^7.8.3",
"blueimp-canvas-to-blob": "^3.5.0",
"browser-encrypt-attachment": "^0.3.0",
"browser-request": "^0.3.3",
@ -71,96 +66,104 @@
"diff-match-patch": "^1.0.4",
"emojibase-data": "^4.0.2",
"emojibase-regex": "^3.0.0",
"escape-html": "^1.0.3",
"file-saver": "^1.3.3",
"filesize": "3.5.6",
"flux": "2.1.1",
"focus-trap-react": "^3.0.5",
"focus-visible": "^5.0.2",
"fuse.js": "^2.2.0",
"gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566",
"gfm.css": "^1.1.1",
"glob": "^5.0.14",
"glob-to-regexp": "^0.4.1",
"highlight.js": "^9.15.8",
"html-entities": "^1.2.1",
"is-ip": "^2.0.0",
"isomorphic-fetch": "^2.2.1",
"linkifyjs": "^2.1.6",
"lodash": "^4.17.14",
"lolex": "4.2",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"optimist": "^0.6.1",
"minimist": "^1.2.0",
"pako": "^1.0.5",
"png-chunks-extract": "^1.0.0",
"prop-types": "^15.5.8",
"qrcode": "^1.4.4",
"qrcode-react": "^0.1.16",
"qs": "^6.6.0",
"querystring": "^0.2.0",
"react": "^16.9.0",
"react-addons-css-transition-group": "15.6.2",
"react-beautiful-dnd": "^4.0.1",
"react-dom": "^16.9.0",
"react-focus-lock": "^2.2.1",
"react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594",
"resize-observer-polyfill": "^1.5.0",
"sanitize-html": "^1.18.4",
"slate": "^0.41.2",
"slate-html-serializer": "^0.6.1",
"slate-md-serializer": "github:matrix-org/slate-md-serializer#f7c4ad3",
"slate-react": "^0.18.10",
"text-encoding-utf-8": "^1.0.1",
"url": "^0.11.0",
"velocity-animate": "^1.5.2",
"whatwg-fetch": "^1.1.1",
"what-input": "^5.2.6",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-loader": "^7.1.5",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-async-to-bluebird": "^1.1.1",
"babel-plugin-transform-builtin-extend": "^1.1.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2016": "^6.24.1",
"babel-preset-es2017": "^6.24.1",
"babel-preset-react": "^6.24.1",
"chokidar": "^2.1.2",
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-proposal-decorators": "^7.7.4",
"@babel/plugin-proposal-export-default-from": "^7.7.4",
"@babel/plugin-proposal-numeric-separator": "^7.7.4",
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
"@babel/plugin-transform-flow-comments": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.7.6",
"@babel/preset-flow": "^7.7.4",
"@babel/preset-react": "^7.7.4",
"@babel/preset-typescript": "^7.7.4",
"@babel/register": "^7.7.4",
"@peculiar/webcrypto": "^1.0.22",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"chokidar": "^3.3.1",
"concurrently": "^4.0.1",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.1",
"eslint": "^5.12.0",
"eslint-config-google": "^0.7.1",
"eslint-plugin-babel": "^5.2.1",
"eslint-plugin-flowtype": "^2.30.0",
"eslint-plugin-jest": "^23.0.4",
"eslint-plugin-react": "^7.7.0",
"eslint-plugin-react-hooks": "^2.0.1",
"estree-walker": "^0.5.0",
"expect": "^24.1.0",
"file-loader": "^3.0.1",
"flow-parser": "^0.57.3",
"jest-mock": "^23.2.0",
"karma": "^4.0.1",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-logcapture-reporter": "0.0.1",
"karma-mocha": "^1.3.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "^0.0.31",
"karma-summary-reporter": "^1.5.1",
"karma-webpack": "^4.0.0-beta.0",
"glob": "^5.0.14",
"jest": "^24.9.0",
"lolex": "^5.1.2",
"matrix-mock-request": "^1.2.3",
"matrix-react-test-utils": "^0.2.2",
"mocha": "^5.0.5",
"react-test-renderer": "^16.9.0",
"require-json": "0.0.1",
"rimraf": "^2.4.3",
"sinon": "^5.0.7",
"source-map-loader": "^0.2.3",
"stylelint": "^9.10.1",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.9.0",
"tslint": "^5.20.1",
"typescript": "^3.7.3",
"walk": "^2.3.9",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.1"
},
"jest": {
"testMatch": [
"<rootDir>/test/**/*-test.js"
],
"setupFilesAfterEnv": [
"<rootDir>/test/setupTests.js"
],
"moduleNameMapper": {
"\\.(gif|png|svg|ttf|woff2)$": "<rootDir>/__mocks__/imageMock.js",
"\\$webapp/i18n/languages.json": "<rootDir>/__mocks__/languages.json"
},
"transformIgnorePatterns": [
"/node_modules/(?!matrix-js-sdk).+$"
]
}
}

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Script to perform a release of matrix-react-sdk.
#
@ -9,4 +9,52 @@ set -e
cd `dirname $0`
exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
for i in matrix-js-sdk
do
echo "Checking version of $i..."
depver=`cat package.json | jq -r .dependencies[\"$i\"]`
latestver=`yarn info -s $i dist-tags.next`
if [ "$depver" != "$latestver" ]
then
echo "The latest version of $i is $latestver but package.json depends on $depver."
echo -n "Type 'u' to auto-upgrade, 'c' to continue anyway, or 'a' to abort:"
read resp
if [ "$resp" != "u" ] && [ "$resp" != "c" ]
then
echo "Aborting."
exit 1
fi
if [ "$resp" == "u" ]
then
echo "Upgrading $i to $latestver..."
yarn add -E $i@$latestver
git add -u
# The `-e` flag opens the editor and gives you a chance to check
# the upgrade for correctness.
git commit -m "Upgrade $i to $latestver" -e
fi
fi
done
./node_modules/matrix-js-sdk/release.sh -z "$@"
release="${1#v}"
prerelease=0
# We check if this build is a prerelease by looking to
# see if the version has a hyphen in it. Crude,
# but semver doesn't support postreleases so anything
# with a hyphen is a prerelease.
echo $release | grep -q '-' && prerelease=1
if [ $prerelease -eq 0 ]
then
# For a release, reset SDK deps back to the `develop` branch.
for i in matrix-js-sdk
do
echo "Resetting $i to develop branch..."
yarn add github:matrix-org/$i#develop
git add -u
git commit -m "Reset $i back to develop branch"
done
git push origin develop
fi

View file

@ -30,6 +30,11 @@ body {
color: $primary-fg-color;
border: 0px;
margin: 0px;
// needed to match the designs correctly on macOS
// see https://github.com/vector-im/riot-web/issues/11425
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
pre, code {
@ -333,6 +338,14 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
margin-bottom: 10px;
}
.mx_Dialog_titleImage {
vertical-align: middle;
width: 25px;
height: 25px;
margin-left: -2px;
margin-right: 4px;
}
.mx_Dialog_title {
font-size: 22px;
line-height: 36px;
@ -373,7 +386,13 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
text-align: right;
}
.mx_Dialog button, .mx_Dialog input[type="submit"] {
/* XXX: Our button style are a mess: buttons that happen to appear in dialogs get special styles applied
* to them that no button anywhere else in the app gets by default. In practice, buttons in other places
* in the app look the same by being AccessibleButtons, or possibly by having explict button classes.
* We should go through and have one consistent set of styles for buttons throughout the app.
* For now, I am duplicating the selectors here for mx_Dialog and mx_DialogButtons.
*/
.mx_Dialog button, .mx_Dialog input[type="submit"], .mx_Dialog_buttons button, .mx_Dialog_buttons input[type="submit"] {
@mixin mx_DialogButton;
margin-left: 0px;
margin-right: 8px;
@ -389,27 +408,32 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
margin-right: 0px;
}
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover {
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover, .mx_Dialog_buttons button:hover, .mx_Dialog_buttons input[type="submit"]:hover {
@mixin mx_DialogButton_hover;
}
.mx_Dialog button:focus, .mx_Dialog input[type="submit"]:focus {
.mx_Dialog button:focus, .mx_Dialog input[type="submit"]:focus, .mx_Dialog_buttons button:focus, .mx_Dialog_buttons input[type="submit"]:focus {
filter: brightness($focus-brightness);
}
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary, .mx_Dialog_buttons button.mx_Dialog_primary, .mx_Dialog_buttons input[type="submit"].mx_Dialog_primary {
color: $accent-fg-color;
background-color: $accent-color;
min-width: 156px;
}
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger, .mx_Dialog_buttons button.danger, .mx_Dialog_buttons input[type="submit"].danger {
background-color: $warning-color;
border: solid 1px $warning-color;
color: $accent-fg-color;
}
.mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled {
.mx_Dialog button.warning, .mx_Dialog input[type="submit"].warning {
border: solid 1px $warning-color;
color: $warning-color;
}
.mx_Dialog button:disabled, .mx_Dialog input[type="submit"]:disabled, .mx_Dialog_buttons button:disabled, .mx_Dialog_buttons input[type="submit"]:disabled {
background-color: $light-fg-color;
border: solid 1px $light-fg-color;
opacity: 0.7;
@ -550,6 +574,22 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
color: $username-variant8-color;
}
@define-mixin mx_Tooltip_dark {
box-shadow: none;
background-color: $tooltip-timeline-bg-color;
color: $tooltip-timeline-fg-color;
border: none;
border-radius: 3px;
padding: 6px 8px;
}
// This is a workaround for our mixins not supporting child selectors
.mx_Tooltip_dark {
.mx_Tooltip_chevron::after {
border-right-color: $tooltip-timeline-bg-color;
}
}
@define-mixin mx_Settings_fullWidthField {
margin-right: 100px;
}

View file

@ -24,10 +24,11 @@
@import "./structures/_SearchBox.scss";
@import "./structures/_TabbedView.scss";
@import "./structures/_TagPanel.scss";
@import "./structures/_TagPanelButtons.scss";
@import "./structures/_ToastContainer.scss";
@import "./structures/_TopLeftMenuButton.scss";
@import "./structures/_UploadBar.scss";
@import "./structures/_ViewSource.scss";
@import "./structures/auth/_CompleteSecurity.scss";
@import "./structures/auth/_Login.scss";
@import "./views/auth/_AuthBody.scss";
@import "./views/auth/_AuthButtons.scss";
@ -35,6 +36,7 @@
@import "./views/auth/_AuthHeader.scss";
@import "./views/auth/_AuthHeaderLogo.scss";
@import "./views/auth/_AuthPage.scss";
@import "./views/auth/_CompleteSecurityBody.scss";
@import "./views/auth/_CountryDropdown.scss";
@import "./views/auth/_InteractiveAuthEntryComponents.scss";
@import "./views/auth/_LanguageSelector.scss";
@ -48,6 +50,7 @@
@import "./views/context_menus/_StatusMessageContextMenu.scss";
@import "./views/context_menus/_TagTileContextMenu.scss";
@import "./views/context_menus/_TopLeftMenu.scss";
@import "./views/context_menus/_WidgetContextMenu.scss";
@import "./views/dialogs/_AddressPickerDialog.scss";
@import "./views/dialogs/_Analytics.scss";
@import "./views/dialogs/_ChangelogDialog.scss";
@ -61,10 +64,13 @@
@import "./views/dialogs/_EncryptedEventDialog.scss";
@import "./views/dialogs/_GroupAddressPicker.scss";
@import "./views/dialogs/_IncomingSasDialog.scss";
@import "./views/dialogs/_InviteDialog.scss";
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
@import "./views/dialogs/_RestoreKeyBackupDialog.scss";
@import "./views/dialogs/_NewSessionReviewDialog.scss";
@import "./views/dialogs/_RoomSettingsDialog.scss";
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
@import "./views/dialogs/_RoomUpgradeDialog.scss";
@import "./views/dialogs/_RoomUpgradeWarningDialog.scss";
@import "./views/dialogs/_SetEmailDialog.scss";
@import "./views/dialogs/_SetMxIdDialog.scss";
@import "./views/dialogs/_SetPasswordDialog.scss";
@ -80,6 +86,8 @@
@import "./views/dialogs/keybackup/_CreateKeyBackupDialog.scss";
@import "./views/dialogs/keybackup/_KeyBackupFailedDialog.scss";
@import "./views/dialogs/keybackup/_RestoreKeyBackupDialog.scss";
@import "./views/dialogs/secretstorage/_AccessSecretStorageDialog.scss";
@import "./views/dialogs/secretstorage/_CreateSecretStorageDialog.scss";
@import "./views/directory/_NetworkDropdown.scss";
@import "./views/elements/_AccessibleButton.scss";
@import "./views/elements/_AddressSelector.scss";
@ -90,6 +98,8 @@
@import "./views/elements/_ErrorBoundary.scss";
@import "./views/elements/_EventListSummary.scss";
@import "./views/elements/_Field.scss";
@import "./views/elements/_FormButton.scss";
@import "./views/elements/_IconButton.scss";
@import "./views/elements/_ImageView.scss";
@import "./views/elements/_InlineSpinner.scss";
@import "./views/elements/_InteractiveTooltip.scss";
@ -108,6 +118,7 @@
@import "./views/elements/_Tooltip.scss";
@import "./views/elements/_TooltipButton.scss";
@import "./views/elements/_Validation.scss";
@import "./views/emojipicker/_EmojiPicker.scss";
@import "./views/globals/_MatrixToolbar.scss";
@import "./views/groups/_GroupPublicityToggle.scss";
@import "./views/groups/_GroupRoomList.scss";
@ -122,8 +133,7 @@
@import "./views/messages/_MTextBody.scss";
@import "./views/messages/_MessageActionBar.scss";
@import "./views/messages/_MessageTimestamp.scss";
@import "./views/messages/_ReactionQuickTooltip.scss";
@import "./views/messages/_ReactionTooltipButton.scss";
@import "./views/messages/_MjolnirBody.scss";
@import "./views/messages/_ReactionsRow.scss";
@import "./views/messages/_ReactionsRowButton.scss";
@import "./views/messages/_ReactionsRowButtonTooltip.scss";
@ -132,6 +142,10 @@
@import "./views/messages/_TextualEvent.scss";
@import "./views/messages/_UnknownBody.scss";
@import "./views/messages/_ViewSourceEvent.scss";
@import "./views/messages/_common_CryptoEvent.scss";
@import "./views/right_panel/_EncryptionInfo.scss";
@import "./views/right_panel/_UserInfo.scss";
@import "./views/right_panel/_VerificationPanel.scss";
@import "./views/room_settings/_AliasSettings.scss";
@import "./views/room_settings/_ColorSettings.scss";
@import "./views/rooms/_AppsDrawer.scss";
@ -142,6 +156,7 @@
@import "./views/rooms/_EditMessageComposer.scss";
@import "./views/rooms/_EntityTile.scss";
@import "./views/rooms/_EventTile.scss";
@import "./views/rooms/_InviteOnlyIcon.scss";
@import "./views/rooms/_JumpToBottomButton.scss";
@import "./views/rooms/_LinkPreviewWidget.scss";
@import "./views/rooms/_MemberDeviceInfo.scss";
@ -167,10 +182,13 @@
@import "./views/rooms/_SendMessageComposer.scss";
@import "./views/rooms/_Stickers.scss";
@import "./views/rooms/_TopUnreadMessagesBar.scss";
@import "./views/rooms/_UserOnlineDot.scss";
@import "./views/rooms/_WhoIsTypingTile.scss";
@import "./views/settings/_AvatarSetting.scss";
@import "./views/settings/_CrossSigningPanel.scss";
@import "./views/settings/_DevicesPanel.scss";
@import "./views/settings/_EmailAddresses.scss";
@import "./views/settings/_IntegrationsManager.scss";
@import "./views/settings/_IntegrationManager.scss";
@import "./views/settings/_KeyBackupPanel.scss";
@import "./views/settings/_Notifications.scss";
@import "./views/settings/_PhoneNumbers.scss";
@ -183,6 +201,7 @@
@import "./views/settings/tabs/room/_SecurityRoomSettingsTab.scss";
@import "./views/settings/tabs/user/_GeneralUserSettingsTab.scss";
@import "./views/settings/tabs/user/_HelpUserSettingsTab.scss";
@import "./views/settings/tabs/user/_MjolnirUserSettingsTab.scss";
@import "./views/settings/tabs/user/_NotificationUserSettingsTab.scss";
@import "./views/settings/tabs/user/_PreferencesUserSettingsTab.scss";
@import "./views/settings/tabs/user/_SecurityUserSettingsTab.scss";

View file

@ -14,12 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/* This file has CSS for both native and non-native scrollbars in an
* order that's fairly logic to read but violates stylelints descending
* specificity rule, so turn it off for this file. It also duplicates
* a selector to separate the hiding/showing from the sizing.
/* This file has CSS for both native and non-native scrollbars in an order
* that's fairly logical to read but duplicates a selector to separate the
* hiding/showing from the sizing.
*/
/* stylelint-disable no-descending-specificity, no-duplicate-selectors */
/* stylelint-disable no-duplicate-selectors */
/*
1. for browsers that support native overlay auto-hiding scrollbars

View file

@ -26,11 +26,16 @@ limitations under the License.
.mx_CustomRoomTagPanel_scroller {
max-height: inherit;
display: flex;
flex-direction: column;
align-items: center;
}
.mx_CustomRoomTagPanel .mx_AccessibleButton {
margin: 9px auto;
margin: 0 auto;
width: 40px;
padding: 10px 0 9px 0;
position: relative;
}
.mx_CustomRoomTagPanel .mx_BaseAvatar_image {
@ -39,7 +44,13 @@ limitations under the License.
height: 40px;
}
.mx_CustomRoomTagPanel .mx_AccessibleButton.CustomRoomTagPanel_tileSelected .mx_BaseAvatar_image {
border: 3px solid $warning-color;
border-radius: 40px;
.mx_CustomRoomTagPanel .mx_AccessibleButton.CustomRoomTagPanel_tileSelected::before {
content: '';
height: 56px;
background-color: $accent-color-alt;
width: 5px;
position: absolute;
left: -15px;
border-radius: 0 3px 3px 0;
top: 2px; // 10 [padding-top] - (56 - 40)/2
}

View file

@ -18,6 +18,7 @@ limitations under the License.
order: 2;
flex: 1 1 0;
overflow-y: auto;
display: flex;
}
.mx_FilePanel .mx_RoomView_messageListWrapper {

View file

@ -44,21 +44,29 @@ limitations under the License.
}
.mx_GroupHeader_button {
position: relative;
margin-left: 5px;
margin-right: 5px;
cursor: pointer;
height: 20px;
width: 20px;
background-color: $groupheader-button-color;
mask-repeat: no-repeat;
mask-size: contain;
&::before {
content: '';
position: absolute;
height: 20px;
width: 20px;
background-color: $groupheader-button-color;
mask-repeat: no-repeat;
mask-size: contain;
}
}
.mx_GroupHeader_editButton {
mask-image: url('$(res)/img/icons-settings-room.svg');
.mx_GroupHeader_editButton::before {
mask-image: url('$(res)/img/feather-customised/settings.svg');
}
.mx_GroupHeader_shareButton {
.mx_GroupHeader_shareButton::before {
mask-image: url('$(res)/img/icons-share.svg');
}

View file

@ -18,6 +18,7 @@ limitations under the License.
order: 2;
flex: 1 1 0;
overflow-y: auto;
display: flex;
}
.mx_NotificationPanel .mx_RoomView_messageListWrapper {

View file

@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -18,7 +19,7 @@ limitations under the License.
overflow-x: hidden;
flex: 0 0 auto;
position: relative;
min-width: 250px;
min-width: 264px;
display: flex;
flex-direction: column;
}
@ -50,18 +51,18 @@ limitations under the License.
height: 20px;
width: 20px;
position: relative;
}
.mx_RightPanel_headerButton::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 20px;
background-color: $rightpanel-button-color;
mask-repeat: no-repeat;
mask-size: contain;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 20px;
background-color: $rightpanel-button-color;
mask-repeat: no-repeat;
mask-size: contain;
}
}
.mx_RightPanel_membersButton::before {

View file

@ -119,6 +119,16 @@ limitations under the License.
display: inline-block;
}
.mx_RoomDirectory_perm {
border-radius: 10px;
display: inline-block;
height: 20px;
line-height: 20px;
padding: 0 5px;
color: $accent-fg-color;
background-color: $rte-room-pill-color;
}
.mx_RoomDirectory_topic {
cursor: initial;
color: $light-fg-color;

View file

@ -20,7 +20,7 @@ limitations under the License.
so they ideally wouldn't affect each other.
lowest category: .mx_RoomSubList
flex-shrink: 10000000
distribute size of items within the same categery by their size
distribute size of items within the same category by their size
middle category: .mx_RoomSubList.resized-sized
flex-shrink: 1000
applied when using the resizer, will have a max-height set to it,
@ -46,10 +46,15 @@ limitations under the License.
flex-direction: row;
align-items: center;
flex: 0 0 auto;
margin: 0 16px;
margin: 0 8px;
padding: 0 8px;
height: 36px;
}
.mx_RoomSubList_labelContainer.focus-visible:focus-within {
background-color: $roomtile-focused-bg-color;
}
.mx_RoomSubList_label {
flex: 1;
cursor: pointer;
@ -67,7 +72,7 @@ limitations under the License.
margin-left: 8px;
}
.mx_RoomSubList_badge {
.mx_RoomSubList_badge > div {
flex: 0 0 auto;
border-radius: 8px;
font-weight: 600;
@ -103,7 +108,7 @@ limitations under the License.
}
}
.mx_RoomSubList_badgeHighlight {
.mx_RoomSubList_badgeHighlight > div {
color: $accent-fg-color;
background-color: $warning-color;
}
@ -146,6 +151,7 @@ limitations under the License.
.mx_RoomSubList_labelContainer {
margin-right: 8px;
margin-left: 2px;
padding: 0;
}
.mx_RoomSubList_addRoom {

View file

@ -221,6 +221,9 @@ hr.mx_RoomView_myReadMarker {
position: relative;
top: -1px;
z-index: 1;
transition: width 400ms easeInSine 1s, opacity 400ms easeInSine 1s;
width: 99%;
opacity: 1;
}
.mx_RoomView_callStatusBar .mx_UploadBar_uploadProgressInner {

View file

@ -68,7 +68,7 @@ limitations under the License.
}
.mx_TagPanel .mx_TagPanel_tagTileContainer > div {
height: 40px;
padding: 5px 0 4px 0;
padding: 10px 0 9px 0;
}
.mx_TagPanel .mx_TagTile {
@ -82,21 +82,39 @@ limitations under the License.
// opacity: 1;
}
.mx_TagPanel .mx_TagTile.mx_TagTile_selected .mx_TagTile_avatar .mx_BaseAvatar {
background-color: $accent-color;
border-radius: 40px;
/* In case this is a "initial" avatar */
display: block;
.mx_TagPanel .mx_TagTile_plus {
margin-bottom: 12px;
height: 40px;
width: 40px;
border-radius: 20px;
background-color: $roomheader-addroom-bg-color;
position: relative;
/* overwrite mx_RoleButton inline-block */
display: block !important;
&::before {
background-color: $roomheader-addroom-fg-color;
mask-image: url('$(res)/img/feather-customised/plus.svg');
mask-position: center;
mask-repeat: no-repeat;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
.mx_TagPanel .mx_TagTile_selected .mx_BaseAvatar_image {
border: 3px solid $accent-color;
height: 40px;
width: 40px;
box-sizing: border-box;
.mx_TagPanel .mx_TagTile.mx_TagTile_selected::before {
content: '';
height: 56px;
background-color: $accent-color;
width: 5px;
position: absolute;
left: -15px;
border-radius: 0 3px 3px 0;
top: -8px; // (56 - 40)/2
}
.mx_TagPanel .mx_TagTile.mx_AccessibleButton:focus {

View file

@ -1,56 +0,0 @@
/*
Copyright 2019 New Vector Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_TagPanelButtons {
background-color: $tagpanel-bg-color;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 17px 0 3px 0;
}
.mx_TagPanelButtons > .mx_GroupsButton::before {
mask: url('$(res)/img/feather-customised/users.svg');
mask-position: center 11px;
}
.mx_TagPanelButtons > .mx_TagPanelButtons_report::before {
mask: url('$(res)/img/feather-customised/life-buoy.svg');
mask-position: center 9px;
}
.mx_TagPanelButtons > .mx_AccessibleButton {
margin-bottom: 12px;
height: 40px;
width: 40px;
border-radius: 20px;
background-color: $tagpanel-button-color;
position: relative;
/* overwrite mx_RoleButton inline-block */
display: block !important;
&::before {
background-color: $tagpanel-bg-color;
mask-repeat: no-repeat;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}

View file

@ -0,0 +1,106 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ToastContainer {
position: absolute;
top: 0;
left: 70px;
z-index: 101;
padding: 4px;
display: grid;
grid-template-rows: 1fr 14px 6px;
&.mx_ToastContainer_stacked::before {
content: "";
margin: 0 4px;
grid-row: 2 / 4;
grid-column: 1;
background-color: white;
box-shadow: 0px 4px 12px $menu-box-shadow-color;
border-radius: 8px;
}
.mx_Toast_toast {
grid-row: 1 / 3;
grid-column: 1;
color: $primary-fg-color;
background-color: $primary-bg-color;
box-shadow: 0px 4px 12px $menu-box-shadow-color;
border-radius: 8px;
overflow: hidden;
display: grid;
grid-template-columns: 20px 1fr;
column-gap: 10px;
row-gap: 4px;
padding: 8px;
padding-right: 16px;
&.mx_Toast_hasIcon {
&::after {
content: "";
width: 22px;
height: 22px;
grid-column: 1;
grid-row: 1;
mask-size: 100%;
mask-repeat: no-repeat;
}
&.mx_Toast_icon_verification::after {
mask-image: url("$(res)/img/e2e/normal.svg");
background-color: $primary-fg-color;
}
&.mx_Toast_icon_verification_warning::after {
background-image: url("$(res)/img/e2e/warning.svg");
}
h2, .mx_Toast_body {
grid-column: 2;
}
}
h2 {
grid-column: 1 / 3;
grid-row: 1;
margin: 0;
font-size: 15px;
font-weight: 600;
}
.mx_Toast_body {
grid-column: 1 / 3;
grid-row: 2;
}
.mx_Toast_buttons {
display: flex;
}
.mx_Toast_description {
max-width: 400px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 4px 0 11px 0;
font-size: 12px;
}
.mx_Toast_deviceID {
font-size: 10px;
}
}
}

View file

@ -0,0 +1,51 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_CompleteSecurity_header {
display: flex;
align-items: center;
}
.mx_CompleteSecurity_headerIcon {
width: 24px;
height: 24px;
margin-right: 4px;
position: relative;
}
.mx_CompleteSecurity_heroIcon {
width: 128px;
height: 128px;
position: relative;
margin: 0 auto;
}
.mx_CompleteSecurity_body {
font-size: 15px;
}
.mx_CompleteSecurity_actionRow {
display: flex;
justify-content: flex-end;
.mx_AccessibleButton {
margin-inline-start: 18px;
&.warning {
color: $warning-color;
}
}
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2019 New Vector Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -16,12 +17,12 @@ limitations under the License.
.mx_AuthBody {
width: 500px;
font-size: 12px;
color: $authpage-secondary-color;
background-color: $authpage-body-bg-color;
border-radius: 0 4px 4px 0;
padding: 25px 60px;
box-sizing: border-box;
font-size: 12px;
color: $authpage-secondary-color;
h2 {
font-size: 24px;

View file

@ -0,0 +1,42 @@
/*
Copyright 2019 New Vector Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_CompleteSecurityBody {
width: 600px;
color: $authpage-primary-color;
background-color: $authpage-body-bg-color;
border-radius: 4px;
padding: 20px;
box-sizing: border-box;
h2 {
font-size: 24px;
font-weight: 600;
margin-top: 0;
}
h3 {
font-size: 14px;
font-weight: 600;
}
a:link,
a:hover,
a:visited {
@mixin mx_Dialog_link;
}
}

View file

@ -40,6 +40,7 @@ limitations under the License.
}
.mx_BaseAvatar_image {
object-fit: cover;
border-radius: 40px;
vertical-align: top;
background-color: $avatar-bg-color;

View file

@ -61,5 +61,5 @@ input.mx_StatusMessageContextMenu_message {
}
.mx_StatusMessageContextMenu_actionContainer .mx_Spinner {
justify-content: start;
justify-content: flex-start;
}

View file

@ -49,23 +49,27 @@ limitations under the License.
padding: 0;
list-style: none;
li.mx_TopLeftMenu_icon_home::after {
.mx_TopLeftMenu_icon_home::after {
mask-image: url('$(res)/img/feather-customised/home.svg');
}
li.mx_TopLeftMenu_icon_settings::after {
.mx_TopLeftMenu_icon_help::after {
mask-image: url('$(res)/img/feather-customised/life-buoy.svg');
}
.mx_TopLeftMenu_icon_settings::after {
mask-image: url('$(res)/img/feather-customised/settings.svg');
}
li.mx_TopLeftMenu_icon_signin::after {
.mx_TopLeftMenu_icon_signin::after {
mask-image: url('$(res)/img/feather-customised/sign-in.svg');
}
li.mx_TopLeftMenu_icon_signout::after {
.mx_TopLeftMenu_icon_signout::after {
mask-image: url('$(res)/img/feather-customised/sign-out.svg');
}
li::after {
.mx_AccessibleButton::after {
mask-repeat: no-repeat;
mask-position: 0 center;
mask-size: 16px;
@ -78,14 +82,14 @@ limitations under the License.
background-color: $primary-fg-color;
}
li {
.mx_AccessibleButton {
position: relative;
cursor: pointer;
white-space: nowrap;
padding: 5px 20px 5px 43px;
}
li:hover {
.mx_AccessibleButton:hover {
background-color: $menu-selected-color;
}
}

View file

@ -0,0 +1,36 @@
/*
Copyright 2019 The Matrix.org Foundaction C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_WidgetContextMenu {
padding: 6px;
.mx_WidgetContextMenu_option {
padding: 3px 6px 3px 6px;
cursor: pointer;
white-space: nowrap;
}
.mx_WidgetContextMenu_separator {
margin-top: 0;
margin-bottom: 0;
border-bottom-style: none;
border-left-style: none;
border-right-style: none;
border-top-style: solid;
border-top-width: 1px;
border-color: $menu-border-color;
}
}

View file

@ -30,7 +30,7 @@ limitations under the License.
> div {
display: flex;
align-items: start;
align-items: flex-start;
margin: 5px 0;
input[type=checkbox] {

View file

@ -135,9 +135,6 @@ limitations under the License.
}
}
/* Ordering this block by specificity would require breaking it up into several
chunks, which seems like it would be more confusing to read. */
/* stylelint-disable no-descending-specificity */
.mx_DevTools_tgl-flip {
+ .mx_DevTools_tgl-btn {
padding: 2px;
@ -192,4 +189,37 @@ limitations under the License.
}
}
}
/* stylelint-enable no-descending-specificity */
.mx_DevTools_VerificationRequest {
border: 1px solid #cccccc;
border-radius: 3px;
padding: 1px 5px;
margin-bottom: 6px;
font-family: $monospace-font-family;
dl {
display: grid;
grid-template-columns: max-content auto;
margin: 0;
}
dd {
grid-column-start: 2;
}
dd:empty {
color: #666666;
&::after {
content: "(empty)";
}
}
dt {
font-weight: bold;
grid-column-start: 1;
}
dt::after {
content: ":";
}
}

View file

@ -0,0 +1,228 @@
/*
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_InviteDialog_addressBar {
display: flex;
flex-direction: row;
.mx_InviteDialog_editor {
flex: 1;
width: 100%; // Needed to make the Field inside grow
background-color: $user-tile-hover-bg-color;
border-radius: 4px;
min-height: 25px;
padding-left: 8px;
overflow-x: hidden;
overflow-y: auto;
.mx_InviteDialog_userTile {
display: inline-block;
float: left;
position: relative;
top: 7px;
}
// Using a textarea for this element, to circumvent autofill
// Mostly copied from AddressPickerDialog
textarea,
textarea:focus {
height: 34px;
line-height: 34px;
font-size: 14px;
padding-left: 12px;
margin: 0 !important;
border: 0 !important;
outline: 0 !important;
resize: none;
overflow: hidden;
box-sizing: border-box;
word-wrap: nowrap;
// Roughly fill about 2/5ths of the available space. This is to try and 'fill' the
// remaining space after a bunch of pills, but is a bit hacky. Ideally we'd have
// support for "fill remaining width", but traditional tricks don't work with what
// we're pushing into this "field". Flexbox just makes things worse. The theory is
// that users won't need more than about 2/5ths of the input to find the person
// they're looking for.
width: 40%;
}
}
.mx_InviteDialog_goButton {
min-width: 48px;
margin-left: 10px;
height: 25px;
line-height: 25px;
}
.mx_InviteDialog_buttonAndSpinner {
.mx_Spinner {
// Width and height are required to trick the layout engine.
width: 20px;
height: 20px;
margin-left: 5px;
display: inline-block;
vertical-align: middle;
}
}
}
.mx_InviteDialog_section {
padding-bottom: 10px;
h3 {
font-size: 12px;
color: $muted-fg-color;
font-weight: bold;
text-transform: uppercase;
}
}
.mx_InviteDialog_roomTile {
cursor: pointer;
padding: 5px 10px;
&:hover {
background-color: $user-tile-hover-bg-color;
border-radius: 4px;
}
* {
vertical-align: middle;
}
.mx_InviteDialog_roomTile_avatarStack {
display: inline-block;
position: relative;
width: 36px;
height: 36px;
& > * {
position: absolute;
top: 0;
left: 0;
}
}
.mx_InviteDialog_roomTile_selected {
width: 36px;
height: 36px;
border-radius: 36px;
background-color: $username-variant1-color;
display: inline-block;
position: relative;
&::before {
content: "";
width: 24px;
height: 24px;
grid-column: 1;
grid-row: 1;
mask-image: url("$(res)/img/feather-customised/check.svg");
mask-size: 100%;
mask-repeat: no-repeat;
position: absolute;
top: 6px; // 50%
left: 6px; // 50%
background-color: #ffffff; // this is fine without a var because it's for both themes
}
}
.mx_InviteDialog_roomTile_name {
font-weight: 600;
font-size: 14px;
color: $primary-fg-color;
margin-left: 7px;
}
.mx_InviteDialog_roomTile_userId {
font-size: 12px;
color: $muted-fg-color;
margin-left: 7px;
}
.mx_InviteDialog_roomTile_time {
text-align: right;
font-size: 12px;
color: $muted-fg-color;
float: right;
line-height: 36px; // Height of the avatar to keep the time vertically aligned
}
.mx_InviteDialog_roomTile_highlight {
font-weight: 900;
}
}
// Many of these styles are stolen from mx_UserPill, but adjusted for the invite dialog.
.mx_InviteDialog_userTile {
margin-right: 8px;
.mx_InviteDialog_userTile_pill {
background-color: $username-variant1-color;
border-radius: 12px;
display: inline-block;
height: 24px;
line-height: 24px;
padding-left: 8px;
padding-right: 8px;
color: #ffffff; // this is fine without a var because it's for both themes
.mx_InviteDialog_userTile_avatar {
border-radius: 20px;
position: relative;
left: -5px;
top: 2px;
}
img.mx_InviteDialog_userTile_avatar {
vertical-align: top;
}
.mx_InviteDialog_userTile_name {
vertical-align: top;
}
.mx_InviteDialog_userTile_threepidAvatar {
background-color: #ffffff; // this is fine without a var because it's for both themes
}
}
.mx_InviteDialog_userTile_remove {
display: inline-block;
margin-left: 4px;
}
}
.mx_InviteDialog {
// Prevent the dialog from jumping around randomly when elements change.
height: 590px;
padding-left: 20px; // the design wants some padding on the left
}
.mx_InviteDialog_userSections {
margin-top: 10px;
overflow-y: auto;
padding-right: 45px;
height: 455px; // mx_InviteDialog's height minus some for the upper elements
}
// Right margin for the design. We could apply this to the whole dialog, but then the scrollbar
// for the user section gets weird.
.mx_InviteDialog_helpText,
.mx_InviteDialog_addressBar {
margin-right: 45px;
}

View file

@ -0,0 +1,37 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_NewSessionReviewDialog_header {
display: flex;
align-items: center;
margin-top: 0;
}
.mx_NewSessionReviewDialog_headerIcon {
width: 24px;
height: 24px;
margin-right: 4px;
position: relative;
}
.mx_NewSessionReviewDialog_deviceName {
font-weight: 600;
}
.mx_NewSessionReviewDialog_deviceID {
font-size: 12px;
color: $notice-secondary-color;
}

View file

@ -29,6 +29,11 @@ limitations under the License.
mask-image: url('$(res)/img/feather-customised/users-sm.svg');
}
.mx_RoomSettingsDialog_bridgesIcon::before {
// This icon is pants, please improve :)
mask-image: url('$(res)/img/feather-customised/bridge.svg');
}
.mx_RoomSettingsDialog_warningIcon::before {
mask-image: url('$(res)/img/feather-customised/warning-triangle.svg');
}
@ -42,3 +47,12 @@ limitations under the License.
padding-left: 40px;
padding-right: 80px;
}
// 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-repeat: no-repeat;
mask-size: 36px;
mask-position: center;
}

View file

@ -0,0 +1,112 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomSettingsDialog_BridgeList {
padding: 0;
.mx_AccessibleButton {
display: inline;
margin: 0;
padding: 0;
}
}
.mx_RoomSettingsDialog_BridgeList li {
list-style-type: none;
padding: 5px;
margin-bottom: 8px;
border-width: 1px 1px;
border-color: $primary-hairline-color;
border-style: solid;
border-radius: 5px;
.column-icon {
float: left;
padding-right: 10px;
* {
border-radius: 5px;
border: 1px solid $input-darker-bg-color;
}
.noProtocolIcon {
width: 48px;
height: 48px;
background: $input-darker-bg-color;
border-radius: 5px;
}
.protocol-icon {
float: left;
margin-right: 5px;
img {
border-radius: 5px;
border-width: 1px 1px;
border-color: $primary-hairline-color;
}
span {
/* Correct letter placement */
left: auto;
}
}
}
.column-data {
display: inline-block;
width: 85%;
> h3 {
margin-top: 0px;
margin-bottom: 0px;
font-size: 16pt;
color: $primary-fg-color;
}
> * {
margin-top: 4px;
margin-bottom: 0;
}
.workspace-channel-details {
color: $primary-fg-color;
font-weight: 600;
.channel {
margin-left: 5px;
}
}
.mx_showMore {
display: block;
text-align: left;
margin-top: 10px;
}
.metadata {
color: $muted-fg-color;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 0;
}
.metadata.visible {
overflow-y: visible;
text-overflow: ellipsis;
white-space: normal;
}
}
}

View file

@ -0,0 +1,37 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RoomUpgradeWarningDialog {
max-width: 38vw;
width: 38vw;
}
.mx_RoomUpgradeWarningDialog .mx_SettingsFlag {
font-weight: 700;
.mx_ToggleSwitch {
display: inline-block;
vertical-align: middle;
margin-left: 8px;
float: right;
}
.mx_SettingsFlag_label {
display: inline-block;
vertical-align: middle;
}
}

View file

@ -16,10 +16,10 @@ limitations under the License.
/*
* To avoid visual glitching of two modals stacking briefly, we customise the
* terms dialog sizing when it will appear for the integrations manager so that
* terms dialog sizing when it will appear for the integration manager so that
* it gets the same basic size as the IM's own modal.
*/
.mx_TermsDialog_forIntegrationsManager .mx_Dialog {
.mx_TermsDialog_forIntegrationManager .mx_Dialog {
width: 60%;
height: 70%;
box-sizing: border-box;

View file

@ -45,6 +45,10 @@ limitations under the License.
mask-image: url('$(res)/img/feather-customised/flag.svg');
}
.mx_UserSettingsDialog_mjolnirIcon::before {
mask-image: url('$(res)/img/feather-customised/face.svg');
}
.mx_UserSettingsDialog_flairIcon::before {
mask-image: url('$(res)/img/feather-customised/flair.svg');
}

View file

@ -32,7 +32,7 @@ limitations under the License.
.mx_CreateKeyBackupDialog_passPhraseContainer {
display: flex;
align-items: start;
align-items: flex-start;
}
.mx_CreateKeyBackupDialog_passPhraseHelp {
@ -85,3 +85,9 @@ limitations under the License.
flex: 1;
white-space: nowrap;
}
.mx_CreateKeyBackupDialog {
details .mx_AccessibleButton {
margin: 1em 0; // emulate paragraph spacing because we can't put this button in a paragraph due to HTML rules
}
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -14,6 +15,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RestoreKeyBackupDialog_keyStatus {
height: 30px;
}
.mx_RestoreKeyBackupDialog_primaryContainer {
/* FIXME: plinth colour in new theme(s). background-color: $accent-color; */
padding: 20px;

View file

@ -0,0 +1,34 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_AccessSecretStorageDialog_keyStatus {
height: 30px;
}
.mx_AccessSecretStorageDialog_primaryContainer {
/* FIXME: plinth colour in new theme(s). background-color: $accent-color; */
padding: 20px;
}
.mx_AccessSecretStorageDialog_passPhraseInput,
.mx_AccessSecretStorageDialog_recoveryKeyInput {
width: 300px;
border: 1px solid $accent-color;
border-radius: 5px;
padding: 10px;
}

View file

@ -0,0 +1,116 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_CreateSecretStorageDialog {
// Why you ask? Because CompleteSecurityBody is 600px so this is the width
// we end up when in there, but when in our own dialog we set our own width
// so need to fix it to something sensible as otherwise we'd end up either
// really wide or really narrow depending on the phase. I bet you wish you
// never asked.
width: 560px;
.mx_SettingsFlag {
display: flex;
}
.mx_SettingsFlag_label {
flex: 1 1 0;
min-width: 0;
font-weight: 600;
}
.mx_ToggleSwitch {
flex: 0 0 auto;
margin-left: 30px;
}
details .mx_AccessibleButton {
margin: 1em 0; // emulate paragraph spacing because we can't put this button in a paragraph due to HTML rules
}
}
.mx_CreateSecretStorageDialog .mx_Dialog_title {
/* TODO: Consider setting this for all dialog titles. */
margin-bottom: 1em;
}
.mx_CreateSecretStorageDialog_primaryContainer {
/* FIXME: plinth colour in new theme(s). background-color: $accent-color; */
padding-top: 20px;
}
.mx_CreateSecretStorageDialog_primaryContainer::after {
content: "";
clear: both;
display: block;
}
.mx_CreateSecretStorageDialog_passPhraseContainer {
display: flex;
align-items: flex-start;
}
.mx_Field.mx_CreateSecretStorageDialog_passPhraseField {
margin-top: 0px;
}
.mx_CreateSecretStorageDialog_passPhraseHelp {
flex: 1;
height: 64px;
margin-left: 20px;
font-size: 80%;
}
.mx_CreateSecretStorageDialog_passPhraseHelp progress {
width: 100%;
}
.mx_CreateSecretStorageDialog_passPhraseMatch {
width: 200px;
margin-left: 20px;
}
.mx_CreateSecretStorageDialog_recoveryKeyHeader {
margin-bottom: 1em;
}
.mx_CreateSecretStorageDialog_recoveryKeyContainer {
display: flex;
}
.mx_CreateSecretStorageDialog_recoveryKey {
width: 262px;
padding: 20px;
color: $info-plinth-fg-color;
background-color: $info-plinth-bg-color;
margin-right: 12px;
}
.mx_CreateSecretStorageDialog_recoveryKeyButtons {
flex: 1;
display: flex;
align-items: center;
}
.mx_CreateSecretStorageDialog_recoveryKeyButtons .mx_AccessibleButton {
margin-right: 10px;
}
.mx_CreateSecretStorageDialog_recoveryKeyButtons button {
flex: 1;
white-space: nowrap;
}

View file

@ -49,6 +49,7 @@ limitations under the License.
color: $primary-fg-color;
background-color: $primary-bg-color;
flex: 1;
min-width: 0;
}
.mx_Field select {
@ -148,9 +149,6 @@ limitations under the License.
color: $greyed-fg-color;
}
/* Ordering this block by specificity would require breaking it up into several
chunks, which seems like it would be more confusing to read. */
/* stylelint-disable no-descending-specificity */
.mx_Field_valid {
&.mx_Field,
&.mx_Field:focus-within {
@ -174,7 +172,6 @@ limitations under the License.
color: $input-invalid-border-color;
}
}
/* stylelint-enable no-descending-specificity */
.mx_Field_tooltip {
margin-top: -12px;

View file

@ -0,0 +1,36 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_FormButton {
line-height: 16px;
padding: 5px 15px;
font-size: 12px;
height: min-content;
&:not(:last-child) {
margin-right: 8px;
}
&.mx_AccessibleButton_kind_primary {
color: $accent-color;
background-color: $accent-bg-color;
}
&.mx_AccessibleButton_kind_danger {
color: $notice-primary-color;
background-color: $notice-primary-bg-color;
}
}

View file

@ -0,0 +1,55 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_IconButton {
width: 32px;
height: 32px;
border-radius: 100%;
background-color: $accent-bg-color;
// don't shrink or grow if in a flex container
flex: 0 0 auto;
&.mx_AccessibleButton_disabled {
background-color: none;
&::before {
background-color: lightgrey;
}
}
&:hover {
opacity: 90%;
}
&::before {
content: "";
display: block;
width: 100%;
height: 100%;
mask-repeat: no-repeat;
mask-position: center;
mask-size: 55%;
background-color: $accent-color;
}
&.mx_IconButton_icon_check::before {
mask-image: url('$(res)/img/feather-customised/check.svg');
}
&.mx_IconButton_icon_edit::before {
mask-image: url('$(res)/img/feather-customised/edit.svg');
}
}

View file

@ -13,6 +13,11 @@
padding-left: 5px;
}
a.mx_Pill {
word-break: break-all;
display: inline;
}
/* More specific to override `.markdown-body a` text-decoration */
.mx_EventTile_content .markdown-body a.mx_Pill {
text-decoration: none;

View file

@ -0,0 +1,229 @@
/*
Copyright 2019 Tulir Asokan <tulir@maunium.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_EmojiPicker {
width: 340px;
height: 450px;
border-radius: 4px;
display: flex;
flex-direction: column;
}
.mx_EmojiPicker_body {
flex: 1;
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
.mx_EmojiPicker_header {
padding: 4px 8px 0;
border-bottom: 1px solid $message-action-bar-border-color;
}
.mx_EmojiPicker_anchor {
border: none;
padding: 8px 8px 6px;
border-bottom: 2px solid transparent;
background-color: transparent;
border-radius: 4px 4px 0 0;
width: 36px;
height: 38px;
&:not(:disabled) {
cursor: pointer;
}
&:not(:disabled):hover {
background-color: $focus-bg-color;
border-bottom: 2px solid $button-bg-color;
}
}
.mx_EmojiPicker_anchor::before {
background-color: $primary-fg-color;
content: '';
display: inline-block;
mask-size: 100%;
mask-repeat: no-repeat;
width: 100%;
height: 100%;
}
.mx_EmojiPicker_anchor:disabled::before {
background-color: $focus-bg-color;
}
.mx_EmojiPicker_anchor_activity::before { mask-image: url('$(res)/img/emojipicker/activity.svg'); }
.mx_EmojiPicker_anchor_custom::before { mask-image: url('$(res)/img/emojipicker/custom.svg'); }
.mx_EmojiPicker_anchor_flags::before { mask-image: url('$(res)/img/emojipicker/flags.svg'); }
.mx_EmojiPicker_anchor_foods::before { mask-image: url('$(res)/img/emojipicker/foods.svg'); }
.mx_EmojiPicker_anchor_nature::before { mask-image: url('$(res)/img/emojipicker/nature.svg'); }
.mx_EmojiPicker_anchor_objects::before { mask-image: url('$(res)/img/emojipicker/objects.svg'); }
.mx_EmojiPicker_anchor_people::before { mask-image: url('$(res)/img/emojipicker/people.svg'); }
.mx_EmojiPicker_anchor_places::before { mask-image: url('$(res)/img/emojipicker/places.svg'); }
.mx_EmojiPicker_anchor_recent::before { mask-image: url('$(res)/img/emojipicker/recent.svg'); }
.mx_EmojiPicker_anchor_symbols::before { mask-image: url('$(res)/img/emojipicker/symbols.svg'); }
.mx_EmojiPicker_anchor_visible {
border-bottom: 2px solid $button-bg-color;
}
.mx_EmojiPicker_search {
margin: 8px;
border-radius: 4px;
border: 1px solid $input-border-color;
background-color: $primary-bg-color;
display: flex;
input {
flex: 1;
border: none;
padding: 8px 12px;
border-radius: 4px 0;
}
button {
border: none;
background-color: inherit;
margin: 0;
padding: 8px;
align-self: center;
width: 32px;
height: 32px;
}
}
.mx_EmojiPicker_search_clear {
cursor: pointer;
}
.mx_EmojiPicker_search_icon {
width: 16px;
margin: 8px;
}
.mx_EmojiPicker_search_icon:not(.mx_EmojiPicker_search_clear) {
pointer-events: none;
}
.mx_EmojiPicker_search_icon::after {
mask: url('$(res)/img/emojipicker/search.svg') no-repeat;
mask-size: 100%;
background-color: $primary-fg-color;
content: '';
display: inline-block;
width: 100%;
height: 100%;
}
.mx_EmojiPicker_search_clear::after {
mask-image: url('$(res)/img/emojipicker/delete.svg');
}
.mx_EmojiPicker_category {
padding: 0 12px;
display: flex;
flex-direction: column;
align-items: center;
}
.mx_EmojiPicker_category_label {
width: 304px;
}
.mx_EmojiPicker_list {
width: 304px;
padding: 0;
margin: 0;
}
.mx_EmojiPicker_item_wrapper {
display: inline-block;
list-style: none;
width: 38px;
cursor: pointer;
}
.mx_EmojiPicker_item {
display: inline-block;
font-size: 20px;
padding: 5px;
width: 100%;
height: 100%;
box-sizing: border-box;
text-align: center;
border-radius: 4px;
&:hover {
background-color: $focus-bg-color;
}
}
.mx_EmojiPicker_item_selected {
color: rgba(0, 0, 0, .5);
border: 1px solid $input-valid-border-color;
padding: 4px;
}
.mx_EmojiPicker_category_label, .mx_EmojiPicker_preview_name {
font-size: 16px;
font-weight: 600;
margin: 0;
}
.mx_EmojiPicker_footer {
border-top: 1px solid $message-action-bar-border-color;
height: 72px;
display: flex;
align-items: center;
}
.mx_EmojiPicker_preview_emoji {
font-size: 32px;
padding: 8px 16px;
}
.mx_EmojiPicker_preview_text {
display: flex;
flex-direction: column;
}
.mx_EmojiPicker_name {
text-transform: capitalize;
}
.mx_EmojiPicker_shortcode {
color: $light-fg-color;
font-size: 14px;
&::before, &::after {
content: ":";
}
}
.mx_EmojiPicker_quick {
flex-direction: column;
justify-content: space-around;
}
.mx_EmojiPicker_quick_header .mx_EmojiPicker_name {
margin-right: 4px;
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_RestoreKeyBackupDialog_keyStatus {
height: 30px;
.mx_MjolnirBody {
opacity: 0.4;
}

View file

@ -0,0 +1,79 @@
/*
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_cryptoEvent {
display: grid;
grid-template-columns: 24px minmax(0, 1fr) min-content;
&.mx_cryptoEvent_icon::after {
grid-column: 1;
grid-row: 1 / 3;
width: 16px;
height: 16px;
content: "";
background-image: url("$(res)/img/e2e/normal.svg");
background-repeat: no-repeat;
background-size: 100%;
margin-top: 4px;
}
&.mx_cryptoEvent_icon_verified::after {
background-image: url("$(res)/img/e2e/verified.svg");
}
&.mx_cryptoEvent_icon_warning::after {
background-image: url("$(res)/img/e2e/warning.svg");
}
.mx_cryptoEvent_title, .mx_cryptoEvent_subtitle, .mx_cryptoEvent_state {
overflow-wrap: break-word;
}
.mx_cryptoEvent_title {
font-weight: 600;
font-size: 15px;
grid-column: 2;
grid-row: 1;
}
.mx_cryptoEvent_subtitle {
grid-column: 2;
grid-row: 2;
}
.mx_cryptoEvent_state, .mx_cryptoEvent_subtitle {
font-size: 12px;
}
.mx_cryptoEvent_state, .mx_cryptoEvent_buttons {
grid-column: 3;
grid-row: 1 / 3;
}
.mx_cryptoEvent_buttons {
align-items: center;
display: flex;
}
.mx_cryptoEvent_state {
width: 130px;
padding: 10px 20px;
margin: auto 0;
text-align: center;
color: $notice-secondary-color;
}
}

View file

@ -0,0 +1,26 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserInfo {
.mx_EncryptionInfo_spinner {
.mx_Spinner {
margin-top: 25px;
margin-bottom: 15px;
}
text-align: center;
}
}

View file

@ -0,0 +1,287 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserInfo {
display: flex;
flex-direction: column;
flex: 1;
overflow-y: auto;
font-size: 12px;
.mx_UserInfo_cancel {
cursor: pointer;
position: absolute;
top: 0;
border-radius: 4px;
background-color: $dark-panel-bg-color;
margin: 9px;
z-index: 1; // render on top of the right panel
div {
height: 16px;
width: 16px;
padding: 4px;
mask-image: url('$(res)/img/minimise.svg');
mask-repeat: no-repeat;
mask-position: 7px center;
background-color: $rightpanel-button-color;
}
}
h2 {
font-size: 18px;
font-weight: 600;
margin: 18px 0 0 0;
}
.mx_UserInfo_container {
padding: 8px 16px;
}
.mx_UserInfo_separator {
border-bottom: 1px solid lightgray;
}
.mx_UserInfo_memberDetailsContainer {
padding-top: 0;
padding-bottom: 0;
margin-bottom: 8px;
}
.mx_RoomTile_nameContainer {
width: 154px;
}
.mx_RoomTile_badge {
display: none;
}
.mx_RoomTile_name {
width: 160px;
}
.mx_UserInfo_avatar {
margin: 24px 32px 0 32px;
}
.mx_UserInfo_avatar > div {
max-width: 30vh;
margin: 0 auto;
transition: 0.5s;
}
.mx_UserInfo_avatar > div > div {
/* use padding-top instead of height to make this element square,
as the % in padding is a % of the width (including margin,
that's why we had to put the margin to center on a parent div),
and not a % of the parent height. */
padding-top: 100%;
position: relative;
}
.mx_UserInfo_avatar > div > div * {
border-radius: 100%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.mx_UserInfo_avatar .mx_BaseAvatar_initial {
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
// override the calculated sizes so that the letter isn't HUGE
font-size: 56px !important;
width: 100% !important;
transition: font-size 0.5s;
}
.mx_UserInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image {
cursor: zoom-in;
}
h3 {
text-transform: uppercase;
color: $notice-secondary-color;
font-weight: bold;
font-size: 12px;
margin: 4px 0;
}
p {
margin: 5px 0;
}
.mx_UserInfo_profile {
text-align: center;
h2 {
font-size: 18px;
line-height: 25px;
flex: 1;
justify-content: center;
align-items: center;
// limit to 2 lines, show an ellipsis if it overflows
// this looks webkit specific but is supported by Firefox 68+
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-all;
text-overflow: ellipsis;
.mx_E2EIcon {
margin: 5px;
}
}
.mx_UserInfo_profileStatus {
margin-top: 12px;
}
}
.mx_UserInfo_memberDetails .mx_UserInfo_profileField {
display: flex;
justify-content: center;
align-items: center;
margin: 6px 0;
.mx_IconButton, .mx_Spinner {
margin-left: 20px;
width: 16px;
height: 16px;
&::before {
mask-size: 80%;
}
}
.mx_UserInfo_roleDescription {
display: flex;
justify-content: center;
align-items: center;
// try to make it the same height as the dropdown
margin: 11px 0 12px 0;
.mx_IconButton {
margin-left: 6px;
}
}
.mx_Field {
margin: 0;
}
}
.mx_UserInfo_field {
cursor: pointer;
color: $accent-color;
line-height: 16px;
margin: 8px 0;
&.mx_UserInfo_destructive {
color: $warning-color;
}
}
.mx_UserInfo_statusMessage {
font-size: 11px;
opacity: 0.5;
overflow: hidden;
white-space: nowrap;
text-overflow: clip;
}
.mx_UserInfo_scrollContainer {
flex: 1 1 0;
padding-bottom: 16px;
}
.mx_UserInfo_container:not(.mx_UserInfo_separator) {
padding-top: 16px;
padding-bottom: 0;
> :not(h3) {
margin-left: 8px;
}
}
.mx_UserInfo_devices {
.mx_UserInfo_device {
display: flex;
margin: 8px 0;
&.mx_UserInfo_device_verified {
.mx_UserInfo_device_trusted {
color: $accent-color;
}
}
&.mx_UserInfo_device_unverified {
.mx_UserInfo_device_trusted {
color: $warning-color;
}
}
.mx_UserInfo_device_name {
flex: 1;
margin-right: 5px;
word-break: break-word;
}
}
// both for icon in expand button and device item
.mx_E2EIcon {
// don't squeeze
flex: 0 0 auto;
margin: 2px 5px 0 0;
width: 12px;
height: 12px;
}
.mx_UserInfo_expand {
display: flex;
margin-top: 11px;
}
}
.mx_UserInfo_wideButton {
display: block;
margin: 16px 0;
}
button.mx_UserInfo_wideButton {
width: 100%; // FIXME get rid of this once we get rid of DialogButtons here
}
}
.mx_UserInfo.mx_UserInfo_smallAvatar {
.mx_UserInfo_avatar > div {
max-width: 72px;
margin: 0 auto;
}
.mx_UserInfo_avatar .mx_BaseAvatar_initial {
font-size: 40px !important; // override the other override because here the avatar is smaller
}
}

View file

@ -0,0 +1,106 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserInfo {
.mx_VerificationPanel_verified_section .mx_E2EIcon {
// Override general user info margin
margin: 0 auto !important;
}
.mx_VerificationPanel_qrCode {
padding: 4px 4px 0 4px;
background: white;
border-radius: 4px;
width: max-content;
max-width: 100%;
// Override general user info margin
margin: 0 auto !important;
canvas {
// override height and width which are set on the element directly
height: auto !important;
width: 100% !important;
max-width: 240px;
}
}
}
// Special case styling for EncryptionPanel in a Modal dialog
.mx_Dialog, .mx_CompleteSecurity_body {
.mx_VerificationPanel_QRPhase_startOptions {
display: flex;
margin-top: 10px;
margin-bottom: 10px;
align-items: stretch;
> .mx_VerificationPanel_QRPhase_betweenText {
width: 50px;
vertical-align: middle;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.mx_VerificationPanel_QRPhase_startOption {
background-color: $user-tile-hover-bg-color;
border-radius: 10px;
flex: 1;
display: flex;
padding: 10px;
align-items: center;
flex-direction: column;
position: relative;
canvas, .mx_VerificationPanel_QRPhase_noQR {
width: 220px !important;
height: 220px !important;
background-color: #fff;
border-radius: 4px;
vertical-align: middle;
text-align: center;
padding: 10px;
}
> p {
font-weight: 700;
}
.mx_VerificationPanel_QRPhase_helpText {
font-size: 14px;
margin-top: 71px;
text-align: center;
}
.mx_AccessibleButton {
position: absolute;
bottom: 30px;
}
}
}
// EncryptionPanel when verification is done
.mx_VerificationPanel_verified_section {
// center the big shield icon
.mx_E2EIcon {
margin: 0 auto;
}
// right align the "Got it" button
.mx_AccessibleButton {
float: right;
}
}
}

View file

@ -153,40 +153,12 @@ $AppsDrawerBodyHeight: 273px;
background-color: $accent-color;
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_reload {
mask-image: url('$(res)/img/feather-customised/widget/refresh.svg');
mask-size: 100%;
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_popout {
mask-image: url('$(res)/img/feather-customised/widget/external-link.svg');
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_snapshot {
mask-image: url('$(res)/img/feather-customised/widget/camera.svg');
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_edit {
mask-image: url('$(res)/img/feather-customised/widget/edit.svg');
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_delete {
mask-image: url('$(res)/img/feather-customised/widget/bin.svg');
background-color: $warning-color;
}
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_cancel {
mask-image: url('$(res)/img/feather-customised/widget/x-circle.svg');
}
/* delete ? */
.mx_AppTileMenuBarWidget {
cursor: pointer;
width: 10px;
height: 10px;
padding: 1px;
transition-duration: 500ms;
border: 1px solid transparent;
.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_menu {
mask-image: url('$(res)/img/icon_context.svg');
}
.mx_AppTileMenuBarWidgetDelete {
@ -294,49 +266,61 @@ form.mx_Custom_Widget_Form div {
.mx_AppPermissionWarning {
text-align: center;
background-color: $primary-bg-color;
background-color: $widget-menu-bar-bg-color;
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 16px;
}
.mx_AppPermissionWarningImage {
margin: 10px 0;
.mx_AppPermissionWarning_row {
margin-bottom: 12px;
}
.mx_AppPermissionWarningImage img {
width: 100px;
.mx_AppPermissionWarning_smallText {
font-size: 12px;
}
.mx_AppPermissionWarningText {
max-width: 90%;
margin: 10px auto 10px auto;
color: $primary-fg-color;
.mx_AppPermissionWarning_bolder {
font-weight: 600;
}
.mx_AppPermissionWarningTextLabel {
font-weight: bold;
display: block;
.mx_AppPermissionWarning h4 {
margin: 0;
padding: 0;
}
.mx_AppPermissionWarningTextURL {
.mx_AppPermissionWarning_helpIcon {
margin-top: 1px;
margin-right: 2px;
width: 10px;
height: 10px;
display: inline-block;
max-width: 100%;
color: $accent-color;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mx_AppPermissionButton {
border: none;
padding: 5px 20px;
border-radius: 5px;
background-color: $button-bg-color;
color: $button-fg-color;
cursor: pointer;
.mx_AppPermissionWarning_helpIcon::before {
display: inline-block;
background-color: $accent-color;
mask-repeat: no-repeat;
mask-size: 12px;
width: 12px;
height: 12px;
mask-position: center;
content: '';
vertical-align: middle;
mask-image: url('$(res)/img/feather-customised/help-circle.svg');
}
.mx_AppPermissionWarning_tooltip {
@mixin mx_Tooltip_dark;
ul {
list-style-position: inside;
padding-left: 2px;
margin-left: 0;
}
}
.mx_AppLoading {

View file

@ -15,19 +15,35 @@ limitations under the License.
*/
.mx_E2EIcon {
width: 25px;
height: 25px;
mask-repeat: no-repeat;
mask-position: center 0;
width: 16px;
height: 16px;
margin: 0 9px;
position: relative;
display: block;
}
.mx_E2EIcon_verified {
mask-image: url('$(res)/img/e2e/lock-verified.svg');
background-color: $accent-color;
.mx_E2EIcon_warning::after,
.mx_E2EIcon_normal::after,
.mx_E2EIcon_verified::after {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-repeat: no-repeat;
background-size: contain;
}
.mx_E2EIcon_warning {
mask-image: url('$(res)/img/e2e/lock-warning.svg');
background-color: $warning-color;
.mx_E2EIcon_warning::after {
background-image: url('$(res)/img/e2e/warning.svg');
}
.mx_E2EIcon_normal::after {
background-image: url('$(res)/img/e2e/normal.svg');
}
.mx_E2EIcon_verified::after {
background-image: url('$(res)/img/e2e/verified.svg');
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -19,6 +20,15 @@ limitations under the License.
align-items: center;
color: $primary-fg-color;
cursor: pointer;
.mx_E2EIcon {
margin: 0;
position: absolute;
bottom: 2px;
right: 7px;
height: 15px;
width: 15px;
}
}
.mx_EntityTile:hover {
@ -30,7 +40,7 @@ limitations under the License.
content: "";
position: absolute;
top: calc(50% - 8px); // center
right: 10px;
right: -8px;
mask: url('$(res)/img/member_chevron.png');
mask-repeat: no-repeat;
width: 16px;
@ -64,14 +74,6 @@ limitations under the License.
position: relative;
}
.mx_EntityTile_power {
position: absolute;
width: 16px;
height: 17px;
top: 0px;
right: 6px;
}
.mx_EntityTile_name,
.mx_GroupRoomTile_name {
flex: 1 1 0;
@ -83,6 +85,7 @@ limitations under the License.
.mx_EntityTile_details {
overflow: hidden;
flex: 1;
}
.mx_EntityTile_ellipsis .mx_EntityTile_name {
@ -112,10 +115,6 @@ limitations under the License.
opacity: 0.25;
}
.mx_EntityTile:not(.mx_EntityTile_noHover):hover .mx_EntityTile_name {
font-size: 13px;
}
.mx_EntityTile_subtext {
font-size: 11px;
opacity: 0.5;
@ -123,3 +122,17 @@ limitations under the License.
white-space: nowrap;
text-overflow: clip;
}
.mx_EntityTile_power {
padding-inline-start: 6px;
font-size: 10px;
color: $notice-secondary-color;
max-width: 6em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mx_EntityTile:hover .mx_EntityTile_power {
display: none;
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -22,6 +23,15 @@ limitations under the License.
position: relative;
}
.mx_EventTile_bubble {
background-color: $dark-panel-bg-color;
padding: 10px;
border-radius: 5px;
margin: 10px auto;
max-width: 75%;
box-sizing: border-box;
}
.mx_EventTile.mx_EventTile_info {
padding-top: 0px;
}
@ -112,6 +122,21 @@ limitations under the License.
line-height: 22px;
}
.mx_EventTile_bubbleContainer {
display: grid;
grid-template-columns: 1fr 100px;
.mx_EventTile_line {
margin-right: 0px;
grid-column: 1 / 3;
padding: 0;
}
.mx_EventTile_msgOption {
grid-column: 2;
}
}
.mx_EventTile_reply {
margin-right: 10px;
}
@ -138,12 +163,15 @@ limitations under the License.
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.mx_EventTile_last > div > a > .mx_MessageTimestamp,
.mx_EventTile:hover > div > a > .mx_MessageTimestamp,
.mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp {
.mx_EventTile.mx_EventTile_actionBarFocused > div > a > .mx_MessageTimestamp,
.mx_EventTile.focus-visible:focus-within > div > a > .mx_MessageTimestamp {
visibility: visible;
}
.mx_EventTile:hover .mx_MessageActionBar,
.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar {
.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar,
[data-whatinput='keyboard'] .mx_EventTile:focus-within .mx_MessageActionBar,
.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar {
visibility: visible;
}
@ -165,8 +193,13 @@ limitations under the License.
}
}
.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line {
padding-left: 78px;
}
.mx_EventTile:hover .mx_EventTile_line,
.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line {
.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line,
.mx_EventTile.focus-visible:focus-within .mx_EventTile_line {
background-color: $event-selected-color;
}
@ -316,27 +349,32 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
}
.mx_EventTile_e2eIcon {
display: block;
position: absolute;
top: 8px;
top: 6px;
left: 46px;
width: 15px;
height: 15px;
cursor: pointer;
mask-size: 14px;
mask-repeat: no-repeat;
mask-position: 0;
display: block;
bottom: 0;
right: 0;
opacity: 0.2;
background-repeat: no-repeat;
background-size: contain;
}
.mx_EventTile_e2eIcon_undecryptable, .mx_EventTile_e2eIcon_unverified {
mask-image: url('$(res)/img/e2e/warning.svg');
background-color: $warning-color;
background-image: url('$(res)/img/e2e/warning.svg');
opacity: 1;
}
.mx_EventTile_e2eIcon_unknown {
background-image: url('$(res)/img/e2e/warning.svg');
opacity: 1;
}
.mx_EventTile_e2eIcon_unencrypted {
mask-image: url('$(res)/img/e2e/warning.svg');
background-color: $composer-e2e-icon-color;
background-image: url('$(res)/img/e2e/warning.svg');
opacity: 1;
}
.mx_EventTile_e2eIcon_hidden {
@ -381,12 +419,9 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
padding-left: 5px;
}
.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line {
padding-left: 78px;
}
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line {
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line,
.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line {
padding-left: 60px;
}
@ -398,8 +433,13 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
border-left: $e2e-unverified-color 5px solid;
}
.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line {
border-left: $e2e-unknown-color 5px solid;
}
.mx_EventTile:hover.mx_EventTile_verified.mx_EventTile_info .mx_EventTile_line,
.mx_EventTile:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line {
.mx_EventTile:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line,
.mx_EventTile:hover.mx_EventTile_unknown.mx_EventTile_info .mx_EventTile_line {
padding-left: 78px;
}
@ -410,14 +450,16 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp {
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp,
.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line > a > .mx_MessageTimestamp {
left: 3px;
width: auto;
}
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon {
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon,
.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line > .mx_EventTile_e2eIcon {
display: block;
left: 41px;
}
@ -465,7 +507,8 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
}
}
.mx_EventTile:hover .mx_EventTile_body pre {
.mx_EventTile:hover .mx_EventTile_body pre,
.mx_EventTile.focus-visible:focus-within .mx_EventTile_body pre {
border: 1px solid #e5e5e5; // deliberate constant as we're behind an invert filter
}
@ -487,6 +530,7 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
background-image: url($copy-button-url);
}
.mx_EventTile_body .mx_EventTile_pre_container:focus-within .mx_EventTile_copyButton,
.mx_EventTile_body .mx_EventTile_pre_container:hover .mx_EventTile_copyButton {
visibility: visible;
}
@ -532,9 +576,6 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
/* end of overrides */
/* Ordering this block by specificity would require breaking it up into several
chunks, which seems like it would be more confusing to read. */
/* stylelint-disable no-descending-specificity */
.mx_MatrixChat_useCompactLayout {
.mx_EventTile {
padding-top: 4px;
@ -612,4 +653,3 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
}
}
}
/* stylelint-enable no-descending-specificity */

View file

@ -0,0 +1,58 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
@define-mixin mx_InviteOnlyIcon {
width: 12px;
height: 12px;
position: relative;
display: block !important;
}
@define-mixin mx_InviteOnlyIcon_padlock {
background-color: $roomtile-name-color;
mask-image: url("$(res)/img/feather-customised/lock-solid.svg");
mask-position: center;
mask-repeat: no-repeat;
mask-size: contain;
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.mx_InviteOnlyIcon_large {
@mixin mx_InviteOnlyIcon;
margin: 0 4px;
&::before {
@mixin mx_InviteOnlyIcon_padlock;
width: 12px;
height: 12px;
}
}
.mx_InviteOnlyIcon_small {
@mixin mx_InviteOnlyIcon;
left: -2px;
&::before {
@mixin mx_InviteOnlyIcon_padlock;
width: 10px;
height: 10px;
}
}

View file

@ -52,12 +52,18 @@ limitations under the License.
}
.mx_LinkPreviewWidget_cancel {
visibility: hidden;
cursor: pointer;
flex: 0 0 40px;
width: 18px;
height: 18px;
img {
flex: 0 0 40px;
visibility: hidden;
}
}
.mx_LinkPreviewWidget:hover .mx_LinkPreviewWidget_cancel {
.mx_LinkPreviewWidget:hover .mx_LinkPreviewWidget_cancel img,
.mx_LinkPreviewWidget_cancel.focus-visible:focus img {
visibility: visible;
}

View file

@ -17,7 +17,7 @@ limitations under the License.
.mx_MemberDeviceInfo {
display: flex;
padding-bottom: 10px;
align-items: start;
align-items: flex-start;
}
.mx_MemberDeviceInfo_icon {
@ -25,6 +25,7 @@ limitations under the License.
width: 12px;
height: 12px;
mask-repeat: no-repeat;
mask-size: 100%;
}
.mx_MemberDeviceInfo_icon_blacklisted {
mask-image: url('$(res)/img/e2e/blacklisted.svg');

View file

@ -23,10 +23,6 @@ limitations under the License.
padding-left: 84px;
}
.mx_MessageComposer_wrapper.mx_MessageComposer_hasE2EIcon {
padding-left: 109px;
}
.mx_MessageComposer_replaced_wrapper {
margin-left: auto;
margin-right: auto;
@ -78,7 +74,10 @@ limitations under the License.
.mx_MessageComposer_e2eIcon.mx_E2EIcon {
position: absolute;
left: 60px;
background-color: $composer-e2e-icon-color;
margin-right: 0; // Counteract the E2EIcon class
margin-left: 3px; // Counteract the E2EIcon class
width: 15px;
height: 15px;
}
.mx_MessageComposer_noperm_error {
@ -104,7 +103,7 @@ limitations under the License.
display: flex;
flex-direction: column;
min-height: 60px;
justify-content: start;
justify-content: flex-start;
align-items: flex-start;
font-size: 14px;
margin-right: 6px;
@ -180,34 +179,42 @@ limitations under the License.
}
.mx_MessageComposer_button {
position: relative;
margin-right: 12px;
cursor: pointer;
padding-top: 4px;
height: 20px;
width: 20px;
background-color: $composer-button-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
&::before {
content: '';
position: absolute;
height: 20px;
width: 20px;
background-color: $composer-button-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
}
}
.mx_MessageComposer_upload {
.mx_MessageComposer_upload::before {
mask-image: url('$(res)/img/feather-customised/paperclip.svg');
}
.mx_MessageComposer_hangup {
.mx_MessageComposer_hangup::before {
mask-image: url('$(res)/img/hangup.svg');
}
.mx_MessageComposer_voicecall {
.mx_MessageComposer_voicecall::before {
mask-image: url('$(res)/img/feather-customised/phone.svg');
}
.mx_MessageComposer_videocall {
.mx_MessageComposer_videocall::before {
mask-image: url('$(res)/img/feather-customised/video.svg');
}
.mx_MessageComposer_stickers {
.mx_MessageComposer_stickers::before {
mask-image: url('$(res)/img/feather-customised/face.svg');
}

View file

@ -40,6 +40,19 @@ limitations under the License.
&:hover {
border-color: $message-action-bar-hover-border-color;
z-index: 1;
}
&:first-child {
border-radius: 3px 0 0 3px;
}
&:last-child {
border-radius: 0 3px 3px 0;
}
&:only-child {
border-radius: 3px;
}
}

View file

@ -17,6 +17,15 @@ limitations under the License.
.mx_RoomHeader {
flex: 0 0 52px;
border-bottom: 1px solid $primary-hairline-color;
.mx_E2EIcon {
margin: 0;
position: absolute;
bottom: -2px;
right: -6px;
height: 15px;
width: 15px;
}
}
.mx_RoomHeader_wrapper {
@ -167,6 +176,7 @@ limitations under the License.
width: 28px;
height: 28px;
margin: 0 7px;
position: relative;
}
.mx_RoomHeader_avatar .mx_BaseAvatar_image {
@ -192,33 +202,41 @@ limitations under the License.
}
.mx_RoomHeader_button {
position: relative;
margin-left: 10px;
cursor: pointer;
height: 20px;
width: 20px;
background-color: $roomheader-button-color;
mask-repeat: no-repeat;
mask-size: contain;
&::before {
content: '';
position: absolute;
height: 20px;
width: 20px;
background-color: $roomheader-button-color;
mask-repeat: no-repeat;
mask-size: contain;
}
}
.mx_RoomHeader_settingsButton {
.mx_RoomHeader_settingsButton::before {
mask-image: url('$(res)/img/feather-customised/settings.svg');
}
.mx_RoomHeader_forgetButton {
.mx_RoomHeader_forgetButton::before {
mask-image: url('$(res)/img/leave.svg');
width: 26px;
}
.mx_RoomHeader_searchButton {
.mx_RoomHeader_searchButton::before {
mask-image: url('$(res)/img/feather-customised/search.svg');
}
.mx_RoomHeader_shareButton {
.mx_RoomHeader_shareButton::before {
mask-image: url('$(res)/img/feather-customised/share.svg');
}
.mx_RoomHeader_manageIntegsButton {
.mx_RoomHeader_manageIntegsButton::before {
mask-image: url('$(res)/img/feather-customised/grid.svg');
}
@ -234,8 +252,7 @@ limitations under the License.
margin-top: 18px;
}
.mx_RoomHeader_pinnedButton {
position: relative;
.mx_RoomHeader_pinnedButton::before {
mask-image: url('$(res)/img/icons-pin.svg');
}

View file

@ -117,12 +117,17 @@ limitations under the License.
.mx_RoomPreviewBar_actions {
flex-direction: column-reverse;
.mx_AccessibleButton {
padding: 7px 50px;//extra wide
padding: 7px 50px; //extra wide
}
& > * {
margin-top: 12px;
}
.mx_AccessibleButton.mx_AccessibleButton_kind_primary {
// to account for the padding of the primary button which causes inconsistent look between
// subsequent secondary (text) buttons
margin-bottom: 7px;
}
}
}

View file

@ -40,4 +40,5 @@ limitations under the License.
.mx_RoomRecoveryReminder_secondary {
font-size: 90%;
margin-top: 1em;
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -97,9 +98,22 @@ limitations under the License.
z-index: 2;
}
// Note we match .mx_E2EIcon to make sure this matches more tightly than just
// .mx_E2EIcon on its own
.mx_RoomTile_e2eIcon.mx_E2EIcon {
height: 14px;
width: 14px;
display: block;
position: absolute;
bottom: -2px;
right: -5px;
z-index: 1;
margin: 0;
}
.mx_RoomTile_name {
font-size: 14px;
padding: 0 6px;
padding: 0 4px;
color: $roomtile-name-color;
white-space: nowrap;
overflow-x: hidden;
@ -141,8 +155,11 @@ limitations under the License.
}
}
// toggle menuButton and badge on hover/menu displayed
// toggle menuButton and badge on menu displayed
.mx_RoomTile_menuDisplayed,
// or on keyboard focus of room tile
.mx_LeftPanel_container:not(.collapsed) .mx_RoomTile:focus-within,
// or on pointer hover
.mx_LeftPanel_container:not(.collapsed) .mx_RoomTile:hover {
.mx_RoomTile_menuButton {
display: block;

View file

@ -37,6 +37,10 @@ limitations under the License.
mask-position: center;
}
.mx_SearchBar_buttons {
display: inherit;
}
.mx_SearchBar_button {
border: 0;
margin: 0 0 0 22px;

View file

@ -25,19 +25,16 @@ limitations under the License.
}
.mx_TopUnreadMessagesBar::after {
content: "·";
content: "";
position: absolute;
top: -8px;
left: 11px;
width: 16px;
height: 16px;
width: 4px;
height: 4px;
border-radius: 16px;
font-weight: 600;
font-size: 30px;
line-height: 14px;
text-align: center;
color: $secondary-accent-color;
background-color: $accent-color;
background-color: $secondary-accent-color;
border: 6px solid $accent-color;
pointer-events: none;
}
.mx_TopUnreadMessagesBar_scrollUp {

View file

@ -0,0 +1,23 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_UserOnlineDot {
border-radius: 50%;
background-color: $accent-color;
height: 5px;
width: 5px;
display: inline-block;
}

View file

@ -31,14 +31,15 @@ limitations under the License.
margin-left: -12px;
}
.mx_WhoIsTypingTile_avatars .mx_BaseAvatar_image {
border: 1px solid $primary-bg-color;
}
.mx_WhoIsTypingTile_avatars .mx_BaseAvatar_initial {
padding-top: 1px;
}
.mx_WhoIsTypingTile_avatars .mx_BaseAvatar {
border: 1px solid $primary-bg-color;
border-radius: 40px;
}
.mx_WhoIsTypingTile_remainingAvatarPlaceholder {
position: relative;
display: inline-block;

View file

@ -0,0 +1,87 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_AvatarSetting_avatar {
width: 88px;
height: 88px;
margin-left: 13px;
position: relative;
& > * {
width: 88px;
box-sizing: border-box;
}
.mx_AccessibleButton.mx_AccessibleButton_kind_primary {
margin-top: 8px;
div {
position: relative;
height: 12px;
width: 12px;
display: inline;
padding-right: 6px; // 0.5 * 12px
left: -6px; // 0.5 * 12px
top: 3px;
}
div::before {
content: '';
position: absolute;
height: 12px;
width: 12px;
background-color: $button-primary-fg-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-image: url('$(res)/img/feather-customised/upload.svg');
}
}
.mx_AccessibleButton.mx_AccessibleButton_kind_link_sm {
color: $button-danger-bg-color;
}
& > img {
cursor: pointer;
object-fit: cover;
}
& > img,
.mx_AvatarSetting_avatarPlaceholder {
display: block;
height: 88px;
border-radius: 4px;
}
.mx_AvatarSetting_avatarPlaceholder::before {
background-color: $settings-profile-overlay-placeholder-fg-color;
mask: url("$(res)/img/feather-customised/user.svg");
mask-repeat: no-repeat;
mask-size: 36px;
mask-position: center;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
.mx_AvatarSetting_avatar .mx_AvatarSetting_avatarPlaceholder {
background-color: $settings-profile-placeholder-bg-color;
}

View file

@ -14,16 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ReactionsQuickTooltip_buttons {
display: grid;
grid-template-columns: repeat(4, auto);
.mx_CrossSigningPanel_statusList {
border-spacing: 0;
td {
padding: 0;
&:first-of-type {
padding-inline-end: 1em;
}
}
}
.mx_ReactionsQuickTooltip_label {
text-align: center;
}
.mx_ReactionsQuickTooltip_shortcode {
padding-left: 6px;
opacity: 0.7;
.mx_CrossSigningPanel_buttonRow {
margin: 1em 0;
}

View file

@ -18,7 +18,7 @@ limitations under the License.
display: table;
table-layout: fixed;
width: 880px;
border-spacing: 2px;
border-spacing: 10px;
}
.mx_DevicesPanel_header {
@ -32,7 +32,11 @@ limitations under the License.
.mx_DevicesPanel_header > div {
display: table-cell;
vertical-align: bottom;
vertical-align: middle;
}
.mx_DevicesPanel_header .mx_DevicesPanel_deviceName {
width: 50%;
}
.mx_DevicesPanel_header .mx_DevicesPanel_deviceLastSeen {

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_IntegrationsManager .mx_Dialog {
.mx_IntegrationManager .mx_Dialog {
width: 60%;
height: 70%;
overflow: hidden;
@ -23,22 +23,22 @@ limitations under the License.
max-height: initial;
}
.mx_IntegrationsManager iframe {
.mx_IntegrationManager iframe {
background-color: #fff;
border: 0px;
width: 100%;
height: 100%;
}
.mx_IntegrationsManager_loading h3 {
.mx_IntegrationManager_loading h3 {
text-align: center;
}
.mx_IntegrationsManager_error {
.mx_IntegrationManager_error {
text-align: center;
padding-top: 20px;
}
.mx_IntegrationsManager_error h3 {
.mx_IntegrationManager_error h3 {
color: $warning-color;
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -30,3 +31,7 @@ limitations under the License.
.mx_KeyBackupPanel_deviceName {
font-style: italic;
}
.mx_KeyBackupPanel_buttonRow {
margin: 1em 0;
}

View file

@ -38,91 +38,6 @@ limitations under the License.
}
}
.mx_ProfileSettings_avatar {
width: 88px;
height: 88px;
margin-left: 13px;
position: relative;
}
.mx_ProfileSettings_avatar > * {
display: block;
width: 88px;
height: 88px;
border-radius: 4px;
}
.mx_ProfileSettings_avatar .mx_ProfileSettings_avatarOverlay_disabled {
cursor: default;
}
.mx_ProfileSettings_avatar .mx_ProfileSettings_avatarPlaceholder {
background-color: $settings-profile-placeholder-bg-color;
}
.mx_ProfileSettings_avatarOverlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: none;
text-align: center;
vertical-align: middle;
font-size: 10px;
cursor: pointer;
}
.mx_ProfileSettings_avatar:hover .mx_ProfileSettings_avatarOverlay:not(.mx_ProfileSettings_avatarOverlay_disabled) {
display: inline-block;
opacity: 0.5 !important;
color: $settings-profile-overlay-fg-color !important;
background-color: $settings-profile-overlay-bg-color !important;
}
.mx_ProfileSettings_avatarOverlay_show {
display: inline-block;
opacity: 1;
color: $settings-profile-overlay-placeholder-fg-color;
background-color: $settings-profile-overlay-placeholder-bg-color;
}
.mx_ProfileSettings_avatarOverlayText {
display: block;
margin-top: 17px;
margin-bottom: 8px;
}
.mx_ProfileSettings_noAvatarText {
display: block;
margin: 34px auto auto;
}
.mx_ProfileSettings_avatarOverlayImgContainer {
position: relative;
width: 14px;
height: 14px;
margin: auto;
}
.mx_ProfileSettings_avatarOverlayImg::before {
background-color: $settings-profile-overlay-placeholder-fg-color;
mask: url("$(res)/img/feather-customised/upload.svg");
mask-repeat: no-repeat;
mask-size: 14px;
mask-position: center;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.mx_ProfileSettings_avatar:hover .mx_ProfileSettings_avatarOverlayImg::before {
background-color: $settings-profile-overlay-fg-color !important;
}
.mx_ProfileSettings_avatarUpload {
display: none;
}

View file

@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_SetIntegrationManager .mx_Field_input {
@mixin mx_Settings_fullWidthField;
}
.mx_SetIntegrationManager {
margin-top: 10px;
margin-bottom: 10px;
@ -32,6 +28,10 @@ limitations under the License.
padding-left: 5px;
}
.mx_SetIntegrationManager_tooltip {
@mixin mx_Settings_tooltip;
.mx_SetIntegrationManager .mx_ToggleSwitch {
display: inline-block;
float: right;
top: 9px;
@mixin mx_Settings_fullWidthField;
}

View file

@ -14,18 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ReactionTooltipButton {
font-size: 16px;
padding: 6px;
user-select: none;
cursor: pointer;
transition: transform 0.25s;
&:hover {
transform: scale(1.2);
}
.mx_MjolnirUserSettingsTab .mx_Field {
@mixin mx_Settings_fullWidthField;
}
.mx_ReactionTooltipButton_selected {
opacity: 0.4;
.mx_MjolnirUserSettingsTab_listItem {
margin-bottom: 2px;
}

View file

@ -14,6 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_PreferencesUserSettingsTab .mx_Field {
@mixin mx_Settings_fullWidthField;
.mx_PreferencesUserSettingsTab {
.mx_Field {
@mixin mx_Settings_fullWidthField;
}
.mx_SettingsTab_section {
margin-bottom: 30px;
}
}

View file

@ -1,5 +1,6 @@
/*
Copyright 2019 New Vector Ltd.
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -28,21 +29,35 @@ limitations under the License.
.mx_VerificationShowSas_emojiSas {
text-align: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
margin: 25px 0;
}
.mx_VerificationShowSas_emojiSas_block {
display: inline-block;
margin-left: 15px;
margin-right: 15px;
text-align: center;
margin-bottom: 20px;
margin-bottom: 16px;
position: relative;
width: 52px;
}
.mx_Dialog .mx_VerificationShowSas_emojiSas_block,
.mx_AuthPage_modal .mx_VerificationShowSas_emojiSas_block {
width: 60px;
}
.mx_VerificationShowSas_emojiSas_emoji {
font-size: 48px;
font-size: 32px;
}
.mx_VerificationShowSas_emojiSas_label {
text-align: center;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 12px;
}
.mx_VerificationShowSas_emojiSas_break {
flex-basis: 100%;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more