diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index b8278f858..6a7218458 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -317,84 +317,6 @@ label { } } -.session-dropdown { - position: relative; - width: 100%; - - &__label { - cursor: pointer; - display: flex; - align-items: center; - justify-content: space-between; - height: 50px; - padding: 0px var(--margins-md); - font-size: var(--font-size-md); - - background-color: var(--right-panel-item-background-color); - color: var(--right-panel-item-text-color); - - &:hover { - background: var(--right-panel-item-background-hover-color); - } - } - - &__list-container { - z-index: 99; - display: block; - position: absolute; - top: 50px; - left: 0px; - right: 0px; - list-style: none; - padding: 0px; - margin: 0px; - max-height: 40vh; - overflow-y: auto; - } - - &__item { - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - height: 35px; - padding: 0 var(--margins-md); - background: var(--right-panel-item-background-color); - color: var(--right-panel-item-text-color); - - font-size: 0.8rem; - width: -webkit-fill-available; - transition: var(--default-duration); - - &:first-child { - border-top: 1px solid var(--border-color); - } - &:last-child { - border-top: 1px solid var(--border-color); - } - - .session-icon { - margin-inline-start: 6px; - } - .item-content { - margin-inline-start: 6px; - } - - &.active, - &:hover { - background: var(--right-panel-item-background-hover-color); - } - - &.danger { - color: var(--danger-color); - } - } - - &:hover { - background: var(--right-panel-item-background-hover-color); - } -} - .image-upload-section { display: flex; align-items: center; diff --git a/ts/components/MemberListItem.tsx b/ts/components/MemberListItem.tsx index edebfc25a..aad823b9f 100644 --- a/ts/components/MemberListItem.tsx +++ b/ts/components/MemberListItem.tsx @@ -95,7 +95,7 @@ type MemberListItemProps = { isAdmin?: boolean; // if true, we add a small crown on top of their avatar onSelect?: (pubkey: string) => void; onUnselect?: (pubkey: string) => void; - dataTestId?: string; + dataTestId?: React.SessionDataTestId; displayGroupStatus?: boolean; groupPk?: string; }; @@ -162,7 +162,10 @@ const GroupStatusText = ({ groupPk, pubkey }: { pubkey: PubkeyType; groupPk: Gro return null; } return ( - + {statusText} ); @@ -194,7 +197,7 @@ const ResendInviteButton = ({ }) => { return ( { return ( - {memberName} + {memberName} void; - dataTestId?: string; + dataTestId?: SessionDataTestId; + imageDataTestId?: SessionDataTestId; }; const Identicon = (props: Pick) => { @@ -110,8 +111,16 @@ const AvatarImage = ( }; const AvatarInner = (props: Props) => { - const { base64Data, size, pubkey, forcedAvatarPath, forcedName, dataTestId, onAvatarClick } = - props; + const { + base64Data, + size, + pubkey, + forcedAvatarPath, + forcedName, + dataTestId, + imageDataTestId, + onAvatarClick, + } = props; const [imageBroken, setImageBroken] = useState(false); const isSelectingMessages = useSelector(isMessageSelectionMode); @@ -163,7 +172,7 @@ const AvatarInner = (props: Props) => { imageBroken={imageBroken} name={forcedName || name} handleImageError={handleImageError} - dataTestId={dataTestId ? `img-${dataTestId}` : undefined} + dataTestId={imageDataTestId} /> ) : ( { diff --git a/ts/components/basic/SessionDropdown.tsx b/ts/components/basic/SessionDropdown.tsx deleted file mode 100644 index eb00a1f42..000000000 --- a/ts/components/basic/SessionDropdown.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useState } from 'react'; -import { SessionIcon, SessionIconType } from '../icon'; - -import { SessionDropdownItem, SessionDropDownItemType } from './SessionDropdownItem'; - -// THIS IS DROPDOWN ACCORDION STYLE OPTIONS SELECTOR ELEMENT, NOT A CONTEXTMENU - -type Props = { - label: string; - onClick?: any; - expanded?: boolean; - options: Array<{ - content: string; - id?: string; - icon?: SessionIconType | null; - type?: SessionDropDownItemType; - active?: boolean; - onClick?: any; - }>; - dataTestId?: string; -}; - -export const SessionDropdown = (props: Props) => { - const { label, options, dataTestId } = props; - const [expanded, setExpanded] = useState(!!props.expanded); - const chevronOrientation = expanded ? 180 : 0; - - return ( -
-
{ - setExpanded(!expanded); - }} - role="button" - > - {label} - -
- - {expanded && ( -
- {options.map((item: any) => { - return ( - { - setExpanded(false); - item.onClick(); - }} - /> - ); - })} -
- )} -
- ); -}; diff --git a/ts/components/basic/SessionDropdownItem.tsx b/ts/components/basic/SessionDropdownItem.tsx deleted file mode 100644 index c6588da41..000000000 --- a/ts/components/basic/SessionDropdownItem.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { SessionIcon, SessionIconType } from '../icon'; - -export enum SessionDropDownItemType { - Default = 'default', - Danger = 'danger', -} - -type Props = { - content: string; - type: SessionDropDownItemType; - icon: SessionIconType | null; - active: boolean; - onClick: any; - dataTestId?: string; -}; - -export const SessionDropdownItem = (props: Props) => { - const clickHandler = (e: any) => { - if (props.onClick) { - e.stopPropagation(); - props.onClick(); - } - }; - - const { content, type, icon, active, dataTestId } = props; - - return ( -
- {icon ? : ''} -
{content}
-
- ); -}; diff --git a/ts/components/basic/SessionIdEditable.tsx b/ts/components/basic/SessionIdEditable.tsx index bbac3fb8e..2fd4ba3ba 100644 --- a/ts/components/basic/SessionIdEditable.tsx +++ b/ts/components/basic/SessionIdEditable.tsx @@ -1,5 +1,5 @@ -import React, { ChangeEvent, KeyboardEvent, useRef } from 'react'; import classNames from 'classnames'; +import React, { ChangeEvent, KeyboardEvent, SessionDataTestId, useRef } from 'react'; import { useFocusMount } from '../../hooks/useFocusMount'; type Props = { @@ -11,7 +11,7 @@ type Props = { onPressEnter?: any; maxLength?: number; isGroup?: boolean; - dataTestId?: string; + dataTestId?: SessionDataTestId; }; export const SessionIdEditable = (props: Props) => { diff --git a/ts/components/basic/SessionInput.tsx b/ts/components/basic/SessionInput.tsx index 0c33a22b0..210715325 100644 --- a/ts/components/basic/SessionInput.tsx +++ b/ts/components/basic/SessionInput.tsx @@ -1,9 +1,9 @@ -import React, { useState } from 'react'; +import React, { SessionDataTestId, useState } from 'react'; import classNames from 'classnames'; -import { SessionIconButton } from '../icon'; import { Noop } from '../../types/Util'; import { useHTMLDirection } from '../../util/i18n'; +import { SessionIconButton } from '../icon'; type Props = { label?: string; @@ -17,7 +17,7 @@ type Props = { onEnterPressed?: any; autoFocus?: boolean; ref?: any; - inputDataTestId?: string; + inputDataTestId?: SessionDataTestId; }; const LabelItem = (props: { inputValue: string; label?: string }) => { diff --git a/ts/components/basic/SessionRadio.tsx b/ts/components/basic/SessionRadio.tsx index cef7908ed..14b8fc517 100644 --- a/ts/components/basic/SessionRadio.tsx +++ b/ts/components/basic/SessionRadio.tsx @@ -1,4 +1,4 @@ -import React, { ChangeEvent } from 'react'; +import React, { ChangeEvent, SessionDataTestId } from 'react'; import styled, { CSSProperties } from 'styled-components'; import { Flex } from './Flex'; @@ -56,6 +56,8 @@ type SessionRadioProps = { disabled?: boolean; radioPosition?: 'left' | 'right'; style?: CSSProperties; + labelDatatestId?: SessionDataTestId; + inputDatatestId?: SessionDataTestId; }; export const SessionRadio = (props: SessionRadioProps) => { @@ -69,6 +71,8 @@ export const SessionRadio = (props: SessionRadioProps) => { disabled = false, radioPosition = 'left', style, + labelDatatestId, + inputDatatestId, } = props; const clickHandler = (e: ChangeEvent) => { @@ -99,7 +103,7 @@ export const SessionRadio = (props: SessionRadioProps) => { filledSize={filledSize * 2} outlineOffset={outlineOffset} disabled={disabled} - data-testid={`input-${value.replaceAll(' ', '-')}`} // data-testid cannot have spaces + data-testid={inputDatatestId} /> { beforeMargins={beforeMargins} aria-label={label} disabled={disabled} - data-testid={`label-${value}`} + data-testid={labelDatatestId} > {label} diff --git a/ts/components/basic/SessionRadioGroup.tsx b/ts/components/basic/SessionRadioGroup.tsx index b0867e3d7..6a07cabf7 100644 --- a/ts/components/basic/SessionRadioGroup.tsx +++ b/ts/components/basic/SessionRadioGroup.tsx @@ -1,10 +1,15 @@ -import React, { useState } from 'react'; +import React, { SessionDataTestId, useState } from 'react'; import useMount from 'react-use/lib/useMount'; import styled, { CSSProperties } from 'styled-components'; import { SessionRadio } from './SessionRadio'; -export type SessionRadioItems = Array<{ value: string; label: string }>; +export type SessionRadioItems = Array<{ + value: string; + label: string; + inputDatatestId: SessionDataTestId; + labelDatatestId: SessionDataTestId; +}>; interface Props { initialItem: string; @@ -50,6 +55,8 @@ export const SessionRadioGroup = (props: Props) => { label={item.label} active={itemIsActive} value={item.value} + inputDatatestId={item.inputDatatestId} + labelDatatestId={item.labelDatatestId} inputName={group} onClick={(value: string) => { setActiveItem(value); diff --git a/ts/components/basic/SessionToggle.tsx b/ts/components/basic/SessionToggle.tsx index 3f9ec0cb4..72fe8708a 100644 --- a/ts/components/basic/SessionToggle.tsx +++ b/ts/components/basic/SessionToggle.tsx @@ -48,7 +48,7 @@ type Props = { active: boolean; onClick: () => void; confirmationDialogParams?: any | undefined; - dataTestId?: string; + dataTestId?: React.SessionDataTestId; }; export const SessionToggle = (props: Props) => { diff --git a/ts/components/basic/Spinner.tsx b/ts/components/basic/Spinner.tsx index 02e7b79b1..1b0d5f6d7 100644 --- a/ts/components/basic/Spinner.tsx +++ b/ts/components/basic/Spinner.tsx @@ -1,10 +1,10 @@ -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import styled from 'styled-components'; type Props = { size: 'small' | 'normal'; direction?: string; - dataTestId?: string; + dataTestId?: SessionDataTestId; }; // Module: Spinner diff --git a/ts/components/buttons/PanelButton.tsx b/ts/components/buttons/PanelButton.tsx index 868bf9bbd..827c0838d 100644 --- a/ts/components/buttons/PanelButton.tsx +++ b/ts/components/buttons/PanelButton.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode } from 'react'; +import React, { ReactNode, SessionDataTestId } from 'react'; import styled, { CSSProperties } from 'styled-components'; import { Flex } from '../basic/Flex'; @@ -87,7 +87,7 @@ export type PanelButtonProps = { disabled?: boolean; children: ReactNode; onClick: (...args: Array) => void; - dataTestId: string; + dataTestId: SessionDataTestId; style?: CSSProperties; }; diff --git a/ts/components/conversation/ContactName.tsx b/ts/components/conversation/ContactName.tsx index 718467b78..3af771ef1 100644 --- a/ts/components/conversation/ContactName.tsx +++ b/ts/components/conversation/ContactName.tsx @@ -1,18 +1,21 @@ -import React from 'react'; import classNames from 'classnames'; +import React from 'react'; import { CSSProperties } from 'styled-components'; -import { Emojify } from './Emojify'; import { - useNicknameOrProfileNameOrShortenedPubkey, useIsPrivate, + useNicknameOrProfileNameOrShortenedPubkey, } from '../../hooks/useParamSelector'; +import { Emojify } from './Emojify'; type Props = { pubkey: string; name?: string | null; profileName?: string | null; - module?: string; + module?: + | 'module-conversation__user' + | 'module-message-search-result__header__name' + | 'module-message__author'; boldProfileName?: boolean; compact?: boolean; shouldShowPubkey: boolean; @@ -38,7 +41,7 @@ export const ContactName = (props: Props) => { {shouldShowProfile ? ( diff --git a/ts/components/conversation/SubtleNotification.tsx b/ts/components/conversation/SubtleNotification.tsx index ac0a34e35..f0202bb8b 100644 --- a/ts/components/conversation/SubtleNotification.tsx +++ b/ts/components/conversation/SubtleNotification.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; import { @@ -42,7 +42,7 @@ const TextInner = styled.div` max-width: 390px; `; -function TextNotification({ html, dataTestId }: { html: string; dataTestId: string }) { +function TextNotification({ html, dataTestId }: { html: string; dataTestId: SessionDataTestId }) { return ( diff --git a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx index 9e4a23d63..e67ad675a 100644 --- a/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx +++ b/ts/components/conversation/message/message-content/MessageContentWithStatus.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import React, { useCallback, useState } from 'react'; +import React, { SessionDataTestId, useCallback, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; import { replyToMessage } from '../../../../interactions/conversationInteractions'; @@ -30,7 +30,7 @@ type Props = { messageId: string; ctxMenuID: string; isDetailView?: boolean; - dataTestId: string; + dataTestId: SessionDataTestId; enableReactions: boolean; }; diff --git a/ts/components/conversation/message/message-content/MessageStatus.tsx b/ts/components/conversation/message/message-content/MessageStatus.tsx index d28a41ef7..0566ddfcc 100644 --- a/ts/components/conversation/message/message-content/MessageStatus.tsx +++ b/ts/components/conversation/message/message-content/MessageStatus.tsx @@ -1,5 +1,5 @@ import { ipcRenderer } from 'electron'; -import React, { useCallback } from 'react'; +import React, { SessionDataTestId, useCallback } from 'react'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; import { useMessageExpirationPropsById } from '../../../../hooks/useParamSelector'; @@ -14,7 +14,7 @@ import { ExpireTimer } from '../../ExpireTimer'; type Props = { isDetailView: boolean; messageId: string; - dataTestId?: string | undefined; + dataTestId: SessionDataTestId; }; /** diff --git a/ts/components/conversation/message/message-item/ReadableMessage.tsx b/ts/components/conversation/message/message-item/ReadableMessage.tsx index e8c05660b..938f62abe 100644 --- a/ts/components/conversation/message/message-item/ReadableMessage.tsx +++ b/ts/components/conversation/message/message-item/ReadableMessage.tsx @@ -2,6 +2,7 @@ import { debounce, noop } from 'lodash'; import React, { AriaRole, MouseEventHandler, + SessionDataTestId, useCallback, useContext, useLayoutEffect, @@ -39,7 +40,7 @@ export type ReadableMessageProps = { onClick?: MouseEventHandler; onDoubleClickCapture?: MouseEventHandler; role?: AriaRole; - dataTestId: string; + dataTestId: SessionDataTestId; onContextMenu?: (e: React.MouseEvent) => void; isControlMessage?: boolean; }; diff --git a/ts/components/conversation/right-panel/overlay/disappearing-messages/DisappearingModes.tsx b/ts/components/conversation/right-panel/overlay/disappearing-messages/DisappearingModes.tsx index 3683119cc..7ecfbc994 100644 --- a/ts/components/conversation/right-panel/overlay/disappearing-messages/DisappearingModes.tsx +++ b/ts/components/conversation/right-panel/overlay/disappearing-messages/DisappearingModes.tsx @@ -1,20 +1,19 @@ -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import { DisappearingMessageConversationModeType } from '../../../../../session/disappearing_messages/types'; import { PanelButtonGroup, PanelLabel } from '../../../../buttons/PanelButton'; import { PanelRadioButton } from '../../../../buttons/PanelRadioButton'; -function loadDataTestId(mode: DisappearingMessageConversationModeType) { - const dataTestId = 'disappear-%-option'; +function toDataTestId(mode: DisappearingMessageConversationModeType): SessionDataTestId { switch (mode) { case 'legacy': - return dataTestId.replace('%', 'legacy'); + return 'disappear-legacy-option'; case 'deleteAfterRead': - return dataTestId.replace('%', 'after-read'); + return 'disappear-after-read-option'; case 'deleteAfterSend': - return dataTestId.replace('%', 'after-send'); + return 'disappear-after-send-option'; case 'off': default: - return dataTestId.replace('%', 'off'); + return 'disappear-off-option'; } } @@ -67,7 +66,7 @@ export const DisappearingModes = (props: DisappearingModesProps) => { setSelected(mode); }} disabled={options[mode]} - dataTestId={loadDataTestId(mode)} + dataTestId={toDataTestId(mode)} /> ); })} diff --git a/ts/components/conversation/right-panel/overlay/disappearing-messages/TimeOptions.tsx b/ts/components/conversation/right-panel/overlay/disappearing-messages/TimeOptions.tsx index cb8273bbb..ed2c0c919 100644 --- a/ts/components/conversation/right-panel/overlay/disappearing-messages/TimeOptions.tsx +++ b/ts/components/conversation/right-panel/overlay/disappearing-messages/TimeOptions.tsx @@ -34,7 +34,7 @@ export const TimeOptions = (props: TimerOptionsProps) => { setSelected(option.value); }} disabled={disabled} - dataTestId={`time-option-${option.name.replace(' ', '-')}`} // we want "time-option-1-minute", etc as accessibility id + dataTestId={`time-option-${option.value}`} // we want "time-option-3600", etc as accessibility id /> ); })} diff --git a/ts/components/dialog/DeleteAccountModal.tsx b/ts/components/dialog/DeleteAccountModal.tsx index 9b886b97e..5567afb5b 100644 --- a/ts/components/dialog/DeleteAccountModal.tsx +++ b/ts/components/dialog/DeleteAccountModal.tsx @@ -154,8 +154,8 @@ async function deleteEverythingAndNetworkData() { } } -const DEVICE_ONLY = 'device_only'; -const DEVICE_AND_NETWORK = 'device_and_network'; +const DEVICE_ONLY = 'device_only' as const; +const DEVICE_AND_NETWORK = 'device_and_network' as const; type DeleteModes = typeof DEVICE_ONLY | typeof DEVICE_AND_NETWORK; const DescriptionBeforeAskingConfirmation = (props: { @@ -163,6 +163,22 @@ const DescriptionBeforeAskingConfirmation = (props: { setDeleteMode: (deleteMode: DeleteModes) => void; }) => { const { deleteMode, setDeleteMode } = props; + + const items = [ + { + label: window.i18n('deviceOnly'), + value: DEVICE_ONLY, + }, + { + label: window.i18n('entireAccount'), + value: DEVICE_AND_NETWORK, + }, + ].map(m => ({ + ...m, + inputDatatestId: `input-${m.value}` as const, + labelDatatestId: `label-${m.value}` as const, + })); + return ( <> {window.i18n('deleteAccountWarning')} @@ -179,10 +195,7 @@ const DescriptionBeforeAskingConfirmation = (props: { setDeleteMode(value); } }} - items={[ - { label: window.i18n('deviceOnly'), value: DEVICE_ONLY }, - { label: window.i18n('entireAccount'), value: 'device_and_network' }, - ]} + items={items} /> ); diff --git a/ts/components/dialog/OnionStatusPathDialog.tsx b/ts/components/dialog/OnionStatusPathDialog.tsx index 3d5917922..2ed74662d 100644 --- a/ts/components/dialog/OnionStatusPathDialog.tsx +++ b/ts/components/dialog/OnionStatusPathDialog.tsx @@ -1,5 +1,5 @@ import { shell } from 'electron'; -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import useHover from 'react-use/lib/useHover'; @@ -25,7 +25,7 @@ export type StatusLightType = { glowStartDelay: number; glowDuration: number; color?: string; - dataTestId?: string; + dataTestId?: SessionDataTestId; }; const StyledCountry = styled.div` @@ -143,7 +143,7 @@ const OnionPathModalInner = () => { export type OnionNodeStatusLightType = { glowStartDelay: number; glowDuration: number; - dataTestId?: string; + dataTestId?: SessionDataTestId; }; /** diff --git a/ts/components/icon/SessionIcon.tsx b/ts/components/icon/SessionIcon.tsx index e190abf42..e5dab292f 100644 --- a/ts/components/icon/SessionIcon.tsx +++ b/ts/components/icon/SessionIcon.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import styled, { css, keyframes } from 'styled-components'; import { icons, SessionIconSize, SessionIconType } from '.'; @@ -15,7 +15,7 @@ export type SessionIconProps = { glowStartDelay?: number; noScale?: boolean; backgroundColor?: string; - dataTestId?: string; + dataTestId?: SessionDataTestId; }; const getIconDimensionFromIconSize = (iconSize: SessionIconSize | number) => { @@ -146,7 +146,7 @@ const SessionSvg = (props: { borderRadius?: string; backgroundColor?: string; iconPadding?: string; - dataTestId?: string; + dataTestId?: SessionDataTestId; }) => { const colorSvg = props.iconColor ? props.iconColor : '--button-icon-stroke-color'; const pathArray = props.path instanceof Array ? props.path : [props.path]; diff --git a/ts/components/icon/SessionIconButton.tsx b/ts/components/icon/SessionIconButton.tsx index b572f6619..ef4b6981d 100644 --- a/ts/components/icon/SessionIconButton.tsx +++ b/ts/components/icon/SessionIconButton.tsx @@ -1,6 +1,6 @@ -import React, { KeyboardEvent } from 'react'; import classNames from 'classnames'; import _ from 'lodash'; +import React, { KeyboardEvent, SessionDataTestId } from 'react'; import styled from 'styled-components'; import { SessionIcon, SessionIconProps } from '.'; @@ -12,8 +12,8 @@ interface SProps extends SessionIconProps { isSelected?: boolean; isHidden?: boolean; margin?: string; - dataTestId?: string; - dataTestIdIcon?: string; + dataTestId?: SessionDataTestId; + dataTestIdIcon?: SessionDataTestId; id?: string; style?: object; tabIndex?: number; diff --git a/ts/components/leftpane/ActionsPanel.tsx b/ts/components/leftpane/ActionsPanel.tsx index fdc0da8d5..19375cd47 100644 --- a/ts/components/leftpane/ActionsPanel.tsx +++ b/ts/components/leftpane/ActionsPanel.tsx @@ -91,6 +91,7 @@ const Section = (props: { type: SectionType }) => { onAvatarClick={handleClick} pubkey={ourNumber} dataTestId="leftpane-primary-avatar" + imageDataTestId={`img-leftpane-primary-avatar`} /> ); } diff --git a/ts/components/leftpane/LeftPaneSettingSection.tsx b/ts/components/leftpane/LeftPaneSettingSection.tsx index b2dd84315..c1a721fa2 100644 --- a/ts/components/leftpane/LeftPaneSettingSection.tsx +++ b/ts/components/leftpane/LeftPaneSettingSection.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { SessionDataTestId } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; @@ -45,73 +45,75 @@ const StyledSettingsListItem = styled.div<{ active: boolean }>` const getCategories = () => { return [ { - id: SessionSettingCategory.Privacy, + id: 'privacy' as const, title: window.i18n('privacySettingsTitle'), }, { - id: SessionSettingCategory.Notifications, + id: 'notifications' as const, title: window.i18n('notificationsSettingsTitle'), }, { - id: SessionSettingCategory.Conversations, + id: 'conversations' as const, title: window.i18n('conversationsSettingsTitle'), }, { - id: SessionSettingCategory.MessageRequests, + id: 'messageRequests' as const, title: window.i18n('openMessageRequestInbox'), }, { - id: SessionSettingCategory.Appearance, + id: 'appearance' as const, title: window.i18n('appearanceSettingsTitle'), }, { - id: SessionSettingCategory.Permissions, + id: 'permissions' as const, title: window.i18n('permissionsSettingsTitle'), }, { - id: SessionSettingCategory.Help, + id: 'help' as const, title: window.i18n('helpSettingsTitle'), }, { - id: SessionSettingCategory.RecoveryPhrase, + id: 'recoveryPhrase' as const, title: window.i18n('recoveryPhrase'), }, { - id: SessionSettingCategory.ClearData, + id: 'ClearData' as const, title: window.i18n('clearDataSettingsTitle'), }, - ]; + ].map(m => ({ ...m, dataTestId: `${m.id}-settings-menu-item` as const })); }; const LeftPaneSettingsCategoryRow = (props: { - item: { id: SessionSettingCategory; title: string }; + item: { + id: SessionSettingCategory; + title: string; + dataTestId: SessionDataTestId; + }; }) => { const { item } = props; const { id, title } = item; const dispatch = useDispatch(); const focusedSettingsSection = useSelector(getFocusedSettingsSection); - const dataTestId = `${title.toLowerCase().replace(' ', '-')}-settings-menu-item`; - - const isClearData = id === SessionSettingCategory.ClearData; + const isClearData = id === 'ClearData'; return ( { switch (id) { - case SessionSettingCategory.MessageRequests: + case 'messageRequests': dispatch(showLeftPaneSection(SectionType.Message)); dispatch(setLeftOverlayMode('message-requests')); dispatch(resetConversationExternal()); break; - case SessionSettingCategory.RecoveryPhrase: + case 'recoveryPhrase': dispatch(recoveryPhraseModal({})); break; - case SessionSettingCategory.ClearData: + case 'ClearData': dispatch(updateDeleteAccountModal({})); break; default: diff --git a/ts/components/settings/SessionNotificationGroupSettings.tsx b/ts/components/settings/SessionNotificationGroupSettings.tsx index 1fd73d430..54c144815 100644 --- a/ts/components/settings/SessionNotificationGroupSettings.tsx +++ b/ts/components/settings/SessionNotificationGroupSettings.tsx @@ -7,16 +7,11 @@ import { SettingsKey } from '../../data/settings-key'; import { isAudioNotificationSupported } from '../../types/Settings'; import { Notifications } from '../../util/notifications'; import { SessionButton } from '../basic/SessionButton'; -import { SessionRadioGroup } from '../basic/SessionRadioGroup'; +import { SessionRadioGroup, SessionRadioItems } from '../basic/SessionRadioGroup'; import { SpacerLG } from '../basic/Text'; import { SessionSettingsItemWrapper, SessionToggleWithDescription } from './SessionSettingListItem'; -enum NOTIFICATION { - MESSAGE = 'message', - NAME = 'name', - COUNT = 'count', - OFF = 'off', -} +const NotificationType = { message: 'message', name: 'name', count: 'count', off: 'off' } as const; const StyledButtonContainer = styled.div` display: flex; @@ -33,28 +28,26 @@ export const SessionNotificationGroupSettings = (props: { hasPassword: boolean | } const initialNotificationEnabled = - window.getSettingValue(SettingsKey.settingsNotification) || NOTIFICATION.MESSAGE; + window.getSettingValue(SettingsKey.settingsNotification) || NotificationType.message; const initialAudioNotificationEnabled = window.getSettingValue(SettingsKey.settingsAudioNotification) || false; const notificationsAreEnabled = - initialNotificationEnabled && initialNotificationEnabled !== NOTIFICATION.OFF; + initialNotificationEnabled && initialNotificationEnabled !== NotificationType.off; - const items = [ - { - label: window.i18n('nameAndMessage'), - value: NOTIFICATION.MESSAGE, - }, - { - label: window.i18n('nameOnly'), - value: NOTIFICATION.NAME, - }, - { - label: window.i18n('noNameOrMessage'), - value: NOTIFICATION.COUNT, - }, - ]; + const options = [ + { label: window.i18n('nameAndMessage'), value: NotificationType.message }, + { label: window.i18n('nameOnly'), value: NotificationType.name }, + { label: window.i18n('noNameOrMessage'), value: NotificationType.count }, + ] as const; + + const items: SessionRadioItems = options.map(m => ({ + label: m.label, + value: m.value, + inputDatatestId: `input-${m.value}`, + labelDatatestId: `label-${m.value}`, + })); const onClickPreview = () => { if (!notificationsAreEnabled) { @@ -79,7 +72,7 @@ export const SessionNotificationGroupSettings = (props: { hasPassword: boolean | onClickToggle={async () => { await window.setSettingValue( SettingsKey.settingsNotification, - notificationsAreEnabled ? NOTIFICATION.OFF : NOTIFICATION.MESSAGE + notificationsAreEnabled ? 'off' : 'message' ); forceUpdate(); }} diff --git a/ts/components/settings/SessionSettingListItem.tsx b/ts/components/settings/SessionSettingListItem.tsx index 20311ff22..56e87e9fa 100644 --- a/ts/components/settings/SessionSettingListItem.tsx +++ b/ts/components/settings/SessionSettingListItem.tsx @@ -1,6 +1,7 @@ import React from 'react'; import styled from 'styled-components'; +import { Noop } from '../../types/Util'; import { SessionButton, SessionButtonColor, @@ -10,7 +11,6 @@ import { import { SessionToggle } from '../basic/SessionToggle'; import { SessionConfirmDialogProps } from '../dialog/SessionConfirm'; import { SessionIconButton } from '../icon'; -import { Noop } from '../../types/Util'; type ButtonSettingsProps = { title?: string; @@ -19,7 +19,7 @@ type ButtonSettingsProps = { buttonType?: SessionButtonType; buttonShape?: SessionButtonShape; buttonText: string; - dataTestId?: string; + dataTestId?: React.SessionDataTestId; onClick: () => void; }; @@ -130,7 +130,7 @@ export const SessionToggleWithDescription = (props: { onClickToggle: () => void; confirmationDialogParams?: SessionConfirmDialogProps; childrenDescription?: React.ReactNode; // if set, those elements will be appended next to description field (only used for typing message settings as of now) - dataTestId?: string; + dataTestId?: React.SessionDataTestId; }) => { const { title, diff --git a/ts/components/settings/SessionSettings.tsx b/ts/components/settings/SessionSettings.tsx index b9226112f..dbf3a467c 100644 --- a/ts/components/settings/SessionSettings.tsx +++ b/ts/components/settings/SessionSettings.tsx @@ -1,6 +1,6 @@ +import autoBind from 'auto-bind'; import { shell } from 'electron'; import React from 'react'; -import autoBind from 'auto-bind'; import styled from 'styled-components'; import { SettingsHeader } from './SessionSettingsHeader'; @@ -9,15 +9,15 @@ import { SessionIconButton } from '../icon'; import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings'; -import { CategoryConversations } from './section/CategoryConversations'; -import { SettingsCategoryPrivacy } from './section/CategoryPrivacy'; -import { SettingsCategoryAppearance } from './section/CategoryAppearance'; import { Data } from '../../data/data'; -import { SettingsCategoryPermissions } from './section/CategoryPermissions'; -import { SettingsCategoryHelp } from './section/CategoryHelp'; import { sessionPassword } from '../../state/ducks/modalDialog'; -import { PasswordAction } from '../dialog/SessionPasswordDialog'; import { SectionType, showLeftPaneSection } from '../../state/ducks/section'; +import { PasswordAction } from '../dialog/SessionPasswordDialog'; +import { SettingsCategoryAppearance } from './section/CategoryAppearance'; +import { CategoryConversations } from './section/CategoryConversations'; +import { SettingsCategoryHelp } from './section/CategoryHelp'; +import { SettingsCategoryPermissions } from './section/CategoryPermissions'; +import { SettingsCategoryPrivacy } from './section/CategoryPrivacy'; export function displayPasswordModal( passwordAction: PasswordAction, @@ -41,17 +41,16 @@ export function getCallMediaPermissionsSettings() { return window.getSettingValue('call-media-permissions'); } -export enum SessionSettingCategory { - Privacy = 'privacy', - Notifications = 'notifications', - Conversations = 'conversations', - MessageRequests = 'messageRequests', - Appearance = 'appearance', - Permissions = 'permissions', - Help = 'help', - RecoveryPhrase = 'recoveryPhrase', - ClearData = 'ClearData', -} +export type SessionSettingCategory = + | 'privacy' + | 'notifications' + | 'conversations' + | 'messageRequests' + | 'appearance' + | 'permissions' + | 'help' + | 'recoveryPhrase' + | 'ClearData'; export interface SettingsViewProps { category: SessionSettingCategory; @@ -120,25 +119,25 @@ const SettingInCategory = (props: { } switch (category) { // special case for blocked user - case SessionSettingCategory.Conversations: + case 'conversations': return ; - case SessionSettingCategory.Appearance: + case 'appearance': return ; - case SessionSettingCategory.Notifications: + case 'notifications': return ; - case SessionSettingCategory.Privacy: + case 'privacy': return ( ); - case SessionSettingCategory.Help: + case 'help': return ; - case SessionSettingCategory.Permissions: + case 'permissions': return ; // these three down there have no options, they are just a button - case SessionSettingCategory.ClearData: - case SessionSettingCategory.MessageRequests: - case SessionSettingCategory.RecoveryPhrase: + case 'ClearData': + case 'messageRequests': + case 'recoveryPhrase': default: return null; } diff --git a/ts/components/settings/SessionSettingsHeader.tsx b/ts/components/settings/SessionSettingsHeader.tsx index 2f6f35772..91b0cefe5 100644 --- a/ts/components/settings/SessionSettingsHeader.tsx +++ b/ts/components/settings/SessionSettingsHeader.tsx @@ -1,7 +1,7 @@ import React from 'react'; import styled from 'styled-components'; import { assertUnreachable } from '../../types/sqlSharedTypes'; -import { SessionSettingCategory, SettingsViewProps } from './SessionSettings'; +import { SettingsViewProps } from './SessionSettings'; type Props = Pick; @@ -26,27 +26,27 @@ export const SettingsHeader = (props: Props) => { let categoryTitle: string | null = null; switch (category) { - case SessionSettingCategory.Appearance: + case 'appearance': categoryTitle = window.i18n('appearanceSettingsTitle'); break; - case SessionSettingCategory.Conversations: + case 'conversations': categoryTitle = window.i18n('conversationsSettingsTitle'); break; - case SessionSettingCategory.Notifications: + case 'notifications': categoryTitle = window.i18n('notificationsSettingsTitle'); break; - case SessionSettingCategory.Help: + case 'help': categoryTitle = window.i18n('helpSettingsTitle'); break; - case SessionSettingCategory.Permissions: + case 'permissions': categoryTitle = window.i18n('permissionsSettingsTitle'); break; - case SessionSettingCategory.Privacy: + case 'privacy': categoryTitle = window.i18n('privacySettingsTitle'); break; - case SessionSettingCategory.ClearData: - case SessionSettingCategory.MessageRequests: - case SessionSettingCategory.RecoveryPhrase: + case 'ClearData': + case 'messageRequests': + case 'recoveryPhrase': throw new Error(`no header for should be tried to be rendered for "${category}"`); default: diff --git a/ts/components/settings/section/CategoryConversations.tsx b/ts/components/settings/section/CategoryConversations.tsx index 4fd0a2074..ac6d68d6e 100644 --- a/ts/components/settings/section/CategoryConversations.tsx +++ b/ts/components/settings/section/CategoryConversations.tsx @@ -5,14 +5,14 @@ import useUpdate from 'react-use/lib/useUpdate'; import { SettingsKey } from '../../../data/settings-key'; import { ToastUtils } from '../../../session/utils'; import { toggleAudioAutoplay } from '../../../state/ducks/userConfig'; +import { useHasEnterSendEnabled } from '../../../state/selectors/settings'; import { getAudioAutoplay } from '../../../state/selectors/userConfig'; -import { SessionRadioGroup } from '../../basic/SessionRadioGroup'; +import { SessionRadioGroup, SessionRadioItems } from '../../basic/SessionRadioGroup'; import { BlockedContactsList } from '../BlockedList'; import { SessionSettingsItemWrapper, SessionToggleWithDescription, } from '../SessionSettingListItem'; -import { useHasEnterSendEnabled } from '../../../state/selectors/settings'; async function toggleCommunitiesPruning() { try { @@ -88,14 +88,18 @@ const EnterKeyFunctionSetting = () => { const initialSetting = useHasEnterSendEnabled(); const selectedWithSettingTrue = 'enterForNewLine'; - const items = [ + const items: SessionRadioItems = [ { label: window.i18n('enterSendNewMessageDescription'), value: 'enterForSend', + inputDatatestId: 'input-enterForSend', + labelDatatestId: 'label-enterForSend', }, { label: window.i18n('enterNewLineDescription'), value: selectedWithSettingTrue, + inputDatatestId: `input-${selectedWithSettingTrue}`, + labelDatatestId: `label-${selectedWithSettingTrue}`, }, ]; diff --git a/ts/interactions/conversations/unsendingInteractions.ts b/ts/interactions/conversations/unsendingInteractions.ts index 006816ec5..c9da1613b 100644 --- a/ts/interactions/conversations/unsendingInteractions.ts +++ b/ts/interactions/conversations/unsendingInteractions.ts @@ -391,8 +391,18 @@ export async function deleteMessagesById(messageIds: Array, conversation : window.i18n('deleteMessageQuestion'), radioOptions: !isMe ? [ - { label: window.i18n('deleteJustForMe'), value: 'deleteJustForMe' }, - { label: window.i18n('deleteForEveryone'), value: 'deleteForEveryone' }, + { + label: window.i18n('deleteJustForMe'), + value: 'deleteJustForMe', + inputDatatestId: 'input-deleteJustForMe', + labelDatatestId: 'label-deleteJustForMe', + }, + { + label: window.i18n('deleteForEveryone'), + value: 'deleteForEveryone', + inputDatatestId: 'input-deleteForEveryone', + labelDatatestId: 'label-deleteForEveryone', + }, ] : undefined, okText: window.i18n('delete'), diff --git a/ts/react.d.ts b/ts/react.d.ts new file mode 100644 index 000000000..9adacdf0a --- /dev/null +++ b/ts/react.d.ts @@ -0,0 +1,202 @@ +import 'react'; + +/** + * WARNING: if you change something here, you will most likely break some integration tests. + * So be sure to check with QA first. + */ + +declare module 'react' { + type SessionDataTestId = + | 'group_member_status_text' + | 'group_member_name' + | 'loading-spinner' + | 'session-toast' + | 'loading-animation' + | 'your-session-id' + | 'chooser-new-community' + | 'chooser-new-group' + | 'chooser-new-conversation-button' + | 'new-conversation-button' + | 'module-conversation__user__profile-name' + | 'message-request-banner' + | 'leftpane-section-container' + | 'group-name-input' + | 'recovery-phrase-seed-modal' + | 'password-input-reconfirm' + | 'conversation-header-subtitle' + | 'password-input' + | 'nickname-input' + | 'image-upload-click' + | 'profile-name-input' + | 'your-profile-name' + | 'edit-profile-dialog' + | 'image-upload-section' + | 'right-panel-group-name' + | 'control-message' + | 'header-conversation-name' + | 'disappear-messages-type-and-time' + | 'message-input' + | 'messages-container' + | 'decline-and-block-message-request' + | 'session-dropdown' + | 'path-light-container' + | 'add-user-button' + | 'back-button-conversation-options' + | 'send-message-button' + | 'scroll-to-bottom-button' + | 'end-call' + | 'modal-close-button' + | 'end-voice-message' + | 'back-button-message-details' + | 'edit-profile-icon' + | 'microphone-button' + | 'call-button' + | 'attachments-button' + + // generic button types + | 'emoji-button' + | 'reveal-blocked-user-settings' + + // left pane section types + | 'theme-section' + | 'settings-section' + | 'message-section' + | 'privacy-section' + + // settings menu item types + | 'messageRequests-settings-menu-item' // needs to be tweaked + | 'recoveryPhrase-settings-menu-item' // needs to be tweaked + | 'privacy-settings-menu-item' // needs to be tweaked + | 'notifications-settings-menu-item' // needs to be tweaked + | 'conversations-settings-menu-item' // needs to be tweaked + | 'appearance-settings-menu-item' // needs to be tweaked + | 'help-settings-menu-item' // needs to be tweaked + | 'permissions-settings-menu-item' // needs to be tweaked + | 'ClearData-settings-menu-item' // TODO AUDRIC needs to be tweaked + + // timer options + | 'time-option-0' + | 'time-option-5' + | 'time-option-10' + | 'time-option-30' + | 'time-option-60' + | 'time-option-300' + | 'time-option-1800' + | 'time-option-3600' + | 'time-option-21600' + | 'time-option-43200' + | 'time-option-86400' + | 'time-option-604800' + | 'time-option-1209600' + + // generic readably message (not control message) + | 'message-content' + + // control message types + | 'message-request-response-message' + | 'interaction-notification' + | 'data-extraction-notification' + | 'group-update-message' + | 'disappear-control-message' + + // subtle control message types + | 'group-request-explanation' + | 'conversation-request-explanation' + | 'group-invite-control-message' + | 'empty-conversation-notification' + + // call notification types + | 'call-notification-missed-call' + | 'call-notification-started-call' + | 'call-notification-answered-a-call' + + // disappear options + | 'disappear-after-send-option' + | 'disappear-after-read-option' + | 'disappear-legacy-option' + | 'disappear-off-option' + + // settings toggle and buttons + | 'remove-password-settings-button' + | 'change-password-settings-button' + | 'enable-read-receipts' + | 'set-password-button' + | 'enable-read-receipts' + | 'enable-calls' + | 'enable-microphone' + | 'enable-follow-system-theme' + | 'unblock-button-settings-screen' + | 'save-attachment-from-details' + | 'resend-msg-from-details' + | 'reply-to-msg-from-details' + | 'leave-group-button' + | 'disappearing-messages' + | 'group-members' + | 'remove-moderators' + | 'add-moderators' + | 'edit-group-name' + + // SessionRadioGroup & SessionRadio + | 'password-input-confirm' + | 'msg-status' + | 'input-device_and_network' + | 'label-device_and_network' + | 'input-device_only' + | 'label-device_only' + | 'input-deleteForEveryone' + | 'label-deleteForEveryone' + | 'input-deleteJustForMe' + | 'label-deleteJustForMe' + | 'input-enterForSend' + | 'label-enterForSend' + | 'input-enterForNewLine' + | 'label-enterForNewLine' + | 'input-message' + | 'label-message' + | 'input-name' + | 'label-name' + | 'input-count' + | 'label-count' + + // to sort + | 'restore-using-recovery' + | 'link-device' + | 'continue-session-button' + | 'next-new-conversation-button' + | 'reveal-recovery-phrase' + | 'resend_invite_button' + | 'session-confirm-cancel-button' + | 'session-confirm-ok-button' + | 'confirm-nickname' + | 'path-light-svg' + | 'group_member_status_text' + | 'group_member_name' + | 'resend_promote_button' + | 'next-button' + | 'save-button-profile-update' + | 'save-button-profile-update' + | 'copy-button-profile-update' + | 'disappear-set-button' + | 'decline-message-request' + | 'accept-message-request' + | 'mentions-popup-row' + | 'session-id-signup' + | 'three-dot-loading-animation' + | 'recovery-phrase-input' + | 'display-name-input' + | 'new-session-conversation' + | 'new-closed-group-name' + | 'leftpane-primary-avatar' + | 'img-leftpane-primary-avatar' + | 'conversation-options-avatar' + // modules profile name + | 'module-conversation__user__profile-name' + | 'module-message-search-result__header__name__profile-name' + | 'module-message__author__profile-name' + | 'module-contact-name__profile-name' + | 'delete-from-details'; + + interface HTMLAttributes { + 'data-testid'?: SessionDataTestId; + } +} diff --git a/ts/session/disappearing_messages/timerOptions.ts b/ts/session/disappearing_messages/timerOptions.ts index 1dc1267f3..8c1f0af6c 100644 --- a/ts/session/disappearing_messages/timerOptions.ts +++ b/ts/session/disappearing_messages/timerOptions.ts @@ -2,35 +2,43 @@ import moment from 'moment'; import { isDevProd } from '../../shared/env_vars'; import { LocalizerKeys } from '../../types/LocalizerKeys'; -type TimerOptionsEntry = { name: string; value: number }; +type TimerOptionsEntry = { name: string; value: TimerOptionSeconds }; export type TimerOptionsArray = Array; +type TimerOptionSeconds = + | 0 + | 5 + | 10 + | 30 + | 60 + | 300 + | 1800 + | 3600 + | 21600 + | 43200 + | 86400 + | 604800 + | 1209600; + const timerOptionsDurations: Array<{ time: number; unit: moment.DurationInputArg2; - seconds: number; + seconds: TimerOptionSeconds; }> = [ - { time: 0, unit: 'seconds' as moment.DurationInputArg2 }, - { time: 5, unit: 'seconds' as moment.DurationInputArg2 }, - { time: 10, unit: 'seconds' as moment.DurationInputArg2 }, - { time: 30, unit: 'seconds' as moment.DurationInputArg2 }, - { time: 1, unit: 'minute' as moment.DurationInputArg2 }, - { time: 5, unit: 'minutes' as moment.DurationInputArg2 }, - { time: 30, unit: 'minutes' as moment.DurationInputArg2 }, - { time: 1, unit: 'hour' as moment.DurationInputArg2 }, - { time: 6, unit: 'hours' as moment.DurationInputArg2 }, - { time: 12, unit: 'hours' as moment.DurationInputArg2 }, - { time: 1, unit: 'day' as moment.DurationInputArg2 }, - { time: 1, unit: 'week' as moment.DurationInputArg2 }, - { time: 2, unit: 'weeks' as moment.DurationInputArg2 }, -].map(o => { - const duration = moment.duration(o.time, o.unit); // 5, 'seconds' - return { - time: o.time, - unit: o.unit, - seconds: duration.asSeconds(), - }; -}); + { time: 0, unit: 'seconds' as moment.DurationInputArg2, seconds: 0 }, + { time: 5, unit: 'seconds' as moment.DurationInputArg2, seconds: 5 }, + { time: 10, unit: 'seconds' as moment.DurationInputArg2, seconds: 10 }, + { time: 30, unit: 'seconds' as moment.DurationInputArg2, seconds: 30 }, + { time: 1, unit: 'minute' as moment.DurationInputArg2, seconds: 60 }, + { time: 5, unit: 'minutes' as moment.DurationInputArg2, seconds: 300 }, + { time: 30, unit: 'minutes' as moment.DurationInputArg2, seconds: 1800 }, + { time: 1, unit: 'hour' as moment.DurationInputArg2, seconds: 3600 }, + { time: 6, unit: 'hours' as moment.DurationInputArg2, seconds: 21600 }, + { time: 12, unit: 'hours' as moment.DurationInputArg2, seconds: 43200 }, + { time: 1, unit: 'day' as moment.DurationInputArg2, seconds: 86400 }, + { time: 1, unit: 'week' as moment.DurationInputArg2, seconds: 604800 }, + { time: 2, unit: 'weeks' as moment.DurationInputArg2, seconds: 1209600 }, +]; function getTimerOptionName(time: number, unit: moment.DurationInputArg2) { return ( @@ -62,7 +70,7 @@ function getAbbreviated(seconds = 0) { return [seconds, 's'].join(''); } -const VALUES: Array = timerOptionsDurations.map(t => { +const VALUES = timerOptionsDurations.map(t => { return t.seconds; }); @@ -110,10 +118,10 @@ const DELETE_LEGACY = VALUES.filter(option => { }).filter(filterOutDebugValues); const DEFAULT_OPTIONS = { - DELETE_AFTER_READ: 43200, // 12 hours - DELETE_AFTER_SEND: 86400, // 1 day + DELETE_AFTER_READ: 43200 as TimerOptionSeconds, // 12 hours + DELETE_AFTER_SEND: 86400 as TimerOptionSeconds, // 1 day // TODO legacy messages support will be removed in a future release - LEGACY: 86400, // 1 day + LEGACY: 86400 as TimerOptionSeconds, // 1 day }; export const TimerOptions = { diff --git a/ts/session/utils/Toast.tsx b/ts/session/utils/Toast.tsx index 748d79371..d3f9169b8 100644 --- a/ts/session/utils/Toast.tsx +++ b/ts/session/utils/Toast.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { toast } from 'react-toastify'; import { SessionToast, SessionToastType } from '../../components/basic/SessionToast'; import { SessionIconType } from '../../components/icon'; -import { SessionSettingCategory } from '../../components/settings/SessionSettings'; import { SectionType, showLeftPaneSection, showSettingsSection } from '../../state/ducks/section'; // if you push a toast manually with toast...() be sure to set the type attribute of the SessionToast component @@ -127,7 +126,7 @@ export function pushedMissedCall(conversationName: string) { const openPermissionsSettings = () => { window.inboxStore?.dispatch(showLeftPaneSection(SectionType.Settings)); - window.inboxStore?.dispatch(showSettingsSection(SessionSettingCategory.Permissions)); + window.inboxStore?.dispatch(showSettingsSection('permissions')); }; export function pushedMissedCallCauseOfPermission(conversationName: string) { diff --git a/ts/shared/data_test_id.ts b/ts/shared/data_test_id.ts new file mode 100644 index 000000000..29222d4a1 --- /dev/null +++ b/ts/shared/data_test_id.ts @@ -0,0 +1,8 @@ +/** + * Returns a string with all spaces replaced to '-'. + * A datatestid cannot have spaces on desktop, so we use this to format them accross the app. + * + */ +export function strToDataTestId(input: string) { + return input.replaceAll(' ', '-'); +} diff --git a/ts/state/ducks/metaGroups.ts b/ts/state/ducks/metaGroups.ts index 8b8b51de5..7f403f64b 100644 --- a/ts/state/ducks/metaGroups.ts +++ b/ts/state/ducks/metaGroups.ts @@ -384,7 +384,6 @@ const refreshGroupDetailsFromWrapper = createAsyncThunk( const destroyGroupDetails = createAsyncThunk( 'group/destroyGroupDetails', async ({ groupPk }: { groupPk: GroupPubkeyType }) => { - debugger; const us = UserUtils.getOurPubKeyStrFromCache(); const weAreAdmin = await checkWeAreAdmin(groupPk); const allMembers = await MetaGroupWrapperActions.memberGetAll(groupPk); diff --git a/ts/state/ducks/section.tsx b/ts/state/ducks/section.tsx index 5060af4cc..0475311fc 100644 --- a/ts/state/ducks/section.tsx +++ b/ts/state/ducks/section.tsx @@ -173,7 +173,7 @@ export const reducer = ( return { ...state, focusedSection: payload, - focusedSettingsSection: SessionSettingCategory.Privacy, + focusedSettingsSection: 'privacy', }; case FOCUS_SETTINGS_SECTION: return {