{ _t("User Interface") }
-{ _t('Autocomplete Delay (ms):') } | -- - | -
{ _t("Key Backup") }
-{ _t("Cryptography") }
--
-
-
-
{ deviceId }
- -
-
{ identityKey }
-
{ _t("Ignored Users") }
--
- { this.state.ignoredUsers.map(function(userId) {
- return (
{ _t("Devices") }
-{ _t("Submit Debug Logs") }
-{ - _t( "If you've submitted a bug via GitHub, debug logs can help " + - "us track down the problem. Debug logs contain application " + - "usage data including your username, the IDs or aliases of " + - "the rooms or groups you have visited and the usernames of " + - "other users. They do not contain messages.", - ) - }
- -{ _t('Analytics') }
-- { _t('Privacy is important to us, so we don\'t collect any personal' - + ' or identifiable data for our analytics.') } -
{ _t("Labs") }
-{ _t("These are experimental features that may break in unexpected ways") }. { _t("Use with caution") }.
- { features } -{ _t("Deactivate Account") }
-{ _t("Legal") }
-{ _t("Clear Cache") }
-{ _t('Updates') }
-{ _t("Bulk Options") }
-{ _t('Desktop specific') }
-{ _t('No Audio Outputs detected') }
; - let microphoneDropdown ={ _t('No Microphones detected') }
; - let webcamDropdown ={ _t('No Webcams detected') }
; - - const defaultOption = { - deviceId: '', - label: _t('Default Device'), - }; - - const audioOutputs = this.state.mediaDevices.audiooutput.slice(0); - if (audioOutputs.length > 0) { - let defaultOutput = ''; - if (!audioOutputs.some((input) => input.deviceId === 'default')) { - audioOutputs.unshift(defaultOption); - } else { - defaultOutput = 'default'; - } - - speakerDropdown ={ _t('Audio Output') }
-{ _t('Microphone') }
-{ _t('Camera') }
-{ _t('VoIP') }
-{ _t("Notifications") }
- -{ _t("Profile") }
- -{ _t("Account") }
- -{ _t("Advanced") }
- -- { _t('riot-web version:') } { (this.state.vectorVersion !== undefined) - ? gHVersionLabel('vector-im/riot-web', this.state.vectorVersion) - : 'unknown' - }
- { _t("olm version:") } { olmVersionString }
-
- { this.props.device.getDisplayName() }
-
{ this.props.device.deviceId }
diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js
index b6821560721..b068428bed7 100644
--- a/src/components/views/dialogs/InteractiveAuthDialog.js
+++ b/src/components/views/dialogs/InteractiveAuthDialog.js
@@ -77,7 +77,7 @@ export default React.createClass({
- - { unbanButton } - - { this.props.member.name } { this.props.member.userId } - { this.props.reason ? " " +_t('Reason') + ": " + this.props.reason : "" } - - - ); - }, -}); - -module.exports = React.createClass({ - displayName: 'RoomSettings', - - propTypes: { - room: PropTypes.object.isRequired, - }, - - getInitialState: function() { - const tags = {}; - Object.keys(this.props.room.tags).forEach(function(tagName) { - tags[tagName] = ['yep']; - }); - - return { - name: this._yankValueFromEvent("m.room.name", "name"), - topic: this._yankValueFromEvent("m.room.topic", "topic"), - join_rule: this._yankValueFromEvent("m.room.join_rules", "join_rule"), - history_visibility: this._yankValueFromEvent("m.room.history_visibility", "history_visibility"), - guest_access: this._yankValueFromEvent("m.room.guest_access", "guest_access"), - powerLevels: this._yankContentFromEvent("m.room.power_levels", {}), - powerLevelsChanged: false, - tags_changed: false, - tags: tags, - // isRoomPublished is loaded async in componentWillMount so when the component - // inits, the saved value will always be undefined, however getInitialState() - // is also called from the saving code so we must return the correct value here - // if we have it (although this could race if the user saves before we load whether - // the room is published or not). - // Default to false if it's undefined, otherwise react complains about changing - // components from uncontrolled to controlled - isRoomPublished: this._originalIsRoomPublished || false, - }; - }, - - componentWillMount: function() { - MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership); - - MatrixClientPeg.get().getRoomDirectoryVisibility( - this.props.room.roomId, - ).done((result = {}) => { - this.setState({ isRoomPublished: result.visibility === "public" }); - this._originalIsRoomPublished = result.visibility === "public"; - }, (err) => { - console.error("Failed to get room visibility: " + err); - }); - - dis.dispatch({ - action: 'panel_disable', - sideDisabled: true, - middleDisabled: true, - }); - }, - - componentWillUnmount: function() { - const cli = MatrixClientPeg.get(); - if (cli) { - cli.removeListener("RoomMember.membership", this._onRoomMemberMembership); - } - - dis.dispatch({ - action: 'panel_disable', - sideDisabled: false, - middleDisabled: false, - }); - }, - - setName: function(name) { - this.setState({ - name: name, - }); - }, - - setTopic: function(topic) { - this.setState({ - topic: topic, - }); - }, - - /** - * Returns a promise which resolves once all of the save operations have completed or failed. - * - * The result is a list of promise state snapshots, each with the form - * `{ state: "fulfilled", value: v }` or `{ state: "rejected", reason: r }`. - */ - save: function() { - const stateWasSetDefer = Promise.defer(); - // the caller may have JUST called setState on stuff, so we need to re-render before saving - // else we won't use the latest values of things. - // We can be a bit cheeky here and set a loading flag, and listen for the callback on that - // to know when things have been set. - this.setState({ _loading: true}, () => { - stateWasSetDefer.resolve(); - this.setState({ _loading: false}); - }); - - function mapPromiseToSnapshot(p) { - return p.then((r) => { - return { state: "fulfilled", value: r }; - }, (e) => { - return { state: "rejected", reason: e }; - }); - } - - return stateWasSetDefer.promise.then(() => { - return Promise.all( - this._calcSavePromises().map(mapPromiseToSnapshot), - ); - }); - }, - - _calcSavePromises: function() { - const roomId = this.props.room.roomId; - const promises = this.saveAliases(); // returns Promise[] - const originalState = this.getInitialState(); - - // diff between original state and this.state to work out what has been changed - console.log("Original: %s", JSON.stringify(originalState)); - console.log("New: %s", JSON.stringify(this.state)); - - // name and topic - if (this._hasDiff(this.state.name, originalState.name)) { - promises.push(MatrixClientPeg.get().setRoomName(roomId, this.state.name)); - } - if (this._hasDiff(this.state.topic, originalState.topic)) { - promises.push(MatrixClientPeg.get().setRoomTopic(roomId, this.state.topic)); - } - - if (this.state.history_visibility !== originalState.history_visibility) { - promises.push(MatrixClientPeg.get().sendStateEvent( - roomId, "m.room.history_visibility", - { history_visibility: this.state.history_visibility }, - "", - )); - } - - if (this.state.isRoomPublished !== originalState.isRoomPublished) { - promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility( - roomId, - this.state.isRoomPublished ? "public" : "private", - )); - } - - if (this.state.join_rule !== originalState.join_rule) { - promises.push(MatrixClientPeg.get().sendStateEvent( - roomId, "m.room.join_rules", - { join_rule: this.state.join_rule }, - "", - )); - } - - if (this.state.guest_access !== originalState.guest_access) { - promises.push(MatrixClientPeg.get().sendStateEvent( - roomId, "m.room.guest_access", - { guest_access: this.state.guest_access }, - "", - )); - } - - - // power levels - const powerLevels = this.state.powerLevels; - if (this.state.powerLevelsChanged) { - promises.push(MatrixClientPeg.get().sendStateEvent( - roomId, "m.room.power_levels", powerLevels, "", - )); - } - - // tags - if (this.state.tags_changed) { - const tagDiffs = ObjectUtils.getKeyValueArrayDiffs(originalState.tags, this.state.tags); - // [ {place: add, key: "m.favourite", val: ["yep"]} ] - tagDiffs.forEach(function(diff) { - switch (diff.place) { - case "add": - promises.push( - MatrixClientPeg.get().setRoomTag(roomId, diff.key, {}), - ); - break; - case "del": - promises.push( - MatrixClientPeg.get().deleteRoomTag(roomId, diff.key), - ); - break; - default: - console.error("Unknown tag operation: %s", diff.place); - break; - } - }); - } - - // color scheme - let p; - p = this.saveColor(); - if (!p.isFulfilled()) { - promises.push(p); - } - - // related groups - promises.push(this.saveRelatedGroups()); - - // encryption - p = this.saveEnableEncryption(); - if (!p.isFulfilled()) { - promises.push(p); - } - - this.saveBlacklistUnverifiedDevicesPerRoom(); - - console.log("Performing %s operations: %s", promises.length, JSON.stringify(promises)); - return promises; - }, - - saveAliases: function() { - if (!this.refs.alias_settings) { return [Promise.resolve()]; } - return this.refs.alias_settings.saveSettings(); - }, - - saveRelatedGroups: function() { - if (!this.refs.related_groups) { return Promise.resolve(); } - return this.refs.related_groups.saveSettings(); - }, - - saveColor: function() { - if (!this.refs.color_settings) { return Promise.resolve(); } - return this.refs.color_settings.saveSettings(); - }, - - saveEnableEncryption: function() { - if (!this.refs.encrypt) { return Promise.resolve(); } - - const encrypt = this.refs.encrypt.checked; - if (!encrypt) { return Promise.resolve(); } - - const roomId = this.props.room.roomId; - return MatrixClientPeg.get().sendStateEvent( - roomId, "m.room.encryption", - { algorithm: "m.megolm.v1.aes-sha2" }, - ); - }, - - saveBlacklistUnverifiedDevicesPerRoom: function() { - if (!this.refs.blacklistUnverifiedDevices) return; - this.refs.blacklistUnverifiedDevices.save().then(() => { - const value = SettingsStore.getValueAt( - SettingLevel.ROOM_DEVICE, - "blacklistUnverifiedDevices", - this.props.room.roomId, - /*explicit=*/true, - ); - this.props.room.setBlacklistUnverifiedDevices(value); - }); - }, - - _hasDiff: function(strA, strB) { - // treat undefined as an empty string because other components may blindly - // call setName("") when there has been no diff made to the name! - strA = strA || ""; - strB = strB || ""; - return strA !== strB; - }, - - onPowerLevelsChanged: function(value, powerLevelKey) { - const powerLevels = Object.assign({}, this.state.powerLevels); - const eventsLevelPrefix = "event_levels_"; - - value = parseInt(value); - - if (powerLevelKey.startsWith(eventsLevelPrefix)) { - // deep copy "events" object, Object.assign itself won't deep copy - powerLevels["events"] = Object.assign({}, this.state.powerLevels["events"] || {}); - powerLevels["events"][powerLevelKey.slice(eventsLevelPrefix.length)] = value; - } else { - const keyPath = powerLevelKey.split('.'); - let parentObj; - let currentObj = powerLevels; - for (const key of keyPath) { - if (!currentObj[key]) { - currentObj[key] = {}; - } - parentObj = currentObj; - currentObj = currentObj[key]; - } - parentObj[keyPath[keyPath.length - 1]] = value; - } - this.setState({ - powerLevels, - powerLevelsChanged: true, - }); - }, - - _yankContentFromEvent: function(stateEventType, defaultValue) { - // E.g.("m.room.name") would yank the content of "m.room.name" - const event = this.props.room.currentState.getStateEvents(stateEventType, ''); - if (!event) { - return defaultValue; - } - return event.getContent() || defaultValue; - }, - - _yankValueFromEvent: function(stateEventType, keyName, defaultValue) { - // E.g.("m.room.name","name") would yank the "name" content key from "m.room.name" - const event = this.props.room.currentState.getStateEvents(stateEventType, ''); - if (!event) { - return defaultValue; - } - const content = event.getContent(); - return keyName in content ? content[keyName] : defaultValue; - }, - - _onHistoryRadioToggle: function(ev) { - const self = this; - const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - - // cancel the click unless the user confirms it - ev.preventDefault(); - const value = ev.target.value; - - Modal.createTrackedDialog('Privacy warning', '', QuestionDialog, { - title: _t('Privacy warning'), - description: -
-
- { _t("%(user)s is a %(userRole)s", {
- user: user,
- userRole:
, - }) } - );
- } else if (userLevels[user] < defaultUserLevel) { // muted
- mutedUsers.push( -
- { _t("%(user)s is a %(userRole)s", {
- user: user,
- userRole:
, - }) } - );
- }
- });
-
- // comparator for sorting PL users lexicographically on PL descending, MXID ascending. (case-insensitive)
- const comparator = (a, b) => {
- const plDiff = userLevels[b.key] - userLevels[a.key];
- return plDiff !== 0 ? plDiff : a.key.toLocaleLowerCase().localeCompare(b.key.toLocaleLowerCase());
- };
-
- privilegedUsers.sort(comparator);
- mutedUsers.sort(comparator);
-
- if (privilegedUsers.length) {
- privilegedUsersSection =
-
- { _t('The visibility of existing history will be unchanged') }. -
{ _t('Privileged Users') }
--
- { privilegedUsers }
-
{ _t('Muted Users') }
--
- { mutedUsers }
-
{ _t('Banned users') }
--
- { banned.map(function(member) {
- const banEvent = member.events.member.getContent();
- const sender = self.props.room.getMember(member.events.member.getSender());
- let bannedBy = member.events.member.getSender(); // start by falling back to mxid
- if (sender) bannedBy = sender.name;
- return (
-
{ eventType }
},
- );
- }
- return (
- { _t('Who can access this room?') }
- { inviteGuestWarning } - - - - { addressWarning } -- { this._renderEncryptionSection() } - -
{ _t('Who can read history?') }
- - - - -{ _t('Room Colour') }
-{ _t('Permissions') }
-{ _t('Advanced') }
-{ this.props.room.roomId }
- { _t('Room version number: ') }
{ this.props.room.getVersion() }
- { roomUpgradeButton } - { devtoolsButton } -