Add translations

This commit is contained in:
Nicola Benaglia
2025-05-10 11:22:15 +02:00
parent f1d62fe11b
commit 5f602442e4
8 changed files with 104 additions and 69 deletions

View File

@@ -9,20 +9,12 @@ import {
Typography,
useTheme,
} from '@mui/material';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ChatGroup } from '../Chat/ChatGroup';
import { CreateCommonSecret } from '../Chat/CreateCommonSecret';
import { base64ToUint8Array } from '../../qdn/encryption/group-encryption';
import { uint8ArrayToObject } from '../../backgroundFunctions/encryption';
import CampaignIcon from '@mui/icons-material/Campaign';
import { AddGroup } from './AddGroup';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
import CreateIcon from '@mui/icons-material/Create';
import {
AuthenticatedContainerInnerRight,
@@ -52,7 +44,6 @@ import {
import { RequestQueueWithPromise } from '../../utils/queue/queue';
import { WebSocketActive } from './WebsocketActive';
import { useMessageQueue } from '../../MessageQueueContext';
import { ContextMenu } from '../ContextMenu';
import { HomeDesktop } from './HomeDesktop';
import { IconWrapper } from '../Desktop/DesktopFooter';
import { DesktopHeader } from '../Desktop/DesktopHeader';
@@ -63,7 +54,6 @@ import { HubsIcon } from '../../assets/Icons/HubsIcon';
import { MessagingIcon } from '../../assets/Icons/MessagingIcon';
import { formatEmailDate } from './QMailMessages';
import { AdminSpace } from '../Chat/AdminSpace';
import {
addressInfoControllerAtom,
groupAnnouncementsAtom,
@@ -77,9 +67,6 @@ import {
timestampEnterDataAtom,
} from '../../atoms/global';
import { sortArrayByTimestampAndGroupName } from '../../utils/time';
import PersonOffIcon from '@mui/icons-material/PersonOff';
import LockIcon from '@mui/icons-material/Lock';
import NoEncryptionGmailerrorredIcon from '@mui/icons-material/NoEncryptionGmailerrorred';
import { BlockedUsersModal } from './BlockedUsersModal';
import { WalletsAppWrapper } from './WalletsAppWrapper';
import { useTranslation } from 'react-i18next';
@@ -92,6 +79,7 @@ export const getPublishesFromAdmins = async (admins: string[], groupId) => {
groupId
}&exactmatchnames=true&limit=0&reverse=true&${queryString}&prefix=true`;
const response = await fetch(url);
if (!response.ok) {
throw new Error('network error');
}
@@ -100,9 +88,11 @@ export const getPublishesFromAdmins = async (admins: string[], groupId) => {
const filterId = adminData.filter(
(data: any) => data.identifier === `symmetric-qchat-group-${groupId}`
);
if (filterId?.length === 0) {
return false;
}
const sortedData = filterId.sort((a: any, b: any) => {
// Get the most recent date for both a and b
const dateA = a.updated ? new Date(a.updated) : new Date(a.created);
@@ -114,24 +104,18 @@ export const getPublishesFromAdmins = async (admins: string[], groupId) => {
return sortedData[0];
};
interface GroupProps {
myAddress: string;
isFocused: boolean;
userInfo: any;
balance: number;
isFocused: boolean;
myAddress: string;
userInfo: any;
}
export const timeDifferenceForNotificationChats = 900000;
export const requestQueueMemberNames = new RequestQueueWithPromise(5);
export const requestQueueAdminMemberNames = new RequestQueueWithPromise(5);
// const audio = new Audio(chrome.runtime?.getURL("msg-not1.wav"));
export const getGroupAdminsAddress = async (groupNumber: number) => {
// const validApi = await findUsableApi();
const response = await fetch(
`${getBaseApiReact()}/groups/members/${groupNumber}?limit=0&onlyAdmins=true`
);
@@ -422,27 +406,24 @@ export const Group = ({
const [chatMode, setChatMode] = useState('groups');
const [newChat, setNewChat] = useState(false);
const [openSnack, setOpenSnack] = React.useState(false);
const [infoSnack, setInfoSnack] = React.useState(null);
const [isLoadingNotifyAdmin, setIsLoadingNotifyAdmin] = React.useState(false);
const [isLoadingGroups, setIsLoadingGroups] = React.useState(true);
const [isLoadingGroup, setIsLoadingGroup] = React.useState(false);
const [openSnack, setOpenSnack] = useState(false);
const [infoSnack, setInfoSnack] = useState(null);
const [isLoadingNotifyAdmin, setIsLoadingNotifyAdmin] = useState(false);
const [isLoadingGroups, setIsLoadingGroups] = useState(true);
const [isLoadingGroup, setIsLoadingGroup] = useState(false);
const [firstSecretKeyInCreation, setFirstSecretKeyInCreation] =
React.useState(false);
const [groupSection, setGroupSection] = React.useState('home');
useState(false);
const [groupSection, setGroupSection] = useState('home');
const [groupAnnouncements, setGroupAnnouncements] = useAtom(
groupAnnouncementsAtom
);
const [defaultThread, setDefaultThread] = React.useState(null);
const [isOpenDrawer, setIsOpenDrawer] = React.useState(false);
const [defaultThread, setDefaultThread] = useState(null);
const [isOpenDrawer, setIsOpenDrawer] = useState(false);
const setIsOpenBlockedUserModal = useSetAtom(isOpenBlockedModalAtom);
const [hideCommonKeyPopup, setHideCommonKeyPopup] = React.useState(false);
const [isLoadingGroupMessage, setIsLoadingGroupMessage] = React.useState('');
const [drawerMode, setDrawerMode] = React.useState('groups');
const [hideCommonKeyPopup, setHideCommonKeyPopup] = useState(false);
const [isLoadingGroupMessage, setIsLoadingGroupMessage] = useState('');
const [drawerMode, setDrawerMode] = useState('groups');
const setMutedGroups = useSetAtom(mutedGroupsAtom);
const [mobileViewMode, setMobileViewMode] = useState('home');
const [mobileViewModeKeepOpen, setMobileViewModeKeepOpen] = useState('');
const isFocusedRef = useRef(true);
@@ -531,7 +512,10 @@ export const Group = ({
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
});
} catch (error) {
@@ -557,7 +541,10 @@ export const Group = ({
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
});
} catch (error) {
@@ -586,7 +573,10 @@ export const Group = ({
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
});
} catch (error) {
@@ -1106,7 +1096,10 @@ export const Group = ({
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
});
setInfoSnack({

View File

@@ -140,6 +140,7 @@ export const ListOfGroupPromotions = () => {
let data: any[] = [];
const uniqueGroupIds = new Set();
const oneWeekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
const getPromos = responseData?.map(async (promo: any) => {
if (promo?.size < 200 && promo.created > oneWeekAgo) {
const name = await requestQueuePromos.enqueue(async () => {
@@ -241,9 +242,12 @@ export const ListOfGroupPromotions = () => {
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
}); // TODO translate
});
setInfoSnack({
type: 'success',
message:

View File

@@ -61,7 +61,7 @@ export const ListOfInvites = ({
const [openPopoverIndex, setOpenPopoverIndex] = useState(null); // Track which list item has the popover open
const [isLoadingCancelInvite, setIsLoadingCancelInvite] = useState(false);
const { t } = useTranslation(['core', 'group']);
const listRef = useRef();
const listRef = useRef(null);
const getInvites = async (groupId) => {
try {
@@ -91,7 +91,6 @@ export const ListOfInvites = ({
const handleCancelInvitation = async (address) => {
try {
// TODO translate
const fee = await getFee('CANCEL_GROUP_INVITE');
await show({
@@ -101,7 +100,9 @@ export const ListOfInvites = ({
}),
publishFee: fee.fee + ' QORT',
});
setIsLoadingCancelInvite(true);
await new Promise((res, rej) => {
window
.sendMessage('cancelInvitationToGroup', {
@@ -112,8 +113,9 @@ export const ListOfInvites = ({
if (!response?.error) {
setInfoSnack({
type: 'success',
message:
'Successfully canceled invitation. It may take a couple of minutes for the changes to propagate',
message: t('group:message.success.invitation_cancellation', {
postProcess: 'capitalize',
}),
});
setOpenSnack(true);
handlePopoverClose();
@@ -131,7 +133,11 @@ export const ListOfInvites = ({
.catch((error) => {
setInfoSnack({
type: 'error',
message: error.message || 'An error occurred',
message:
error.message ||
t('core:message.error.generic', {
postProcess: 'capitalize',
}),
});
setOpenSnack(true);
rej(error);
@@ -189,7 +195,9 @@ export const ListOfInvites = ({
variant="contained"
onClick={() => handleCancelInvitation(member?.invitee)}
>
Cancel Invitation
{t('core:action.cancel_invitation', {
postProcess: 'capitalize',
})}
</LoadingButton>
</Box>
</Popover>
@@ -207,6 +215,7 @@ export const ListOfInvites = ({
}
/>
</ListItemAvatar>
<ListItemText primary={member?.name || member?.invitee} />
</ListItemButton>
</ListItem>
@@ -218,7 +227,11 @@ export const ListOfInvites = ({
return (
<div>
<p>Invitees list</p>
<p>
{t('group:invitees_list', {
postProcess: 'capitalize',
})}
</p>
<div
style={{
display: 'flex',

View File

@@ -15,11 +15,12 @@ import {
List,
} from 'react-virtualized';
import { getNameInfo } from './Group';
import { getBaseApi, getFee } from '../../background';
import { getFee } from '../../background';
import { LoadingButton } from '@mui/lab';
import { getBaseApiReact } from '../../App';
import { txListAtom } from '../../atoms/global';
import { useAtom } from 'jotai';
import { useTranslation } from 'react-i18next';
export const getMemberInvites = async (groupNumber) => {
const response = await fetch(
@@ -59,11 +60,11 @@ export const ListOfJoinRequests = ({
}) => {
const [invites, setInvites] = useState([]);
const [txList, setTxList] = useAtom(txListAtom);
const [popoverAnchor, setPopoverAnchor] = useState(null); // Track which list item the popover is anchored to
const [openPopoverIndex, setOpenPopoverIndex] = useState(null); // Track which list item has the popover open
const listRef = useRef();
const listRef = useRef(null);
const [isLoadingAccept, setIsLoadingAccept] = useState(false);
const { t } = useTranslation(['core', 'group']);
const getInvites = async (groupId) => {
try {
@@ -93,7 +94,8 @@ export const ListOfJoinRequests = ({
const handleAcceptJoinRequest = async (address) => {
try {
const fee = await getFee('GROUP_INVITE'); // TODO translate
const fee = await getFee('GROUP_INVITE');
await show({
message: t('group:question.perform_transaction', {
action: 'GROUP_INVITE',
@@ -101,7 +103,9 @@ export const ListOfJoinRequests = ({
}),
publishFee: fee.fee + ' QORT',
});
setIsLoadingAccept(true);
await new Promise((res, rej) => {
window
.sendMessage('inviteToGroup', {
@@ -114,19 +118,23 @@ export const ListOfJoinRequests = ({
setIsLoadingAccept(false);
setInfoSnack({
type: 'success',
message:
'Successfully accepted join request. It may take a couple of minutes for the changes to propagate',
message: t('group:message.success,group_join', {
postProcess: 'capitalize',
}),
});
setOpenSnack(true);
handlePopoverClose();
res(response);
setTxList((prev) => [
{
...response,
type: 'join-request-accept',
label: `Accepted join request: awaiting confirmation`,
labelDone: `User successfully joined!`,
label: t('group:message.success,invitation_request', {
postProcess: 'capitalize',
}),
labelDone: t('group:message.success,user_joined', {
postProcess: 'capitalize',
}),
done: false,
groupId,
qortalAddress: address,
@@ -147,13 +155,16 @@ export const ListOfJoinRequests = ({
.catch((error) => {
setInfoSnack({
type: 'error',
message: error?.message || 'An error occurred',
message:
error?.message ||
t('core:message.error.generic', { postProcess: 'capitalize' }),
});
setOpenSnack(true);
rej(error);
});
});
} catch (error) {
console.log(error);
} finally {
setIsLoadingAccept(false);
}
@@ -161,13 +172,15 @@ export const ListOfJoinRequests = ({
const rowRenderer = ({ index, key, parent, style }) => {
const member = invites[index];
const findJoinRequsetInTxList = txList?.find(
const findJoinRequestInTxList = txList?.find(
(tx) =>
tx?.groupId === groupId &&
tx?.qortalAddress === member?.joiner &&
tx?.type === 'join-request-accept'
);
if (findJoinRequsetInTxList) return null;
if (findJoinRequestInTxList) return null;
return (
<CellMeasurer
key={key}
@@ -210,10 +223,11 @@ export const ListOfJoinRequests = ({
variant="contained"
onClick={() => handleAcceptJoinRequest(member?.joiner)}
>
Accept
{t('core:action.accept', { postProcess: 'capitalize' })}
</LoadingButton>
</Box>
</Popover>
<ListItemButton
onClick={(event) => handlePopoverOpen(event, index)}
>
@@ -238,7 +252,7 @@ export const ListOfJoinRequests = ({
return (
<div>
<p>Join request list</p>
<p>{t('core:list.join_request', { postProcess: 'capitalize' })}</p>
<div
style={{
position: 'relative',

View File

@@ -133,7 +133,10 @@ export const Settings = ({ open, setOpen, rawWallet }) => {
rej(response.error);
})
.catch((error) => {
rej(error.message || 'An error occurred');
rej(
error.message ||
t('core:message.error.generic', { postProcess: 'capitalize' })
);
});
});
} catch (error) {

View File

@@ -264,7 +264,7 @@ export const UserListOfInvites = ({
}}
>
<p>
{t('core:invite_list', {
{t('core:list.invite', {
postProcess: 'capitalize',
})}
</p>