diff --git a/res/css/_components.scss b/res/css/_components.scss index 3aa127e03a..985987ec2e 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -228,6 +228,7 @@ @import "./views/rooms/_EventBubbleTile.scss"; @import "./views/rooms/_EventTile.scss"; @import "./views/rooms/_GroupLayout.scss"; +@import "./views/rooms/_HistoryTile.scss"; @import "./views/rooms/_IRCLayout.scss"; @import "./views/rooms/_JumpToBottomButton.scss"; @import "./views/rooms/_LinkPreviewGroup.scss"; diff --git a/res/css/views/rooms/_HistoryTile.scss b/res/css/views/rooms/_HistoryTile.scss new file mode 100644 index 0000000000..48f5a4ce2e --- /dev/null +++ b/res/css/views/rooms/_HistoryTile.scss @@ -0,0 +1,20 @@ +/* +Copyright 2021 Robin Townsend + +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_HistoryTile::before { + background-color: $header-panel-text-primary-color; + mask-image: url('$(res)/img/element-icons/hide.svg'); +} diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 660a97ef55..5be430a6d2 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -35,6 +35,7 @@ import { hasText } from "../../TextForEvent"; import IRCTimelineProfileResizer from "../views/elements/IRCTimelineProfileResizer"; import DMRoomMap from "../../utils/DMRoomMap"; import NewRoomIntro from "../views/rooms/NewRoomIntro"; +import HistoryTile from "../views/rooms/HistoryTile"; import { replaceableComponent } from "../../utils/replaceableComponent"; import defaultDispatcher from '../../dispatcher/dispatcher'; import CallEventGrouper from "./CallEventGrouper"; @@ -129,8 +130,8 @@ interface IProps { // for pending messages. ourUserId?: string; - // true to suppress the date at the start of the timeline - suppressFirstDateSeparator?: boolean; + // whether the timeline can visually go back any further + canBackPaginate?: boolean; // whether to show read receipts showReadReceipts?: boolean; @@ -823,7 +824,7 @@ export default class MessagePanel extends React.Component { if (prevEvent == null) { // first event in the panel: depends if we could back-paginate from // here. - return !this.props.suppressFirstDateSeparator; + return !this.props.canBackPaginate; } return wantsDateSeparator(prevEvent.getDate(), nextEventDate); } @@ -1365,6 +1366,12 @@ class MemberGrouper extends BaseGrouper { eventTiles = null; } + // If a membership event is the start of visible history, tell the user + // why they can't see earlier messages + if (!this.panel.props.canBackPaginate && !this.prevEvent) { + ret.push(); + } + ret.push( { highlightedEventId={this.props.highlightedEventId} readMarkerEventId={this.state.readMarkerEventId} readMarkerVisible={this.state.readMarkerVisible} - suppressFirstDateSeparator={this.state.canBackPaginate} + canBackPaginate={this.state.canBackPaginate && this.state.firstVisibleEventIndex === 0} showUrlPreview={this.props.showUrlPreview} showReadReceipts={this.props.showReadReceipts} ourUserId={MatrixClientPeg.get().credentials.userId} diff --git a/src/components/views/rooms/HistoryTile.tsx b/src/components/views/rooms/HistoryTile.tsx new file mode 100644 index 0000000000..9247ead012 --- /dev/null +++ b/src/components/views/rooms/HistoryTile.tsx @@ -0,0 +1,47 @@ +/* +Copyright 2021 Robin Townsend + +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, { useContext } from "react"; +import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline"; + +import EventTileBubble from "../messages/EventTileBubble"; +import RoomContext from "../../../contexts/RoomContext"; +import { _t } from "../../../languageHandler"; + +const HistoryTile = () => { + const { room } = useContext(RoomContext); + + const oldState = room.getLiveTimeline().getState(EventTimeline.BACKWARDS); + const encryptionState = oldState.getStateEvents("m.room.encryption")[0]; + const historyState = oldState.getStateEvents("m.room.history_visibility")[0]?.getContent().history_visibility; + + let subtitle; + if (historyState == "invited") { + subtitle = _t("You don't have permission to view messages from before you were invited."); + } else if (historyState == "joined") { + subtitle = _t("You don't have permission to view messages from before you joined."); + } else if (encryptionState) { + subtitle = _t("Encrypted messages before this point are unavailable."); + } + + return ; +}; + +export default HistoryTile; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 202c639608..83d550a60b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1687,6 +1687,10 @@ "Encrypting your message...": "Encrypting your message...", "Your message was sent": "Your message was sent", "Failed to send": "Failed to send", + "You don't have permission to view messages from before you were invited.": "You don't have permission to view messages from before you were invited.", + "You don't have permission to view messages from before you joined.": "You don't have permission to view messages from before you joined.", + "Encrypted messages before this point are unavailable.": "Encrypted messages before this point are unavailable.", + "You can't see earlier messages": "You can't see earlier messages", "Scroll to most recent messages": "Scroll to most recent messages", "Show %(count)s other previews|other": "Show %(count)s other previews", "Show %(count)s other previews|one": "Show %(count)s other preview",