feat: started adding rtl support to composition input

updated buttons, emoji panel, @mentions
pull/2796/head
William Grant 2 years ago
parent 80178a6e4c
commit 7542a42fa6

@ -6,7 +6,7 @@ export interface FlexProps {
container?: boolean;
dataTestId?: string;
/****** Container Props ********/
flexDirection?: 'row' | 'column';
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
justifyContent?:
| 'flex-start'
| 'flex-end'

@ -16,8 +16,10 @@ import {
import { hexColorToRGB } from '../../util/hexColorToRGB';
import { getPrimaryColor } from '../../state/selectors/primaryColor';
import { i18nEmojiData } from '../../util/emoji';
import { getWritingDirection } from '../../state/selectors/user';
export const StyledEmojiPanel = styled.div<{
dir: string;
isModal: boolean;
primaryColor: PrimaryColorStateType;
theme: ThemeStateType;
@ -68,7 +70,7 @@ export const StyledEmojiPanel = styled.div<{
content: '';
position: absolute;
top: calc(100% - 40px);
left: calc(100% - 79px);
left: ${props.dir === 'rtl' ? '75px' : 'calc(100% - 106px)'};
width: 22px;
height: 22px;
transform: rotate(45deg);
@ -102,6 +104,7 @@ export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props
const primaryColor = useSelector(getPrimaryColor);
const theme = useSelector(getTheme);
const isDarkMode = useSelector(isDarkTheme);
const writingDirection = useSelector(getWritingDirection);
let panelBackgroundRGB = hexColorToRGB(THEMES.CLASSIC_DARK.COLOR1);
let panelTextRGB = hexColorToRGB(THEMES.CLASSIC_DARK.COLOR6);
@ -134,6 +137,7 @@ export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props
theme={theme}
panelBackgroundRGB={panelBackgroundRGB}
panelTextRGB={panelTextRGB}
dir={writingDirection}
className={classNames(show && 'show')}
ref={ref}
>

@ -57,6 +57,7 @@ import {
getSelectedConversationKey,
} from '../../../state/selectors/selectedConversation';
import { SettingsKey } from '../../../data/settings-key';
import { isRtlBody } from '../../menu/Menu';
export interface ReplyingToMessageProps {
convoId: string;
@ -205,21 +206,22 @@ const getSelectionBasedOnMentions = (draft: string, index: number) => {
return Number.MAX_SAFE_INTEGER;
};
const StyledEmojiPanelContainer = styled.div`
const StyledEmojiPanelContainer = styled.div<{ dir: string }>`
${StyledEmojiPanel} {
position: absolute;
bottom: 68px;
right: 0px;
${props => (props.dir === 'rtl' ? 'left: 0px' : 'right: 0px;')}
}
`;
const StyledSendMessageInput = styled.div`
const StyledSendMessageInput = styled.div<{ dir: string }>`
cursor: text;
display: flex;
align-items: center;
flex-grow: 1;
min-height: var(--composition-container-height);
padding: var(--margins-xs) 0;
${props => (props.dir = 'rtl' && 'margin-right: var(--margins-sm);')}
z-index: 1;
background-color: inherit;
@ -409,8 +411,16 @@ class CompositionBoxInner extends React.Component<Props, State> {
const { showEmojiPanel } = this.state;
const { typingEnabled } = this.props;
const rtl = isRtlBody();
const writingDirection = rtl ? 'rtl' : 'ltr';
return (
<>
<Flex
container={true}
flexDirection={rtl ? 'row-reverse' : 'row'}
alignItems={'center'}
width={'100%'}
>
{typingEnabled && <AddStagedAttachmentButton onClick={this.onChooseAttachment} />}
<input
@ -426,13 +436,14 @@ class CompositionBoxInner extends React.Component<Props, State> {
<StyledSendMessageInput
role="main"
dir={writingDirection}
onClick={this.focusCompositionBox} // used to focus on the textarea when clicking in its container
ref={el => {
this.container = el;
}}
data-testid="message-input"
>
{this.renderTextArea()}
{this.renderTextArea(writingDirection)}
</StyledSendMessageInput>
{typingEnabled && (
@ -441,7 +452,7 @@ class CompositionBoxInner extends React.Component<Props, State> {
<SendMessageButton onClick={this.onSendMessage} />
{typingEnabled && showEmojiPanel && (
<StyledEmojiPanelContainer role="button">
<StyledEmojiPanelContainer role="button" dir={writingDirection}>
<SessionEmojiPanel
ref={this.emojiPanel}
show={showEmojiPanel}
@ -450,11 +461,11 @@ class CompositionBoxInner extends React.Component<Props, State> {
/>
</StyledEmojiPanelContainer>
)}
</>
</Flex>
);
}
private renderTextArea() {
private renderTextArea(dir: string) {
const { i18n } = window;
const { draft } = this.state;
@ -491,6 +502,7 @@ class CompositionBoxInner extends React.Component<Props, State> {
onKeyUp={this.onKeyUp}
placeholder={messagePlaceHolder}
spellCheck={true}
dir={dir}
inputRef={this.textarea}
disabled={!typingEnabled}
rows={1}
@ -505,7 +517,7 @@ class CompositionBoxInner extends React.Component<Props, State> {
markup="@ᅭ__id__ᅲ__display__ᅭ" // ᅭ = \uFFD2 is one of the forbidden char for a display name (check displayNameRegex)
trigger="@"
// this is only for the composition box visible content. The real stuff on the backend box is the @markup
displayTransform={(_id, display) => `@${display}`}
displayTransform={(_id, display) => (dir === 'rtl' ? `${display}@` : `@${display}`)}
data={this.fetchUsersForGroup}
renderSuggestion={renderUserMentionRow}
/>

@ -4,6 +4,7 @@ import { LocalizerType } from '../../types/Util';
import { StateType } from '../reducer';
import { UserStateType } from '../ducks/user';
import { isRtlBody } from '../../components/menu/Menu';
export const getUser = (state: StateType): UserStateType => state.user;
@ -13,3 +14,7 @@ export const getOurNumber = createSelector(
);
export const getIntl = createSelector(getUser, (): LocalizerType => window.i18n);
export const getWritingDirection = createSelector(getUser, (): string =>
isRtlBody() ? 'rtl' : 'ltr'
);

Loading…
Cancel
Save