Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"build-compile": "babel ts --out-dir ts --extensions .js",
"build-minify": "node minify.js",
"build:workers": "yarn worker:utils && yarn worker:libsession && yarn worker:image_processor",
"build-post": "yarn build:workers",
"build:svg": "webpack --config svgs.webpack.config.js",
"build-post": "yarn build:workers && yarn build:svg",
"build": "yarn build-pre && yarn build-ts && yarn build-compile && yarn build-post",
"build:dev": "yarn build-pre && yarn build-ts-source-maps && cross-env SESSION_RC_ALLOW_ERRORS=1 yarn build-compile && yarn build-post",
"protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js --force-long",
Expand Down Expand Up @@ -132,6 +133,7 @@
"@commitlint/cli": "^19.8.0",
"@commitlint/config-conventional": "^19.8.0",
"@emotion/is-prop-valid": "^1.4.0",
"@svgr/webpack": "^8.1.0",
"@testing-library/dom": "10.4.1",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.0",
Expand Down
53 changes: 53 additions & 0 deletions svgs.webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');

const svgsPath = path.resolve(__dirname, 'ts', 'svgs');

module.exports = {
entry: './index.ts',
context: svgsPath,
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'ts-loader',
options: {
configFile: path.resolve(svgsPath, 'tsconfig.json'),
transpileOnly: true,
},
},
},
{
test: /\.svg$/,
issuer: /\.ts$/,
use: [
{
loader: '@svgr/webpack',
options: {
exportType: 'default',
},
},
],
},
],
},
resolve: {
extensions: ['.ts', '.js', '.svg'],
},
output: {
filename: 'index.js',
path: svgsPath,
library: {
type: 'commonjs2',
},
},
externals: {
react: 'commonjs2 react',
},
optimization: {
minimize: false,
},
mode: 'development',
devtool: false,
};
14 changes: 7 additions & 7 deletions ts/components/basic/Flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export interface FlexProps {
height?: string;
$maxHeight?: string;
$minHeight?: string;
overflow?: 'hidden' | 'visible' | 'scroll' | 'auto';
overflowX?: 'hidden' | 'visible' | 'scroll' | 'auto';
overflowY?: 'hidden' | 'visible' | 'scroll' | 'auto';
$overflow?: 'hidden' | 'visible' | 'scroll' | 'auto';
$overflowX?: 'hidden' | 'visible' | 'scroll' | 'auto';
$overflowY?: 'hidden' | 'visible' | 'scroll' | 'auto';
// RTL support
dir?: HTMLDirection;
$paddingInline?: string;
Expand All @@ -69,9 +69,9 @@ export const Flex = styled.div<FlexProps>`
height: ${props => props.height || 'auto'};
max-height: ${props => props.$maxHeight || 'none'};
min-height: ${props => props.$minHeight || 'none'};
overflow: ${props => (props.overflow !== undefined ? props.overflow : undefined)};
overflow-x: ${props => (props.overflowX !== undefined ? props.overflowX : undefined)};
overflow-y: ${props => (props.overflowY !== undefined ? props.overflowY : undefined)};
overflow: ${props => (props.$overflow !== undefined ? props.$overflow : undefined)};
overflow-x: ${props => (props.$overflowX !== undefined ? props.$overflowX : undefined)};
overflow-y: ${props => (props.$overflowY !== undefined ? props.$overflowY : undefined)};
direction: ${props => props.dir || undefined};
padding-inline: ${props => props.$paddingInline || undefined};
padding-block: ${props => props.$paddingBlock || undefined};
Expand All @@ -97,7 +97,7 @@ export const AnimatedFlex = styled(motion.div)<HTMLMotionProps<'div'> & FlexProp
height: ${props => props.height || 'auto'};
max-height: ${props => props.$maxHeight || 'none'};
min-height: ${props => props.$minHeight || 'none'};
overflow: ${props => (props.overflow !== undefined ? props.overflow : undefined)};
overflow: ${props => (props.$overflow !== undefined ? props.$overflow : undefined)};
direction: ${props => props.dir || undefined};
padding-inline: ${props => props.$paddingInline || undefined};
padding-block: ${props => props.$paddingBlock || undefined};
Expand Down
2 changes: 1 addition & 1 deletion ts/components/conversation/composition/CompositionBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styled from 'styled-components';
import { AbortController } from 'abort-controller';

import autoBind from 'auto-bind';
import { Component, createRef, RefObject, KeyboardEvent, type JSX } from 'react';
import { Component, createRef, RefObject, KeyboardEvent } from 'react';
import { FrequentlyUsed } from 'emoji-mart';
import * as MIME from '../../../types/MIME';
import { SessionEmojiPanel, StyledEmojiPanel } from '../SessionEmojiPanel';
Expand Down
18 changes: 16 additions & 2 deletions ts/components/dialog/debug/FeatureFlags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,19 +256,25 @@ type FlagIntegerInputProps = {
flag: SessionDataFeatureFlagKeys;
visibleWithBooleanFlag?: SessionBooleanFeatureFlagKeys;
label: string;
min?: number;
max?: number;
};

export const FlagIntegerInput = ({
flag,
forceUpdate,
visibleWithBooleanFlag,
label,
min,
max,
}: FlagIntegerInputProps) => {
const currentValue = getDataFeatureFlagMemo(flag);
const key = `feature-flag-integer-input-${flag}`;
const [value, setValue] = useState<number>(() => {
const initValue = window.sessionDataFeatureFlags[flag];
return typeof initValue === 'number' && Number.isFinite(initValue) ? initValue : 0;
return typeof initValue === 'number' && Number.isFinite(initValue)
? initValue
: Math.max(Math.min(0, max ?? Number.NEGATIVE_INFINITY), min ?? Number.POSITIVE_INFINITY);
});

if (!isFeatureFlagAvailable(flag)) {
Expand Down Expand Up @@ -315,7 +321,8 @@ export const FlagIntegerInput = ({
<input
type="number"
value={value}
min={0}
min={min ?? 0}
max={max ?? undefined}
onChange={e => setValue(e.target.valueAsNumber)}
style={{
width: '100px',
Expand Down Expand Up @@ -527,6 +534,13 @@ export function DebugFeatureFlags({ forceUpdate }: { forceUpdate: () => void })
{debugFeatureFlags.map(props => (
<FlagToggle {...props} forceUpdate={forceUpdate} />
))}
<FlagIntegerInput
flag="mockNetworkPageNodeCount"
forceUpdate={forceUpdate}
label="Network Page Node Count"
min={1}
max={10}
/>
</DebugMenuSection>
);
}
Expand Down
62 changes: 28 additions & 34 deletions ts/components/dialog/user-settings/pages/network/NodeImage.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { type SVGProps, type JSX } from 'react';
import styled from 'styled-components';
import { Block } from './components';
import { NodeGraph1 } from './nodes/NodeGraph1';
import { NodeGraph10 } from './nodes/NodeGraph10';
import { NodeGraph2 } from './nodes/NodeGraph2';
import { NodeGraph3 } from './nodes/NodeGraph3';
import { NodeGraph4 } from './nodes/NodeGraph4';
import { NodeGraph5 } from './nodes/NodeGraph5';
import { NodeGraph6 } from './nodes/NodeGraph6';
import { NodeGraph7 } from './nodes/NodeGraph7';
import { NodeGraph8 } from './nodes/NodeGraph8';
import { NodeGraph9 } from './nodes/NodeGraph9';
import { useSecuringNodesCount } from './sections/network/hooks/useSecuringNodesCount';
import {
AnimatedSpinnerIcon,
AnimatedSpinnerIconWrapper,
} from '../../../../loading/spinner/AnimatedSpinnerIcon';
import {
NodeGraph1,
NodeGraph10,
NodeGraph2,
NodeGraph3,
NodeGraph4,
NodeGraph5,
NodeGraph6,
NodeGraph7,
NodeGraph8,
NodeGraph9,
} from '../../../../../svgs/index';
import { useInfoFakeRefreshing } from '../../../../../state/selectors/networkModal';

const StyledNodeImage = styled(Block)`
const StyledNodeImage = styled(Block)<{ $nodeColor: string; $pathColor: string }>`
display: flex;
justify-content: center;
align-items: center;
--c1: ${({ $nodeColor }) => $nodeColor};
--c2: ${({ $pathColor }) => $pathColor};

${AnimatedSpinnerIconWrapper} {
margin: auto;
Expand All @@ -30,23 +34,17 @@ const StyledNodeImage = styled(Block)`
${AnimatedSpinnerIconWrapper} {
position: absolute;
inset: 0;
}

svg:nth-child(2) {
transform: translateY((-100%));
width: 100%;
height: 100%;
}
`;

export type NodeGraphProps = SVGProps<SVGSVGElement> & { nodeColor: string; pathColor: string };

type Props = {
count: number;
width: string;
height: string;
loading?: boolean;
};

const nodeComps: Record<number, (props: NodeGraphProps) => JSX.Element> = {
const nodeGraphs: Record<number, React.FC<React.SVGProps<SVGSVGElement>>> = {
1: NodeGraph1,
2: NodeGraph2,
3: NodeGraph3,
Expand All @@ -59,31 +57,27 @@ const nodeComps: Record<number, (props: NodeGraphProps) => JSX.Element> = {
10: NodeGraph10,
};

export const NodeImage = ({ width, height, loading }: Props) => {
const { swarmNodeCount } = useSecuringNodesCount();

const NodeComp = nodeComps[swarmNodeCount ?? 0];
const sharedNodeProps = {
nodeColor: 'var(--primary-color)',
pathColor: 'var(--text-primary-color)',
width,
height,
};
export const NodeImage = ({ width, height }: Props) => {
const { swarmNodeCount, dataIsStale } = useSecuringNodesCount();
const isFakeRefreshing = useInfoFakeRefreshing();
const NodeGraph = nodeGraphs[swarmNodeCount ?? 1];

const ready = !loading && NodeComp;
const loading = !swarmNodeCount || !NodeGraph || dataIsStale || isFakeRefreshing;

return (
<StyledNodeImage
$flexDirection="column"
$justifyContent="center"
$alignItems="center"
borderColor="var(--primary-color)"
$nodeColor="var(--primary-color)"
$pathColor="var(--text-primary-color)"
$borderColor={!loading ? 'hidden' : undefined}
width={width}
height={height}
style={{ position: 'relative', overflow: 'hidden' }}
data-testid="swarm-image"
>
{ready ? <NodeComp {...sharedNodeProps} /> : <AnimatedSpinnerIcon size="huge2" />}
{!loading ? <NodeGraph /> : <AnimatedSpinnerIcon size="huge2" />}
</StyledNodeImage>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function SessionNetworkPage(modalState: UserSettingsModalState) {
{!dataIsStale && lastRefreshedTimestamp && !loading ? (
<>
<SpacerXL />
<ExtraSmallText color={'var(--text-secondary-color)'} textAlignment="center">
<ExtraSmallText color={'var(--text-secondary-color)'} $textAlignment="center">
<LastRefreshedText />
</ExtraSmallText>
<SpacerXS />
Expand Down
37 changes: 19 additions & 18 deletions ts/components/dialog/user-settings/pages/network/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export const SessionNetworkButton = styled(SessionButton)<SessionButtonProps>`
`;

export const SectionHeading = styled.h3<{
margin?: string;
textAlignment?: 'start' | 'center' | 'end';
$margin?: string;
$textAlignment?: 'start' | 'center' | 'end';
}>`
direction: 'auto';
color: var(--text-secondary-color);
Expand All @@ -32,13 +32,13 @@ export const SectionHeading = styled.h3<{
line-height: var(--font-line-height);
width: 100%;
padding: 0;
margin: ${props => props.margin ?? '0'};
text-align: ${props => props.textAlignment ?? 'start'};
margin: ${props => props.$margin ?? '0'};
text-align: ${props => props.$textAlignment ?? 'start'};
`;

export const SessionNetworkHeading = styled.h4<{
color?: string;
textAlignment?: 'start' | 'center' | 'end';
$textAlignment?: 'start' | 'center' | 'end';
width?: string;
}>`
direction: 'auto';
Expand All @@ -49,16 +49,16 @@ export const SessionNetworkHeading = styled.h4<{
padding: 0;
margin: 0;

text-align: ${props => props.textAlignment ?? 'start'};
text-align: ${props => props.$textAlignment ?? 'start'};
${props => props.color && `color: ${props.color};`}
${props => props.width && `width: ${props.width};`}
`;

type SessionNetworkParagraphProps = {
children: ReactNode;
interactive?: boolean;
$interactive?: boolean;
onClick?: () => void;
textAlignment?: 'start' | 'center' | 'end';
$textAlignment?: 'start' | 'center' | 'end';
width?: string;
color?: string;
};
Expand All @@ -74,21 +74,22 @@ const StyledSessionNetworkParagraph = styled.p<SessionNetworkParagraphProps>`

/* NOTE we want to bold Learn CTA */
${props =>
props.interactive &&
props.$interactive &&
'cursor: pointer; div span { font-weight: 700; span[role="img"] { font-weight: unset; } }'}
${props => props.width && `width: ${props.width};`}
text-align: ${props => props.textAlignment ?? 'start'};
text-align: ${props => props.$textAlignment ?? 'start'};
${props => props.color && `color: ${props.color};`}
`;

export const SessionNetworkParagraph = (props: SessionNetworkParagraphProps) => {
return <StyledSessionNetworkParagraph {...props} role={props.interactive ? 'link' : undefined} />;
return (
<StyledSessionNetworkParagraph {...props} role={props.$interactive ? 'link' : undefined} />
);
};

export const ExtraSmallText = styled.p<{
color?: string;
margin?: string;
textAlignment?: 'start' | 'center' | 'end';
$textAlignment?: 'start' | 'center' | 'end';
}>`
direction: 'auto';
font-family: var(--font-default);
Expand All @@ -97,16 +98,16 @@ export const ExtraSmallText = styled.p<{
line-height: var(--font-line-height);
width: 100%;
padding: 0;
margin: ${props => props.margin ?? '0'};
text-align: ${props => props.textAlignment ?? 'start'};
margin: 0;
text-align: ${props => props.$textAlignment ?? 'start'};
${props => props.color && `color: ${props.color};`}
`;

export const Block = styled(Flex)<{ backgroundColor?: string; borderColor?: string }>`
export const Block = styled(Flex)<{ $backgroundColor?: string; $borderColor?: string }>`
position: relative;
${props => props.backgroundColor && `background-color: ${props.backgroundColor};`};
${props => props.$backgroundColor && `background-color: ${props.$backgroundColor};`};
border-radius: 8px;
border: 1px solid ${props => props.borderColor ?? 'var(--border-color)'};
border: 1px solid ${props => props.$borderColor ?? 'var(--border-color)'};
font-size: var(--font-display-size-lg);
line-height: var(--font-line-height);
`;
Expand Down
Loading
Loading