Add data-layout to MELS for better CSS structure
This commit is contained in:
parent
788abac74d
commit
8104ba936c
4 changed files with 105 additions and 90 deletions
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_EventTile[data-layout=bubble],
|
.mx_EventTile[data-layout=bubble],
|
||||||
.mx_EventTile[data-layout=bubble] ~ .mx_EventListSummary {
|
.mx_EventListSummary[data-layout=bubble] {
|
||||||
--avatarSize: 32px;
|
--avatarSize: 32px;
|
||||||
--gutterSize: 11px;
|
--gutterSize: 11px;
|
||||||
--cornerRadius: 12px;
|
--cornerRadius: 12px;
|
||||||
|
@ -224,90 +224,6 @@ limitations under the License.
|
||||||
border-left-color: $eventbubble-reply-color;
|
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 */
|
/* Special layout scenario for "Unable To Decrypt (UTD)" events */
|
||||||
&.mx_EventTile_bad > .mx_EventTile_line {
|
&.mx_EventTile_bad > .mx_EventTile_line {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -342,3 +258,78 @@ limitations under the License.
|
||||||
max-width: 100%;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -618,7 +618,15 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
for (const Grouper of groupers) {
|
for (const Grouper of groupers) {
|
||||||
if (Grouper.canStartGroup(this, mxEv)) {
|
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) {
|
if (!grouper) {
|
||||||
|
@ -981,6 +989,7 @@ abstract class BaseGrouper {
|
||||||
public readonly event: MatrixEvent,
|
public readonly event: MatrixEvent,
|
||||||
public readonly prevEvent: MatrixEvent,
|
public readonly prevEvent: MatrixEvent,
|
||||||
public readonly lastShownEvent: MatrixEvent,
|
public readonly lastShownEvent: MatrixEvent,
|
||||||
|
protected readonly layout: Layout,
|
||||||
public readonly nextEvent?: MatrixEvent,
|
public readonly nextEvent?: MatrixEvent,
|
||||||
public readonly nextEventTile?: MatrixEvent,
|
public readonly nextEventTile?: MatrixEvent,
|
||||||
) {
|
) {
|
||||||
|
@ -1107,6 +1116,7 @@ class CreationGrouper extends BaseGrouper {
|
||||||
onToggle={panel.onHeightChanged} // Update scroll state
|
onToggle={panel.onHeightChanged} // Update scroll state
|
||||||
summaryMembers={[ev.sender]}
|
summaryMembers={[ev.sender]}
|
||||||
summaryText={summaryText}
|
summaryText={summaryText}
|
||||||
|
layout={this.layout}
|
||||||
>
|
>
|
||||||
{ eventTiles }
|
{ eventTiles }
|
||||||
</EventListSummary>,
|
</EventListSummary>,
|
||||||
|
@ -1134,10 +1144,11 @@ class RedactionGrouper extends BaseGrouper {
|
||||||
ev: MatrixEvent,
|
ev: MatrixEvent,
|
||||||
prevEvent: MatrixEvent,
|
prevEvent: MatrixEvent,
|
||||||
lastShownEvent: MatrixEvent,
|
lastShownEvent: MatrixEvent,
|
||||||
|
layout: Layout,
|
||||||
nextEvent: MatrixEvent,
|
nextEvent: MatrixEvent,
|
||||||
nextEventTile: MatrixEvent,
|
nextEventTile: MatrixEvent,
|
||||||
) {
|
) {
|
||||||
super(panel, ev, prevEvent, lastShownEvent, nextEvent, nextEventTile);
|
super(panel, ev, prevEvent, lastShownEvent, layout, nextEvent, nextEventTile);
|
||||||
this.events = [ev];
|
this.events = [ev];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,6 +1213,7 @@ class RedactionGrouper extends BaseGrouper {
|
||||||
onToggle={panel.onHeightChanged} // Update scroll state
|
onToggle={panel.onHeightChanged} // Update scroll state
|
||||||
summaryMembers={Array.from(senders)}
|
summaryMembers={Array.from(senders)}
|
||||||
summaryText={_t("%(count)s messages deleted.", { count: eventTiles.length })}
|
summaryText={_t("%(count)s messages deleted.", { count: eventTiles.length })}
|
||||||
|
layout={this.layout}
|
||||||
>
|
>
|
||||||
{ eventTiles }
|
{ eventTiles }
|
||||||
</EventListSummary>,
|
</EventListSummary>,
|
||||||
|
@ -1230,8 +1242,9 @@ class MemberGrouper extends BaseGrouper {
|
||||||
public readonly event: MatrixEvent,
|
public readonly event: MatrixEvent,
|
||||||
public readonly prevEvent: MatrixEvent,
|
public readonly prevEvent: MatrixEvent,
|
||||||
public readonly lastShownEvent: MatrixEvent,
|
public readonly lastShownEvent: MatrixEvent,
|
||||||
|
protected readonly layout: Layout,
|
||||||
) {
|
) {
|
||||||
super(panel, event, prevEvent, lastShownEvent);
|
super(panel, event, prevEvent, lastShownEvent, layout);
|
||||||
this.events = [event];
|
this.events = [event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,6 +1319,7 @@ class MemberGrouper extends BaseGrouper {
|
||||||
events={this.events}
|
events={this.events}
|
||||||
onToggle={panel.onHeightChanged} // Update scroll state
|
onToggle={panel.onHeightChanged} // Update scroll state
|
||||||
startExpanded={highlightInMels}
|
startExpanded={highlightInMels}
|
||||||
|
layout={this.layout}
|
||||||
>
|
>
|
||||||
{ eventTiles }
|
{ eventTiles }
|
||||||
</MemberEventListSummary>,
|
</MemberEventListSummary>,
|
||||||
|
|
|
@ -22,6 +22,7 @@ import MemberAvatar from '../avatars/MemberAvatar';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import { useStateToggle } from "../../../hooks/useStateToggle";
|
import { useStateToggle } from "../../../hooks/useStateToggle";
|
||||||
import AccessibleButton from "./AccessibleButton";
|
import AccessibleButton from "./AccessibleButton";
|
||||||
|
import { Layout } from '../../../settings/Layout';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// An array of member events to summarise
|
// An array of member events to summarise
|
||||||
|
@ -38,6 +39,8 @@ interface IProps {
|
||||||
children: ReactNode[];
|
children: ReactNode[];
|
||||||
// Called when the event list expansion is toggled
|
// Called when the event list expansion is toggled
|
||||||
onToggle?(): void;
|
onToggle?(): void;
|
||||||
|
// The layout currently used
|
||||||
|
layout?: Layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EventListSummary: React.FC<IProps> = ({
|
const EventListSummary: React.FC<IProps> = ({
|
||||||
|
@ -48,6 +51,7 @@ const EventListSummary: React.FC<IProps> = ({
|
||||||
startExpanded,
|
startExpanded,
|
||||||
summaryMembers = [],
|
summaryMembers = [],
|
||||||
summaryText,
|
summaryText,
|
||||||
|
layout,
|
||||||
}) => {
|
}) => {
|
||||||
const [expanded, toggleExpanded] = useStateToggle(startExpanded);
|
const [expanded, toggleExpanded] = useStateToggle(startExpanded);
|
||||||
|
|
||||||
|
@ -63,7 +67,7 @@ const EventListSummary: React.FC<IProps> = ({
|
||||||
// If we are only given few events then just pass them through
|
// If we are only given few events then just pass them through
|
||||||
if (events.length < threshold) {
|
if (events.length < threshold) {
|
||||||
return (
|
return (
|
||||||
<li className="mx_EventListSummary" data-scroll-tokens={eventIds} data-expanded={true}>
|
<li className="mx_EventListSummary" data-scroll-tokens={eventIds} data-expanded={true} data-layout={layout}>
|
||||||
{ children }
|
{ children }
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -92,7 +96,7 @@ const EventListSummary: React.FC<IProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="mx_EventListSummary" data-scroll-tokens={eventIds} data-expanded={expanded + ""}>
|
<li className="mx_EventListSummary" data-scroll-tokens={eventIds} data-expanded={expanded + ""} data-layout={layout}>
|
||||||
<AccessibleButton className="mx_EventListSummary_toggle" onClick={toggleExpanded} aria-expanded={expanded}>
|
<AccessibleButton className="mx_EventListSummary_toggle" onClick={toggleExpanded} aria-expanded={expanded}>
|
||||||
{ expanded ? _t('collapse') : _t('expand') }
|
{ expanded ? _t('collapse') : _t('expand') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
@ -103,6 +107,7 @@ const EventListSummary: React.FC<IProps> = ({
|
||||||
|
|
||||||
EventListSummary.defaultProps = {
|
EventListSummary.defaultProps = {
|
||||||
startExpanded: false,
|
startExpanded: false,
|
||||||
|
layout: Layout.Group,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EventListSummary;
|
export default EventListSummary;
|
||||||
|
|
|
@ -25,12 +25,15 @@ import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
|
||||||
import { isValid3pidInvite } from "../../../RoomInvite";
|
import { isValid3pidInvite } from "../../../RoomInvite";
|
||||||
import EventListSummary from "./EventListSummary";
|
import EventListSummary from "./EventListSummary";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
import { Layout } from '../../../settings/Layout';
|
||||||
|
|
||||||
interface IProps extends Omit<ComponentProps<typeof EventListSummary>, "summaryText" | "summaryMembers"> {
|
interface IProps extends Omit<ComponentProps<typeof EventListSummary>, "summaryText" | "summaryMembers"> {
|
||||||
// The maximum number of names to show in either each summary e.g. 2 would result "A, B and 234 others left"
|
// The maximum number of names to show in either each summary e.g. 2 would result "A, B and 234 others left"
|
||||||
summaryLength?: number;
|
summaryLength?: number;
|
||||||
// The maximum number of avatars to display in the summary
|
// The maximum number of avatars to display in the summary
|
||||||
avatarsMaxLength?: number;
|
avatarsMaxLength?: number;
|
||||||
|
// The currently selected layout
|
||||||
|
layout: Layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IUserEvents {
|
interface IUserEvents {
|
||||||
|
@ -67,6 +70,7 @@ export default class MemberEventListSummary extends React.Component<IProps> {
|
||||||
summaryLength: 1,
|
summaryLength: 1,
|
||||||
threshold: 3,
|
threshold: 3,
|
||||||
avatarsMaxLength: 5,
|
avatarsMaxLength: 5,
|
||||||
|
layout: Layout.Group,
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
shouldComponentUpdate(nextProps) {
|
||||||
|
@ -453,6 +457,7 @@ export default class MemberEventListSummary extends React.Component<IProps> {
|
||||||
startExpanded={this.props.startExpanded}
|
startExpanded={this.props.startExpanded}
|
||||||
children={this.props.children}
|
children={this.props.children}
|
||||||
summaryMembers={[...latestUserAvatarMember.values()]}
|
summaryMembers={[...latestUserAvatarMember.values()]}
|
||||||
|
layout={this.props.layout}
|
||||||
summaryText={this.generateSummary(aggregate.names, orderedTransitionSequences)} />;
|
summaryText={this.generateSummary(aggregate.names, orderedTransitionSequences)} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue