diff --git a/res/css/_common.scss b/res/css/_common.scss index 4a9c2945f5..11894e414a 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -36,6 +36,12 @@ body { color: $warning-color; } +b { + // On Firefox, the default weight for `` is `bolder` which results in no bold + // effect since we only have specific weights of our fonts available. + font-weight: bold; +} + h2 { color: $primary-fg-color; font-weight: 400; diff --git a/src/SdkConfig.js b/src/SdkConfig.js index 78dd050a1e..eb18dad453 100644 --- a/src/SdkConfig.js +++ b/src/SdkConfig.js @@ -41,6 +41,12 @@ class SdkConfig { static unset() { global.mxReactSdkConfig = undefined; } + + static add(cfg) { + const liveConfig = SdkConfig.get(); + const newConfig = Object.assign({}, liveConfig, cfg); + SdkConfig.put(newConfig); + } } module.exports = SdkConfig; diff --git a/src/components/structures/GenericErrorPage.js b/src/components/structures/GenericErrorPage.js index 1962b471f3..f28f66064c 100644 --- a/src/components/structures/GenericErrorPage.js +++ b/src/components/structures/GenericErrorPage.js @@ -35,4 +35,4 @@ export default class GenericErrorPage extends React.PureComponent { ; } -} \ No newline at end of file +} diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index fe0deb0d49..f6ca6fbdd9 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1797,7 +1797,7 @@ export default React.createClass({ }, _setPageSubtitle: function(subtitle='') { - document.title = `Riot ${subtitle}`; + document.title = `${SdkConfig.get().brand || 'Riot'} ${subtitle}`; }, updateStatusIndicator: function(state, prevState) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 92775f75b3..fdfc6acf9b 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -272,6 +272,28 @@ module.exports = React.createClass({ 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() { this.setState({ showApps: this._shouldShowApps(this.state.room), @@ -436,9 +458,7 @@ module.exports = React.createClass({ } // stop tracking room changes to format permalinks - if (this.state.permalinkCreator) { - this.state.permalinkCreator.stop(); - } + this._stopAllPermalinkCreators(); if (this.refs.roomView) { // disconnect the D&D event listeners from the room view. This @@ -651,11 +671,6 @@ module.exports = React.createClass({ this._loadMembersIfJoined(room); this._calculateRecommendedVersion(room); this._updateE2EStatus(room); - if (!this.state.permalinkCreator) { - const permalinkCreator = new RoomPermalinkCreator(room); - permalinkCreator.start(); - this.setState({permalinkCreator}); - } }, _calculateRecommendedVersion: async function(room) { @@ -1169,6 +1184,7 @@ module.exports = React.createClass({ const mxEv = result.context.getEvent(); const roomId = mxEv.getRoomId(); + const room = cli.getRoom(roomId); if (!EventTile.haveTileForEvent(mxEv)) { // 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 (roomId != lastRoomId) { - const room = cli.getRoom(roomId); // 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 @@ -1199,7 +1214,7 @@ module.exports = React.createClass({ searchResult={result} searchHighlights={this.state.searchHighlights} resultLink={resultLink} - permalinkCreator={this.state.permalinkCreator} + permalinkCreator={this._getPermalinkCreatorForRoom(room)} onHeightChanged={onHeightChanged} />); } return ret; @@ -1724,7 +1739,7 @@ module.exports = React.createClass({ disabled={this.props.disabled} showApps={this.state.showApps} e2eStatus={this.state.e2eStatus} - permalinkCreator={this.state.permalinkCreator} + permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)} />; } @@ -1826,7 +1841,7 @@ module.exports = React.createClass({ showUrlPreview = {this.state.showUrlPreview} className="mx_RoomView_messagePanel" membersLoaded={this.state.membersLoaded} - permalinkCreator={this.state.permalinkCreator} + permalinkCreator={this._getPermalinkCreatorForRoom(this.state.room)} resizeNotifier={this.props.resizeNotifier} />); diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js index 7667e11d46..2ba05a0e6b 100644 --- a/src/components/views/settings/KeyBackupPanel.js +++ b/src/components/views/settings/KeyBackupPanel.js @@ -187,12 +187,17 @@ export default class KeyBackupPanel extends React.PureComponent { clientBackupStatus =

{encryptedMessageAreEncrypted}

{_t( - "This device is not backing up your keys.", {}, + "This device is not backing up your keys, " + + "but you do have an existing backup you can restore from " + + "and add to going forward.", {}, {b: sub => {sub}}, )}

-

{_t("Back up your keys before signing out to avoid losing them.")}

+

{_t( + "Connect this device to key backup before signing out to avoid " + + "losing any keys that may only be on this device.", + )}

; - restoreButtonCaption = _t("Use key backup"); + restoreButtonCaption = _t("Connect this device to Key Backup"); } let uploadStatus; @@ -221,7 +226,10 @@ export default class KeyBackupPanel extends React.PureComponent { {sub} ; const device = sub => {deviceName}; - const fromThisDevice = sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key(); + const fromThisDevice = ( + sig.device && + sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key() + ); let sigStatus; if (!sig.device) { sigStatus = _t( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e4d1d3ea80..d0f265e430 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -467,9 +467,9 @@ "Unable to load key backup status": "Unable to load key backup status", "Restore from Backup": "Restore from Backup", "This device is backing up your keys. ": "This device is backing up your keys. ", - "This device is not backing up your keys.": "This device is not backing up your keys.", - "Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.", - "Use key backup": "Use key backup", + "This device is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "This device is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.", + "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.", + "Connect this device to Key Backup": "Connect this device to Key Backup", "Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...", "All keys backed up": "All keys backed up", "Backup has a signature from unknown device with ID %(deviceId)s.": "Backup has a signature from unknown device with ID %(deviceId)s.", @@ -485,6 +485,7 @@ "Backup version: ": "Backup version: ", "Algorithm: ": "Algorithm: ", "Your keys are not being backed up from this device.": "Your keys are not being backed up from this device.", + "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", "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.", diff --git a/src/matrix-to.js b/src/matrix-to.js index bb7ddfbd94..a198bb422e 100644 --- a/src/matrix-to.js +++ b/src/matrix-to.js @@ -77,6 +77,7 @@ export class RoomPermalinkCreator { this._bannedHostsRegexps = null; this._allowedHostsRegexps = null; this._serverCandidates = null; + this._started = false; this.onMembership = this.onMembership.bind(this); this.onRoomState = this.onRoomState.bind(this); @@ -101,11 +102,17 @@ export class RoomPermalinkCreator { this.load(); this._room.on("RoomMember.membership", this.onMembership); this._room.on("RoomState.events", this.onRoomState); + this._started = true; } stop() { this._room.removeListener("RoomMember.membership", this.onMembership); this._room.removeListener("RoomState.events", this.onRoomState); + this._started = false; + } + + isStarted() { + return this._started; } forEvent(eventId) {