diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index ba5d5780b4..46dce8bd2e 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -14,31 +14,40 @@ 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. */ -var React = require('react'); -var ReactDOM = require('react-dom'); -var sdk = require('../../index'); -var MatrixClientPeg = require("../../MatrixClientPeg"); -var PlatformPeg = require("../../PlatformPeg"); -var Modal = require('../../Modal'); -var dis = require("../../dispatcher"); -var q = require('q'); -var package_json = require('../../../package.json'); -var UserSettingsStore = require('../../UserSettingsStore'); -var GeminiScrollbar = require('react-gemini-scrollbar'); -var Email = require('../../email'); -var AddThreepid = require('../../AddThreepid'); -var SdkConfig = require('../../SdkConfig'); +const React = require('react'); +const ReactDOM = require('react-dom'); +const sdk = require('../../index'); +const MatrixClientPeg = require("../../MatrixClientPeg"); +const PlatformPeg = require("../../PlatformPeg"); +const Modal = require('../../Modal'); +const dis = require("../../dispatcher"); +const q = require('q'); +const packageJson = require('../../../package.json'); +const UserSettingsStore = require('../../UserSettingsStore'); +const GeminiScrollbar = require('react-gemini-scrollbar'); +const Email = require('../../email'); +const AddThreepid = require('../../AddThreepid'); +const SdkConfig = require('../../SdkConfig'); import AccessibleButton from '../views/elements/AccessibleButton'; // if this looks like a release, use the 'version' from package.json; else use // the git sha. Prepend version with v, to look like riot-web version -const REACT_SDK_VERSION = 'dist' in package_json ? `v${package_json.version}` : package_json.gitHead || ''; +const REACT_SDK_VERSION = 'dist' in packageJson ? packageJson.version : packageJson.gitHead || ''; // Simple method to help prettify GH Release Tags and Commit Hashes. -const GHVersionUrl = function(repo, token) { - const uriTail = (token.startsWith('v') && token.includes('.')) ? `releases/tag/${token}` : `commit/${token}`; - return `https://github.com/${repo}/${uriTail}`; -} +const semVerRegex = /^v?(\d+\.\d+\.\d+(?:-rc.+)?)(?:-(?:\d+-g)?([0-9a-fA-F]+))?(?:-dirty)?$/i; +const gHVersionLabel = function(repo, token) { + const match = token.match(semVerRegex); + let url; + if (match && match[1]) { // basic semVer string possibly with commit hash + url = (match.length > 1 && match[2]) + ? `https://github.com/${repo}/commit/${match[2]}` + : `https://github.com/${repo}/releases/tag/v${match[1]}`; + } else { + url = `https://github.com/${repo}/commit/${token.split('-')[0]}`; + } + return {token}; +}; // Enumerate some simple 'flip a bit' UI settings (if any). // 'id' gives the key name in the im.vector.web.settings account data event @@ -50,7 +59,7 @@ const SETTINGS_LABELS = [ }, { id: 'hideReadReceipts', - label: 'Hide read receipts' + label: 'Hide read receipts', }, { id: 'dontSendTypingNotifications', @@ -106,7 +115,7 @@ const THEMES = [ id: 'theme', label: 'Dark theme', value: 'dark', - } + }, ]; @@ -180,7 +189,7 @@ module.exports = React.createClass({ }); this._refreshFromServer(); - var syncedSettings = UserSettingsStore.getSyncedSettings(); + const syncedSettings = UserSettingsStore.getSyncedSettings(); if (!syncedSettings.theme) { syncedSettings.theme = 'light'; } @@ -202,16 +211,16 @@ module.exports = React.createClass({ middleOpacity: 1.0, }); dis.unregister(this.dispatcherRef); - let cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.get(); if (cli) { cli.removeListener("RoomMember.membership", this._onInviteStateChange); } }, _refreshFromServer: function() { - var self = this; + const self = this; q.all([ - UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids() + UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids(), ]).done(function(resps) { self.setState({ avatarUrl: resps[0].avatar_url, @@ -219,7 +228,7 @@ module.exports = React.createClass({ phase: "UserSettings.DISPLAY", }); }, function(error) { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to load user settings: " + error); Modal.createDialog(ErrorDialog, { title: "Can't load user settings", @@ -236,7 +245,7 @@ module.exports = React.createClass({ onAvatarPickerClick: function(ev) { if (MatrixClientPeg.get().isGuest()) { - var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + const NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); Modal.createDialog(NeedToRegisterDialog, { title: "Please Register", description: "Guests can't set avatars. Please register.", @@ -250,8 +259,8 @@ module.exports = React.createClass({ }, onAvatarSelected: function(ev) { - var self = this; - var changeAvatar = this.refs.changeAvatar; + const self = this; + const changeAvatar = this.refs.changeAvatar; if (!changeAvatar) { console.error("No ChangeAvatar found to upload image to!"); return; @@ -260,9 +269,9 @@ module.exports = React.createClass({ // dunno if the avatar changed, re-check it. self._refreshFromServer(); }, function(err) { - var errMsg = (typeof err === "string") ? err : (err.error || ""); + // const errMsg = (typeof err === "string") ? err : (err.error || ""); console.error("Failed to set avatar: " + err); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createDialog(ErrorDialog, { title: "Failed to set avatar", description: ((err && err.message) ? err.message : "Operation failed"), @@ -271,7 +280,7 @@ module.exports = React.createClass({ }, onLogoutClicked: function(ev) { - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { title: "Sign out?", description: @@ -286,7 +295,7 @@ module.exports = React.createClass({ + , ], onFinished: (confirmed) => { if (confirmed) { @@ -300,34 +309,33 @@ module.exports = React.createClass({ }, onPasswordChangeError: function(err) { - var errMsg = err.error || ""; + let errMsg = err.error || ""; if (err.httpStatus === 403) { errMsg = "Failed to change password. Is your password correct?"; - } - else if (err.httpStatus) { + } else if (err.httpStatus) { errMsg += ` (HTTP status ${err.httpStatus})`; } - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Failed to change password: " + errMsg); Modal.createDialog(ErrorDialog, { title: "Error", - description: errMsg + description: errMsg, }); }, onPasswordChanged: function() { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createDialog(ErrorDialog, { title: "Success", description: `Your password was successfully changed. You will not receive push notifications on other devices until you - log back in to them.` + log back in to them.`, }); }, onUpgradeClicked: function() { dis.dispatch({ - action: "start_upgrade_registration" + action: "start_upgrade_registration", }); }, @@ -341,11 +349,11 @@ module.exports = React.createClass({ }, _addEmail: function() { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - var email_address = this.refs.add_email_input.value; - if (!Email.looksValid(email_address)) { + const emailAddress = this.refs.add_email_input.value; + if (!Email.looksValid(emailAddress)) { Modal.createDialog(ErrorDialog, { title: "Invalid Email Address", description: "This doesn't appear to be a valid email address", @@ -355,7 +363,7 @@ module.exports = React.createClass({ this._addThreepid = new AddThreepid(); // we always bind emails when registering, so let's do the // same here. - this._addThreepid.addEmailAddress(email_address, true).done(() => { + this._addThreepid.addEmailAddress(emailAddress, true).done(() => { Modal.createDialog(QuestionDialog, { title: "Verification Pending", description: "Please check your email and click on the link it contains. Once this is done, click continue.", @@ -364,7 +372,7 @@ module.exports = React.createClass({ }); }, (err) => { this.setState({email_add_pending: false}); - console.error("Unable to add email address " + email_address + " " + err); + console.error("Unable to add email address " + emailAddress + " " + err); Modal.createDialog(ErrorDialog, { title: "Unable to add email address", description: ((err && err.message) ? err.message : "Operation failed"), @@ -418,9 +426,9 @@ module.exports = React.createClass({ this.setState({email_add_pending: false}); }, (err) => { this.setState({email_add_pending: false}); - if (err.errcode == 'M_THREEPID_AUTH_FAILED') { - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - var message = "Unable to verify email address. "; + if (err.errcode === 'M_THREEPID_AUTH_FAILED') { + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + let message = "Unable to verify email address. "; message += "Please check your email and click on the link it contains. Once this is done, click continue."; Modal.createDialog(QuestionDialog, { title: "Verification Pending", @@ -429,7 +437,7 @@ module.exports = React.createClass({ onFinished: this.onEmailDialogFinished, }); } else { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); console.error("Unable to verify email address: " + err); Modal.createDialog(ErrorDialog, { title: "Unable to verify email address", @@ -469,17 +477,17 @@ module.exports = React.createClass({ _onRejectAllInvitesClicked: function(rooms, ev) { this.setState({ - rejectingInvites: true + rejectingInvites: true, }); // reject the invites - let promises = rooms.map((room) => { + const promises = rooms.map((room) => { return MatrixClientPeg.get().leave(room.roomId); }); // purposefully drop errors to the floor: we'll just have a non-zero number on the UI // after trying to reject all the invites. q.allSettled(promises).then(() => { this.setState({ - rejectingInvites: false + rejectingInvites: false, }); }).done(); }, @@ -492,7 +500,7 @@ module.exports = React.createClass({ }, "e2e-export"); }, { matrixClient: MatrixClientPeg.get(), - } + }, ); }, @@ -504,7 +512,7 @@ module.exports = React.createClass({ }, "e2e-export"); }, { matrixClient: MatrixClientPeg.get(), - } + }, ); }, @@ -530,8 +538,6 @@ module.exports = React.createClass({ }, _renderUserInterfaceSettings: function() { - var client = MatrixClientPeg.get(); - return (

User Interface

@@ -549,7 +555,7 @@ module.exports = React.createClass({ UserSettingsStore.setUrlPreviewsDisabled(e.target.checked) } + onChange={ (e) => UserSettingsStore.setUrlPreviewsDisabled(e.target.checked) } />