From 7cd3d10d67381bed5e9676b16f25d42496b126fb Mon Sep 17 00:00:00 2001 From: Nicola Benaglia Date: Fri, 9 May 2025 21:20:38 +0200 Subject: [PATCH 01/15] Add translations --- public/locales/en/core.json | 3 + public/locales/en/group.json | 11 ++- public/locales/it/group.json | 8 +- src/common/CustomLoader.tsx | 2 +- src/common/CustomSvg.tsx | 29 +++---- src/common/customloader.css | 1 + src/common/useFetchResources.tsx | 2 +- src/components/Group/ListOfBans.tsx | 12 +-- .../Group/ListOfGroupPromotions.tsx | 24 +++--- src/components/Group/ListOfInvites.tsx | 14 ++-- .../Group/ListOfThreadPostsWatched.tsx | 11 +-- src/components/Group/ManageMembers.tsx | 5 +- src/components/Group/QMailMessages.tsx | 13 ++- src/components/Group/Settings.tsx | 79 ++++++++++++++----- src/components/Group/ThingsToDoInitial.tsx | 8 +- src/components/Group/UserListOfInvites.tsx | 51 +++++++++--- src/components/Group/WalletsAppWrapper.tsx | 21 ++--- src/components/Group/useBlockUsers.tsx | 1 + src/components/GroupAvatar.tsx | 2 +- src/components/Loader.tsx | 19 ++--- src/components/MainAvatar.tsx | 2 +- src/components/RegisterName.tsx | 34 ++++---- src/styles/theme-common.ts | 2 + src/styles/theme-dark.ts | 7 ++ src/styles/theme-light.ts | 4 + 25 files changed, 229 insertions(+), 136 deletions(-) diff --git a/public/locales/en/core.json b/public/locales/en/core.json index 33755f1..d39dc42 100644 --- a/public/locales/en/core.json +++ b/public/locales/en/core.json @@ -12,6 +12,7 @@ "continue": "continue", "continue_logout": "continue to logout", "decline": "decline", + "decrypt": "decrypt", "edit": "edit", "export": "export", "import": "import", @@ -38,6 +39,7 @@ "payment": "payment fee", "publish": "publish fee" }, + "general_settings": "general settings", "page": { "last": "last", "first": "first", @@ -45,6 +47,7 @@ "previous": "previous" }, "downloading_qdn": "downloading from QDN", + "invite_list": "invite list", "last_height": "last height", "loading": "loading...", "loading_posts": "loading posts... please wait.", diff --git a/public/locales/en/group.json b/public/locales/en/group.json index 345c6d0..9b9d030 100644 --- a/public/locales/en/group.json +++ b/public/locales/en/group.json @@ -1,7 +1,12 @@ { "action": { "cancel_ban": "cancel ban", + "copy_private_key": "copy private key", "create_group": "create group", + "disable_push_notifications": "disable all push notifications", + "enable_dev_mode": "enable dev mode", + "export_password": "export password", + "export_private_key": "export private key", "find_group": "find group", "join_group": "join group", "invite_member": "invite member", @@ -35,16 +40,20 @@ }, "message": { "generic": { + "descrypt_wallet": "decrypting wallet...", "encryption_key": "the group's first common encryption key is in the process of creation. Please wait a few minutes for it to be retrieved by the network. Checking every 2 minutes...", "group_invited_you": "{{group}} has invited you", "no_display": "nothing to display", "no_selection": "no group selected", "not_part_group": "you are not part of the encrypted group of members. Wait until an admin re-encrypts the keys.", "only_encrypted": "only unencrypted messages will be displayed.", + "private_key_copied": "private key copied", + "secure_place": "keep your private key in a secure place. Do not share!", "setting_group": "setting up group... please wait." }, "error": { "access_name": "cannot send a message without a access to your name", + "descrypt_wallet": "error decrypting wallet {{ :errorMessage }}", "description_required": "please provide a description", "group_info": "cannot access group information", "name_required": "please provide a name", @@ -55,7 +64,7 @@ "group_creation_name": "created group {{group_name}}: awaiting confirmation", "group_creation_label": "created group {{name}}: success!", "group_invite": "successfully invited {{value}}. It may take a couple of minutes for the changes to propagate", - "join_creation": "successfully requested to join group. It may take a couple of minutes for the changes to propagate", + "group_join": "successfully requested to join group. It may take a couple of minutes for the changes to propagate", "group_join_name": "joined group {{group_name}}: awaiting confirmation", "group_join_label": "joined group {{name}}: success!", "loading_threads": "loading threads... please wait.", diff --git a/public/locales/it/group.json b/public/locales/it/group.json index 862496d..5ec0b0b 100644 --- a/public/locales/it/group.json +++ b/public/locales/it/group.json @@ -2,6 +2,8 @@ "action": { "cancel_ban": "annulla ban", "create_group": "crea gruppo", + "disable_push_notifications": "disabilita tutte le notifiche push", + "enable_dev_mode": "enable dev mode", "find_group": "trova gruppo", "join_group": "unisciti al gruppo", "invite_member": "invita membro", @@ -35,6 +37,7 @@ }, "message": { "generic": { + "descrypt_wallet": "decriptazione del wallet...", "encryption_key": "la prima chiave di cifratura comune del gruppo è in fase di creazione. Attendere alcuni minuti affinché venga recuperata dalla rete. Controllo ogni 2 minuti...", "group_invited_you": "{{group}} ti ha invitato", "no_display": "niente da visualizzare", @@ -45,6 +48,7 @@ }, "error": { "access_name": "impossibile inviare un messaggio senza accesso al tuo nome", + "descrypt_wallet": "errore di decriptazione del wallet {{: errorMessage }}", "description_required": "per favore fornisci una descrizione", "group_info": "impossibile accedere alle informazioni del gruppo", "name_required": "per favore fornisci un nome", @@ -55,11 +59,11 @@ "group_creation_name": "gruppo {{group_name}} creato: in attesa di conferma", "group_creation_label": "gruppo {{name}} creato: successo!", "group_invite": "invito inviato con successo a {{value}}. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino", - "join_creation": "richiesta di adesione al gruppo inviata con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino", + "group_join": "richiesta di adesione al gruppo inviata con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino", "group_join_name": "entrato nel gruppo {{group_name}}: in attesa di conferma", "group_join_label": "entrato nel gruppo {{name}}: successo!", "loading_threads": "caricamento thread... attendere prego.", - "unbanned_user": "utente sbannato con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino" + "unbanned_user": "utente riammesso con successo. Potrebbero volerci alcuni minuti affinché le modifiche si propaghino" } } } diff --git a/src/common/CustomLoader.tsx b/src/common/CustomLoader.tsx index d1ae3b2..84dbfac 100644 --- a/src/common/CustomLoader.tsx +++ b/src/common/CustomLoader.tsx @@ -1,6 +1,6 @@ -import React from 'react'; import './customloader.css'; import { Box, useTheme } from '@mui/material'; + export const CustomLoader = () => { const theme = useTheme(); return ( diff --git a/src/common/CustomSvg.tsx b/src/common/CustomSvg.tsx index c1d8f09..fc805a9 100644 --- a/src/common/CustomSvg.tsx +++ b/src/common/CustomSvg.tsx @@ -1,17 +1,14 @@ -import React from 'react'; - export const CustomSvg = ({ src, color = 'black', size = 24 }) => { - return ( - - {src} - - ); - }; - \ No newline at end of file + return ( + + {src} + + ); +}; diff --git a/src/common/customloader.css b/src/common/customloader.css index dd00558..c16d21d 100644 --- a/src/common/customloader.css +++ b/src/common/customloader.css @@ -36,6 +36,7 @@ left: 56px; animation: lds-ellipsis3 0.6s infinite; } + @keyframes lds-ellipsis1 { 0% { transform: scale(0); diff --git a/src/common/useFetchResources.tsx b/src/common/useFetchResources.tsx index 242f418..8e388a7 100644 --- a/src/common/useFetchResources.tsx +++ b/src/common/useFetchResources.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useRef } from 'react'; +import { useCallback } from 'react'; import { resourceDownloadControllerAtom } from '../atoms/global'; import { getBaseApiReact } from '../App'; import { useSetAtom } from 'jotai'; diff --git a/src/components/Group/ListOfBans.tsx b/src/components/Group/ListOfBans.tsx index 355f1d8..0dec68e 100644 --- a/src/components/Group/ListOfBans.tsx +++ b/src/components/Group/ListOfBans.tsx @@ -165,13 +165,13 @@ export const ListOfBans = ({ groupId, setInfoSnack, setOpenSnack, show }) => { > {

{t('group:ban_list', { postProcess: 'capitalize' })}

diff --git a/src/components/Group/ListOfGroupPromotions.tsx b/src/components/Group/ListOfGroupPromotions.tsx index c7c9ecf..d48158b 100644 --- a/src/components/Group/ListOfGroupPromotions.tsx +++ b/src/components/Group/ListOfGroupPromotions.tsx @@ -331,6 +331,7 @@ export const ListOfGroupPromotions = () => { }); setIsLoadingJoinGroup(false); } catch (error) { + console.log(error); } finally { setIsLoadingJoinGroup(false); } @@ -339,30 +340,30 @@ export const ListOfGroupPromotions = () => { return ( setIsExpanded((prev) => !prev)} > @@ -374,6 +375,7 @@ export const ListOfGroupPromotions = () => { Group promotions{' '} {promotions.length > 0 && ` (${promotions.length})`} + {isExpanded ? ( { <> + handlePopoverOpen(event, index)} > @@ -214,12 +216,12 @@ export const ListOfInvites = ({

Invitees list

diff --git a/src/components/Group/ListOfThreadPostsWatched.tsx b/src/components/Group/ListOfThreadPostsWatched.tsx index 1cf0d2a..e3dfac6 100644 --- a/src/components/Group/ListOfThreadPostsWatched.tsx +++ b/src/components/Group/ListOfThreadPostsWatched.tsx @@ -42,10 +42,11 @@ export const ListOfThreadPostsWatched = () => { rej(response.error); }) .catch((error) => { - rej(error.message || 'An error occurred'); // TODO translate + rej(error.message || 'An error occurred'); }); }); } catch (error) { + console.log(error); } finally { setLoading(false); } @@ -58,21 +59,21 @@ export const ListOfThreadPostsWatched = () => { return ( - { try { setIsLoadingLeave(true); - const fee = await getFee('LEAVE_GROUP'); + const fee = await getFee('LEAVE_GROUP'); // TODO translate await show({ message: 'Would you like to perform an LEAVE_GROUP transaction?', publishFee: fee.fee + ' QORT', @@ -109,7 +109,7 @@ export const ManageMembers = ({ rej(response.error); }) .catch((error) => { - rej(error.message || 'An error occurred'); // TODO translate + rej(error.message || 'An error occurred'); }); }); } catch (error) { @@ -139,6 +139,7 @@ export const ManageMembers = ({ console.log(error); } }; + const getGroupInfo = async (groupId) => { try { const response = await fetch(`${getBaseApiReact()}/groups/${groupId}`); diff --git a/src/components/Group/QMailMessages.tsx b/src/components/Group/QMailMessages.tsx index 72a23d5..3d897e3 100644 --- a/src/components/Group/QMailMessages.tsx +++ b/src/components/Group/QMailMessages.tsx @@ -11,7 +11,6 @@ import MailIcon from '@mui/icons-material/Mail'; import MailOutlineIcon from '@mui/icons-material/MailOutline'; import { executeEvent } from '../../utils/events'; import { CustomLoader } from '../../common/CustomLoader'; - import { mailsAtom, qMailLastEnteredTimestampAtom } from '../../atoms/global'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; @@ -89,7 +88,7 @@ export const QMailMessages = ({ userName, userAddress }) => { rej(response.error); }) .catch((error) => { - rej(error.message || 'An error occurred'); // TODO translate + rej(error.message || 'An error occurred'); }); }); } catch (error) { @@ -129,24 +128,24 @@ export const QMailMessages = ({ userName, userAddress }) => { return ( setIsExpanded((prev) => !prev)} > - ({ padding: 8, @@ -87,8 +86,8 @@ const Transition = forwardRef(function Transition( export const Settings = ({ open, setOpen, rawWallet }) => { const [checked, setChecked] = useState(false); const [isEnabledDevMode, setIsEnabledDevMode] = useAtom(enabledDevModeAtom); - const theme = useTheme(); + const { t } = useTranslation(['core', 'group']); const handleChange = (event: ChangeEvent) => { setChecked(event.target.checked); @@ -103,7 +102,7 @@ export const Settings = ({ open, setOpen, rawWallet }) => { if (response?.error) { console.error('Error adding user settings:', response.error); } else { - console.log('User settings added successfully'); // TODO translate + console.log('User settings added successfully'); } }) .catch((error) => { @@ -157,7 +156,9 @@ export const Settings = ({ open, setOpen, rawWallet }) => { - General Settings + {t('core:general_settings', { + postProcess: 'capitalize', + })} { { control={ } - label="Disable all push notifications" + label={t('group:action.disable_push_notifications', { + postProcess: 'capitalize', + })} /> {window?.electronAPI && ( { }} /> } - label="Enable dev mode" + label={t('group:action.enable_dev_mode', { + postProcess: 'capitalize', + })} /> )} {isEnabledDevMode && } @@ -222,11 +227,15 @@ const ExportPrivateKey = ({ rawWallet }) => { const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const { setOpenSnackGlobal, setInfoSnackCustom } = useContext(MyContext); + const { t } = useTranslation(['core', 'group']); + const exportPrivateKeyFunc = async () => { try { setInfoSnackCustom({ type: 'info', - message: 'Decrypting wallet...', + message: t('group:message.generic.descrypt_wallet', { + postProcess: 'capitalize', + }), }); setOpenSnackGlobal(true); @@ -247,13 +256,19 @@ const ExportPrivateKey = ({ rawWallet }) => { setInfoSnackCustom({ type: 'error', message: error?.message - ? `Error decrypting wallet: ${error?.message}` - : 'Error decrypting wallet', + ? t('group:message.error.decrypt_wallet', { + errorMessage: error?.message, + postProcess: 'capitalize', + }) + : t('group:message.error.descrypt_wallet', { + postProcess: 'capitalize', + }), }); setOpenSnackGlobal(true); } }; + return ( <> + - Export password + + {t('group:action.export_password', { + postProcess: 'capitalize', + })} + + { }} > - Keep your private key in a secure place. Do not share! + {t('group:message.generic.secure_place', { + postProcess: 'capitalize', + })} + + { navigator.clipboard.writeText(privateKey); setInfoSnackCustom({ type: 'success', - message: 'Copied privated key', + message: t('group:message.generic.private_key_copied', { + postProcess: 'capitalize', + }), }); setOpenSnackGlobal(true); }} > - {`Copy private key `} + {t('group:action.copy_private_key', { + postProcess: 'capitalize', + })}{' '} )} + + diff --git a/src/components/Group/ThingsToDoInitial.tsx b/src/components/Group/ThingsToDoInitial.tsx index 84c806b..e7cc642 100644 --- a/src/components/Group/ThingsToDoInitial.tsx +++ b/src/components/Group/ThingsToDoInitial.tsx @@ -55,18 +55,18 @@ export const ThingsToDoInitial = ({ return ( + + ([]); const [isLoading, setIsLoading] = useState(false); const theme = useTheme(); + const { t } = useTranslation(['core', 'group']); 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(); @@ -94,9 +96,12 @@ export const UserListOfInvites = ({ const handleJoinGroup = async (groupId, groupName) => { try { - const fee = await getFee('JOIN_GROUP'); // TODO translate + const fee = await getFee('JOIN_GROUP'); + await show({ - message: 'Would you like to perform an JOIN_GROUP transaction?', + message: t('group:question.join_group', { + postProcess: 'capitalize', + }), publishFee: fee.fee + ' QORT', }); @@ -123,8 +128,9 @@ export const UserListOfInvites = ({ res(response); setInfoSnack({ type: 'success', - message: - 'Successfully requested to join group. It may take a couple of minutes for the changes to propagate', + message: t('group:message.success.group_join', { + postProcess: 'capitalize', + }), }); setOpenSnack(true); handlePopoverClose(); @@ -140,13 +146,16 @@ export const UserListOfInvites = ({ .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 { setIsLoading(false); } @@ -182,16 +191,22 @@ export const UserListOfInvites = ({ > - Join {invite?.groupName} + + {t('core:action.join', { + postProcess: 'capitalize', + })}{' '} + {invite?.groupName} + + - Join group + {t('group:action.join_group', { + postProcess: 'capitalize', + })} + handlePopoverOpen(event, index)} > @@ -221,7 +239,9 @@ export const UserListOfInvites = ({ }} /> )} + + -

Invite list

+

+ {t('core:invite_list', { + postProcess: 'capitalize', + })} +

+
diff --git a/src/components/Group/WalletsAppWrapper.tsx b/src/components/Group/WalletsAppWrapper.tsx index 7e44eb6..23faccb 100644 --- a/src/components/Group/WalletsAppWrapper.tsx +++ b/src/components/Group/WalletsAppWrapper.tsx @@ -19,7 +19,6 @@ export const WalletsAppWrapper = () => { const [navigationController, setNavigationController] = useAtom( navigationControllerAtom ); - const [selectedTab, setSelectedTab] = useState({ tabId: '5558589', name: 'Q-Wallets', @@ -60,17 +59,17 @@ export const WalletsAppWrapper = () => { {isOpen && ( { display: 'flex', alignItems: 'center', padding: '5px', - justifyContent: 'space-between', }} > Q-Wallets + { ref={iframeRef} skipAuth={true} /> + { > + { if (selectedTab?.refreshFunc) { diff --git a/src/components/Group/useBlockUsers.tsx b/src/components/Group/useBlockUsers.tsx index e82d0c6..4aa100c 100644 --- a/src/components/Group/useBlockUsers.tsx +++ b/src/components/Group/useBlockUsers.tsx @@ -164,6 +164,7 @@ export const useBlockedAddresses = () => { }); }); } + if (address) { await new Promise((res, rej) => { window diff --git a/src/components/GroupAvatar.tsx b/src/components/GroupAvatar.tsx index 3364b8f..3244d5c 100644 --- a/src/components/GroupAvatar.tsx +++ b/src/components/GroupAvatar.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { useCallback, useContext, useEffect, useState } from 'react'; import Logo2 from '../assets/svgs/Logo2.svg'; import { MyContext, getArbitraryEndpointReact, getBaseApiReact } from '../App'; import { diff --git a/src/components/Loader.tsx b/src/components/Loader.tsx index 8db908e..dadf8fd 100644 --- a/src/components/Loader.tsx +++ b/src/components/Loader.tsx @@ -1,9 +1,9 @@ -import React from 'react' -import { Box, CircularProgress } from "@mui/material"; +import { Box, CircularProgress } from '@mui/material'; export const Loader = () => { return ( - { height: '100%', position: 'fixed', top: '0px', - left:'0px', + left: '0px', right: '0px', bottom: '0px', zIndex: 10, - background: 'rgba(0, 0, 0, 0.4)' - }}> - + background: 'rgba(0, 0, 0, 0.4)', + }} + > + - ) -} + ); +}; diff --git a/src/components/MainAvatar.tsx b/src/components/MainAvatar.tsx index 04d7172..10370de 100644 --- a/src/components/MainAvatar.tsx +++ b/src/components/MainAvatar.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import Logo2 from '../assets/svgs/Logo2.svg'; import { MyContext, getArbitraryEndpointReact, getBaseApiReact } from '../App'; import { diff --git a/src/components/RegisterName.tsx b/src/components/RegisterName.tsx index 4b52a45..adb8198 100644 --- a/src/components/RegisterName.tsx +++ b/src/components/RegisterName.tsx @@ -1,33 +1,22 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { - Avatar, Box, Button, - ButtonBase, - Collapse, Dialog, DialogActions, DialogContent, - DialogContentText, DialogTitle, - Input, ListItem, - ListItemAvatar, - ListItemButton, ListItemIcon, ListItemText, List, - MenuItem, - Popover, - Select, TextField, Typography, useTheme, } from '@mui/material'; import { Label } from './Group/AddGroup'; import { Spacer } from '../common/Spacer'; -import { LoadingButton } from '@mui/lab'; -import { getBaseApiReact, MyContext } from '../App'; +import { getBaseApiReact } from '../App'; import { getFee } from '../background'; import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; import { subscribeToEvent, unsubscribeFromEvent } from '../utils/events'; @@ -43,6 +32,7 @@ enum Availability { AVAILABLE = 'available', NOT_AVAILABLE = 'not-available', } + export const RegisterName = ({ setOpenSnack, setInfoSnack, @@ -77,7 +67,6 @@ export const RegisterName = ({ } } catch (error) { console.error(error); - } finally { } }; // Debounce logic @@ -195,21 +184,22 @@ export const RegisterName = ({ aria-describedby="alert-dialog-description" > {'Register name'} + - + // TODO: translate + )} @@ -307,6 +298,7 @@ export const RegisterName = ({ + + + @@ -351,6 +384,7 @@ export const ManageMembers = ({ /> )} + {value === 1 && ( - + ); }; From 55c042c02bea0a20a8154b509ba9948bb3e1b2fa Mon Sep 17 00:00:00 2001 From: Nicola Benaglia Date: Sat, 10 May 2025 12:17:15 +0200 Subject: [PATCH 08/15] Add translations --- public/locales/en/group.json | 1 + src/components/Group/QMailMessages.tsx | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/public/locales/en/group.json b/public/locales/en/group.json index 09b8c38..62abd70 100644 --- a/public/locales/en/group.json +++ b/public/locales/en/group.json @@ -42,6 +42,7 @@ "invitees_list": "invitees list", "join_link": "join group link", "join_requests": "join requests", + "latest_mails": "latest Q-Mails", "message": { "generic": { "already_in_group": "you are already in this group!", diff --git a/src/components/Group/QMailMessages.tsx b/src/components/Group/QMailMessages.tsx index 3d897e3..b20f519 100644 --- a/src/components/Group/QMailMessages.tsx +++ b/src/components/Group/QMailMessages.tsx @@ -16,6 +16,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import MarkEmailUnreadIcon from '@mui/icons-material/MarkEmailUnread'; import { useAtom } from 'jotai'; +import { useTranslation } from 'react-i18next'; export const isLessThanOneWeekOld = (timestamp) => { // Current time in milliseconds @@ -53,6 +54,7 @@ export const QMailMessages = ({ userName, userAddress }) => { const [loading, setLoading] = useState(true); const theme = useTheme(); + const { t } = useTranslation(['core', 'group']); const getMails = useCallback(async () => { try { @@ -88,7 +90,10 @@ export const QMailMessages = ({ userName, userAddress }) => { rej(response.error); }) .catch((error) => { - rej(error.message || 'An error occurred'); + rej( + error.message || + t('core:message.error.generic', { postProcess: 'capitalize' }) + ); }); }); } catch (error) { @@ -145,13 +150,14 @@ export const QMailMessages = ({ userName, userAddress }) => { }} onClick={() => setIsExpanded((prev) => !prev)} > - - Latest Q-Mails + {t('group:latest_mails', { postProcess: 'capitalize' })} + { {loading && mails.length === 0 && ( @@ -205,11 +211,11 @@ export const QMailMessages = ({ userName, userAddress }) => { {!loading && mails.length === 0 && ( { color: theme.palette.primary, }} > - Nothing to display + {t('group:message.generic.no_display', { + postProcess: 'capitalize', + })} )} From 13f6651caa4d50925f25b21df4431e3731623520 Mon Sep 17 00:00:00 2001 From: Nicola Benaglia Date: Sat, 10 May 2025 12:32:35 +0200 Subject: [PATCH 09/15] Refactor imports --- public/locales/en/group.json | 1 + src/components/Apps/AppsCategoryDesktop.tsx | 2 +- src/components/Apps/AppsLibraryDesktop.tsx | 2 +- src/components/Chat/AnnouncementList.tsx | 2 +- src/components/Chat/ChatList.tsx | 2 +- src/components/Chat/ChatOptions.tsx | 4 +- src/components/Group/AddGroup.tsx | 5 ++ src/components/Group/AddGroupList.tsx | 2 +- src/components/Group/Forum/GroupMail.tsx | 69 ++++++++----------- src/components/Group/Forum/NewThread.tsx | 9 ++- src/components/Group/Forum/ReadOnlySlate.tsx | 4 +- src/components/Group/Forum/ReusableModal.tsx | 4 +- .../Group/Forum/ShowMessageWithoutModal.tsx | 21 ------ src/components/Group/Forum/Thread.tsx | 25 +++---- src/components/Group/ListOfBans.tsx | 2 +- .../Group/ListOfGroupPromotions.tsx | 2 +- src/components/Group/Settings.tsx | 1 - src/components/Group/ThingsToDoInitial.tsx | 14 ++-- src/components/Group/UserListOfInvites.tsx | 2 +- src/components/Group/WalletsAppWrapper.tsx | 2 +- 20 files changed, 73 insertions(+), 102 deletions(-) diff --git a/public/locales/en/group.json b/public/locales/en/group.json index 62abd70..6fba714 100644 --- a/public/locales/en/group.json +++ b/public/locales/en/group.json @@ -42,6 +42,7 @@ "invitees_list": "invitees list", "join_link": "join group link", "join_requests": "join requests", + "last_message": "last message", "latest_mails": "latest Q-Mails", "message": { "generic": { diff --git a/src/components/Apps/AppsCategoryDesktop.tsx b/src/components/Apps/AppsCategoryDesktop.tsx index 754ba85..39f12ee 100644 --- a/src/components/Apps/AppsCategoryDesktop.tsx +++ b/src/components/Apps/AppsCategoryDesktop.tsx @@ -56,7 +56,7 @@ export const AppsCategoryDesktop = ({ isShow, }) => { const [searchValue, setSearchValue] = useState(''); - const virtuosoRef = useRef(); + const virtuosoRef = useRef(null); const theme = useTheme(); const categoryList = useMemo(() => { diff --git a/src/components/Apps/AppsLibraryDesktop.tsx b/src/components/Apps/AppsLibraryDesktop.tsx index 3490e89..17b9b71 100644 --- a/src/components/Apps/AppsLibraryDesktop.tsx +++ b/src/components/Apps/AppsLibraryDesktop.tsx @@ -102,7 +102,7 @@ export const AppsLibraryDesktop = ({ getQapps, }) => { const [searchValue, setSearchValue] = useState(''); - const virtuosoRef = useRef(); + const virtuosoRef = useRef(null); const theme = useTheme(); const officialApps = useMemo(() => { diff --git a/src/components/Chat/AnnouncementList.tsx b/src/components/Chat/AnnouncementList.tsx index 9c32cc1..5f3c75b 100644 --- a/src/components/Chat/AnnouncementList.tsx +++ b/src/components/Chat/AnnouncementList.tsx @@ -18,7 +18,7 @@ export const AnnouncementList = ({ loadMore, myName, }) => { - const listRef = useRef(); + const listRef = useRef(null); const [messages, setMessages] = useState(initialMessages); useEffect(() => { diff --git a/src/components/Chat/ChatList.tsx b/src/components/Chat/ChatList.tsx index 56acbc7..8362fad 100644 --- a/src/components/Chat/ChatList.tsx +++ b/src/components/Chat/ChatList.tsx @@ -23,7 +23,7 @@ export const ChatList = ({ hasSecretKey, isPrivate, }) => { - const parentRef = useRef(); + const parentRef = useRef(null); const [messages, setMessages] = useState(initialMessages); const [showScrollButton, setShowScrollButton] = useState(false); const [showScrollDownButton, setShowScrollDownButton] = useState(false); diff --git a/src/components/Chat/ChatOptions.tsx b/src/components/Chat/ChatOptions.tsx index 4f92f53..0ec1866 100644 --- a/src/components/Chat/ChatOptions.tsx +++ b/src/components/Chat/ChatOptions.tsx @@ -60,8 +60,8 @@ export const ChatOptions = ({ const [searchValue, setSearchValue] = useState(''); const [selectedMember, setSelectedMember] = useState(0); const theme = useTheme(); - const parentRef = useRef(); - const parentRefMentions = useRef(); + const parentRef = useRef(null); + const parentRefMentions = useRef(null); const [lastMentionTimestamp, setLastMentionTimestamp] = useState(null); const [debouncedValue, setDebouncedValue] = useState(''); // Debounced value const messages = useMemo(() => { diff --git a/src/components/Group/AddGroup.tsx b/src/components/Group/AddGroup.tsx index e97917d..e9e9515 100644 --- a/src/components/Group/AddGroup.tsx +++ b/src/components/Group/AddGroup.tsx @@ -452,6 +452,7 @@ export const AddGroup = ({ address, open, setOpen }) => { 100% + { postProcess: 'capitalize', })} + + { postProcess: 'capitalize', })} + + { const [groups, setGroups] = useState([]); 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 [inputValue, setInputValue] = useState(''); const [filteredItems, setFilteredItems] = useState(groups); const [isLoading, setIsLoading] = useState(false); diff --git a/src/components/Group/Forum/GroupMail.tsx b/src/components/Group/Forum/GroupMail.tsx index 60bfd12..41f75ef 100644 --- a/src/components/Group/Forum/GroupMail.tsx +++ b/src/components/Group/Forum/GroupMail.tsx @@ -1,26 +1,17 @@ -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Avatar, Box, Popover, Typography, useTheme } from '@mui/material'; -// import { MAIL_SERVICE_TYPE, THREAD_SERVICE_TYPE } from "../../constants/mail"; import { Thread } from './Thread'; import { AllThreadP, ArrowDownIcon, ComposeContainer, ComposeContainerBlank, - ComposeIcon, ComposeP, GroupContainer, InstanceFooter, InstanceListContainer, InstanceListContainerRow, InstanceListContainerRowCheck, - InstanceListContainerRowCheckIcon, InstanceListContainerRowMain, InstanceListContainerRowMainP, InstanceListHeader, @@ -48,7 +39,6 @@ import { getTempPublish, handleUnencryptedPublishes, } from '../../Chat/GroupAnnouncements'; -import CheckSVG from '../../../assets/svgs/Check.svg'; import ArrowDownSVG from '../../../assets/svgs/ArrowDown.svg'; import { LoadingSnackbar } from '../../Snackbar/LoadingSnackbar'; import { executeEvent } from '../../../utils/events'; @@ -73,9 +63,9 @@ export const GroupMail = ({ hide, isPrivate, }) => { - const [viewedThreads, setViewedThreads] = React.useState({}); + const [viewedThreads, setViewedThreads] = useState({}); const [filterMode, setFilterMode] = useState('Recently active'); - const [currentThread, setCurrentThread] = React.useState(null); + const [currentThread, setCurrentThread] = useState(null); const [recentThreads, setRecentThreads] = useState([]); const [allThreads, setAllThreads] = useState([]); const [members, setMembers] = useState(null); @@ -178,7 +168,10 @@ export const GroupMail = ({ rej(response.error); }) .catch((error) => { - rej(error.message || 'An error occurred'); + rej( + error.message || + t('core:message.error.generic', { postProcess: 'capitalize' }) + ); }); }); } catch (error) { @@ -186,7 +179,7 @@ export const GroupMail = ({ } }; - const getAllThreads = React.useCallback( + const getAllThreads = useCallback( async (groupId: string, mode: string, isInitial?: boolean) => { try { setIsLoading(true); @@ -206,7 +199,7 @@ export const GroupMail = ({ }); const responseData = await response.json(); - let fullArrayMsg = isInitial ? [] : [...allThreads]; + const fullArrayMsg = isInitial ? [] : [...allThreads]; const getMessageForThreads = responseData.map(async (message: any) => { let fullObject: any = null; if (message?.metadata?.description) { @@ -271,13 +264,12 @@ export const GroupMail = ({ } finally { if (isInitial) { setIsLoading(false); - // dispatch(setIsLoadingCustom(null)); } } }, [allThreads, isPrivate] ); - const getMailMessages = React.useCallback( + const getMailMessages = useCallback( async (groupId: string, members: any) => { try { setIsLoading(true); @@ -315,7 +307,7 @@ export const GroupMail = ({ .sort((a, b) => b.created - a.created) .slice(0, 10); - let fullThreadArray: any = []; + const fullThreadArray: any = []; const getMessageForThreads = newArray.map(async (message: any) => { try { const identifierQuery = message.threadId; @@ -327,6 +319,7 @@ export const GroupMail = ({ }, }); const responseData = await response.json(); + if (responseData.length > 0) { const thread = responseData[0]; if (thread?.metadata?.description) { @@ -342,7 +335,7 @@ export const GroupMail = ({ }; fullThreadArray.push(fullObject); } else { - let threadRes = await Promise.race([ + const threadRes = await Promise.race([ getEncryptedResource( { name: thread.name, @@ -377,13 +370,12 @@ export const GroupMail = ({ console.log(error); } finally { setIsLoading(false); - // dispatch(setIsLoadingCustom(null)); } }, [secretKey, isPrivate] ); - const getMessages = React.useCallback(async () => { + const getMessages = useCallback(async () => { // if ( !groupId || members?.length === 0) return; if (!groupId || isPrivate === null) return; @@ -400,7 +392,6 @@ export const GroupMail = ({ if (filterModeRef.current !== filterMode) { firstMount.current = false; } - // if (groupId && !firstMount.current && members.length > 0) { if (groupId && !firstMount.current && isPrivate !== null) { if (filterMode === 'Recently active') { getMessages(); @@ -427,11 +418,6 @@ export const GroupMail = ({ if (groupData && Array.isArray(groupData?.members)) { for (const member of groupData.members) { if (member.member) { - // const res = await getNameInfo(member.member); - // const resAddress = await qortalRequest({ - // action: "GET_ACCOUNT_DATA", - // address: member.member, - // }); const name = res; const publicKey = resAddress.publicKey; if (name) { @@ -465,16 +451,6 @@ export const GroupMail = ({ [filterMode] ); - // useEffect(()=> { - // if(user?.name){ - // const threads = JSON.parse( - // localStorage.getItem(`qmail_threads_viewedtimestamp_${user.name}`) || "{}" - // ); - // setViewedThreads(threads) - - // } - // }, [user?.name, currentThread]) - const handleCloseThreadFilterList = () => { setIsOpenFilterList(false); }; @@ -596,7 +572,7 @@ export const GroupMail = ({ padding: '0px', }} > - + {filterOptions?.map((filter) => { return ( @@ -621,6 +597,7 @@ export const GroupMail = ({ /> )} + {filter} @@ -630,9 +607,10 @@ export const GroupMail = ({ ); })} - + + + + - last message:{' '} + {t('group:last_message', { + postProcess: 'capitalize', + })} + :{' '} {formatDate(thread?.created)}
)}
+ { setTimeout(() => { @@ -834,6 +820,7 @@ export const GroupMail = ({
+ { const { t } = useTranslation(['core', 'group']); - const { show } = React.useContext(MyContext); + const { show } = useContext(MyContext); const [isOpen, setIsOpen] = useState(false); const [value, setValue] = useState(''); const [isSending, setIsSending] = useState(false); const [threadTitle, setThreadTitle] = useState(''); - const [openSnack, setOpenSnack] = React.useState(false); - const [infoSnack, setInfoSnack] = React.useState(null); + const [openSnack, setOpenSnack] = useState(false); + const [infoSnack, setInfoSnack] = useState(null); const editorRef = useRef(null); const theme = useTheme(); const setEditorRef = (editorInstance) => { diff --git a/src/components/Group/Forum/ReadOnlySlate.tsx b/src/components/Group/Forum/ReadOnlySlate.tsx index 5724f92..15e1436 100644 --- a/src/components/Group/Forum/ReadOnlySlate.tsx +++ b/src/components/Group/Forum/ReadOnlySlate.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { createEditor } from 'slate'; import { withReact, @@ -96,7 +96,7 @@ interface ReadOnlySlateProps { content: any; mode?: string; } -const ReadOnlySlate: React.FC = ({ content, mode }) => { +const ReadOnlySlate: FC = ({ content, mode }) => { const [load, setLoad] = useState(false); const editor = useMemo(() => withReact(createEditor()), []); const value = useMemo(() => content, [content]); diff --git a/src/components/Group/Forum/ReusableModal.tsx b/src/components/Group/Forum/ReusableModal.tsx index 1bedccb..9bd25c7 100644 --- a/src/components/Group/Forum/ReusableModal.tsx +++ b/src/components/Group/Forum/ReusableModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import { FC } from 'react'; import { Box, Modal, useTheme } from '@mui/material'; interface MyModalProps { @@ -9,7 +9,7 @@ interface MyModalProps { customStyles?: any; } -export const ReusableModal: React.FC = ({ +export const ReusableModal: FC = ({ open, onClose, onSubmit, diff --git a/src/components/Group/Forum/ShowMessageWithoutModal.tsx b/src/components/Group/Forum/ShowMessageWithoutModal.tsx index 914b9c5..4b862d4 100644 --- a/src/components/Group/Forum/ShowMessageWithoutModal.tsx +++ b/src/components/Group/Forum/ShowMessageWithoutModal.tsx @@ -118,27 +118,6 @@ export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => { width: 'auto', }} > - {/* - - - - {file?.originalFilename || file?.filename} - - */} {message?.attachments?.length > 1 && isFirst && ( { try { setTempPublishedList([]); @@ -328,7 +321,7 @@ export const Thread = ({ }, [messages, secretKey] ); - const getMessages = React.useCallback(async () => { + const getMessages = useCallback(async () => { if ( !currentThread || (!secretKey && isPrivate) || @@ -410,7 +403,7 @@ export const Thread = ({ const interval = useRef(null); - const checkNewMessages = React.useCallback( + const checkNewMessages = useCallback( async (groupInfo: any) => { try { let threadId = groupInfo.threadId; @@ -494,7 +487,7 @@ export const Thread = ({ firstMount.current = true; }; - React.useEffect(() => { + useEffect(() => { subscribeToEvent('threadFetchMode', threadFetchModeFunc); return () => { @@ -656,6 +649,7 @@ export const Thread = ({
+ {t('core:page.previous', { postProcess: 'capitalize' })} + + + + +