Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Improve composer visiblity #8578

Merged
merged 20 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions res/css/structures/_RightPanel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ limitations under the License.
.mx_RoomView_MessageList {
padding: 14px 18px; // top and bottom is 4px smaller to balance with the padding set above
}

.mx_MessageComposer_wrapper {
margin-top: $spacing-8;
margin-bottom: $spacing-8;
}
}

.mx_RightPanel_header {
Expand Down Expand Up @@ -177,14 +182,14 @@ $pulse-color: $alert;

.mx_RightPanel_headerButton_unread {
&::before {
background-color: $room-icon-unread-color !important;
background-color: $room-icon-unread-color !important;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
}
}

.mx_RightPanel_headerButton_highlight,
.mx_RightPanel_headerButton:hover {
&::before {
background-color: $accent !important;
background-color: $accent !important;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
11 changes: 9 additions & 2 deletions res/css/structures/_RoomView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ limitations under the License.
flex-direction: column;
flex: 1;
position: relative;

}

.mx_MainSplit_timeline {
.mx_MessageComposer_wrapper {
margin: $spacing-16;
}
}

.mx_RoomView_auxPanel {
Expand Down Expand Up @@ -155,7 +162,7 @@ limitations under the License.
.mx_RoomView_messageListWrapper {
justify-content: flex-start;

>.mx_RoomView_MessageList > li > ol {
>.mx_RoomView_MessageList>li>ol {
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
list-style-type: none;
}
}
Expand Down Expand Up @@ -266,7 +273,7 @@ hr.mx_RoomView_myReadMarker {
}

.mx_RoomView_ongoingConfCallNotification a {
color: $accent-fg-color !important;
color: $accent-fg-color !important;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
}

.mx_MatrixChat_useCompactLayout {
Expand Down
97 changes: 69 additions & 28 deletions res/css/views/rooms/_MessageComposer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,30 @@ limitations under the License.
margin: auto;
border-top: 1px solid $primary-hairline-color;
position: relative;
padding-left: 42px;
padding-right: 16px;
display: flex;
justify-content: flex-end;
align-items: end;

.mx_MessageComposer_row {
flex: 1;
}

>[role=button] {
margin-bottom: 7px;
}

.mx_VoiceRecordComposerTile_delete {
margin-bottom: 9px;
}
t3chguy marked this conversation as resolved.
Show resolved Hide resolved

.mx_VoiceRecordComposerTile_stop,
.mx_MessageComposer_sendMessage {
margin-bottom: $spacing-4;
}

.mx_VoiceMessagePrimaryContainer {
margin-right: $spacing-8;
}
}

.mx_MessageComposer_replaced_wrapper {
Expand Down Expand Up @@ -56,7 +78,16 @@ limitations under the License.
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
border: 1px solid $quaternary-content;
border-radius: 8px;
padding: $spacing-12 $spacing-8;
margin-right: $spacing-16;

transition: border-color .2s;

&:focus-within {
border-color: $tertiary-content;
}
}

.mx_MessageComposer .mx_MessageComposer_avatar {
Expand All @@ -73,12 +104,10 @@ limitations under the License.
}

.mx_MessageComposer_e2eIcon.mx_E2EIcon {
position: absolute;
left: 20px;
margin-right: 0; // Counteract the E2EIcon class
margin-left: 3px; // Counteract the E2EIcon class
margin: 0 0 2px;
width: 12px;
height: 12px;
align-self: end;
}

.mx_MessageComposer_noperm_error {
Expand Down Expand Up @@ -121,16 +150,22 @@ limitations under the License.

// FIXME: rather unpleasant hack to get rid of <p/> margins.
// really we should be mixing in markdown-body from gfm.css instead
.mx_MessageComposer_editor > :first-child {
.mx_MessageComposer_editor> :first-child {
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
margin-top: 0 !important;
}
.mx_MessageComposer_editor > :last-child {

.mx_MessageComposer_editor> :last-child {
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
margin-bottom: 0 !important;
}

@keyframes visualbell {
from { background-color: $visual-bell-bg-color; }
to { background-color: $background; }
from {
background-color: $visual-bell-bg-color;
}

to {
background-color: $background;
}
}

.mx_MessageComposer_input_error {
Expand Down Expand Up @@ -166,15 +201,17 @@ limitations under the License.
color: $accent;
opacity: 1.0;
}

.mx_MessageComposer_input textarea::-webkit-input-placeholder {
color: $accent;
}

.mx_MessageComposer_button_highlight {
background: rgba($accent, 0.25);

// make the icon the accent color too
&::before {
background-color: $accent !important;
background-color: $accent !important;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -261,11 +298,29 @@ limitations under the License.
mask-image: url('$(res)/img/image-view/more.svg');
}

.mx_MessageComposer_sendMessageWrapper {
--sendMessageSize: 32px;
}

.mx_MessageComposer_sendMessageWrapper-enter,
.mx_MessageComposer_sendMessageWrapper-exit {
width: 0;
transform: scale(.6);
opacity: 0;
}

.mx_MessageComposer_sendMessageWrapper-enter-active {
width: var(--sendMessageSize);
transform: scale(1);
opacity: 1;
transition: all 200ms;
}

.mx_MessageComposer_sendMessage {
cursor: pointer;
position: relative;
width: 32px;
height: 32px;
width: var(--sendMessageSize);
height: var(--sendMessageSize);
border-radius: 100%;
background-color: $accent;

Expand Down Expand Up @@ -371,21 +426,7 @@ limitations under the License.
.mx_MessageComposer.mx_MessageComposer--compact {
margin-right: 0;

.mx_MessageComposer_wrapper {
padding: 0 0 0 25px;
}

&:not(.mx_MessageComposer_e2eStatus) {
.mx_MessageComposer_wrapper {
padding: 0;
}
}

.mx_MessageComposer_button:last-child {
margin-right: 0;
}

.mx_MessageComposer_e2eIcon {
left: 0;
}
}
6 changes: 0 additions & 6 deletions res/css/views/rooms/_SendMessageComposer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,8 @@ limitations under the License.
flex: 1;
display: flex;
flex-direction: column;
// min-height at this level so the mx_BasicMessageComposer_input
// still stays vertically centered when less than 55px.
// We also set this to ensure the voice message recording widget
// doesn't cause a jump.
min-height: 55px;

.mx_BasicMessageComposer_input {
padding: 3px 0;
// this will center the contenteditable
// in it's parent vertically
// while keeping the autocomplete at the top
Expand Down
75 changes: 43 additions & 32 deletions src/components/views/rooms/MessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { EventType } from 'matrix-js-sdk/src/@types/event';
import { Optional } from "matrix-events-sdk";
import { THREAD_RELATION_TYPE } from 'matrix-js-sdk/src/models/thread';
import { CSSTransition } from 'react-transition-group';

import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
Expand Down Expand Up @@ -57,6 +58,7 @@ let instanceCount = 0;
interface ISendButtonProps {
onClick: (ev: ButtonEvent) => void;
title?: string; // defaults to something generic
"aria-hidden"?: boolean;
}

function SendButton(props: ISendButtonProps) {
Expand All @@ -65,6 +67,7 @@ function SendButton(props: ISendButtonProps) {
className="mx_MessageComposer_sendMessage"
onClick={props.onClick}
title={props.title ?? _t('Send message')}
aria-hidden={props['aria-hidden'] ?? false}
/>
);
}
Expand Down Expand Up @@ -351,11 +354,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
};

public render() {
const controls = [
this.props.e2eStatus ?
<E2EIcon key="e2eIcon" status={this.props.e2eStatus} className="mx_MessageComposer_e2eIcon" /> :
null,
];
const controls = [];

let menuPosition: AboveLeftOf | undefined;
if (this.ref.current) {
Expand All @@ -379,11 +378,6 @@ export default class MessageComposer extends React.Component<IProps, IState> {
toggleStickerPickerOpen={this.toggleStickerPickerOpen}
/>,
);

controls.push(<VoiceRecordComposerTile
key="controls_voice_record"
ref={this.voiceRecordingButton}
room={this.props.room} />);
} else if (this.context.tombstone) {
const replacementRoomId = this.context.tombstone.getContent()['replacement_room'];

Expand Down Expand Up @@ -442,6 +436,12 @@ export default class MessageComposer extends React.Component<IProps, IState> {

const showSendButton = !this.state.isComposerEmpty || this.state.haveRecording;

if (this.props.e2eStatus) {
controls.push(
<E2EIcon key="e2eIcon" status={this.props.e2eStatus} className="mx_MessageComposer_e2eIcon" />,
);
}

const classes = classNames({
"mx_MessageComposer": true,
"mx_GroupLayout": true,
Expand All @@ -458,33 +458,44 @@ export default class MessageComposer extends React.Component<IProps, IState> {
permalinkCreator={this.props.permalinkCreator} />
<div className="mx_MessageComposer_row">
{ controls }
{ canSendMessages && <MessageComposerButtons
addEmoji={this.addEmoji}
haveRecording={this.state.haveRecording}
isMenuOpen={this.state.isMenuOpen}
isStickerPickerOpen={this.state.isStickerPickerOpen}
menuPosition={menuPosition}
relation={this.props.relation}
onRecordStartEndClick={() => {
this.voiceRecordingButton.current?.onRecordStartEndClick();
if (this.context.narrow) {
this.toggleButtonMenu();
}
}}
setStickerPickerOpen={this.setStickerPickerOpen}
showLocationButton={!window.electron}
showPollsButton={this.state.showPollsButton}
showStickersButton={this.state.showStickersButton}
toggleButtonMenu={this.toggleButtonMenu}
/> }
{ showSendButton && (
</div>
{ canSendMessages && <VoiceRecordComposerTile
key="controls_voice_record"
ref={this.voiceRecordingButton}
room={this.props.room} /> }
{ canSendMessages && <MessageComposerButtons
addEmoji={this.addEmoji}
haveRecording={this.state.haveRecording}
isMenuOpen={this.state.isMenuOpen}
isStickerPickerOpen={this.state.isStickerPickerOpen}
menuPosition={menuPosition}
relation={this.props.relation}
onRecordStartEndClick={() => {
this.voiceRecordingButton.current?.onRecordStartEndClick();
if (this.context.narrow) {
this.toggleButtonMenu();
}
}}
setStickerPickerOpen={this.setStickerPickerOpen}
showLocationButton={!window.electron}
showPollsButton={this.state.showPollsButton}
showStickersButton={this.state.showStickersButton}
toggleButtonMenu={this.toggleButtonMenu}
/> }
<CSSTransition
in={showSendButton}
classNames="mx_MessageComposer_sendMessageWrapper"
addEndListener={() => {}}
>
<div className='mx_MessageComposer_sendMessageWrapper'>
<SendButton
key="controls_send"
onClick={this.sendMessage}
title={this.state.haveRecording ? _t("Send voice message") : undefined}
aria-hidden={!showSendButton}
/>
) }
</div>
</div>
</CSSTransition>
</div>
</div>
);
Expand Down