Add translations

This commit is contained in:
Nicola Benaglia 2025-05-19 23:35:05 +02:00
parent 253370a050
commit d00265d878
16 changed files with 211 additions and 57 deletions

View File

@ -1697,10 +1697,11 @@ function App() {
style={{ style={{
fontSize: '14px', fontSize: '14px',
fontWeight: 700, fontWeight: 700,
textTransform: 'uppercase',
}} }}
> >
{t('core:user_lookup')} {t('core:user_lookup', {
postProcess: 'capitalizeAll',
})}
</span> </span>
} }
placement="left" placement="left"

View File

@ -40,6 +40,7 @@ const TabComponent = ({ isSelected, app }) => {
}} }}
/> />
)} )}
{app?.isPrivate && !app?.privateAppProperties?.logo ? ( {app?.isPrivate && !app?.privateAppProperties?.logo ? (
<LockIcon <LockIcon
sx={{ sx={{

View File

@ -249,6 +249,7 @@ export const GroupAvatar = ({
); );
}; };
// TODO the following part is the same as in MainAvatar.tsx
const PopoverComp = ({ const PopoverComp = ({
avatarFile, avatarFile,
setAvatarFile, setAvatarFile,

View File

@ -34,20 +34,20 @@ export const DesktopSideBar = ({
<Box <Box
sx={{ sx={{
alignItems: 'center', alignItems: 'center',
backgroundColor: theme.palette.background.surface,
borderRight: `1px solid ${theme.palette.border.subtle}`,
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: '25px', gap: '25px',
height: '100vh', height: '100vh',
width: '60px', width: '60px',
backgroundColor: theme.palette.background.surface,
borderRight: `1px solid ${theme.palette.border.subtle}`,
}} }}
> >
<ButtonBase <ButtonBase
sx={{ sx={{
width: '70px',
height: '70px', height: '70px',
paddingTop: '23px', paddingTop: '23px',
width: '70px',
}} }}
> >
<CoreSyncStatus /> <CoreSyncStatus />
@ -55,8 +55,8 @@ export const DesktopSideBar = ({
<ButtonBase <ButtonBase
sx={{ sx={{
width: '60px',
height: '60px', height: '60px',
width: '60px',
}} }}
onClick={() => { onClick={() => {
goToHome(); goToHome();

View File

@ -593,6 +593,7 @@ export const AddGroup = ({ address, open, setOpen }) => {
</Box> </Box>
</Box> </Box>
)} )}
{value === 1 && ( {value === 1 && (
<Box <Box
sx={{ sx={{

View File

@ -41,9 +41,7 @@ const cache = new CellMeasurerCache({
export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => { export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
const { show } = useContext(MyContext); const { show } = useContext(MyContext);
const [memberGroups] = useAtom(memberGroupsAtom); const [memberGroups] = useAtom(memberGroupsAtom);
const setTxList = useSetAtom(txListAtom); const setTxList = useSetAtom(txListAtom);
const { t } = useTranslation(['auth', 'core', 'group']); const { t } = useTranslation(['auth', 'core', 'group']);
const [groups, setGroups] = useState([]); const [groups, setGroups] = useState([]);
const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to
@ -189,7 +187,11 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
.catch((error) => { .catch((error) => {
setInfoSnack({ setInfoSnack({
type: 'error', type: 'error',
message: error.message || 'An error occurred', message:
error.message ||
t('core:message.error.generic', {
postProcess: 'capitalizeFirst',
}),
}); });
setOpenSnack(true); setOpenSnack(true);
rej(error); rej(error);
@ -248,10 +250,14 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
})}{' '} })}{' '}
{group?.groupName} {group?.groupName}
</Typography> </Typography>
<Typography> <Typography>
{group?.isOpen === false && {group?.isOpen === false &&
'This is a closed/private group, so you will need to wait until an admin accepts your request'} t('group:message.generic.closed_group', {
postProcess: 'capitalizeFirstChar',
})}
</Typography> </Typography>
<LoadingButton <LoadingButton
loading={isLoading} loading={isLoading}
loadingPosition="start" loadingPosition="start"
@ -264,6 +270,7 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
</LoadingButton> </LoadingButton>
</Box> </Box>
</Popover> </Popover>
<ListItemButton <ListItemButton
onClick={(event) => handlePopoverOpen(event, index)} onClick={(event) => handlePopoverOpen(event, index)}
> >
@ -274,6 +281,7 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
}} }}
/> />
)} )}
{group?.isOpen === true && ( {group?.isOpen === true && (
<NoEncryptionGmailerrorredIcon <NoEncryptionGmailerrorredIcon
sx={{ sx={{
@ -281,7 +289,9 @@ export const AddGroupList = ({ setInfoSnack, setOpenSnack }) => {
}} }}
/> />
)} )}
<Spacer width="15px" /> <Spacer width="15px" />
<ListItemText <ListItemText
primary={group?.groupName} primary={group?.groupName}
secondary={group?.description} secondary={group?.description}

View File

@ -24,13 +24,14 @@ import { useModal } from '../../common/useModal';
import { isOpenBlockedModalAtom } from '../../atoms/global'; import { isOpenBlockedModalAtom } from '../../atoms/global';
import InfoIcon from '@mui/icons-material/Info'; import InfoIcon from '@mui/icons-material/Info';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { useTranslation } from 'react-i18next';
export const BlockedUsersModal = () => { export const BlockedUsersModal = () => {
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation(['auth', 'core', 'group']);
const [isOpenBlockedModal, setIsOpenBlockedModal] = useAtom( const [isOpenBlockedModal, setIsOpenBlockedModal] = useAtom(
isOpenBlockedModalAtom isOpenBlockedModalAtom
); );
const [hasChanged, setHasChanged] = useState(false); const [hasChanged, setHasChanged] = useState(false);
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const [addressesWithNames, setAddressesWithNames] = useState({}); const [addressesWithNames, setAddressesWithNames] = useState({});
@ -95,7 +96,12 @@ export const BlockedUsersModal = () => {
if (!isAddress) { if (!isAddress) {
const response = await fetch(`${getBaseApiReact()}/names/${valUser}`); const response = await fetch(`${getBaseApiReact()}/names/${valUser}`);
const data = await response.json(); const data = await response.json();
if (!data?.owner) throw new Error('Name does not exist'); if (!data?.owner)
throw new Error(
t('auth:message.error.name_not_existing', {
postProcess: 'capitalizeFirst',
})
);
if (data?.owner) { if (data?.owner) {
userAddress = data.owner; userAddress = data.owner;
userName = valUser; userName = valUser;

View File

@ -271,6 +271,7 @@ export const GroupMail = ({
}, },
[allThreads, isPrivate] [allThreads, isPrivate]
); );
const getMailMessages = useCallback( const getMailMessages = useCallback(
async (groupId: string, members: any) => { async (groupId: string, members: any) => {
try { try {
@ -385,7 +386,6 @@ export const GroupMail = ({
}, [getMailMessages, groupId, members, secretKey, isPrivate]); }, [getMailMessages, groupId, members, secretKey, isPrivate]);
const interval = useRef<any>(null); const interval = useRef<any>(null);
const firstMount = useRef(false); const firstMount = useRef(false);
const filterModeRef = useRef(''); const filterModeRef = useRef('');
@ -575,6 +575,7 @@ export const GroupMail = ({
}} }}
> >
<InstanceListHeader /> <InstanceListHeader />
<InstanceListContainer> <InstanceListContainer>
{filterOptions?.map((filter) => { {filterOptions?.map((filter) => {
return ( return (
@ -796,6 +797,7 @@ export const GroupMail = ({
postProcess: 'capitalizeFirstChar', postProcess: 'capitalizeFirstChar',
})} })}
</Typography> </Typography>
<ArrowForwardIosIcon <ArrowForwardIosIcon
sx={{ sx={{
color: theme.palette.text.primary, color: theme.palette.text.primary,

View File

@ -13,7 +13,6 @@ import {
NewMessageSendButton, NewMessageSendButton,
NewMessageSendP, NewMessageSendP,
} from './Mail-styles'; } from './Mail-styles';
import { ReusableModal } from './ReusableModal'; import { ReusableModal } from './ReusableModal';
import { Spacer } from '../../../common/Spacer'; import { Spacer } from '../../../common/Spacer';
import { CreateThreadIcon } from '../../../assets/Icons/CreateThreadIcon'; import { CreateThreadIcon } from '../../../assets/Icons/CreateThreadIcon';

View File

@ -29,10 +29,10 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
return ( return (
<SingleTheadMessageParent <SingleTheadMessageParent
sx={{ sx={{
height: 'auto',
alignItems: 'flex-start', alignItems: 'flex-start',
cursor: 'default',
borderRadius: '35px 4px 4px 4px', borderRadius: '35px 4px 4px 4px',
cursor: 'default',
height: 'auto',
}} }}
> >
<Box <Box
@ -80,6 +80,7 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => {
{formatTimestampForum(message?.created)} {formatTimestampForum(message?.created)}
</ThreadInfoColumnTime> </ThreadInfoColumnTime>
</ThreadInfoColumn> </ThreadInfoColumn>
<div <div
style={{ style={{
display: 'flex', display: 'flex',

View File

@ -278,12 +278,14 @@ export const Thread = ({
const urlNewer = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=1&includemetadata=false&reverse=false&prefix=true&before=${ const urlNewer = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=1&includemetadata=false&reverse=false&prefix=true&before=${
fullArrayMsg[0].created fullArrayMsg[0].created
}`; }`;
const responseNewer = await fetch(urlNewer, { const responseNewer = await fetch(urlNewer, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
}); });
const responseDataNewer = await responseNewer.json(); const responseDataNewer = await responseNewer.json();
if (responseDataNewer.length > 0) { if (responseDataNewer.length > 0) {
setHasFirstPage(true); setHasFirstPage(true);
@ -296,12 +298,14 @@ export const Thread = ({
const urlOlder = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=1&includemetadata=false&reverse=false&prefix=true&after=${ const urlOlder = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=1&includemetadata=false&reverse=false&prefix=true&after=${
fullArrayMsg[fullArrayMsg.length - 1].created fullArrayMsg[fullArrayMsg.length - 1].created
}`; }`;
const responseOlder = await fetch(urlOlder, { const responseOlder = await fetch(urlOlder, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
}); });
const responseDataOlder = await responseOlder.json(); const responseDataOlder = await responseOlder.json();
if (responseDataOlder.length > 0) { if (responseDataOlder.length > 0) {
setHasLastPage(true); setHasLastPage(true);
@ -321,6 +325,7 @@ export const Thread = ({
}, },
[messages, secretKey] [messages, secretKey]
); );
const getMessages = useCallback(async () => { const getMessages = useCallback(async () => {
if ( if (
!currentThread || !currentThread ||
@ -337,6 +342,7 @@ export const Thread = ({
groupInfo?.groupId, groupInfo?.groupId,
isPrivate, isPrivate,
]); ]);
const firstMount = useRef(false); const firstMount = useRef(false);
const saveTimestamp = useCallback((currentThread: any, username?: string) => { const saveTimestamp = useCallback((currentThread: any, username?: string) => {
@ -613,6 +619,7 @@ export const Thread = ({
})} })}
</ComposeP> </ComposeP>
</ShowMessageReturnButton> </ShowMessageReturnButton>
{/* Conditionally render the scroll buttons */} {/* Conditionally render the scroll buttons */}
{showScrollButton && {showScrollButton &&
(isAtBottom ? ( (isAtBottom ? (

View File

@ -68,16 +68,26 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
const publishAvatar = async () => { const publishAvatar = async () => {
try { try {
// TODO translate
const fee = await getFee('ARBITRARY'); const fee = await getFee('ARBITRARY');
if (+balance < +fee.fee) if (+balance < +fee.fee)
throw new Error(`Publishing an Avatar requires ${fee.fee}`); throw new Error(
t('core:message.generic.avatar_publish_fee', {
fee: fee.fee,
postProcess: 'capitalizeFirstChar',
})
);
await show({ await show({
message: 'Would you like to publish an avatar?', message: t('core:message.question.publish_avatar', {
postProcess: 'capitalizeFirstChar',
}),
publishFee: fee.fee + ' QORT', publishFee: fee.fee + ' QORT',
}); });
setIsLoading(true); setIsLoading(true);
const avatarBase64 = await fileToBase64(avatarFile); const avatarBase64 = await fileToBase64(avatarFile);
await new Promise((res, rej) => { await new Promise((res, rej) => {
window window
.sendMessage('publishOnQDN', { .sendMessage('publishOnQDN', {
@ -93,7 +103,12 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
rej(response.error); rej(response.error);
}) })
.catch((error) => { .catch((error) => {
rej(error.message || 'An error occurred'); rej(
error.message ||
t('core:message.error.generic', {
postProcess: 'capitalizeFirst',
})
);
}); });
}); });
setAvatarFile(null); setAvatarFile(null);
@ -125,6 +140,7 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
> >
{myName?.charAt(0)} {myName?.charAt(0)}
</Avatar> </Avatar>
<ButtonBase onClick={handleChildClick}> <ButtonBase onClick={handleChildClick}>
<Typography <Typography
sx={{ sx={{
@ -132,9 +148,12 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
opacity: 0.5, opacity: 0.5,
}} }}
> >
change avatar {t('core:action.change_avatar', {
postProcess: 'capitalizeFirstChar',
})}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<PopoverComp <PopoverComp
myName={myName} myName={myName}
avatarFile={avatarFile} avatarFile={avatarFile}
@ -163,6 +182,7 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
> >
{myName?.charAt(0)} {myName?.charAt(0)}
</Avatar> </Avatar>
<ButtonBase onClick={handleChildClick}> <ButtonBase onClick={handleChildClick}>
<Typography <Typography
sx={{ sx={{
@ -170,9 +190,12 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
opacity: 0.5, opacity: 0.5,
}} }}
> >
change avatar {t('core:action.change_avatar', {
postProcess: 'capitalizeFirstChar',
})}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<PopoverComp <PopoverComp
myName={myName} myName={myName}
avatarFile={avatarFile} avatarFile={avatarFile}
@ -198,9 +221,10 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
opacity: 0.5, opacity: 0.5,
}} }}
> >
set avatar {t('core:action.set_avatar', { postProcess: 'capitalizeFirstChar' })}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<PopoverComp <PopoverComp
myName={myName} myName={myName}
avatarFile={avatarFile} avatarFile={avatarFile}
@ -216,6 +240,7 @@ export const MainAvatar = ({ myName, balance, setOpenSnack, setInfoSnack }) => {
); );
}; };
// TODO the following part is the same as in GroupAvatar.tsx
const PopoverComp = ({ const PopoverComp = ({
avatarFile, avatarFile,
setAvatarFile, setAvatarFile,
@ -228,6 +253,8 @@ const PopoverComp = ({
myName, myName,
}) => { }) => {
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation(['auth', 'core', 'group']);
return ( return (
<Popover <Popover
id={id} id={id}
@ -249,13 +276,24 @@ const PopoverComp = ({
fontSize: '12px', fontSize: '12px',
}} }}
> >
(500 KB max. for GIFS){' '} {t('core:message.generic.avatar_size', {
size: 500, // TODO magic number
postProcess: 'capitalizeFirstChar',
})}
</Typography> </Typography>
<ImageUploader onPick={(file) => setAvatarFile(file)}> <ImageUploader onPick={(file) => setAvatarFile(file)}>
<Button variant="contained">Choose Image</Button> <Button variant="contained">
{t('core:action.choose_image', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
</ImageUploader> </ImageUploader>
{avatarFile?.name} {avatarFile?.name}
<Spacer height="25px" /> <Spacer height="25px" />
{!myName && ( {!myName && (
<Box <Box
sx={{ sx={{
@ -270,19 +308,24 @@ const PopoverComp = ({
}} }}
/> />
<Typography> <Typography>
A registered name is required to set an avatar {t('core:message.generic.avatar_registered_name', {
postProcess: 'capitalizeFirstChar',
})}
</Typography> </Typography>
</Box> </Box>
)} )}
<Spacer height="25px" /> <Spacer height="25px" />
<LoadingButton <LoadingButton
loading={isLoading} loading={isLoading}
disabled={!avatarFile || !myName} disabled={!avatarFile || !myName}
onClick={publishAvatar} onClick={publishAvatar}
variant="contained" variant="contained"
> >
Publish avatar {t('group:action.publish_avatar', {
postProcess: 'capitalizeFirstChar',
})}
</LoadingButton> </LoadingButton>
</Box> </Box>
</Popover> </Popover>

View File

@ -33,6 +33,7 @@ import {
unsubscribeFromEvent, unsubscribeFromEvent,
} from '../../utils/events'; } from '../../utils/events';
import { useNameSearch } from '../../hooks/useNameSearch'; import { useNameSearch } from '../../hooks/useNameSearch';
import { useTranslation } from 'react-i18next';
function formatAddress(str) { function formatAddress(str) {
if (str.length <= 12) return str; if (str.length <= 12) return str;
@ -45,6 +46,7 @@ function formatAddress(str) {
export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => { export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation(['auth', 'core', 'group']);
const [nameOrAddress, setNameOrAddress] = useState(''); const [nameOrAddress, setNameOrAddress] = useState('');
const [inputValue, setInputValue] = useState(''); const [inputValue, setInputValue] = useState('');
const { results, isLoading } = useNameSearch(inputValue); const { results, isLoading } = useNameSearch(inputValue);
@ -64,13 +66,27 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
const inputAddressOrName = messageAddressOrName || nameOrAddress; const inputAddressOrName = messageAddressOrName || nameOrAddress;
if (!inputAddressOrName?.trim()) if (!inputAddressOrName?.trim())
throw new Error('Please insert a name or address'); throw new Error(
t('auth:action.insert_name_address', {
postProcess: 'capitalizeFirst',
})
);
const owner = await getNameOrAddress(inputAddressOrName); const owner = await getNameOrAddress(inputAddressOrName);
if (!owner) throw new Error('Name does not exist'); if (!owner)
throw new Error(
t('auth:message.error.name_not_existing', {
postProcess: 'capitalizeFirst',
})
);
const addressInfoRes = await getAddressInfo(owner); const addressInfoRes = await getAddressInfo(owner);
if (!addressInfoRes?.publicKey) { if (!addressInfoRes?.publicKey) {
throw new Error('Address does not exist on blockchain'); throw new Error(
t('auth:message.error.address_not_existing', {
postProcess: 'capitalizeFirst',
})
);
} }
const name = await getNameInfo(owner); const name = await getNameInfo(owner);
@ -175,7 +191,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
autoFocus autoFocus
autoComplete="off" autoComplete="off"
{...params} {...params}
label="Address or Name" label={t('auth:address_name', {
postProcess: 'capitalizeFirst',
})}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === 'Enter' && nameOrAddress) { if (e.key === 'Enter' && nameOrAddress) {
lookupFunc(inputValue); lookupFunc(inputValue);
@ -200,6 +218,7 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
/> />
</ButtonBase> </ButtonBase>
</Box> </Box>
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
@ -220,6 +239,7 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
<Typography>{errorMessage}</Typography> <Typography>{errorMessage}</Typography>
</Box> </Box>
)} )}
{isLoadingUser && ( {isLoadingUser && (
<Box <Box
sx={{ sx={{
@ -236,6 +256,7 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
/> />
</Box> </Box>
)} )}
{!isLoadingUser && addressInfo && ( {!isLoadingUser && addressInfo && (
<> <>
<Spacer height="30px" /> <Spacer height="30px" />
@ -265,7 +286,10 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
textAlign: 'center', textAlign: 'center',
}} }}
> >
{addressInfo?.name ?? 'Name not registered'} {addressInfo?.name ??
t('auth:message.error.name_not_registered', {
postProcess: 'capitalizeFirst',
})}
</Typography> </Typography>
<Spacer height="20px" /> <Spacer height="20px" />
@ -307,7 +331,8 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
textAlign: 'center', textAlign: 'center',
}} }}
> >
Level {addressInfo?.level} {t('core:level', { postProcess: 'capitalizeFirst' })}{' '}
{addressInfo?.level}
</Typography> </Typography>
</Card> </Card>
@ -336,8 +361,11 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
flexShrink: 0, flexShrink: 0,
}} }}
> >
<Typography>Address</Typography> <Typography>
{t('auth:address', { postProcess: 'capitalizeFirst' })}
</Typography>
</Box> </Box>
<Tooltip <Tooltip
title={ title={
<span <span
@ -347,7 +375,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
fontWeight: 700, fontWeight: 700,
}} }}
> >
copy address {t('auth:action.copy_address', {
postProcess: 'capitalizeFirst',
})}
</span> </span>
} }
placement="bottom" placement="bottom"
@ -391,7 +421,10 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
width: '100%', width: '100%',
}} }}
> >
<Typography>Balance</Typography> <Typography>
{t('core:balance', { postProcess: 'capitalizeFirst' })}
</Typography>
<Typography>{addressInfo?.balance}</Typography> <Typography>{addressInfo?.balance}</Typography>
</Box> </Box>
@ -406,7 +439,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
}); });
}} }}
> >
Send QORT {t('core:action.send_qort', {
postProcess: 'capitalizeFirst',
})}
</Button> </Button>
</Card> </Card>
</Box> </Box>
@ -440,7 +475,12 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
padding: '15px', padding: '15px',
}} }}
> >
<Typography>20 most recent payments</Typography> <Typography>
{t('core:message.generic.most_recent_payment', {
count: 20,
postProcess: 'capitalizeFirst',
})}
</Typography>
<Spacer height="20px" /> <Spacer height="20px" />
@ -452,17 +492,29 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
width: '100%', width: '100%',
}} }}
> >
<Typography>No payments</Typography> <Typography>
{t('core:message.generic.no_payments', {
postProcess: 'capitalizeFirst',
})}
</Typography>
</Box> </Box>
)} )}
<Table> <Table>
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell>Sender</TableCell> <TableCell>
<TableCell>Reciver</TableCell> {t('core:sender', { postProcess: 'capitalizeFirst' })}
<TableCell>Amount</TableCell> </TableCell>
<TableCell>Time</TableCell> <TableCell>
{t('core:receiver', { postProcess: 'capitalizeFirst' })}
</TableCell>
<TableCell>
{t('core:amount', { postProcess: 'capitalizeFirst' })}
</TableCell>
<TableCell>
{t('core:time', { postProcess: 'capitalizeFirst' })}
</TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
@ -479,7 +531,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
fontWeight: 700, fontWeight: 700,
}} }}
> >
copy address {t('auth:action.copy_address', {
postProcess: 'capitalizeFirst',
})}
</span> </span>
} }
placement="bottom" placement="bottom"
@ -522,7 +576,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
fontWeight: 700, fontWeight: 700,
}} }}
> >
copy address {t('auth:action.copy_address', {
postProcess: 'capitalizeFirst',
})}
</span> </span>
} }
placement="bottom" placement="bottom"
@ -552,7 +608,9 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
</ButtonBase> </ButtonBase>
</Tooltip> </Tooltip>
</TableCell> </TableCell>
<TableCell>{payment?.amount}</TableCell> <TableCell>{payment?.amount}</TableCell>
<TableCell> <TableCell>
{formatTimestamp(payment?.timestamp)} {formatTimestamp(payment?.timestamp)}
</TableCell> </TableCell>

View File

@ -10,9 +10,11 @@ import { executeEvent } from '../utils/events';
import { MyContext } from '../App'; import { MyContext } from '../App';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { isRunningPublicNodeAtom } from '../atoms/global'; import { isRunningPublicNodeAtom } from '../atoms/global';
import { useTranslation } from 'react-i18next';
export const WrapperUserAction = ({ children, address, name, disabled }) => { export const WrapperUserAction = ({ children, address, name, disabled }) => {
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation(['auth', 'core', 'group']);
const [isRunningPublicNode] = useAtom(isRunningPublicNodeAtom); const [isRunningPublicNode] = useAtom(isRunningPublicNodeAtom);
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
@ -96,7 +98,7 @@ export const WrapperUserAction = ({ children, address, name, disabled }) => {
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
Message {t('core:message.message', { postProcess: 'capitalizeFirst' })}
</Button> </Button>
{/* Option 2: Send QORT */} {/* Option 2: Send QORT */}
@ -114,8 +116,11 @@ export const WrapperUserAction = ({ children, address, name, disabled }) => {
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
Send QORT {t('core:action.send_qort', {
postProcess: 'capitalizeFirst',
})}
</Button> </Button>
<Button <Button
variant="text" variant="text"
onClick={() => { onClick={() => {
@ -127,8 +132,11 @@ export const WrapperUserAction = ({ children, address, name, disabled }) => {
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
Copy address {t('auth:action.copy_address', {
postProcess: 'capitalizeFirst',
})}
</Button> </Button>
<Button <Button
variant="text" variant="text"
onClick={() => { onClick={() => {
@ -142,7 +150,9 @@ export const WrapperUserAction = ({ children, address, name, disabled }) => {
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
User lookup {t('core:user_lookup', {
postProcess: 'capitalizeFirst',
})}
</Button> </Button>
{!isRunningPublicNode && ( {!isRunningPublicNode && (
@ -165,6 +175,7 @@ const BlockUser = ({ address, name, handleClose }) => {
const { isUserBlocked, addToBlockList, removeBlockFromList } = const { isUserBlocked, addToBlockList, removeBlockFromList } =
useContext(MyContext); useContext(MyContext);
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation(['auth', 'core', 'group']);
useEffect(() => { useEffect(() => {
if (!address) return; if (!address) return;
@ -180,12 +191,6 @@ const BlockUser = ({ address, name, handleClose }) => {
executeEvent('blockUserFromOutside', { executeEvent('blockUserFromOutside', {
user: address, user: address,
}); });
// if(isAlreadyBlocked === true){
// await removeBlockFromList(address, name)
// } else if(isAlreadyBlocked === false) {
// await addToBlockList(address, name)
// }
// executeEvent('updateChatMessagesWithBlocks', true)
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} finally { } finally {
@ -202,8 +207,9 @@ const BlockUser = ({ address, name, handleClose }) => {
{(isAlreadyBlocked === null || isLoading) && ( {(isAlreadyBlocked === null || isLoading) && (
<CircularProgress color="secondary" size={24} /> <CircularProgress color="secondary" size={24} />
)} )}
{isAlreadyBlocked && 'Unblock name'} {isAlreadyBlocked &&
{isAlreadyBlocked === false && 'Block name'} t('core:action.unblock_name', { postProcess: 'capitalizeFirst' })}
{isAlreadyBlocked === false && t('core:action.block_name', { postProcess: 'capitalizeFirst' })}}
</Button> </Button>
); );
}; };

View File

@ -11,17 +11,21 @@
"seed_phrase": "add seed-phrase" "seed_phrase": "add seed-phrase"
}, },
"authenticate": "authenticate", "authenticate": "authenticate",
"copy_address": "copy address",
"create_account": "create account", "create_account": "create account",
"create_qortal_account": "create your Qortal account by clicking <next>NEXT</next> below.", "create_qortal_account": "create your Qortal account by clicking <next>NEXT</next> below.",
"choose_password": "choose new password", "choose_password": "choose new password",
"download_account": "download account", "download_account": "download account",
"export_seedphrase": "export Seedphrase", "export_seedphrase": "export Seedphrase",
"insert_name_address": "please insert a name or address",
"publish_admin_secret_key": "publish admin secret key", "publish_admin_secret_key": "publish admin secret key",
"publish_group_secret_key": "publish group secret key", "publish_group_secret_key": "publish group secret key",
"reencrypt_key": "re-encrypt key", "reencrypt_key": "re-encrypt key",
"return_to_list": "return to list", "return_to_list": "return to list",
"setup_qortal_account": "set up your Qortal account" "setup_qortal_account": "set up your Qortal account"
}, },
"address": "address",
"address_name": "address or name",
"advanced_users": "for advanced users", "advanced_users": "for advanced users",
"apikey": { "apikey": {
"alternative": "alternative: File select", "alternative": "alternative: File select",
@ -35,10 +39,13 @@
"message": { "message": {
"error": { "error": {
"account_creation": "could not create account.", "account_creation": "could not create account.",
"address_not_existing": "address does not exist on blockchain",
"decrypt_data": "could not decrypt data", "decrypt_data": "could not decrypt data",
"field_not_found_json": "{{ field }} not found in JSON", "field_not_found_json": "{{ field }} not found in JSON",
"incorrect_password": "incorrect password", "incorrect_password": "incorrect password",
"invalid_secret_key": "secretKey is not valid", "invalid_secret_key": "secretKey is not valid",
"name_not_existing": "name does not exist",
"name_not_registered": "name not registered",
"unable_decrypt": "unable to decrypt", "unable_decrypt": "unable to decrypt",
"unable_reencrypt_secret_key": "unable to re-encrypt secret key" "unable_reencrypt_secret_key": "unable to re-encrypt secret key"
}, },

View File

@ -8,6 +8,7 @@
"access_app": "access app", "access_app": "access app",
"backup_account": "backup account", "backup_account": "backup account",
"backup_wallet": "backup wallet", "backup_wallet": "backup wallet",
"block_name": "block name",
"cancel": "cancel", "cancel": "cancel",
"cancel_invitation": "cancel invitation", "cancel_invitation": "cancel invitation",
"change": "change", "change": "change",
@ -70,12 +71,14 @@
"select_app_type": "select App Type", "select_app_type": "select App Type",
"select_category": "select Category", "select_category": "select Category",
"select_name_app": "select Name/App", "select_name_app": "select Name/App",
"send_qort": "send QORT",
"set_avatar": "set avatar", "set_avatar": "set avatar",
"show": "show", "show": "show",
"show_poll": "show poll", "show_poll": "show poll",
"start_minting": "start minting", "start_minting": "start minting",
"start_typing": "start typing here...", "start_typing": "start typing here...",
"transfer_qort": "Transfer QORT", "transfer_qort": "Transfer QORT",
"unblock_name": "unblock name",
"unpin": "unpin", "unpin": "unpin",
"unpin_app": "unpin app", "unpin_app": "unpin app",
"unpin_from_dashboard": "unpin from dashboard", "unpin_from_dashboard": "unpin from dashboard",
@ -86,6 +89,7 @@
"admin": "admin", "admin": "admin",
"admin_other": "admins", "admin_other": "admins",
"all": "all", "all": "all",
"amount": "amount",
"announcement": "announcement", "announcement": "announcement",
"announcement_other": "announcements", "announcement_other": "announcements",
"api": "API", "api": "API",
@ -96,6 +100,7 @@
"apps_dashboard": "apps Dashboard", "apps_dashboard": "apps Dashboard",
"apps_official": "official Apps", "apps_official": "official Apps",
"attachment": "attachment", "attachment": "attachment",
"balance": "balance",
"category": "category", "category": "category",
"category_other": "categories", "category_other": "categories",
"chat": "chat", "chat": "chat",
@ -194,6 +199,7 @@
"foreign_fee": "foreign fee: {{ message }}", "foreign_fee": "foreign fee: {{ message }}",
"mentioned": "mentioned", "mentioned": "mentioned",
"message_with_image": "this message already has an image", "message_with_image": "this message already has an image",
"most_recent_payment": "{{ count }} most recent payment",
"name_available": "{{ name }} is available", "name_available": "{{ name }} is available",
"name_benefits": "benefits of a name", "name_benefits": "benefits of a name",
"name_checking": "checking if name already exists", "name_checking": "checking if name already exists",
@ -207,6 +213,7 @@
"no_messages": "no messages", "no_messages": "no messages",
"no_minting_details": "cannot view minting details on the gateway", "no_minting_details": "cannot view minting details on the gateway",
"no_notifications": "no new notifications", "no_notifications": "no new notifications",
"no_payments": "no payments",
"no_pinned_changes": "you currently do not have any changes to your pinned apps", "no_pinned_changes": "you currently do not have any changes to your pinned apps",
"no_results": "no results", "no_results": "no results",
"one_app_per_name": "note: Currently, only one App and Website is allowed per Name.", "one_app_per_name": "note: Currently, only one App and Website is allowed per Name.",
@ -236,6 +243,7 @@
"unsaved_changes": "you have unsaved changes to your pinned apps. Save them to QDN.", "unsaved_changes": "you have unsaved changes to your pinned apps. Save them to QDN.",
"updating": "updating" "updating": "updating"
}, },
"message": "message",
"question": { "question": {
"accept_vote_on_poll": "do you accept this VOTE_ON_POLL transaction? POLLS are public!", "accept_vote_on_poll": "do you accept this VOTE_ON_POLL transaction? POLLS are public!",
"logout": "are you sure you would like to logout?", "logout": "are you sure you would like to logout?",
@ -290,6 +298,8 @@
"q_manager": "q-manager", "q_manager": "q-manager",
"q_sandbox": "q-Sandbox" "q_sandbox": "q-Sandbox"
}, },
"receiver": "receiver",
"sender": "sender",
"server": "server", "server": "server",
"settings": "settings", "settings": "settings",
"sort": { "sort": {
@ -311,6 +321,7 @@
"minute_one": "{{count}} minute", "minute_one": "{{count}} minute",
"minute_other": "{{count}} minutes" "minute_other": "{{count}} minutes"
}, },
"time": "time",
"title": "title", "title": "title",
"tutorial": "tutorial", "tutorial": "tutorial",
"user_lookup": "user lookup", "user_lookup": "user lookup",