Skip to content

Commit 305b3ca

Browse files
authored
Merge pull request #1526 from session-foundation/feat/user-profile-modal
feat: user details modal
2 parents d3fc1f1 + cb01c80 commit 305b3ca

File tree

65 files changed

+1128
-827
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1128
-827
lines changed
524 KB
Loading

preload.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ window.sessionFeatureFlags = {
6666
alwaysShowRemainingChars: false,
6767
showPopoverAnchors: false,
6868
proAvailable: !isEmpty(process.env.SESSION_PRO),
69-
mockUserHasPro: !isEmpty(process.env.SESSION_HAS_PRO),
69+
mockCurrentUserHasPro: !isEmpty(process.env.SESSION_USER_HAS_PRO),
70+
mockOthersHavePro: !isEmpty(process.env.SESSION_OTHERS_HAVE_PRO),
7071
// Note: some stuff are init when the app starts, so fsTTL30s should only be set from the env itself (before app starts)
7172
fsTTL30s: !isEmpty(process.env.FILE_SERVER_TTL_30S),
7273
debug: {

ts/components/SessionQRCode.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { MouseEvent, useEffect, useRef, useState, type SessionDataTestId } from 'react';
1+
import {
2+
MouseEvent,
3+
useEffect,
4+
useRef,
5+
useState,
6+
type ReactNode,
7+
type SessionDataTestId,
8+
} from 'react';
29
import { QRCode } from 'react-qrcode-logo';
310
import styled, { CSSProperties } from 'styled-components';
411
import { THEME_GLOBALS } from '../themes/globals';
@@ -13,7 +20,7 @@ const StyledQRView = styled(AnimatedFlex)<{
1320
}>`
1421
cursor: pointer;
1522
border-radius: 10px;
16-
overflow: hidden;
23+
overflow: visible; // we need this for overflow buttons to be visible (see UserProfileModal)
1724
${props => props.size && `width: ${props.size}px; height: ${props.size}px;`}
1825
`;
1926

@@ -33,6 +40,7 @@ export type SessionQRCodeProps = {
3340
ariaLabel?: string;
3441
dataTestId?: SessionDataTestId;
3542
style?: CSSProperties;
43+
children?: ReactNode;
3644
};
3745

3846
export function SessionQRCode(props: SessionQRCodeProps) {
@@ -50,6 +58,7 @@ export function SessionQRCode(props: SessionQRCodeProps) {
5058
ariaLabel,
5159
dataTestId,
5260
style,
61+
children,
5362
} = props;
5463
const [logo, setLogo] = useState(logoImage);
5564
const [bgColor, setBgColor] = useState(backgroundColor);
@@ -144,6 +153,7 @@ export function SessionQRCode(props: SessionQRCodeProps) {
144153
height: size,
145154
}}
146155
/>
156+
{children}
147157
</StyledQRView>
148158
);
149159
}

ts/components/SessionWrapperModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export const ModalActionsContainer = ({
159159
};
160160

161161
export type SessionWrapperModalType = {
162-
headerChildren: ReactNode | null;
162+
headerChildren: ReactNode;
163163
children: ReactNode;
164164
/**
165165
* *Should* be some SessionButtons enclosed in a ModalActionsContainer

ts/components/avatar/Avatar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export enum AvatarSize {
2323
M = 48,
2424
L = 80,
2525
XL = 110,
26-
HUGE = 300,
26+
HUGE = 190,
2727
}
2828

2929
type Props = {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import styled from 'styled-components';
2+
import { tr } from '../../localization/localeTools';
3+
4+
const StyledPillDividerLine = styled.div`
5+
border-bottom: 1px solid var(--border-color);
6+
line-height: 0.1rem;
7+
flex-grow: 1;
8+
height: 1px;
9+
align-self: center;
10+
`;
11+
12+
const StyledPillSpan = styled.span`
13+
padding: 6px 15px 5px;
14+
border-radius: 50px;
15+
color: var(--text-secondary-color);
16+
border: 1px solid var(--border-color);
17+
`;
18+
19+
const StyledPillDivider = styled.div`
20+
width: 100%;
21+
text-align: center;
22+
display: flex;
23+
margin: 0;
24+
`;
25+
26+
export const AccountIdPill = ({ accountType }: { accountType: 'ours' | 'theirs' | 'blinded' }) => {
27+
return (
28+
<StyledPillDivider data-testid="account-id-pill">
29+
<StyledPillDividerLine />
30+
<StyledPillSpan>
31+
{tr(
32+
accountType === 'blinded'
33+
? 'blindedId'
34+
: accountType === 'ours'
35+
? 'accountIdYours'
36+
: 'accountId'
37+
)}
38+
</StyledPillSpan>
39+
<StyledPillDividerLine />
40+
</StyledPillDivider>
41+
);
42+
};
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { ReactNode, SessionDataTestId, CSSProperties } from 'react';
2+
import styled from 'styled-components';
3+
import { PubKey } from '../../session/types';
4+
5+
const StyledSessionIDNotEditable = styled.div`
6+
display: flex;
7+
gap: var(--margins-sm);
8+
user-select: none;
9+
text-align: center;
10+
word-break: break-all;
11+
font-weight: 400;
12+
font-size: var(--font-size-md);
13+
color: var(--text-secondary-color);
14+
flex-shrink: 0;
15+
font-family: var(--font-mono);
16+
17+
.session-id-tooltip {
18+
font-family: var(--font-default);
19+
font-size: var(--font-size-sm);
20+
}
21+
`;
22+
23+
export const SessionIDNotEditable = ({
24+
sessionId,
25+
dataTestId,
26+
tooltipNode,
27+
displayType,
28+
style: providedStyle = {},
29+
}: {
30+
sessionId: string;
31+
tooltipNode: ReactNode;
32+
displayType: 'blinded' | '2lines' | '3lines';
33+
dataTestId: SessionDataTestId;
34+
style: CSSProperties;
35+
}) => {
36+
if (sessionId.length !== 66) {
37+
throw new Error('Unsupported case for SessionIDNotEditable: sessionId.length !== 66');
38+
}
39+
if (PubKey.isBlinded(sessionId) && displayType !== 'blinded') {
40+
throw new Error('Unsupported case for SessionIDNotEditable: sessionId is blinded');
41+
}
42+
43+
const style = tooltipNode ? { ...providedStyle, marginLeft: 'var(--margins-lg)' } : providedStyle;
44+
45+
if (displayType === 'blinded') {
46+
const shortenedSessionId = PubKey.shorten(sessionId, {
47+
keepCharacters: 12,
48+
withParenthesis: false,
49+
});
50+
51+
return (
52+
<StyledSessionIDNotEditable
53+
data-testid={dataTestId}
54+
// Note: we want the text centered even if the tooltip is offsetting it
55+
style={style}
56+
>
57+
{shortenedSessionId}
58+
{tooltipNode}
59+
</StyledSessionIDNotEditable>
60+
);
61+
}
62+
63+
if (displayType === '3lines') {
64+
const firstLine = sessionId.slice(0, 27);
65+
const secondLine = sessionId.slice(27, 54);
66+
const thirdLine = sessionId.slice(54);
67+
return (
68+
<StyledSessionIDNotEditable
69+
data-testid={dataTestId} // Note: we want the text centered even if the tooltip is offsetting it
70+
style={style}
71+
>
72+
{firstLine}
73+
<br />
74+
{secondLine}
75+
<br />
76+
{thirdLine}
77+
{tooltipNode}
78+
</StyledSessionIDNotEditable>
79+
);
80+
}
81+
82+
return (
83+
<StyledSessionIDNotEditable data-testid={dataTestId} style={style}>
84+
{sessionId.slice(0, 33)}
85+
<br />
86+
{sessionId.slice(33)}
87+
</StyledSessionIDNotEditable>
88+
);
89+
};

ts/components/basic/YourSessionIDPill.tsx

Lines changed: 0 additions & 65 deletions
This file was deleted.

ts/components/buttons/CopyToClipboardButton.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { isEmpty } from 'lodash';
22
import { useState } from 'react';
33
import { clipboard } from 'electron';
4+
import useTimeoutFn from 'react-use/lib/useTimeoutFn';
5+
46
import { useHotkey } from '../../hooks/useHotkey';
57
import { ToastUtils } from '../../session/utils';
68
import { SessionButton, SessionButtonProps } from '../basic/SessionButton';
79
import { SessionIconButtonProps, SessionLucideIconButton } from '../icon/SessionIconButton';
810
import { LUCIDE_ICONS_UNICODE } from '../icon/lucide';
911
import type { SessionIconSize } from '../icon';
1012
import { tr } from '../../localization/localeTools';
13+
import { DURATION } from '../../session/constants';
1114

1215
type CopyProps = {
1316
copyContent?: string;
@@ -21,6 +24,14 @@ export const CopyToClipboardButton = (props: CopyToClipboardButtonProps) => {
2124
const { copyContent, onCopyComplete, hotkey = false, text } = props;
2225
const [copied, setCopied] = useState(false);
2326

27+
// reset the copied state after 5 seconds
28+
useTimeoutFn(
29+
() => {
30+
setCopied(false);
31+
},
32+
copied ? 5 * DURATION.SECONDS : 0
33+
);
34+
2435
const onClick = () => {
2536
try {
2637
const toCopy = copyContent || text;

ts/components/buttons/PlusAvatarButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const PlusAvatarButton = ({
2020
padding={'var(--margins-xxs)'}
2121
style={{
2222
position: 'absolute',
23-
bottom: '0',
23+
bottom: '3%',
2424
insetInlineEnd: 0,
2525
boxShadow: '0px 0px 3px 2px var(--border-color)',
2626
}}

0 commit comments

Comments
 (0)