Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into fix-pip-color
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonBrandner committed Apr 23, 2021
2 parents 9ffef8f + 5b8cd10 commit d757b7d
Show file tree
Hide file tree
Showing 615 changed files with 23,180 additions and 4,936 deletions.
2 changes: 1 addition & 1 deletion .eslintignore.errorfiles
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# autogenerated file: run scripts/generate-eslint-error-ignore-file to update.

src/Markdown.js
src/Velociraptor.js
src/NodeAnimator.js
src/components/structures/RoomDirectory.js
src/components/views/rooms/MemberList.js
src/ratelimitedfunc.js
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ package-lock.json
/src/component-index.js

.DS_Store
*.tmp
1 change: 1 addition & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
387 changes: 387 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ 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}],
Expand All @@ -18,6 +21,6 @@ module.exports = {
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-flow-comments",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-runtime"
]
"@babel/plugin-transform-runtime",
],
};
6 changes: 3 additions & 3 deletions docs/ciderEditor.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.

Expand Down
19 changes: 19 additions & 0 deletions docs/media-handling.md
Original file line number Diff line number Diff line change
@@ -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.
66 changes: 40 additions & 26 deletions docs/room-list-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It's so complicated it needs its own README.

Legend:
* Orange = External event.
* Purple = Deterministic flow.
* Purple = Deterministic flow.
* Green = Algorithm definition.
* Red = Exit condition/point.
* Blue = Process definition.
Expand All @@ -24,8 +24,8 @@ 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.
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
Expand All @@ -36,7 +36,7 @@ useful.

### Tag sorting algorithm: Manual

Manual sorting makes use of the `order` property present on all tags for a room, per the
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.

Expand Down Expand Up @@ -74,15 +74,15 @@ relative (perceived) importance to the user:
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
* **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
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
Expand All @@ -103,48 +103,62 @@ receive another notification which causes the room to move into the topmost posi
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
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
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
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, which are then passed along to the algorithm
implementations. The implementations then get to decide how to actually filter the rooms, however in
practice the base `Algorithm` class deals with the filtering in a more optimized/generic way.
Filters are provided to the store as condition classes and have two major kinds: Prefilters and Runtime.

The results of 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
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
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
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
"version": "3.14.0",
"version": "3.18.0",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
Expand Down Expand Up @@ -83,6 +83,7 @@
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-widget-api": "^0.1.0-beta.13",
"minimist": "^1.2.5",
"opus-recorder": "^8.0.3",
"pako": "^2.0.3",
"parse5": "^6.0.1",
"png-chunks-extract": "^1.0.0",
Expand All @@ -101,7 +102,6 @@
"tar-js": "^0.3.0",
"text-encoding-utf-8": "^1.0.2",
"url": "^0.11.0",
"velocity-animate": "^1.5.2",
"what-input": "^5.2.10",
"zxcvbn": "^4.4.2"
},
Expand Down Expand Up @@ -157,6 +157,7 @@
"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",
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
Expand Down
69 changes: 20 additions & 49 deletions res/css/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ $MessageTimestamp_width_hover: calc($MessageTimestamp_width - 2 * $EventTile_e2e

:root {
font-size: 10px;

--transition-short: .1s;
--transition-standard: .3s;
}

@media (prefers-reduced-motion) {
:root {
--transition-short: 0;
--transition-standard: 0;
}
}

html {
Expand Down Expand Up @@ -303,7 +313,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;
}

Expand All @@ -315,6 +325,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 {
Expand Down Expand Up @@ -395,6 +406,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 {
Expand Down Expand Up @@ -489,54 +501,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 {
Expand Down Expand Up @@ -606,6 +570,13 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
}
}

@define-mixin ProgressBarBgColour $colour {
background-color: $colour;
&::-webkit-progress-bar {
background-color: $colour;
}
}

@define-mixin ProgressBarBorderRadius $radius {
border-radius: $radius;
&::-moz-progress-bar {
Expand Down
Loading

0 comments on commit d757b7d

Please sign in to comment.