Skip to content

Commit 57a4cff

Browse files
committed
feat: added the help settings page and remove it from legacy settings
1 parent 7b112ca commit 57a4cff

13 files changed

+231
-101
lines changed

ts/components/buttons/panel/PanelWithButtonInline.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@ import {
77
type GenericPanelButtonProps,
88
} from './GenericPanelButtonWithAction';
99

10-
type PanelButtonOnRightProps = Pick<GenericPanelButtonProps, 'rowDataTestId' | 'textElement'> &
10+
export type PanelWithButtonInlineProps = Pick<
11+
GenericPanelButtonProps,
12+
'rowDataTestId' | 'textElement'
13+
> &
1114
Required<Pick<SessionButtonProps, 'buttonColor'>> & {
1215
onClick: () => Promise<void>;
1316
buttonDataTestId: SessionDataTestId;
1417
disabled?: boolean;
1518
buttonText: string;
1619
};
1720

18-
export const PanelWithButtonInline = (props: PanelButtonOnRightProps) => {
21+
export const PanelWithButtonInline = (props: PanelWithButtonInlineProps) => {
1922
const {
2023
onClick,
2124
buttonDataTestId,

ts/components/dialog/user-settings/UserSettingsDialog.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type UserSettingsModalState } from '../../../state/ducks/modalDialog';
22
import { ConversationSettingsPage } from './pages/ConversationSettingsPage';
33
import { DefaultSettingPage } from './pages/DefaultSettingsPage';
4+
import { HelpSettingsPage } from './pages/HelpSettingsPage';
45
import { NotificationsSettingsPage } from './pages/NotificationsSettingsPage';
56
import { PrivacySettingsPage } from './pages/PrivacySettingsPage';
67

@@ -18,6 +19,8 @@ export const UserSettingsDialog = (modalState: UserSettingsModalState) => {
1819
return <NotificationsSettingsPage {...modalState} />;
1920
case 'conversations':
2021
return <ConversationSettingsPage {...modalState} />;
22+
case 'help':
23+
return <HelpSettingsPage {...modalState} />;
2124
default:
2225
return <DefaultSettingPage />;
2326
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { SettingsExternalLinkButtons } from 'react';
2+
import type { TokenSimpleNoArgs } from '../../../../localization/locales';
3+
import { PanelButtonTextWithSubText } from '../../../buttons/panel/PanelButton';
4+
import { tr } from '../../../../localization/localeTools';
5+
import {
6+
GenericPanelButtonWithAction,
7+
type GenericPanelButtonProps,
8+
} from '../../../buttons/panel/GenericPanelButtonWithAction';
9+
import { SessionLucideIconButton } from '../../../icon/SessionIconButton';
10+
import { LUCIDE_ICONS_UNICODE } from '../../../icon/lucide';
11+
12+
const PanelExternalLinkButton = (
13+
props: Pick<GenericPanelButtonProps, 'textElement'> & {
14+
onClick?: () => void;
15+
baseDataTestId: SettingsExternalLinkButtons;
16+
}
17+
) => {
18+
const { onClick, baseDataTestId, textElement } = props;
19+
20+
return (
21+
<GenericPanelButtonWithAction
22+
onClick={onClick}
23+
rowDataTestId={`${baseDataTestId}-settings-row`}
24+
textElement={textElement}
25+
actionElement={
26+
<SessionLucideIconButton
27+
dataTestId={`${baseDataTestId}-settings-chevron`}
28+
unicode={LUCIDE_ICONS_UNICODE.EXTERNAL_LINK_ICON}
29+
iconSize="medium"
30+
iconColor="var(--primary-color)"
31+
style={{ paddingInlineEnd: 'var(--margins-xs)' }}
32+
/>
33+
}
34+
/>
35+
);
36+
};
37+
38+
export function SettingsExternalLinkBasic({
39+
baseDataTestId,
40+
onClick,
41+
textToken,
42+
subTextToken,
43+
}: {
44+
textToken: TokenSimpleNoArgs;
45+
subTextToken: TokenSimpleNoArgs;
46+
baseDataTestId: SettingsExternalLinkButtons;
47+
onClick: () => Promise<void>;
48+
}) {
49+
return (
50+
<PanelExternalLinkButton
51+
textElement={
52+
<PanelButtonTextWithSubText
53+
text={tr(textToken)}
54+
subText={tr(subTextToken)}
55+
textDataTestId={`${baseDataTestId}-settings-text`}
56+
subTextDataTestId={`${baseDataTestId}-settings-sub-text`}
57+
/>
58+
}
59+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
60+
onClick={onClick}
61+
baseDataTestId={baseDataTestId}
62+
/>
63+
);
64+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { SettingsInlineButtons } from 'react';
2+
import type { TokenSimpleNoArgs } from '../../../../localization/locales';
3+
import { PanelButtonTextWithSubText } from '../../../buttons/panel/PanelButton';
4+
import { tr } from '../../../../localization/localeTools';
5+
import {
6+
PanelWithButtonInline,
7+
type PanelWithButtonInlineProps,
8+
} from '../../../buttons/panel/PanelWithButtonInline';
9+
10+
export function SettingsPanelButtonInlineBasic({
11+
baseDataTestId,
12+
onClick,
13+
textToken,
14+
subTextToken,
15+
buttonColor,
16+
buttonText,
17+
disabled,
18+
}: {
19+
textToken: TokenSimpleNoArgs;
20+
subTextToken: TokenSimpleNoArgs;
21+
baseDataTestId: SettingsInlineButtons;
22+
} & Pick<PanelWithButtonInlineProps, 'buttonColor' | 'buttonText' | 'onClick' | 'disabled'>) {
23+
return (
24+
<PanelWithButtonInline
25+
textElement={
26+
<PanelButtonTextWithSubText
27+
text={tr(textToken)}
28+
subText={tr(subTextToken)}
29+
textDataTestId={`${baseDataTestId}-settings-text`}
30+
subTextDataTestId={`${baseDataTestId}-settings-sub-text`}
31+
/>
32+
}
33+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
34+
onClick={onClick}
35+
buttonColor={buttonColor}
36+
buttonText={buttonText}
37+
disabled={disabled}
38+
rowDataTestId={`${baseDataTestId}-settings-row`}
39+
buttonDataTestId={`${baseDataTestId}-settings-button`}
40+
/>
41+
);
42+
}

ts/components/dialog/user-settings/pages/DefaultSettingsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ function AdminSection() {
230230
iconElement={<LucideIconForSettings unicode={LUCIDE_ICONS_UNICODE.CIRCLE_HELP} />}
231231
text={tr('sessionHelp')}
232232
onClick={() => {
233-
throw new Error('Not implemented');
233+
dispatch(userSettingsModal({ userSettingsPage: 'help' }));
234234
}}
235235
dataTestId="help-settings-menu-item"
236236
/>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { useDispatch } from 'react-redux';
2+
3+
import { tr } from '../../../../localization/localeTools';
4+
import { type UserSettingsModalState } from '../../../../state/ducks/modalDialog';
5+
import { PanelButtonGroup, PanelLabelWithDescription } from '../../../buttons/panel/PanelButton';
6+
import {
7+
ModalBasicHeader,
8+
SessionWrapperModal,
9+
WrapperModalWidth,
10+
} from '../../../SessionWrapperModal';
11+
import { ModalBackButton } from '../../shared/ModalBackButton';
12+
import {
13+
useUserSettingsBackAction,
14+
useUserSettingsCloseAction,
15+
useUserSettingsTitle,
16+
} from './userSettingsHooks';
17+
import { SessionButtonColor } from '../../../basic/SessionButton';
18+
import { saveLogToDesktop } from '../../../../util/logger/renderer_process_logging';
19+
import { SettingsPanelButtonInlineBasic } from '../components/SettingsPanelButtonInlineBasic';
20+
import { SettingsExternalLinkBasic } from '../components/SettingsExternalLinkBasic';
21+
import { showLinkVisitWarningDialog } from '../../OpenUrlModal';
22+
23+
export function HelpSettingsPage(modalState: UserSettingsModalState) {
24+
const backAction = useUserSettingsBackAction(modalState);
25+
const closeAction = useUserSettingsCloseAction(modalState);
26+
const title = useUserSettingsTitle(modalState);
27+
28+
const dispatch = useDispatch();
29+
30+
return (
31+
<SessionWrapperModal
32+
headerChildren={
33+
<ModalBasicHeader
34+
title={title}
35+
bigHeader={true}
36+
showExitIcon={true}
37+
extraLeftButton={backAction ? <ModalBackButton onClick={backAction} /> : undefined}
38+
/>
39+
}
40+
onClose={closeAction || undefined}
41+
shouldOverflow={true}
42+
allowOutsideClick={false}
43+
$contentMinWidth={WrapperModalWidth.normal}
44+
>
45+
<PanelLabelWithDescription title={{ token: 'logs' }} />
46+
<PanelButtonGroup>
47+
<SettingsPanelButtonInlineBasic
48+
baseDataTestId="export-logs"
49+
textToken="helpReportABug"
50+
subTextToken="helpReportABugExportLogsSaveToDesktopDescription"
51+
onClick={async () => saveLogToDesktop()}
52+
buttonColor={SessionButtonColor.Primary}
53+
buttonText={tr('helpReportABugExportLogs')}
54+
/>
55+
</PanelButtonGroup>
56+
<PanelLabelWithDescription title={{ token: 'links' }} />
57+
<PanelButtonGroup>
58+
<SettingsExternalLinkBasic
59+
baseDataTestId="faq"
60+
textToken="helpFAQ"
61+
subTextToken="helpFAQDescription"
62+
onClick={async () => {
63+
showLinkVisitWarningDialog('https://getsession.org/faq', dispatch);
64+
}}
65+
/>
66+
<SettingsExternalLinkBasic
67+
baseDataTestId="translate"
68+
textToken="translate"
69+
subTextToken="helpTranslateSessionDescription"
70+
onClick={async () => {
71+
showLinkVisitWarningDialog('https://getsession.org/translate', dispatch);
72+
}}
73+
/>
74+
75+
<SettingsExternalLinkBasic
76+
baseDataTestId="feedback"
77+
textToken="feedback"
78+
subTextToken="feedbackDescription"
79+
onClick={async () => {
80+
showLinkVisitWarningDialog('https://getsession.org/survey', dispatch);
81+
}}
82+
/>
83+
<SettingsExternalLinkBasic
84+
baseDataTestId="support"
85+
textToken="helpSupport"
86+
subTextToken="supportDescription"
87+
onClick={async () => {
88+
showLinkVisitWarningDialog('https://sessionapp.zendesk.com/hc/en-us', dispatch);
89+
}}
90+
/>
91+
</PanelButtonGroup>
92+
</SessionWrapperModal>
93+
);
94+
}

ts/components/dialog/user-settings/pages/PrivacySettingsPage.tsx

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ import { SettingsKey } from '../../../../data/settings-key';
3333
import { SessionUtilUserProfile } from '../../../../session/utils/libsession/libsession_utils_user_profile';
3434
import { getPasswordHash, Storage } from '../../../../util/storage';
3535
import { SpacerXS } from '../../../basic/Text';
36-
import { PanelWithButtonInline } from '../../../buttons/panel/PanelWithButtonInline';
3736
import { displayPasswordModal } from '../../../settings/SessionSettings';
3837
import { SettingsToggleBasic } from '../components/SettingsToggleBasic';
38+
import { SettingsPanelButtonInlineBasic } from '../components/SettingsPanelButtonInlineBasic';
3939

4040
type WithPasswordUpdatedCb = { onPasswordUpdated: (action: string) => void };
4141

@@ -113,34 +113,18 @@ function StaticTypingBubble({ width }: { width: string }) {
113113
function HasPasswordSubSection(props: WithPasswordUpdatedCb) {
114114
return (
115115
<PanelButtonGroup>
116-
<PanelWithButtonInline
117-
textElement={
118-
<PanelButtonTextWithSubText
119-
text={tr('passwordChange')}
120-
subText={tr('passwordChangeShortDescription')}
121-
textDataTestId={'change-password-settings-text'}
122-
subTextDataTestId={'change-password-settings-sub-text'}
123-
/>
124-
}
125-
rowDataTestId={'change-password-settings-row'}
126-
buttonDataTestId={'change-password-settings-button'}
127-
onClick={async () => {
128-
displayPasswordModal('change', props.onPasswordUpdated);
129-
}}
116+
<SettingsPanelButtonInlineBasic
117+
baseDataTestId="change-password"
118+
textToken="passwordChange"
119+
subTextToken="passwordChangeShortDescription"
120+
onClick={async () => displayPasswordModal('change', props.onPasswordUpdated)}
130121
buttonColor={SessionButtonColor.Primary}
131122
buttonText={tr('change')}
132123
/>
133-
<PanelWithButtonInline
134-
textElement={
135-
<PanelButtonTextWithSubText
136-
text={tr('passwordRemove')}
137-
subText={tr('passwordRemoveShortDescription')}
138-
textDataTestId={'remove-password-settings-text'}
139-
subTextDataTestId={'remove-password-settings-sub-text'}
140-
/>
141-
}
142-
rowDataTestId={'remove-password-settings-row'}
143-
buttonDataTestId={'remove-password-settings-button'}
124+
<SettingsPanelButtonInlineBasic
125+
baseDataTestId="remove-password"
126+
textToken="passwordRemove"
127+
subTextToken="passwordRemoveShortDescription"
144128
onClick={async () => {
145129
displayPasswordModal('remove', props.onPasswordUpdated);
146130
}}
@@ -153,17 +137,10 @@ function HasPasswordSubSection(props: WithPasswordUpdatedCb) {
153137
function NoPasswordSubSection(props: WithPasswordUpdatedCb) {
154138
return (
155139
<PanelButtonGroup>
156-
<PanelWithButtonInline
157-
textElement={
158-
<PanelButtonTextWithSubText
159-
text={tr('passwordSet')}
160-
subText={tr('passwordSetShortDescription')}
161-
textDataTestId={'set-password-settings-text'}
162-
subTextDataTestId={'set-password-settings-sub-text'}
163-
/>
164-
}
165-
rowDataTestId={'set-password-settings-row'}
166-
buttonDataTestId={'set-password-settings-button'}
140+
<SettingsPanelButtonInlineBasic
141+
baseDataTestId="set-password"
142+
textToken="passwordSet"
143+
subTextToken="passwordSetShortDescription"
167144
onClick={async () => {
168145
displayPasswordModal('set', props.onPasswordUpdated);
169146
}}

ts/components/leftpane/LeftPaneSettingSection.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,6 @@ const categories: Array<Categories> = (
8484
title: tr('sessionConversations'),
8585
icon: { type: 'lucide', unicode: LUCIDE_ICONS_UNICODE.MESSAGE_SQUARE },
8686
},
87-
{
88-
id: 'message-requests',
89-
title: tr('sessionMessageRequests'),
90-
icon: { type: 'lucide', unicode: LUCIDE_ICONS_UNICODE.MESSAGE_SQUARE_WARNING },
91-
},
9287
{
9388
id: 'appearance',
9489
title: tr('sessionAppearance'),
@@ -127,8 +122,6 @@ const LeftPaneSettingsCategoryRow = ({ item }: { item: Categories }) => {
127122
padding={'0 var(--margins-xs)'}
128123
onClick={() => {
129124
switch (id) {
130-
case 'message-requests':
131-
break;
132125
default:
133126
dispatch(sectionActions.showSettingsSection(id));
134127
}

ts/components/settings/SessionSettings.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { sessionPassword } from '../../state/ducks/modalDialog';
1010
import type { PasswordAction, SessionSettingCategory } from '../../types/ReduxTypes';
1111
import { SettingsCategoryAppearance } from './section/CategoryAppearance';
1212
import { CategoryConversations } from './section/CategoryConversations';
13-
import { SettingsCategoryHelp } from './section/CategoryHelp';
1413
import { SettingsCategoryPermissions } from './section/CategoryPermissions';
1514
import { SettingsCategoryRecoveryPassword } from './section/CategoryRecoveryPassword';
1615
import { setDebugMode } from '../../state/ducks/debug';
@@ -113,16 +112,10 @@ const SettingInCategory = (props: { category: SessionSettingCategory }) => {
113112
return <CategoryConversations />;
114113
case 'appearance':
115114
return <SettingsCategoryAppearance />;
116-
117-
case 'help':
118-
return <SettingsCategoryHelp />;
119115
case 'permissions':
120116
return <SettingsCategoryPermissions />;
121117
case 'recovery-password':
122118
return <SettingsCategoryRecoveryPassword />;
123-
124-
// these are just buttons or modals and don't have screens
125-
case 'message-requests':
126119
default:
127120
return null;
128121
}

ts/components/settings/SessionSettingsHeader.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,12 @@ export const SettingsHeader = (props: Props) => {
3232
case 'conversations':
3333
categoryTitleKey = 'sessionConversations';
3434
break;
35-
case 'help':
36-
categoryTitleKey = 'sessionHelp';
37-
break;
3835
case 'permissions':
3936
categoryTitleKey = 'sessionPermissions';
4037
break;
4138
case 'recovery-password':
4239
categoryTitleKey = 'sessionRecoveryPassword';
4340
break;
44-
// these are modals or other screens
45-
case 'message-requests':
46-
throw new Error(`no header for should be tried to be rendered for "${category}"`);
47-
4841
default:
4942
assertUnreachable(category, `SettingsHeader "${category}"`);
5043
}

0 commit comments

Comments
 (0)