feat: updated right panel in a conversation to use overlay logic in preparation for disappearing messages

added panel buttons specific to this UI
pull/2660/head
William Grant 2 years ago
parent 9310b43394
commit 8abd624c47

@ -3,7 +3,7 @@ body.rtl {
textarea,
.module-left-pane,
.module-conversation-list-item,
.group-settings-item,
.right-panel-item,
.contact-selection-list,
.group-member-list__selection,
.react-contexify__item {

@ -1,4 +1,4 @@
.group-settings {
.right-panel {
display: flex;
flex-direction: column;
height: 100vh;
@ -90,10 +90,10 @@
.module-media-grid-item {
height: calc(
22vw / 4
); //.group-settings is 22vw and we want three rows with some space so divide it by 4
); //.right-panel is 22vw and we want three rows with some space so divide it by 4
width: calc(
22vw / 4
); //.group-settings is 22vw and we want three rows with some space so divide it by 4
); //.right-panel is 22vw and we want three rows with some space so divide it by 4
margin: auto;
}
}

@ -35,7 +35,7 @@
@import 'session_theme';
@import 'session_left_pane';
@import 'session_group_panel';
@import 'session_right_panel';
@import 'session_slider';
@import 'session_conversation';

@ -0,0 +1,76 @@
import React, { ReactNode } from 'react';
import styled from 'styled-components';
const StyledRoundedPanelButtonGroup = styled.div`
overflow: hidden;
background: var(--background-secondary-color);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: var(--margins-lg);
margin: 0 var(--margins-lg);
width: -webkit-fill-available;
`;
const PanelButtonContainer = styled.div`
overflow: auto;
min-height: 40px;
max-height: 100%;
`;
export const PanelButtonGroup = ({ children }: { children: ReactNode }) => {
return (
<StyledRoundedPanelButtonGroup>
<PanelButtonContainer>{children}</PanelButtonContainer>
</StyledRoundedPanelButtonGroup>
);
};
const StyledPanelButton = styled.button<{
disableBg?: boolean;
}>`
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
flex-grow: 1;
font-family: var(--font-default);
padding: 0px var(--margins-sm);
height: '50px';
width: 100%;
transition: var(--default-duration);
background-color: ${props =>
!props.disableBg ? 'var(--conversation-tab-background-selected-color) !important' : null};
:not(:last-child) {
border-bottom: 1px solid var(--border-color);
}
`;
export type PanelButtonProps = {
disableBg?: boolean;
children: ReactNode;
onClick: (...args: any[]) => void;
dataTestId?: string;
};
export const PanelButton = (props: PanelButtonProps) => {
const { disableBg, children, onClick, dataTestId } = props;
return (
<StyledPanelButton
disableBg={disableBg}
onClick={onClick}
style={
!disableBg
? {
backgroundColor: 'var(--background-primary-color)',
}
: {}
}
data-testid={dataTestId}
>
{children}
</StyledPanelButton>
);
};

@ -0,0 +1,41 @@
import React from 'react';
import styled from 'styled-components';
import { SessionIcon, SessionIconType } from '../icon';
import { PanelButton, PanelButtonProps } from './PanelButton';
const StyledContent = styled.div`
display: flex;
align-items: center;
width: 100%;
`;
const StyledText = styled.span`
font-size: var(--font-size-md);
font-weight: 500;
margin-inline-start: var(--margins-lg);
margin-inline-end: var(--margins-lg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
/* TODO needs RTL support */
text-align: left;
`;
interface PanelIconButton extends Omit<PanelButtonProps, 'children'> {
iconType: SessionIconType;
text: string;
}
export const PanelIconButton = (props: PanelIconButton) => {
const { iconType, text, disableBg, onClick, dataTestId } = props;
return (
<PanelButton disableBg={disableBg} onClick={onClick} dataTestId={dataTestId}>
<StyledContent>
<SessionIcon iconType={iconType} iconSize="medium" />
<StyledText>{text}</StyledText>
</StyledContent>
</PanelButton>
);
};

@ -0,0 +1,5 @@
import { MenuButton } from './MenuButton';
import { PanelButton, PanelButtonGroup } from './PanelButton';
import { PanelIconButton } from './PanelIconButton';
export { MenuButton, PanelButton, PanelButtonGroup, PanelIconButton };

@ -42,7 +42,6 @@ import { SessionButtonColor } from '../basic/SessionButton';
import { MessageView } from '../MainViewController';
import { ConversationHeaderWithDetails } from './ConversationHeader';
import { MessageDetail } from './message/message-item/MessageDetail';
import { SessionRightPanelWithDetails } from './SessionRightPanel';
import {
makeImageThumbnailBuffer,
makeVideoScreenshot,
@ -58,6 +57,7 @@ import { markAllReadByConvoId } from '../../interactions/conversationInteraction
import { SessionSpinner } from '../basic/SessionSpinner';
import styled from 'styled-components';
import { RightPanel } from './right-panel/RightPanel';
// tslint:disable: jsx-curly-spacing
interface State {
@ -300,7 +300,7 @@ export class SessionConversation extends React.Component<Props, State> {
isRightPanelShowing && 'show'
)}
>
<SessionRightPanelWithDetails />
<RightPanel />
</div>
</>
)}

@ -0,0 +1,25 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { getRightOverlayMode } from '../../../state/selectors/section';
import { OverlayDisappearingMessages } from './overlay/OverlayDisappearingMessages';
import { OverlayRightPanelSettings } from './overlay/OverlayRightPanelSettings';
const ClosableOverlay = () => {
const rightOverlayMode = useSelector(getRightOverlayMode);
switch (rightOverlayMode) {
case 'disappearing-messages':
return <OverlayDisappearingMessages />;
case 'panel-settings':
default:
return <OverlayRightPanelSettings />;
}
};
export const RightPanel = () => {
return (
<div className="right-panel">
<ClosableOverlay />
</div>
);
};

@ -0,0 +1,24 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { resetRightOverlayMode } from '../../../../state/ducks/section';
export const OverlayDisappearingMessages = () => {
const dispatch = useDispatch();
function resetOverlay() {
dispatch(resetRightOverlayMode());
}
// const timerOptions = useSelector(getTimerOptions).timerOptions;
// const disappearingMessagesOptions = timerOptions.map(option => {
// return {
// content: option.name,
// onClick: () => {
// void setDisappearingMessagesByConvoId(id, option.value);
// },
// };
// });
return <div onClick={resetOverlay}>TODO</div>;
};

@ -1,33 +1,35 @@
import React, { useEffect, useState } from 'react';
import { SessionIconButton } from '../icon';
import _ from 'lodash';
// tslint:disable-next-line: no-submodule-imports
import useInterval from 'react-use/lib/useInterval';
import { useDispatch, useSelector } from 'react-redux';
import { Data } from '../../data/data';
import { Data } from '../../../../data/data';
import {
deleteAllMessagesByConvoIdWithConfirmation,
setDisappearingMessagesByConvoId,
showAddModeratorsByConvoId,
showInviteContactByConvoId,
showLeaveGroupByConvoId,
showRemoveModeratorsByConvoId,
showUpdateGroupMembersByConvoId,
showUpdateGroupNameByConvoId,
} from '../../interactions/conversationInteractions';
import { Constants } from '../../session';
import { closeRightPanel } from '../../state/ducks/conversations';
import { getSelectedConversation, isRightPanelShowing } from '../../state/selectors/conversations';
import { getTimerOptions } from '../../state/selectors/timerOptions';
import { AttachmentTypeWithPath } from '../../types/Attachment';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SessionDropdown } from '../basic/SessionDropdown';
import { SpacerLG } from '../basic/Text';
import { MediaItemType } from '../lightbox/LightboxGallery';
import { MediaGallery } from './media-gallery/MediaGallery';
import { getAbsoluteAttachmentPath } from '../../types/MessageAttachment';
} from '../../../../interactions/conversationInteractions';
import { Constants } from '../../../../session';
import {
getSelectedConversation,
isRightPanelShowing,
} from '../../../../state/selectors/conversations';
import { AttachmentTypeWithPath } from '../../../../types/Attachment';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../../../basic/SessionButton';
import { SpacerLG } from '../../../basic/Text';
import { MediaItemType } from '../../../lightbox/LightboxGallery';
import { MediaGallery } from '../../media-gallery/MediaGallery';
import { getAbsoluteAttachmentPath } from '../../../../types/MessageAttachment';
import styled from 'styled-components';
import { SessionIconButton } from '../../../icon';
import { closeRightPanel } from '../../../../state/ducks/conversations';
import { Avatar, AvatarSize } from '../../../avatar/Avatar';
import { setRightOverlayMode } from '../../../../state/ducks/section';
import { PanelButtonGroup, PanelIconButton } from '../../../buttons';
async function getMediaGalleryProps(
conversationId: string
@ -114,7 +116,7 @@ const HeaderItem = () => {
const showInviteContacts = isGroup && !isKickedFromGroup && !isBlocked && !left;
return (
<div className="group-settings-header">
<div className="right-panel-header">
<SessionIconButton
iconType="chevron"
iconSize="medium"
@ -188,10 +190,11 @@ const StyledName = styled.h4`
// tslint:disable: cyclomatic-complexity
// tslint:disable: max-func-body-length
export const SessionRightPanelWithDetails = () => {
export const OverlayRightPanelSettings = () => {
const [documents, setDocuments] = useState<Array<MediaItemType>>([]);
const [media, setMedia] = useState<Array<MediaItemType>>([]);
const dispatch = useDispatch();
const selectedConversation = useSelector(getSelectedConversation);
const isShowing = useSelector(isRightPanelShowing);
@ -255,17 +258,6 @@ export const SessionRightPanelWithDetails = () => {
? window.i18n('youLeftTheGroup')
: window.i18n('leaveGroup');
const timerOptions = useSelector(getTimerOptions).timerOptions;
const disappearingMessagesOptions = timerOptions.map(option => {
return {
content: option.name,
onClick: () => {
void setDisappearingMessagesByConvoId(id, option.value);
},
};
});
const showUpdateGroupNameButton =
isGroup && (!isPublic || (isPublic && weAreAdmin)) && !commonNoShow;
const showAddRemoveModeratorsButton = weAreAdmin && !commonNoShow && isPublic;
@ -278,8 +270,9 @@ export const SessionRightPanelWithDetails = () => {
: () => {
showLeaveGroupByConvoId(id);
};
return (
<div className="group-settings">
<>
<HeaderItem />
<StyledName data-testid="right-panel-group-name">{displayNameInProfile}</StyledName>
{showMemberCount && (
@ -293,7 +286,7 @@ export const SessionRightPanelWithDetails = () => {
)}
{showUpdateGroupNameButton && (
<StyledGroupSettingsItem
className="group-settings-item"
className="right-panel-item"
role="button"
onClick={async () => {
await showUpdateGroupNameByConvoId(id);
@ -305,7 +298,7 @@ export const SessionRightPanelWithDetails = () => {
{showAddRemoveModeratorsButton && (
<>
<StyledGroupSettingsItem
className="group-settings-item"
className="right-panel-item"
role="button"
onClick={() => {
showAddModeratorsByConvoId(id);
@ -314,7 +307,7 @@ export const SessionRightPanelWithDetails = () => {
{window.i18n('addModerators')}
</StyledGroupSettingsItem>
<StyledGroupSettingsItem
className="group-settings-item"
className="right-panel-item"
role="button"
onClick={() => {
showRemoveModeratorsByConvoId(id);
@ -327,7 +320,7 @@ export const SessionRightPanelWithDetails = () => {
{showUpdateGroupMembersButton && (
<StyledGroupSettingsItem
className="group-settings-item"
className="right-panel-item"
role="button"
onClick={async () => {
await showUpdateGroupMembersByConvoId(id);
@ -338,10 +331,17 @@ export const SessionRightPanelWithDetails = () => {
)}
{hasDisappearingMessages && (
<SessionDropdown
label={window.i18n('disappearingMessages')}
options={disappearingMessagesOptions}
/>
/* TODO Move ButtonGroup around all settings items */
<PanelButtonGroup>
<PanelIconButton
iconType={'timer50'}
text={window.i18n('disappearingMessages')}
disableBg={true}
onClick={() => {
dispatch(setRightOverlayMode('disappearing-messages'));
}}
/>
</PanelButtonGroup>
)}
<MediaGallery documents={documents} media={media} />
@ -357,6 +357,6 @@ export const SessionRightPanelWithDetails = () => {
/>
</StyledLeaveButton>
)}
</div>
</>
);
};

@ -9,7 +9,7 @@ import { getFocusedSection, getOverlayMode } from '../../state/selectors/section
import { SectionType } from '../../state/ducks/section';
import { SessionButton } from '../basic/SessionButton';
import { isSignWithRecoveryPhrase } from '../../util/storage';
import { MenuButton } from '../button/MenuButton';
import { MenuButton } from '../buttons';
const SectionTitle = styled.h1`
padding-top: var(--margins-xs);

@ -5,6 +5,8 @@ export const FOCUS_SETTINGS_SECTION = 'FOCUS_SETTINGS_SECTION';
export const IS_APP_FOCUSED = 'IS_APP_FOCUSED';
export const OVERLAY_MODE = 'OVERLAY_MODE';
export const RESET_OVERLAY_MODE = 'RESET_OVERLAY_MODE';
export const RIGHT_OVERLAY_MODE = 'RIGHT_OVERLAY_MODE';
export const RESET_RIGHT_OVERLAY_MODE = 'RESET_RIGHT_OVERLAY_MODE';
export enum SectionType {
Profile,
@ -38,6 +40,15 @@ type ResetOverlayModeActionType = {
type: 'RESET_OVERLAY_MODE';
};
type RightOverlayModeActionType = {
type: 'RIGHT_OVERLAY_MODE';
payload: RightOverlayMode;
};
type ResetRightOverlayModeActionType = {
type: 'RESET_RIGHT_OVERLAY_MODE';
};
export function showLeftPaneSection(section: SectionType): FocusSectionActionType {
return {
type: FOCUS_SECTION,
@ -54,6 +65,7 @@ export function setIsAppFocused(focused: boolean): IsAppFocusedActionType {
};
}
// TODO Should be renamed to LeftOverlayMode
export type OverlayMode =
| 'choose-action'
| 'message'
@ -74,6 +86,22 @@ export function resetOverlayMode(): ResetOverlayModeActionType {
};
}
// TODO possibly more overlays here
export type RightOverlayMode = 'disappearing-messages' | 'panel-settings';
export function setRightOverlayMode(overlayMode: RightOverlayMode): RightOverlayModeActionType {
return {
type: RIGHT_OVERLAY_MODE,
payload: overlayMode,
};
}
export function resetRightOverlayMode(): ResetRightOverlayModeActionType {
return {
type: RESET_RIGHT_OVERLAY_MODE,
};
}
export function showSettingsSection(
category: SessionSettingCategory
): FocusSettingsSectionActionType {
@ -88,6 +116,8 @@ export const actions = {
showSettingsSection,
setOverlayMode,
resetOverlayMode,
setRightOverlayMode,
resetRightOverlayMode,
};
export const initialSectionState: SectionStateType = {
@ -95,6 +125,7 @@ export const initialSectionState: SectionStateType = {
focusedSettingsSection: undefined,
isAppFocused: false,
overlayMode: undefined,
rightOverlayMode: undefined,
};
export type SectionStateType = {
@ -102,6 +133,7 @@ export type SectionStateType = {
focusedSettingsSection?: SessionSettingCategory;
isAppFocused: boolean;
overlayMode: OverlayMode | undefined;
rightOverlayMode: RightOverlayMode | undefined;
};
export const reducer = (
@ -154,6 +186,16 @@ export const reducer = (
...state,
overlayMode: undefined,
};
case RIGHT_OVERLAY_MODE:
return {
...state,
rightOverlayMode: payload,
};
case RESET_RIGHT_OVERLAY_MODE:
return {
...state,
rightOverlayMode: undefined,
};
default:
return state;
}

@ -1,7 +1,7 @@
import { createSelector } from '@reduxjs/toolkit';
import { StateType } from '../reducer';
import { OverlayMode, SectionStateType, SectionType } from '../ducks/section';
import { OverlayMode, RightOverlayMode, SectionStateType, SectionType } from '../ducks/section';
import { SessionSettingCategory } from '../../components/settings/SessionSettings';
export const getSection = (state: StateType): SectionStateType => state.section;
@ -21,7 +21,13 @@ export const getIsAppFocused = createSelector(
(state: SectionStateType): boolean => state.isAppFocused
);
// TODO This should probably be renamed to getLeftOverlayMode and the props should be updated.
export const getOverlayMode = createSelector(
getSection,
(state: SectionStateType): OverlayMode | undefined => state.overlayMode
);
export const getRightOverlayMode = createSelector(
getSection,
(state: SectionStateType): RightOverlayMode | undefined => state.rightOverlayMode
);

Loading…
Cancel
Save