Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/querystring
Conflicts: package.json src/@types/global.d.ts src/components/views/elements/AppTile.js src/utils/HostingLink.js yarn.lock
This commit is contained in:
commit
5dbd79c729
1950 changed files with 174795 additions and 76807 deletions
|
@ -1,4 +1,4 @@
|
|||
src/component-index.js
|
||||
test/end-to-end-tests/node_modules/
|
||||
test/end-to-end-tests/riot/
|
||||
test/end-to-end-tests/element/
|
||||
test/end-to-end-tests/synapse/
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
# autogenerated file: run scripts/generate-eslint-error-ignore-file to update.
|
||||
|
||||
src/components/structures/RoomDirectory.js
|
||||
src/components/structures/RoomStatusBar.js
|
||||
src/components/structures/RoomView.js
|
||||
src/components/structures/ScrollPanel.js
|
||||
src/components/structures/SearchBox.js
|
||||
src/components/structures/UploadBar.js
|
||||
src/components/views/avatars/BaseAvatar.js
|
||||
src/components/views/avatars/MemberAvatar.js
|
||||
src/components/views/create_room/RoomAlias.js
|
||||
src/components/views/dialogs/SetPasswordDialog.js
|
||||
src/components/views/dialogs/UnknownDeviceDialog.js
|
||||
src/components/views/elements/AddressSelector.js
|
||||
src/components/views/elements/DirectorySearchBox.js
|
||||
src/components/views/elements/MemberEventListSummary.js
|
||||
src/components/views/elements/UserSelector.js
|
||||
src/components/views/globals/MatrixToolbar.js
|
||||
src/components/views/globals/NewVersionBar.js
|
||||
src/components/views/globals/UpdateCheckBar.js
|
||||
src/components/views/messages/MFileBody.js
|
||||
src/components/views/messages/TextualBody.js
|
||||
src/components/views/room_settings/ColorSettings.js
|
||||
src/components/views/rooms/Autocomplete.js
|
||||
src/components/views/rooms/AuxPanel.js
|
||||
src/components/views/rooms/LinkPreviewWidget.js
|
||||
src/components/views/rooms/MemberDeviceInfo.js
|
||||
src/components/views/rooms/MemberInfo.js
|
||||
src/components/views/rooms/MemberList.js
|
||||
src/components/views/rooms/RoomList.js
|
||||
src/components/views/rooms/RoomPreviewBar.js
|
||||
src/components/views/rooms/SearchResultTile.js
|
||||
src/components/views/settings/ChangeAvatar.js
|
||||
src/components/views/settings/ChangePassword.js
|
||||
src/components/views/settings/DevicesPanel.js
|
||||
src/components/views/settings/Notifications.js
|
||||
src/HtmlUtils.js
|
||||
src/ImageUtils.js
|
||||
src/Markdown.js
|
||||
src/notifications/ContentRules.js
|
||||
src/notifications/PushRuleVectorState.js
|
||||
src/PlatformPeg.js
|
||||
src/rageshake/rageshake.js
|
||||
src/ratelimitedfunc.js
|
||||
src/Rooms.js
|
||||
src/Unread.js
|
||||
src/utils/DecryptFile.js
|
||||
src/utils/DirectoryUtils.js
|
||||
src/utils/DMRoomMap.js
|
||||
src/utils/FormattingUtils.js
|
||||
src/utils/MultiInviter.js
|
||||
src/utils/Receipt.js
|
||||
src/Velociraptor.js
|
||||
test/components/structures/MessagePanel-test.js
|
||||
test/components/views/dialogs/InteractiveAuthDialog-test.js
|
||||
test/mock-clock.js
|
||||
test/notifications/ContentRules-test.js
|
||||
test/notifications/PushRuleVectorState-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/
|
171
.eslintrc.js
171
.eslintrc.js
|
@ -1,121 +1,80 @@
|
|||
const path = require('path');
|
||||
|
||||
// get the path of the js-sdk so we can extend the config
|
||||
// eslint supports loading extended configs by module,
|
||||
// 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)
|
||||
//
|
||||
// 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"
|
||||
plugins: ["matrix-org"],
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
"plugin:matrix-org/react",
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
globals: {
|
||||
LANGUAGES_FILE: "readonly",
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
legacyDecorators: true,
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// eslint's built in no-invalid-this rule breaks with class properties
|
||||
"no-invalid-this": "off",
|
||||
// so we replace it with a version that is class property aware
|
||||
"babel/no-invalid-this": "error",
|
||||
// Things we do that break the ideal style
|
||||
"no-constant-condition": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-async-promise-executor": "off",
|
||||
"quotes": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// We appear to follow this most of the time, so let's enforce it instead
|
||||
// of occasionally following it (or catching it in review)
|
||||
"keyword-spacing": "error",
|
||||
|
||||
/** react **/
|
||||
// This just uses the react plugin to help eslint known when
|
||||
// variables have been used in JSX
|
||||
"react/jsx-uses-vars": "error",
|
||||
// Don't mark React as unused if we're using JSX
|
||||
"react/jsx-uses-react": "error",
|
||||
|
||||
// bind or arrow function in props causes performance issues
|
||||
// (but we currently use them in some places)
|
||||
// Bind or arrow functions in props causes performance issues (but we
|
||||
// currently use them in some places).
|
||||
// It's disabled here, but we should using it sparingly.
|
||||
"react/jsx-no-bind": "off",
|
||||
"react/jsx-key": ["error"],
|
||||
|
||||
// Components in JSX should always be defined.
|
||||
"react/jsx-no-undef": "error",
|
||||
|
||||
// Assert no spacing in JSX curly brackets
|
||||
// <Element prop={ consideredError} prop={notConsideredError} />
|
||||
//
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md
|
||||
//
|
||||
// Disabled for now - if anything we'd like to *enforce* spacing in JSX
|
||||
// curly brackets for legibility, but in practice it's not clear that the
|
||||
// consistency particularly improves legibility here. --Matthew
|
||||
//
|
||||
// "react/jsx-curly-spacing": ["error", {"when": "never", "children": {"when": "always"}}],
|
||||
|
||||
// Assert spacing before self-closing JSX tags, and no spacing before or
|
||||
// after the closing slash, and no spacing after the opening bracket of
|
||||
// the opening tag or closing tag.
|
||||
//
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-tag-spacing.md
|
||||
"react/jsx-tag-spacing": ["error"],
|
||||
|
||||
/** flowtype **/
|
||||
"flowtype/require-parameter-type": ["warn", {
|
||||
"excludeArrowFunctions": true,
|
||||
}],
|
||||
"flowtype/define-flow-type": "warn",
|
||||
"flowtype/require-return-type": ["warn",
|
||||
"always",
|
||||
{
|
||||
"annotateUndefined": "never",
|
||||
"excludeArrowFunctions": true,
|
||||
}
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["window.innerHeight", "window.innerWidth", "window.visualViewport"],
|
||||
"Use UIStore to access window dimensions instead.",
|
||||
),
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["*.mxcUrlToHttp", "*.getHttpUriForMxc"],
|
||||
"Use Media helper instead to centralise access for customisation.",
|
||||
),
|
||||
],
|
||||
"flowtype/space-after-type-colon": ["warn", "always"],
|
||||
"flowtype/space-before-type-colon": ["warn", "never"],
|
||||
|
||||
/*
|
||||
* things that are errors in the js-sdk config that the current
|
||||
* code does not adhere to, turned down to warn
|
||||
*/
|
||||
"max-len": ["warn", {
|
||||
// apparently people believe the length limit shouldn't apply
|
||||
// to JSX.
|
||||
ignorePattern: '^\\s*<',
|
||||
ignoreComments: true,
|
||||
ignoreRegExpLiterals: true,
|
||||
code: 120,
|
||||
}],
|
||||
"valid-jsdoc": ["warn"],
|
||||
"new-cap": ["warn"],
|
||||
"key-spacing": ["warn"],
|
||||
"prefer-const": ["warn"],
|
||||
|
||||
// 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: {
|
||||
onlyFilesWithFlowAnnotation: true
|
||||
overrides: [{
|
||||
files: [
|
||||
"src/**/*.{ts,tsx}",
|
||||
"test/**/*.{ts,tsx}",
|
||||
],
|
||||
extends: [
|
||||
"plugin:matrix-org/typescript",
|
||||
"plugin:matrix-org/react",
|
||||
],
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// Remove Babel things manually due to override limitations
|
||||
"@babel/no-invalid-this": ["off"],
|
||||
|
||||
// We're okay being explicit at the moment
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We'd rather not do this but we do
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
},
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
function buildRestrictedPropertiesOptions(properties, message) {
|
||||
return properties.map(prop => {
|
||||
let [object, property] = prop.split(".");
|
||||
if (object === "*") {
|
||||
object = undefined;
|
||||
}
|
||||
return {
|
||||
object,
|
||||
property,
|
||||
message,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[include]
|
||||
src/**/*.js
|
||||
test/**/*.js
|
||||
|
||||
[ignore]
|
||||
node_modules/
|
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!-- Please read https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md before submitting your pull request -->
|
||||
|
||||
<!-- Include a Sign-Off as described in https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.md#sign-off -->
|
||||
|
||||
<!-- To specify text for the changelog entry (otherwise the PR title will be used):
|
||||
Notes:
|
||||
|
||||
Changes in this project generate changelog entries in element-web by default.
|
||||
To suppress this:
|
||||
|
||||
element-web notes: none
|
||||
|
||||
...or to specify different notes:
|
||||
element-web notes: <notes>
|
||||
-->
|
44
.github/workflows/develop.yml
vendored
Normal file
44
.github/workflows/develop.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
name: Develop
|
||||
on:
|
||||
# These tests won't work for non-develop branches at the moment as they
|
||||
# won't pull in the right versions of other repos, so they're only enabled
|
||||
# on develop.
|
||||
push:
|
||||
branches: [develop]
|
||||
pull_request:
|
||||
branches: [develop]
|
||||
jobs:
|
||||
end-to-end:
|
||||
runs-on: ubuntu-latest
|
||||
container: vectorim/element-web-ci-e2etests-env:latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Prepare End-to-End tests
|
||||
run: ./scripts/ci/prepare-end-to-end-tests.sh
|
||||
- name: Run End-to-End tests
|
||||
run: ./scripts/ci/run-end-to-end-tests.sh
|
||||
- name: Archive logs
|
||||
uses: actions/upload-artifact@v2
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
path: |
|
||||
test/end-to-end-tests/logs/**/*
|
||||
test/end-to-end-tests/synapse/installations/consent/homeserver.log
|
||||
retention-days: 14
|
||||
- name: Download previous benchmark data
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ./cache
|
||||
key: ${{ runner.os }}-benchmark
|
||||
- name: Store benchmark result
|
||||
uses: matrix-org/github-action-benchmark@jsperfentry-1
|
||||
with:
|
||||
tool: 'jsperformanceentry'
|
||||
output-file-path: test/end-to-end-tests/performance-entries.json
|
||||
fail-on-alert: false
|
||||
comment-on-alert: false
|
||||
# Only temporary to monitor where failures occur
|
||||
alert-comment-cc-users: '@gsouquet'
|
||||
github-token: ${{ secrets.DEPLOY_GH_PAGES }}
|
||||
auto-push: ${{ github.ref == 'refs/heads/develop' }}
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
/*.log
|
||||
package-lock.json
|
||||
|
||||
/coverage
|
||||
/node_modules
|
||||
/lib
|
||||
|
||||
|
@ -13,3 +14,7 @@ package-lock.json
|
|||
/src/component-index.js
|
||||
|
||||
.DS_Store
|
||||
*.tmp
|
||||
|
||||
.vscode
|
||||
.vscode/
|
||||
|
|
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
"stylelint-scss",
|
||||
],
|
||||
"rules": {
|
||||
"color-hex-case": null,
|
||||
"indentation": 4,
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
|
@ -17,7 +18,7 @@ module.exports = {
|
|||
"at-rule-no-unknown": null,
|
||||
"no-descending-specificity": null,
|
||||
"scss/at-rule-no-unknown": [true, {
|
||||
// https://github.com/vector-im/riot-web/issues/10544
|
||||
// https://github.com/vector-im/element-web/issues/10544
|
||||
"ignoreAtRules": ["define-mixin"],
|
||||
}],
|
||||
}
|
||||
|
|
4063
CHANGELOG.md
4063
CHANGELOG.md
File diff suppressed because it is too large
Load diff
30
README.md
30
README.md
|
@ -11,14 +11,14 @@ a 'skin'. A skin provides:
|
|||
* The containing application
|
||||
* Zero or more 'modules' containing non-UI functionality
|
||||
|
||||
As of Aug 2018, the only skin that exists is `vector-im/riot-web`; it and
|
||||
As of Aug 2018, the only skin that exists is `vector-im/element-web`; it and
|
||||
`matrix-org/matrix-react-sdk` should effectively
|
||||
be considered as a single project (for instance, matrix-react-sdk bugs
|
||||
are currently filed against vector-im/riot-web rather than this project).
|
||||
are currently filed against vector-im/element-web rather than this project).
|
||||
|
||||
Translation Status
|
||||
==================
|
||||
[](https://translate.riot.im/engage/riot-web/?utm_source=widget)
|
||||
[](https://translate.element.io/engage/element-web/?utm_source=widget)
|
||||
|
||||
Developer Guide
|
||||
===============
|
||||
|
@ -28,7 +28,7 @@ Platform Targets:
|
|||
* WebRTC features (VoIP and Video calling) are only available in Chrome & Firefox.
|
||||
* Mobile Web is not currently a target platform - instead please use the native
|
||||
iOS (https://github.com/matrix-org/matrix-ios-kit) and Android
|
||||
(https://github.com/matrix-org/matrix-android-sdk) SDKs.
|
||||
(https://github.com/matrix-org/matrix-android-sdk2) SDKs.
|
||||
|
||||
All code lands on the `develop` branch - `master` is only used for stable releases.
|
||||
**Please file PRs against `develop`!!**
|
||||
|
@ -41,10 +41,10 @@ https://github.com/matrix-org/matrix-react-sdk/blob/master/code_style.md
|
|||
|
||||
Code should be committed as follows:
|
||||
* All new components: https://github.com/matrix-org/matrix-react-sdk/tree/master/src/components
|
||||
* Riot-specific components: https://github.com/vector-im/riot-web/tree/master/src/components
|
||||
* Element-specific components: https://github.com/vector-im/element-web/tree/master/src/components
|
||||
* In practice, `matrix-react-sdk` is still evolving so fast that the maintenance
|
||||
burden of customising and overriding these components for Riot can seriously
|
||||
impede development. So right now, there should be very few (if any) customisations for Riot.
|
||||
burden of customising and overriding these components for Element can seriously
|
||||
impede development. So right now, there should be very few (if any) customisations for Element.
|
||||
* CSS: https://github.com/matrix-org/matrix-react-sdk/tree/master/res/css
|
||||
* Theme specific CSS & resources: https://github.com/matrix-org/matrix-react-sdk/tree/master/res/themes
|
||||
|
||||
|
@ -71,7 +71,7 @@ practices that anyone working with the SDK needs to be be aware of and uphold:
|
|||
|
||||
* The view's CSS file MUST have the same name (e.g. view/rooms/MessageTile.css).
|
||||
CSS for matrix-react-sdk currently resides in
|
||||
https://github.com/vector-im/riot-web/tree/master/src/skins/vector/css/matrix-react-sdk.
|
||||
https://github.com/vector-im/element-web/tree/master/src/skins/vector/css/matrix-react-sdk.
|
||||
|
||||
* Per-view CSS is optional - it could choose to inherit all its styling from
|
||||
the context of the rest of the app, although this is unusual for any but
|
||||
|
@ -125,7 +125,7 @@ from it.
|
|||
Github Issues
|
||||
=============
|
||||
|
||||
All issues should be filed under https://github.com/vector-im/riot-web/issues
|
||||
All issues should be filed under https://github.com/vector-im/element-web/issues
|
||||
for now.
|
||||
|
||||
Development
|
||||
|
@ -133,8 +133,10 @@ Development
|
|||
|
||||
Ensure you have the latest LTS version of Node.js installed.
|
||||
|
||||
Using `yarn` instead of `npm` is recommended. Please see the Yarn [install
|
||||
guide](https://yarnpkg.com/docs/install/) if you do not have it already.
|
||||
Using `yarn` instead of `npm` is recommended. Please see the Yarn 1 [install
|
||||
guide](https://classic.yarnpkg.com/docs/install) if you do not have it
|
||||
already. This project has not yet been migrated to Yarn 2, so please ensure
|
||||
`yarn --version` shows a version from the 1.x series.
|
||||
|
||||
`matrix-react-sdk` depends on `matrix-js-sdk`. To make use of changes in the
|
||||
latter and to ensure tests run against the develop branch of `matrix-js-sdk`,
|
||||
|
@ -158,8 +160,8 @@ yarn link matrix-js-sdk
|
|||
yarn install
|
||||
```
|
||||
|
||||
See the [help for `yarn link`](https://yarnpkg.com/docs/cli/link) for more
|
||||
details about this.
|
||||
See the [help for `yarn link`](https://classic.yarnpkg.com/docs/cli/link) for
|
||||
more details about this.
|
||||
|
||||
Running tests
|
||||
=============
|
||||
|
@ -172,5 +174,5 @@ 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`.
|
||||
Make sure you've got your Element development server running (by doing `yarn start` in element-web), and then in this project, run `yarn run e2etests`.
|
||||
See `test/end-to-end-tests/README.md` for more information.
|
||||
|
|
6
__mocks__/FontManager.js
Normal file
6
__mocks__/FontManager.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Stub out FontManager for tests as it doesn't validate anything we don't already know given
|
||||
// our fixed test environment and it requires the installation of node-canvas.
|
||||
|
||||
module.exports = {
|
||||
fixupColorFonts: () => Promise.resolve(),
|
||||
};
|
|
@ -1,5 +1,10 @@
|
|||
const en = require("../src/i18n/strings/en_EN");
|
||||
const de = require("../src/i18n/strings/de_DE");
|
||||
|
||||
// Mock the browser-request for the languageHandler tests to return
|
||||
// Fake languages.json containing references to en_EN and de_DE
|
||||
// en_EN.json
|
||||
// de_DE.json
|
||||
module.exports = jest.fn((opts, cb) => {
|
||||
const url = opts.url || opts.uri;
|
||||
if (url && url.endsWith("languages.json")) {
|
||||
|
@ -8,9 +13,15 @@ module.exports = jest.fn((opts, cb) => {
|
|||
"fileName": "en_EN.json",
|
||||
"label": "English",
|
||||
},
|
||||
"de": {
|
||||
"fileName": "de_DE.json",
|
||||
"label": "German",
|
||||
},
|
||||
}));
|
||||
} else if (url && url.endsWith("en_EN.json")) {
|
||||
cb(undefined, {status: 200}, JSON.stringify(en));
|
||||
} else if (url && url.endsWith("de_DE.json")) {
|
||||
cb(undefined, {status: 200}, JSON.stringify(de));
|
||||
} else {
|
||||
cb(true, {status: 404}, "");
|
||||
}
|
||||
|
|
2
__mocks__/empty.js
Normal file
2
__mocks__/empty.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Yes, this is empty.
|
||||
module.exports = {};
|
1
__mocks__/workerMock.js
Normal file
1
__mocks__/workerMock.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = jest.fn();
|
17
__test-utils__/environment.js
Normal file
17
__test-utils__/environment.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const BaseEnvironment = require("jest-environment-jsdom-sixteen");
|
||||
|
||||
class Environment extends BaseEnvironment {
|
||||
constructor(config, options) {
|
||||
super(Object.assign({}, config, {
|
||||
globals: Object.assign({}, config.globals, {
|
||||
// Explicitly specify the correct globals to workaround Jest bug
|
||||
// https://github.com/facebook/jest/issues/7780
|
||||
Uint32Array: Uint32Array,
|
||||
Uint8Array: Uint8Array,
|
||||
ArrayBuffer: ArrayBuffer,
|
||||
}),
|
||||
}), options);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Environment;
|
|
@ -3,12 +3,14 @@ module.exports = {
|
|||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": [
|
||||
"last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions"
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"last 2 Safari versions",
|
||||
"last 2 Edge versions",
|
||||
],
|
||||
}],
|
||||
"@babel/preset-typescript",
|
||||
"@babel/preset-flow",
|
||||
"@babel/preset-react"
|
||||
"@babel/preset-react",
|
||||
],
|
||||
"plugins": [
|
||||
["@babel/plugin-proposal-decorators", {legacy: true}],
|
||||
|
@ -16,8 +18,7 @@ module.exports = {
|
|||
"@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"
|
||||
]
|
||||
"@babel/plugin-transform-runtime",
|
||||
],
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ Matrix JavaScript/ECMAScript Style Guide
|
|||
The intention of this guide is to make Matrix's JavaScript codebase clean,
|
||||
consistent with other popular JavaScript styles and consistent with the rest of
|
||||
the Matrix codebase. For reference, the Matrix Python style guide can be found
|
||||
at https://github.com/matrix-org/synapse/blob/master/docs/code_style.rst
|
||||
at https://github.com/matrix-org/synapse/blob/master/docs/code_style.md
|
||||
|
||||
This document reflects how we would like Matrix JavaScript code to look, with
|
||||
acknowledgement that a significant amount of code is written to older
|
||||
|
@ -17,7 +17,7 @@ writing in modern ECMAScript and using a transpile step to generate the file
|
|||
that applications can then include. There are significant benefits in being
|
||||
able to use modern ECMAScript, although the tooling for doing so can be awkward
|
||||
for library code, especially with regard to translating source maps and line
|
||||
number throgh from the original code to the final application.
|
||||
number through from the original code to the final application.
|
||||
|
||||
General Style
|
||||
-------------
|
||||
|
@ -35,12 +35,6 @@ General Style
|
|||
- lowerCamelCase for functions and variables.
|
||||
- Single line ternary operators are fine.
|
||||
- UPPER_SNAKE_CASE for constants
|
||||
- Single quotes for strings by default, for consistency with most JavaScript styles:
|
||||
|
||||
```javascript
|
||||
"bad" // Bad
|
||||
'good' // Good
|
||||
```
|
||||
- Use parentheses or `` ` `` instead of `\` for line continuation where ever possible
|
||||
- Open braces on the same line (consistent with Node):
|
||||
|
||||
|
@ -151,6 +145,7 @@ General Style
|
|||
Don't set things to undefined. Reserve that value to mean "not yet set to anything."
|
||||
Boolean objects are verboten.
|
||||
- Use JSDoc
|
||||
- Use switch-case statements where there are 5 or more branches running against the same variable.
|
||||
|
||||
ECMAScript
|
||||
----------
|
||||
|
@ -161,7 +156,14 @@ ECMAScript
|
|||
- Be careful mixing arrow functions and regular functions, eg. if one function in a promise chain is an
|
||||
arrow function, they probably all should be.
|
||||
- Apart from that, newer ES features should be used whenever the author deems them to be appropriate.
|
||||
- Flow annotations are welcome and encouraged.
|
||||
|
||||
TypeScript
|
||||
----------
|
||||
- TypeScript is preferred over the use of JavaScript
|
||||
- It's desirable to convert existing JavaScript files to TypeScript. TypeScript conversions should be done in small
|
||||
chunks without functional changes to ease the review process.
|
||||
- Use full type definitions for function parameters and return values.
|
||||
- Avoid `any` types and `any` casts
|
||||
|
||||
React
|
||||
-----
|
||||
|
@ -200,6 +202,8 @@ React
|
|||
this.state = { counter: 0 };
|
||||
}
|
||||
```
|
||||
- Prefer class components over function components and hooks (not a strict rule though)
|
||||
|
||||
- Think about whether your component really needs state: are you duplicating
|
||||
information in component state that could be derived from the model?
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# The CIDER (Contenteditable-Input-Diff-Error-Reconcile) editor
|
||||
|
||||
The CIDER editor is a custom editor written for Riot.
|
||||
The CIDER editor is a custom editor written for Element.
|
||||
Most of the code can be found in the `/editor/` directory of the `matrix-react-sdk` project.
|
||||
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, ...).
|
||||
|
||||
|
@ -21,14 +21,14 @@ caret nodes (more on that later).
|
|||
For these reasons it doesn't use `innerText`, `textContent` or anything similar.
|
||||
The model addresses any content in the editor within as an offset within this string.
|
||||
The caret position is thus also converted from a position in the DOM tree
|
||||
to an offset in the content string. This happens in `getCaretOffsetAndText` in `dom.js`.
|
||||
to an offset in the content string. This happens in `getCaretOffsetAndText` in `dom.ts`.
|
||||
|
||||
Once the content string and caret offset is calculated, it is passed to the `update()`
|
||||
method of the model. The model first calculates the same content string of its current parts,
|
||||
basically just concatenating their text. It then looks for differences between
|
||||
the current and the new content string. The diffing algorithm is very basic,
|
||||
and assumes there is only one change around the caret offset,
|
||||
so this should be very inexpensive. See `diff.js` for details.
|
||||
so this should be very inexpensive. See `diff.ts` for details.
|
||||
|
||||
The result of the diffing is the strings that were added and/or removed from
|
||||
the current content. These differences are then applied to the parts,
|
||||
|
@ -51,7 +51,7 @@ which relate poorly to text input or changes, and don't need the `beforeinput` e
|
|||
which isn't broadly supported yet.
|
||||
|
||||
Once the parts of the model are updated, the DOM of the editor is then reconciled
|
||||
with the new model state, see `renderModel` in `render.js` for this.
|
||||
with the new model state, see `renderModel` in `render.ts` for this.
|
||||
If the model didn't reject the input and didn't make any additional changes,
|
||||
this won't make any changes to the DOM at all, and should thus be fairly efficient.
|
||||
|
||||
|
|
BIN
docs/img/RoomListStore2.png
Normal file
BIN
docs/img/RoomListStore2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
|
@ -25,7 +25,7 @@ which takes several parameters:
|
|||
be null.
|
||||
|
||||
The react-sdk will assume that `jitsi.html` is at the path of wherever it is currently
|
||||
being served. For example, `https://riot.im/develop/jitsi.html` or `vector://webapp/jitsi.html`.
|
||||
being served. For example, `https://develop.element.io/jitsi.html` or `vector://webapp/jitsi.html`.
|
||||
|
||||
The `jitsi.html` wrapper can use the react-sdk's `WidgetApi` to communicate, making
|
||||
it easier to actually implement the feature.
|
||||
|
|
39
docs/local-echo-dev.md
Normal file
39
docs/local-echo-dev.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Local echo (developer docs)
|
||||
|
||||
The React SDK provides some local echo functionality to allow for components to do something
|
||||
quickly and fall back when it fails. This is all available in the `local-echo` directory within
|
||||
`stores`.
|
||||
|
||||
Echo is handled in EchoChambers, with `GenericEchoChamber` being the base implementation for all
|
||||
chambers. The `EchoChamber` class is provided as semantic access to a `GenericEchoChamber`
|
||||
implementation, such as the `RoomEchoChamber` (which handles echoable details of a room).
|
||||
|
||||
Anything that can be locally echoed will be provided by the `GenericEchoChamber` implementation.
|
||||
The echo chamber will also need to deal with external changes, and has full control over whether
|
||||
or not something has successfully been echoed.
|
||||
|
||||
An `EchoContext` is provided to echo chambers (usually with a matching type: `RoomEchoContext`
|
||||
gets provided to a `RoomEchoChamber` for example) with details about their intended area of
|
||||
effect, as well as manage `EchoTransaction`s. An `EchoTransaction` is simply a unit of work that
|
||||
needs to be locally echoed.
|
||||
|
||||
The `EchoStore` manages echo chamber instances, builds contexts, and is generally less semantically
|
||||
accessible than the `EchoChamber` class. For separation of concerns, and to try and keep things
|
||||
tidy, this is an intentional design decision.
|
||||
|
||||
**Note**: The local echo stack uses a "whenable" pattern, which is similar to thenables and
|
||||
`EventEmitter`. Whenables are ways of actioning a changing condition without having to deal
|
||||
with listeners being torn down. Once the reference count of the Whenable causes garbage collection,
|
||||
the Whenable's listeners will also be torn down. This is accelerated by the `IDestroyable` interface
|
||||
usage.
|
||||
|
||||
## Audit functionality
|
||||
|
||||
The UI supports a "Server isn't responding" dialog which includes a partial audit log-like
|
||||
structure to it. This is partially the reason for added complexity of `EchoTransaction`s
|
||||
and `EchoContext`s - this information feeds the UI states which then provide direct retry
|
||||
mechanisms.
|
||||
|
||||
The `EchoStore` is responsible for ensuring that the appropriate non-urgent toast (lower left)
|
||||
is set up, where the dialog then drives through the contexts and transactions.
|
||||
|
19
docs/media-handling.md
Normal file
19
docs/media-handling.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Media handling
|
||||
|
||||
Surely media should be as easy as just putting a URL into an `img` and calling it good, right?
|
||||
Not quite. Matrix uses something called a Matrix Content URI (better known as MXC URI) to identify
|
||||
content, which is then converted to a regular HTTPS URL on the homeserver. However, sometimes that
|
||||
URL can change depending on deployment considerations.
|
||||
|
||||
The react-sdk features a [customisation endpoint](https://github.com/vector-im/element-web/blob/develop/docs/customisations.md)
|
||||
for media handling where all conversions from MXC URI to HTTPS URL happen. This is to ensure that
|
||||
those obscure deployments can route all their media to the right place.
|
||||
|
||||
For development, there are currently two functions available: `mediaFromMxc` and `mediaFromContent`.
|
||||
The `mediaFromMxc` function should be self-explanatory. `mediaFromContent` takes an event content as
|
||||
a parameter and will automatically parse out the source media and thumbnail. Both functions return
|
||||
a `Media` object with a number of options on it, such as getting various common HTTPS URLs for the
|
||||
media.
|
||||
|
||||
**It is extremely important that all media calls are put through this customisation endpoint.** So
|
||||
much so it's a lint rule to avoid accidental use of the wrong functions.
|
165
docs/room-list-store.md
Normal file
165
docs/room-list-store.md
Normal file
|
@ -0,0 +1,165 @@
|
|||
# Room list sorting
|
||||
|
||||
It's so complicated it needs its own README.
|
||||
|
||||

|
||||
|
||||
Legend:
|
||||
* Orange = External event.
|
||||
* Purple = Deterministic flow.
|
||||
* Green = Algorithm definition.
|
||||
* Red = Exit condition/point.
|
||||
* Blue = Process definition.
|
||||
|
||||
## Algorithms involved
|
||||
|
||||
There's two main kinds of algorithms involved in the room list store: list ordering and tag sorting.
|
||||
Throughout the code an intentional decision has been made to call them the List Algorithm and Sorting
|
||||
Algorithm respectively. The list algorithm determines the primary ordering of a given tag whereas the
|
||||
tag sorting defines how rooms within that tag get sorted, at the discretion of the list ordering.
|
||||
|
||||
Behaviour of the overall room list (sticky rooms, etc) are determined by the generically-named Algorithm
|
||||
class. Here is where much of the coordination from the room list store is done to figure out which list
|
||||
algorithm to call, instead of having all the logic in the room list store itself.
|
||||
|
||||
|
||||
Tag sorting is effectively the comparator supplied to the list algorithm. This gives the list algorithm
|
||||
the power to decide when and how to apply the tag sorting, if at all. For example, the importance algorithm,
|
||||
later described in this document, heavily uses the list ordering behaviour to break the tag into categories.
|
||||
Each category then gets sorted by the appropriate tag sorting algorithm.
|
||||
|
||||
### Tag sorting algorithm: Alphabetical
|
||||
|
||||
When used, rooms in a given tag will be sorted alphabetically, where the alphabet's order is a problem
|
||||
for the browser. All we do is a simple string comparison and expect the browser to return something
|
||||
useful.
|
||||
|
||||
### Tag sorting algorithm: Manual
|
||||
|
||||
Manual sorting makes use of the `order` property present on all tags for a room, per the
|
||||
[Matrix specification](https://matrix.org/docs/spec/client_server/r0.6.0#room-tagging). Smaller values
|
||||
of `order` cause rooms to appear closer to the top of the list.
|
||||
|
||||
### Tag sorting algorithm: Recent
|
||||
|
||||
Rooms get ordered by the timestamp of the most recent useful message. Usefulness is yet another algorithm
|
||||
in the room list system which determines whether an event type is capable of bubbling up in the room list.
|
||||
Normally events like room messages, stickers, and room security changes will be considered useful enough
|
||||
to cause a shift in time.
|
||||
|
||||
Note that this is reliant on the event timestamps of the most recent message. Because Matrix is eventually
|
||||
consistent this means that from time to time a room might plummet or skyrocket across the tag due to the
|
||||
timestamp contained within the event (generated server-side by the sender's server).
|
||||
|
||||
### List ordering algorithm: Natural
|
||||
|
||||
This is the easiest of the algorithms to understand because it does essentially nothing. It imposes no
|
||||
behavioural changes over the tag sorting algorithm and is by far the simplest way to order a room list.
|
||||
Historically, it's been the only option in Element and extremely common in most chat applications due to
|
||||
its relative deterministic behaviour.
|
||||
|
||||
### List ordering algorithm: Importance
|
||||
|
||||
On the other end of the spectrum, this is the most complicated algorithm which exists. There's major
|
||||
behavioural changes, and the tag sorting algorithm gets selectively applied depending on circumstances.
|
||||
|
||||
Each tag which is not manually ordered gets split into 4 sections or "categories". Manually ordered tags
|
||||
simply get the manual sorting algorithm applied to them with no further involvement from the importance
|
||||
algorithm. There are 4 categories: Red, Grey, Bold, and Idle. Each has their own definition based off
|
||||
relative (perceived) importance to the user:
|
||||
|
||||
* **Red**: The room has unread mentions waiting for the user.
|
||||
* **Grey**: The room has unread notifications waiting for the user. Notifications are simply unread
|
||||
messages which cause a push notification or badge count. Typically, this is the default as rooms get
|
||||
set to 'All Messages'.
|
||||
* **Bold**: The room has unread messages waiting for the user. Essentially this is a grey room without
|
||||
a badge/notification count (or 'Mentions Only'/'Muted').
|
||||
* **Idle**: No useful (see definition of useful above) activity has occurred in the room since the user
|
||||
last read it.
|
||||
|
||||
Conveniently, each tag gets ordered by those categories as presented: red rooms appear above grey, grey
|
||||
above bold, etc.
|
||||
|
||||
Once the algorithm has determined which rooms belong in which categories, the tag sorting algorithm
|
||||
gets applied to each category in a sub-list fashion. This should result in the red rooms (for example)
|
||||
being sorted alphabetically amongst each other as well as the grey rooms sorted amongst each other, but
|
||||
collectively the tag will be sorted into categories with red being at the top.
|
||||
|
||||
## Sticky rooms
|
||||
|
||||
When the user visits a room, that room becomes 'sticky' in the list, regardless of ordering algorithm.
|
||||
From a code perspective, the underlying algorithm is not aware of a sticky room and instead the base class
|
||||
manages which room is sticky. This is to ensure that all algorithms handle it the same.
|
||||
|
||||
The sticky flag is simply to say it will not move higher or lower down the list while it is active. For
|
||||
example, if using the importance algorithm, the room would naturally become idle once viewed and thus
|
||||
would normally fly down the list out of sight. The sticky room concept instead holds it in place, never
|
||||
letting it fly down until the user moves to another room.
|
||||
|
||||
Only one room can be sticky at a time. Room updates around the sticky room will still hold the sticky
|
||||
room in place. The best example of this is the importance algorithm: if the user has 3 red rooms and
|
||||
selects the middle room, they will see exactly one room above their selection at all times. If they
|
||||
receive another notification which causes the room to move into the topmost position, the room that was
|
||||
above the sticky room will move underneath to allow for the new room to take the top slot, maintaining
|
||||
the sticky room's position.
|
||||
|
||||
Though only applicable to the importance algorithm, the sticky room is not aware of category boundaries
|
||||
and thus the user can see a shift in what kinds of rooms move around their selection. An example would
|
||||
be the user having 4 red rooms, the user selecting the third room (leaving 2 above it), and then having
|
||||
the rooms above it read on another device. This would result in 1 red room and 1 other kind of room
|
||||
above the sticky room as it will try to maintain 2 rooms above the sticky room.
|
||||
|
||||
An exception for the sticky room placement is when there's suddenly not enough rooms to maintain the placement
|
||||
exactly. This typically happens if the user selects a room and leaves enough rooms where it cannot maintain
|
||||
the N required rooms above the sticky room. In this case, the sticky room will simply decrease N as needed.
|
||||
The N value will never increase while selection remains unchanged: adding a bunch of rooms after having
|
||||
put the sticky room in a position where it's had to decrease N will not increase N.
|
||||
|
||||
## Responsibilities of the store
|
||||
|
||||
The store is responsible for the ordering, upkeep, and tracking of all rooms. The room list component simply gets
|
||||
an object containing the tags it needs to worry about and the rooms within. The room list component will
|
||||
decide which tags need rendering (as it commonly filters out empty tags in most cases), and will deal with
|
||||
all kinds of filtering.
|
||||
|
||||
## Filtering
|
||||
|
||||
Filters are provided to the store as condition classes and have two major kinds: Prefilters and Runtime.
|
||||
|
||||
Prefilters flush out rooms which shouldn't appear to the algorithm implementations. Typically this is
|
||||
due to some higher order room list filtering (such as spaces or tags) deliberately exposing a subset of
|
||||
rooms to the user. The algorithm implementations will not see a room being prefiltered out.
|
||||
|
||||
Runtime filters are used for more dynamic filtering, such as the user filtering by room name. These
|
||||
filters are passed along to the algorithm implementations where those implementations decide how and
|
||||
when to apply the filter. In practice, the base `Algorithm` class ends up doing the heavy lifting for
|
||||
optimization reasons.
|
||||
|
||||
The results of runtime filters get cached to avoid needlessly iterating over potentially thousands of
|
||||
rooms, as the old room list store does. When a filter condition changes, it emits an update which (in this
|
||||
case) the `Algorithm` class will pick up and act accordingly. Typically, this also means filtering a
|
||||
minor subset where possible to avoid over-iterating rooms.
|
||||
|
||||
All filter conditions are considered "stable" by the consumers, meaning that the consumer does not
|
||||
expect a change in the condition unless the condition says it has changed. This is intentional to
|
||||
maintain the caching behaviour described above.
|
||||
|
||||
One might ask why we don't just use prefilter conditions for everything, and the answer is one of slight
|
||||
subtlety: in the cases of prefilters we are knowingly exposing the user to a workspace-style UX where
|
||||
room notifications are self-contained within that workspace. Runtime filters tend to not want to affect
|
||||
visible notification counts (as it doesn't want the room header to suddenly be confusing to the user as
|
||||
they type), and occasionally UX like "found 2/12 rooms" is desirable. If prefiltering were used instead,
|
||||
the notification counts would vary while the user was typing and "found 2/12" UX would not be possible.
|
||||
|
||||
## Class breakdowns
|
||||
|
||||
The `RoomListStore` is the major coordinator of various algorithm implementations, which take care
|
||||
of the various `ListAlgorithm` and `SortingAlgorithm` options. The `Algorithm` class is responsible
|
||||
for figuring out which tags get which rooms, as Matrix specifies them as a reverse map: tags get
|
||||
defined on rooms and are not defined as a collection of rooms (unlike how they are presented to the
|
||||
user). Various list-specific utilities are also included, though they are expected to move somewhere
|
||||
more general when needed. For example, the `membership` utilities could easily be moved elsewhere
|
||||
as needed.
|
||||
|
||||
The various bits throughout the room list store should also have jsdoc of some kind to help describe
|
||||
what they do and how they work.
|
|
@ -13,7 +13,7 @@ ScrollPanel supports a mode to prevent it shrinking. This is used to prevent a j
|
|||
|
||||
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 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/element-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.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ of dealing with the different levels and exposes easy to use getters and setters
|
|||
## Levels
|
||||
|
||||
Granular Settings rely on a series of known levels in order to use the correct value for the scenario. These levels, in
|
||||
order of prioirty, are:
|
||||
order of priority, are:
|
||||
* `device` - The current user's device
|
||||
* `room-device` - The current user's device, but only when in a specific room
|
||||
* `room-account` - The current user's account, but only when in a specific room
|
||||
|
@ -25,33 +25,10 @@ that room administrators cannot force account-only settings upon participants.
|
|||
## Settings
|
||||
|
||||
Settings are the different options a user may set or experience in the application. These are pre-defined in
|
||||
`src/settings/Settings.js` under the `SETTINGS` constant and have the following minimum requirements:
|
||||
```
|
||||
// The ID is used to reference the setting throughout the application. This must be unique.
|
||||
"theSettingId": {
|
||||
// The levels this setting supports is required. In `src/settings/Settings.js` there are various pre-set arrays
|
||||
// for this option - they should be used where possible to avoid copy/pasting arrays across settings.
|
||||
supportedLevels: [...],
|
||||
`src/settings/Settings.ts` under the `SETTINGS` constant, and match the `ISetting` interface as defined there.
|
||||
|
||||
// The default for this setting serves two purposes: It provides a value if the setting is not defined at other
|
||||
// levels, and it serves to demonstrate the expected type to other developers. The value isn't enforced, but it
|
||||
// should be respected throughout the code. The default may be any data type.
|
||||
default: false,
|
||||
|
||||
// The display name has two notations: string and object. The object notation allows for different translatable
|
||||
// strings to be used for different levels, while the string notation represents the string for all levels.
|
||||
|
||||
displayName: _td("Change something"), // effectively `displayName: { "default": _td("Change something") }`
|
||||
displayName: {
|
||||
"room": _td("Change something for participants of this room"),
|
||||
|
||||
// Note: the default will be used if the level requested (such as `device`) does not have a string defined here.
|
||||
"default": _td("Change something"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Settings that support the config level can be set in the config file under the `settingDefaults` key (note that some settings, like the "theme" setting, are special cased in the config file):
|
||||
Settings that support the config level can be set in the config file under the `settingDefaults` key (note that some
|
||||
settings, like the "theme" setting, are special cased in the config file):
|
||||
```json
|
||||
{
|
||||
...
|
||||
|
@ -119,39 +96,42 @@ for you. If a display name cannot be found, it will return `null`.
|
|||
|
||||
## Features
|
||||
|
||||
Occasionally some parts of the application may be undergoing testing and are not quite production ready. These are
|
||||
commonly known to be behind a "labs flag". Features behind lab flags must go through the granular settings system, and
|
||||
look and act very much normal settings. The exception is that they must supply `isFeature: true` as part of the setting
|
||||
definition and should go through the helper functions on `SettingsStore`.
|
||||
Feature flags are just like regular settings with some underlying semantics for how they are meant to be used. Usually
|
||||
a feature flag is used when a portion of the application is under development or not ready for full release yet, such
|
||||
as new functionality or experimental ideas. In these cases, the feature name *should* be named with the `feature_*`
|
||||
convention and must be tagged with `isFeature: true` in the setting definition. By doing so, the feature will automatically
|
||||
appear in the "labs" section of the user's settings.
|
||||
|
||||
Although features have levels and a default value, the calculation of those options is blocked by the feature's state.
|
||||
A feature's state is determined from the `SdkConfig` and is a little complex. If `enableLabs` (a legacy flag) is `true`
|
||||
then the feature's state is `labs`, if it is `false`, the state is `disable`. If `enableLabs` is not set then the state
|
||||
is determined from the `features` config, such as in the following:
|
||||
Features can be controlled at the config level using the following structure:
|
||||
```json
|
||||
"features": {
|
||||
"feature_lazyloading": "labs"
|
||||
"feature_lazyloading": true
|
||||
}
|
||||
```
|
||||
In this example, `feature_lazyloading` is in the `labs` state. It may also be in the `enable` or `disable` state with a
|
||||
similar approach. If the state is invalid, the feature is in the `disable` state. A feature's levels are only calculated
|
||||
if it is in the `labs` state, therefore the default only applies in that scenario. If the state is `enable`, the feature
|
||||
is always-on.
|
||||
|
||||
Once a feature flag has served its purpose, it is generally recommended to remove it and the associated feature flag
|
||||
checks. This would enable the feature implicitly as it is part of the application now.
|
||||
When `true`, the user will see the feature as enabled. Similarly, when `false` the user will see the feature as disabled.
|
||||
The user will only be able to change/see these states if `showLabsSettings: true` is in the config.
|
||||
|
||||
### Determining if a feature is enabled
|
||||
|
||||
A simple call to `SettingsStore.isFeatureEnabled` will tell you if the feature is enabled. This will perform all the
|
||||
required calculations to determine if the feature is enabled based upon the configuration and user selection.
|
||||
Call `SettingsStore.getValue()` as you would for any other setting.
|
||||
|
||||
### Enabling a feature
|
||||
|
||||
Features can only be enabled if the feature is in the `labs` state, otherwise this is a no-op. To find the current set
|
||||
of features in the `labs` state, call `SettingsStore.getLabsFeatures`. To set the value, call
|
||||
`SettingsStore.setFeatureEnabled`.
|
||||
Call `SettingsStore.setValue("feature_name", null, SettingLevel.DEVICE, true)`.
|
||||
|
||||
### A note on UI features
|
||||
|
||||
UI features are a different concept to plain features. Instead of being representative of unstable or
|
||||
unpredicatable behaviour, they are logical chunks of UI which can be disabled by deployments for ease
|
||||
of understanding with users. They are simply represented as boring settings with a convention of being
|
||||
named as `UIFeature.$location` where `$location` is a rough descriptor of what is toggled, such as
|
||||
`URLPreviews` or `Communities`.
|
||||
|
||||
UI features also tend to have their own setting controller (see below) to manipulate settings which might
|
||||
be affected by the UI feature being disabled. For example, if URL previews are disabled as a UI feature
|
||||
then the URL preview options will use the `UIFeatureController` to ensure they remain disabled while the
|
||||
UI feature is disabled.
|
||||
|
||||
## Setting controllers
|
||||
|
||||
|
@ -162,7 +142,7 @@ kept up to date with the setting where it is otherwise not possible. An example
|
|||
they can only be considered enabled if the platform supports notifications, and enabling notifications requires
|
||||
additional steps to actually enable notifications.
|
||||
|
||||
For more information, see `src/settings/controllers/SettingController.js`.
|
||||
For more information, see `src/settings/controllers/SettingController.ts`.
|
||||
|
||||
|
||||
## Local echo
|
||||
|
@ -222,7 +202,7 @@ The `SettingsStore` uses the hardcoded `LEVEL_ORDER` constant to ensure that it
|
|||
The array is checked from left to right, simulating the behaviour of overriding values from the higher levels. Each
|
||||
level should be defined in this array, including `default`.
|
||||
|
||||
Handlers (`src/settings/handlers/SettingsHandler.js`) represent a single level and are responsible for getting and
|
||||
Handlers (`src/settings/handlers/SettingsHandler.ts`) represent a single level and are responsible for getting and
|
||||
setting values at that level. Handlers also provide additional information to the `SettingsStore` such as if the level
|
||||
is supported or if the current user may set values at the level. The `SettingsStore` will use the handler to enforce
|
||||
checks and manipulate settings. Handlers are also responsible for dealing with migration patterns or legacy settings for
|
||||
|
@ -230,7 +210,7 @@ their level (for example, a setting being renamed or using a different key from
|
|||
Handlers are provided to the `SettingsStore` via the `LEVEL_HANDLERS` constant. `SettingsStore` will optimize lookups by
|
||||
only considering handlers that are supported on the platform.
|
||||
|
||||
Local echo is achieved through `src/settings/handlers/LocalEchoWrapper.js` which acts as a wrapper around a given
|
||||
Local echo is achieved through `src/settings/handlers/LocalEchoWrapper.ts` which acts as a wrapper around a given
|
||||
handler. This is automatically applied to all defined `LEVEL_HANDLERS` and proxies the calls to the wrapped handler
|
||||
where possible. The echo is achieved by a simple object cache stored within the class itself. The cache is invalidated
|
||||
immediately upon the proxied save call succeeding or failing.
|
||||
|
@ -240,20 +220,7 @@ Controllers are notified of changes by the `SettingsStore`, and are given the op
|
|||
|
||||
### Features
|
||||
|
||||
Features automatically get considered as `disabled` if they are not listed in the `SdkConfig` or `enableLabs` is
|
||||
false/not set. Features are always checked against the configuration before going through the level order as they have
|
||||
the option of being forced-on or forced-off for the application. This is done by the `features` section and looks
|
||||
something like this:
|
||||
|
||||
```
|
||||
"features": {
|
||||
"feature_groups": "enable",
|
||||
"feature_pinning": "disable", // the default
|
||||
"feature_presence": "labs"
|
||||
}
|
||||
```
|
||||
|
||||
If `enableLabs` is true in the configuration, the default for features becomes `"labs"`.
|
||||
See above for feature reference.
|
||||
|
||||
### Watchers
|
||||
|
||||
|
@ -271,4 +238,3 @@ In practice, handlers which rely on remote changes (account data, room events, e
|
|||
generalized `WatchManager` - a class specifically designed to deduplicate the logic of managing watchers. The handlers
|
||||
which are localized to the local client (device) generally just trigger the `WatchManager` when they manipulate the
|
||||
setting themselves as there's nothing to really 'watch'.
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ 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.
|
||||
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 Element 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.
|
||||
Its function is to create an Object URL for the user/browser to use but bound to an origin different to that of the Element 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:
|
||||
|
||||
|
@ -24,4 +24,4 @@ It exposes a function over a postMessage API, when sent an object with the match
|
|||
|
||||
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.
|
||||
It is expected that this target be available at `usercontent/` relative to the root of the app, this can be seen in element-web's webpack config.
|
||||
|
|
60
docs/widget-layouts.md
Normal file
60
docs/widget-layouts.md
Normal file
|
@ -0,0 +1,60 @@
|
|||
# Widget layout support
|
||||
|
||||
Rooms can have a default widget layout to auto-pin certain widgets, make the container different
|
||||
sizes, etc. These are defined through the `io.element.widgets.layout` state event (empty state key).
|
||||
|
||||
Full example content:
|
||||
```json5
|
||||
{
|
||||
"widgets": {
|
||||
"first-widget-id": {
|
||||
"container": "top",
|
||||
"index": 0,
|
||||
"width": 60,
|
||||
"height": 40
|
||||
},
|
||||
"second-widget-id": {
|
||||
"container": "right"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As shown, there are two containers possible for widgets. These containers have different behaviour
|
||||
and interpret the other options differently.
|
||||
|
||||
## `top` container
|
||||
|
||||
This is the "App Drawer" or any pinned widgets in a room. This is by far the most versatile container
|
||||
though does introduce potential usability issues upon members of the room (widgets take up space and
|
||||
therefore fewer messages can be shown).
|
||||
|
||||
The `index` for a widget determines which order the widgets show up in from left to right. Widgets
|
||||
without an `index` will show up as the rightmost widgets. Tiebreaks (same `index` or multiple defined
|
||||
without an `index`) are resolved by comparing widget IDs. A maximum of 3 widgets can be in the top
|
||||
container - any which exceed this will be ignored (placed into the `right` container). Smaller numbers
|
||||
represent leftmost widgets.
|
||||
|
||||
The `width` is relative width within the container in percentage points. This will be clamped to a
|
||||
range of 0-100 (inclusive). The widgets will attempt to scale to relative proportions when more than
|
||||
100% space is allocated. For example, if 3 widgets are defined at 40% width each then the client will
|
||||
attempt to show them at 33% width each.
|
||||
|
||||
Note that the client may impose minimum widths on the widgets, such as a 10% minimum to avoid pinning
|
||||
hidden widgets. In general, widgets defined in the 30-70% range each will be free of these restrictions.
|
||||
|
||||
The `height` is not in fact applied per-widget but is recorded per-widget for potential future
|
||||
capabilities in future containers. The top container will take the tallest `height` and use that for
|
||||
the height of the whole container, and thus all widgets in that container. The `height` is relative
|
||||
to the container, like with `width`, meaning that 100% will consume as much space as the client is
|
||||
willing to sacrifice to the widget container. Like with `width`, the client may impose minimums to avoid
|
||||
the container being uselessly small. Heights in the 30-100% range are generally acceptable. The height
|
||||
is also clamped to be within 0-100, inclusive.
|
||||
|
||||
## `right` container
|
||||
|
||||
This is the default container and has no special configuration. Widgets which overflow from the top
|
||||
container will be put in this container instead. Putting a widget in the right container does not
|
||||
automatically show it - it only mentions that widgets should not be in another container.
|
||||
|
||||
The behaviour of this container may change in the future.
|
229
package.json
229
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "matrix-react-sdk",
|
||||
"version": "2.3.1",
|
||||
"version": "3.25.0",
|
||||
"description": "SDK for matrix.org using React",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
|
@ -23,18 +23,17 @@
|
|||
"package.json"
|
||||
],
|
||||
"bin": {
|
||||
"reskindex": "scripts/reskindex.js",
|
||||
"matrix-gen-i18n": "scripts/gen-i18n.js",
|
||||
"matrix-prune-i18n": "scripts/prune-i18n.js"
|
||||
"reskindex": "scripts/reskindex.js"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"typings": "./lib/index.d.ts",
|
||||
"main": "./src/index.js",
|
||||
"matrix_src_main": "./src/index.js",
|
||||
"matrix_lib_main": "./lib/index.js",
|
||||
"matrix_lib_typings": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"prepare": "yarn build",
|
||||
"prepublishOnly": "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",
|
||||
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && matrix-gen-i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
|
||||
"reskindex": "node scripts/reskindex.js -h header",
|
||||
"reskindex:watch": "node scripts/reskindex.js -h header -w",
|
||||
"rethemendex": "res/css/rethemendex.sh",
|
||||
|
@ -45,126 +44,160 @@
|
|||
"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": "yarn lint:types && yarn lint:js && yarn lint:style",
|
||||
"lint:js": "eslint --max-warnings 0 src test",
|
||||
"lint:types": "tsc --noEmit --jsx react",
|
||||
"lint:style": "stylelint 'res/css/**/*.scss'",
|
||||
"test": "jest",
|
||||
"test:e2e": "./test/end-to-end-tests/run.sh --riot-url http://localhost:8080"
|
||||
"test:e2e": "./test/end-to-end-tests/run.sh --app-url http://localhost:8080",
|
||||
"coverage": "yarn test --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.3",
|
||||
"blueimp-canvas-to-blob": "^3.5.0",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"await-lock": "^2.1.0",
|
||||
"blurhash": "^1.1.3",
|
||||
"browser-encrypt-attachment": "^0.3.0",
|
||||
"browser-request": "^0.3.3",
|
||||
"classnames": "^2.1.2",
|
||||
"commonmark": "^0.28.1",
|
||||
"counterpart": "^0.18.0",
|
||||
"create-react-class": "^15.6.0",
|
||||
"diff-dom": "^4.1.3",
|
||||
"diff-match-patch": "^1.0.4",
|
||||
"emojibase-data": "^5.0.1",
|
||||
"emojibase-regex": "^4.0.1",
|
||||
"cheerio": "^1.0.0-rc.9",
|
||||
"classnames": "^2.2.6",
|
||||
"commonmark": "^0.29.3",
|
||||
"counterpart": "^0.18.6",
|
||||
"diff-dom": "^4.2.2",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"emojibase-data": "^5.1.1",
|
||||
"emojibase-regex": "^4.1.1",
|
||||
"escape-html": "^1.0.3",
|
||||
"file-saver": "^1.3.3",
|
||||
"filesize": "3.5.6",
|
||||
"file-saver": "^2.0.5",
|
||||
"filesize": "6.1.0",
|
||||
"flux": "2.1.1",
|
||||
"focus-visible": "^5.0.2",
|
||||
"fuse.js": "^2.2.0",
|
||||
"gfm.css": "^1.1.1",
|
||||
"focus-visible": "^5.2.0",
|
||||
"gfm.css": "^1.1.2",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"highlight.js": "^9.15.8",
|
||||
"html-entities": "^1.2.1",
|
||||
"is-ip": "^2.0.0",
|
||||
"linkifyjs": "^2.1.6",
|
||||
"lodash": "^4.17.14",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"minimist": "^1.2.0",
|
||||
"pako": "^1.0.5",
|
||||
"highlight.js": "^10.5.0",
|
||||
"html-entities": "^1.4.0",
|
||||
"is-ip": "^3.1.0",
|
||||
"katex": "^0.12.0",
|
||||
"linkifyjs": "^2.1.9",
|
||||
"lodash": "^4.17.20",
|
||||
"matrix-js-sdk": "12.0.1",
|
||||
"matrix-widget-api": "^0.1.0-beta.15",
|
||||
"minimist": "^1.2.5",
|
||||
"opus-recorder": "^8.0.3",
|
||||
"pako": "^2.0.3",
|
||||
"parse5": "^6.0.1",
|
||||
"png-chunks-extract": "^1.0.0",
|
||||
"project-name-generator": "^2.1.7",
|
||||
"prop-types": "^15.5.8",
|
||||
"prop-types": "^15.7.2",
|
||||
"qrcode": "^1.4.4",
|
||||
"qrcode-react": "^0.1.16",
|
||||
"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",
|
||||
"resize-observer-polyfill": "^1.5.0",
|
||||
"sanitize-html": "^1.18.4",
|
||||
"text-encoding-utf-8": "^1.0.1",
|
||||
"re-resizable": "^6.9.0",
|
||||
"react": "^17.0.2",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-blurhash": "^0.1.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-focus-lock": "^2.5.0",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"rfc4648": "^1.4.0",
|
||||
"sanitize-html": "^2.3.2",
|
||||
"tar-js": "^0.3.0",
|
||||
"url": "^0.11.0",
|
||||
"velocity-animate": "^1.5.2",
|
||||
"what-input": "^5.2.6",
|
||||
"what-input": "^5.2.10",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@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",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/eslint-parser": "^7.12.10",
|
||||
"@babel/eslint-plugin": "^7.12.10",
|
||||
"@babel/parser": "^7.12.11",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||
"@babel/plugin-proposal-decorators": "^7.12.12",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.12.1",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.12.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
|
||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||
"@babel/preset-env": "^7.12.11",
|
||||
"@babel/preset-react": "^7.12.10",
|
||||
"@babel/preset-typescript": "^7.12.7",
|
||||
"@babel/register": "^7.12.10",
|
||||
"@babel/traverse": "^7.12.12",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@peculiar/webcrypto": "^1.1.4",
|
||||
"@sinonjs/fake-timers": "^7.0.2",
|
||||
"@types/classnames": "^2.2.11",
|
||||
"@types/commonmark": "^0.27.4",
|
||||
"@types/counterpart": "^0.18.1",
|
||||
"@types/css-font-loading-module": "^0.0.6",
|
||||
"@types/diff-match-patch": "^1.0.32",
|
||||
"@types/flux": "^3.1.9",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/linkifyjs": "^2.1.3",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/modernizr": "^3.5.3",
|
||||
"@types/react": "16.9",
|
||||
"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",
|
||||
"file-loader": "^3.0.1",
|
||||
"flow-parser": "^0.57.3",
|
||||
"glob": "^5.0.14",
|
||||
"jest": "^24.9.0",
|
||||
"lolex": "^5.1.2",
|
||||
"@types/node": "^14.14.22",
|
||||
"@types/pako": "^1.0.1",
|
||||
"@types/parse5": "^6.0.0",
|
||||
"@types/qrcode": "^1.3.5",
|
||||
"@types/react": "^17.0.2",
|
||||
"@types/react-beautiful-dnd": "^13.0.0",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/sanitize-html": "^2.3.1",
|
||||
"@types/zxcvbn": "^4.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.17.0",
|
||||
"@typescript-eslint/parser": "^4.17.0",
|
||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.1",
|
||||
"babel-jest": "^26.6.3",
|
||||
"chokidar": "^3.5.1",
|
||||
"concurrently": "^5.3.0",
|
||||
"enzyme": "^3.11.0",
|
||||
"eslint": "7.18.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-matrix-org": "github:matrix-org/eslint-plugin-matrix-org#main",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"glob": "^7.1.6",
|
||||
"jest": "^26.6.3",
|
||||
"jest-canvas-mock": "^2.3.0",
|
||||
"jest-environment-jsdom-sixteen": "^1.0.3",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"matrix-mock-request": "^1.2.3",
|
||||
"matrix-react-test-utils": "^0.2.2",
|
||||
"react-test-renderer": "^16.9.0",
|
||||
"rimraf": "^2.4.3",
|
||||
"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"
|
||||
"matrix-react-test-utils": "^0.2.3",
|
||||
"matrix-web-i18n": "github:matrix-org/matrix-web-i18n",
|
||||
"react-test-renderer": "^17.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stylelint": "^13.9.0",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-scss": "^3.18.0",
|
||||
"typescript": "^4.1.3",
|
||||
"walk": "^2.3.14"
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "./__test-utils__/environment.js",
|
||||
"testMatch": [
|
||||
"<rootDir>/test/**/*-test.js"
|
||||
"<rootDir>/test/**/*-test.[jt]s?(x)"
|
||||
],
|
||||
"setupFiles": [
|
||||
"jest-canvas-mock"
|
||||
],
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/test/setupTests.js"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"\\.(gif|png|svg|ttf|woff2)$": "<rootDir>/__mocks__/imageMock.js",
|
||||
"\\$webapp/i18n/languages.json": "<rootDir>/__mocks__/languages.json"
|
||||
"\\$webapp/i18n/languages.json": "<rootDir>/__mocks__/languages.json",
|
||||
"decoderWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
|
||||
"decoderWorker\\.min\\.wasm": "<rootDir>/__mocks__/empty.js",
|
||||
"waveWorker\\.min\\.js": "<rootDir>/__mocks__/empty.js",
|
||||
"workers/(.+)\\.worker\\.ts": "<rootDir>/__mocks__/workerMock.js"
|
||||
},
|
||||
"transformIgnorePatterns": [
|
||||
"/node_modules/(?!matrix-js-sdk).+$"
|
||||
],
|
||||
"collectCoverageFrom": [
|
||||
"<rootDir>/src/**/*.{js,ts,tsx}"
|
||||
],
|
||||
"coverageReporters": [
|
||||
"text"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ set -e
|
|||
|
||||
cd `dirname $0`
|
||||
|
||||
# This link seems to get eaten by the release process, so ensure it exists.
|
||||
yarn link matrix-js-sdk
|
||||
|
||||
for i in matrix-js-sdk
|
||||
do
|
||||
echo "Checking version of $i..."
|
||||
|
@ -29,9 +32,7 @@ do
|
|||
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
|
||||
git commit -m "Upgrade $i to $latestver"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -17,9 +17,27 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
@import "./_font-sizes.scss";
|
||||
@import "./_font-weights.scss";
|
||||
|
||||
$hover-transition: 0.08s cubic-bezier(.46, .03, .52, .96); // quadratic
|
||||
|
||||
$EventTile_e2e_state_indicator_width: 4px;
|
||||
|
||||
$MessageTimestamp_width: 46px; /* 8 + 30 (avatar) + 8 */
|
||||
$MessageTimestamp_width_hover: calc($MessageTimestamp_width - 2 * $EventTile_e2e_state_indicator_width);
|
||||
|
||||
:root {
|
||||
font-size: 15px;
|
||||
font-size: 10px;
|
||||
|
||||
--transition-short: .1s;
|
||||
--transition-standard: .3s;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
:root {
|
||||
--transition-short: 0;
|
||||
--transition-standard: 0;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -27,6 +45,8 @@ html {
|
|||
N.B. Breaks things when we have legitimate horizontal overscroll */
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
// Stop similar overscroll bounce in Firefox Nightly for macOS
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -38,7 +58,7 @@ body {
|
|||
margin: 0px;
|
||||
|
||||
// needed to match the designs correctly on macOS
|
||||
// see https://github.com/vector-im/riot-web/issues/11425
|
||||
// see https://github.com/vector-im/element-web/issues/11425
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
@ -57,6 +77,10 @@ pre, code {
|
|||
color: $accent-color;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
|
||||
b {
|
||||
// On Firefox, the default weight for `<b>` is `bolder` which results in no bold
|
||||
// effect since we only have specific weights of our fonts available.
|
||||
|
@ -160,11 +184,9 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
background-color: transparent;
|
||||
color: $input-darker-fg-color;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $dialog-close-fg-color;
|
||||
// these things should probably not be defined
|
||||
// globally
|
||||
border: 1px solid rgba($primary-fg-color, .1);
|
||||
// these things should probably not be defined globally
|
||||
margin: 9px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_textinput {
|
||||
|
@ -175,7 +197,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
:not(.mx_textinput):not(.mx_Field):not(.mx_no_textinput) > input[type=text]::placeholder,
|
||||
:not(.mx_textinput):not(.mx_Field):not(.mx_no_textinput) > input[type=search]::placeholder,
|
||||
.mx_textinput input::placeholder {
|
||||
color: $roomsublist-label-fg-color;
|
||||
color: rgba($input-darker-fg-color, .75);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,12 +229,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
border: 0;
|
||||
}
|
||||
|
||||
/* applied to side-panels and messagepanel when in RoomSettings */
|
||||
.mx_fadable {
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
// These are magic constants which are excluded from tinting, to let themes
|
||||
// (which only have CSS, unlike skins) tell the app what their non-tinted
|
||||
// colourscheme is by inspecting the stylesheet DOM.
|
||||
|
@ -227,7 +243,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
}
|
||||
|
||||
#mx_theme_tertiaryAccentColor {
|
||||
color: $roomsublist-label-bg-color;
|
||||
color: $tertiary-accent-color;
|
||||
}
|
||||
|
||||
/* Expected z-indexes for dialogs:
|
||||
|
@ -261,10 +277,10 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
font-weight: 300;
|
||||
font-size: $font-15px;
|
||||
position: relative;
|
||||
padding: 25px 30px 30px 30px;
|
||||
padding: 24px;
|
||||
max-height: 80%;
|
||||
box-shadow: 2px 15px 30px 0 $dialog-shadow-color;
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
@ -275,6 +291,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
|
||||
.mx_Dialog_staticWrapper .mx_Dialog {
|
||||
z-index: 4010;
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.mx_Dialog_background {
|
||||
|
@ -299,7 +316,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
}
|
||||
|
||||
.mx_Dialog_lightbox .mx_Dialog_background {
|
||||
opacity: 0.85;
|
||||
opacity: $lightbox-background-bg-opacity;
|
||||
background-color: $lightbox-background-bg-color;
|
||||
}
|
||||
|
||||
|
@ -311,6 +328,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
pointer-events: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_Dialog_header {
|
||||
|
@ -319,7 +337,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
}
|
||||
|
||||
.mx_Dialog_titleImage {
|
||||
vertical-align: middle;
|
||||
vertical-align: sub;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
margin-left: -2px;
|
||||
|
@ -328,6 +346,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
|
||||
.mx_Dialog_title {
|
||||
font-size: $font-22px;
|
||||
font-weight: $font-semi-bold;
|
||||
line-height: $font-36px;
|
||||
color: $dialog-title-fg-color;
|
||||
}
|
||||
|
@ -335,6 +354,9 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
.mx_Dialog_header.mx_Dialog_headerWithButton > .mx_Dialog_title {
|
||||
text-align: center;
|
||||
}
|
||||
.mx_Dialog_header.mx_Dialog_headerWithCancel > .mx_Dialog_title {
|
||||
margin-right: 20px; // leave space for the 'X' cancel button
|
||||
}
|
||||
|
||||
.mx_Dialog_title.danger {
|
||||
color: $warning-color;
|
||||
|
@ -350,8 +372,8 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
background-color: $dialog-close-fg-color;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 0px;
|
||||
top: 10px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
|
@ -364,6 +386,11 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
.mx_Dialog_buttons {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
|
||||
.mx_Dialog_buttons_additive {
|
||||
// The consumer is responsible for positioning their elements.
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: Our button style are a mess: buttons that happen to appear in dialogs get special styles applied
|
||||
|
@ -382,6 +409,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
border: 1px solid $accent-color;
|
||||
color: $accent-color;
|
||||
background-color: $button-secondary-bg-color;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.mx_Dialog button:last-child {
|
||||
|
@ -425,12 +453,16 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
border-radius: 8px;
|
||||
padding: 0px;
|
||||
box-shadow: none;
|
||||
|
||||
/* Don't show scroll-bars on spinner dialogs */
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
// TODO: Review mx_GeneralButton usage to see if it can use a different class
|
||||
// These classes were brought in from the old UserSettings and are included here to avoid
|
||||
// breaking the app.
|
||||
// Ref: https://github.com/vector-im/riot-web/issues/8420
|
||||
// Ref: https://github.com/vector-im/element-web/issues/8420
|
||||
.mx_GeneralButton {
|
||||
@mixin mx_DialogButton;
|
||||
display: inline;
|
||||
|
@ -472,54 +504,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
margin-top: 69px;
|
||||
}
|
||||
|
||||
.mx_Beta {
|
||||
color: red;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
background-color: white;
|
||||
padding: 0 4px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid darkred;
|
||||
cursor: help;
|
||||
transition-duration: 200ms;
|
||||
font-size: smaller;
|
||||
filter: opacity(0.5);
|
||||
}
|
||||
|
||||
.mx_Beta:hover {
|
||||
color: white;
|
||||
border: 1px solid gray;
|
||||
background-color: darkred;
|
||||
}
|
||||
|
||||
.mx_TintableSvgButton {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.mx_TintableSvgButton object {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.mx_TintableSvgButton span {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// username colors
|
||||
// used by SenderProfile & RoomPreviewBar
|
||||
.mx_Username_color1 {
|
||||
|
@ -578,3 +562,43 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
|||
// So it fits in the space provided by the page
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
@define-mixin ProgressBarColour $colour {
|
||||
color: $colour;
|
||||
&::-moz-progress-bar {
|
||||
background-color: $colour;
|
||||
}
|
||||
&::-webkit-progress-value {
|
||||
background-color: $colour;
|
||||
}
|
||||
}
|
||||
|
||||
@define-mixin ProgressBarBgColour $colour {
|
||||
background-color: $colour;
|
||||
&::-webkit-progress-bar {
|
||||
background-color: $colour;
|
||||
}
|
||||
}
|
||||
|
||||
@define-mixin ProgressBarBorderRadius $radius {
|
||||
border-radius: $radius;
|
||||
&::-moz-progress-bar {
|
||||
border-radius: $radius;
|
||||
}
|
||||
&::-webkit-progress-bar,
|
||||
&::-webkit-progress-value {
|
||||
border-radius: $radius;
|
||||
}
|
||||
}
|
||||
|
||||
@define-mixin unreal-focus {
|
||||
outline-width: 2px;
|
||||
outline-style: solid;
|
||||
outline-color: Highlight;
|
||||
|
||||
/* WebKit gets its native focus styles. */
|
||||
@media (-webkit-min-device-pixel-ratio: 0) {
|
||||
outline-color: -webkit-focus-ring-color;
|
||||
outline-style: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// autogenerated by rethemendex.sh
|
||||
@import "./_common.scss";
|
||||
@import "./_font-sizes.scss";
|
||||
@import "./_font-weights.scss";
|
||||
@import "./structures/_AutoHideScrollbar.scss";
|
||||
@import "./structures/_CompatibilityPage.scss";
|
||||
@import "./structures/_ContextualMenu.scss";
|
||||
|
@ -8,29 +9,39 @@
|
|||
@import "./structures/_CustomRoomTagPanel.scss";
|
||||
@import "./structures/_FilePanel.scss";
|
||||
@import "./structures/_GenericErrorPage.scss";
|
||||
@import "./structures/_GroupFilterPanel.scss";
|
||||
@import "./structures/_GroupView.scss";
|
||||
@import "./structures/_HeaderButtons.scss";
|
||||
@import "./structures/_HomePage.scss";
|
||||
@import "./structures/_LeftPanel.scss";
|
||||
@import "./structures/_LeftPanelWidget.scss";
|
||||
@import "./structures/_MainSplit.scss";
|
||||
@import "./structures/_MatrixChat.scss";
|
||||
@import "./structures/_MyGroups.scss";
|
||||
@import "./structures/_NonUrgentToastContainer.scss";
|
||||
@import "./structures/_NotificationPanel.scss";
|
||||
@import "./structures/_RightPanel.scss";
|
||||
@import "./structures/_RoomDirectory.scss";
|
||||
@import "./structures/_RoomSearch.scss";
|
||||
@import "./structures/_RoomStatusBar.scss";
|
||||
@import "./structures/_RoomSubList.scss";
|
||||
@import "./structures/_RoomView.scss";
|
||||
@import "./structures/_ScrollPanel.scss";
|
||||
@import "./structures/_SearchBox.scss";
|
||||
@import "./structures/_SpacePanel.scss";
|
||||
@import "./structures/_SpaceRoomDirectory.scss";
|
||||
@import "./structures/_SpaceRoomView.scss";
|
||||
@import "./structures/_TabbedView.scss";
|
||||
@import "./structures/_TagPanel.scss";
|
||||
@import "./structures/_ToastContainer.scss";
|
||||
@import "./structures/_TopLeftMenuButton.scss";
|
||||
@import "./structures/_UploadBar.scss";
|
||||
@import "./structures/_UserMenu.scss";
|
||||
@import "./structures/_ViewSource.scss";
|
||||
@import "./structures/auth/_CompleteSecurity.scss";
|
||||
@import "./structures/auth/_Login.scss";
|
||||
@import "./views/audio_messages/_AudioPlayer.scss";
|
||||
@import "./views/audio_messages/_PlayPauseButton.scss";
|
||||
@import "./views/audio_messages/_PlaybackContainer.scss";
|
||||
@import "./views/audio_messages/_SeekBar.scss";
|
||||
@import "./views/audio_messages/_Waveform.scss";
|
||||
@import "./views/auth/_AuthBody.scss";
|
||||
@import "./views/auth/_AuthButtons.scss";
|
||||
@import "./views/auth/_AuthFooter.scss";
|
||||
|
@ -41,79 +52,102 @@
|
|||
@import "./views/auth/_CountryDropdown.scss";
|
||||
@import "./views/auth/_InteractiveAuthEntryComponents.scss";
|
||||
@import "./views/auth/_LanguageSelector.scss";
|
||||
@import "./views/auth/_ServerConfig.scss";
|
||||
@import "./views/auth/_ServerTypeSelector.scss";
|
||||
@import "./views/auth/_PassphraseField.scss";
|
||||
@import "./views/auth/_Welcome.scss";
|
||||
@import "./views/avatars/_BaseAvatar.scss";
|
||||
@import "./views/avatars/_DecoratedRoomAvatar.scss";
|
||||
@import "./views/avatars/_MemberStatusMessageAvatar.scss";
|
||||
@import "./views/avatars/_WidgetAvatar.scss";
|
||||
@import "./views/beta/_BetaCard.scss";
|
||||
@import "./views/context_menus/_CallContextMenu.scss";
|
||||
@import "./views/context_menus/_IconizedContextMenu.scss";
|
||||
@import "./views/context_menus/_MessageContextMenu.scss";
|
||||
@import "./views/context_menus/_RoomTileContextMenu.scss";
|
||||
@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/_AddExistingToSpaceDialog.scss";
|
||||
@import "./views/dialogs/_AddressPickerDialog.scss";
|
||||
@import "./views/dialogs/_Analytics.scss";
|
||||
@import "./views/dialogs/_BetaFeedbackDialog.scss";
|
||||
@import "./views/dialogs/_BugReportDialog.scss";
|
||||
@import "./views/dialogs/_ChangelogDialog.scss";
|
||||
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
|
||||
@import "./views/dialogs/_CommunityPrototypeInviteDialog.scss";
|
||||
@import "./views/dialogs/_ConfirmUserActionDialog.scss";
|
||||
@import "./views/dialogs/_CreateCommunityPrototypeDialog.scss";
|
||||
@import "./views/dialogs/_CreateGroupDialog.scss";
|
||||
@import "./views/dialogs/_CreateRoomDialog.scss";
|
||||
@import "./views/dialogs/_DeactivateAccountDialog.scss";
|
||||
@import "./views/dialogs/_DeviceVerifyDialog.scss";
|
||||
@import "./views/dialogs/_DevtoolsDialog.scss";
|
||||
@import "./views/dialogs/_EncryptedEventDialog.scss";
|
||||
@import "./views/dialogs/_EditCommunityPrototypeDialog.scss";
|
||||
@import "./views/dialogs/_FeedbackDialog.scss";
|
||||
@import "./views/dialogs/_ForwardDialog.scss";
|
||||
@import "./views/dialogs/_GroupAddressPicker.scss";
|
||||
@import "./views/dialogs/_HostSignupDialog.scss";
|
||||
@import "./views/dialogs/_IncomingSasDialog.scss";
|
||||
@import "./views/dialogs/_InviteDialog.scss";
|
||||
@import "./views/dialogs/_KeyboardShortcutsDialog.scss";
|
||||
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
|
||||
@import "./views/dialogs/_ModalWidgetDialog.scss";
|
||||
@import "./views/dialogs/_NewSessionReviewDialog.scss";
|
||||
@import "./views/dialogs/_RegistrationEmailPromptDialog.scss";
|
||||
@import "./views/dialogs/_RoomSettingsDialog.scss";
|
||||
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
|
||||
@import "./views/dialogs/_RoomUpgradeDialog.scss";
|
||||
@import "./views/dialogs/_RoomUpgradeWarningDialog.scss";
|
||||
@import "./views/dialogs/_ServerOfflineDialog.scss";
|
||||
@import "./views/dialogs/_ServerPickerDialog.scss";
|
||||
@import "./views/dialogs/_SetEmailDialog.scss";
|
||||
@import "./views/dialogs/_SetMxIdDialog.scss";
|
||||
@import "./views/dialogs/_SetPasswordDialog.scss";
|
||||
@import "./views/dialogs/_SettingsDialog.scss";
|
||||
@import "./views/dialogs/_ShareDialog.scss";
|
||||
@import "./views/dialogs/_SlashCommandHelpDialog.scss";
|
||||
@import "./views/dialogs/_SpaceSettingsDialog.scss";
|
||||
@import "./views/dialogs/_TabbedIntegrationManagerDialog.scss";
|
||||
@import "./views/dialogs/_TermsDialog.scss";
|
||||
@import "./views/dialogs/_UnknownDeviceDialog.scss";
|
||||
@import "./views/dialogs/_UntrustedDeviceDialog.scss";
|
||||
@import "./views/dialogs/_UploadConfirmDialog.scss";
|
||||
@import "./views/dialogs/_UserSettingsDialog.scss";
|
||||
@import "./views/dialogs/_WidgetCapabilitiesPromptDialog.scss";
|
||||
@import "./views/dialogs/_WidgetOpenIDPermissionsDialog.scss";
|
||||
@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/dialogs/security/_AccessSecretStorageDialog.scss";
|
||||
@import "./views/dialogs/security/_CreateCrossSigningDialog.scss";
|
||||
@import "./views/dialogs/security/_CreateKeyBackupDialog.scss";
|
||||
@import "./views/dialogs/security/_CreateSecretStorageDialog.scss";
|
||||
@import "./views/dialogs/security/_KeyBackupFailedDialog.scss";
|
||||
@import "./views/dialogs/security/_RestoreKeyBackupDialog.scss";
|
||||
@import "./views/directory/_NetworkDropdown.scss";
|
||||
@import "./views/elements/_AccessibleButton.scss";
|
||||
@import "./views/elements/_AddressSelector.scss";
|
||||
@import "./views/elements/_AddressTile.scss";
|
||||
@import "./views/elements/_DesktopBuildsNotice.scss";
|
||||
@import "./views/elements/_DesktopCapturerSourcePicker.scss";
|
||||
@import "./views/elements/_DialPadBackspaceButton.scss";
|
||||
@import "./views/elements/_DirectorySearchBox.scss";
|
||||
@import "./views/elements/_Dropdown.scss";
|
||||
@import "./views/elements/_EditableItemList.scss";
|
||||
@import "./views/elements/_ErrorBoundary.scss";
|
||||
@import "./views/elements/_EventListSummary.scss";
|
||||
@import "./views/elements/_FacePile.scss";
|
||||
@import "./views/elements/_Field.scss";
|
||||
@import "./views/elements/_FormButton.scss";
|
||||
@import "./views/elements/_IconButton.scss";
|
||||
@import "./views/elements/_ImageView.scss";
|
||||
@import "./views/elements/_InfoTooltip.scss";
|
||||
@import "./views/elements/_InlineSpinner.scss";
|
||||
@import "./views/elements/_InteractiveTooltip.scss";
|
||||
@import "./views/elements/_InviteReason.scss";
|
||||
@import "./views/elements/_ManageIntegsButton.scss";
|
||||
@import "./views/elements/_MiniAvatarUploader.scss";
|
||||
@import "./views/elements/_PowerSelector.scss";
|
||||
@import "./views/elements/_ProgressBar.scss";
|
||||
@import "./views/elements/_QRCode.scss";
|
||||
@import "./views/elements/_ReplyThread.scss";
|
||||
@import "./views/elements/_ResizeHandle.scss";
|
||||
@import "./views/elements/_RichText.scss";
|
||||
@import "./views/elements/_RoleButton.scss";
|
||||
@import "./views/elements/_RoomAliasField.scss";
|
||||
@import "./views/elements/_SSOButtons.scss";
|
||||
@import "./views/elements/_ServerPicker.scss";
|
||||
@import "./views/elements/_Slider.scss";
|
||||
@import "./views/elements/_Spinner.scss";
|
||||
@import "./views/elements/_StyledCheckbox.scss";
|
||||
@import "./views/elements/_StyledRadioButton.scss";
|
||||
@import "./views/elements/_SyntaxHighlight.scss";
|
||||
@import "./views/elements/_TextWithTooltip.scss";
|
||||
@import "./views/elements/_ToggleSwitch.scss";
|
||||
|
@ -121,35 +155,43 @@
|
|||
@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";
|
||||
@import "./views/groups/_GroupUserSettings.scss";
|
||||
@import "./views/messages/_CreateEvent.scss";
|
||||
@import "./views/messages/_DateSeparator.scss";
|
||||
@import "./views/messages/_EventTileBubble.scss";
|
||||
@import "./views/messages/_MEmoteBody.scss";
|
||||
@import "./views/messages/_MFileBody.scss";
|
||||
@import "./views/messages/_MImageBody.scss";
|
||||
@import "./views/messages/_MImageReplyBody.scss";
|
||||
@import "./views/messages/_MJitsiWidgetEvent.scss";
|
||||
@import "./views/messages/_MNoticeBody.scss";
|
||||
@import "./views/messages/_MStickerBody.scss";
|
||||
@import "./views/messages/_MTextBody.scss";
|
||||
@import "./views/messages/_MVideoBody.scss";
|
||||
@import "./views/messages/_MVoiceMessageBody.scss";
|
||||
@import "./views/messages/_MediaBody.scss";
|
||||
@import "./views/messages/_MessageActionBar.scss";
|
||||
@import "./views/messages/_MessageTimestamp.scss";
|
||||
@import "./views/messages/_MjolnirBody.scss";
|
||||
@import "./views/messages/_ReactionsRow.scss";
|
||||
@import "./views/messages/_ReactionsRowButton.scss";
|
||||
@import "./views/messages/_ReactionsRowButtonTooltip.scss";
|
||||
@import "./views/messages/_RedactedBody.scss";
|
||||
@import "./views/messages/_RoomAvatarEvent.scss";
|
||||
@import "./views/messages/_SenderProfile.scss";
|
||||
@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/_BaseCard.scss";
|
||||
@import "./views/right_panel/_EncryptionInfo.scss";
|
||||
@import "./views/right_panel/_PinnedMessagesCard.scss";
|
||||
@import "./views/right_panel/_RoomSummaryCard.scss";
|
||||
@import "./views/right_panel/_UserInfo.scss";
|
||||
@import "./views/right_panel/_VerificationPanel.scss";
|
||||
@import "./views/right_panel/_WidgetCard.scss";
|
||||
@import "./views/room_settings/_AliasSettings.scss";
|
||||
@import "./views/room_settings/_ColorSettings.scss";
|
||||
@import "./views/rooms/_AppsDrawer.scss";
|
||||
@import "./views/rooms/_Autocomplete.scss";
|
||||
@import "./views/rooms/_AuxPanel.scss";
|
||||
|
@ -158,31 +200,33 @@
|
|||
@import "./views/rooms/_EditMessageComposer.scss";
|
||||
@import "./views/rooms/_EntityTile.scss";
|
||||
@import "./views/rooms/_EventTile.scss";
|
||||
@import "./views/rooms/_InviteOnlyIcon.scss";
|
||||
@import "./views/rooms/_GroupLayout.scss";
|
||||
@import "./views/rooms/_IRCLayout.scss";
|
||||
@import "./views/rooms/_JumpToBottomButton.scss";
|
||||
@import "./views/rooms/_LinkPreviewGroup.scss";
|
||||
@import "./views/rooms/_LinkPreviewWidget.scss";
|
||||
@import "./views/rooms/_MemberDeviceInfo.scss";
|
||||
@import "./views/rooms/_MemberInfo.scss";
|
||||
@import "./views/rooms/_MemberList.scss";
|
||||
@import "./views/rooms/_MessageComposer.scss";
|
||||
@import "./views/rooms/_MessageComposerFormatBar.scss";
|
||||
@import "./views/rooms/_NewRoomIntro.scss";
|
||||
@import "./views/rooms/_NotificationBadge.scss";
|
||||
@import "./views/rooms/_PinnedEventTile.scss";
|
||||
@import "./views/rooms/_PinnedEventsPanel.scss";
|
||||
@import "./views/rooms/_PresenceLabel.scss";
|
||||
@import "./views/rooms/_ReplyPreview.scss";
|
||||
@import "./views/rooms/_ReplyTile.scss";
|
||||
@import "./views/rooms/_RoomBreadcrumbs.scss";
|
||||
@import "./views/rooms/_RoomDropTarget.scss";
|
||||
@import "./views/rooms/_RoomHeader.scss";
|
||||
@import "./views/rooms/_RoomList.scss";
|
||||
@import "./views/rooms/_RoomPreviewBar.scss";
|
||||
@import "./views/rooms/_RoomRecoveryReminder.scss";
|
||||
@import "./views/rooms/_RoomSublist.scss";
|
||||
@import "./views/rooms/_RoomTile.scss";
|
||||
@import "./views/rooms/_RoomUpgradeWarningBar.scss";
|
||||
@import "./views/rooms/_SearchBar.scss";
|
||||
@import "./views/rooms/_SendMessageComposer.scss";
|
||||
@import "./views/rooms/_Stickers.scss";
|
||||
@import "./views/rooms/_TopUnreadMessagesBar.scss";
|
||||
@import "./views/rooms/_UserOnlineDot.scss";
|
||||
@import "./views/rooms/_VoiceRecordComposerTile.scss";
|
||||
@import "./views/rooms/_WhoIsTypingTile.scss";
|
||||
@import "./views/settings/_AvatarSetting.scss";
|
||||
@import "./views/settings/_CrossSigningPanel.scss";
|
||||
|
@ -190,25 +234,39 @@
|
|||
@import "./views/settings/_E2eAdvancedPanel.scss";
|
||||
@import "./views/settings/_EmailAddresses.scss";
|
||||
@import "./views/settings/_IntegrationManager.scss";
|
||||
@import "./views/settings/_KeyBackupPanel.scss";
|
||||
@import "./views/settings/_Notifications.scss";
|
||||
@import "./views/settings/_PhoneNumbers.scss";
|
||||
@import "./views/settings/_ProfileSettings.scss";
|
||||
@import "./views/settings/_SecureBackupPanel.scss";
|
||||
@import "./views/settings/_SetIdServer.scss";
|
||||
@import "./views/settings/_SetIntegrationManager.scss";
|
||||
@import "./views/settings/_SpellCheckLanguages.scss";
|
||||
@import "./views/settings/_UpdateCheckButton.scss";
|
||||
@import "./views/settings/tabs/_SettingsTab.scss";
|
||||
@import "./views/settings/tabs/room/_GeneralRoomSettingsTab.scss";
|
||||
@import "./views/settings/tabs/room/_RolesRoomSettingsTab.scss";
|
||||
@import "./views/settings/tabs/room/_SecurityRoomSettingsTab.scss";
|
||||
@import "./views/settings/tabs/user/_AppearanceUserSettingsTab.scss";
|
||||
@import "./views/settings/tabs/user/_GeneralUserSettingsTab.scss";
|
||||
@import "./views/settings/tabs/user/_HelpUserSettingsTab.scss";
|
||||
@import "./views/settings/tabs/user/_LabsUserSettingsTab.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";
|
||||
@import "./views/settings/tabs/user/_VoiceUserSettingsTab.scss";
|
||||
@import "./views/spaces/_SpaceBasicSettings.scss";
|
||||
@import "./views/spaces/_SpaceCreateMenu.scss";
|
||||
@import "./views/spaces/_SpacePublicShare.scss";
|
||||
@import "./views/terms/_InlineTermsAgreement.scss";
|
||||
@import "./views/toasts/_AnalyticsToast.scss";
|
||||
@import "./views/toasts/_NonUrgentEchoFailureToast.scss";
|
||||
@import "./views/verification/_VerificationShowSas.scss";
|
||||
@import "./views/voip/_CallContainer.scss";
|
||||
@import "./views/voip/_CallView.scss";
|
||||
@import "./views/voip/_IncomingCallbox.scss";
|
||||
@import "./views/voip/_VideoView.scss";
|
||||
@import "./views/voip/_CallViewForRoom.scss";
|
||||
@import "./views/voip/_CallPreview.scss";
|
||||
@import "./views/voip/_DialPad.scss";
|
||||
@import "./views/voip/_DialPadContextMenu.scss";
|
||||
@import "./views/voip/_DialPadModal.scss";
|
||||
@import "./views/voip/_VideoFeed.scss";
|
||||
|
|
|
@ -14,50 +14,60 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
$font-8px: 0.533rem;
|
||||
$font-9px: 0.600rem;
|
||||
$font-10px: 0.667rem;
|
||||
$font-10-4px: 0.693rem;
|
||||
$font-11px: 0.733rem;
|
||||
$font-12px: 0.800rem;
|
||||
$font-13px: 0.867rem;
|
||||
$font-14px: 0.933rem;
|
||||
$font-15px: 1.000rem;
|
||||
$font-16px: 1.067rem;
|
||||
$font-17px: 1.133rem;
|
||||
$font-18px: 1.200rem;
|
||||
$font-19px: 1.267rem;
|
||||
$font-20px: 1.333rem;
|
||||
$font-21px: 1.400rem;
|
||||
$font-22px: 1.467rem;
|
||||
$font-23px: 1.533rem;
|
||||
$font-24px: 1.600rem;
|
||||
$font-25px: 1.667rem;
|
||||
$font-26px: 1.733rem;
|
||||
$font-27px: 1.800rem;
|
||||
$font-28px: 1.867rem;
|
||||
$font-29px: 1.933rem;
|
||||
$font-30px: 2.000rem;
|
||||
$font-31px: 2.067rem;
|
||||
$font-32px: 2.133rem;
|
||||
$font-33px: 2.200rem;
|
||||
$font-34px: 2.267rem;
|
||||
$font-35px: 2.333rem;
|
||||
$font-36px: 2.400rem;
|
||||
$font-37px: 2.467rem;
|
||||
$font-38px: 2.533rem;
|
||||
$font-39px: 2.600rem;
|
||||
$font-40px: 2.667rem;
|
||||
$font-41px: 2.733rem;
|
||||
$font-42px: 2.800rem;
|
||||
$font-43px: 2.867rem;
|
||||
$font-44px: 2.933rem;
|
||||
$font-45px: 3.000rem;
|
||||
$font-46px: 3.067rem;
|
||||
$font-47px: 3.133rem;
|
||||
$font-48px: 3.200rem;
|
||||
$font-49px: 3.267rem;
|
||||
$font-50px: 3.333rem;
|
||||
$font-51px: 3.400rem;
|
||||
$font-52px: 3.467rem;
|
||||
$font-400px: 26.667rem;
|
||||
$font-1px: 0.1rem;
|
||||
$font-1-5px: 0.15rem;
|
||||
$font-2px: 0.2rem;
|
||||
$font-3px: 0.3rem;
|
||||
$font-4px: 0.4rem;
|
||||
$font-5px: 0.5rem;
|
||||
$font-6px: 0.6rem;
|
||||
$font-7px: 0.7rem;
|
||||
$font-8px: 0.8rem;
|
||||
$font-9px: 0.9rem;
|
||||
$font-10px: 1.0rem;
|
||||
$font-10-4px: 1.04rem;
|
||||
$font-11px: 1.1rem;
|
||||
$font-12px: 1.2rem;
|
||||
$font-13px: 1.3rem;
|
||||
$font-14px: 1.4rem;
|
||||
$font-15px: 1.5rem;
|
||||
$font-16px: 1.6rem;
|
||||
$font-17px: 1.7rem;
|
||||
$font-18px: 1.8rem;
|
||||
$font-19px: 1.9rem;
|
||||
$font-20px: 2.0rem;
|
||||
$font-21px: 2.1rem;
|
||||
$font-22px: 2.2rem;
|
||||
$font-23px: 2.3rem;
|
||||
$font-24px: 2.4rem;
|
||||
$font-25px: 2.5rem;
|
||||
$font-26px: 2.6rem;
|
||||
$font-27px: 2.7rem;
|
||||
$font-28px: 2.8rem;
|
||||
$font-29px: 2.9rem;
|
||||
$font-30px: 3.0rem;
|
||||
$font-31px: 3.1rem;
|
||||
$font-32px: 3.2rem;
|
||||
$font-33px: 3.3rem;
|
||||
$font-34px: 3.4rem;
|
||||
$font-35px: 3.5rem;
|
||||
$font-36px: 3.6rem;
|
||||
$font-37px: 3.7rem;
|
||||
$font-38px: 3.8rem;
|
||||
$font-39px: 3.9rem;
|
||||
$font-40px: 4.0rem;
|
||||
$font-41px: 4.1rem;
|
||||
$font-42px: 4.2rem;
|
||||
$font-43px: 4.3rem;
|
||||
$font-44px: 4.4rem;
|
||||
$font-45px: 4.5rem;
|
||||
$font-46px: 4.6rem;
|
||||
$font-47px: 4.7rem;
|
||||
$font-48px: 4.8rem;
|
||||
$font-49px: 4.9rem;
|
||||
$font-50px: 5.0rem;
|
||||
$font-51px: 5.1rem;
|
||||
$font-52px: 5.2rem;
|
||||
$font-78px: 7.8rem;
|
||||
$font-88px: 8.8rem;
|
||||
$font-400px: 40rem;
|
||||
|
|
17
res/css/_font-weights.scss
Normal file
17
res/css/_font-weights.scss
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
$font-semi-bold: 600;
|
|
@ -31,13 +31,14 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_ContextualMenu {
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 4px 4px 12px 0 $menu-box-shadow-color;
|
||||
background-color: $menu-bg-color;
|
||||
color: $primary-fg-color;
|
||||
position: absolute;
|
||||
font-size: $font-14px;
|
||||
z-index: 5001;
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_right {
|
||||
|
@ -115,8 +116,3 @@ limitations under the License.
|
|||
border-top: 8px solid $menu-bg-color;
|
||||
border-right: 8px solid transparent;
|
||||
}
|
||||
|
||||
.mx_ContextualMenu_spinner {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_LeftPanel_tagPanelContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
// TODO: Update design for custom tags to match new designs
|
||||
|
||||
.mx_CustomRoomTagPanel {
|
||||
background-color: $tagpanel-bg-color;
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
max-height: 40vh;
|
||||
}
|
||||
|
||||
|
@ -50,7 +47,7 @@ limitations under the License.
|
|||
background-color: $accent-color-alt;
|
||||
width: 5px;
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
left: -9px;
|
||||
border-radius: 0 3px 3px 0;
|
||||
top: 2px; // 10 [padding-top] - (56 - 40)/2
|
||||
top: 5px; // just feels right (see comment above about designs needing to be updated)
|
||||
}
|
||||
|
|
|
@ -22,7 +22,13 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_FilePanel .mx_RoomView_messageListWrapper {
|
||||
margin-right: 20px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mx_FilePanel .mx_RoomView_MessageList {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_FilePanel .mx_RoomView_MessageList h2 {
|
||||
|
@ -41,13 +47,19 @@ limitations under the License.
|
|||
|
||||
.mx_FilePanel .mx_EventTile {
|
||||
word-break: break-word;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.mx_FilePanel .mx_EventTile .mx_MImageBody {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.mx_FilePanel .mx_EventTile .mx_MFileBody {
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
|
||||
.mx_FilePanel .mx_EventTile .mx_MFileBody_download {
|
||||
padding-top: 8px;
|
||||
display: flex;
|
||||
font-size: $font-14px;
|
||||
color: $event-timestamp-color;
|
||||
|
@ -60,7 +72,7 @@ limitations under the License.
|
|||
|
||||
.mx_FilePanel .mx_EventTile .mx_MImageBody_size {
|
||||
flex: 1 0 0;
|
||||
font-size: $font-11px;
|
||||
font-size: $font-14px;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -80,7 +92,7 @@ limitations under the License.
|
|||
flex: 1 1 auto;
|
||||
line-height: initial;
|
||||
padding: 0px;
|
||||
font-size: $font-11px;
|
||||
font-size: $font-14px;
|
||||
opacity: 1.0;
|
||||
color: $event-timestamp-color;
|
||||
}
|
||||
|
@ -90,7 +102,7 @@ limitations under the License.
|
|||
text-align: right;
|
||||
visibility: visible;
|
||||
position: initial;
|
||||
font-size: $font-11px;
|
||||
font-size: $font-14px;
|
||||
opacity: 1.0;
|
||||
color: $event-timestamp-color;
|
||||
}
|
||||
|
@ -109,3 +121,7 @@ limitations under the License.
|
|||
.mx_FilePanel .mx_EventTile:hover .mx_EventTile_line {
|
||||
background-color: $primary-bg-color;
|
||||
}
|
||||
|
||||
.mx_FilePanel_empty::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/files.svg');
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_TagPanel {
|
||||
.mx_GroupFilterPanel {
|
||||
flex: 1;
|
||||
background-color: $tagpanel-bg-color;
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
|
@ -26,68 +26,98 @@ limitations under the License.
|
|||
min-height: 0;
|
||||
}
|
||||
|
||||
.mx_TagPanel_items_selected {
|
||||
.mx_GroupFilterPanel_items_selected {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagPanel_clearButton_container {
|
||||
/* Constant height within flex mx_TagPanel */
|
||||
height: 70px;
|
||||
width: 60px;
|
||||
|
||||
flex: none;
|
||||
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagPanel_clearButton object {
|
||||
/* Same as .mx_SearchBox padding-top */
|
||||
margin-top: 24px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagPanel_divider {
|
||||
.mx_GroupFilterPanel .mx_GroupFilterPanel_divider {
|
||||
height: 0px;
|
||||
width: 42px;
|
||||
border-bottom: 1px solid $panel-divider-color;
|
||||
display: none;
|
||||
width: 90%;
|
||||
border: none;
|
||||
border-bottom: 1px solid $groupFilterPanel-divider-color;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagPanel_scroller {
|
||||
.mx_GroupFilterPanel .mx_GroupFilterPanel_scroller {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagPanel_tagTileContainer {
|
||||
.mx_GroupFilterPanel .mx_GroupFilterPanel_tagTileContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
height: 100%;
|
||||
padding-top: 6px;
|
||||
}
|
||||
.mx_TagPanel .mx_TagPanel_tagTileContainer > div {
|
||||
height: 40px;
|
||||
padding: 10px 0 9px 0;
|
||||
.mx_GroupFilterPanel .mx_GroupFilterPanel_tagTileContainer > div {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagTile {
|
||||
margin: 9px 0;
|
||||
.mx_GroupFilterPanel .mx_TagTile {
|
||||
// opacity: 0.5;
|
||||
position: relative;
|
||||
|
||||
.mx_BetaDot {
|
||||
position: absolute;
|
||||
right: -13px;
|
||||
top: -11px;
|
||||
}
|
||||
}
|
||||
.mx_TagPanel .mx_TagTile:focus,
|
||||
.mx_TagPanel .mx_TagTile:hover,
|
||||
.mx_TagPanel .mx_TagTile.mx_TagTile_selected {
|
||||
|
||||
.mx_GroupFilterPanel .mx_TagTile.mx_TagTile_prototype {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.mx_GroupFilterPanel .mx_TagTile:focus,
|
||||
.mx_GroupFilterPanel .mx_TagTile:hover,
|
||||
.mx_GroupFilterPanel .mx_TagTile.mx_TagTile_selected {
|
||||
// opacity: 1;
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagTile_plus {
|
||||
.mx_GroupFilterPanel .mx_TagTile.mx_TagTile_selected_prototype {
|
||||
background-color: $primary-bg-color;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.mx_TagTile_selected_prototype {
|
||||
.mx_TagTile_homeIcon::before {
|
||||
background-color: $primary-fg-color; // dark-on-light
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TagTile:not(.mx_TagTile_selected_prototype) .mx_TagTile_homeIcon {
|
||||
background-color: $roomheader-addroom-bg-color;
|
||||
border-radius: 48px;
|
||||
|
||||
&::before {
|
||||
background-color: $roomheader-addroom-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TagTile_homeIcon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
mask-image: url('$(res)/img/element-icons/home.svg');
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 21px;
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
top: calc(50% - 16px);
|
||||
left: calc(50% - 16px);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_GroupFilterPanel .mx_TagTile_plus {
|
||||
margin-bottom: 12px;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border-radius: 20px;
|
||||
background-color: $roomheader-addroom-bg-color;
|
||||
position: relative;
|
||||
|
@ -108,18 +138,17 @@ limitations under the License.
|
|||
}
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagTile.mx_TagTile_selected::before {
|
||||
.mx_GroupFilterPanel .mx_TagTile.mx_TagTile_selected::before {
|
||||
content: '';
|
||||
height: 56px;
|
||||
height: 100%;
|
||||
background-color: $accent-color;
|
||||
width: 5px;
|
||||
width: 4px;
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
left: -12px;
|
||||
border-radius: 0 3px 3px 0;
|
||||
top: -8px; // (56 - 40)/2
|
||||
}
|
||||
|
||||
.mx_TagPanel .mx_TagTile.mx_AccessibleButton:focus {
|
||||
.mx_GroupFilterPanel .mx_TagTile.mx_AccessibleButton:focus {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
|
@ -159,7 +188,7 @@ limitations under the License.
|
|||
font-weight: 600;
|
||||
font-size: $font-14px;
|
||||
padding: 0 5px;
|
||||
background-color: $roomtile-name-color;
|
||||
background-color: $muted-fg-color;
|
||||
}
|
||||
|
||||
.mx_TagTile_badgeHighlight {
|
|
@ -29,12 +29,12 @@ limitations under the License.
|
|||
align-items: center;
|
||||
display: flex;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
.mx_GroupView_header_view {
|
||||
border-bottom: 1px solid $primary-hairline-color;
|
||||
padding-bottom: 0px;
|
||||
padding-left: 19px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
|
@ -63,11 +63,11 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_GroupHeader_editButton::before {
|
||||
mask-image: url('$(res)/img/feather-customised/settings.svg');
|
||||
mask-image: url('$(res)/img/element-icons/settings.svg');
|
||||
}
|
||||
|
||||
.mx_GroupHeader_shareButton::before {
|
||||
mask-image: url('$(res)/img/icons-share.svg');
|
||||
mask-image: url('$(res)/img/element-icons/room/share.svg');
|
||||
}
|
||||
|
||||
.mx_GroupView_hostingSignup img {
|
||||
|
@ -182,6 +182,7 @@ limitations under the License.
|
|||
|
||||
.mx_GroupView_body {
|
||||
flex-grow: 1;
|
||||
margin: 0 24px;
|
||||
}
|
||||
|
||||
.mx_GroupView_rooms {
|
||||
|
@ -250,6 +251,7 @@ limitations under the License.
|
|||
.mx_GroupView_membershipSubSection {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_GroupView_membershipSubSection .mx_Spinner {
|
||||
|
@ -321,7 +323,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_GroupView_featuredThing .mx_BaseAvatar {
|
||||
/* To prevent misalignment with mx_TintableSvg (in addButton) */
|
||||
/* To prevent misalignment with img (in addButton) */
|
||||
vertical-align: initial;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,19 @@ limitations under the License.
|
|||
display: flex;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_buttons + .mx_HeaderButtons {
|
||||
// remove the | separator line for when next to RoomHeaderButtons
|
||||
// TODO: remove this once when we redo communities and make the right panel similar to the new rooms one
|
||||
&::before {
|
||||
content: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_HeaderButtons::before {
|
||||
content: "";
|
||||
background-color: $header-divider-color;
|
||||
opacity: 0.5;
|
||||
margin: 0 15px;
|
||||
margin: 6px 8px;
|
||||
border-radius: 1px;
|
||||
width: 1px;
|
||||
}
|
||||
|
|
|
@ -26,9 +26,10 @@ limitations under the License.
|
|||
|
||||
.mx_HomePage_default {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
|
||||
.mx_HomePage_default_wrapper {
|
||||
padding: 25vh 0 12px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
img {
|
||||
|
@ -50,56 +51,54 @@ limitations under the License.
|
|||
color: $muted-fg-color;
|
||||
}
|
||||
|
||||
.mx_MiniAvatarUploader {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.mx_HomePage_default_buttons {
|
||||
margin: 80px auto 0;
|
||||
margin: 60px auto 0;
|
||||
width: fit-content;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
padding: 73px 8px 15px; // top: 20px top padding + 40px icon + 13px margin
|
||||
|
||||
width: 104px; // 120px - 2* 8px
|
||||
margin: 0 39px; // 55px - 2* 8px
|
||||
width: 160px;
|
||||
height: 132px;
|
||||
margin: 20px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-radius: 8px;
|
||||
vertical-align: top;
|
||||
word-break: break-word;
|
||||
box-sizing: border-box;
|
||||
|
||||
font-weight: 600;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-20px;
|
||||
color: $muted-fg-color;
|
||||
|
||||
&:hover {
|
||||
color: $accent-color;
|
||||
background: rgba(#03b381, 0.06);
|
||||
|
||||
&::before {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
}
|
||||
color: #fff; // on all themes
|
||||
background-color: $accent-color;
|
||||
|
||||
&::before {
|
||||
top: 20px;
|
||||
left: 40px; // (120px-40px)/2
|
||||
left: 60px; // (160px-40px)/2
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: $muted-fg-color;
|
||||
background-color: #fff; // on all themes
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
}
|
||||
|
||||
&.mx_HomePage_button_sendDm::before {
|
||||
mask-image: url('$(res)/img/feather-customised/message-circle.svg');
|
||||
mask-image: url('$(res)/img/element-icons/feedback.svg');
|
||||
}
|
||||
&.mx_HomePage_button_explore::before {
|
||||
mask-image: url('$(res)/img/feather-customised/explore.svg');
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
||||
}
|
||||
&.mx_HomePage_button_createGroup::before {
|
||||
mask-image: url('$(res)/img/feather-customised/group.svg');
|
||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2018 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.
|
||||
|
@ -15,163 +14,212 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_LeftPanel_container {
|
||||
display: flex;
|
||||
/* LeftPanel 260px */
|
||||
min-width: 260px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_container.collapsed {
|
||||
min-width: unset;
|
||||
/* Collapsed LeftPanel 50px */
|
||||
flex: 0 0 50px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_container.collapsed.mx_LeftPanel_container_hasTagPanel {
|
||||
/* TagPanel 70px + Collapsed LeftPanel 50px */
|
||||
flex: 0 0 120px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_tagPanelContainer {
|
||||
flex: 0 0 70px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_hideButton {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 0px;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
$groupFilterPanelWidth: 56px; // only applies in this file, used for calculations
|
||||
$roomListCollapsedWidth: 68px;
|
||||
|
||||
.mx_LeftPanel {
|
||||
flex: 1;
|
||||
overflow-x: hidden;
|
||||
background-color: $roomlist-bg-color;
|
||||
// TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel
|
||||
min-width: 206px;
|
||||
max-width: 50%;
|
||||
|
||||
// Create a row-based flexbox for the GroupFilterPanel and the room list
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
contain: content;
|
||||
|
||||
.mx_LeftPanel .mx_AppTile_mini {
|
||||
height: 132px;
|
||||
}
|
||||
.mx_LeftPanel_GroupFilterPanelContainer {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: $groupFilterPanelWidth;
|
||||
height: 100%;
|
||||
|
||||
.mx_LeftPanel .mx_RoomList_scrollbar {
|
||||
order: 1;
|
||||
// Create another flexbox so the GroupFilterPanel fills the container
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
flex: 1 1 0;
|
||||
|
||||
overflow-y: auto;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||
order: 3;
|
||||
|
||||
border-top: 1px solid $panel-divider-color;
|
||||
margin-left: 16px; /* gutter */
|
||||
margin-right: 16px; /* gutter */
|
||||
flex: 0 0 60px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_container.collapsed .mx_BottomLeftMenu {
|
||||
flex: 0 0 160px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_options {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options object {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options .mx_RoleButton {
|
||||
margin-left: 0px;
|
||||
margin-right: 10px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings .mx_RoleButton {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_container.collapsed .mx_BottomLeftMenu_settings {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_useCompactLayout {
|
||||
.mx_LeftPanel .mx_BottomLeftMenu {
|
||||
flex: 0 0 50px;
|
||||
// GroupFilterPanel handles its own CSS
|
||||
}
|
||||
|
||||
.mx_LeftPanel_container.collapsed .mx_BottomLeftMenu {
|
||||
flex: 0 0 160px;
|
||||
}
|
||||
|
||||
.mx_LeftPanel .mx_BottomLeftMenu_options {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_exploreAndFilterRow {
|
||||
display: flex;
|
||||
|
||||
.mx_SearchBox {
|
||||
flex: 1 1 0;
|
||||
// Note: The 'room list' in this context is actually everything that isn't the tag
|
||||
// panel, such as the menu options, breadcrumbs, filtering, etc
|
||||
.mx_LeftPanel_roomListContainer {
|
||||
background-color: $roomlist-bg-color;
|
||||
flex: 1 0 0;
|
||||
min-width: 0;
|
||||
margin: 4px 9px 1px 9px;
|
||||
}
|
||||
}
|
||||
// Create another flexbox (this time a column) for the room list components
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mx_LeftPanel_explore {
|
||||
flex: 0 0 50%;
|
||||
overflow: hidden;
|
||||
transition: flex-basis 0.2s;
|
||||
box-sizing: border-box;
|
||||
.mx_LeftPanel_userHeader {
|
||||
/* 12px top, 12px sides, 20px bottom (using 13px bottom to account
|
||||
* for internal whitespace in the breadcrumbs)
|
||||
*/
|
||||
padding: 12px;
|
||||
flex-shrink: 0; // to convince safari's layout engine the flexbox is fine
|
||||
|
||||
&.mx_LeftPanel_explore_hidden {
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton {
|
||||
font-size: $font-14px;
|
||||
margin: 4px 0 1px 9px;
|
||||
padding: 9px;
|
||||
padding-left: 42px;
|
||||
font-weight: 600;
|
||||
color: $notice-secondary-color;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: $primary-bg-color;
|
||||
// Create another flexbox column for the rows to stack within
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&::before {
|
||||
cursor: pointer;
|
||||
mask: url('$(res)/img/explore.svg');
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center center;
|
||||
content: "";
|
||||
left: 14px;
|
||||
top: 10px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: $notice-secondary-color;
|
||||
position: absolute;
|
||||
.mx_LeftPanel_breadcrumbsContainer {
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
margin: 12px 12px 0 12px;
|
||||
flex: 0 0 auto;
|
||||
// Create yet another flexbox, this time within the row, to ensure items stay
|
||||
// aligned correctly. This is also a row-based flexbox.
|
||||
display: flex;
|
||||
align-items: center;
|
||||
contain: content;
|
||||
|
||||
&.mx_IndicatorScrollbar_leftOverflow {
|
||||
mask-image: linear-gradient(90deg, transparent, black 5%);
|
||||
}
|
||||
|
||||
&.mx_IndicatorScrollbar_rightOverflow {
|
||||
mask-image: linear-gradient(90deg, black, black 95%, transparent);
|
||||
}
|
||||
|
||||
&.mx_IndicatorScrollbar_rightOverflow.mx_IndicatorScrollbar_leftOverflow {
|
||||
mask-image: linear-gradient(90deg, transparent, black 5%, black 95%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_filterContainer {
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
|
||||
flex-shrink: 0; // to convince safari's layout engine the flexbox is fine
|
||||
|
||||
// Create a flexbox to organize the inputs
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_RoomSearch_focused, .mx_RoomSearch_hasQuery {
|
||||
& + .mx_LeftPanel_exploreButton {
|
||||
// Cheaty way to return the occupied space to the filter input
|
||||
flex-basis: 0;
|
||||
margin: 0;
|
||||
width: 0;
|
||||
|
||||
// Don't forget to hide the masked ::before icon,
|
||||
// using display:none or visibility:hidden would break accessibility
|
||||
&::before {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_dialPadButton {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
background-color: $roomlist-button-bg-color;
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
mask-image: url('$(res)/img/element-icons/call/dialpad.svg');
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_exploreButton {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
background-color: $roomlist-button-bg-color;
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $secondary-fg-color;
|
||||
}
|
||||
|
||||
&.mx_LeftPanel_exploreButton_space::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_roomListFilterCount {
|
||||
font-size: $font-13px;
|
||||
font-weight: $font-semi-bold;
|
||||
margin-left: 12px;
|
||||
margin-top: 14px;
|
||||
margin-bottom: -4px; // to counteract the normal roomListWrapper margin-top
|
||||
}
|
||||
|
||||
.mx_LeftPanel_roomListWrapper {
|
||||
overflow: hidden;
|
||||
margin-top: 10px; // so we're not up against the search/filter
|
||||
flex: 1 0 0; // needed in Safari to properly set flex-basis
|
||||
|
||||
&.mx_LeftPanel_roomListWrapper_stickyBottom {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
&.mx_LeftPanel_roomListWrapper_stickyTop {
|
||||
padding-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanel_actualRoomListContainer {
|
||||
position: relative; // for sticky headers
|
||||
height: 100%; // ensure scrolling still works
|
||||
}
|
||||
}
|
||||
|
||||
// These styles override the defaults for the minimized (66px) layout
|
||||
&.mx_LeftPanel_minimized {
|
||||
min-width: unset;
|
||||
width: unset !important;
|
||||
|
||||
.mx_LeftPanel_roomListContainer {
|
||||
width: $roomListCollapsedWidth;
|
||||
|
||||
.mx_LeftPanel_userHeader {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_filterContainer {
|
||||
// Organize the flexbox into a centered column layout
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.mx_LeftPanel_dialPadButton {
|
||||
margin-left: 0;
|
||||
margin-top: 8px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.mx_LeftPanel_exploreButton {
|
||||
margin-left: 0;
|
||||
margin-top: 8px;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
145
res/css/structures/_LeftPanelWidget.scss
Normal file
145
res/css/structures/_LeftPanelWidget.scss
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
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_LeftPanelWidget {
|
||||
// largely based on RoomSublist
|
||||
margin-left: 8px;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.mx_LeftPanelWidget_headerContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
height: 24px;
|
||||
color: $roomlist-header-color;
|
||||
margin-top: 4px;
|
||||
|
||||
.mx_LeftPanelWidget_stickable {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_LeftPanelWidget_headerText {
|
||||
flex: 1;
|
||||
max-width: calc(100% - 16px);
|
||||
line-height: $font-16px;
|
||||
font-size: $font-13px;
|
||||
font-weight: 600;
|
||||
|
||||
// Ellipsize any text overflow
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
.mx_LeftPanelWidget_collapseBtn {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 6px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $roomlist-header-color;
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
|
||||
&.mx_LeftPanelWidget_collapseBtn_collapsed::before {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanelWidget_resizeBox {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: visible; // let the resize handle out
|
||||
}
|
||||
|
||||
.mx_AppTileFullWidth {
|
||||
flex: 1 0 0;
|
||||
overflow: hidden;
|
||||
// need this to be flex otherwise the overflow hidden from above
|
||||
// sometimes vertically centers the clipped list ... no idea why it would do this
|
||||
// as the box model should be top aligned. Happens in both FF and Chromium
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
mask-image: linear-gradient(0deg, transparent, black 4px);
|
||||
}
|
||||
|
||||
.mx_LeftPanelWidget_resizerHandle {
|
||||
cursor: ns-resize;
|
||||
border-radius: 3px;
|
||||
|
||||
// Override styles from library
|
||||
width: unset !important;
|
||||
height: 4px !important;
|
||||
|
||||
position: absolute;
|
||||
top: -24px !important; // override from library - puts it in the margin-top of the headerContainer
|
||||
|
||||
// Together, these make the bar 64px wide
|
||||
// These are also overridden from the library
|
||||
left: calc(50% - 32px) !important;
|
||||
right: calc(50% - 32px) !important;
|
||||
}
|
||||
|
||||
&:hover .mx_LeftPanelWidget_resizerHandle {
|
||||
opacity: 0.8;
|
||||
background-color: $primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_LeftPanelWidget_maximizeButton {
|
||||
margin-left: 8px;
|
||||
margin-right: 7px;
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 32px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
mask-image: url('$(res)/img/feather-customised/maximise.svg');
|
||||
background: $muted-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LeftPanelWidget_maximizeButtonTooltip {
|
||||
margin-top: -3px;
|
||||
}
|
|
@ -18,11 +18,27 @@ limitations under the License.
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// move hit area 5px to the right so it doesn't overlap with the timeline scrollbar
|
||||
.mx_MainSplit > .mx_ResizeHandle.mx_ResizeHandle_horizontal {
|
||||
margin: 0 -10px 0 0;
|
||||
padding: 0 10px 0 0;
|
||||
.mx_MainSplit > .mx_RightPanel_ResizeWrapper {
|
||||
padding: 5px;
|
||||
// margin left to not allow the handle to not encroach on the space for the scrollbar
|
||||
margin-left: 8px;
|
||||
height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel
|
||||
|
||||
&:hover .mx_RightPanel_ResizeHandle {
|
||||
// Need to use important to override element style attributes
|
||||
// set by re-resizable
|
||||
top: 50% !important;
|
||||
transform: translate(0, -50%);
|
||||
|
||||
height: 64px !important; // to match width of the ones on roomlist
|
||||
width: 4px !important;
|
||||
border-radius: 4px !important;
|
||||
|
||||
background-color: $primary-fg-color;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,10 +41,6 @@ limitations under the License.
|
|||
height: 40px;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_toolbarShowing {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mx_MatrixChat {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -70,15 +66,35 @@ limitations under the License.
|
|||
}
|
||||
|
||||
/* not the left panel, and not the resize handle, so the roomview/groupview/... */
|
||||
.mx_MatrixChat > :not(.mx_LeftPanel_container):not(.mx_ResizeHandle) {
|
||||
.mx_MatrixChat > :not(.mx_LeftPanel):not(.mx_SpacePanel):not(.mx_ResizeHandle) {
|
||||
background-color: $primary-bg-color;
|
||||
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
|
||||
/* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari
|
||||
/* To fix https://github.com/vector-im/element-web/issues/3298 where Safari
|
||||
needed height 100% all the way down to the HomePage. Height does not
|
||||
have to be auto, empirically.
|
||||
*/
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_MatrixChat > .mx_ResizeHandle_horizontal:hover {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
|
||||
height: 64px; // to match width of the ones on roomlist
|
||||
width: 4px;
|
||||
border-radius: 4px;
|
||||
|
||||
content: ' ';
|
||||
|
||||
background-color: $primary-fg-color;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ limitations under the License.
|
|||
.mx_MyGroups {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mx_BetaCard {
|
||||
margin: 0 72px;
|
||||
max-width: 760px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_MyGroups .mx_RoomHeader_simpleHeader {
|
||||
|
@ -30,7 +35,7 @@ limitations under the License.
|
|||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.mx_MyGroups > :not(.mx_RoomHeader) {
|
||||
.mx_MyGroups > :not(.mx_RoomHeader):not(.mx_BetaCard) {
|
||||
max-width: 960px;
|
||||
margin: 40px;
|
||||
}
|
||||
|
|
35
res/css/structures/_NonUrgentToastContainer.scss
Normal file
35
res/css/structures/_NonUrgentToastContainer.scss
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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_NonUrgentToastContainer {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 28px;
|
||||
z-index: 101; // same level as other toasts
|
||||
|
||||
.mx_NonUrgentToastContainer_toast {
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
width: 320px;
|
||||
font-size: $font-13px;
|
||||
margin-top: 8px;
|
||||
|
||||
// We don't use variables on the colours because we want it to be the same
|
||||
// in all themes.
|
||||
background-color: #17191c;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
|
@ -22,7 +22,13 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_NotificationPanel .mx_RoomView_messageListWrapper {
|
||||
margin-right: 20px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_RoomView_MessageList {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_RoomView_MessageList h2 {
|
||||
|
@ -35,11 +41,32 @@ limitations under the License.
|
|||
|
||||
.mx_NotificationPanel .mx_EventTile {
|
||||
word-break: break-word;
|
||||
position: relative;
|
||||
padding-bottom: 18px;
|
||||
|
||||
&:not(.mx_EventTile_last):not(.mx_EventTile_lastInSection)::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: $tertiary-fg-color;
|
||||
height: 1px;
|
||||
opacity: 0.4;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_roomName {
|
||||
font-weight: bold;
|
||||
font-size: $font-14px;
|
||||
|
||||
> * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
> .mx_BaseAvatar {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_roomName a {
|
||||
|
@ -47,8 +74,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_avatar {
|
||||
top: 8px;
|
||||
left: 0px;
|
||||
display: none; // we don't need this in this view
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile .mx_SenderProfile,
|
||||
|
@ -56,13 +82,15 @@ limitations under the License.
|
|||
color: $primary-fg-color;
|
||||
font-size: $font-12px;
|
||||
display: inline;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_senderDetails {
|
||||
padding-left: 32px;
|
||||
padding-top: 8px;
|
||||
padding-left: 36px; // align with the room name
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_roomName a,
|
||||
|
@ -74,11 +102,12 @@ limitations under the License.
|
|||
visibility: visible;
|
||||
position: initial;
|
||||
display: inline;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.mx_NotificationPanel .mx_EventTile_line {
|
||||
margin-right: 0px;
|
||||
padding-left: 32px;
|
||||
padding-left: 36px; // align with the room name
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-right: 0px;
|
||||
|
@ -95,3 +124,7 @@ limitations under the License.
|
|||
.mx_NotificationPanel .mx_EventTile_content {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.mx_NotificationPanel_empty::before {
|
||||
mask-image: url('$(res)/img/element-icons/notifications.svg');
|
||||
}
|
||||
|
|
|
@ -19,9 +19,17 @@ limitations under the License.
|
|||
overflow-x: hidden;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
min-width: 264px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
padding: 4px 0;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
contain: strict;
|
||||
|
||||
.mx_RoomView_MessageList {
|
||||
padding: 14px 18px; // top and bottom is 4px smaller to balance with the padding set above
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_header {
|
||||
|
@ -43,56 +51,128 @@ limitations under the License.
|
|||
.mx_RightPanel_headerButton {
|
||||
cursor: pointer;
|
||||
flex: 0 0 auto;
|
||||
vertical-align: top;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid transparent;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-left: 1px;
|
||||
margin-right: 1px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
position: relative;
|
||||
border-radius: 100%;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: $rightpanel-button-color;
|
||||
top: 4px; // center with parent of 32px
|
||||
left: 4px; // center with parent of 32px
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background-color: $icon-button-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_membersButton::before {
|
||||
mask-image: url('$(res)/img/feather-customised/user.svg');
|
||||
}
|
||||
&:hover {
|
||||
background: rgba($accent-color, 0.1);
|
||||
|
||||
.mx_RightPanel_filesButton::before {
|
||||
mask-image: url('$(res)/img/feather-customised/files.svg');
|
||||
&::before {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_notifsButton::before {
|
||||
mask-image: url('$(res)/img/feather-customised/notifications.svg');
|
||||
mask-image: url('$(res)/img/element-icons/notifications.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
.mx_RightPanel_roomSummaryButton::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
.mx_RightPanel_groupMembersButton::before {
|
||||
mask-image: url('$(res)/img/icons-people.svg');
|
||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
.mx_RightPanel_roomsButton::before {
|
||||
mask-image: url('$(res)/img/icons-room-nobg.svg');
|
||||
mask-image: url('$(res)/img/element-icons/community-rooms.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_highlight::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background-color: $button-bg-color;
|
||||
$dot-size: 8px;
|
||||
$pulse-color: $pinned-unread-color;
|
||||
|
||||
.mx_RightPanel_pinnedMessagesButton {
|
||||
&::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/pin.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
.mx_RightPanel_pinnedMessagesButton_unreadIndicator {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 4px;
|
||||
width: $dot-size;
|
||||
height: $dot-size;
|
||||
border-radius: 50%;
|
||||
transform: scale(1);
|
||||
background: rgba($pulse-color, 1);
|
||||
box-shadow: 0 0 0 0 rgba($pulse-color, 1);
|
||||
animation: mx_RightPanel_indicator_pulse 2s infinite;
|
||||
animation-iteration-count: 1;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: scale(1);
|
||||
transform-origin: center center;
|
||||
animation-name: mx_RightPanel_indicator_pulse_shadow;
|
||||
animation-duration: inherit;
|
||||
animation-iteration-count: inherit;
|
||||
border-radius: 50%;
|
||||
background: rgba($pulse-color, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mx_RightPanel_indicator_pulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mx_RightPanel_indicator_pulse_shadow {
|
||||
0% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(2.2);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_highlight {
|
||||
&::before {
|
||||
background-color: $accent-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_headerButton_badge {
|
||||
|
@ -126,3 +206,45 @@ limitations under the License.
|
|||
order: 2;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mx_RightPanel_empty {
|
||||
margin-right: -28px;
|
||||
|
||||
h2 {
|
||||
font-weight: 700;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
h2, p {
|
||||
font-size: $font-14px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
margin: 11px auto 29px auto;
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
background-color: $rightpanel-button-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
mask-position: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RightPanel_scopeHeader {
|
||||
margin: 24px;
|
||||
text-align: center;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-18px;
|
||||
line-height: $font-22px;
|
||||
|
||||
.mx_BaseAvatar {
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,31 +61,59 @@ limitations under the License.
|
|||
.mx_RoomDirectory_tableWrapper {
|
||||
overflow-y: auto;
|
||||
flex: 1 1 0;
|
||||
|
||||
.mx_RoomDirectory_footer {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
|
||||
> h5 {
|
||||
margin: 0;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-18px;
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
|
||||
> p {
|
||||
margin: 40px auto 60px;
|
||||
font-size: $font-14px;
|
||||
line-height: $font-20px;
|
||||
color: $secondary-fg-color;
|
||||
max-width: 464px; // easier reading
|
||||
}
|
||||
|
||||
> hr {
|
||||
margin: 0;
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: $header-panel-bg-color;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_newRoom {
|
||||
margin: 24px auto 0;
|
||||
width: max-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table {
|
||||
font-size: $font-12px;
|
||||
color: $primary-fg-color;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
font-size: $font-12px;
|
||||
grid-template-columns: max-content auto max-content max-content max-content;
|
||||
row-gap: 24px;
|
||||
text-align: left;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_roomAvatar {
|
||||
width: 32px;
|
||||
padding-right: 14px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_roomDescription {
|
||||
padding-bottom: 16px;
|
||||
padding: 2px 14px 0 0;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_roomMemberCount {
|
||||
align-self: center;
|
||||
color: $light-fg-color;
|
||||
width: 60px;
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
padding: 3px 10px 0;
|
||||
|
||||
&::before {
|
||||
background-color: $light-fg-color;
|
||||
|
@ -105,8 +133,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomDirectory_join, .mx_RoomDirectory_preview {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
@ -133,6 +160,10 @@ limitations under the License.
|
|||
.mx_RoomDirectory_topic {
|
||||
cursor: initial;
|
||||
color: $light-fg-color;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_alias {
|
||||
|
@ -140,11 +171,6 @@ limitations under the License.
|
|||
color: $settings-grey-fg-color;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory_table tr {
|
||||
padding-bottom: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomDirectory .mx_RoomView_MessageList {
|
||||
padding: 0;
|
||||
}
|
||||
|
|
94
res/css/structures/_RoomSearch.scss
Normal file
94
res/css/structures/_RoomSearch.scss
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// Note: this component expects to be contained within a flexbox
|
||||
.mx_RoomSearch {
|
||||
flex: 1;
|
||||
border-radius: 8px;
|
||||
background-color: $roomlist-button-bg-color;
|
||||
// keep border thickness consistent to prevent movement
|
||||
border: 1px solid transparent;
|
||||
height: 28px;
|
||||
padding: 1px;
|
||||
|
||||
// Create a flexbox for the icons (easier to manage)
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_RoomSearch_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
mask: url('$(res)/img/element-icons/roomlist/search.svg');
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $secondary-fg-color;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomSearch_input {
|
||||
border: none !important; // !important to override default app-wide styles
|
||||
flex: 1 !important; // !important to override default app-wide styles
|
||||
color: $primary-fg-color !important; // !important to override default app-wide styles
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-16px;
|
||||
|
||||
&:not(.mx_RoomSearch_inputExpanded)::placeholder {
|
||||
color: $tertiary-fg-color !important; // !important to override default app-wide styles
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_RoomSearch_hasQuery {
|
||||
border-color: $secondary-fg-color;
|
||||
}
|
||||
|
||||
&.mx_RoomSearch_focused {
|
||||
box-shadow: 0 0 4px 4px rgba(0, 132, 255, 0.5);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
&.mx_RoomSearch_focused, &.mx_RoomSearch_hasQuery {
|
||||
background-color: $roomlist-filter-active-bg-color;
|
||||
|
||||
.mx_RoomSearch_clearButton {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/search-clear.svg');
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $secondary-fg-color;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomSearch_clearButton {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
&.mx_RoomSearch_minimized {
|
||||
border-radius: 32px;
|
||||
height: auto;
|
||||
width: auto;
|
||||
padding: 8px;
|
||||
|
||||
.mx_RoomSearch_icon {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,62 +14,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_RoomStatusBar {
|
||||
.mx_RoomStatusBar:not(.mx_RoomStatusBar_unsentMessages) {
|
||||
margin-left: 65px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
/* position the indicator in the same place horizontally as .mx_EventTile_avatar. */
|
||||
.mx_RoomStatusBar_indicator {
|
||||
padding-left: 17px;
|
||||
padding-right: 12px;
|
||||
margin-left: -73px;
|
||||
margin-top: 15px;
|
||||
float: left;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_callBar {
|
||||
height: 50px;
|
||||
line-height: $font-50px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_placeholderIndicator span {
|
||||
color: $primary-fg-color;
|
||||
opacity: 0.5;
|
||||
position: relative;
|
||||
top: -4px;
|
||||
/*
|
||||
animation-duration: 1s;
|
||||
animation-name: bounce;
|
||||
animation-direction: alternate;
|
||||
animation-iteration-count: infinite;
|
||||
*/
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_placeholderIndicator span:nth-child(1) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
.mx_RoomStatusBar_placeholderIndicator span:nth-child(2) {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
.mx_RoomStatusBar_placeholderIndicator span:nth-child(3) {
|
||||
animation-delay: 0.9s;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
from {
|
||||
opacity: 0.5;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0.2;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_typingIndicatorAvatars {
|
||||
width: 52px;
|
||||
margin-top: -1px;
|
||||
|
@ -119,6 +68,97 @@ limitations under the License.
|
|||
min-height: 58px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unsentMessages {
|
||||
> div[role="alert"] {
|
||||
// cheat some basic alignment
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 70px;
|
||||
margin: 12px;
|
||||
padding-left: 16px;
|
||||
background-color: $header-panel-bg-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unsentBadge {
|
||||
margin-right: 12px;
|
||||
|
||||
.mx_NotificationBadge {
|
||||
// Override sizing from the default badge
|
||||
width: 24px !important;
|
||||
height: 24px !important;
|
||||
border-radius: 24px !important;
|
||||
|
||||
.mx_NotificationBadge_count {
|
||||
font-size: $font-16px !important; // override default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unsentTitle {
|
||||
color: $warning-color;
|
||||
font-size: $font-15px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unsentDescription {
|
||||
font-size: $font-12px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_unsentButtonBar {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
margin-right: 22px;
|
||||
color: $muted-fg-color;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
padding: 5px 10px;
|
||||
padding-left: 30px; // 18px for the icon, 2px margin to text, 10px regular padding
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
&:nth-child(2) {
|
||||
border-left: 1px solid $resend-button-divider-color;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 10px; // inset for regular button padding
|
||||
background-color: $muted-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
top: 50%; // text sizes are dynamic
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&.mx_RoomStatusBar_unsentCancelAllBtn::before {
|
||||
mask-image: url('$(res)/img/element-icons/trashcan.svg');
|
||||
}
|
||||
|
||||
&.mx_RoomStatusBar_unsentResendAllBtn {
|
||||
padding-left: 34px; // 28px from above, but +6px to account for the wider icon
|
||||
|
||||
&::before {
|
||||
mask-image: url('$(res)/img/element-icons/retry.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InlineSpinner {
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
top: 1px; // just to help the vertical alignment be slightly better
|
||||
|
||||
& + span {
|
||||
margin-right: 10px; // same margin/padding as the rightmost button
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_connectionLostBar img {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
|
@ -153,18 +193,8 @@ limitations under the License.
|
|||
display: block;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_isAlone {
|
||||
height: 50px;
|
||||
line-height: $font-50px;
|
||||
|
||||
color: $primary-fg-color;
|
||||
opacity: 0.5;
|
||||
overflow-y: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_MatrixChat_useCompactLayout {
|
||||
.mx_RoomStatusBar {
|
||||
.mx_RoomStatusBar:not(.mx_RoomStatusBar_unsentMessages) {
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
|
@ -172,11 +202,6 @@ limitations under the License.
|
|||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_callBar {
|
||||
height: 40px;
|
||||
line-height: $font-40px;
|
||||
}
|
||||
|
||||
.mx_RoomStatusBar_typingBar {
|
||||
height: 40px;
|
||||
line-height: $font-40px;
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket 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.
|
||||
*/
|
||||
|
||||
/* a word of explanation about the flex-shrink values employed here:
|
||||
there are 3 priotized categories of screen real-estate grabbing,
|
||||
each with a flex-shrink difference of 4 order of magnitude,
|
||||
so they ideally wouldn't affect each other.
|
||||
lowest category: .mx_RoomSubList
|
||||
flex-shrink: 10000000
|
||||
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,
|
||||
to limit the size
|
||||
highest category: .mx_RoomSubList.resized-all
|
||||
flex-shrink: 1
|
||||
small flex-shrink value (1), is only added if you can drag the resizer so far
|
||||
so in practice you can only assign this category if there is enough space.
|
||||
*/
|
||||
|
||||
.mx_RoomSubList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.mx_RoomSubList_nonEmpty .mx_AutoHideScrollbar_offset {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_labelContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex: 0 0 auto;
|
||||
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;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_label > span {
|
||||
flex: 1 1 auto;
|
||||
text-transform: uppercase;
|
||||
color: $roomsublist-label-fg-color;
|
||||
font-weight: 700;
|
||||
font-size: $font-12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_badge > div {
|
||||
flex: 0 0 auto;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: $font-12px;
|
||||
padding: 0 5px;
|
||||
color: $roomtile-badge-fg-color;
|
||||
background-color: $roomtile-name-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_addRoom, .mx_RoomSubList_badge {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_addRoom {
|
||||
background-color: $roomheader-addroom-bg-color;
|
||||
border-radius: 10px; // 16/2 + 2 padding
|
||||
height: 16px;
|
||||
flex: 0 0 16px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
background-color: $roomheader-addroom-fg-color;
|
||||
mask: url('$(res)/img/icons-room-add.svg');
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomSubList_badgeHighlight > div {
|
||||
color: $accent-fg-color;
|
||||
background-color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevron {
|
||||
pointer-events: none;
|
||||
mask: url('$(res)/img/feather-customised/dropdown-arrow.svg');
|
||||
mask-repeat: no-repeat;
|
||||
transition: transform 0.2s ease-in;
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
margin-left: 2px;
|
||||
background-color: $roomsublist-label-fg-color;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevronDown {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevronUp {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
|
||||
.mx_RoomSubList_chevronRight {
|
||||
transform: rotateZ(-90deg);
|
||||
}
|
||||
|
||||
.mx_RoomSubList_scroll {
|
||||
/* let rooms list grab as much space as it needs (auto),
|
||||
potentially overflowing and showing a scrollbar */
|
||||
flex: 0 1 auto;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.collapsed {
|
||||
.mx_RoomSubList_scroll {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_labelContainer {
|
||||
margin-right: 8px;
|
||||
margin-left: 2px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_addRoom {
|
||||
margin-left: 3px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_label > span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// overflow indicators
|
||||
.mx_RoomSubList:not(.resized-all) > .mx_RoomSubList_scroll {
|
||||
&.mx_IndicatorScrollbar_topOverflow::before {
|
||||
position: sticky;
|
||||
content: "";
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 8px;
|
||||
z-index: 100;
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
transition: background-image 0.1s ease-in;
|
||||
background: linear-gradient(to top, $panel-gradient);
|
||||
}
|
||||
|
||||
|
||||
&.mx_IndicatorScrollbar_topOverflow {
|
||||
margin-top: -8px;
|
||||
}
|
||||
}
|
|
@ -20,35 +20,55 @@ limitations under the License.
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
@keyframes mx_RoomView_fileDropTarget_animation {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 0.95;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomView_fileDropTarget {
|
||||
min-width: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-size: $font-18px;
|
||||
text-align: center;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
margin-left: -12px;
|
||||
background-color: $primary-bg-color;
|
||||
opacity: 0.95;
|
||||
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
|
||||
background-color: $droptarget-bg-color;
|
||||
border: 2px #e1dddd solid;
|
||||
border-bottom: none;
|
||||
position: absolute;
|
||||
top: 52px;
|
||||
bottom: 0px;
|
||||
z-index: 3000;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
animation: mx_RoomView_fileDropTarget_animation;
|
||||
animation-duration: 0.5s;
|
||||
}
|
||||
|
||||
.mx_RoomView_fileDropTargetLabel {
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
margin-top: -50px;
|
||||
position: absolute;
|
||||
@keyframes mx_RoomView_fileDropTarget_image_animation {
|
||||
from {
|
||||
transform: scaleX(0);
|
||||
}
|
||||
to {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomView_fileDropTarget_image {
|
||||
width: 32px;
|
||||
animation: mx_RoomView_fileDropTarget_image_animation;
|
||||
animation-duration: 0.5s;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_RoomView_auxPanel {
|
||||
|
@ -117,7 +137,6 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomView_body {
|
||||
position: relative; //for .mx_RoomView_auxPanel_fullHeight
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
@ -134,6 +153,7 @@ limitations under the License.
|
|||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.mx_RoomView_statusArea {
|
||||
|
@ -185,13 +205,11 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_RoomView_empty {
|
||||
flex: 1 1 auto;
|
||||
font-size: $font-13px;
|
||||
padding-left: 3em;
|
||||
padding-right: 3em;
|
||||
margin-right: 20px;
|
||||
margin-top: 33%;
|
||||
padding: 0 24px;
|
||||
margin-right: 30px;
|
||||
text-align: center;
|
||||
margin-bottom: 80px; // visually center the content (intentional offset)
|
||||
}
|
||||
|
||||
.mx_RoomView_MessageList {
|
||||
|
@ -221,7 +239,8 @@ hr.mx_RoomView_myReadMarker {
|
|||
position: relative;
|
||||
top: -1px;
|
||||
z-index: 1;
|
||||
transition: width 400ms easeInSine 1s, opacity 400ms easeInSine 1s;
|
||||
will-change: width;
|
||||
transition: width 400ms easeinsine 1s, opacity 400ms easeinsine 1s;
|
||||
width: 99%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
@ -246,12 +265,6 @@ hr.mx_RoomView_myReadMarker {
|
|||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.mx_RoomView_inCall .mx_RoomView_statusAreaBox {
|
||||
background-color: $accent-color;
|
||||
color: $accent-fg-color;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_RoomView_voipChevron {
|
||||
position: absolute;
|
||||
bottom: -11px;
|
||||
|
@ -261,7 +274,7 @@ hr.mx_RoomView_myReadMarker {
|
|||
.mx_RoomView_voipButton {
|
||||
float: right;
|
||||
margin-right: 13px;
|
||||
margin-top: 10px;
|
||||
margin-top: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ limitations under the License.
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
overflow-y: hidden;
|
||||
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: 50px;
|
||||
}
|
||||
}
|
||||
|
|
376
res/css/structures/_SpacePanel.scss
Normal file
376
res/css/structures/_SpacePanel.scss
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
Copyright 2021 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.
|
||||
*/
|
||||
|
||||
$topLevelHeight: 32px;
|
||||
$nestedHeight: 24px;
|
||||
$gutterSize: 16px;
|
||||
$activeBorderTransparentGap: 1px;
|
||||
|
||||
$activeBackgroundColor: $roomtile-selected-bg-color;
|
||||
$activeBorderColor: $secondary-fg-color;
|
||||
|
||||
.mx_SpacePanel {
|
||||
flex: 0 0 auto;
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
// Create another flexbox so the Panel fills the container
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.mx_SpacePanel_spaceTreeWrapper {
|
||||
flex: 1;
|
||||
padding: 8px 8px 16px 0;
|
||||
}
|
||||
|
||||
.mx_SpacePanel_toggleCollapse {
|
||||
flex: 0 0 auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
mask-position: center;
|
||||
mask-size: 32px;
|
||||
mask-repeat: no-repeat;
|
||||
margin-left: $gutterSize;
|
||||
margin-bottom: 12px;
|
||||
background-color: $roomlist-header-color;
|
||||
mask-image: url('$(res)/img/element-icons/expand-space-panel.svg');
|
||||
|
||||
&.expanded {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
|
||||
> .mx_SpaceItem {
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceButton_toggleCollapse {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_SpaceItem_dragging {
|
||||
.mx_SpaceButton_toggleCollapse {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceTreeLevel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 250px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.mx_SpaceItem {
|
||||
display: inline-flex;
|
||||
flex-flow: wrap;
|
||||
|
||||
&.mx_SpaceItem_narrow {
|
||||
align-self: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceItem.collapsed {
|
||||
& > .mx_SpaceButton > .mx_SpaceButton_toggleCollapse {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
& > .mx_SpaceTreeLevel {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceItem:not(.hasSubSpaces) > .mx_SpaceButton {
|
||||
margin-left: $gutterSize;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.mx_SpaceButton {
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 4px 4px 0;
|
||||
width: 100%;
|
||||
|
||||
&.mx_SpaceButton_active {
|
||||
&:not(.mx_SpaceButton_narrow) .mx_SpaceButton_selectionWrapper {
|
||||
background-color: $activeBackgroundColor;
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_narrow .mx_SpaceButton_selectionWrapper {
|
||||
padding: $activeBorderTransparentGap;
|
||||
border: 3px $activeBorderColor solid;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceButton_selectionWrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
border-radius: 12px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
&:not(.mx_SpaceButton_narrow) {
|
||||
.mx_SpaceButton_selectionWrapper {
|
||||
width: 100%;
|
||||
padding-right: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceButton_name {
|
||||
flex: 1;
|
||||
margin-left: 8px;
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
padding-right: 8px;
|
||||
font-size: $font-14px;
|
||||
line-height: $font-18px;
|
||||
}
|
||||
|
||||
.mx_SpaceButton_toggleCollapse {
|
||||
width: $gutterSize;
|
||||
height: 20px;
|
||||
mask-position: center;
|
||||
mask-size: 20px;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $roomlist-header-color;
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
|
||||
.mx_SpaceButton_icon {
|
||||
width: $topLevelHeight;
|
||||
min-width: $topLevelHeight;
|
||||
height: $topLevelHeight;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: $topLevelHeight;
|
||||
height: $topLevelHeight;
|
||||
top: 0;
|
||||
left: 0;
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_home .mx_SpaceButton_icon {
|
||||
background-color: #ffffff;
|
||||
|
||||
&::before {
|
||||
background-color: #3f3d3d;
|
||||
mask-image: url('$(res)/img/element-icons/home.svg');
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_new .mx_SpaceButton_icon {
|
||||
background-color: $accent-color;
|
||||
transition: all .1s ease-in-out; // TODO transition
|
||||
|
||||
&::before {
|
||||
background-color: #ffffff;
|
||||
mask-image: url('$(res)/img/element-icons/plus.svg');
|
||||
transition: all .2s ease-in-out; // TODO transition
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_newCancel .mx_SpaceButton_icon {
|
||||
background-color: $icon-button-color;
|
||||
|
||||
&::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.mx_SpaceButton_menuButton {
|
||||
width: 20px;
|
||||
min-width: 20px; // yay flex
|
||||
height: 20px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
|
||||
&::before {
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
mask-image: url('$(res)/img/element-icons/context-menu.svg');
|
||||
background: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpacePanel_badgeContainer {
|
||||
position: absolute;
|
||||
|
||||
// Create a flexbox to make aligning dot badges easier
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_NotificationBadge {
|
||||
margin: 0 2px; // centering
|
||||
}
|
||||
|
||||
.mx_NotificationBadge_dot {
|
||||
// make the smaller dot occupy the same width for centering
|
||||
margin: 0 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
.mx_SpaceButton {
|
||||
.mx_SpacePanel_badgeContainer {
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
.mx_NotificationBadge {
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.mx_NotificationBadge_dot {
|
||||
margin: 0 -1px 0 0;
|
||||
border: 3px solid $groupFilterPanel-bg-color;
|
||||
}
|
||||
|
||||
.mx_NotificationBadge_2char,
|
||||
.mx_NotificationBadge_3char {
|
||||
margin: -5px -5px 0 0;
|
||||
border: 2px solid $groupFilterPanel-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_SpaceButton_active .mx_SpacePanel_badgeContainer {
|
||||
// when we draw the selection border we move the relative bounds of our parent
|
||||
// so update our position within the bounds of the parent to maintain position overall
|
||||
right: -3px;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.collapsed) {
|
||||
.mx_SpacePanel_badgeContainer {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.mx_SpaceButton:hover,
|
||||
.mx_SpaceButton:focus-within,
|
||||
.mx_SpaceButton_hasMenuOpen {
|
||||
&:not(.mx_SpaceButton_home):not(.mx_SpaceButton_invite) {
|
||||
// Hide the badge container on hover because it'll be a menu button
|
||||
.mx_SpacePanel_badgeContainer {
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_SpaceButton_menuButton {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* root space buttons are bigger and not indented */
|
||||
& > .mx_AutoHideScrollbar {
|
||||
& > .mx_SpaceButton {
|
||||
height: $topLevelHeight;
|
||||
|
||||
&.mx_SpaceButton_active::before {
|
||||
height: $topLevelHeight;
|
||||
}
|
||||
}
|
||||
|
||||
& > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpacePanel_contextMenu {
|
||||
.mx_SpacePanel_contextMenu_header {
|
||||
margin: 12px 16px 12px;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-18px;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_optionList .mx_AccessibleButton.mx_SpacePanel_contextMenu_inviteButton {
|
||||
color: $accent-color;
|
||||
|
||||
.mx_SpacePanel_iconInvite::before {
|
||||
background-color: $accent-color;
|
||||
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconSettings::before {
|
||||
mask-image: url('$(res)/img/element-icons/settings.svg');
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconLeave::before {
|
||||
mask-image: url('$(res)/img/element-icons/leave.svg');
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconMembers::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconPlus::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/plus-circle.svg');
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconHash::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/hash-circle.svg');
|
||||
}
|
||||
|
||||
.mx_SpacePanel_iconExplore::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.mx_SpacePanel_sharePublicSpace {
|
||||
margin: 0;
|
||||
}
|
315
res/css/structures/_SpaceRoomDirectory.scss
Normal file
315
res/css/structures/_SpaceRoomDirectory.scss
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
Copyright 2021 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_SpaceRoomDirectory_dialogWrapper > .mx_Dialog {
|
||||
max-width: 960px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory {
|
||||
height: 100%;
|
||||
margin-bottom: 12px;
|
||||
color: $primary-fg-color;
|
||||
word-break: break-word;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory,
|
||||
.mx_SpaceRoomView_landing {
|
||||
.mx_Dialog_title {
|
||||
display: flex;
|
||||
|
||||
.mx_BaseAvatar {
|
||||
margin-right: 12px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
> div {
|
||||
> h1 {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-18px;
|
||||
line-height: $font-22px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> div {
|
||||
font-weight: 400;
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mx_SearchBox {
|
||||
margin: 24px 0 16px;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_noResults {
|
||||
text-align: center;
|
||||
|
||||
> div {
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_listHeader {
|
||||
display: flex;
|
||||
min-height: 32px;
|
||||
align-items: center;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $primary-fg-color;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
padding: 4px 12px;
|
||||
font-weight: normal;
|
||||
|
||||
& + .mx_AccessibleButton {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_danger_outline,
|
||||
.mx_AccessibleButton_kind_primary_outline {
|
||||
padding: 3px 12px; // to account for the 1px border
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_error {
|
||||
position: relative;
|
||||
font-weight: $font-semi-bold;
|
||||
color: $notice-primary-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-18px;
|
||||
margin: 20px auto 12px;
|
||||
padding-left: 24px;
|
||||
width: max-content;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
left: 0;
|
||||
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_list {
|
||||
margin-top: 16px;
|
||||
padding-bottom: 40px;
|
||||
|
||||
.mx_SpaceRoomDirectory_roomCount {
|
||||
> h3 {
|
||||
display: inline;
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-18px;
|
||||
line-height: $font-22px;
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-left: 8px;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_subspace {
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_subspace_toggle {
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
top: 10px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
border-radius: 4px;
|
||||
background-color: $primary-bg-color;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
background-color: $tertiary-fg-color;
|
||||
mask-size: 16px;
|
||||
transform: rotate(270deg);
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
|
||||
&.mx_SpaceRoomDirectory_subspace_toggle_shown::before {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_subspace_children {
|
||||
position: relative;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_roomTile {
|
||||
position: relative;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
min-height: 56px;
|
||||
box-sizing: border-box;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 20px auto max-content;
|
||||
grid-column-gap: 8px;
|
||||
grid-row-gap: 6px;
|
||||
align-items: center;
|
||||
|
||||
.mx_BaseAvatar {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_roomTile_name {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-18px;
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
|
||||
.mx_InfoTooltip {
|
||||
display: inline;
|
||||
margin-left: 12px;
|
||||
color: $tertiary-fg-color;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
|
||||
.mx_InfoTooltip_icon {
|
||||
margin-right: 4px;
|
||||
position: relative;
|
||||
vertical-align: text-top;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_roomTile_info {
|
||||
font-size: $font-14px;
|
||||
line-height: $font-18px;
|
||||
color: $secondary-fg-color;
|
||||
grid-row: 2;
|
||||
grid-column: 1/3;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_actions {
|
||||
text-align: right;
|
||||
margin-left: 20px;
|
||||
grid-column: 3;
|
||||
grid-row: 1/3;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
line-height: $font-24px;
|
||||
padding: 4px 16px;
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_danger_outline,
|
||||
.mx_AccessibleButton_kind_primary_outline {
|
||||
padding: 3px 16px; // to account for the 1px border
|
||||
}
|
||||
|
||||
.mx_Checkbox {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_roomTile,
|
||||
.mx_SpaceRoomDirectory_subspace_children {
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
left: 6px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_actions {
|
||||
.mx_SpaceRoomDirectory_actionsText {
|
||||
font-weight: normal;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
> hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: rgba(141, 151, 165, 0.2);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomDirectory_createRoom {
|
||||
display: block;
|
||||
margin: 16px auto 0;
|
||||
width: max-content;
|
||||
}
|
||||
}
|
569
res/css/structures/_SpaceRoomView.scss
Normal file
569
res/css/structures/_SpaceRoomView.scss
Normal file
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
Copyright 2021 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.
|
||||
*/
|
||||
|
||||
$SpaceRoomViewInnerWidth: 428px;
|
||||
|
||||
@define-mixin SpacePillButton {
|
||||
position: relative;
|
||||
padding: 16px 32px 16px 72px;
|
||||
width: 432px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
border: 1px solid $input-border-color;
|
||||
font-size: $font-15px;
|
||||
margin: 20px 0;
|
||||
|
||||
> h3 {
|
||||
font-weight: $font-semi-bold;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
> span {
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
top: 24px;
|
||||
left: 20px;
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 24px;
|
||||
background-color: $tertiary-fg-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $accent-color;
|
||||
|
||||
&::before {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
|
||||
> span {
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView {
|
||||
.mx_MainSplit > div:first-child {
|
||||
padding: 80px 60px;
|
||||
flex-grow: 1;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: $font-24px;
|
||||
font-weight: $font-semi-bold;
|
||||
color: $primary-fg-color;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_description {
|
||||
font-size: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 24px;
|
||||
max-width: $SpaceRoomViewInnerWidth;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace {
|
||||
max-width: $SpaceRoomViewInnerWidth;
|
||||
|
||||
.mx_AddExistingToSpace_content {
|
||||
height: calc(100vh - 360px);
|
||||
max-height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.mx_SpaceRoomView_landing) .mx_SpaceFeedbackPrompt {
|
||||
width: $SpaceRoomViewInnerWidth;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_buttons {
|
||||
display: block;
|
||||
margin-top: 44px;
|
||||
width: $SpaceRoomViewInnerWidth;
|
||||
text-align: right; // button alignment right
|
||||
|
||||
.mx_AccessibleButton_hasKind {
|
||||
padding: 8px 22px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
input.mx_AccessibleButton {
|
||||
border: none; // override default styles
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Field {
|
||||
max-width: $SpaceRoomViewInnerWidth;
|
||||
|
||||
& + .mx_Field {
|
||||
margin-top: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_errorText {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $notice-primary-color;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_preview {
|
||||
padding: 32px 24px !important; // override default padding from above
|
||||
margin: auto;
|
||||
max-width: 480px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 2px 15px 30px $dialog-shadow-color;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
|
||||
// XXX remove this when spaces leaves Beta
|
||||
.mx_BetaCard_betaPill {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: 32px;
|
||||
}
|
||||
// XXX remove this when spaces leaves Beta
|
||||
.mx_SpaceRoomView_preview_spaceBetaPrompt {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-14px;
|
||||
line-height: $font-24px;
|
||||
color: $primary-fg-color;
|
||||
margin-top: 24px;
|
||||
position: relative;
|
||||
padding-left: 24px;
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
display: inline;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: $font-24px;
|
||||
width: 20px;
|
||||
left: 0;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||
background-color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_preview_inviter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: $font-15px;
|
||||
|
||||
> div {
|
||||
margin-left: 8px;
|
||||
|
||||
.mx_SpaceRoomView_preview_inviter_name {
|
||||
line-height: $font-18px;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_preview_inviter_mxid {
|
||||
line-height: $font-24px;
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .mx_BaseAvatar_image,
|
||||
> .mx_BaseAvatar > .mx_BaseAvatar_image {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
h1.mx_SpaceRoomView_preview_name {
|
||||
margin: 20px 0 !important; // override default margin from above
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_preview_topic {
|
||||
font-size: $font-14px;
|
||||
line-height: $font-22px;
|
||||
color: $secondary-fg-color;
|
||||
margin: 20px 0;
|
||||
max-height: 160px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_preview_joinButtons {
|
||||
margin-top: 20px;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
width: 200px;
|
||||
box-sizing: border-box;
|
||||
padding: 14px 0;
|
||||
|
||||
& + .mx_AccessibleButton {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing {
|
||||
> .mx_BaseAvatar_image,
|
||||
> .mx_BaseAvatar > .mx_BaseAvatar_image {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_name {
|
||||
margin: 24px 0 16px;
|
||||
font-size: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
|
||||
> span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_nameRow {
|
||||
margin-top: 12px;
|
||||
|
||||
> h1 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_inviter {
|
||||
.mx_BaseAvatar {
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_SpaceRoomView_info {
|
||||
display: inline-block;
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
|
||||
.mx_FacePile {
|
||||
display: inline-block;
|
||||
margin-right: 12px;
|
||||
|
||||
.mx_FacePile_faces {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_inviteButton {
|
||||
position: relative;
|
||||
padding: 4px 18px 4px 40px;
|
||||
line-height: $font-24px;
|
||||
height: min-content;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 8px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background: #ffffff; // white icon fill
|
||||
mask-position: center;
|
||||
mask-size: 16px;
|
||||
mask-repeat: no-repeat;
|
||||
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_settingsButton {
|
||||
position: relative;
|
||||
margin-left: 16px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background: $tertiary-fg-color;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
mask-image: url('$(res)/img/element-icons/settings.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_landing_topic {
|
||||
font-size: $font-15px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 16px;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
> hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
}
|
||||
|
||||
.mx_SearchBox {
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.mx_SpaceFeedbackPrompt {
|
||||
margin-bottom: 16px;
|
||||
|
||||
// hide the HR as we have our own
|
||||
& + hr {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_privateScope {
|
||||
> .mx_AccessibleButton {
|
||||
@mixin SpacePillButton;
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_privateScope_justMeButton::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_privateScope_meAndMyTeammatesButton::before {
|
||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_betaWarning {
|
||||
padding: 12px 12px 12px 54px;
|
||||
position: relative;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
width: 432px;
|
||||
border-radius: 8px;
|
||||
background-color: $info-plinth-bg-color;
|
||||
color: $secondary-fg-color;
|
||||
box-sizing: border-box;
|
||||
|
||||
> h3 {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> p {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
content: '';
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 14px;
|
||||
background-color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_inviteTeammates {
|
||||
// XXX remove this when spaces leaves Beta
|
||||
.mx_SpaceRoomView_inviteTeammates_betaDisclaimer {
|
||||
padding: 58px 16px 16px;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
background-color: $header-panel-bg-color;
|
||||
max-width: $SpaceRoomViewInnerWidth;
|
||||
margin: 20px 0 30px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.mx_BetaCard_betaPill {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_inviteTeammates_buttons {
|
||||
color: $secondary-fg-color;
|
||||
margin-top: 28px;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 32px;
|
||||
line-height: 24px; // to center icons
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: $secondary-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
}
|
||||
|
||||
& + .mx_AccessibleButton {
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_inviteTeammates_inviteDialogButton::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_info {
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
margin: 20px 0;
|
||||
|
||||
.mx_SpaceRoomView_info_public,
|
||||
.mx_SpaceRoomView_info_private {
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 0;
|
||||
left: -2px;
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $tertiary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_info_public::before {
|
||||
mask-size: 12px;
|
||||
mask-image: url("$(res)/img/globe.svg");
|
||||
}
|
||||
|
||||
.mx_SpaceRoomView_info_private::before {
|
||||
mask-size: 14px;
|
||||
mask-image: url("$(res)/img/element-icons/lock.svg");
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
color: inherit;
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
|
||||
&::before {
|
||||
content: "·"; // visual separator
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SpaceFeedbackPrompt {
|
||||
margin-top: 18px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
> hr {
|
||||
border: none;
|
||||
border-top: 1px solid $input-border-color;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
|
||||
> span {
|
||||
color: $secondary-fg-color;
|
||||
position: relative;
|
||||
padding-left: 32px;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
margin-right: auto;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: $secondary-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
color: $accent-color;
|
||||
position: relative;
|
||||
padding: 0 0 0 24px;
|
||||
margin-left: 8px;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background-color: $accent-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
mask-image: url('$(res)/img/element-icons/chat-bubbles.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright 2017 Travis Ralston
|
||||
Copyright 2019 New Vector Ltd
|
||||
Copyright 2021 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.
|
||||
|
@ -17,62 +18,126 @@ limitations under the License.
|
|||
|
||||
.mx_TabbedView {
|
||||
margin: 0;
|
||||
padding: 0 0 0 58px;
|
||||
padding: 0 0 0 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabsOnLeft {
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
|
||||
.mx_TabbedView_tabLabels {
|
||||
width: 170px;
|
||||
max-width: 170px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabPanel {
|
||||
margin-left: 240px; // 170px sidebar + 70px padding
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active {
|
||||
background-color: $tab-label-active-bg-color;
|
||||
color: $tab-label-active-fg-color;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active .mx_TabbedView_maskedIcon::before {
|
||||
background-color: $tab-label-active-icon-bg-color;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 8px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon::before {
|
||||
mask-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabsOnTop {
|
||||
flex-direction: column;
|
||||
|
||||
.mx_TabbedView_tabLabels {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel {
|
||||
padding-left: 0px;
|
||||
padding-right: 52px;
|
||||
|
||||
.mx_TabbedView_tabLabel_text {
|
||||
font-size: 15px;
|
||||
color: $tertiary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabPanel {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active {
|
||||
color: $accent-color;
|
||||
.mx_TabbedView_tabLabel_text {
|
||||
color: $accent-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active .mx_TabbedView_maskedIcon::before {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: 0px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon::before {
|
||||
mask-size: 22px;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabels {
|
||||
width: 170px;
|
||||
max-width: 170px;
|
||||
color: $tab-label-fg-color;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
vertical-align: text-top;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
font-size: $font-14px;
|
||||
min-height: 24px; // use min-height instead of height to allow the label to overflow a bit
|
||||
margin-bottom: 6px;
|
||||
padding: 8px 0;
|
||||
border-radius: 8px;
|
||||
font-size: $font-13px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active {
|
||||
background-color: $tab-label-active-bg-color;
|
||||
color: $tab-label-active-fg-color;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon {
|
||||
margin-left: 6px;
|
||||
margin-right: 9px;
|
||||
margin-top: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_TabbedView_maskedIcon::before {
|
||||
display: inline-block;
|
||||
background-color: $tab-label-icon-bg-color;
|
||||
background-color: $icon-button-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 16px;
|
||||
width: 16px;
|
||||
height: 22px;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_active .mx_TabbedView_maskedIcon::before {
|
||||
background-color: $tab-label-active-icon-bg-color;
|
||||
}
|
||||
|
||||
.mx_TabbedView_tabLabel_text {
|
||||
|
@ -80,10 +145,8 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_TabbedView_tabPanel {
|
||||
margin-left: 240px; // 170px sidebar + 70px padding
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0; // firefox
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019-2021 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,8 +28,8 @@ limitations under the License.
|
|||
margin: 0 4px;
|
||||
grid-row: 2 / 4;
|
||||
grid-column: 1;
|
||||
background-color: white;
|
||||
box-shadow: 0px 4px 12px $menu-box-shadow-color;
|
||||
background-color: $dark-panel-bg-color;
|
||||
box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
@ -37,26 +37,28 @@ limitations under the License.
|
|||
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;
|
||||
background-color: $dark-panel-bg-color;
|
||||
box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
grid-template-columns: 20px 1fr;
|
||||
column-gap: 10px;
|
||||
grid-template-columns: 22px 1fr;
|
||||
column-gap: 8px;
|
||||
row-gap: 4px;
|
||||
padding: 8px;
|
||||
padding-right: 16px;
|
||||
|
||||
&.mx_Toast_hasIcon {
|
||||
&::after {
|
||||
&::before, &::after {
|
||||
content: "";
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
mask-size: 100%;
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
&.mx_Toast_icon_verification::after {
|
||||
|
@ -64,21 +66,64 @@ limitations under the License.
|
|||
background-color: $primary-fg-color;
|
||||
}
|
||||
|
||||
&.mx_Toast_icon_verification_warning::after {
|
||||
background-image: url("$(res)/img/e2e/warning.svg");
|
||||
&.mx_Toast_icon_verification_warning {
|
||||
// white infill for the hollow svg mask
|
||||
&::before {
|
||||
background-color: #ffffff;
|
||||
mask-image: url('$(res)/img/e2e/normal.svg');
|
||||
mask-size: 80%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
mask-image: url("$(res)/img/e2e/warning.svg");
|
||||
background-color: $notice-primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
h2, .mx_Toast_body {
|
||||
&.mx_Toast_icon_secure_backup::after {
|
||||
mask-image: url('$(res)/img/feather-customised/secure-backup.svg');
|
||||
background-color: $primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_Toast_title, .mx_Toast_body {
|
||||
grid-column: 2;
|
||||
}
|
||||
}
|
||||
&:not(.mx_Toast_hasIcon) {
|
||||
padding-left: 12px;
|
||||
|
||||
h2 {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1;
|
||||
margin: 0;
|
||||
font-size: $font-15px;
|
||||
font-weight: 600;
|
||||
.mx_Toast_title {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Toast_title,
|
||||
.mx_Toast_description {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.mx_Toast_title {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
h2 {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1;
|
||||
margin: 0;
|
||||
font-size: $font-15px;
|
||||
font-weight: 600;
|
||||
display: inline;
|
||||
width: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span {
|
||||
padding-left: 8px;
|
||||
float: right;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-22px;
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Toast_body {
|
||||
|
@ -87,16 +132,38 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_Toast_buttons {
|
||||
float: right;
|
||||
display: flex;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
min-width: 96px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton + .mx_AccessibleButton {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Toast_description {
|
||||
max-width: 400px;
|
||||
max-width: 272px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 4px 0 11px 0;
|
||||
font-size: $font-12px;
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Toast_detail {
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
|
||||
.mx_Toast_deviceID {
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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_TopLeftMenuButton {
|
||||
flex: 0 0 52px;
|
||||
border-bottom: 1px solid $panel-divider-color;
|
||||
color: $topleftmenu-color;
|
||||
background-color: $primary-bg-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
padding: 0 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mx_TopLeftMenuButton .mx_BaseAvatar {
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
.mx_TopLeftMenuButton_name {
|
||||
margin: 0 7px;
|
||||
font-size: $font-18px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mx_TopLeftMenuButton_chevron {
|
||||
margin: 0 7px;
|
||||
mask: url('$(res)/img/feather-customised/dropdown-arrow.svg');
|
||||
mask-repeat: no-repeat;
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
background-color: $roomsublist-label-fg-color;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2015, 2016, 2021 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.
|
||||
|
@ -15,47 +15,45 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
.mx_UploadBar {
|
||||
padding-left: 65px; // line up with the shield area in the composer
|
||||
position: relative;
|
||||
|
||||
.mx_ProgressBar {
|
||||
width: calc(100% - 40px); // cheating at a right margin
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadProgressOuter {
|
||||
height: 5px;
|
||||
margin-left: 63px;
|
||||
margin-top: -1px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadProgressInner {
|
||||
background-color: $accent-color;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadFilename {
|
||||
.mx_UploadBar_filename {
|
||||
margin-top: 5px;
|
||||
margin-left: 65px;
|
||||
opacity: 0.5;
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadIcon {
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadCancel {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 10px;
|
||||
color: $muted-fg-color;
|
||||
position: relative;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
padding-left: 22px; // 18px for icon, 4px for padding
|
||||
font-size: $font-15px;
|
||||
vertical-align: middle;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
background-color: $muted-fg-color;
|
||||
mask-image: url('$(res)/img/element-icons/upload.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UploadBar_uploadBytes {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 30px;
|
||||
color: $accent-color;
|
||||
.mx_UploadBar_cancel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-right: 16px; // align over rightmost button in composer
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
background-color: $muted-fg-color;
|
||||
mask-image: url('$(res)/img/icons-close.svg');
|
||||
}
|
||||
|
|
337
res/css/structures/_UserMenu.scss
Normal file
337
res/css/structures/_UserMenu.scss
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
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_UserMenu {
|
||||
// to make the menu button sort of aligned with the explore button below
|
||||
padding-right: 6px;
|
||||
|
||||
&.mx_UserMenu_prototype {
|
||||
// The margin & padding combination between here and the ::after is to
|
||||
// align the border line with the tag panel.
|
||||
margin-bottom: 6px;
|
||||
|
||||
padding-right: 0; // make the right edge line up with the explore button
|
||||
|
||||
.mx_UserMenu_headerButtons {
|
||||
// considering we've eliminated right padding on the menu itself, we need to
|
||||
// push the chevron in slightly (roughly lining up with the center of the
|
||||
// plus buttons)
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
// we cheat opacity on the theme colour with an after selector here
|
||||
&::after {
|
||||
content: '';
|
||||
border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
|
||||
opacity: 0.2;
|
||||
display: block;
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_headerButtons {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $tertiary-fg-color;
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_row {
|
||||
// Create a row-based flexbox to ensure items stay aligned correctly.
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_UserMenu_userAvatarContainer {
|
||||
position: relative; // to make default avatars work
|
||||
margin-right: 8px;
|
||||
height: 32px; // to remove the unknown 4px gap the browser puts below it
|
||||
padding: 3px 0; // to align with and without using doubleName
|
||||
|
||||
.mx_UserMenu_userAvatar {
|
||||
border-radius: 32px; // should match avatar size
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_doubleName {
|
||||
flex: 1;
|
||||
min-width: 0; // make flexbox aware that it can crush this to a tiny width
|
||||
|
||||
.mx_UserMenu_userName,
|
||||
.mx_UserMenu_subUserName {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_UserMenu_subUserName {
|
||||
color: $muted-fg-color;
|
||||
font-size: $font-13px;
|
||||
line-height: $font-18px;
|
||||
flex: 1;
|
||||
|
||||
// Ellipsize any text overflow
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_userName {
|
||||
font-weight: 600;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-20px;
|
||||
flex: 1;
|
||||
|
||||
// Ellipsize any text overflow
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_UserMenu_headerButtons {
|
||||
// No special styles: the rest of the layout happens to make it work.
|
||||
}
|
||||
|
||||
.mx_UserMenu_dnd {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $muted-fg-color;
|
||||
}
|
||||
|
||||
&.mx_UserMenu_dnd_noisy::before {
|
||||
mask-image: url('$(res)/img/element-icons/notifications.svg');
|
||||
}
|
||||
|
||||
&.mx_UserMenu_dnd_muted::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/notifications-off.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_UserMenu_minimized {
|
||||
padding-right: 0px;
|
||||
|
||||
.mx_UserMenu_userAvatarContainer {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_contextMenu {
|
||||
width: 258px;
|
||||
|
||||
// These override the styles already present on the user menu rather than try to
|
||||
// define a new menu. They are specifically for the stacked menu when a community
|
||||
// is being represented as a prototype.
|
||||
&.mx_UserMenu_contextMenu_prototype {
|
||||
padding-bottom: 16px;
|
||||
|
||||
.mx_UserMenu_contextMenu_header {
|
||||
padding-bottom: 0;
|
||||
padding-top: 16px;
|
||||
|
||||
&:nth-child(n + 2) {
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 85%;
|
||||
opacity: 0.2;
|
||||
border: none;
|
||||
border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
|
||||
}
|
||||
|
||||
&.mx_IconizedContextMenu {
|
||||
> .mx_IconizedContextMenu_optionList {
|
||||
margin-top: 4px;
|
||||
|
||||
&::before {
|
||||
border: none;
|
||||
}
|
||||
|
||||
> .mx_AccessibleButton {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_IconizedContextMenu .mx_IconizedContextMenu_optionList_red {
|
||||
.mx_AccessibleButton {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_contextMenu_header {
|
||||
padding: 20px;
|
||||
|
||||
// Create a flexbox to organize the header a bit easier
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_UserMenu_contextMenu_name {
|
||||
// Create another flexbox of columns to handle large user IDs
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: calc(100% - 40px); // 40px = 32px theme button + 8px margin to theme button
|
||||
|
||||
* {
|
||||
// Automatically grow all subelements to fit the container
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
|
||||
// Ellipsize any text overflow
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_UserMenu_contextMenu_displayName {
|
||||
font-weight: bold;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-20px;
|
||||
}
|
||||
|
||||
.mx_UserMenu_contextMenu_userId {
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_contextMenu_themeButton {
|
||||
min-width: 32px;
|
||||
max-width: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
border-radius: 32px;
|
||||
background-color: $theme-button-bg-color;
|
||||
cursor: pointer;
|
||||
|
||||
// to make alignment easier, create flexbox for the image
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.mx_UserMenu_contextMenu_guestPrompts,
|
||||
&.mx_UserMenu_contextMenu_hostingLink {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&.mx_UserMenu_contextMenu_guestPrompts {
|
||||
display: inline-block;
|
||||
|
||||
> span {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
|
||||
& + span {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
font-weight: normal;
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconHome::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/home.svg');
|
||||
}
|
||||
.mx_UserMenu_iconHosting::before {
|
||||
mask-image: url('$(res)/img/element-icons/brands/element.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconBell::before {
|
||||
mask-image: url('$(res)/img/element-icons/notifications.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconLock::before {
|
||||
mask-image: url('$(res)/img/element-icons/security.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconSettings::before {
|
||||
mask-image: url('$(res)/img/element-icons/settings.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconArchive::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/archived.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconMessage::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/feedback.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconSignOut::before {
|
||||
mask-image: url('$(res)/img/element-icons/leave.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconMembers::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
||||
}
|
||||
|
||||
.mx_UserMenu_iconInvite::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||
}
|
||||
}
|
|
@ -14,17 +14,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_ViewSource_label_left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mx_ViewSource_label_right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mx_ViewSource_label_bottom {
|
||||
.mx_ViewSource_separator {
|
||||
clear: both;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
padding-top: 0.7em;
|
||||
padding-bottom: 0.7em;
|
||||
}
|
||||
|
||||
.mx_ViewSource_heading {
|
||||
font-size: $font-17px;
|
||||
font-weight: 400;
|
||||
color: $primary-fg-color;
|
||||
margin-top: 0.7em;
|
||||
}
|
||||
|
||||
.mx_ViewSource pre {
|
||||
|
@ -34,3 +35,7 @@ limitations under the License.
|
|||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mx_ViewSource_details {
|
||||
margin-top: 0.8em;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ limitations under the License.
|
|||
.mx_CompleteSecurity_actionRow {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: $font-28px;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
margin-inline-start: 18px;
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
.mx_Login_submit {
|
||||
@mixin mx_DialogButton;
|
||||
width: 100%;
|
||||
margin-top: 35px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
|
@ -33,12 +33,6 @@ limitations under the License.
|
|||
cursor: default;
|
||||
}
|
||||
|
||||
.mx_AuthBody a.mx_Login_sso_link:link,
|
||||
.mx_AuthBody a.mx_Login_sso_link:hover,
|
||||
.mx_AuthBody a.mx_Login_sso_link:visited {
|
||||
color: $button-primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_Login_loader {
|
||||
display: inline;
|
||||
position: relative;
|
||||
|
@ -87,5 +81,18 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_Login_underlinedServerName {
|
||||
width: max-content;
|
||||
border-bottom: 1px dashed $accent-color;
|
||||
}
|
||||
|
||||
div.mx_AccessibleButton_kind_link.mx_Login_forgot {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
// style it as a link
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
|
||||
&.mx_AccessibleButton_disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
|
68
res/css/views/audio_messages/_AudioPlayer.scss
Normal file
68
res/css/views/audio_messages/_AudioPlayer.scss
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright 2021 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_AudioPlayer_container {
|
||||
padding: 16px 12px 12px 12px;
|
||||
max-width: 267px; // use max to make the control fit in the files/pinned panels
|
||||
|
||||
.mx_AudioPlayer_primaryContainer {
|
||||
display: flex;
|
||||
|
||||
.mx_PlayPauseButton {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mx_AudioPlayer_mediaInfo {
|
||||
flex: 1;
|
||||
overflow: hidden; // makes the ellipsis on the file name work
|
||||
|
||||
& > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_AudioPlayer_mediaName {
|
||||
color: $primary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-15px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding-bottom: 4px; // mimics the line-height differences in the Figma
|
||||
}
|
||||
|
||||
.mx_AudioPlayer_byline {
|
||||
font-size: $font-12px;
|
||||
line-height: $font-12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AudioPlayer_seek {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.mx_SeekBar {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_Clock {
|
||||
width: $font-42px; // we're not using a monospace font, so fake it
|
||||
min-width: $font-42px; // for flexbox
|
||||
padding-left: 4px; // isolate from seek bar
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
53
res/css/views/audio_messages/_PlayPauseButton.scss
Normal file
53
res/css/views/audio_messages/_PlayPauseButton.scss
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2021 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_PlayPauseButton {
|
||||
position: relative;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 32px; // for when the button is used in a flexbox
|
||||
min-height: 32px; // for when the button is used in a flexbox
|
||||
border-radius: 32px;
|
||||
background-color: $voice-playback-button-bg-color;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute; // sizing varies by icon
|
||||
background-color: $voice-playback-button-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
}
|
||||
|
||||
&.mx_PlayPauseButton_disabled::before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.mx_PlayPauseButton_play::before {
|
||||
width: 13px;
|
||||
height: 16px;
|
||||
top: 8px; // center
|
||||
left: 12px; // center
|
||||
mask-image: url('$(res)/img/element-icons/play.svg');
|
||||
}
|
||||
|
||||
&.mx_PlayPauseButton_pause::before {
|
||||
width: 10px;
|
||||
height: 12px;
|
||||
top: 10px; // center
|
||||
left: 11px; // center
|
||||
mask-image: url('$(res)/img/element-icons/pause.svg');
|
||||
}
|
||||
}
|
56
res/css/views/audio_messages/_PlaybackContainer.scss
Normal file
56
res/css/views/audio_messages/_PlaybackContainer.scss
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright 2021 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.
|
||||
*/
|
||||
|
||||
// Dev note: there's no actual component called <PlaybackContainer />. These classes
|
||||
// are shared amongst multiple voice message components.
|
||||
|
||||
// Container for live recording and playback controls
|
||||
.mx_VoiceMessagePrimaryContainer {
|
||||
// 7px top and bottom for visual design. 12px left & right, but the waveform (right)
|
||||
// has a 1px padding on it that we want to account for.
|
||||
padding: 7px 12px 7px 11px;
|
||||
|
||||
// Cheat at alignment a bit
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
contain: content;
|
||||
|
||||
.mx_Waveform {
|
||||
.mx_Waveform_bar {
|
||||
background-color: $voice-record-waveform-incomplete-fg-color;
|
||||
height: 100%;
|
||||
/* Variable set by a JS component */
|
||||
transform: scaleY(max(0.05, var(--barHeight)));
|
||||
|
||||
&.mx_Waveform_bar_100pct {
|
||||
// Small animation to remove the mechanical feel of progress
|
||||
transition: background-color 250ms ease;
|
||||
background-color: $message-body-panel-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Clock {
|
||||
width: $font-42px; // we're not using a monospace font, so fake it
|
||||
padding-right: 6px; // with the fixed width this ends up as a visual 8px most of the time, as intended.
|
||||
padding-left: 8px; // isolate from recording circle / play control
|
||||
}
|
||||
|
||||
&.mx_VoiceMessagePrimaryContainer_noWaveform {
|
||||
max-width: 162px; // with all the padding this results in 185px wide
|
||||
}
|
||||
}
|
103
res/css/views/audio_messages/_SeekBar.scss
Normal file
103
res/css/views/audio_messages/_SeekBar.scss
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright 2021 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.
|
||||
*/
|
||||
|
||||
// CSS inspiration from:
|
||||
// * https://www.w3schools.com/howto/howto_js_rangeslider.asp
|
||||
// * https://stackoverflow.com/a/28283806
|
||||
// * https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/
|
||||
|
||||
.mx_SeekBar {
|
||||
// Dev note: we deliberately do not have the -ms-track (and friends) selectors because we don't
|
||||
// need to support IE.
|
||||
|
||||
appearance: none; // default style override
|
||||
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: $quaternary-fg-color;
|
||||
outline: none; // remove blue selection border
|
||||
position: relative; // for before+after pseudo elements later on
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
appearance: none; // default style override
|
||||
|
||||
// Dev note: This needs to be duplicated with the -moz-range-thumb selector
|
||||
// because otherwise Edge (webkit) will fail to see the styles and just refuse
|
||||
// to apply them.
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: $tertiary-fg-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: $tertiary-fg-color;
|
||||
cursor: pointer;
|
||||
|
||||
// Firefox adds a border on the thumb
|
||||
border: none;
|
||||
}
|
||||
|
||||
// This is for webkit support, but we can't limit the functionality of it to just webkit
|
||||
// browsers. Firefox responds to webkit-prefixed values now, which means we can't use media
|
||||
// or support queries to selectively apply the rule. An upside is that this CSS doesn't work
|
||||
// in firefox, so it's just wasted CPU/GPU time.
|
||||
&::before { // ::before to ensure it ends up under the thumb
|
||||
content: '';
|
||||
background-color: $tertiary-fg-color;
|
||||
|
||||
// Absolute positioning to ensure it overlaps with the existing bar
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
// Sizing to match the bar
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
|
||||
// And finally dynamic width without overly hurting the rendering engine.
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleX(var(--fillTo));
|
||||
}
|
||||
|
||||
// This is firefox's built-in support for the above, with 100% less hacks.
|
||||
&::-moz-range-progress {
|
||||
background-color: $tertiary-fg-color;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
// Increase clickable area for the slider (approximately same size as browser default)
|
||||
// We do it this way to keep the same padding and margins of the element, avoiding margin math.
|
||||
// Source: https://front-back.com/expand-clickable-areas-for-a-better-touch-experience/
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
bottom: -6px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
40
res/css/views/audio_messages/_Waveform.scss
Normal file
40
res/css/views/audio_messages/_Waveform.scss
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2021 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_Waveform {
|
||||
position: relative;
|
||||
height: 30px; // tallest bar can only be 30px
|
||||
top: 1px; // because of our border trick (see below), we're off by 1px of aligntment
|
||||
|
||||
display: flex;
|
||||
align-items: center; // so the bars grow from the middle
|
||||
|
||||
overflow: hidden; // this is cheaper than a `max-height: calc(100% - 4px)` in the bar's CSS.
|
||||
|
||||
// A bar is meant to be a 2x2 circle when at zero height, and otherwise a 2px wide line
|
||||
// with rounded caps.
|
||||
.mx_Waveform_bar {
|
||||
width: 0; // 0px width means we'll end up using the border as our width
|
||||
border: 1px solid transparent; // transparent means we'll use the background colour
|
||||
border-radius: 2px; // rounded end caps, based on the border
|
||||
min-height: 0; // like the width, we'll rely on the border to give us height
|
||||
max-height: 100%; // this makes the `height: 42%` work on the element
|
||||
margin-left: 1px; // we want 2px between each bar, so 1px on either side for balance
|
||||
margin-right: 1px;
|
||||
|
||||
// background color is handled by the parent components
|
||||
}
|
||||
}
|
|
@ -34,7 +34,11 @@ limitations under the License.
|
|||
h3 {
|
||||
font-size: $font-14px;
|
||||
font-weight: 600;
|
||||
color: $authpage-primary-color;
|
||||
color: $authpage-secondary-color;
|
||||
}
|
||||
|
||||
h3.mx_AuthBody_centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a:link,
|
||||
|
@ -96,12 +100,6 @@ limitations under the License.
|
|||
}
|
||||
}
|
||||
|
||||
.mx_AuthBody_editServerDetails {
|
||||
padding-left: 1em;
|
||||
font-size: $font-12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mx_AuthBody_fieldRow {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
@ -119,36 +117,52 @@ limitations under the License.
|
|||
margin-right: 0;
|
||||
}
|
||||
|
||||
.mx_AuthBody_paddedFooter {
|
||||
height: 80px; // height of the submit button + register link
|
||||
padding-top: 28px;
|
||||
text-align: center;
|
||||
|
||||
.mx_AuthBody_paddedFooter_title {
|
||||
margin-top: 16px;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
|
||||
.mx_InlineSpinner img {
|
||||
vertical-align: sub;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AuthBody_paddedFooter_subtitle {
|
||||
margin-top: 8px;
|
||||
font-size: $font-10px;
|
||||
line-height: $font-14px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AuthBody_changeFlow {
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
||||
> a {
|
||||
font-weight: $font-semi-bold;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SSOButtons + .mx_AuthBody_changeFlow {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mx_AuthBody_spinner {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.mx_AuthBody_passwordScore {
|
||||
width: 100%;
|
||||
appearance: none;
|
||||
height: 4px;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
|
||||
&::-moz-progress-bar {
|
||||
border-radius: 2px;
|
||||
background-color: $accent-color;
|
||||
}
|
||||
|
||||
&::-webkit-progress-bar,
|
||||
&::-webkit-progress-value {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&::-webkit-progress-value {
|
||||
background-color: $accent-color;
|
||||
@media only screen and (max-width: 480px) {
|
||||
.mx_AuthBody {
|
||||
border-radius: 4px;
|
||||
width: auto;
|
||||
max-width: 500px;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ limitations under the License.
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 206px;
|
||||
padding: 25px 40px;
|
||||
padding: 25px 25px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.mx_AuthHeader {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,15 @@ limitations under the License.
|
|||
.mx_AuthHeaderLogo {
|
||||
margin-top: 15px;
|
||||
flex: 1;
|
||||
padding: 0 10px;
|
||||
padding: 0 25px;
|
||||
}
|
||||
|
||||
.mx_AuthHeaderLogo img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.mx_AuthHeaderLogo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,3 +29,9 @@ limitations under the License.
|
|||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.33);
|
||||
background-color: $authpage-modal-bg-color;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.mx_AuthPage_modal {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,35 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_emailWrapper {
|
||||
padding-right: 100px;
|
||||
position: relative;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 32px;
|
||||
|
||||
&::before, &::after {
|
||||
position: absolute;
|
||||
width: 116px;
|
||||
height: 116px;
|
||||
content: "";
|
||||
right: -10px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
background-color: rgba(244, 246, 250, 0.91);
|
||||
border-radius: 50%;
|
||||
top: -20px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background-image: url('$(res)/img/element-icons/email-prompt.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
top: -25px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_msisdnWrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -54,7 +83,10 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_termsPolicy {
|
||||
display: block;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_InteractiveAuthEntryComponents_passwordSection {
|
||||
|
|
|
@ -23,6 +23,7 @@ limitations under the License.
|
|||
font-size: $font-14px;
|
||||
font-weight: 600;
|
||||
color: $authpage-lang-color;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.mx_AuthBody_language .mx_Dropdown_arrow {
|
||||
|
|
37
res/css/views/auth/_PassphraseField.scss
Normal file
37
res/css/views/auth/_PassphraseField.scss
Normal 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.
|
||||
*/
|
||||
|
||||
$PassphraseStrengthHigh: $accent-color;
|
||||
$PassphraseStrengthMedium: $username-variant5-color;
|
||||
$PassphraseStrengthLow: $notice-primary-color;
|
||||
|
||||
progress.mx_PassphraseField_progress {
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
height: 4px;
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
|
||||
@mixin ProgressBarBorderRadius "2px";
|
||||
@mixin ProgressBarColour $PassphraseStrengthLow;
|
||||
&[value="2"], &[value="3"] {
|
||||
@mixin ProgressBarColour $PassphraseStrengthMedium;
|
||||
}
|
||||
&[value="4"] {
|
||||
@mixin ProgressBarColour $PassphraseStrengthHigh;
|
||||
}
|
||||
}
|
|
@ -1,69 +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_ServerTypeSelector {
|
||||
display: flex;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_type {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_type:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_type:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_label {
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
color: $authpage-primary-color;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_type .mx_AccessibleButton {
|
||||
padding: 10px;
|
||||
border: 1px solid $input-border-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_type.mx_ServerTypeSelector_type_selected .mx_AccessibleButton {
|
||||
border-color: $input-valid-border-color;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 18px;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 600;
|
||||
color: $authpage-primary-color;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_logo > div {
|
||||
display: flex;
|
||||
width: 70%;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.mx_ServerTypeSelector_description {
|
||||
font-size: $font-10px;
|
||||
}
|
|
@ -18,9 +18,14 @@ limitations under the License.
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
&.mx_WelcomePage_registrationDisabled {
|
||||
.mx_ButtonCreateAccount {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Welcome .mx_AuthBody_language {
|
||||
width: 120px;
|
||||
width: 160px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ limitations under the License.
|
|||
// different results during full reflow of the page vs. incremental reflow
|
||||
// of small portions. While that's surely a browser bug, we can avoid it by
|
||||
// using `inline-block` instead of the default `inline`.
|
||||
// https://github.com/vector-im/riot-web/issues/5594
|
||||
// https://github.com/vector-im/element-web/issues/5594
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1535053
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=255139
|
||||
display: inline-block;
|
||||
|
@ -41,7 +41,7 @@ limitations under the License.
|
|||
|
||||
.mx_BaseAvatar_image {
|
||||
object-fit: cover;
|
||||
border-radius: 40px;
|
||||
border-radius: 125px;
|
||||
vertical-align: top;
|
||||
background-color: $avatar-bg-color;
|
||||
}
|
||||
|
|
73
res/css/views/avatars/_DecoratedRoomAvatar.scss
Normal file
73
res/css/views/avatars/_DecoratedRoomAvatar.scss
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
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_DecoratedRoomAvatar, .mx_ExtraTile {
|
||||
position: relative;
|
||||
contain: content;
|
||||
|
||||
&.mx_DecoratedRoomAvatar_cutout .mx_BaseAvatar {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/decorated-avatar-mask.svg');
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon {
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
right: -2px;
|
||||
margin: 4px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon::before {
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon_globe::before {
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $secondary-fg-color;
|
||||
mask-image: url('$(res)/img/globe.svg');
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon_offline::before {
|
||||
background-color: $presence-offline;
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon_online::before {
|
||||
background-color: $presence-online;
|
||||
}
|
||||
|
||||
.mx_DecoratedRoomAvatar_icon_away::before {
|
||||
background-color: $presence-away;
|
||||
}
|
||||
|
||||
.mx_NotificationBadge, .mx_RoomTile_badgeContainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
.mx_MessageComposer_avatar .mx_BaseAvatar {
|
||||
padding: 2px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 15px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_avatar .mx_BaseAvatar_initial {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
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.
|
||||
|
@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_ReactionsRowButtonTooltip_reactedWith {
|
||||
opacity: 0.7;
|
||||
.mx_WidgetAvatar {
|
||||
border-radius: 4px;
|
||||
}
|
161
res/css/views/beta/_BetaCard.scss
Normal file
161
res/css/views/beta/_BetaCard.scss
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
Copyright 2021 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_BetaCard {
|
||||
margin-bottom: 20px;
|
||||
padding: 24px;
|
||||
background-color: $settings-profile-placeholder-bg-color;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.mx_BetaCard_columns {
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
.mx_BetaCard_title {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-18px;
|
||||
line-height: $font-22px;
|
||||
color: $primary-fg-color;
|
||||
margin: 4px 0 14px;
|
||||
|
||||
.mx_BetaCard_betaPill {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_BetaCard_caption {
|
||||
font-size: $font-15px;
|
||||
line-height: $font-20px;
|
||||
color: $secondary-fg-color;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.mx_BetaCard_buttons .mx_AccessibleButton {
|
||||
display: block;
|
||||
margin: 12px 0;
|
||||
padding: 7px 40px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.mx_BetaCard_disclaimer {
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
> img {
|
||||
margin: auto 0 auto 20px;
|
||||
width: 300px;
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_BetaCard_relatedSettings {
|
||||
.mx_SettingsFlag {
|
||||
margin: 16px 0 0;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $primary-fg-color;
|
||||
|
||||
.mx_SettingsFlag_microcopy {
|
||||
margin-top: 4px;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_BetaCard_betaPill {
|
||||
background-color: $accent-color-alt;
|
||||
padding: 4px 10px;
|
||||
border-radius: 8px;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
color: #FFFFFF;
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
|
||||
&.mx_BetaCard_betaPill_clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
$pulse-color: $accent-color-alt;
|
||||
$dot-size: 12px;
|
||||
|
||||
.mx_BetaDot {
|
||||
border-radius: 50%;
|
||||
margin: 10px;
|
||||
height: $dot-size;
|
||||
width: $dot-size;
|
||||
transform: scale(1);
|
||||
background: rgba($pulse-color, 1);
|
||||
animation: mx_Beta_bluePulse 2s infinite;
|
||||
animation-iteration-count: 20;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: scale(1);
|
||||
transform-origin: center center;
|
||||
animation-name: mx_Beta_bluePulse_shadow;
|
||||
animation-duration: inherit;
|
||||
animation-iteration-count: inherit;
|
||||
border-radius: 50%;
|
||||
background: rgba($pulse-color, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mx_Beta_bluePulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mx_Beta_bluePulse_shadow {
|
||||
0% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(2.2);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2020 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.
|
||||
|
@ -14,10 +14,10 @@ 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;
|
||||
.mx_CallContextMenu_item {
|
||||
width: 205px;
|
||||
height: 40px;
|
||||
padding-left: 16px;
|
||||
line-height: 40px;
|
||||
vertical-align: center;
|
||||
}
|
156
res/css/views/context_menus/_IconizedContextMenu.scss
Normal file
156
res/css/views/context_menus/_IconizedContextMenu.scss
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// A context menu that largely fits the | [icon] [label] | format.
|
||||
.mx_IconizedContextMenu {
|
||||
min-width: 146px;
|
||||
|
||||
.mx_IconizedContextMenu_optionList {
|
||||
& > * {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
// the notFirst class is for cases where the optionList might be under a header of sorts.
|
||||
&:nth-child(n + 2), .mx_IconizedContextMenu_optionList_notFirst {
|
||||
// This is a bit of a hack when we could just use a simple border-top property,
|
||||
// however we have a (kinda) good reason for doing it this way: we need opacity.
|
||||
// To get the right color, we need an opacity modifier which means we have to work
|
||||
// around the problem. PostCSS doesn't support the opacity() function, and if we
|
||||
// use something like postcss-functions we quickly run into an issue where the
|
||||
// function we would define gets passed a CSS variable for custom themes, which
|
||||
// can't be converted easily even when considering https://stackoverflow.com/a/41265350/7037379
|
||||
//
|
||||
// Therefore, we just hack in a line and border the thing ourselves
|
||||
&::before {
|
||||
border-top: 1px solid $primary-fg-color;
|
||||
opacity: 0.1;
|
||||
content: '';
|
||||
|
||||
// Counteract the padding problems (width: 100% ignores the 40px padding,
|
||||
// unless we position it absolutely then it does the right thing).
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// round the top corners of the top button for the hover effect to be bounded
|
||||
&:first-child .mx_AccessibleButton:first-child {
|
||||
border-radius: 8px 8px 0 0; // radius matches .mx_ContextualMenu
|
||||
}
|
||||
|
||||
// round the bottom corners of the bottom button for the hover effect to be bounded
|
||||
&:last-child .mx_AccessibleButton:last-child {
|
||||
border-radius: 0 0 8px 8px; // radius matches .mx_ContextualMenu
|
||||
}
|
||||
|
||||
.mx_AccessibleButton {
|
||||
// pad the inside of the button so that the hover background is padded too
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
text-decoration: none;
|
||||
color: $primary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
|
||||
// Create a flexbox to more easily define the list items
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: $menu-selected-color;
|
||||
}
|
||||
|
||||
&.mx_AccessibleButton_disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
img, .mx_IconizedContextMenu_icon { // icons
|
||||
width: 16px;
|
||||
min-width: 16px;
|
||||
max-width: 16px;
|
||||
}
|
||||
|
||||
span.mx_IconizedContextMenu_label { // labels
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
|
||||
// Ellipsize any text overflow
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon + .mx_IconizedContextMenu_label {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_optionList_red {
|
||||
.mx_AccessibleButton {
|
||||
color: $warning-color !important;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon::before {
|
||||
background-color: $warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_active {
|
||||
&.mx_AccessibleButton, .mx_AccessibleButton {
|
||||
color: $accent-color !important;
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_icon::before {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.mx_IconizedContextMenu_compact {
|
||||
.mx_IconizedContextMenu_optionList > * {
|
||||
padding: 8px 16px 8px 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_IconizedContextMenu_checked {
|
||||
margin-left: 16px;
|
||||
margin-right: -5px;
|
||||
|
||||
&::before {
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/checkmark.svg');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2021 Michael Weimann <mail@michael-weimann.eu>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -15,15 +16,69 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
.mx_MessageContextMenu {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_field {
|
||||
padding: 3px 6px 3px 6px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.mx_IconizedContextMenu_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
|
||||
.mx_MessageContextMenu_field.mx_MessageContextMenu_fieldSet {
|
||||
font-weight: bold;
|
||||
&::before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconCollapse::before {
|
||||
mask-image: url('$(res)/img/element-icons/message/chevron-up.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconReport::before {
|
||||
mask-image: url('$(res)/img/element-icons/warning-badge.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconLink::before {
|
||||
mask-image: url('$(res)/img/element-icons/link.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconPermalink::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/share.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconUnhidePreview::before {
|
||||
mask-image: url('$(res)/img/element-icons/settings/appearance.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconForward::before {
|
||||
mask-image: url('$(res)/img/element-icons/message/fwd.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconRedact::before {
|
||||
mask-image: url('$(res)/img/element-icons/trashcan.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconResend::before {
|
||||
mask-image: url('$(res)/img/element-icons/retry.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconSource::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/format-bar/code.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconQuote::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/format-bar/quote.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconPin::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
|
||||
}
|
||||
|
||||
.mx_MessageContextMenu_iconUnpin::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/pin.svg');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket 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_RoomTileContextMenu {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_icon {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_icon_set {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field, .mx_RoomTileContextMenu_leave {
|
||||
padding-top: 8px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: $font-16px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon_set {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_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;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_leave {
|
||||
color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_picker {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field {
|
||||
padding-top: 4px;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 8px; /* 20px */
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldSet {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldDisabled {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_icon {
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_activeIcon {
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.mx_RoomTileContextMenu_notif_fieldSet .mx_RoomTileContextMenu_notif_activeIcon {
|
||||
opacity: 1;
|
||||
}
|
|
@ -15,9 +15,8 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
.mx_TagTileContextMenu_item {
|
||||
padding-top: 8px;
|
||||
padding: 8px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
|
@ -25,15 +24,31 @@ limitations under the License.
|
|||
line-height: $font-16px;
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_item object {
|
||||
pointer-events: none;
|
||||
.mx_TagTileContextMenu_item::before {
|
||||
content: '';
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
background-color: currentColor;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_viewCommunity::before {
|
||||
mask-image: url('$(res)/img/element-icons/view-community.svg');
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_item_icon {
|
||||
padding-right: 8px;
|
||||
padding-left: 4px;
|
||||
display: inline-block;
|
||||
.mx_TagTileContextMenu_moveUp::before {
|
||||
transform: rotate(180deg);
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_moveDown::before {
|
||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_hideCommunity::before {
|
||||
mask-image: url('$(res)/img/element-icons/hide.svg');
|
||||
}
|
||||
|
||||
.mx_TagTileContextMenu_separator {
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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_TopLeftMenu {
|
||||
min-width: 210px;
|
||||
border-radius: 4px;
|
||||
|
||||
.mx_TopLeftMenu_greyedText {
|
||||
font-size: $font-12px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_upgradeLink {
|
||||
font-size: $font-12px;
|
||||
|
||||
img {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_section:not(:last-child) {
|
||||
border-bottom: 1px solid $menu-border-color;
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_section_noIcon {
|
||||
margin: 5px 0;
|
||||
padding: 5px 20px 5px 15px;
|
||||
|
||||
div:not(:first-child) {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_section_withIcon {
|
||||
margin: 5px 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
.mx_TopLeftMenu_icon_home::after {
|
||||
mask-image: url('$(res)/img/feather-customised/home.svg');
|
||||
}
|
||||
|
||||
.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');
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_icon_signin::after {
|
||||
mask-image: url('$(res)/img/feather-customised/sign-in.svg');
|
||||
}
|
||||
|
||||
.mx_TopLeftMenu_icon_signout::after {
|
||||
mask-image: url('$(res)/img/feather-customised/sign-out.svg');
|
||||
}
|
||||
|
||||
.mx_AccessibleButton::after {
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: 0 center;
|
||||
mask-size: 16px;
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
content: "";
|
||||
top: 5px;
|
||||
left: 14px;
|
||||
background-color: $primary-fg-color;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
padding: 5px 20px 5px 43px;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton:hover {
|
||||
background-color: $menu-selected-color;
|
||||
}
|
||||
}
|
||||
}
|
281
res/css/views/dialogs/_AddExistingToSpaceDialog.scss
Normal file
281
res/css/views/dialogs/_AddExistingToSpaceDialog.scss
Normal file
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
Copyright 2021 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_AddExistingToSpaceDialog_wrapper {
|
||||
.mx_Dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace {
|
||||
.mx_SearchBox {
|
||||
// To match the space around the title
|
||||
margin: 0 0 15px 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_noResults {
|
||||
display: block;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_section {
|
||||
&:not(:first-child) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
> h3 {
|
||||
margin: 0;
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-12px;
|
||||
font-weight: $font-semi-bold;
|
||||
line-height: $font-15px;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_entry {
|
||||
display: flex;
|
||||
margin-top: 12px;
|
||||
|
||||
// we can't target .mx_BaseAvatar here as it'll break the decorated avatar styling
|
||||
.mx_DecoratedRoomAvatar {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_entry_name {
|
||||
font-size: $font-15px;
|
||||
line-height: 30px;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.mx_Checkbox {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_section_spaces {
|
||||
.mx_BaseAvatar {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_section_experimental {
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
margin: 12px 0;
|
||||
padding: 8px 8px 8px 42px;
|
||||
background-color: $header-panel-bg-color;
|
||||
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: calc(50% - 8px); // vertical centering
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background-color: $secondary-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||
mask-position: center;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_footer {
|
||||
display: flex;
|
||||
margin-top: 20px;
|
||||
|
||||
> span {
|
||||
flex-grow: 1;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $secondary-fg-color;
|
||||
|
||||
.mx_ProgressBar {
|
||||
height: 8px;
|
||||
width: 100%;
|
||||
|
||||
@mixin ProgressBarBorderRadius 8px;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_progressText {
|
||||
margin-top: 8px;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
|
||||
> * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_error {
|
||||
padding-left: 12px;
|
||||
|
||||
> img {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_errorHeading {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-18px;
|
||||
color: $notice-primary-color;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_errorCaption {
|
||||
margin-top: 4px;
|
||||
font-size: $font-12px;
|
||||
line-height: $font-15px;
|
||||
color: $primary-fg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton {
|
||||
display: inline-block;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_primary {
|
||||
padding: 8px 36px;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace_retryButton {
|
||||
margin-left: 12px;
|
||||
padding-left: 24px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: $primary-fg-color;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-image: url('$(res)/img/element-icons/retry.svg');
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpaceDialog {
|
||||
width: 480px;
|
||||
color: $primary-fg-color;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
min-height: 0;
|
||||
height: 80vh;
|
||||
|
||||
.mx_Dialog_title {
|
||||
display: flex;
|
||||
|
||||
.mx_BaseAvatar_image {
|
||||
border-radius: 8px;
|
||||
margin: 0;
|
||||
vertical-align: unset;
|
||||
}
|
||||
|
||||
.mx_BaseAvatar {
|
||||
display: inline-flex;
|
||||
margin: auto 16px auto 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
> div {
|
||||
> h1 {
|
||||
font-weight: $font-semi-bold;
|
||||
font-size: $font-18px;
|
||||
line-height: $font-22px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpaceDialog_onlySpace {
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Dropdown_input {
|
||||
border: none;
|
||||
|
||||
> .mx_Dropdown_option {
|
||||
padding-left: 0;
|
||||
flex: unset;
|
||||
height: unset;
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-15px;
|
||||
line-height: $font-24px;
|
||||
|
||||
.mx_BaseAvatar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_Dropdown_menu {
|
||||
.mx_AddExistingToSpaceDialog_dropdownOptionActive {
|
||||
color: $accent-color;
|
||||
padding-right: 32px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 8px;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
mask-position: center;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-color: $accent-color;
|
||||
mask-image: url('$(res)/img/element-icons/roomlist/checkmark.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AddExistingToSpace {
|
||||
display: contents;
|
||||
}
|
||||
}
|
30
res/css/views/dialogs/_BetaFeedbackDialog.scss
Normal file
30
res/css/views/dialogs/_BetaFeedbackDialog.scss
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2021 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_BetaFeedbackDialog {
|
||||
.mx_BetaFeedbackDialog_subheading {
|
||||
color: $primary-fg-color;
|
||||
font-size: $font-14px;
|
||||
line-height: $font-20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
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.
|
||||
|
@ -14,13 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export default function(dest, src) {
|
||||
for (const i in src) {
|
||||
if (src.hasOwnProperty(i)) {
|
||||
dest[i] = src[i];
|
||||
.mx_BugReportDialog {
|
||||
.mx_BugReportDialog_download {
|
||||
.mx_AccessibleButton_kind_link {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
88
res/css/views/dialogs/_CommunityPrototypeInviteDialog.scss
Normal file
88
res/css/views/dialogs/_CommunityPrototypeInviteDialog.scss
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
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_CommunityPrototypeInviteDialog {
|
||||
&.mx_Dialog_fixedWidth {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
margin-bottom: 0;
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_people {
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.mx_AccessibleButton {
|
||||
display: inline-block;
|
||||
background-color: $focus-bg-color; // XXX: Abuse of variables
|
||||
border-radius: 4px;
|
||||
padding: 3px 5px;
|
||||
font-size: $font-12px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_morePeople {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_person {
|
||||
position: relative;
|
||||
margin-top: 4px;
|
||||
|
||||
& > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mx_Checkbox {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(50% - 8px); // checkbox is 16px high
|
||||
width: 16px; // to force a square
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_personIdentifiers {
|
||||
display: inline-block;
|
||||
|
||||
& > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_personName {
|
||||
font-weight: 600;
|
||||
font-size: $font-14px;
|
||||
color: $primary-fg-color;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_personId {
|
||||
font-size: $font-12px;
|
||||
color: $muted-fg-color;
|
||||
margin-left: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CommunityPrototypeInviteDialog_primaryButton {
|
||||
display: block;
|
||||
font-size: $font-13px;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
}
|
102
res/css/views/dialogs/_CreateCommunityPrototypeDialog.scss
Normal file
102
res/css/views/dialogs/_CreateCommunityPrototypeDialog.scss
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
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_CreateCommunityPrototypeDialog {
|
||||
.mx_Dialog_content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_colName {
|
||||
flex-basis: 66.66%;
|
||||
padding-right: 100px;
|
||||
|
||||
.mx_Field input {
|
||||
font-size: $font-16px;
|
||||
line-height: $font-20px;
|
||||
}
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_subtext {
|
||||
display: block;
|
||||
color: $muted-fg-color;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&.mx_CreateCommunityPrototypeDialog_subtext_error {
|
||||
color: $warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_communityId {
|
||||
position: relative;
|
||||
|
||||
.mx_InfoTooltip {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_AccessibleButton {
|
||||
display: block;
|
||||
height: 32px;
|
||||
font-size: $font-16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_colAvatar {
|
||||
flex-basis: 33.33%;
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_avatarContainer {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_avatar,
|
||||
.mx_CreateCommunityPrototypeDialog_placeholderAvatar {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 96px;
|
||||
}
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_placeholderAvatar {
|
||||
background-color: #368bd6; // hardcoded for both themes
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
background-color: #fff; // hardcoded because the background is
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 96px;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
vertical-align: middle;
|
||||
mask-image: url('$(res)/img/element-icons/add-photo.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CreateCommunityPrototypeDialog_tip {
|
||||
& > b, & > span {
|
||||
display: block;
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -223,3 +223,54 @@ limitations under the License.
|
|||
content: ":";
|
||||
}
|
||||
}
|
||||
|
||||
.mx_DevTools_SettingsExplorer {
|
||||
table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
|
||||
th {
|
||||
// Colour choice: first one autocomplete gave me.
|
||||
border-bottom: 1px solid $accent-color;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td, th {
|
||||
width: 360px; // "feels right" number
|
||||
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td + td, th + th {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
// Colour choice: first one autocomplete gave me.
|
||||
background-color: $accent-color-50pct;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_DevTools_SettingsExplorer_mutable {
|
||||
background-color: $accent-color;
|
||||
}
|
||||
|
||||
.mx_DevTools_SettingsExplorer_immutable {
|
||||
background-color: $warning-color;
|
||||
}
|
||||
|
||||
.mx_DevTools_SettingsExplorer_edit {
|
||||
float: right;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.mx_DevTools_SettingsExplorer_warning {
|
||||
border: 2px solid $warning-color;
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
|
77
res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
Normal file
77
res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// XXX: many of these styles are shared with the create dialog
|
||||
.mx_EditCommunityPrototypeDialog {
|
||||
&.mx_Dialog_fixedWidth {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
margin-bottom: 12px;
|
||||
|
||||
.mx_AccessibleButton.mx_AccessibleButton_kind_primary {
|
||||
display: block;
|
||||
height: 32px;
|
||||
font-size: $font-16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.mx_EditCommunityPrototypeDialog_rowAvatar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mx_EditCommunityPrototypeDialog_avatarContainer {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.mx_EditCommunityPrototypeDialog_avatar,
|
||||
.mx_EditCommunityPrototypeDialog_placeholderAvatar {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 96px;
|
||||
}
|
||||
|
||||
.mx_EditCommunityPrototypeDialog_placeholderAvatar {
|
||||
background-color: #368bd6; // hardcoded for both themes
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
background-color: #fff; // hardcoded because the background is
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 96px;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
mask-position: center;
|
||||
content: '';
|
||||
vertical-align: middle;
|
||||
mask-image: url('$(res)/img/element-icons/add-photo.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mx_EditCommunityPrototypeDialog_tip {
|
||||
margin-left: 20px;
|
||||
|
||||
& > b, & > span {
|
||||
display: block;
|
||||
color: $muted-fg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
121
res/css/views/dialogs/_FeedbackDialog.scss
Normal file
121
res/css/views/dialogs/_FeedbackDialog.scss
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
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_FeedbackDialog {
|
||||
hr {
|
||||
margin: 24px 0;
|
||||
border-color: $input-border-color;
|
||||
}
|
||||
|
||||
.mx_Dialog_content {
|
||||
margin-bottom: 24px;
|
||||
|
||||
> h2 {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_FeedbackDialog_section {
|
||||
position: relative;
|
||||
padding-left: 52px;
|
||||
|
||||
> p {
|
||||
color: $tertiary-fg-color;
|
||||
}
|
||||
|
||||
.mx_AccessibleButton_kind_link {
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
a, .mx_AccessibleButton_kind_link {
|
||||
color: $accent-color;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&::before, &::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&::before {
|
||||
background-color: $icon-button-color;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: $avatar-initial-color; // TODO
|
||||
mask-position: center;
|
||||
mask-size: 24px;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_FeedbackDialog_reportBug {
|
||||
&::after {
|
||||
mask-image: url('$(res)/img/feather-customised/bug.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.mx_FeedbackDialog_rateApp {
|
||||
.mx_RadioButton {
|
||||
display: inline-flex;
|
||||
font-size: 20px;
|
||||
transition: font-size 1s, border .5s;
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 24px;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
|
||||
input[type="radio"] + div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mx_RadioButton_content {
|
||||
background: $icon-button-color;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
border-radius: 20px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.mx_RadioButton_spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& + .mx_RadioButton {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RadioButton_checked {
|
||||
font-size: 24px;
|
||||
border-color: $accent-color;
|
||||
}
|
||||
|
||||
&::after {
|
||||
mask-image: url('$(res)/img/element-icons/feedback.svg');
|
||||
}
|
||||
}
|
||||
}
|
159
res/css/views/dialogs/_ForwardDialog.scss
Normal file
159
res/css/views/dialogs/_ForwardDialog.scss
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Copyright 2021 Robin Townsend <robin@robin.town>
|
||||
|
||||
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_ForwardDialog {
|
||||
width: 520px;
|
||||
color: $primary-fg-color;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
min-height: 0;
|
||||
height: 80vh;
|
||||
|
||||
> h3 {
|
||||
margin: 0 0 6px;
|
||||
color: $secondary-fg-color;
|
||||
font-size: $font-12px;
|
||||
font-weight: $font-semi-bold;
|
||||
line-height: $font-15px;
|
||||
}
|
||||
|
||||
> .mx_ForwardDialog_preview {
|
||||
max-height: 30%;
|
||||
flex-shrink: 0;
|
||||
overflow-y: auto;
|
||||
|
||||
div {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.mx_EventTile_msgOption {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// When forwarding messages from encrypted rooms, EventTile will complain
|
||||
// that our preview is unencrypted, which doesn't actually matter
|
||||
.mx_EventTile_e2eIcon_unencrypted {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// We also hide download links to not encourage users to try interacting
|
||||
.mx_MFileBody_download {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
> hr {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid $input-border-color;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
> .mx_ForwardList {
|
||||
display: contents;
|
||||
|
||||
.mx_SearchBox {
|
||||
// To match the space around the title
|
||||
margin: 0 0 15px 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.mx_ForwardList_content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.mx_ForwardList_noResults {
|
||||
display: block;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mx_ForwardList_results {
|
||||
&:not(:first-child) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.mx_ForwardList_entry {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 32px;
|
||||
padding: 6px;
|
||||
border-radius: 8px;
|
||||
|
||||
&:hover {
|
||||
background-color: $groupFilterPanel-bg-color;
|
||||
}
|
||||
|
||||
.mx_ForwardList_roomButton {
|
||||
display: flex;
|
||||
margin-right: 12px;
|
||||
min-width: 0;
|
||||
|
||||
.mx_DecoratedRoomAvatar {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.mx_ForwardList_entry_name {
|
||||
font-size: $font-15px;
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_ForwardList_sendButton {
|
||||
position: relative;
|
||||
|
||||
&:not(.mx_ForwardList_canSend) .mx_ForwardList_sendLabel {
|
||||
// Hide the "Send" label while preserving button size
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mx_ForwardList_sendIcon, .mx_NotificationBadge {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.mx_NotificationBadge {
|
||||
// Match the failed to send indicator's color with the disabled button
|
||||
background-color: $button-danger-disabled-fg-color;
|
||||
}
|
||||
|
||||
&.mx_ForwardList_sending .mx_ForwardList_sendIcon {
|
||||
background-color: $button-primary-bg-color;
|
||||
mask-image: url('$(res)/img/element-icons/circle-sending.svg');
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 14px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&.mx_ForwardList_sent .mx_ForwardList_sendIcon {
|
||||
background-color: $button-primary-bg-color;
|
||||
mask-image: url('$(res)/img/element-icons/circle-sent.svg');
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 14px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue