From 8104ba936cad7a0c1c03ac0aceb6a608651bba36 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Tue, 27 Jul 2021 11:30:25 +0200 Subject: [PATCH] Add data-layout to MELS for better CSS structure --- res/css/views/rooms/_EventBubbleTile.scss | 161 +++++++++--------- src/components/structures/MessagePanel.tsx | 20 ++- .../views/elements/EventListSummary.tsx | 9 +- .../views/elements/MemberEventListSummary.tsx | 5 + 4 files changed, 105 insertions(+), 90 deletions(-) diff --git a/res/css/views/rooms/_EventBubbleTile.scss b/res/css/views/rooms/_EventBubbleTile.scss index 7e127e0dd5..1d43c3030d 100644 --- a/res/css/views/rooms/_EventBubbleTile.scss +++ b/res/css/views/rooms/_EventBubbleTile.scss @@ -15,7 +15,7 @@ limitations under the License. */ .mx_EventTile[data-layout=bubble], -.mx_EventTile[data-layout=bubble] ~ .mx_EventListSummary { +.mx_EventListSummary[data-layout=bubble] { --avatarSize: 32px; --gutterSize: 11px; --cornerRadius: 12px; @@ -224,90 +224,6 @@ limitations under the License. border-left-color: $eventbubble-reply-color; } - &.mx_EventTile_bubbleContainer, - &.mx_EventTile_info, - & ~ .mx_EventListSummary[data-expanded=false] { - --backgroundColor: transparent; - --gutterSize: 0; - - display: flex; - align-items: center; - justify-content: center; - padding: 5px 0; - - .mx_EventTile_avatar { - position: static; - order: -1; - margin-right: 5px; - } - } - - & ~ .mx_EventListSummary { - --maxWidth: 80%; - margin-left: calc(var(--avatarSize) + var(--gutterSize)); - margin-right: calc(var(--gutterSize) + var(--avatarSize)); - .mx_EventListSummary_toggle { - float: none; - margin: 0; - order: 9; - margin-left: 5px; - } - .mx_EventListSummary_avatars { - padding-top: 0; - } - - &::after { - content: ""; - clear: both; - } - - .mx_EventTile { - margin: 0 6px; - } - - .mx_EventTile_line { - margin: 0 5px; - > a { - left: auto; - right: 0; - transform: translateX(calc(100% + 5px)); - } - } - - .mx_MessageActionBar { - transform: translate3d(90%, 0, 0); - } - } - - & ~ .mx_EventListSummary[data-expanded=false] { - padding: 0 34px; - } - - /* events that do not require bubble layout */ - & ~ .mx_EventListSummary, - &.mx_EventTile_bad { - .mx_EventTile_line { - background: transparent; - } - - &:hover { - &::before { - background: transparent; - } - } - } - - & + .mx_EventListSummary { - .mx_EventTile { - margin-top: 0; - padding: 2px 0; - } - } - - .mx_EventListSummary_toggle { - margin-right: 55px; - } - /* Special layout scenario for "Unable To Decrypt (UTD)" events */ &.mx_EventTile_bad > .mx_EventTile_line { display: grid; @@ -342,3 +258,78 @@ limitations under the License. max-width: 100%; } } + +.mx_EventTile.mx_EventTile_bubbleContainer[data-layout=bubble], +.mx_EventTile.mx_EventTile_info[data-layout=bubble], +.mx_EventListSummary[data-layout=bubble][data-expanded=false] { + --backgroundColor: transparent; + --gutterSize: 0; + + display: flex; + align-items: center; + justify-content: center; + padding: 5px 0; + + .mx_EventTile_avatar { + position: static; + order: -1; + margin-right: 5px; + } +} + +.mx_EventListSummary[data-layout=bubble] { + --maxWidth: 80%; + margin-left: calc(var(--avatarSize) + var(--gutterSize)); + margin-right: calc(var(--gutterSize) + var(--avatarSize)); + .mx_EventListSummary_toggle { + float: none; + margin: 0; + order: 9; + margin-left: 5px; + margin-right: 55px; + } + .mx_EventListSummary_avatars { + padding-top: 0; + } + + &::after { + content: ""; + clear: both; + } + + .mx_EventTile { + margin: 0 6px; + padding: 2px 0; + } + + .mx_EventTile_line { + margin: 0 5px; + > a { + left: auto; + right: 0; + transform: translateX(calc(100% + 5px)); + } + } + + .mx_MessageActionBar { + transform: translate3d(90%, 0, 0); + } +} + +.mx_EventListSummary[data-expanded=false][data-layout=bubble] { + padding: 0 34px; +} + +/* events that do not require bubble layout */ +.mx_EventListSummary[data-layout=bubble], +.mx_EventTile.mx_EventTile_bad[data-layout=bubble] { + .mx_EventTile_line { + background: transparent; + } + + &:hover { + &::before { + background: transparent; + } + } +} diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 39ede68a75..698a36127b 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -618,7 +618,15 @@ export default class MessagePanel extends React.Component { for (const Grouper of groupers) { if (Grouper.canStartGroup(this, mxEv)) { - grouper = new Grouper(this, mxEv, prevEvent, lastShownEvent, nextEvent, nextTile); + grouper = new Grouper( + this, + mxEv, + prevEvent, + lastShownEvent, + this.props.layout, + nextEvent, + nextTile, + ); } } if (!grouper) { @@ -981,6 +989,7 @@ abstract class BaseGrouper { public readonly event: MatrixEvent, public readonly prevEvent: MatrixEvent, public readonly lastShownEvent: MatrixEvent, + protected readonly layout: Layout, public readonly nextEvent?: MatrixEvent, public readonly nextEventTile?: MatrixEvent, ) { @@ -1107,6 +1116,7 @@ class CreationGrouper extends BaseGrouper { onToggle={panel.onHeightChanged} // Update scroll state summaryMembers={[ev.sender]} summaryText={summaryText} + layout={this.layout} > { eventTiles } , @@ -1134,10 +1144,11 @@ class RedactionGrouper extends BaseGrouper { ev: MatrixEvent, prevEvent: MatrixEvent, lastShownEvent: MatrixEvent, + layout: Layout, nextEvent: MatrixEvent, nextEventTile: MatrixEvent, ) { - super(panel, ev, prevEvent, lastShownEvent, nextEvent, nextEventTile); + super(panel, ev, prevEvent, lastShownEvent, layout, nextEvent, nextEventTile); this.events = [ev]; } @@ -1202,6 +1213,7 @@ class RedactionGrouper extends BaseGrouper { onToggle={panel.onHeightChanged} // Update scroll state summaryMembers={Array.from(senders)} summaryText={_t("%(count)s messages deleted.", { count: eventTiles.length })} + layout={this.layout} > { eventTiles } , @@ -1230,8 +1242,9 @@ class MemberGrouper extends BaseGrouper { public readonly event: MatrixEvent, public readonly prevEvent: MatrixEvent, public readonly lastShownEvent: MatrixEvent, + protected readonly layout: Layout, ) { - super(panel, event, prevEvent, lastShownEvent); + super(panel, event, prevEvent, lastShownEvent, layout); this.events = [event]; } @@ -1306,6 +1319,7 @@ class MemberGrouper extends BaseGrouper { events={this.events} onToggle={panel.onHeightChanged} // Update scroll state startExpanded={highlightInMels} + layout={this.layout} > { eventTiles } , diff --git a/src/components/views/elements/EventListSummary.tsx b/src/components/views/elements/EventListSummary.tsx index b1cc9c773d..d66319ca73 100644 --- a/src/components/views/elements/EventListSummary.tsx +++ b/src/components/views/elements/EventListSummary.tsx @@ -22,6 +22,7 @@ import MemberAvatar from '../avatars/MemberAvatar'; import { _t } from '../../../languageHandler'; import { useStateToggle } from "../../../hooks/useStateToggle"; import AccessibleButton from "./AccessibleButton"; +import { Layout } from '../../../settings/Layout'; interface IProps { // An array of member events to summarise @@ -38,6 +39,8 @@ interface IProps { children: ReactNode[]; // Called when the event list expansion is toggled onToggle?(): void; + // The layout currently used + layout?: Layout; } const EventListSummary: React.FC = ({ @@ -48,6 +51,7 @@ const EventListSummary: React.FC = ({ startExpanded, summaryMembers = [], summaryText, + layout, }) => { const [expanded, toggleExpanded] = useStateToggle(startExpanded); @@ -63,7 +67,7 @@ const EventListSummary: React.FC = ({ // If we are only given few events then just pass them through if (events.length < threshold) { return ( -
  • +
  • { children }
  • ); @@ -92,7 +96,7 @@ const EventListSummary: React.FC = ({ } return ( -
  • +
  • { expanded ? _t('collapse') : _t('expand') } @@ -103,6 +107,7 @@ const EventListSummary: React.FC = ({ EventListSummary.defaultProps = { startExpanded: false, + layout: Layout.Group, }; export default EventListSummary; diff --git a/src/components/views/elements/MemberEventListSummary.tsx b/src/components/views/elements/MemberEventListSummary.tsx index d52462f629..604e6c63b0 100644 --- a/src/components/views/elements/MemberEventListSummary.tsx +++ b/src/components/views/elements/MemberEventListSummary.tsx @@ -25,12 +25,15 @@ import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; import { isValid3pidInvite } from "../../../RoomInvite"; import EventListSummary from "./EventListSummary"; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { Layout } from '../../../settings/Layout'; interface IProps extends Omit, "summaryText" | "summaryMembers"> { // The maximum number of names to show in either each summary e.g. 2 would result "A, B and 234 others left" summaryLength?: number; // The maximum number of avatars to display in the summary avatarsMaxLength?: number; + // The currently selected layout + layout: Layout; } interface IUserEvents { @@ -67,6 +70,7 @@ export default class MemberEventListSummary extends React.Component { summaryLength: 1, threshold: 3, avatarsMaxLength: 5, + layout: Layout.Group, }; shouldComponentUpdate(nextProps) { @@ -453,6 +457,7 @@ export default class MemberEventListSummary extends React.Component { startExpanded={this.props.startExpanded} children={this.props.children} summaryMembers={[...latestUserAvatarMember.values()]} + layout={this.props.layout} summaryText={this.generateSummary(aggregate.names, orderedTransitionSequences)} />; } }