Skip to content

feat: add donate settings item and cleanup settings categories #1443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 6 additions & 30 deletions ts/components/icon/Icons.tsx

Large diffs are not rendered by default.

18 changes: 15 additions & 3 deletions ts/components/icon/LucideIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SessionDataTestId } from 'react';
import type { CSSProperties, SessionDataTestId } from 'react';
import styled from 'styled-components';

const LucideIconWrapper = styled.div<{ iconColor?: string; iconSize: string }>`
Expand All @@ -12,14 +12,26 @@ export type LucideIconProps = {
iconColor?: string;
iconSize: string;
dataTestId?: SessionDataTestId;
style?: CSSProperties;
};

/**
* This is a wrapper around Lucide icons with unicode.
*/
export const LucideIcon = ({ unicode, iconColor, iconSize, dataTestId }: LucideIconProps) => {
export const LucideIcon = ({
unicode,
iconColor,
iconSize,
dataTestId,
style,
}: LucideIconProps) => {
return (
<LucideIconWrapper iconColor={iconColor} iconSize={iconSize} data-testid={dataTestId}>
<LucideIconWrapper
iconColor={iconColor}
iconSize={iconSize}
data-testid={dataTestId}
style={style}
>
{unicode}
</LucideIconWrapper>
);
Expand Down
155 changes: 83 additions & 72 deletions ts/components/icon/SessionIconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const StyledSessionIconButton = styled.button<{ color?: string; $isSelected?: bo
};`}
}

color: ${props =>
props.color || props.$isSelected
? 'var(--button-icon-stroke-selected-color)'
: 'var(--button-icon-stroke-color)'};

${props => props.disabled && 'cursor: not-allowed;'}

&:hover svg path {
Expand Down Expand Up @@ -130,77 +135,83 @@ const SessionIconButtonInner = forwardRef<HTMLButtonElement, SessionIconButtonPr

export const SessionIconButton = memo(SessionIconButtonInner, _.isEqual);

export const SessionLucideIconButton = (
props: Pick<
SessionIconButtonProps,
| 'onClick'
| 'disabled'
| 'isSelected'
| 'margin'
| 'padding'
| 'ariaLabel'
| 'title'
| 'dataTestId'
| 'dataTestIdIcon'
| 'style'
| 'tabIndex'
> &
Pick<LucideIconProps, 'unicode' | 'iconSize' | 'iconColor'>
) => {
const {
unicode,
iconSize,
isSelected: $isSelected,
margin,
padding,
ariaLabel,
title,
dataTestId,
dataTestIdIcon,
style,
iconColor,
tabIndex,
disabled,
onClick,
} = props;
export type SessionLucideIconButtonProps = Pick<
SessionIconButtonProps,
| 'onClick'
| 'disabled'
| 'isSelected'
| 'margin'
| 'padding'
| 'ariaLabel'
| 'title'
| 'dataTestId'
| 'dataTestIdIcon'
| 'style'
| 'tabIndex'
| 'children'
> &
Pick<LucideIconProps, 'unicode' | 'iconSize' | 'iconColor'>;

const clickHandler = (e: MouseEvent<HTMLButtonElement>) => {
if (!disabled && onClick) {
e.stopPropagation();
onClick(e);
}
};
const keyPressHandler = (e: KeyboardEvent<HTMLButtonElement>) => {
if (e.currentTarget.tabIndex > -1 && e.key === 'Enter' && !disabled && onClick) {
e.stopPropagation();
onClick();
}
};
export const SessionLucideIconButton = forwardRef<HTMLButtonElement, SessionLucideIconButtonProps>(
(props, ref) => {
const {
unicode,
iconSize,
isSelected: $isSelected,
margin,
padding,
ariaLabel,
title,
dataTestId,
dataTestIdIcon,
style,
iconColor,
tabIndex,
disabled,
onClick,
children,
} = props;

return (
<StyledSessionIconButton
color={iconColor}
$isSelected={$isSelected}
title={title}
aria-label={ariaLabel}
onClick={clickHandler}
style={{
...style,
display: style?.display ? style.display : 'flex',
margin: margin || '',
padding: padding || '',
}}
tabIndex={tabIndex}
onKeyDown={keyPressHandler}
disabled={disabled}
data-testid={dataTestId}
>
<LucideIcon
unicode={unicode}
iconSize={iconSize}
iconColor={iconColor}
dataTestId={dataTestIdIcon}
/>
</StyledSessionIconButton>
);
};
const clickHandler = (e: MouseEvent<HTMLButtonElement>) => {
if (!disabled && onClick) {
e.stopPropagation();
onClick(e);
}
};
const keyPressHandler = (e: KeyboardEvent<HTMLButtonElement>) => {
if (e.currentTarget.tabIndex > -1 && e.key === 'Enter' && !disabled && onClick) {
e.stopPropagation();
onClick();
}
};

return (
<StyledSessionIconButton
color={iconColor}
$isSelected={$isSelected}
title={title}
aria-label={ariaLabel}
onClick={clickHandler}
style={{
...style,
display: style?.display ? style.display : 'flex',
margin: margin || '',
padding: padding || '',
}}
tabIndex={tabIndex}
onKeyDown={keyPressHandler}
disabled={disabled}
data-testid={dataTestId}
ref={ref}
>
<LucideIcon
unicode={unicode}
iconSize={iconSize}
iconColor={iconColor}
dataTestId={dataTestIdIcon}
/>
{children}
</StyledSessionIconButton>
);
}
);
11 changes: 11 additions & 0 deletions ts/components/icon/lucide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ export enum LUCIDE_ICONS_UNICODE {
USER_ROUND_X = '',
USER_ROUND_CHECK = '',
PENCIL = '',
HEART = '',
LOCK_KEYHOLE = '',
MESSAGE_SQUARE = '',
MESSAGE_SQUARE_WARNING = '',
PAINTBRUSH_VERTICAL = '',
CIRCLE_CHECK = '',
MOON = '',
SUN_MEDIUM = '',
SETTINGS = '',
SQUARE_CODE = '',
CHEVRON_RIGHT = '',
}

/**
Expand Down
49 changes: 26 additions & 23 deletions ts/components/leftpane/ActionsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ import { getSwarmPollingInstance } from '../../session/apis/snode_api';
import { UserUtils } from '../../session/utils';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { ActionPanelOnionStatusLight } from '../dialog/OnionStatusPathDialog';
import { SessionIconButton } from '../icon/SessionIconButton';
import {
SessionLucideIconButton,
type SessionLucideIconButtonProps,
} from '../icon/SessionIconButton';
import { LeftPaneSectionContainer } from './LeftPaneSectionContainer';

import { SettingsKey } from '../../data/settings-key';
Expand All @@ -61,6 +64,7 @@ import { useCheckReleasedFeatures } from '../../hooks/useCheckReleasedFeatures';
import { useDebugMode } from '../../state/selectors/debug';
import { networkDataActions } from '../../state/ducks/networkData';
import { isSesh101ReadyOutsideRedux } from '../../state/selectors/releasedFeatures';
import { LUCIDE_ICONS_UNICODE } from '../icon/lucide';

const Section = (props: { type: SectionType }) => {
const ourNumber = useSelector(getOurNumber);
Expand All @@ -71,7 +75,7 @@ const Section = (props: { type: SectionType }) => {
const isModalVisible = useSelector(getIsModalVisible);
const isDarkTheme = useIsDarkTheme();
const focusedSection = useSelector(getFocusedSection);
const isSelected = focusedSection === props.type;
const isSelected = focusedSection === type;

const handleClick = () => {
if (type === SectionType.Profile) {
Expand Down Expand Up @@ -125,38 +129,39 @@ const Section = (props: { type: SectionType }) => {

const unreadToShow = type === SectionType.Message ? globalUnreadMessageCount : undefined;

const buttonProps = {
iconSize: '22px',
padding: 'var(--margins-lg)',
onClick: handleClick,
isSelected,
} satisfies Omit<SessionLucideIconButtonProps, 'unicode' | 'dataTestId'>;

switch (type) {
case SectionType.Message:
return (
<SessionIconButton
iconSize="medium"
<SessionLucideIconButton
{...buttonProps}
dataTestId="message-section"
iconType={'chatBubble'}
onClick={handleClick}
isSelected={isSelected}
unicode={LUCIDE_ICONS_UNICODE.MESSAGE_SQUARE}
>
{Boolean(unreadToShow) && <SessionNotificationCount count={unreadToShow} />}
</SessionIconButton>
</SessionLucideIconButton>
);
case SectionType.Settings:
return (
<SessionIconButton
iconSize="medium"
<SessionLucideIconButton
{...buttonProps}
dataTestId="settings-section"
iconType={'gear'}
onClick={handleClick}
isSelected={isSelected}
unicode={LUCIDE_ICONS_UNICODE.SETTINGS}
ref={settingsIconRef}
/>
);
case SectionType.DebugMenu:
return (
<SessionIconButton
iconSize="medium"
<SessionLucideIconButton
{...buttonProps}
unicode={LUCIDE_ICONS_UNICODE.SQUARE_CODE}
dataTestId="debug-menu-section"
iconType={'debug'}
onClick={handleClick}
isSelected={isSelected}
/>
);
case SectionType.PathIndicator:
Expand All @@ -170,12 +175,10 @@ const Section = (props: { type: SectionType }) => {
case SectionType.ColorMode:
default:
return (
<SessionIconButton
iconSize="medium"
iconType={isDarkTheme ? 'moon' : 'sun'}
<SessionLucideIconButton
{...buttonProps}
unicode={isDarkTheme ? LUCIDE_ICONS_UNICODE.MOON : LUCIDE_ICONS_UNICODE.SUN_MEDIUM}
dataTestId="theme-section"
onClick={handleClick}
isSelected={isSelected}
/>
);
}
Expand Down
Loading
Loading