diff --git a/res/css/_components.scss b/res/css/_components.scss index 9823b4ac3d..4b8b687146 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -124,6 +124,7 @@ @import "./views/messages/_SenderProfile.scss"; @import "./views/messages/_TextualEvent.scss"; @import "./views/messages/_UnknownBody.scss"; +@import "./views/messages/_ViewSourceEvent.scss"; @import "./views/room_settings/_AliasSettings.scss"; @import "./views/room_settings/_ColorSettings.scss"; @import "./views/rooms/_AppsDrawer.scss"; diff --git a/res/css/views/messages/_ViewSourceEvent.scss b/res/css/views/messages/_ViewSourceEvent.scss new file mode 100644 index 0000000000..a15924e759 --- /dev/null +++ b/res/css/views/messages/_ViewSourceEvent.scss @@ -0,0 +1,50 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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. +*/ + +.mx_EventTile_content.mx_ViewSourceEvent { + display: flex; + opacity: 0.6; + font-size: 12px; + + pre, code { + flex: 1; + } + + pre { + line-height: 1.2; + margin: 3.5px 0; + } + + .mx_ViewSourceEvent_toggle { + width: 12px; + mask-repeat: no-repeat; + mask-position: 0 center; + mask-size: auto 12px; + visibility: hidden; + background-color: $accent-color; + mask-image: url('$(res)/img/feather-customised/widget/maximise.svg'); + } + + &.mx_ViewSourceEvent_expanded .mx_ViewSourceEvent_toggle { + mask-position: 0 bottom; + margin-bottom: 7px; + mask-image: url('$(res)/img/feather-customised/widget/minimise.svg'); + } + + &:hover .mx_ViewSourceEvent_toggle { + visibility: visible; + } +} diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index dbaab57adf..562d067a7b 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -24,6 +24,7 @@ import {wantsDateSeparator} from '../../DateUtils'; import sdk from '../../index'; import MatrixClientPeg from '../../MatrixClientPeg'; +import SettingsStore from '../../settings/SettingsStore'; const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes const continuedTypes = ['m.sticker', 'm.room.message']; @@ -248,6 +249,10 @@ module.exports = React.createClass({ return false; // ignored = no show (only happens if the ignore happens after an event was received) } + if (SettingsStore.isFeatureEnabled("showHiddenEventsInTimeline")) { + return true; + } + const EventTile = sdk.getComponent('rooms.EventTile'); if (!EventTile.haveTileForEvent(mxEv)) { return false; // no tile = no show diff --git a/src/components/views/messages/ViewSourceEvent.js b/src/components/views/messages/ViewSourceEvent.js new file mode 100644 index 0000000000..717a4b0f05 --- /dev/null +++ b/src/components/views/messages/ViewSourceEvent.js @@ -0,0 +1,67 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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 classNames from 'classnames'; + +export default class ViewSourceEvent extends React.PureComponent { + static propTypes = { + /* the MatrixEvent to show */ + mxEvent: PropTypes.object.isRequired, + }; + + constructor(props) { + super(props); + + this.state = { + expanded: false, + }; + } + + onToggle = (ev) => { + ev.preventDefault(); + const { expanded } = this.state; + this.setState({ + expanded: !expanded, + }); + } + + render() { + const { mxEvent } = this.props; + const { expanded } = this.state; + + let content; + if (expanded) { + content =
{JSON.stringify(mxEvent, null, 4)}; + } else { + content =
{`{ "type": ${mxEvent.getType()} }`}
;
+ }
+
+ const classes = classNames("mx_ViewSourceEvent mx_EventTile_content", {
+ mx_ViewSourceEvent_expanded: expanded,
+ });
+
+ return
+ {content}
+
+ ;
+ }
+ }
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index f38e3c3946..91699c0c99 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -520,7 +520,10 @@ module.exports = withMatrixClient(React.createClass({
eventType !== 'm.room.message' && eventType !== 'm.sticker' && eventType != 'm.room.create'
);
- const tileHandler = getHandlerTile(this.props.mxEvent);
+ let tileHandler = getHandlerTile(this.props.mxEvent);
+ if (!tileHandler && SettingsStore.isFeatureEnabled("showHiddenEventsInTimeline")) {
+ tileHandler = "messages.ViewSourceEvent";
+ }
// This shouldn't happen: the caller should check we support this type
// before trying to instantiate us
if (!tileHandler) {
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 86131645cf..067c2bdeef 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -302,6 +302,7 @@
"Render simple counters in room header": "Render simple counters in room header",
"Edit messages after they have been sent (refresh to apply changes)": "Edit messages after they have been sent (refresh to apply changes)",
"React to messages with emoji (refresh to apply changes)": "React to messages with emoji (refresh to apply changes)",
+ "Show hidden events in timeline": "Show hidden events in timeline",
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
"Use compact timeline layout": "Use compact timeline layout",
"Show a placeholder for removed messages": "Show a placeholder for removed messages",
diff --git a/src/settings/Settings.js b/src/settings/Settings.js
index 429030d862..5db8599112 100644
--- a/src/settings/Settings.js
+++ b/src/settings/Settings.js
@@ -130,6 +130,12 @@ export const SETTINGS = {
supportedLevels: LEVELS_FEATURE,
default: false,
},
+ "showHiddenEventsInTimeline": {
+ isFeature: true,
+ displayName: _td("Show hidden events in timeline"),
+ supportedLevels: LEVELS_FEATURE,
+ default: false,
+ },
"MessageComposerInput.suggestEmoji": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Enable Emoji suggestions while typing'),