diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 7ba2022c6d..a6481d5b95 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -44,6 +44,8 @@ import { ViewUserPayload } from "./dispatcher/payloads/ViewUserPayload"; import { Action } from "./dispatcher/actions"; import { EffectiveMembership, getEffectiveMembership, leaveRoomBehaviour } from "./utils/membership"; import SdkConfig from "./SdkConfig"; +import SettingsStore from "./settings/SettingsStore"; +import {UIFeature} from "./settings/UIFeature"; // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 interface HTMLInputEvent extends Event { @@ -797,6 +799,7 @@ export const Commands = [ command: 'addwidget', args: '', description: _td('Adds a custom widget by URL to the room'), + isEnabled: () => SettingsStore.getValue(UIFeature.Widgets), runFn: function(roomId, widgetUrl) { if (!widgetUrl) { return reject(_t("Please supply a widget URL or embed code")); diff --git a/src/components/views/elements/ErrorBoundary.js b/src/components/views/elements/ErrorBoundary.js index 68bec667d8..9fe6861250 100644 --- a/src/components/views/elements/ErrorBoundary.js +++ b/src/components/views/elements/ErrorBoundary.js @@ -20,6 +20,7 @@ import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import PlatformPeg from '../../../PlatformPeg'; import Modal from '../../../Modal'; +import SdkConfig from "../../../SdkConfig"; /** * This error boundary component can be used to wrap large content areas and @@ -73,9 +74,10 @@ export default class ErrorBoundary extends React.PureComponent { if (this.state.error) { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const newIssueUrl = "https://github.com/vector-im/element-web/issues/new"; - return
-
-

{_t("Something went wrong!")}

+ + let bugReportSection; + if (SdkConfig.get().bug_report_endpoint_url) { + bugReportSection =

{_t( "Please create a new issue " + "on GitHub so that we can investigate this bug.", {}, { @@ -94,6 +96,13 @@ export default class ErrorBoundary extends React.PureComponent { {_t("Submit debug logs")} + ; + } + + return

+
+

{_t("Something went wrong!")}

+ { bugReportSection } {_t("Clear cache and reload")} diff --git a/src/components/views/messages/TileErrorBoundary.js b/src/components/views/messages/TileErrorBoundary.js index e42ddab16a..9b67e32548 100644 --- a/src/components/views/messages/TileErrorBoundary.js +++ b/src/components/views/messages/TileErrorBoundary.js @@ -19,6 +19,7 @@ import classNames from 'classnames'; import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import Modal from '../../../Modal'; +import SdkConfig from "../../../SdkConfig"; export default class TileErrorBoundary extends React.Component { constructor(props) { @@ -54,14 +55,20 @@ export default class TileErrorBoundary extends React.Component { mx_EventTile_content: true, mx_EventTile_tileError: true, }; + + let submitLogsButton; + if (SdkConfig.get().bug_report_endpoint_url) { + submitLogsButton = + {_t("Submit logs")} + ; + } + return (
{_t("Can't load this message")} { mxEvent && ` (${mxEvent.getType()})` } - - {_t("Submit logs")} - + { submitLogsButton }
); diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index f51f66a5ea..9d20dc1fe1 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -42,6 +42,7 @@ import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import WidgetStore, {IApp} from "../../../stores/WidgetStore"; import { E2EStatus } from "../../../utils/ShieldUtils"; import RoomContext from "../../../contexts/RoomContext"; +import {UIFeature} from "../../../settings/UIFeature"; interface IProps { room: Room; @@ -242,7 +243,7 @@ const RoomSummaryCard: React.FC = ({ room, onClose }) => { - + { SettingsStore.getValue(UIFeature.Widgets) && } ; }; diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index fc73c8b542..3171890955 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -952,30 +952,26 @@ function useRoomPermissions(cli, room, user) { const PowerLevelSection = ({user, room, roomPermissions, powerLevels}) => { const [isEditing, setEditing] = useState(false); - if (room && user.roomId) { // is in room - if (isEditing) { - return ( setEditing(false)} />); - } else { - const IconButton = sdk.getComponent('elements.IconButton'); - const powerLevelUsersDefault = powerLevels.users_default || 0; - const powerLevel = parseInt(user.powerLevel, 10); - const modifyButton = roomPermissions.canEdit ? - ( setEditing(true)} />) : null; - const role = textualPowerLevel(powerLevel, powerLevelUsersDefault); - const label = _t("%(role)s in %(roomName)s", - {role, roomName: room.name}, - {strong: label => {label}}, - ); - return ( -
-
{label}{modifyButton}
-
- ); - } + if (isEditing) { + return ( setEditing(false)} />); } else { - return null; + const IconButton = sdk.getComponent('elements.IconButton'); + const powerLevelUsersDefault = powerLevels.users_default || 0; + const powerLevel = parseInt(user.powerLevel, 10); + const modifyButton = roomPermissions.canEdit ? + ( setEditing(true)} />) : null; + const role = textualPowerLevel(powerLevel, powerLevelUsersDefault); + const label = _t("%(role)s in %(roomName)s", + {role, roomName: room.name}, + {strong: label => {label}}, + ); + return ( +
+
{label}{modifyButton}
+
+ ); } }; @@ -1268,14 +1264,15 @@ const BasicUserInfo = ({room, member, groupId, devices, isRoomEncrypted}) => { spinner = ; } - const memberDetails = ( - - ); + />; + } // only display the devices list if our client supports E2E const cryptoEnabled = cli.isCryptoEnabled(); diff --git a/src/components/views/rooms/AuxPanel.js b/src/components/views/rooms/AuxPanel.js index 1f6f104487..f2211dba5c 100644 --- a/src/components/views/rooms/AuxPanel.js +++ b/src/components/views/rooms/AuxPanel.js @@ -28,6 +28,7 @@ import RateLimitedFunc from '../../../ratelimitedfunc'; import SettingsStore from "../../../settings/SettingsStore"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; import CallView from "../voip/CallView"; +import {UIFeature} from "../../../settings/UIFeature"; export default class AuxPanel extends React.Component { @@ -198,18 +199,21 @@ export default class AuxPanel extends React.Component { /> ); - const appsDrawer = ; + let appsDrawer; + if (SettingsStore.getValue(UIFeature.Widgets)) { + appsDrawer = ; + } let stateViews = null; if (this.state.counters && SettingsStore.getValue("feature_state_counters")) { - let counters = []; + const counters = []; this.state.counters.forEach((counter, idx) => { const title = counter.title; @@ -218,7 +222,7 @@ export default class AuxPanel extends React.Component { const severity = counter.severity; const stateKey = counter.stateKey; - let span = { title }: { value } + let span = { title }: { value }; if (link) { span = ( diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 922cc2b11e..81c2ae7a33 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -31,6 +31,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import {aboveLeftOf, ContextMenu, ContextMenuTooltipButton, useContextMenu} from "../../structures/ContextMenu"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import ReplyPreview from "./ReplyPreview"; +import {UIFeature} from "../../../settings/UIFeature"; function ComposerAvatar(props) { const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar'); @@ -384,9 +385,12 @@ export default class MessageComposer extends React.Component { permalinkCreator={this.props.permalinkCreator} />, , , - , ); + if (SettingsStore.getValue(UIFeature.Widgets)) { + controls.push(); + } + if (this.state.showCallButtons) { if (callInProgress) { controls.push( diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 1ebefae590..42e12077f2 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -37,6 +37,7 @@ import {abbreviateUrl} from "../../../../../utils/UrlUtils"; import { getThreepidsWithBindStatus } from '../../../../../boundThreepids'; import Spinner from "../../../elements/Spinner"; import {SettingLevel} from "../../../../../settings/SettingLevel"; +import {UIFeature} from "../../../../../settings/UIFeature"; export default class GeneralUserSettingsTab extends React.Component { static propTypes = { @@ -366,6 +367,8 @@ export default class GeneralUserSettingsTab extends React.Component { } _renderIntegrationManagerSection() { + if (!SettingsStore.getValue(UIFeature.Widgets)) return null; + const SetIntegrationManager = sdk.getComponent("views.settings.SetIntegrationManager"); return ( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 767dcd390c..aa6432ddba 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1440,8 +1440,8 @@ "Click to view edits": "Click to view edits", "Edited at %(date)s. Click to view edits.": "Edited at %(date)s. Click to view edits.", "edited": "edited", - "Can't load this message": "Can't load this message", "Submit logs": "Submit logs", + "Can't load this message": "Can't load this message", "Failed to load group members": "Failed to load group members", "Filter community members": "Filter community members", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?", diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 505e64a024..21b3935c3e 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -618,6 +618,10 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_UI_FEATURE, default: true, }, + [UIFeature.Widgets]: { + supportedLevels: LEVELS_UI_FEATURE, + default: true, + }, [UIFeature.Feedback]: { supportedLevels: LEVELS_UI_FEATURE, default: true, diff --git a/src/settings/UIFeature.ts b/src/settings/UIFeature.ts index 084ac62be7..dddef82df1 100644 --- a/src/settings/UIFeature.ts +++ b/src/settings/UIFeature.ts @@ -17,5 +17,6 @@ limitations under the License. // see settings.md for documentation on conventions export enum UIFeature { URLPreviews = "UIFeature.urlPreviews", + Widgets = "UIFeature.widgets", Feedback = "UIFeature.feedback", }