Skip to content
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

fix(ui): wallet & seedword styling fixes #1146

Merged
merged 14 commits into from
Nov 28, 2024
805 changes: 372 additions & 433 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,52 @@
},
"dependencies": {
"@floating-ui/react": "^0.26.28",
"@sentry/react": "^8.38.0",
"@lottiefiles/dotlottie-react": "^0.10.1",
"@sentry/react": "^8.41.0",
"@tauri-apps/api": "^1",
"emoji-regex": "^10.4.0",
"framer-motion": "^11.11.17",
"framer-motion": "^11.12.0",
"globals": "^15.12.0",
"i18next": "^23.16.5",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.6.2",
"linkify-react": "^4.1.3",
"i18next-http-backend": "^2.7.1",
"linkify-react": "^4.1.4",
"react": "^18.3.1",
"react-dom": "^18.2.0",
"react-hook-form": "^7.53.2",
"react-i18next": "^15.1.1",
"react-i18next": "^15.1.2",
"react-icons": "^5.3.0",
"react-lottie": "^1.2.7",
"socket.io-client": "^4.8.1",
"styled-components": "^6.1.12",
"uuid": "^10.0.0",
"vite-tsconfig-paths": "^5.1.2",
"vite-tsconfig-paths": "^5.1.3",
"zustand": "^5.0.1"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@nabla/vite-plugin-eslint": "^2.0.4",
"@nabla/vite-plugin-eslint": "^2.0.5",
"@sentry/vite-plugin": "^2.22.6",
"@taplo/cli": "^0.7.0",
"@tauri-apps/cli": "^1.6.3",
"@types/eslint__js": "^8.42.3",
"@types/node": "^22.9.0",
"@types/node": "^22.10.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/uuid": "^10.0.0",
"@typescript-eslint/parser": "^8.3.0",
"@vitejs/plugin-react": "^4.3.3",
"@vitejs/plugin-react": "^4.3.4",
"babel-plugin-styled-components": "^2.1.4",
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-i18next": "^6.1.0",
"eslint-plugin-i18next": "^6.1.1",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"prettier": "3.3.3",
"prettier-eslint": "^16.3.0",
"react-qr-code": "^2.0.15",
"typescript": "^5.6.3",
"typescript-eslint": "^8.14.0",
"typescript": "^5.7.2",
"typescript-eslint": "^8.16.0",
"vite": "^5.4.11"
}
}
}
2 changes: 2 additions & 0 deletions src/components/dialogs/SendLogsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export function SendLogsDialog({ onSetReference }: { onSetReference?: (reference
<TextArea
onChange={(e) => setFeedback(e.target.value)}
placeholder={t('your-feedback', { ns: 'settings' })}
minWidth="500px"
minHeight="200px"
value={feedback}
/>
<Typography variant={'p'} color={'red'}>
Expand Down
4 changes: 4 additions & 0 deletions src/components/elements/buttons/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const BaseIconButton = styled.button<StyleProps>`
css`
height: 24px;
width: 24px;
padding: 4px;
svg {
height: 14px;
}
`}
`;

Expand Down
26 changes: 17 additions & 9 deletions src/components/elements/inputs/TextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import styled from 'styled-components';
import styled, { css } from 'styled-components';
import { TextareaHTMLAttributes } from 'react';

const Wrapper = styled.div<{ $minWidth?: number }>`
const Wrapper = styled.div<{ $minWidth?: string; $minHeight?: string }>`
width: 100%;
min-width: ${({ $minWidth }) => $minWidth}px;
min-width: ${({ $minWidth }) => $minWidth};
min-height: ${({ $minHeight }) => $minHeight};
display: flex;
`;
const StyledTextArea = styled.textarea`
min-height: 250px;
const StyledTextArea = styled.textarea<{ $variant?: 'primary' | 'secondary' }>`
width: 100%;
border-radius: 10px;
padding: 10px;
Expand All @@ -23,15 +23,23 @@ const StyledTextArea = styled.textarea`
&::placeholder {
color: ${({ theme }) => theme.palette.text.secondary};
}

${({ $variant }) =>
$variant === 'secondary' &&
css`
box-shadow: none;
`}
`;

interface TextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
minWidth?: number;
minWidth?: string;
minHeight?: string;
variant?: 'primary' | 'secondary';
}
export function TextArea({ minWidth = 500, ...props }: TextAreaProps) {
export function TextArea({ minWidth, minHeight, variant = 'primary', ...props }: TextAreaProps) {
return (
<Wrapper $minWidth={minWidth}>
<StyledTextArea {...props} />
<Wrapper $minWidth={minWidth} $minHeight={minHeight}>
<StyledTextArea $variant={variant} {...props} />
</Wrapper>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const SettingsGroupWrapper = styled.div<{ $advanced?: boolean; $subGroup?
justify-content: center;
gap: 10px;
position: relative;
margin-top: ${({ $subGroup }) => ($subGroup ? '-10px' : '0')};
margin-top: ${({ $subGroup }) => ($subGroup ? '-5px' : '0')};

${({ $advanced }) =>
$advanced &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const MoneroAddressEditor = ({ initialAddress, onApply }: MoneroAddressEditorPro
</>
) : (
<IconButton
size="small"
onClick={(e) => {
e.preventDefault();
copyToClipboard(address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import {
SettingsGroupTitle,
SettingsGroupWrapper,
} from '@app/containers/floating/Settings/components/SettingsGroup.styles';
import { useCopyToClipboard } from '@app/hooks/helpers/useCopyToClipboard';
import { useCallback, useRef, useState } from 'react';
import { invoke } from '@tauri-apps/api/tauri';
import { CircularProgress } from '@app/components/elements/CircularProgress.tsx';
import { IoEyeOffOutline, IoEyeOutline } from 'react-icons/io5';
import { IoCheckmarkOutline, IoCopyOutline, IoEyeOffOutline, IoEyeOutline } from 'react-icons/io5';
import { Stack } from '@app/components/elements/Stack.tsx';
import { useTranslation } from 'react-i18next';

Expand All @@ -15,11 +16,13 @@ import { IconButton } from '@app/components/elements/buttons/IconButton.tsx';
import { useAppStateStore } from '@app/store/appStateStore.ts';

export default function MoneroSeedWordSettings() {
const { copyToClipboard, isCopied } = useCopyToClipboard();
const { t } = useTranslation('settings', { useSuspense: false });
const setError = useAppStateStore((s) => s.setError);
const [showSeedWords, setShowSeedWords] = useState(false);
const [isFetching, setIsFetching] = useState(false);
const [seedWords, setSeedWords] = useState<string[]>([]);
const [copyFetchLoading, setCopyFetchLoading] = useState(false);

const hasFetched = useRef(false);

Expand All @@ -30,6 +33,7 @@ export default function MoneroSeedWordSettings() {
if (mSeedWords) {
setSeedWords(mSeedWords);
hasFetched.current = true;
return mSeedWords;
}
} catch (e) {
const errorMessage = e as unknown as string;
Expand All @@ -41,6 +45,22 @@ export default function MoneroSeedWordSettings() {
setIsFetching(false);
}
}, [setError]);

const handleCopyClick = useCallback(async () => {
// TODO: dedupe from OG seed words again
if (seedWords && hasFetched.current) {
copyToClipboard(seedWords.join(' '));
} else {
setCopyFetchLoading(true);
getSeedWords().then((r) => {
setCopyFetchLoading(false);

if (r?.length) {
copyToClipboard(r.join(' '));
}
});
}
}, [copyToClipboard, getSeedWords, seedWords]);
const toggleSeedWordsVisibility = useCallback(async () => {
if (!hasFetched.current) {
await getSeedWords();
Expand All @@ -66,7 +86,22 @@ export default function MoneroSeedWordSettings() {
</Stack>
</SettingsGroupTitle>

<SeedWords seedWords={seedWords} showSeedWords={showSeedWords && !!seedWords?.length} />
<Stack direction="row" justifyContent="stretch" alignItems="center" style={{ width: '100%' }} gap={10}>
<SeedWords seedWords={seedWords} showSeedWords={showSeedWords && !!seedWords?.length} />
{!showSeedWords && (
<IconButton size="small" onClick={() => handleCopyClick()}>
{!isCopied ? (
copyFetchLoading ? (
<CircularProgress />
) : (
<IoCopyOutline />
)
) : (
<IoCheckmarkOutline />
)}
</IconButton>
)}
</Stack>
</SettingsGroupWrapper>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SquaredButton } from '@app/components/elements/buttons/SquaredButton';
import { TextArea } from '@app/components/elements/inputs/TextArea';

import { Typography } from '@app/components/elements/Typography.tsx';
import styled from 'styled-components';
Expand Down Expand Up @@ -26,12 +27,14 @@ export const WrapperForm = styled.form(() => ({
gap: '10px',
}));

export const StyledTextArea = styled.textarea<{ $hasError: boolean }>(({ $hasError, theme }) => ({
export const StyledTextArea = styled(TextArea)<{ $hasError: boolean }>(({ $hasError, theme }) => ({
backgroundColor: theme.palette.background.default,
width: '100%',
borderRadius: '10px',
border: `1px solid ${$hasError ? theme.palette.error.main : theme.colorsAlpha.darkAlpha[10]}`,
padding: '20px',
padding: '10px',
fontSize: theme.typography.h6.fontSize,
lineHeight: theme.typography.h6.lineHeight,
}));

export const IconContainer = styled.div(({ theme }) => ({
Expand Down Expand Up @@ -82,7 +85,6 @@ export const SeedWordsEdit = ({ seedWords, seedWordsFetching, toggleEdit }: Seed
return newStr !== oldStr;
}, [seedWords, seedWordsValue]);

// await importSeedWords(data.seedWords.split(' '));
const handleApply = useCallback(
(data: { seedWords: string }) => {
if (hasChanges) {
Expand Down Expand Up @@ -132,21 +134,23 @@ export const SeedWordsEdit = ({ seedWords, seedWordsFetching, toggleEdit }: Seed
const { ref: _ref, ...rest } = field;
return (
<StyledTextArea
variant="secondary"
$hasError={!!errors.seedWords}
disabled={seedWordsFetching}
onPaste={handlePaste}
minHeight="80px"
{...rest}
/>
);
}}
/>
<IconContainer>
{!errors.seedWords && (
<IconButton type="submit" disabled={!isDirty}>
<IconButton size="small" type="submit" disabled={!isDirty && !hasChanges}>
<IoCheckmarkOutline />
</IconButton>
)}
<IconButton type="reset">
<IconButton size="small" type="reset">
<IoCloseOutline />
</IconButton>
</IconContainer>
Expand Down
Loading