Merge branch 'develop' into travis/poc/theme-command

This commit is contained in:
Travis Ralston 2020-03-06 17:33:22 -07:00
commit 65d7bb2ef9
14 changed files with 90 additions and 58 deletions

View File

@ -34,7 +34,7 @@ All code lands on the `develop` branch - `master` is only used for stable releas
**Please file PRs against `develop`!!** **Please file PRs against `develop`!!**
Please follow the standard Matrix contributor's guide: Please follow the standard Matrix contributor's guide:
https://github.com/matrix-org/synapse/tree/master/CONTRIBUTING.rst https://github.com/matrix-org/matrix-js-sdk/blob/develop/CONTRIBUTING.rst
Please follow the Matrix JS/React code style as per: Please follow the Matrix JS/React code style as per:
https://github.com/matrix-org/matrix-react-sdk/blob/master/code_style.md https://github.com/matrix-org/matrix-react-sdk/blob/master/code_style.md

View File

@ -289,17 +289,11 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
display: inline-block; display: inline-block;
width: 14px; width: 14px;
height: 14px; height: 14px;
top: 29px; top: -19px;
user-select: none; user-select: none;
z-index: 1; z-index: 1;
} }
.mx_EventTile_continuation .mx_EventTile_readAvatars,
.mx_EventTile_info .mx_EventTile_readAvatars,
.mx_EventTile_emote .mx_EventTile_readAvatars {
top: 7px;
}
.mx_EventTile_readAvatars .mx_BaseAvatar { .mx_EventTile_readAvatars .mx_BaseAvatar {
position: absolute; position: absolute;
display: inline-block; display: inline-block;
@ -634,15 +628,6 @@ div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody {
top: 27px; top: 27px;
} }
.mx_EventTile_continuation .mx_EventTile_readAvatars,
.mx_EventTile_emote .mx_EventTile_readAvatars {
top: 5px;
}
.mx_EventTile_info .mx_EventTile_readAvatars {
top: 4px;
}
.mx_RoomView_MessageList h2 { .mx_RoomView_MessageList h2 {
margin-top: 6px; margin-top: 6px;
} }

View File

@ -56,3 +56,17 @@ limitations under the License.
mask-position: 9px 13px; mask-position: 9px 13px;
background: $roomtile-name-color; background: $roomtile-name-color;
} }
.mx_TopUnreadMessagesBar_markAsRead {
display: block;
width: 18px;
height: 18px;
background-image: url('$(res)/img/cancel.svg');
background-position: center;
background-size: 10px;
background-repeat: no-repeat;
background-color: $primary-bg-color;
border: 1.3px solid $roomtile-name-color;
border-radius: 99px;
margin: 5px auto;
}

View File

@ -141,15 +141,17 @@ export default class ManageEventIndexDialog extends React.Component {
let crawlerState; let crawlerState;
if (this.state.currentRoom === null) { if (this.state.currentRoom === null) {
crawlerState = _t("Not currently downloading messages for any room."); crawlerState = _t("Not currently indexing messages for any room.");
} else { } else {
crawlerState = ( crawlerState = (
_t("Downloading mesages for %(currentRoom)s.", { currentRoom: this.state.currentRoom }) _t("Currently indexing: %(currentRoom)s.", { currentRoom: this.state.currentRoom })
); );
} }
const Field = sdk.getComponent('views.elements.Field'); const Field = sdk.getComponent('views.elements.Field');
const doneRooms = Math.max(0, (this.state.roomCount - this.state.crawlingRoomsCount));
const eventIndexingSettings = ( const eventIndexingSettings = (
<div> <div>
{ {
@ -158,13 +160,13 @@ export default class ManageEventIndexDialog extends React.Component {
) )
} }
<div className='mx_SettingsTab_subsectionText'> <div className='mx_SettingsTab_subsectionText'>
{crawlerState}<br />
{_t("Space used:")} {formatBytes(this.state.eventIndexSize, 0)}<br /> {_t("Space used:")} {formatBytes(this.state.eventIndexSize, 0)}<br />
{_t("Indexed messages:")} {formatCountLong(this.state.eventCount)}<br /> {_t("Indexed messages:")} {formatCountLong(this.state.eventCount)}<br />
{_t("Indexed rooms:")} {_t("%(crawlingRooms)s out of %(totalRooms)s", { {_t("Indexed rooms:")} {_t("%(doneRooms)s out of %(totalRooms)s", {
crawlingRooms: formatCountLong(this.state.crawlingRoomsCount), doneRooms: formatCountLong(doneRooms),
totalRooms: formatCountLong(this.state.roomCount), totalRooms: formatCountLong(this.state.roomCount),
})} <br /> })} <br />
{crawlerState}<br />
<Field <Field
id={"crawlerSleepTimeMs"} id={"crawlerSleepTimeMs"}
label={_t('Message downloading sleep time(ms)')} label={_t('Message downloading sleep time(ms)')}

View File

@ -1495,9 +1495,20 @@ export default createReactClass({
} }
}); });
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
cli.on("crypto.verification.request", request => { cli.on("crypto.verification.request", request => {
if (request.pending) { const isFlagOn = SettingsStore.isFeatureEnabled("feature_cross_signing");
if (!isFlagOn && !request.channel.deviceId) {
request.cancel({code: "m.invalid_message", reason: "This client has cross-signing disabled"});
return;
}
if (request.verifier) {
const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog");
Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, {
verifier: request.verifier,
}, null, /* priority = */ false, /* static = */ true);
} else if (request.pending) {
ToastStore.sharedInstance().addOrReplaceToast({ ToastStore.sharedInstance().addOrReplaceToast({
key: 'verifreq_' + request.channel.transactionId, key: 'verifreq_' + request.channel.transactionId,
title: _t("Verification Request"), title: _t("Verification Request"),
@ -1507,14 +1518,6 @@ export default createReactClass({
}); });
} }
}); });
} else {
cli.on("crypto.verification.start", (verifier) => {
const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog");
Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, {
verifier,
}, null, /* priority = */ false, /* static = */ true);
});
}
// Fire the tinter right on startup to ensure the default theme is applied // Fire the tinter right on startup to ensure the default theme is applied
// A later sync can/will correct the tint to be the right value for the user // A later sync can/will correct the tint to be the right value for the user
const colorScheme = SettingsStore.getValue("roomColor"); const colorScheme = SettingsStore.getValue("roomColor");

View File

@ -182,6 +182,7 @@ export default class RightPanel extends React.Component {
member: payload.member, member: payload.member,
event: payload.event, event: payload.event,
verificationRequest: payload.verificationRequest, verificationRequest: payload.verificationRequest,
verificationRequestPromise: payload.verificationRequestPromise,
}); });
} }
} }
@ -231,6 +232,7 @@ export default class RightPanel extends React.Component {
onClose={onClose} onClose={onClose}
phase={this.state.phase} phase={this.state.phase}
verificationRequest={this.state.verificationRequest} verificationRequest={this.state.verificationRequest}
verificationRequestPromise={this.state.verificationRequestPromise}
/>; />;
} else { } else {
panel = <MemberInfo panel = <MemberInfo

View File

@ -121,10 +121,12 @@ export default class MessageActionBar extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.props.mxEvent.on("Event.decrypted", this.onDecrypted); this.props.mxEvent.on("Event.decrypted", this.onDecrypted);
this.props.mxEvent.on("Event.beforeRedaction", this.onBeforeRedaction);
} }
componentWillUnmount() { componentWillUnmount() {
this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted); this.props.mxEvent.removeListener("Event.decrypted", this.onDecrypted);
this.props.mxEvent.removeListener("Event.beforeRedaction", this.onBeforeRedaction);
} }
onDecrypted = () => { onDecrypted = () => {
@ -133,6 +135,11 @@ export default class MessageActionBar extends React.PureComponent {
this.forceUpdate(); this.forceUpdate();
}; };
onBeforeRedaction = () => {
// When an event is redacted, we can't edit it so update the available actions.
this.forceUpdate();
};
onFocusChange = (focused) => { onFocusChange = (focused) => {
if (!this.props.onFocusChange) { if (!this.props.onFocusChange) {
return; return;

View File

@ -30,7 +30,7 @@ import {_t} from "../../../languageHandler";
// cancellation codes which constitute a key mismatch // cancellation codes which constitute a key mismatch
const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"]; const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"];
const EncryptionPanel = ({verificationRequest, member, onClose, layout}) => { const EncryptionPanel = ({verificationRequest, verificationRequestPromise, member, onClose, layout}) => {
const [request, setRequest] = useState(verificationRequest); const [request, setRequest] = useState(verificationRequest);
// state to show a spinner immediately after clicking "start verification", // state to show a spinner immediately after clicking "start verification",
// before we have a request // before we have a request
@ -43,6 +43,19 @@ const EncryptionPanel = ({verificationRequest, member, onClose, layout}) => {
setPhase(verificationRequest.phase); setPhase(verificationRequest.phase);
} }
}, [verificationRequest]); }, [verificationRequest]);
useEffect(() => {
async function awaitPromise() {
setRequesting(true);
const request = await verificationRequestPromise;
setRequesting(false);
setRequest(request);
setPhase(request.phase);
}
if (verificationRequestPromise) {
awaitPromise();
}
}, [verificationRequestPromise]);
const changeHandler = useCallback(() => { const changeHandler = useCallback(() => {
// handle transitions -> cancelled for mismatches which fire a modal instead of showing a card // handle transitions -> cancelled for mismatches which fire a modal instead of showing a card
if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) { if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) {

View File

@ -171,14 +171,14 @@ async function verifyDevice(userId, device) {
return; return;
} }
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
const verificationRequest = await cli.requestVerification( const verificationRequestPromise = cli.requestVerification(
userId, userId,
[device.deviceId], [device.deviceId],
); );
dis.dispatch({ dis.dispatch({
action: "set_right_panel_phase", action: "set_right_panel_phase",
phase: RIGHT_PANEL_PHASES.EncryptionPanel, phase: RIGHT_PANEL_PHASES.EncryptionPanel,
refireParams: {member, verificationRequest}, refireParams: {member, verificationRequestPromise},
}); });
}, },
primaryButton: _t("Done"), primaryButton: _t("Done"),

View File

@ -880,9 +880,6 @@ export default createReactClass({
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
return ( return (
<div className={classes} tabIndex={-1}> <div className={classes} tabIndex={-1}>
<div className="mx_EventTile_msgOption">
{ readAvatars }
</div>
{ sender } { sender }
<div className="mx_EventTile_line"> <div className="mx_EventTile_line">
<a <a
@ -906,6 +903,9 @@ export default createReactClass({
{ reactionsRow } { reactionsRow }
{ actionBar } { actionBar }
</div> </div>
<div className="mx_EventTile_msgOption">
{ readAvatars }
</div>
{ {
// The avatar goes after the event tile as it's absolutely positioned to be over the // The avatar goes after the event tile as it's absolutely positioned to be over the
// event tile line, so needs to be later in the DOM so it appears on top (this avoids // event tile line, so needs to be later in the DOM so it appears on top (this avoids

View File

@ -490,6 +490,7 @@ export default createReactClass({
height="13" height="13"
alt="dm" alt="dm"
/>; />;
}
const { room } = this.props; const { room } = this.props;
const member = room.getMember(dmUserId); const member = room.getMember(dmUserId);
@ -500,7 +501,6 @@ export default createReactClass({
const UserOnlineDot = sdk.getComponent('rooms.UserOnlineDot'); const UserOnlineDot = sdk.getComponent('rooms.UserOnlineDot');
dmOnline = <UserOnlineDot userId={dmUserId} />; dmOnline = <UserOnlineDot userId={dmUserId} />;
} }
}
// The following labels are written in such a fashion to increase screen reader efficiency (speed). // The following labels are written in such a fashion to increase screen reader efficiency (speed).
if (notifBadges && mentionBadges && !isInvite) { if (notifBadges && mentionBadges && !isInvite) {

View File

@ -27,6 +27,7 @@ export default createReactClass({
propTypes: { propTypes: {
onScrollUpClick: PropTypes.func, onScrollUpClick: PropTypes.func,
onCloseClick: PropTypes.func,
}, },
render: function() { render: function() {
@ -36,6 +37,10 @@ export default createReactClass({
title={_t('Jump to first unread message.')} title={_t('Jump to first unread message.')}
onClick={this.props.onScrollUpClick}> onClick={this.props.onScrollUpClick}>
</AccessibleButton> </AccessibleButton>
<AccessibleButton className="mx_TopUnreadMessagesBar_markAsRead"
title={_t('Mark all as read')}
onClick={this.props.onCloseClick}>
</AccessibleButton>
</div> </div>
); );
}, },

View File

@ -1145,6 +1145,7 @@
"Revoke invite": "Revoke invite", "Revoke invite": "Revoke invite",
"Invited by %(sender)s": "Invited by %(sender)s", "Invited by %(sender)s": "Invited by %(sender)s",
"Jump to first unread message.": "Jump to first unread message.", "Jump to first unread message.": "Jump to first unread message.",
"Mark all as read": "Mark all as read",
"Error updating main address": "Error updating main address", "Error updating main address": "Error updating main address",
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.", "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
"Error creating alias": "Error creating alias", "Error creating alias": "Error creating alias",
@ -2134,13 +2135,13 @@
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.", "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.",
"If disabled, messages from encrypted rooms won't appear in search results.": "If disabled, messages from encrypted rooms won't appear in search results.", "If disabled, messages from encrypted rooms won't appear in search results.": "If disabled, messages from encrypted rooms won't appear in search results.",
"Disable": "Disable", "Disable": "Disable",
"Not currently downloading messages for any room.": "Not currently downloading messages for any room.", "Not currently indexing messages for any room.": "Not currently indexing messages for any room.",
"Downloading mesages for %(currentRoom)s.": "Downloading mesages for %(currentRoom)s.", "Currently indexing: %(currentRoom)s.": "Currently indexing: %(currentRoom)s.",
"Riot is securely caching encrypted messages locally for them to appear in search results:": "Riot is securely caching encrypted messages locally for them to appear in search results:", "Riot is securely caching encrypted messages locally for them to appear in search results:": "Riot is securely caching encrypted messages locally for them to appear in search results:",
"Space used:": "Space used:", "Space used:": "Space used:",
"Indexed messages:": "Indexed messages:", "Indexed messages:": "Indexed messages:",
"Indexed rooms:": "Indexed rooms:", "Indexed rooms:": "Indexed rooms:",
"%(crawlingRooms)s out of %(totalRooms)s": "%(crawlingRooms)s out of %(totalRooms)s", "%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s out of %(totalRooms)s",
"Message downloading sleep time(ms)": "Message downloading sleep time(ms)", "Message downloading sleep time(ms)": "Message downloading sleep time(ms)",
"Failed to set direct chat tag": "Failed to set direct chat tag", "Failed to set direct chat tag": "Failed to set direct chat tag",
"Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room", "Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",

View File

@ -46,7 +46,7 @@ export function isContentActionable(mxEvent) {
} }
export function canEditContent(mxEvent) { export function canEditContent(mxEvent) {
if (mxEvent.status === EventStatus.CANCELLED || mxEvent.getType() !== "m.room.message") { if (mxEvent.status === EventStatus.CANCELLED || mxEvent.getType() !== "m.room.message" || mxEvent.isRedacted()) {
return false; return false;
} }
const content = mxEvent.getOriginalContent(); const content = mxEvent.getOriginalContent();