Merge branch 'develop' into bwindels/stylepreviewbar
This commit is contained in:
commit
22874f62ab
25 changed files with 280 additions and 139 deletions
|
@ -9,6 +9,10 @@ steps:
|
||||||
image: "node:10"
|
image: "node:10"
|
||||||
|
|
||||||
- label: ":chains: End-to-End Tests"
|
- label: ":chains: End-to-End Tests"
|
||||||
|
agents:
|
||||||
|
# We use a medium sized instance instead of the normal small ones because
|
||||||
|
# e2e tests otherwise take +-8min
|
||||||
|
queue: "medium"
|
||||||
command:
|
command:
|
||||||
# TODO: Remove hacky chmod for BuildKite
|
# TODO: Remove hacky chmod for BuildKite
|
||||||
- "echo '--- Setup'"
|
- "echo '--- Setup'"
|
||||||
|
|
|
@ -36,6 +36,12 @@ body {
|
||||||
color: $warning-color;
|
color: $warning-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.
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: $primary-fg-color;
|
color: $primary-fg-color;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
@import "./structures/_CreateRoom.scss";
|
@import "./structures/_CreateRoom.scss";
|
||||||
@import "./structures/_CustomRoomTagPanel.scss";
|
@import "./structures/_CustomRoomTagPanel.scss";
|
||||||
@import "./structures/_FilePanel.scss";
|
@import "./structures/_FilePanel.scss";
|
||||||
|
@import "./structures/_GenericErrorPage.scss";
|
||||||
@import "./structures/_GroupView.scss";
|
@import "./structures/_GroupView.scss";
|
||||||
@import "./structures/_HeaderButtons.scss";
|
@import "./structures/_HeaderButtons.scss";
|
||||||
@import "./structures/_HomePage.scss";
|
@import "./structures/_HomePage.scss";
|
||||||
|
|
19
res/css/structures/_GenericErrorPage.scss
Normal file
19
res/css/structures/_GenericErrorPage.scss
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
.mx_GenericErrorPage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_GenericErrorPage_box {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
width: 500px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px solid #f22;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #fcc;
|
||||||
|
}
|
|
@ -72,3 +72,7 @@ limitations under the License.
|
||||||
// give them more visual distinction between the sections.
|
// give them more visual distinction between the sections.
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_SettingsTab a {
|
||||||
|
color: $accent-color-alt;
|
||||||
|
}
|
|
@ -492,6 +492,9 @@ export default class ContentMessages {
|
||||||
this.inprogress.push(upload);
|
this.inprogress.push(upload);
|
||||||
dis.dispatch({action: 'upload_started'});
|
dis.dispatch({action: 'upload_started'});
|
||||||
|
|
||||||
|
// Focus the composer view
|
||||||
|
dis.dispatch({action: 'focus_composer'});
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
function onProgress(ev) {
|
function onProgress(ev) {
|
||||||
|
|
|
@ -41,6 +41,12 @@ class SdkConfig {
|
||||||
static unset() {
|
static unset() {
|
||||||
global.mxReactSdkConfig = undefined;
|
global.mxReactSdkConfig = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static add(cfg) {
|
||||||
|
const liveConfig = SdkConfig.get();
|
||||||
|
const newConfig = Object.assign({}, liveConfig, cfg);
|
||||||
|
SdkConfig.put(newConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SdkConfig;
|
module.exports = SdkConfig;
|
||||||
|
|
|
@ -155,7 +155,7 @@ export const CommandMap = {
|
||||||
<p>
|
<p>
|
||||||
{_t(
|
{_t(
|
||||||
"Please confirm that you'd like to go forward with upgrading this room " +
|
"Please confirm that you'd like to go forward with upgrading this room " +
|
||||||
"from <oldVersion /> to <newVersion />",
|
"from <oldVersion /> to <newVersion />.",
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
oldVersion: () => <code>{room ? room.getVersion() : "1"}</code>,
|
oldVersion: () => <code>{room ? room.getVersion() : "1"}</code>,
|
||||||
|
|
38
src/components/structures/GenericErrorPage.js
Normal file
38
src/components/structures/GenericErrorPage.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {_t} from "../../languageHandler";
|
||||||
|
|
||||||
|
export default class GenericErrorPage extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
message: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div className='mx_GenericErrorPage'>
|
||||||
|
<div className='mx_GenericErrorPage_box'>
|
||||||
|
<h1>{_t("Error loading Riot")}</h1>
|
||||||
|
<p>{this.props.message}</p>
|
||||||
|
<p>{_t(
|
||||||
|
"If this is unexpected, please contact your system administrator " +
|
||||||
|
"or technical support representative.",
|
||||||
|
)}</p>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,13 +29,6 @@ export default class IndicatorScrollbar extends React.Component {
|
||||||
// scroll horizontally rather than vertically. This should only be used on components
|
// scroll horizontally rather than vertically. This should only be used on components
|
||||||
// with no vertical scroll opportunity.
|
// with no vertical scroll opportunity.
|
||||||
verticalScrollsHorizontally: PropTypes.bool,
|
verticalScrollsHorizontally: PropTypes.bool,
|
||||||
|
|
||||||
// An object containing 2 numbers: xyThreshold and yReduction. xyThreshold is the amount
|
|
||||||
// of horizontal movement required in order to ignore any vertical changes in scroll, and
|
|
||||||
// only applies when verticalScrollsHorizontally is true. yReduction is the factor to
|
|
||||||
// multiply the vertical delta by when verticalScrollsHorizontally is true. The default
|
|
||||||
// behaviour is to have an xyThreshold of infinity and a yReduction of 0.8
|
|
||||||
scrollTolerances: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -127,20 +120,19 @@ export default class IndicatorScrollbar extends React.Component {
|
||||||
|
|
||||||
onMouseWheel = (e) => {
|
onMouseWheel = (e) => {
|
||||||
if (this.props.verticalScrollsHorizontally && this._scrollElement) {
|
if (this.props.verticalScrollsHorizontally && this._scrollElement) {
|
||||||
const xyThreshold = this.props.scrollTolerances
|
// xyThreshold is the amount of horizontal motion required for the component to
|
||||||
? this.props.scrollTolerances.xyThreshold
|
// ignore the vertical delta in a scroll. Used to stop trackpads from acting in
|
||||||
: Number.MAX_SAFE_INTEGER;
|
// strange ways. Should be positive.
|
||||||
|
const xyThreshold = 0;
|
||||||
|
|
||||||
const yReduction = this.props.scrollTolerances
|
// yRetention is the factor multiplied by the vertical delta to try and reduce
|
||||||
? this.props.scrollTolerances.yReduction
|
// the harshness of the scroll behaviour. Should be a value between 0 and 1.
|
||||||
: 0.8;
|
const yRetention = 1.0;
|
||||||
|
|
||||||
// Don't apply vertical motion to horizontal scrolls. This is meant to eliminate
|
|
||||||
// trackpads causing excessive scroll motion.
|
|
||||||
if (e.deltaX >= xyThreshold) return;
|
|
||||||
|
|
||||||
|
if (Math.abs(e.deltaX) < xyThreshold) {
|
||||||
// noinspection JSSuspiciousNameCombination
|
// noinspection JSSuspiciousNameCombination
|
||||||
this._scrollElement.scrollLeft += e.deltaY * yReduction;
|
this._scrollElement.scrollLeft += e.deltaY * yRetention;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -565,23 +565,6 @@ export default React.createClass({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'view_user':
|
|
||||||
// FIXME: ugly hack to expand the RightPanel and then re-dispatch.
|
|
||||||
if (this.state.collapsedRhs) {
|
|
||||||
setTimeout(()=>{
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'show_right_panel',
|
|
||||||
});
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_user',
|
|
||||||
member: payload.member,
|
|
||||||
});
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// different from view_user,
|
|
||||||
// this show the user panel outside of the context
|
|
||||||
// of a room, like a /user/<id> url
|
|
||||||
case 'view_user_info':
|
case 'view_user_info':
|
||||||
this._viewUser(payload.userId);
|
this._viewUser(payload.userId);
|
||||||
break;
|
break;
|
||||||
|
@ -1820,7 +1803,7 @@ export default React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_setPageSubtitle: function(subtitle='') {
|
_setPageSubtitle: function(subtitle='') {
|
||||||
document.title = `Riot ${subtitle}`;
|
document.title = `${SdkConfig.get().brand || 'Riot'} ${subtitle}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateStatusIndicator: function(state, prevState) {
|
updateStatusIndicator: function(state, prevState) {
|
||||||
|
|
|
@ -272,6 +272,28 @@ module.exports = React.createClass({
|
||||||
return this.state.room ? this.state.room.roomId : this.state.roomId;
|
return this.state.room ? this.state.room.roomId : this.state.roomId;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getPermalinkCreatorForRoom: function(room) {
|
||||||
|
if (!this._permalinkCreators) this._permalinkCreators = {};
|
||||||
|
if (this._permalinkCreators[room.roomId]) return this._permalinkCreators[room.roomId];
|
||||||
|
|
||||||
|
this._permalinkCreators[room.roomId] = new RoomPermalinkCreator(room);
|
||||||
|
if (this.state.room && room.roomId === this.state.room.roomId) {
|
||||||
|
// We want to watch for changes in the creator for the primary room in the view, but
|
||||||
|
// don't need to do so for search results.
|
||||||
|
this._permalinkCreators[room.roomId].start();
|
||||||
|
} else {
|
||||||
|
this._permalinkCreators[room.roomId].load();
|
||||||
|
}
|
||||||
|
return this._permalinkCreators[room.roomId];
|
||||||
|
},
|
||||||
|
|
||||||
|
_stopAllPermalinkCreators: function() {
|
||||||
|
if (!this._permalinkCreators) return;
|
||||||
|
for (const roomId of Object.keys(this._permalinkCreators)) {
|
||||||
|
this._permalinkCreators[roomId].stop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onWidgetEchoStoreUpdate: function() {
|
_onWidgetEchoStoreUpdate: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showApps: this._shouldShowApps(this.state.room),
|
showApps: this._shouldShowApps(this.state.room),
|
||||||
|
@ -436,9 +458,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop tracking room changes to format permalinks
|
// stop tracking room changes to format permalinks
|
||||||
if (this.state.permalinkCreator) {
|
this._stopAllPermalinkCreators();
|
||||||
this.state.permalinkCreator.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.refs.roomView) {
|
if (this.refs.roomView) {
|
||||||
// disconnect the D&D event listeners from the room view. This
|
// disconnect the D&D event listeners from the room view. This
|
||||||
|
@ -651,11 +671,6 @@ module.exports = React.createClass({
|
||||||
this._loadMembersIfJoined(room);
|
this._loadMembersIfJoined(room);
|
||||||
this._calculateRecommendedVersion(room);
|
this._calculateRecommendedVersion(room);
|
||||||
this._updateE2EStatus(room);
|
this._updateE2EStatus(room);
|
||||||
if (!this.state.permalinkCreator) {
|
|
||||||
const permalinkCreator = new RoomPermalinkCreator(room);
|
|
||||||
permalinkCreator.start();
|
|
||||||
this.setState({permalinkCreator});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_calculateRecommendedVersion: async function(room) {
|
_calculateRecommendedVersion: async function(room) {
|
||||||
|
@ -1169,6 +1184,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
const mxEv = result.context.getEvent();
|
const mxEv = result.context.getEvent();
|
||||||
const roomId = mxEv.getRoomId();
|
const roomId = mxEv.getRoomId();
|
||||||
|
const room = cli.getRoom(roomId);
|
||||||
|
|
||||||
if (!EventTile.haveTileForEvent(mxEv)) {
|
if (!EventTile.haveTileForEvent(mxEv)) {
|
||||||
// XXX: can this ever happen? It will make the result count
|
// XXX: can this ever happen? It will make the result count
|
||||||
|
@ -1178,7 +1194,6 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (this.state.searchScope === 'All') {
|
if (this.state.searchScope === 'All') {
|
||||||
if (roomId != lastRoomId) {
|
if (roomId != lastRoomId) {
|
||||||
const room = cli.getRoom(roomId);
|
|
||||||
|
|
||||||
// XXX: if we've left the room, we might not know about
|
// XXX: if we've left the room, we might not know about
|
||||||
// it. We should tell the js sdk to go and find out about
|
// it. We should tell the js sdk to go and find out about
|
||||||
|
@ -1199,7 +1214,7 @@ module.exports = React.createClass({
|
||||||
searchResult={result}
|
searchResult={result}
|
||||||
searchHighlights={this.state.searchHighlights}
|
searchHighlights={this.state.searchHighlights}
|
||||||
resultLink={resultLink}
|
resultLink={resultLink}
|
||||||
permalinkCreator={this.state.permalinkCreator}
|
permalinkCreator={this._getPermalinkCreatorForRoom(room)}
|
||||||
onHeightChanged={onHeightChanged} />);
|
onHeightChanged={onHeightChanged} />);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1715,7 +1730,7 @@ module.exports = React.createClass({
|
||||||
disabled={this.props.disabled}
|
disabled={this.props.disabled}
|
||||||
showApps={this.state.showApps}
|
showApps={this.state.showApps}
|
||||||
e2eStatus={this.state.e2eStatus}
|
e2eStatus={this.state.e2eStatus}
|
||||||
permalinkCreator={this.state.permalinkCreator}
|
permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1812,7 +1827,7 @@ module.exports = React.createClass({
|
||||||
showUrlPreview = {this.state.showUrlPreview}
|
showUrlPreview = {this.state.showUrlPreview}
|
||||||
className="mx_RoomView_messagePanel"
|
className="mx_RoomView_messagePanel"
|
||||||
membersLoaded={this.state.membersLoaded}
|
membersLoaded={this.state.membersLoaded}
|
||||||
permalinkCreator={this.state.permalinkCreator}
|
permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>);
|
/>);
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,12 @@ const PHASES_ENABLED = true;
|
||||||
// These are used in several places, and come from the js-sdk's autodiscovery
|
// These are used in several places, and come from the js-sdk's autodiscovery
|
||||||
// stuff. We define them here so that they'll be picked up by i18n.
|
// stuff. We define them here so that they'll be picked up by i18n.
|
||||||
_td("Invalid homeserver discovery response");
|
_td("Invalid homeserver discovery response");
|
||||||
|
_td("Failed to get autodiscovery configuration from server");
|
||||||
|
_td("Invalid base_url for m.homeserver");
|
||||||
|
_td("Homeserver URL does not appear to be a valid Matrix homeserver");
|
||||||
_td("Invalid identity server discovery response");
|
_td("Invalid identity server discovery response");
|
||||||
|
_td("Invalid base_url for m.identity_server");
|
||||||
|
_td("Identity server URL does not appear to be a valid identity server");
|
||||||
_td("General failure");
|
_td("General failure");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default class RoomSettingsDialog extends React.Component {
|
||||||
tabs.push(new Tab(
|
tabs.push(new Tab(
|
||||||
_td("Advanced"),
|
_td("Advanced"),
|
||||||
"mx_RoomSettingsDialog_warningIcon",
|
"mx_RoomSettingsDialog_warningIcon",
|
||||||
<AdvancedRoomSettingsTab roomId={this.props.roomId} />,
|
<AdvancedRoomSettingsTab roomId={this.props.roomId} closeSettingsFn={this.props.onFinished} />,
|
||||||
));
|
));
|
||||||
|
|
||||||
return tabs;
|
return tabs;
|
||||||
|
|
|
@ -19,23 +19,30 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
import HeaderButton from './HeaderButton';
|
import HeaderButton from './HeaderButton';
|
||||||
import HeaderButtons from './HeaderButtons';
|
import HeaderButtons from './HeaderButtons';
|
||||||
import RightPanel from '../../structures/RightPanel';
|
import RightPanel from '../../structures/RightPanel';
|
||||||
|
|
||||||
|
const GROUP_PHASES = [
|
||||||
|
RightPanel.Phase.GroupMemberInfo,
|
||||||
|
RightPanel.Phase.GroupMemberList,
|
||||||
|
];
|
||||||
|
const ROOM_PHASES = [
|
||||||
|
RightPanel.Phase.GroupRoomList,
|
||||||
|
RightPanel.Phase.GroupRoomInfo,
|
||||||
|
];
|
||||||
|
|
||||||
export default class GroupHeaderButtons extends HeaderButtons {
|
export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, RightPanel.Phase.GroupMemberList);
|
super(props, RightPanel.Phase.GroupMemberList);
|
||||||
|
this._onMembersClicked = this._onMembersClicked.bind(this);
|
||||||
|
this._onRoomsClicked = this._onRoomsClicked.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAction(payload) {
|
onAction(payload) {
|
||||||
super.onAction(payload);
|
super.onAction(payload);
|
||||||
|
|
||||||
if (payload.action === "view_user") {
|
if (payload.action === "view_user") {
|
||||||
dis.dispatch({
|
|
||||||
action: 'show_right_panel',
|
|
||||||
});
|
|
||||||
if (payload.member) {
|
if (payload.member) {
|
||||||
this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
|
this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,27 +61,26 @@ export default class GroupHeaderButtons extends HeaderButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderButtons() {
|
_onMembersClicked() {
|
||||||
const groupPhases = [
|
this.togglePhase(RightPanel.Phase.GroupMemberList, GROUP_PHASES);
|
||||||
RightPanel.Phase.GroupMemberInfo,
|
}
|
||||||
RightPanel.Phase.GroupMemberList,
|
|
||||||
];
|
|
||||||
const roomPhases = [
|
|
||||||
RightPanel.Phase.GroupRoomList,
|
|
||||||
RightPanel.Phase.GroupRoomInfo,
|
|
||||||
];
|
|
||||||
|
|
||||||
|
_onRoomsClicked() {
|
||||||
|
this.togglePhase(RightPanel.Phase.GroupRoomList, ROOM_PHASES);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons() {
|
||||||
return [
|
return [
|
||||||
<HeaderButton key="groupMembersButton" name="groupMembersButton"
|
<HeaderButton key="groupMembersButton" name="groupMembersButton"
|
||||||
title={_t('Members')}
|
title={_t('Members')}
|
||||||
isHighlighted={this.isPhase(groupPhases)}
|
isHighlighted={this.isPhase(GROUP_PHASES)}
|
||||||
clickPhase={RightPanel.Phase.GroupMemberList}
|
onClick={this._onMembersClicked}
|
||||||
analytics={['Right Panel', 'Group Member List Button', 'click']}
|
analytics={['Right Panel', 'Group Member List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
<HeaderButton key="roomsButton" name="roomsButton"
|
<HeaderButton key="roomsButton" name="roomsButton"
|
||||||
title={_t('Rooms')}
|
title={_t('Rooms')}
|
||||||
isHighlighted={this.isPhase(roomPhases)}
|
isHighlighted={this.isPhase(ROOM_PHASES)}
|
||||||
clickPhase={RightPanel.Phase.GroupRoomList}
|
onClick={this._onRoomsClicked}
|
||||||
analytics={['Right Panel', 'Group Room List Button', 'click']}
|
analytics={['Right Panel', 'Group Room List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
|
|
|
@ -20,7 +20,6 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
import Analytics from '../../../Analytics';
|
import Analytics from '../../../Analytics';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
|
|
||||||
|
@ -32,11 +31,7 @@ export default class HeaderButton extends React.Component {
|
||||||
|
|
||||||
onClick(ev) {
|
onClick(ev) {
|
||||||
Analytics.trackEvent(...this.props.analytics);
|
Analytics.trackEvent(...this.props.analytics);
|
||||||
dis.dispatch({
|
this.props.onClick();
|
||||||
action: 'view_right_panel_phase',
|
|
||||||
phase: this.props.clickPhase,
|
|
||||||
fromHeader: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -59,9 +54,8 @@ export default class HeaderButton extends React.Component {
|
||||||
HeaderButton.propTypes = {
|
HeaderButton.propTypes = {
|
||||||
// Whether this button is highlighted
|
// Whether this button is highlighted
|
||||||
isHighlighted: PropTypes.bool.isRequired,
|
isHighlighted: PropTypes.bool.isRequired,
|
||||||
// The phase to swap to when the button is clicked
|
// click handler
|
||||||
clickPhase: PropTypes.string.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
|
|
||||||
// The badge to display above the icon
|
// The badge to display above the icon
|
||||||
badge: PropTypes.node,
|
badge: PropTypes.node,
|
||||||
// The parameters to track the click event
|
// The parameters to track the click event
|
||||||
|
|
|
@ -40,14 +40,36 @@ export default class HeaderButtons extends React.Component {
|
||||||
dis.unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (!prevProps.collapsedRhs && this.props.collapsedRhs) {
|
||||||
|
this.setState({
|
||||||
|
phase: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setPhase(phase, extras) {
|
setPhase(phase, extras) {
|
||||||
// TODO: delay?
|
if (this.props.collapsedRhs) {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'show_right_panel',
|
||||||
|
});
|
||||||
|
}
|
||||||
dis.dispatch(Object.assign({
|
dis.dispatch(Object.assign({
|
||||||
action: 'view_right_panel_phase',
|
action: 'view_right_panel_phase',
|
||||||
phase: phase,
|
phase: phase,
|
||||||
}, extras));
|
}, extras));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
togglePhase(phase, validPhases = [phase]) {
|
||||||
|
if (validPhases.includes(this.state.phase)) {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'hide_right_panel',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setPhase(phase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isPhase(phases) {
|
isPhase(phases) {
|
||||||
if (this.props.collapsedRhs) {
|
if (this.props.collapsedRhs) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -61,30 +83,11 @@ export default class HeaderButtons extends React.Component {
|
||||||
|
|
||||||
onAction(payload) {
|
onAction(payload) {
|
||||||
if (payload.action === "view_right_panel_phase") {
|
if (payload.action === "view_right_panel_phase") {
|
||||||
// only actions coming from header buttons should collapse the right panel
|
|
||||||
if (this.state.phase === payload.phase && payload.fromHeader) {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'hide_right_panel',
|
|
||||||
});
|
|
||||||
this.setState({
|
|
||||||
phase: null,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (this.props.collapsedRhs && payload.fromHeader) {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'show_right_panel',
|
|
||||||
});
|
|
||||||
// emit payload again as the RightPanel didn't exist up
|
|
||||||
// till show_right_panel, just without the fromHeader flag
|
|
||||||
// as that would hide the right panel again
|
|
||||||
dis.dispatch(Object.assign({}, payload, {fromHeader: false}));
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: payload.phase,
|
phase: payload.phase,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// inline style as this will be swapped around in future commits
|
// inline style as this will be swapped around in future commits
|
||||||
|
|
|
@ -19,28 +19,33 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
import HeaderButton from './HeaderButton';
|
import HeaderButton from './HeaderButton';
|
||||||
import HeaderButtons from './HeaderButtons';
|
import HeaderButtons from './HeaderButtons';
|
||||||
import RightPanel from '../../structures/RightPanel';
|
import RightPanel from '../../structures/RightPanel';
|
||||||
|
|
||||||
|
const MEMBER_PHASES = [
|
||||||
|
RightPanel.Phase.RoomMemberList,
|
||||||
|
RightPanel.Phase.RoomMemberInfo,
|
||||||
|
RightPanel.Phase.Room3pidMemberInfo,
|
||||||
|
];
|
||||||
|
|
||||||
export default class RoomHeaderButtons extends HeaderButtons {
|
export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props, RightPanel.Phase.RoomMemberList);
|
super(props, RightPanel.Phase.RoomMemberList);
|
||||||
|
this._onMembersClicked = this._onMembersClicked.bind(this);
|
||||||
|
this._onFilesClicked = this._onFilesClicked.bind(this);
|
||||||
|
this._onNotificationsClicked = this._onNotificationsClicked.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAction(payload) {
|
onAction(payload) {
|
||||||
super.onAction(payload);
|
super.onAction(payload);
|
||||||
if (payload.action === "view_user") {
|
if (payload.action === "view_user") {
|
||||||
dis.dispatch({
|
|
||||||
action: 'show_right_panel',
|
|
||||||
});
|
|
||||||
if (payload.member) {
|
if (payload.member) {
|
||||||
this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
|
this.setPhase(RightPanel.Phase.RoomMemberInfo, {member: payload.member});
|
||||||
} else {
|
} else {
|
||||||
this.setPhase(RightPanel.Phase.RoomMemberList);
|
this.setPhase(RightPanel.Phase.RoomMemberList);
|
||||||
}
|
}
|
||||||
} else if (payload.action === "view_room") {
|
} else if (payload.action === "view_room" && !this.props.collapsedRhs) {
|
||||||
this.setPhase(RightPanel.Phase.RoomMemberList);
|
this.setPhase(RightPanel.Phase.RoomMemberList);
|
||||||
} else if (payload.action === "view_3pid_invite") {
|
} else if (payload.action === "view_3pid_invite") {
|
||||||
if (payload.event) {
|
if (payload.event) {
|
||||||
|
@ -51,30 +56,36 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderButtons() {
|
_onMembersClicked() {
|
||||||
const membersPhases = [
|
this.togglePhase(RightPanel.Phase.RoomMemberList, MEMBER_PHASES);
|
||||||
RightPanel.Phase.RoomMemberList,
|
}
|
||||||
RightPanel.Phase.RoomMemberInfo,
|
|
||||||
RightPanel.Phase.Room3pidMemberInfo,
|
|
||||||
];
|
|
||||||
|
|
||||||
|
_onFilesClicked() {
|
||||||
|
this.togglePhase(RightPanel.Phase.FilePanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onNotificationsClicked() {
|
||||||
|
this.togglePhase(RightPanel.Phase.NotificationPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons() {
|
||||||
return [
|
return [
|
||||||
<HeaderButton key="membersButton" name="membersButton"
|
<HeaderButton key="membersButton" name="membersButton"
|
||||||
title={_t('Members')}
|
title={_t('Members')}
|
||||||
isHighlighted={this.isPhase(membersPhases)}
|
isHighlighted={this.isPhase(MEMBER_PHASES)}
|
||||||
clickPhase={RightPanel.Phase.RoomMemberList}
|
onClick={this._onMembersClicked}
|
||||||
analytics={['Right Panel', 'Member List Button', 'click']}
|
analytics={['Right Panel', 'Member List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
<HeaderButton key="filesButton" name="filesButton"
|
<HeaderButton key="filesButton" name="filesButton"
|
||||||
title={_t('Files')}
|
title={_t('Files')}
|
||||||
isHighlighted={this.isPhase(RightPanel.Phase.FilePanel)}
|
isHighlighted={this.isPhase(RightPanel.Phase.FilePanel)}
|
||||||
clickPhase={RightPanel.Phase.FilePanel}
|
onClick={this._onFilesClicked}
|
||||||
analytics={['Right Panel', 'File List Button', 'click']}
|
analytics={['Right Panel', 'File List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
<HeaderButton key="notifsButton" name="notifsButton"
|
<HeaderButton key="notifsButton" name="notifsButton"
|
||||||
title={_t('Notifications')}
|
title={_t('Notifications')}
|
||||||
isHighlighted={this.isPhase(RightPanel.Phase.NotificationPanel)}
|
isHighlighted={this.isPhase(RightPanel.Phase.NotificationPanel)}
|
||||||
clickPhase={RightPanel.Phase.NotificationPanel}
|
onClick={this._onNotificationsClicked}
|
||||||
analytics={['Right Panel', 'Notification List Button', 'click']}
|
analytics={['Right Panel', 'Notification List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
|
|
|
@ -33,12 +33,7 @@ const MAX_ROOMS = 20;
|
||||||
export default class RoomBreadcrumbs extends React.Component {
|
export default class RoomBreadcrumbs extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.state = {rooms: []};
|
||||||
const tolerances = SettingsStore.getValue("breadcrumb_scroll_tolerances");
|
|
||||||
this.state = {rooms: [], scrollTolerances: tolerances};
|
|
||||||
|
|
||||||
// Record this for debugging purposes
|
|
||||||
console.log("Breadcrumbs scroll tolerances:", tolerances);
|
|
||||||
|
|
||||||
this.onAction = this.onAction.bind(this);
|
this.onAction = this.onAction.bind(this);
|
||||||
this._dispatcherRef = null;
|
this._dispatcherRef = null;
|
||||||
|
@ -343,8 +338,7 @@ export default class RoomBreadcrumbs extends React.Component {
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs"
|
<IndicatorScrollbar ref="scroller" className="mx_RoomBreadcrumbs"
|
||||||
trackHorizontalOverflow={true} verticalScrollsHorizontally={true}
|
trackHorizontalOverflow={true} verticalScrollsHorizontally={true}>
|
||||||
scrollTolerances={this.state.scrollTolerances}>
|
|
||||||
{ avatars }
|
{ avatars }
|
||||||
</IndicatorScrollbar>
|
</IndicatorScrollbar>
|
||||||
);
|
);
|
||||||
|
|
|
@ -187,12 +187,17 @@ export default class KeyBackupPanel extends React.PureComponent {
|
||||||
clientBackupStatus = <div>
|
clientBackupStatus = <div>
|
||||||
<p>{encryptedMessageAreEncrypted}</p>
|
<p>{encryptedMessageAreEncrypted}</p>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
"This device is <b>not backing up your keys</b>.", {},
|
"This device is <b>not backing up your keys</b>, " +
|
||||||
|
"but you do have an existing backup you can restore from " +
|
||||||
|
"and add to going forward.", {},
|
||||||
{b: sub => <b>{sub}</b>},
|
{b: sub => <b>{sub}</b>},
|
||||||
)}</p>
|
)}</p>
|
||||||
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
|
<p>{_t(
|
||||||
|
"Connect this device to key backup before signing out to avoid " +
|
||||||
|
"losing any keys that may only be on this device.",
|
||||||
|
)}</p>
|
||||||
</div>;
|
</div>;
|
||||||
restoreButtonCaption = _t("Use key backup");
|
restoreButtonCaption = _t("Connect this device to Key Backup");
|
||||||
}
|
}
|
||||||
|
|
||||||
let uploadStatus;
|
let uploadStatus;
|
||||||
|
@ -221,7 +226,10 @@ export default class KeyBackupPanel extends React.PureComponent {
|
||||||
{sub}
|
{sub}
|
||||||
</span>;
|
</span>;
|
||||||
const device = sub => <span className="mx_KeyBackupPanel_deviceName">{deviceName}</span>;
|
const device = sub => <span className="mx_KeyBackupPanel_deviceName">{deviceName}</span>;
|
||||||
const fromThisDevice = sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key();
|
const fromThisDevice = (
|
||||||
|
sig.device &&
|
||||||
|
sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key()
|
||||||
|
);
|
||||||
let sigStatus;
|
let sigStatus;
|
||||||
if (!sig.device) {
|
if (!sig.device) {
|
||||||
sigStatus = _t(
|
sigStatus = _t(
|
||||||
|
|
|
@ -21,10 +21,12 @@ import MatrixClientPeg from "../../../../../MatrixClientPeg";
|
||||||
import sdk from "../../../../..";
|
import sdk from "../../../../..";
|
||||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
import Modal from "../../../../../Modal";
|
import Modal from "../../../../../Modal";
|
||||||
|
import dis from "../../../../../dispatcher";
|
||||||
|
|
||||||
export default class AdvancedRoomSettingsTab extends React.Component {
|
export default class AdvancedRoomSettingsTab extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
roomId: PropTypes.string.isRequired,
|
roomId: PropTypes.string.isRequired,
|
||||||
|
closeSettingsFn: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -41,9 +43,21 @@ export default class AdvancedRoomSettingsTab extends React.Component {
|
||||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||||
room.getRecommendedVersion().then((v) => {
|
room.getRecommendedVersion().then((v) => {
|
||||||
const tombstone = room.currentState.getStateEvents("m.room.tombstone", "");
|
const tombstone = room.currentState.getStateEvents("m.room.tombstone", "");
|
||||||
|
|
||||||
|
const additionalStateChanges = {};
|
||||||
|
const createEvent = room.currentState.getStateEvents("m.room.create", "");
|
||||||
|
const predecessor = createEvent ? createEvent.getContent().predecessor : null;
|
||||||
|
if (predecessor && predecessor.room_id) {
|
||||||
|
additionalStateChanges['oldRoomId'] = predecessor.room_id;
|
||||||
|
additionalStateChanges['oldEventId'] = predecessor.event_id;
|
||||||
|
additionalStateChanges['hasPreviousRoom'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
upgraded: tombstone && tombstone.getContent().replacement_room,
|
upgraded: tombstone && tombstone.getContent().replacement_room,
|
||||||
upgradeRecommendation: v,
|
upgradeRecommendation: v,
|
||||||
|
...additionalStateChanges,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -59,6 +73,18 @@ export default class AdvancedRoomSettingsTab extends React.Component {
|
||||||
Modal.createDialog(DevtoolsDialog, {roomId: this.props.roomId});
|
Modal.createDialog(DevtoolsDialog, {roomId: this.props.roomId});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_onOldRoomClicked = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_room',
|
||||||
|
room_id: this.state.oldRoomId,
|
||||||
|
event_id: this.state.oldEventId,
|
||||||
|
});
|
||||||
|
this.props.closeSettingsFn();
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const room = client.getRoom(this.props.roomId);
|
const room = client.getRoom(this.props.roomId);
|
||||||
|
@ -91,6 +117,18 @@ export default class AdvancedRoomSettingsTab extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let oldRoomLink;
|
||||||
|
if (this.state.hasPreviousRoom) {
|
||||||
|
let name = _t("this room");
|
||||||
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||||
|
if (room && room.name) name = room.name;
|
||||||
|
oldRoomLink = (
|
||||||
|
<AccessibleButton element='a' onClick={this._onOldRoomClicked}>
|
||||||
|
{_t("View older messages in %(roomName)s.", {roomName: name})}
|
||||||
|
</AccessibleButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab">
|
<div className="mx_SettingsTab">
|
||||||
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
|
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
|
||||||
|
@ -108,6 +146,7 @@ export default class AdvancedRoomSettingsTab extends React.Component {
|
||||||
<span>{_t("Room version:")}</span>
|
<span>{_t("Room version:")}</span>
|
||||||
{room.getVersion()}
|
{room.getVersion()}
|
||||||
</div>
|
</div>
|
||||||
|
{oldRoomLink}
|
||||||
{roomUpgradeButton}
|
{roomUpgradeButton}
|
||||||
</div>
|
</div>
|
||||||
<div className='mx_SettingsTab_section mx_SettingsTab_subsectionText'>
|
<div className='mx_SettingsTab_section mx_SettingsTab_subsectionText'>
|
||||||
|
|
|
@ -136,7 +136,7 @@ export default class HelpUserSettingsTab extends React.Component {
|
||||||
<li>
|
<li>
|
||||||
The <a href="themes/riot/img/backgrounds/valley.jpg" rel="noopener" target="_blank">
|
The <a href="themes/riot/img/backgrounds/valley.jpg" rel="noopener" target="_blank">
|
||||||
default cover photo</a> is (C)
|
default cover photo</a> is (C)
|
||||||
<a href="https://www.flickr.com/golan" rel="noopener" target="_blank">Jesús Roncero</a>
|
<a href="https://www.flickr.com/golan" rel="noopener" target="_blank">Jesús Roncero</a>{' '}
|
||||||
used under the terms of
|
used under the terms of
|
||||||
<a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="noopener" target="_blank">
|
<a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="noopener" target="_blank">
|
||||||
CC-BY-SA 4.0</a>. No warranties are given.
|
CC-BY-SA 4.0</a>. No warranties are given.
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
|
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
|
||||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.",
|
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.",
|
||||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
|
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
|
||||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />": "Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />",
|
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.",
|
||||||
"Upgrade": "Upgrade",
|
"Upgrade": "Upgrade",
|
||||||
"Changes your display nickname": "Changes your display nickname",
|
"Changes your display nickname": "Changes your display nickname",
|
||||||
"Changes your display nickname in the current room only": "Changes your display nickname in the current room only",
|
"Changes your display nickname in the current room only": "Changes your display nickname in the current room only",
|
||||||
|
@ -467,9 +467,9 @@
|
||||||
"Unable to load key backup status": "Unable to load key backup status",
|
"Unable to load key backup status": "Unable to load key backup status",
|
||||||
"Restore from Backup": "Restore from Backup",
|
"Restore from Backup": "Restore from Backup",
|
||||||
"This device is backing up your keys. ": "This device is backing up your keys. ",
|
"This device is backing up your keys. ": "This device is backing up your keys. ",
|
||||||
"This device is <b>not backing up your keys</b>.": "This device is <b>not backing up your keys</b>.",
|
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.",
|
||||||
"Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.",
|
"Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.",
|
||||||
"Use key backup": "Use key backup",
|
"Connect this device to Key Backup": "Connect this device to Key Backup",
|
||||||
"Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...",
|
"Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...",
|
||||||
"All keys backed up": "All keys backed up",
|
"All keys backed up": "All keys backed up",
|
||||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.",
|
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.",
|
||||||
|
@ -485,6 +485,7 @@
|
||||||
"Backup version: ": "Backup version: ",
|
"Backup version: ": "Backup version: ",
|
||||||
"Algorithm: ": "Algorithm: ",
|
"Algorithm: ": "Algorithm: ",
|
||||||
"Your keys are <b>not being backed up from this device</b>.": "Your keys are <b>not being backed up from this device</b>.",
|
"Your keys are <b>not being backed up from this device</b>.": "Your keys are <b>not being backed up from this device</b>.",
|
||||||
|
"Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.",
|
||||||
"Start using Key Backup": "Start using Key Backup",
|
"Start using Key Backup": "Start using Key Backup",
|
||||||
"Error saving email notification preferences": "Error saving email notification preferences",
|
"Error saving email notification preferences": "Error saving email notification preferences",
|
||||||
"An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.",
|
"An error occurred whilst saving your email notification preferences.": "An error occurred whilst saving your email notification preferences.",
|
||||||
|
@ -599,6 +600,8 @@
|
||||||
"Voice & Video": "Voice & Video",
|
"Voice & Video": "Voice & Video",
|
||||||
"This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers",
|
"This room is not accessible by remote Matrix servers": "This room is not accessible by remote Matrix servers",
|
||||||
"Upgrade this room to the recommended room version": "Upgrade this room to the recommended room version",
|
"Upgrade this room to the recommended room version": "Upgrade this room to the recommended room version",
|
||||||
|
"this room": "this room",
|
||||||
|
"View older messages in %(roomName)s": "View older messages in %(roomName)s",
|
||||||
"Room information": "Room information",
|
"Room information": "Room information",
|
||||||
"Internal room ID:": "Internal room ID:",
|
"Internal room ID:": "Internal room ID:",
|
||||||
"Room version": "Room version",
|
"Room version": "Room version",
|
||||||
|
@ -1347,6 +1350,8 @@
|
||||||
"You must <a>register</a> to use this functionality": "You must <a>register</a> to use this functionality",
|
"You must <a>register</a> to use this functionality": "You must <a>register</a> to use this functionality",
|
||||||
"You must join the room to see its files": "You must join the room to see its files",
|
"You must join the room to see its files": "You must join the room to see its files",
|
||||||
"There are no visible files in this room": "There are no visible files in this room",
|
"There are no visible files in this room": "There are no visible files in this room",
|
||||||
|
"Error loading Riot": "Error loading Riot",
|
||||||
|
"If this is unexpected, please contact your system administrator or technical support representative.": "If this is unexpected, please contact your system administrator or technical support representative.",
|
||||||
"<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n": "<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n",
|
"<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n": "<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n",
|
||||||
"Add rooms to the community summary": "Add rooms to the community summary",
|
"Add rooms to the community summary": "Add rooms to the community summary",
|
||||||
"Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?",
|
"Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?",
|
||||||
|
@ -1487,7 +1492,12 @@
|
||||||
"Return to login screen": "Return to login screen",
|
"Return to login screen": "Return to login screen",
|
||||||
"Set a new password": "Set a new password",
|
"Set a new password": "Set a new password",
|
||||||
"Invalid homeserver discovery response": "Invalid homeserver discovery response",
|
"Invalid homeserver discovery response": "Invalid homeserver discovery response",
|
||||||
|
"Failed to get autodiscovery configuration from server": "Failed to get autodiscovery configuration from server",
|
||||||
|
"Invalid base_url for m.homeserver": "Invalid base_url for m.homeserver",
|
||||||
|
"Homeserver URL does not appear to be a valid Matrix homeserver": "Homeserver URL does not appear to be a valid Matrix homeserver",
|
||||||
"Invalid identity server discovery response": "Invalid identity server discovery response",
|
"Invalid identity server discovery response": "Invalid identity server discovery response",
|
||||||
|
"Invalid base_url for m.identity_server": "Invalid base_url for m.identity_server",
|
||||||
|
"Identity server URL does not appear to be a valid identity server": "Identity server URL does not appear to be a valid identity server",
|
||||||
"General failure": "General failure",
|
"General failure": "General failure",
|
||||||
"This homeserver does not support login using email address.": "This homeserver does not support login using email address.",
|
"This homeserver does not support login using email address.": "This homeserver does not support login using email address.",
|
||||||
"Please <a>contact your service administrator</a> to continue using this service.": "Please <a>contact your service administrator</a> to continue using this service.",
|
"Please <a>contact your service administrator</a> to continue using this service.": "Please <a>contact your service administrator</a> to continue using this service.",
|
||||||
|
|
|
@ -77,6 +77,7 @@ export class RoomPermalinkCreator {
|
||||||
this._bannedHostsRegexps = null;
|
this._bannedHostsRegexps = null;
|
||||||
this._allowedHostsRegexps = null;
|
this._allowedHostsRegexps = null;
|
||||||
this._serverCandidates = null;
|
this._serverCandidates = null;
|
||||||
|
this._started = false;
|
||||||
|
|
||||||
this.onMembership = this.onMembership.bind(this);
|
this.onMembership = this.onMembership.bind(this);
|
||||||
this.onRoomState = this.onRoomState.bind(this);
|
this.onRoomState = this.onRoomState.bind(this);
|
||||||
|
@ -101,11 +102,17 @@ export class RoomPermalinkCreator {
|
||||||
this.load();
|
this.load();
|
||||||
this._room.on("RoomMember.membership", this.onMembership);
|
this._room.on("RoomMember.membership", this.onMembership);
|
||||||
this._room.on("RoomState.events", this.onRoomState);
|
this._room.on("RoomState.events", this.onRoomState);
|
||||||
|
this._started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
this._room.removeListener("RoomMember.membership", this.onMembership);
|
this._room.removeListener("RoomMember.membership", this.onMembership);
|
||||||
this._room.removeListener("RoomState.events", this.onRoomState);
|
this._room.removeListener("RoomState.events", this.onRoomState);
|
||||||
|
this._started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isStarted() {
|
||||||
|
return this._started;
|
||||||
}
|
}
|
||||||
|
|
||||||
forEvent(eventId) {
|
forEvent(eventId) {
|
||||||
|
|
|
@ -262,13 +262,6 @@ export const SETTINGS = {
|
||||||
supportedLevels: ['account'],
|
supportedLevels: ['account'],
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
"breadcrumb_scroll_tolerances": {
|
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
|
||||||
default: {
|
|
||||||
xyThreshold: 10,
|
|
||||||
yReduction: 0.8,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"analyticsOptIn": {
|
"analyticsOptIn": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
|
||||||
displayName: _td('Send analytics data'),
|
displayName: _td('Send analytics data'),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue